With the multi-issuing (per dot) of CMD10 it now consistently produces an error message on unusable rxlag values.
I've worked out that not all SD cards react the same to pin registration. Then the timing compensation causes lsb ordering mismatch. I'm not sure of best way to resolve. I've already improved the outcome by widening the min-max search of the calibration routine so that it still finds all good cases. But when using clock divider of 2 it can still end up picking the wrong value for rxlag.
I could reject the choice on basis that that value failed and select plus/minus one instead. Or I could try separating the pin registration step so that the search order isn't based on preconceived behaviour of the SD cards.
EDIT: Okay, it's really at the edge of that particular card's ability I think. ie: Not a Prop2 timing limitation. Older cards are sometimes slower unsurprisingly.
Amusingly, another SD card, the camera card, of the same brand but 6 years older is actually a faster card.
Well, I've simply made it subtract one for correcting rxlag when it hits the mis-ordered registration issue. The default choice was rounded up on halfway. So it now kind of rounds down for this exception.
@evanh said:
EDIT: Okay, it's really at the edge of that particular card's ability I think. ie: Not a Prop2 timing limitation. Older cards are sometimes slower unsurprisingly.
I would imagine there is going to be quite a bit of variation in delay required amongst different cards at the same P2 clock freq and divider, which affects the rxlag value needed. As so many different types of cards have been released from different manufacturers there is unlikely to be some one size fits all value. Not going to be something like the PSRAM output timing from the same manufacturer for example.
@rogloh said:
I would imagine there is going to be quite a bit of variation in delay required amongst different cards at the same P2 clock freq and divider, which affects the rxlag value needed. As so many different types of cards have been released from different manufacturers there is unlikely to be some one size fits all value. Not going to be something like the PSRAM output timing from the same manufacturer for example.
Oh, I was being way more demanding there. That was explicitly using sysclock/2 only. So the timings were tight even at low speed frequency. And that particular stress was also at high frequency, although I've forgotten exactly how fast now. Certainly beyond max freq spec for SD High Speed mode.
I had left it for a while before doing some small tidying and making sense of making the driver a plug-in instead of gluing the driver file into the includes as I had been previously.
On a tangent, I've half remade the smartpin's based SPI mode driver as a plug-in too. I'm attempting to strip out the use of smartpins entirely while still keeping the performance using optimised bit-bashing instead. The aim is to make it as small as possible ... and eventually replace the built-in driver.
I had left it for a while before doing some small tidying and making sense of making the driver a plug-in instead of gluing the driver file into the includes as I had been previously.
It'd be neat to not have to recompile flexspin to make use of this if could eventually be bundled in somehow. The include Readme file mentions you need to edit various source files included with Flex which would imply a recompile of flexspin too before this can be used.
@evanh said:
On a tangent, I've half remade the smartpin's based SPI mode driver as a plug-in too. I'm attempting to strip out the use of smartpins entirely while still keeping the performance using optimised bit-bashing instead. The aim is to make it as small as possible ... and eventually replace the built-in driver.
I'd forgotten how far I'd got with it. It works fine for all SD card except the two Sandisks ... they both get stuck not responding to the ACMD41 during init ...
And here's a comparison of good vs bad results:
Adata SD card first, with normal response:
Orange trace is CLK pin
Blue trace is MOSI pin (command to card)
Pink trace is MISO pin (response from card)
Now a Sandisk SD card with abnormal response:
It's actually responding with the same ack response as the normal response but it's three clocks late ... EDIT: And then it stops responding altogether ... so the card is definitely not happy with the situation ...
Well, the Sandisk's are happy now by adding an extra read byte after each prefixing CMD55. I can see there is a requirement for a spacer byte between a response and an adjoining command. And it seems Sandisk are the only ones adhering to that requirement.
At this stage I'm not sure why this hadn't been a problem in the smartpin's version of driver too.
EDIT: Oh, wow, I see. I'd been smart and shifted the order of deselect()/select() in the command sequence. I'd realised there wasn't a need to do that twice in the middle of an ACMD. But in the optimisation I'd wiped out all extra spacings as well.
Serves me right for doing a change in the middle of a retrofit ... now reverted back to how Eric had it.
@evanh said:
On a tangent, I've half remade the smartpin's based SPI mode driver as a plug-in too. I'm attempting to strip out the use of smartpins entirely while still keeping the performance using optimised bit-bashing instead. The aim is to make it as small as possible ... and eventually replace the built-in driver.
"small as possible"
Especially if it keeps the performance.
I also wonder if, with the new multitask feature, it'd make sense to have a cogged SD driver (because the task calling into the FS code can yield to other work). I feel like smartpin SPI handling locked to a reasonable(TM) rate like sysclk/10 would be able to fit into some other PASM cog as an interrupt handler (at /10 that's one interrupt every 320 cycles)
Can't say I've seen such behaviour. How are you obtaining that error code? Is it reading/writing/mounting? Sysclock frequency?
I also wonder if, with the new multitask feature, it'd make sense to have a cogged SD driver (because the task calling into the FS code can yield to other work). I feel like smartpin SPI handling locked to a reasonable(TM) rate like sysclk/10 would be able to fit into some other PASM cog as an interrupt handler (at /10 that's one interrupt every 320 cycles)
I'd be inclined to run the application code as managing the file buffers between multiple tasks. Then the filesystem and driver stay together under one task.
Can't say I've seen such behaviour. How are you obtaining that error code? Is it reading/writing/mounting? Sysclock frequency?
The usual 300-something MHz (happens regardless of 45MHz flag, so clock rate issue seems out of the picture). You can see the raw FatFS error codes if you define _DEBUG_FATFS. It does mount successfully, but it seems FatFS is lazy on this and only actually mounts on the volume when you run another function, so that's why the error comes from f_opendir or something.
@evanh said:
Time to ditch the old device open function and start using the new API.
>
Those are really the same thing - the errors ripple through. But there is no error code, the init just fails silently.
With _DEBUG_SDMM there's ty=12 when it (or any of the other cards) are working and ty=4 when it's broken.
Never seen a type 4 ... that's bizarre, it's failing the block-addressing check after detecting SDv2.
BTW: I've shrunk sdmm.cc driver by 556 bytes compiled.
EDIT: Added the demo. You can pull the driver and use it in your emulators. PS: The binary won't actually be smaller though, since the built-in driver doesn't get replaced.
EDIT2: Duh! That was wrong. The built-in driver is of course excluded when not used.
Comments
With the multi-issuing (per dot) of CMD10 it now consistently produces an error message on unusable rxlag values.
I've worked out that not all SD cards react the same to pin registration. Then the timing compensation causes lsb ordering mismatch. I'm not sure of best way to resolve. I've already improved the outcome by widening the min-max search of the calibration routine so that it still finds all good cases. But when using clock divider of 2 it can still end up picking the wrong value for rxlag.
I could reject the choice on basis that that value failed and select plus/minus one instead. Or I could try separating the pin registration step so that the search order isn't based on preconceived behaviour of the SD cards.
EDIT: Okay, it's really at the edge of that particular card's ability I think. ie: Not a Prop2 timing limitation. Older cards are sometimes slower unsurprisingly.
Amusingly, another SD card, the camera card, of the same brand but 6 years older is actually a faster card.
Well, I've simply made it subtract one for correcting rxlag when it hits the mis-ordered registration issue. The default choice was rounded up on halfway. So it now kind of rounds down for this exception.
I would imagine there is going to be quite a bit of variation in delay required amongst different cards at the same P2 clock freq and divider, which affects the rxlag value needed. As so many different types of cards have been released from different manufacturers there is unlikely to be some one size fits all value. Not going to be something like the PSRAM output timing from the same manufacturer for example.
Oh, I was being way more demanding there. That was explicitly using sysclock/2 only. So the timings were tight even at low speed frequency. And that particular stress was also at high frequency, although I've forgotten exactly how fast now. Certainly beyond max freq spec for SD High Speed mode.
Okay, I've finally posted an Obex for the driver - https://obex.parallax.com/obex/sdsd-cc/
I had left it for a while before doing some small tidying and making sense of making the driver a plug-in instead of gluing the driver file into the includes as I had been previously.
On a tangent, I've half remade the smartpin's based SPI mode driver as a plug-in too. I'm attempting to strip out the use of smartpins entirely while still keeping the performance using optimised bit-bashing instead. The aim is to make it as small as possible ... and eventually replace the built-in driver.
It'd be neat to not have to recompile flexspin to make use of this if could eventually be bundled in somehow. The include Readme file mentions you need to edit various source files included with Flex which would imply a recompile of flexspin too before this can be used.
That's the old method. Maybe I should just remove that text.
Yeah, if it's no longer valid.
done.
BTW: The speedtest demo does everything for you.
I'd forgotten how far I'd got with it. It works fine for all SD card except the two Sandisks ... they both get stuck not responding to the ACMD41 during init ...
And here's a comparison of good vs bad results:

Adata SD card first, with normal response:
Orange trace is CLK pin
Blue trace is MOSI pin (command to card)
Pink trace is MISO pin (response from card)
Now a Sandisk SD card with abnormal response:

It's actually responding with the same ack response as the normal response but it's three clocks late ... EDIT: And then it stops responding altogether ... so the card is definitely not happy with the situation ...
Well, the Sandisk's are happy now by adding an extra read byte after each prefixing CMD55. I can see there is a requirement for a spacer byte between a response and an adjoining command. And it seems Sandisk are the only ones adhering to that requirement.
At this stage I'm not sure why this hadn't been a problem in the smartpin's version of driver too.
EDIT: Oh, wow, I see. I'd been smart and shifted the order of deselect()/select() in the command sequence. I'd realised there wasn't a need to do that twice in the middle of an ACMD. But in the optimisation I'd wiped out all extra spacings as well.
Serves me right for doing a change in the middle of a retrofit ... now reverted back to how Eric had it.
"small as possible"
Especially if it keeps the performance.
Incidentially, I've been having a bug with the current built-in driver: https://github.com/totalspectrum/spin2cpp/issues/471 Any ideas?
I also wonder if, with the new multitask feature, it'd make sense to have a cogged SD driver (because the task calling into the FS code can yield to other work). I feel like smartpin SPI handling locked to a reasonable(TM) rate like sysclk/10 would be able to fit into some other PASM cog as an interrupt handler (at /10 that's one interrupt every 320 cycles)
Can't say I've seen such behaviour. How are you obtaining that error code? Is it reading/writing/mounting? Sysclock frequency?
I'd be inclined to run the application code as managing the file buffers between multiple tasks. Then the filesystem and driver stay together under one task.
The usual 300-something MHz (happens regardless of 45MHz flag, so clock rate issue seems out of the picture). You can see the raw FatFS error codes if you define
_DEBUG_FATFS
. It does mount successfully, but it seems FatFS is lazy on this and only actually mounts on the volume when you run another function, so that's why the error comes fromf_opendir
or something.Time to ditch the old device open function and start using the new API.
Where you have something like:
Replace it with:
And -D _DEBUG_SDMM for init reporting.
>
Those are really the same thing - the errors ripple through. But there is no error code, the init just fails silently.
With
_DEBUG_SDMM
there'sty=12
when it (or any of the other cards) are working andty=4
when it's broken.Never seen a type 4 ... that's bizarre, it's failing the block-addressing check after detecting SDv2.
BTW: I've shrunk sdmm.cc driver by 556 bytes compiled.
EDIT: Added the demo. You can pull the driver and use it in your emulators.
PS: The binary won't actually be smaller though, since the built-in driver doesn't get replaced.
EDIT2: Duh! That was wrong. The built-in driver is of course excluded when not used.
Remember, this is the same card, just re-loading the same program binary toggles between the states.
Give sdmm_bashed a try with that SD card.
EDIT: Oh, to quickly integrate in Spin2:
It's not a local malloc()'d object like it is in C but that's all I know off the cuff. I'd copied the C solution from how Eric had done it.
Same thing happens, same
type=4
.Okay, try this one. Now waiting on OCR bit31(card ready) to rise first before checking the CCS bit.
PS: I've renamed sdmm_bashed's open function to
_sdmm_open()
. Since it's the same parameters as the built driver, may as well use the same name.I'll have to try that tomorrow
@evanh nope same problem
Some added debug output reporting of CMD58 in particular. eg:
Good run:
(the f_open error is just a file-not-found because this card doesn't have PADMAP.TXT)
Bad run:
That's bizarre! It's literally reporting itself as a byte addressed card. I could just ignore it and assume all SDv2 cards are also block addressed.
Attached now ignores the CCS bit.
Still busted
Oh, so it's some sort of mode change then. Didn't even know that was possible.
Here's one that retries the init a few times to see if the mode can be toggled that way: