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
286 stars 48 forks source link

The 5V Arduino SD modules might work with a simple trick #83

Open iCMDdev opened 1 year ago

iCMDdev commented 1 year ago

Hi,

I believe blue 5V Arduino SD modules work with 3v3 devices with a simple trick. These feature a 74LVC125A and an AMS1117 3v3 LDO. If you bypass the LDO (connect the 3v3 supply to the ldo's 3v3 pin), the module seems to work fine.

Though, of course, modules designed for 3v3 could be better suited, especially those from known brands.

If the resistors are used as dividers, everything should work fine as long as the 74LVC125A's inputs are above 2V when high.

carlk3 commented 1 year ago

Ah, so you're bypassing the LDO to avoid the dropout?

I'm working on developing my own Pico oriented SD card board; something that could go right on the Pico, perhaps in a "hat"-like stackable design like this RTC module: pico-rtc-ds3231-1_4 (https://www.waveshare.com/wiki/Pico-RTC-DS3231)

There are so many possible configurations. Since these could be pretty small (no need to be a full-size "hat"), and JLCPCB's lowest prices go up to 100mm x 100mm, I'm thinking of designing a "panelized" board containing a few different configurations. That would help keep costs down since one board from JLCPCB would contain multiple units of the SD card board.

One module I'm considering would be arranged like this: Pico GPIO Function
GP2 CLK/SCK
GP3 CMD/COPI (or Peripheral's SDI)
GP4 DATA 0/CIPO (or Peripheral's SDO)
GP5 DATA 1
GP6 DATA 2
GP7 DATA 3/CS
GP9 Card Detect

which would be useable on SPI0 or with SDIO.

If mounted directly on the Pico, it should be capable of very high speeds.

iCMDdev commented 1 year ago

Nice idea! So one ordered PCB will actually contain multiple SD modules (in order to cut costs), and you're going to split them yourself, right?

And yes, I tried the bypass trick (basically directly supplying 3.3v from the Pico) since I had one of those modules around :)

carlk3 commented 1 year ago

Nice idea! So one ordered PCB will actually contain multiple SD modules (in order to cut costs), and you're going to split them yourself, right?

Yes, like this: image Not only to cut costs, but to have more than one configuration. Another dual use (SPI & SDIO) configuration could be:

GPIO Pico Pin Function SPI SPI signal SDIO
GP10   CLK/SCK SCLK SPI1_SCK CLK
GP11   CMD/COPI (or Peripheral's SDI) MOSI SPI1_TX CMD
GP12   DATA 0/CIPO (or Peripheral's SDO) MISO SPI1_RX D0
GP13   DATA 1     D1
GP14   DATA 2     D2
GP15   DATA 3/CS SS (or "CS")   D3
GP9?   Card Detect      

I'm also thinking of some minimal small boards for, say, SPI only, or even 1-bit SDIO (which no-OS-FatFS-SD-SPI-RPi-Pico does not yet support, but there is the old pico_sd_card implementation). For short boards, getting to the 3V3 pin is a problem unless you're up at the USB end of the Pico. But, that could be solved with a jumper. SDIO can be moved around more easily than SPI. I need to look at how the Pico-W is laid out.

And yes, I tried the bypass trick (basically directly supplying 3.3v from the Pico) since I had one of those modules around :)

Maybe you could take a photo?

iCMDdev commented 1 year ago

Maybe you could take a photo?

Yes, it's just a simple jumper soldered to the LDO's 3.3v, which is then connected to the Pico: sd-module The other pins are connected as usual, and the Vcc pin is unused. Edit: you can also make a solder bridge between the Vin and Vout pins of the LDO and everything should work fine.

Edit: note that it would be good to add a diode to prevent reverse polarity current from going through the AMS1117., or simply removing it completely. Otherwise, the ldo can get damaged. Moreover, it seems that the device's inputs and outputs are 3.3v-safe (but that needs to be tested), since the whole SD card circuit is powered by 3v. If that's the case, you could also power the module from Vin (with 5V) instead of connecting that jumper,

I need to look at how the Pico-W is laid out.

I think the pinout is similar, if not the same (except the LED is connected to the WiFi module and the SWD pins' position has changed).

I like your ideas. Good luck with this project!

By the way (maybe I should open another issue for this?), is there any easy way to check whether the SPI bus is in use by the SD card? For example, when you want to use an SD card and another SPI device on the same bus, you would want to check whether the DMA transfer has finished before switching the CS pin and sending data to the other device (to avoid race conditions). I took a quick at your library's internals, and perhaps I could use the SD object's mutex attribute and the mutex_try_enter() SDK function like this: mutex_try_enter(&sd_init_driver(0)->mutex)?

carlk3 commented 1 year ago

Maybe you could take a photo?

Yes, it's just a simple jumper soldered to the LDO's 3.3v, which is then connected to the Pico: ... The other pins are connected as usual, and the Vcc pin is unused.

Thanks. That might be worth adding to the README.

... By the way (maybe I should open another issue for this?), is there any easy way to check whether the SPI bus is in use by the SD card? For example, when you want to use an SD card and another SPI device on the same bus, you would want to check whether the DMA transfer has finished before switching the CS pin and sending data to the other device (to avoid race conditions). I took a quick at your library's internals, and perhaps I could use the SD object's mutex attribute and the mutex_try_enter() SDK function like this: mutex_try_enter(&sd_init_driver(0)->mutex)?

At the low level, there is dma_channel_is_busy(spi_p->rx_dma). But, the mutex protects whole transactions against interruption, so that is probably a better approach. Maybe you could add another higher-level mutex to control access to the SPI bus itself. The library's mutex was designed to keep multiple threads using the library from interfering with one another.

EDIT: Also, take heed of ChaN's Cosideration on Multi-slave Configuration.

iCMDdev commented 1 year ago

Maybe you could take a photo?

Yes, it's just a simple jumper soldered to the LDO's 3.3v, which is then connected to the Pico: ... The other pins are connected as usual, and the Vcc pin is unused.

Thanks. That might be worth adding to the README.

Yes, sure.

By the way (maybe I should open another issue for this?), is there any easy way to check whether the SPI bus is in use by the SD card? For example, when you want to use an SD card and another SPI device on the same bus, you would want to check whether the DMA transfer has finished before switching the CS pin and sending data to the other device (to avoid race conditions). I took a quick at your library's internals, and perhaps I could use the SD object's mutex attribute and the mutex_try_enter() SDK function like this: mutex_try_enter(&sd_init_driver(0)->mutex)?

At the low level, there is dma_channel_is_busy(spi_p->rx_dma). But, the mutex protects whole transactions against interruption, so that is probably a better approach. Maybe you could add another higher-level mutex to control access to the SPI bus itself. The library's mutex was designed to keep multiple threads using the library from interfering with one another.

EDIT: Also, take heed of ChaN's Cosideration on Multi-slave Configuration.

Alright, thanks! I've noticed that spi_t also has a mutex attribute. Maybe I could use this one instead, or the DMA function (provided that everything else within the library happens on the main thread).

carlk3 commented 1 year ago

I've noticed that spi_t also has a mutex attribute. Maybe I could use this one instead.

Right, the library supports multiple SD cards per SPI as well as multiple SPIs. An SD card can only do one thing at a time, and an SPI bus can only do one thing at a time. But, where possible (e.g., two cards are on separate buses [whether SPI or SDIO], multiple SD cards should be able to work in parallel.

On Thu, Aug 31, 2023 at 1:28 PM CMD @.***> wrote:

Maybe you could take a photo?

Yes, it's just a simple jumper soldered to the LDO's 3.3v, which is then connected to the Pico: ... The other pins are connected as usual, and the Vcc pin is unused.

Thanks. That might be worth adding to the README.

Yes, sure.

By the way (maybe I should open another issue for this?), is there any easy way to check whether the SPI bus is in use by the SD card? For example, when you want to use an SD card and another SPI device on the same bus, you would want to check whether the DMA transfer has finished before switching the CS pin and sending data to the other device (to avoid race conditions). I took a quick at your library's internals, and perhaps I could use the SD object's mutex attribute and the mutex_try_enter() SDK function like this: mutex_try_enter(&sd_init_driver(0)->mutex)?

At the low level, there is dma_channel_is_busy(spi_p->rx_dma). But, the mutex protects whole transactions against interruption, so that is probably a better approach. Maybe you could add another higher-level mutex to control access to the SPI bus itself. The library's mutex was designed to keep multiple threads using the library from interfering with one another.

EDIT: Also, take heed of ChaN's Cosideration on Multi-slave Configuration http://elm-chan.org/docs/mmc/mmc_e.html#spibus.

Alright, thanks! I've noticed that spi_t also has a mutex attribute. Maybe I could use this one instead.

— Reply to this email directly, view it on GitHub https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico/issues/83#issuecomment-1701665444, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL6MY4JHXH4IQG3DQBNLAMDXYDQVLANCNFSM6AAAAAA4EIWAWA . You are receiving this because you commented.Message ID: @.***>