CRC-7 for MMC Flash

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Has anyone written the CRC generation routine for the CRC-7 error checking for MMC cards ?

The poly is X^7 + X^3 + 1 or (0x89). CRC initial value = 0x00.

According to the SanDisk documentation, this is a valid reset command:

0x40, 0x00, 0x00, 0x00, 0x00, 0x95

The 0x95 is actually a left justified CRC value of 0x4A with 1 added for the stop bit. ((0x4A << 1) + 1) = 0x95

However, I haven't been able to duplicate this value. Here is the method.

7..0
C <-- CRC <-- 0x40,0x00,0x00,0x00,0x00,0x00 (40 data + 7 pad bits)
| ^
| |
| xor
| |
+---> poly

Any help would be appreciated.

Thanks,
Fiz

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Problem solved !

My problem was that I was treating the CRC register as an 8 bit register instead on a 7 bit. That means that the carry out of this register comes from bit 6 and NOT bit 7. Here is psuedo code for the "long" method. This is ok for calculating CRC on 5 byte message like the MMC command message. I will use a table lookup method for CRC on packets.

Clear CRC to 0x00
TotalBits = 47
While(TotalBits)
shift CRC, data bits, and pad bits left 1 bit
if carry from bit 6 of CRC
CRC = CRC exclusive-or Poly
TotalBits--
Loop

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does someone have a working C-Source of this?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Waldlaufer

This might give a hint

http://www.humblesoft.com/n-card...

/Bingo

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will post my C source code for the psuedo code this afternoon.

Also, keep in mind that when you put a MMC into SPI mode, it automatically turns off the CRC generator/checker. So, after you send the RESET command, you do not have to calculate CRC on commands anymore. However, if you are concerned with errors slipping through, there is a bit in a register where you can re-enable the CRC.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I understand this thread is quite old, but i was wondreing if you ever got arround to posting that code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jimparisi wrote:
I understand this thread is quite old, but i was wondreing if you ever got arround to posting that code.
In the SD Specifications it gives this example, yet i cannot seem to get the same CRC7 result.

CRC7 Examples
The CRC section of the command/response is bolded.
CMD0 (Argument=0) --> 01 000000 00000000000000000000000000000000 "1001010" 1
CMD17 (Argument=0) --> 01 010001 00000000000000000000000000000000 "0101010" 1
Response of CMD17 --> 00 010001 00000000000000000000100100000000 "0110011" 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here's a batch file (requires perl) that'll calculate it. Went between command line passing and static defining so currently thing you pass the packet on the command line and define the length in a variable, but you can at least see how it works. The C-code should be almost the same as the perl, aside from the stuff to convert from string to hex.

@ECHO OFF
GOTO START_SCRIPT

#!perl -w

use strict;

my $crc = 0x00;
my $data = $ARGV[0]; # "1101004D4D4331364700123CC2655A";
my $length = 10;

for ( my $i = 0; $i < $length; $i += 2 )
{
    my $c = hex( substr( $data, $i, 2 ) );

    for ( my $ibit = 0; $ibit < 8; $ibit++)
    {
        $crc = $crc << 1;
        if (($c ^ $crc) & 0x80) 
        {
            $crc = $crc ^ 0x09;
        }
        $c = $c << 1;
    }

    $crc = $crc & 0x7F;
}

$crc = ($crc << 1) | 0x1;
printf "\nCRC: 0x%02x", $crc;
print "\n";

__END__

:START_SCRIPT
@perl -x -S crc.cmd %*

Clancy _________________ Step 1: RTFM Step 2: RTFF (Forums) Step 3: RTFG (Google) Step 4: Post

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, i got it working last night.