Getting SPI-based MicroSD card adapter working with Seed

Hi @jogawebb. I said that because I spent a lot of time stuck on a SD card not working on the Daisy Pod, but who was working fine with any computers … even if it was correctly formatted (FAT for windows).
I’m not a SD card expert but I know there’s some difference between a normal SD card (2GB) and SD card HC (16go). Also there’s something about High Speed, UHS-I, UHS-II, UHS-III …
Turns out that the classic SD card was never read by the Pod and the SDHC with UHS-III was totally fine.

Thanks for the heads up, the card I’m using is a 16gb SDHC with UHS-I, so maybe I’ll try swapping it out and see if it makes a difference.

I also tried checking against some test code with an arduino using the SPI interface, and that was able to read the card info just fine. I’m hoping it’s just something I’m overlooking :mag_right:

I previously stumbled across this edge case: f_mount returned FR_NOT_READY which means the card is mounted but hasn’t completed its internal initialisation yet. You could start using it but on the first actual card access you would see a little delay until the card is finally ready. (Check the docs for f_mount)

In my code I wasn’t handling this case. I only checked the mounting like this:

if (f_mount(...) != FR_OK) 
    // failure

Since the return value was FR_NOT_READY, it seemed as if the card failed to mount which simply wasn’t true.
I observed this behaviour with old card whereas newer cards were quick enough to directly return FR_OK.

Maybe in your case it’s something similar?

I’ve finally gotten around to giving the SDIO breakout board a try, and I’m having exactly the same problem of FR_NOT_READY returned by f_mount using what seems to be the same type of card that @jogawebb is describing (a 16GB SanDisk Ultra), which I was also able to read using Arduino/SPI. I don’t have any “newer cards”; @TheSlowGrowth , can you suggest a specific card that has worked for you? Thanks!

BTW, I put the f_mount in a loop with a delay. It never gets to FR_OK, so the SDIO reader is currently non-operational for me.

Did you try reading and writing to the card? It may just be that f_mount never checks for card readiness again after the initial successful mounting.

Edit: did you probe the data lines yet? Does the card respond to any commands at all?
You could also step through the fatfs code to see where exactly it fails.

Yes, the SDMMC example that I’m trying does an fopen for write and then for read. Both fail. Based on your comment, I stepped into the fopen with the debugger, and could see that it fails on

if (fmt == 4) return FR_DISK_ERR;		/* An error occured in the disk I/O layer */

in find_volume(). It looks to me like the mount has succeeded, but the routine fails on trying to load sector 0. Probing data lines is something I’ve not yet learned to do, and I’d have no idea what to look for.

Have you gotten these read/write operations to work with a card of this type? I’d be happy to order and try a different card type if you can give me a suggestion. Thanks.

@Elby It sounds like we’re having a pretty similar experience. I checked for FR_NOT_READY and, sure enough, that’s what was happening. I also added a long delay to give the card some more time, but I haven’t gotten successful read/write to happen yet.

Reading back over this thread, I see one comment from @YMNK that indicates that UHS-3 might be the key (rather than the UHS-1 that you and I are using @jogawebb ). This looks like it might do the trick: https://smile.amazon.com/SanDisk-Endurance-microSDHC-Adapter-Monitoring/dp/B07P14QHB7/ref=sr_1_5?crid=1T4O0IB1SABAH&dchild=1&keywords=micro%2Bsd%2Bcard%2B32gb%2Buhs%2B3&qid=1631651555&sr=8-5&th=1. If I don’t hear otherwise, I can order in the next 6 hours and have it by Thursday. I’ll report on results here.

1 Like

I’ve just ordered the SD slot on my side on the Adafruit website. I will be able to give it a test next week!

I can’t say much to SPI access to a MicroSD card, but if you are using the SDIO peripheral, and trying to get it to work on a breadboard, you’re likely running into an issue with the GPIO drive strength. I mentioned it a while back in a github issue.

Try changing these two assignments: here and here to GPIO_SPEED_FREQ_LOW and see if things work better.

If it helps, I’ll make a PR which maps the GPIO drive strength, to the clock frequency as I suggested in that comment.

Unfortunately, @recursinging , that doesn’t seem to make a difference, at least for me. I’d like to suggest that someone else having this problem try it as well, and validate what I’m finding. I changed the mount statement in SDMCC test code to:

FRESULT res = FR_NOT_READY;
while(res != FR_OK)
    {
        res = f_mount(&SDFatFS, SDPath, 1);
        hw.PrintLine("Mount result: %d", res);
        System::Delay(1000);
    }

The first mount prints FR_NOT_READY (3), and then all subsequent mounts print FR_DISK_ERR (4). This happens exactly the same with both GPIO_SPEED_FREQ_LOW and with GPIO_SPEED_FREQ_VERY_HIGH. Neither case reads or writes successfully.

Hmm… Did you try configuring the peripheral with different clock speeds as well?

No, I hadn’t, and that is, indeed, the fix!! Thanks SO much!! For others that are struggling with this, here’s the block of code in SDMMC that I modified:

// Init SD Card
    SdmmcHandler::Config sd_cfg;
    sd_cfg.Defaults();
    sd_cfg.speed = SdmmcHandler::Speed::SLOW;
    sd.Init(sd_cfg);

That’s in addition to the changes to scmmc.cpp that @recursinging suggested.

2 Likes

Great, I’m glad it’s working for you.

Just to clarify what’s going on (at least as I’ve come to understand it), the GPIO_SPEED_FREQ_* configuration affects the “slew rate” of the GPIO signalling. The faster the GPIO speed, the lower the slew rate of the signal, and the sharper the edges.

Sharp signal edges can cause ringing, or oscillations after signal transitions at the resonant frequency of the parasitic capacitance and inductance of the circuit.

A breadboard, and jumper wires have more parasitic capacitance and inductance than a well designed PCB trace, which is why the default configuration of the SDIO peripheral works fine on the Pod, Patch, Petal, and Field, but not so well on a breadboard (or in my case, a not so well designed PCB trace).

You can counteract this by adding some small inline resistance to the signals paths. If you’re curious, give it a try, and you may be able to get the peripheral working at higher clock speeds.

2 Likes

Just to add to this: place the inline resistance (try 20 - 200 Ohms) at the driving side of the signal lines.

If you imagine the wire as a capacitor, you want this inline resistance to limit the current that this capacitor is charged with in order to reduce the ringing.

1 Like

Thanks for the explanation, @recursinging. For my application, higher speeds aren’t needed, what I really need is more flash. After getting my test code running, I added FatFS to my real code and was 5KB over limit. Guess I need to go back to trying to figure out why my QSPI-based patch storage scheme very occasionally wipes clean. :frowning:

Keep an eye on this PR, when it’s merged, there will be more program space available.

Until then, if you’re close to the 128k limit, try compiling with -0s - it might reduce the size just enough.

The slower speed and the addition of some 20 Ohm resistors seems to have remedied the problem for me, as well. Thanks!

1 Like

Hi everyone.
I had no issue with my Pod and no issue with my breadboard too!
The troubles came when I added the SD card reader with daisy on a protoboard. Changing the GPIO speed did the trick.
I should try to add some 20R on the way too!

Hello all…

I just wanted to report that as of this post, January 2023, the above mentioned changes regarding SDIO speed set to low appear to still be necessary to make a seed board use the Adafruit SDIO SDMicro breakout card also mentioned in this thread.

3 Likes