carlk3 / no-OS-FatFS-SD-SPI-RPi-Pico

A FAT filesystem with SPI driver for SD card on Raspberry Pi Pico
Apache License 2.0
282 stars 48 forks source link

Use with Adafruit Micro SD SPI/SDIO Karten Breakout Board (3V) #69

Closed niansa closed 1 year ago

niansa commented 1 year ago

Hey!

I've got this breakout board: https://web.archive.org/web/20230720155359id_/https://i.ebayimg.com/images/g/t5UAAOSwaQ5h8n5M/s-l1600.jpg

I was able to map the pins from the readme, at least it looks similar:

However I'd like to know if this actually makes sense before testing this and melting my SD card or whatever 😁

Also I am a tiny bit worried because it says "3V power and logic ONLY", however the Picos output is 3.3V, will that difference matter?

carlk3 commented 1 year ago

That looks like the like the Adafruit Micro SD SPI or SDIO Card Breakout Board. That should work fine. I've used it many times. The only thing that sucks about that board, or socket, is that the card detect switch doesn't work very well at all.

Your pin mapping is suspect, however. It should be like this: MicroSD contacts

Pin Number Pin Name In SD Mode In SPI Mode
1 DAT2/X Connector Data line 2 No use
2 DAT3/CS Connector Data line 3 Chip Select
3 CMD/DI Command / Response Line Data Input
4 VDD/VDD Power supply (+3.3V) Power supply (+3.3V)
5 CLK/SCLK Clock Serial Clock
6 VSS/VSS Ground Ground
7 DAT0/D0 Connector Data line 0 Data Out
8 DAT1/X Connector Data line 1 No use

If you're using the SPI interface, D1 and D2 are unused.

For the Pico's SPI0, that would be: Function Old SPI name Signal name
DATA 3/CS SS any 
DATA 2    
DATA 1    
DATA 0/CIPO (or Peripheral's SDO) MISO SPI0_RX
Card Detect   any
CLK/SCK SCLK SPI0_SCK
CMD/COPI (or Peripheral's SDI) MOSI SPI0_TX

Card Detect and Chip Select (i.e., Slave Select) can be on any arbitrary GPIOs.

niansa commented 1 year ago

Thank you very much for the table

However, on mine I can't find a "CMD/DI" pin (only "CMD/SI") and "DAT0/D0" seems to me "D0/SO" for me? I can't figure out what MISO would map to at all. as well as some of the other pins you've listed.

You can look at the picture I've sent in the initial post to see what pins I have.

I figured it out! Just took me a bit to really understand the tables 😄

I think it'd be a good idea to add this to the README or at least reference this issue so people with the same board can figure it out more easily 😄

carlk3 commented 1 year ago

I'll look at adding something to the README.

Yeah, SPI and SD nomenclature is a mess. It doesn't help that the powers that be have proclaimed that certain words in the original names shall not be uttered, so existing documentation is a confusing mix of old and new terms, with the new ones being less understandable. https://www.oshwa.org/a-resolution-to-redefine-spi-signal-names/

niansa commented 1 year ago

I've wired it up like this now:

But it doesn't seem to work with the example:

sd_spi_go_low_frequency: Actual frequency: 398089
V2-Version Card
R3/R7: 0x1aa
R3/R7: 0xff8000
No response CMD:41
No response CMD:41
No response CMD:41
No response CMD:41 response: 0xff
...
No response CMD:41
No response CMD:41
No response CMD:41
No response CMD:41 response: 0xff
Timeout waiting for card
Failed to initialize card
f_mount error: The physical drive cannot work (3)
carlk3 commented 1 year ago

Which branch are you on (master, dev, sdio, dev_sdio)? Are you using a hw_config.c? If so, what's in it?

When you say

S0 -> 16 CS -> 17 CLK -> 18 SI -> 19 3V -> 3v3 GND -> GND

I assume you are talking GP numbers (RP2040 pin numbers), not Pico pin numbers, right?

image

It looks like you are getting some response from the card. If it's not responding to ACMD41, the card apparently hasn't successfully completed initialization. One common reason for that is poor electrical connections, especially ground connections. If you have a voltmeter, see what you're getting between the GND and 3V terminals on the Adafruit 4682, preferably while initialization is attempting to run. Sticking a big honking decoupling capacitor across those pins sometimes helps.

niansa commented 1 year ago

I am on the master branch, with this exact hw_config: https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico/blob/master/example/hw_config.c I'm running the example unmodified.

What values should the capacitor between the GND and 3V pins on the Adafruit 4682 have? I'm quite new to this topic and am probably going to be doing it wrong if I just guess.

Voltage between GND and 3V pins on Adafruit 4682 is fully stable at 3.25 V.

carlk3 commented 1 year ago

What values should the capacitor between the GND and 3V pins on the Adafruit 4682 have? I'm quite new to this topic and am probably going to be doing it wrong if I just guess.

Actually, the Adafruit 4682 already includes 0.1 uF and 10 uF decoupling capacitors: image so it shouldn't be necessary, but it wouldn't hurt to add a 1 uF or something.

Voltage between GND and 3V pins on Adafruit 4682 is fully stable at 3.25 V.

That should be fine. Do you have another SD card that you could try (preferably another brand)?

niansa commented 1 year ago

Not currently (bought a pack of identical ones back then, all of them behave the same). Looking for one right now. Is there a known-good brand? Tested the 32 GB sandisk ultra one.

carlk3 commented 1 year ago

I've used the SanDisk 16GB microSDHC UHS-I Memory Card a lot. Some others I've used include PNY 16GB Elite Class 10 U1 microSDHC Flash Memory Card, and Silicon Power 3D NAND 32GB MicroSD Card .

I still think it must be an electrical issue, and some cards might be more sensitive to it than others. Do you have access to an oscilloscope? If so, are the signals (especially CLK) at the pins on the Adafruit 4682 clean and square? These SD cards that are capable of running at very high speeds are necessarily sensitive to very short transients.

You could try reducing the drive strength. For example, in hw_config.c:

static spi_t spis[] = {  // One for each SPI.
    {
        .hw_inst = spi0,  // SPI component

        .set_drive_strength = true,
        .mosi_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA,
        .sck_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA,
//...
static sd_card_t sd_cards[] = {  // One for each SD card
    {  
        .pcName = "0:",  // Name used to mount device

        .set_drive_strength = true,
        .ss_gpio_drive_strength = GPIO_DRIVE_STRENGTH_2MA,
//...

The choices are

    GPIO_DRIVE_STRENGTH_2MA = 0, ///< 2 mA nominal drive strength
    GPIO_DRIVE_STRENGTH_4MA = 1, ///< 4 mA nominal drive strength
    GPIO_DRIVE_STRENGTH_8MA = 2, ///< 8 mA nominal drive strength
    GPIO_DRIVE_STRENGTH_12MA = 3 ///< 12 mA nominal drive strength

and the default is 4mA. 2mA seems to be strong enough to run reliably at 25 MHz (with short wires), and it results in less noise.

Another thing you could try is to add series terminating resistors on CLK, SI, and CS, at the Adafruit 4682 terminals. 25 Ω, 47 Ω, or even up to 100 Ω would probably result in cleaner signals. You'd need the oscilloscope to tell, but if you're doing it blind, I'd start with 25ish Ω.

niansa commented 1 year ago

I have tested 2mA drive strength, however it didn't change anything. Can you recommend me a cheap oscilloscope that is just enough to do this kind of stuff? I got a huge bag full of resistors, I'll try to find the ones you suggested and report back my findings.

niansa commented 1 year ago

Okay this bag is mostly filled with ancient 1k+ Ω resistors. I'll get an oscilloscope first (pretty sure it'll be useful for future projects as well) and then order the appropriate resistors.

niansa commented 1 year ago

Here's a photo of my wiring. Note that the wires are currently soldered directly to the pico, for test purposes.

niansa commented 1 year ago

Wellll it turns out I didn't solder the gnd pin on the sd card breakout correctly. I messed around with it, accidentally fused it with the neighboring pin twice, burnt myself but it works now!

sd_spi_go_low_frequency: Actual frequency: 398089
V2-Version Card
R3/R7: 0x1aa
R3/R7: 0xff8000
R3/R7: 0xc0ff8000
Card Initialized: High Capacity Card
SD card initialized
SDHC/SDXC Card: hc_c_size: 60872
Sectors: 62333952
Capacity:    30436 MB
sd_spi_go_high_frequency: Actual frequency: 12500000
carlk3 commented 1 year ago

Glad you got it working! It's amazing how important a good ground is.

Re: oscilloscopes: I'm currently using an Owon VDS1022I, but I'd like to get something with more bandwidth. I have a new PCB with an SD card socket on it, and I was surprised to find that it won't run at 20 MHz, even though my hand-wired prototype did. It will only go up to 12 Mhz or so. Unfortunately, a 25 MHz 'scope is not really adequate for seeing what's going on at 20 MHz.

niansa commented 1 year ago

hmm, thank you