Location

Kaunas, Lithuania

 

The secret of the last byte in the CID number

As there is much confusion with an SD Card CID number’s last 2 digits, I would like to shed some light on this topic.

When ordering a custom CID SD card or changing the CID number in changeable CID cards, the main question that often comes up is that the last 2 digits do not match what you ordered or changed and what you see when reading the CID number.

The main reason is that different systems capable of reading CID, interpret it differently. So, first let’s clarify what that mysterious last byte is, which causes so much confusion. And we will understand where these interpretations arise.

SD Bus Protocol and CRC

Communication on SD card bus is based on a serial protocol containing command and data bit stream. All commands, responses, and data are initiated with a start bit and terminated with an end bit. Each command and response transmission on SD card bus is protected with CRC (Cyclic redundancy check). The main purpose of CRC is to protect data transfer against transmission errors. CRC number is generated for every command and response on CMD line. Data blocks on DAT lines are protected with CRC for each data block.

All commands, responses, CSD, and CID registers CRC are calculated with the CRC7 algorithm  (except R3 type response for OCR register). CRC7 checksum is a 7-bit number. Data transfers on the DAT line use the CRC16 algorithm for payload protection in block transfer mode. CRC checksum is a 16-bit number.

For more in-depth details on the protocol, SD card commands, and responses, you can refer to the Physical Layer Simplified Specification

Understanding the CID Number Structure

CID number is a unique SD card identification number, it’s a 16-byte (128-bit) number. CID structure was described earlier here: What is SD card CID number?

The command for CID reading is CMD2 (ALL_SEND_CID). The response type for this command is a R2 type response.

R2 structure

 

Real-world response to CMD2 example taken with logic analyzer on SD bus below:

R2 response to CMD2 (CID read)

So, as seen from the pictures above, the CID response from an SD card actually is 136 bits in length: the first byte contains the start bit, transmission bit, and 6 reserved bits. Then CID or CSD is 127 bits including CRC7, so the actual CID is 120 bits (15 bytes), and then CRC7 + stop bit.

So the first byte (start bit, transmission bit, and reserved 6 bits) and last bit (end bit) is a part of data transmission protocol, and are not a part of actual CID number. So the full CID number including CRC is 127 bits only (CID 120 bits + 7bit CRC).

 

SD card CID number reading

Frequently, CID reading is performed using a notebook with a Linux OS. Linux often displays only the 15 bytes correctly, with the real CRC value replaced by 00 or 01. Actual CRC is not shown for the user.

Tools like the SD Card toolbox, however, display all 16 bytes, including CRC7. So, the confusion arises due to different representations on different systems. Regardless of the representation, the last byte, including the CRC value, is the same, and it can’t be different, as CRC is math-related to all CID fields. So it’s just a representation matter.

But… there can arise other confusions with CRC. If we will take the whole CID 16 bytes representation, the last CID byte containing the CRC value is displayed together with the end bit. So if we calculate CRC7 from all 15 CID bytes using a CRC7 algorithm, we will get different values.

In the example above we see last 2 digits of CID as 0x8D, but in the decoded CID CRC7 value is 0x46. So why is that? Let’s take a look at the bit representation of those numbers:

0x8D -> 1000 1101
0x46 -> 0100 0110

Now everything should be clear. The last bit is actually part of the data transfer protocol (end bit) 0x8D->1000 1101 and is not related to the CID or CRC anyhow, so let’s remove it 0x8D->1000 110x, now we have only seven bits left representing CRC7, so let’s take those 7 bits 1000110 and convert to hex value. The hex value must be 8-bit aligned, so we must add one bit in the beginning: 0100 0110->0x46. So actual CRC value is 0x46.

So, simplifying all this, we take the last byte from CID and shift it right by one bit and we will get a real CRC7 value.

CID representations

So usually you will meet 3 different representations:

If CID is represented as a 16-byte number:

  • last byte is represented as CRC7+end bit. Using SD Card toolbox or similar tools (0x8d in our example above)
  • last byte is represented as 00,01 or ff. Usually using Linux

For CID representation as separate decoded fields:

  • CRC7 value usually will be and must be displayed as CRC7 value without a stop bit (0x46 in our example

Conclusions

Regardless of what was used for CID reading, confusion with the last byte arises because of different representations only, and regardless of what you see on your screen, the system you use the SD card in will always see the last byte correctly, as the CRC value is not programmed but rather is part of the communication protocol and calculated from the CID by SD card controller.


 

Leave a Reply

Your email address will not be published. Required fields are marked *