0

For a SD card driver I tried to calculate CRC7 for the commands. Now, if I "enable CRC7 check" with CMD59, I get errors with some SD cards. But if I "disable CRC7" check with CMD59, I can read and write files on all kinds of SD cards, who support SPI.

Well, my initial assumption was that it was due to the CRC7 calculation. With SD cards that give me errors, I can still initialize them without any problems with "enabled CRC7 check" and also read and write a few files. But usually only about 10-15 files at most before an error occurs.

The error manifests itself as follows:

After CMD17, I get R1 = 0x00. But then I only read 0xFF. The data token never comes. Also no Data Error Token. Only 0xFF. I read 100 times (100 bytes), but at least for 200 ms (the SD card standard specifies that a timeout can be assumed after 100 ms, so I should be on the safe side to not miss the token). But I only get 0xFF. When I read the status again with CMD13, I get R1 = 0x00 and R2 = 0x00. So no error. From this point on, neither writing nor reading works. I can execute all commands without errors in R1 or R2 (also CMD17,18,24,25), but I only get 0xFF when reading afterwards; the tokens never come. But always with no indication of errors.

If someone is interested, the SD card initialization process is done like this:

  • baudrate <400'000 Hz
  • CMD0 -> CMD59 -> CMD8
  • IF SDSC: CMD58 -> loop(CMD55 -> ACMD41)
  • IF SDHC/SDXC:CMD58 (get OCR register values) -> loop(CMD55 -> ACMD41) -> CDMD50 (get OCR register values and check CCS)
  • CMD9 -> Check CSD-Version and get values
  • CMD10 (get CID register values)
  • CMD55 -> ACMD13 (get SD register values)
  • CMD55 -> ACDM51 (get SCR register values)
  • check, if CMD42 is supported
  • if yes and password should be set or is set:
  • CMD16 (set block length for CMD42)
  • CMD42
  • CMD16 (set block length 51 bytes, for all card)
  • Mount filesystem
  • Switch to baudrate 12 MHz
  • Read with CMD17, CMD18 (CMD12 for STOP_TRAN)
  • Write with CMD24, CMD25
  • if error, check with CDM13

I would now like to rule out that it is due to the CRC7 calculation, which may only return an error with certain inputs. Here is the code (Python/Micropython), and I would be grateful if someone familiar with CRC could check it for correctness. As I said, without CRC7 check, I never get an error, but with CRC7 check, until a error arrives, all CRC7 are calculated correct (double checked with CRC-Calculator)

def crc7(self, cmd, arg1, arg2, arg3, arg4):
    crc = 0x00
    poly = 0x89
        
    cmd_token = bytes([cmd, arg1, arg2, arg3, arg4])
    # Example: CMD0 -> 0x40, 0x00, 0x00, 0x00, 0x00

    for byte in cmd_token:
        for bit in range(8):
            bit = ((byte >> (7 - bit)) & 1)
            crc_bit = ((crc >> 6) & 1)
            crc = ((crc << 1) & 0x7F)
            if bit ^ crc_bit:
                crc ^= poly
                    
    crc = crc & 0x7F
    crc = (crc << 1) | 0x01 # CRC7 and end bit = 1 for CMD    
    return crc
1
  • There are online CRC calculators, have you tried comparing your results? Commented Oct 23 at 19:07

1 Answer 1

0

The error is in using the full 8-bit generator polynomial constant 0x89 in a bit-wise implementation that uses a 7-bit CRC register.

The SD card CRC7 generator polynomial is G(x) = x^7 + x^3 + 1, which is 100010012 or 0x89.

Since your crc variable is only 7 bits wide, the code handles that first '1' in the divisor implicitly:

  • crc_bit = ((crc >> 6) & 1) checks the highest bit
  • crc = ((crc << 1) & 0x7F) shifts the entire 7-bit value

Therefore, you must only XOR the 7-bit remainder of the polynomial, which is x^3 + 1. Corresponding to 00010012 = 0x09.

If you used 0x89, you would be incorrectly applying the high-order bit again, which would completely mess up the remainder and give you the wrong CRC value, leading to the intermittent errors you've seen.

So change the poly variable from 0x89 to 0x09. Hope this solve the problem.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.