I have been working with SD Cards and micro SD Cards for a while.
I am using Part1_Physical_Layer_Simplified_Specification_Ver6.00 for reference.
I am able to do successful card initialization, read and write for other micro SDs like ATP 8GB SLC, Panasonic 8GB SLC etc. However when I am using Delkin 16 GB SLC (and also Swissbit 8GB SLC), although I am successful in card initialization and write, when I am trying to read then I am not getting start block token 0xFE and there are around 512 Bytes of junk data before it becomes normal again.
The pattern is as follows (using the Beagle SPI analyzer):
After writing the following (only the first 24 bytes are shown, but the pattern is the same):
If I am writing 0xA0. Please refer to the following image:
If I change the bytes written, then bytes read are also changed and there is one to one correspondence as well between the bytes written and bytes read. But the bytes are not the same.
I am verifying the data is written successfully using the SD Card reader with HxD hex viewer.
For the first case:
For the second case:
It doesn't seem like the voltage to SD card is varying, as I checked it on the oscilloscope and it remains 3.3 volts during the read.
I am using F28377s Launchpad from TI as the microcontroller.
I would like to get the inputs from you. What exactly can I try to fix this problem?
Edit1: Exactly same behavior is observed for Swissbit 8GB SLC. The same images above can be applied to Swissbit. The data read for Swissbit is same as Delkin.
SPI clock before initialization is 200 kHz and after initialization is changed to 1 MHz.
Edit2: Please look at the oscilloscope images below (i have changed the clock frequency to 225 KHz):
Edit3: The second oscilloscope image, immediately follows the first oscilloscope image. The first image is the read command and response whereas the Second image is sending 0xFF and waiting for start data block token, which is 0xA8 in the second image as 0xFE is bit shifted by 2 bits. You can look at the decoded hex data of the oscilloscope in the bottom of the oscilloscope images. They are same as my Beagle SPI Analyzer Debug Data for example 2 (where I am writing 0xA0 and reading back 0x28).
Edit4: As per Anonymous' suggestion, I have updated my code such that before every command and after CS LOW, I send 8 clocks before any actual intended SPI transmission. After the command response completion, I send 8 clock cycles just before CS HIGH and 8 clock cycles just after CS HIGH. Command response completion in SD Read case means when we have received the last CRC byte. Command response completion in SD Write means when the card stops sending the busy signal after writing. Similarly, I have applied to other commands as well.
Also, I don't do CS HIGH until the command and its response are completed. For e.g. in SD Read Case, I do CS LOW and I send the command, get the command response, get the start block token (0xFE), get the CRC and then I do the CS HIGH.
Thanks.
Best Answer
I think you should have noticed the pattern:
fe 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 00 01 02 03 ...
shifting this sequence two bits right you get
ff 80 00 40 80 c1 01 41 81 ...
So exactly the sequence you have. You have added two spare bits into the stream, and bytes got misaligned. Why? Without exact diagrams showing the clock it is not possible to say. Most probably you have issues with clock or data synchronization to it.
This misalignment may happen in either write or read - so it may appear that you write wrong sequence because your write command has bytes misaligned, and then read that wrong sequence back (of course), or it could be purely read command issue. The conclusion that you must check what SD-card has actually written to it - using another functioning device (e.g. PC dumping you card to the file and checking the image) - before going into debugging read or write command execution.
Edit: looking to the scope diagrams I see/recommend the following:
Edit 2:
Be very cautious when deselecting the card - your images show that you issue command to the card, deselect it raising CS high, and then reselect it continuosuly sending 0xFFs to the card. Seems card does not understand that, and sends 0x28s back, which are actually 0x05 - "invalid command" R1 response shifted. There're only specific circumstances when you may deselect the card, it is explained in simplified SD specification, and follows very specific protocol:
Regarding my second comment
Spare cycles, while will take some time, will ensure card has properly completed/cancelled the previous operation, and gets ready for next one. So I recommend you to implement it for all commands if possible.