Reading MicroSD card CID register from laptop

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
hlcRaleigh
 
Posts: 3
Joined: Tue Jan 17, 2023 3:22 pm

Reading MicroSD card CID register from laptop

Post by hlcRaleigh »

I do not have an SD card reader on a PCIe bus - all of mine sit on a USB controller. So I do not have direct access to the the SD Card via the SPI bus to read the CID register.

I have wired up an Adafruit FT232H to a MicroSD card breakout board+ and verified the operation of the Micro SD chip select and card detection using the CircuitPython across Blinka.
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
cs = digitalio.DigitalInOut(board.C0)
sdcard = adafruit_sdcard.SDCard(spi, cs)

Alas adafruit_sdcard only has public methods (count, readblocks, writeblocks) to support the SD card in a filesystem - not write/read SPI bus commands.

I am pursuing using SPIDevice and layering on my own SD card write/read commands:
spidev = adafruit_bus_device.spi_device.SPIDevice(spi, cs)
I have lots of code but it all boils down to:
1. I send a 6 byte command: spidev.spi.write(buf)
2. I spin in a loop reading a 1 byte response: spidev.spi.readinto(buf, end=1, write_value=0xFF) and
3. the returned 1 byte status MSB is always on so eventually (200 loops) the command times out failing so I never wait for any possible CID data.
4. If I increase the loop count from 200 to 200000, my DVM sees the chip select high so the Micro SD should be listening. I have no oscilloscope or logic analyzer to monitor the SPI bus.

I can see at least 2 possibilities:
1. I am missing something silly. Can anyone point me at some sample code that implements a command write followed by a data read on a SPI bus?
2. SPI bus timing is such that a laptop running CircuitPython through Blinka simply cannot access the MicroSD card breakout board+ via the FT232H. This seems unlikely since adafruit_sdcard.SDCard(spi, cs) can detect a missing SD card and does timeout on an old V1 SD card I tried.

If this is posted to the wrong forum, please let me know.

I would appreciate any help. Thanks in advance.

User avatar
hlcRaleigh
 
Posts: 3
Joined: Tue Jan 17, 2023 3:22 pm

Re: Reading MicroSD card CID register from laptop

Post by hlcRaleigh »

1. I used the adafruit_sdcard as sample source code. I discovered that it sends CMD9 which is structured the same as CMD10 (the read CID command). I learned that I was not calculating my CRC7 correctly. So was able to grab a copy that source code and add a readCID method to it (note the 0x1B CRC value):
def readCID(self, response_buf: WriteableBuffer)-> None:
with self._spi as card:
# CMD10: response R2 (R1 byte + 16-byte block read)
if self._cmd(card, 10, 0, 0x1B, response_buf) != 0:
raise OSError("no response from SD card cmd10")
2. I am a Python-newbie so I could not determine how to subclass SDCard to 'extend' the class as in C++ so I grabbed a copy of the Python and hacked my readCID method.
3. With some additional 'lily guilding' printing, I could read the CIDs from all of my SD cards - here is an example:

Manufacturer ID= 0x3 <------------- SanDisk
OEM ID= SD
Prod Name= SU04G <----------------- 4GB
Product Rev= 8.0
Product SN= 0xfaa170
Man Date= 2009 month= 8 <--------- Manufactured in August 2008

Raw SD card CID CMD10 response:
cid[ 0 ]= 0x3 0x53 0x44 0x53
cid[ 4 ]= 0x55 0x30 0x34 0x47
cid[ 8 ]= 0x80 0x0 0xfa 0xa1
cid[ 12 ]= 0x70 0x0 0x98 0xb5

4. Now I at least have a tool to investigate possible

User avatar
hlcRaleigh
 
Posts: 3
Joined: Tue Jan 17, 2023 3:22 pm

Re: Reading MicroSD card CID register from laptop

Post by hlcRaleigh »

1. I used the adafruit_sdcard as sample source code. I discovered that it sends CMD9 which is structured the same as CMD10 (the read CID command). I learned that I was not calculating my CRC7 correctly. So was able to grab a copy that source code and add a readCID method to it (note the 0x1B CRC value):
def readCID(self, response_buf: WriteableBuffer)-> None:
with self._spi as card:
# CMD10: response R2 (R1 byte + 16-byte block read)
if self._cmd(card, 10, 0, 0x1B, response_buf) != 0:
raise OSError("no response from SD card cmd10")
2. I am a Python-newbie so I could not determine how to subclass SDCard to 'extend' the class as in C++ so I grabbed a copy of the Python and hacked my readCID method.
3. With some additional 'lily guilding' printing, I could read the CIDs from all of my SD cards - here is an example:

Manufacturer ID= 0x3 <------------- SanDisk
OEM ID= SD
Prod Name= SU04G <----------------- 4GB
Product Rev= 8.0
Product SN= 0xfaa170
Man Date= 2009 month= 8 <--------- Manufactured in August 2008

Raw SD card CID CMD10 response:
cid[ 0 ]= 0x3 0x53 0x44 0x53
cid[ 4 ]= 0x55 0x30 0x34 0x47
cid[ 8 ]= 0x80 0x0 0xfa 0xa1
cid[ 12 ]= 0x70 0x0 0x98 0xb5

Now I have a tool to investigate possible SD card counterfeit labeling some satisfaction at building a tiny FT232H, Micro SD+ breadboard.
FT232HplusMicSD.png
FT232HplusMicSD.png (853.31 KiB) Viewed 90 times

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”