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

A FAT filesystem with SDIO and SPI drivers for SD card on Raspberry Pi Pico
Apache License 2.0
76 stars 15 forks source link

Need help with Waveshare 2.8inch Display for Pi Pico pin configuration of its onboard SD card #40

Open dkts2000 opened 1 month ago

dkts2000 commented 1 month ago

Hi I am trying to understand how to configure the pins on the Waveshare 2.8inch Display Module for Raspberry Pi Pico to access the onboard SD card using your driver (SDIO).

The Pinout Definition of the board is:

image

In the /simple_sdio example if i set .CMD_gpio = 18, .D0_gpio = 19,

the CLK_gpio will become 17 (CLK_gpio = D0_gpio -2.) whereas it should be 5 (if i understand correctly)

Can you give me a hint on the configuration? Thanks!

carlk3 commented 1 month ago

Unfortunately, you'll have to modify the PIO code. (The Pico SDK doesn't provide a way to pass in the offset; I wish it did.)

You need SDIO_CLK offset from D0 by -14, which is 18 in mod32 arithmetic. (19 + 18) % 32 = 5

In rp2040_sdio.pio you'll need to change this line: .define PUBLIC SDIO_CLK_PIN_D0_OFFSET 30 ; (-2 in mod32 arithmetic) to something like

.define PUBLIC SDIO_CLK_PIN_D0_OFFSET 18    ; (-14 in mod32 arithmetic)
dkts2000 commented 1 month ago

Thanks i ll give it a try!

I also tried the /simple example that comes with your library (using spi) and the following pin configuration

/* Configuration of RP2040 hardware SPI object */
static spi_t spi = {  
    .hw_inst = spi0,  // RP2040 SPI component  ------  (i also tried spi1)
    .sck_gpio = 5,    // GPIO number (not Pico pin number)
    .mosi_gpio = 18,
    .miso_gpio = 19,
    .baud_rate = 12 * 1000 * 1000   // Actual frequency: 10416666.
};

/* SPI Interface */
static sd_spi_if_t spi_if = {
    .spi = &spi,  // Pointer to the SPI driving this card
    .ss_gpio = 22      // The SPI slave select GPIO for this SD card
};

I always get the message "The physical drive cannot work" in a loop, without actually being in a loop in code.

The only way i can get the sd card to initialize and read its contents successfully is by using the driver that Waveshare has in its site that combines sd card and lcd driver. https://files.waveshare.com/upload/f/fc/Pico-ResTouch-LCD-X_X_Code.zip

I would like to use a separate lcd driver (that gives frame buffer capabilities from here) and your library to access the sd card but i am stuck.

carlk3 commented 1 month ago

Have a look at Appendix E: Troubleshooting. I would start by compiling with USE_DBG_PRINTF and cutting the baud rate in half.

carlk3 commented 1 month ago

Also, I think there is a problem with your pin assignments if you want to use SPI0. image

/* Configuration of RP2040 hardware SPI object */
static spi_t spi = {  
    .hw_inst = spi0,  // RP2040 SPI component  ------  (i also tried spi1)
    .sck_gpio = 5,    // GPIO number (not Pico pin number)
    .mosi_gpio = 18,
    .miso_gpio = 19,
    .baud_rate = 12 * 1000 * 1000   // Actual frequency: 10416666.
};

/* SPI Interface */
static sd_spi_if_t spi_if = {
    .spi = &spi,  // Pointer to the SPI driving this card
    .ss_gpio = 22      // The SPI slave select GPIO for this SD card
};

I'm not sure what you could use for MISO (SPI0 RX). Do you have a schematic for the Waveshare board?

dkts2000 commented 1 month ago

I must have messed up every single aspect of it!!! Thanks for the clarifications.

from the pin configuration of waveshare's driver:

#define LCD_RST_PIN     15  
#define LCD_DC_PIN      8
#define LCD_CS_PIN      9
#define LCD_CLK_PIN     10
#define LCD_BKL_PIN     13
#define LCD_MOSI_PIN    11
#define LCD_MISO_PIN    12
#define TP_CS_PIN       16
#define TP_IRQ_PIN      17
#define SD_CS_PIN       22

#define SPI_PORT        spi1

i thought that gpios that have LCD_ are for lcd use only

The schematic for this board is here

carlk3 commented 1 month ago

It looks like there are some provisions for running the microSD on SPI: image What position are your jumpers in?

carlk3 commented 1 month ago

Your only choices for SPI0 RX (MISO) are GP4 or GP16. GP16 appears to be assigned to TP_CS. So, you'll need to use GP4 for miso_gpio. Somehow, you'll have to route GPIO4 to SD_SDO". Maybe you can pop off the 0Ω resistor on H3 and run a jumper to GPIO4. Or use SDIO instead of SPI (but then you might have to move all of the 0Ω resistors on the A B headers).

dkts2000 commented 1 month ago

I 'll check the jumpers later, when i get back.

edit: i checked and its spi as in picture

edit2: digging in python driver provided by waveshare i saw this:

# Max baudrate produced by Pico is 31_250_000. ST7789 datasheet allows <= 62.5MHz.
# Note non-standard MISO pin. This works, verified by SD card.
spi = SPI(1, 60_000_000, sck=Pin(10), mosi=Pin(11), miso=Pin(12))

# Optional use of SD card. Requires official driver. In my testing the
# 31.25MHz baudrate works. Other SD cards may have different ideas.
from sdcard import SDCard
import os
sd = SDCard(spi, Pin(22, Pin.OUT), 30_000_000)

so i tried this:

/* Configuration of RP2040 hardware SPI object */
static spi_t spi = {  
    .hw_inst = spi1,  // RP2040 SPI component
    .sck_gpio = 10,    // GPIO number (not Pico pin number)
    .mosi_gpio = 11,
    .miso_gpio = 12,
    .baud_rate = 12 * 1000 * 1000   // Actual frequency: 10416666.
};

/* SPI Interface */
static sd_spi_if_t spi_if = {
    .spi = &spi,  // Pointer to the SPI driving this card
    .ss_gpio = 22      // The SPI slave select GPIO for this SD card
};

the result is a looping message: CRC error CMD:0 response 0x98

but when i remove the sd card and reinsert it i get this:

CRC error CMD:0 response 0x98                                                   
CRC error CMD:0 response 0x98                                                   
CRC error CMD:0 response 0x98                                                   
CRC error CMD:0 response 0x98                                                   
sd_spi_go_low_frequency: Actual frequency: 398089                               
V2-Version Card                                                                 
R3/R7: 0x1aa                                                                    
R3/R7: 0xff8000                                                                 
Illegal command CMD:41 response 0x37                                            
CRC error CMD:41 response 0x3f                                                  
CRC error CMD:41 response 0x3f                                                  
CRC error CMD:41 response 0x3f                                                  
CRC error CMD:41 response 0x3f  

edit3: i added the library to drive the lcd and when i remove and reinsert the sd card i get

*** PANIC ***

f_mount error: The physical drive sd_spi_go_low_frequency: Actual frequency: 398089
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
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
No response CMD:41
No response CMD:58
No response CMD:58
No response CMD:58
No response CMD:58 response: 0xff
SD card initialized
sd_spi_go_high_frequency: Actual frequency: 10416666
No response CMD:9
No response CMD:9
No response CMD:9
No response CMD:9 response: 0xff
Didn't get a response from the disk

*** PANIC ***

i don't understand why the pico resets continually. The good thing is that the card is initialized but this state is not stable.

santolucito commented 1 month ago

My pico (wavshare 0.96 with adafruit sdio sd readers) was also in a boot loop when trying to connect to the SD cards (I have 2 connected). Setting PICO_XOSC_STARTUP_DELAY_MULTIPLIER to 64 fixed it for me. No idea if it is the same situation for you but might be worth a try.

carlk3 commented 1 month ago

Usually when you're getting CRC errors, the baud rate is too high. As a test, you can set the baud rate quite low; e.g.:

.baud_rate = 1000000

I often do this so I can use a $10 logic analyzer to watch the SPI bus. It will be slow, but it should work.

Note: The actual baud rate will be the peripheral clock frequency (_CLKPERI ) divided by an even number. For example, 125000000 / 128 = 976562. (See 4.4.2.3. Clock prescaler in RP2040 Datasheet).

carlk3 commented 1 month ago

i don't understand why the pico resets continually.

Nor do I. How do you know it is doing that?

There are 10 retries in in_sd_go_idle_state. There are also 3 retries in sd_cmd. Could that be what you're referring to? Sometimes it takes a several retries to get a card to Idle state if it was left in some indeterminate state (e.g., if you're running a program under the debugger and restart while the card is in the middle of some operation).