wisi
Member
I would be careful with such operations, as any data transfer (that isn't done while transferring sectors) is taken as a command. So if you are sending data of 0x00, then you are just sending command 0 (GO_IDLE_STATE) multiple times.
Instead you have to carefully determine which command makes the card go in this undetermined state and find a way to exit it.
The other thing to consider is how CMD0 is implemented. As any other command, it has 4 bytes of argument. If each of them is also considered a CMD0, then sending any number of 0x00 bytes should be OK. But if this is not the case, and the 4 bytes of argument must all be sent and are never considered another command(s), or anything within that period is considered only an argument, then we have a problem. And in that case the number of dummy bytes must be a multiple of 5 + the length of CMD0 response. This also brings the question of how polling for response is done and if "reading" more bytes after that is like sending CMD0 (when sending 0x00). My tests show that sending any number of 0x00 bytes is not causing any problems, at least on some SD cards. Still I would like to avoid that.
There is also the question of how the /CS interruptions are treated. Because it could be that a command can only start after a /CS high to low. But this seems not to be the case.
It might be that when an /CS interruption happens within the argument bytes of CMD0, those are treated as potential commands, but this is not the case for other commands. This would explain how after an arbitrary number of 'dummy' bytes transferred commands can still be sent.
If somebody can find how the above things are specified in the SD Card specs, I would be thankful.
I believe that may have to do with the way the polling for response is done. But the latest code you are using is always working in single byte chunks, so this shouldn't be a problem, unless the problem is just that - interrupting /CS in the middle of commands/responses.
Still I think it *might* be that the cause is some missed transfer - like forgetting to read/write the CRC bytes after the transfer of a sector. So check if that is always done (AFAIK the checksum is always transferred, even if disabled).
Also check if you are transferring sectors fully - for example if you are transferring less than the set amount. And also you can try testing with reduced number of dummy bytes, until it starts failing again to determine the necessary minimum and if that needs to be multiple of anything (which is unlikely).
EDIT: I got confused above - each command is OR-ed with 0x40 (the highest two bits are always 01), so sending 0x00 is not sending any command. This solves the above questions mostly.
Still, @Maximus32 you should determine which command is creating the need for transferring those dummy bytes.
I don't remember if the specification states that such zero bytes can be sent at any time, but I guess doing that is harmless.
EDIT2: Maybe the required initial dummy cycles should be of 0x00, rather than the initialization command.
Instead you have to carefully determine which command makes the card go in this undetermined state and find a way to exit it.
The other thing to consider is how CMD0 is implemented. As any other command, it has 4 bytes of argument. If each of them is also considered a CMD0, then sending any number of 0x00 bytes should be OK. But if this is not the case, and the 4 bytes of argument must all be sent and are never considered another command(s), or anything within that period is considered only an argument, then we have a problem. And in that case the number of dummy bytes must be a multiple of 5 + the length of CMD0 response. This also brings the question of how polling for response is done and if "reading" more bytes after that is like sending CMD0 (when sending 0x00). My tests show that sending any number of 0x00 bytes is not causing any problems, at least on some SD cards. Still I would like to avoid that.
There is also the question of how the /CS interruptions are treated. Because it could be that a command can only start after a /CS high to low. But this seems not to be the case.
It might be that when an /CS interruption happens within the argument bytes of CMD0, those are treated as potential commands, but this is not the case for other commands. This would explain how after an arbitrary number of 'dummy' bytes transferred commands can still be sent.
If somebody can find how the above things are specified in the SD Card specs, I would be thankful.
I believe that may have to do with the way the polling for response is done. But the latest code you are using is always working in single byte chunks, so this shouldn't be a problem, unless the problem is just that - interrupting /CS in the middle of commands/responses.
Still I think it *might* be that the cause is some missed transfer - like forgetting to read/write the CRC bytes after the transfer of a sector. So check if that is always done (AFAIK the checksum is always transferred, even if disabled).
Also check if you are transferring sectors fully - for example if you are transferring less than the set amount. And also you can try testing with reduced number of dummy bytes, until it starts failing again to determine the necessary minimum and if that needs to be multiple of anything (which is unlikely).
EDIT: I got confused above - each command is OR-ed with 0x40 (the highest two bits are always 01), so sending 0x00 is not sending any command. This solves the above questions mostly.
Still, @Maximus32 you should determine which command is creating the need for transferring those dummy bytes.
I don't remember if the specification states that such zero bytes can be sent at any time, but I guess doing that is harmless.
EDIT2: Maybe the required initial dummy cycles should be of 0x00, rather than the initialization command.
Last edited: