Skip to content

Commit 67e2647

Browse files
committed
Add SDIO support for RP2040/RP2350
1 parent 052d38e commit 67e2647

File tree

99 files changed

+4281
-1529
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+4281
-1529
lines changed

README.md

+62
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,65 @@
1+
### Warning: This version has major internal changes.
2+
3+
SdFat version 2.3.0 has major changes to implement RP2040/RP2350 SDIO.
4+
5+
In addition there are number of bug fixes.
6+
7+
Begin by running the Rp2040SdioSetup example to try RP2040/RP2350 SDIO.
8+
9+
This example requires a SDIO Card socket with the following six lines.
10+
11+
CLK - A clock signal sent to the card by the MCU.
12+
CMD - A bidirectional line for for commands and responses.
13+
DAT[0:3] - Four bidirectional lines for data transfer.
14+
15+
CLK and CMD can be connected to any GPIO pins. DAT[0:3] can be connected
16+
to any four consecutive GPIO pins in the order DAT0, DAT1, DAT2, DAT3.
17+
18+
Here is an example of SDIO for Pico using an Adafruit socket, PiCowbell
19+
Proto and PiCowbell Proto Doubler.
20+
21+
![Alt text](images/SdioSpi.jpg)
22+
23+
This Socket supports SDIO with:
24+
```
25+
#define RP_CLK_GPIO 10
26+
#define RP_CMD_GPIO 11
27+
#define RP_DAT0_GPIO 12 // DAT1: GPIO13 DAT2: GPIO14, DAT3: GPIO15.
28+
```
29+
It also can be used on SPI1 with:
30+
```
31+
const uint8_t SD_CS_PIN = 15;
32+
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK, &SPI1)
33+
34+
// In setup
35+
SPI1.setSCK(10);
36+
SPI1.setTX(11);
37+
SPI1.setRX(12);
38+
```
39+
40+
This setup gets the following result in the bench example using SDIO.
41+
42+
<pre>
43+
FILE_SIZE_MB = 5
44+
BUF_SIZE = 512 bytes
45+
Starting write test, please wait.
46+
47+
write speed and latency
48+
speed,max,min,avg
49+
KB/Sec,usec,usec,usec
50+
15014.05,1165,32,32
51+
15289.54,1249,32,32
52+
53+
Starting read test, please wait.
54+
55+
read speed and latency
56+
speed,max,min,avg
57+
KB/Sec,usec,usec,usec
58+
15624.00,58,32,32
59+
15624.00,51,32,32
60+
</pre>
61+
62+
163
File copy constructors and file assignment operators have been made private by
264
default in 2.2.3 to prevent call by value and multiple copies of file instances.
365

doc/Doxyfile

+181-68
Large diffs are not rendered by default.

doc/SdErrorCodes.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
2022-07-01
1+
2025-01-01
22

33
Run the SdErrorCode example to produce an updated list.
44

@@ -12,7 +12,7 @@ Code,Symbol - failed operation
1212
0X06,SD_CARD_ERROR_CMD8 - Send and check interface settings
1313
0X07,SD_CARD_ERROR_CMD9 - Read CSD data
1414
0X08,SD_CARD_ERROR_CMD10 - Read CID data
15-
0X09,SD_CARD_ERROR_CMD12 - Stop multiple block read
15+
0X09,SD_CARD_ERROR_CMD12 - Stop multiple block transmission
1616
0X0A,SD_CARD_ERROR_CMD13 - Read card status
1717
0X0B,SD_CARD_ERROR_CMD17 - Read single block
1818
0X0C,SD_CARD_ERROR_CMD18 - Read multiple blocks

doc/html.zip

50.3 KB
Binary file not shown.

examples/AvrAdcLogger/AvrAdcLogger.ino

+1-2
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@
2020
*/
2121
#ifdef __AVR__
2222
#include <SPI.h>
23-
23+
#include "SdFat.h"
2424
#include "AvrAdcLogger.h"
2525
#include "BufferedPrint.h"
2626
#include "FreeStack.h"
27-
#include "SdFat.h"
2827

2928
// Save SRAM if 328.
3029
#ifdef __AVR_ATmega328P__

examples/BufferedPrint/BufferedPrint.ino

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// Test and benchmark of the fast bufferedPrint class.
22
//
33
// Mainly for AVR but may improve print performance with other CPUs.
4-
#include "BufferedPrint.h"
4+
#define DISABLE_FS_H_WARNING // Disable warning for type File not defined.
55
#include "SdFat.h"
6-
6+
#include "BufferedPrint.h"
77
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
88
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
99
#define SD_FAT_TYPE 3
@@ -28,13 +28,16 @@ const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
2828
#define SPI_CLOCK SD_SCK_MHZ(50)
2929

3030
// Try to select the best SD card configuration.
31-
#if HAS_SDIO_CLASS
31+
#if defined(HAS_TEENSY_SDIO)
3232
#define SD_CONFIG SdioConfig(FIFO_SDIO)
33+
#elif defined(RP_CLK_GPIO) && defined(RP_CMD_GPIO) && defined(RP_DAT0_GPIO)
34+
// See the Rp2040SdioSetup example for RP2040/RP2350 boards.
35+
#define SD_CONFIG SdioConfig(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO)
3336
#elif ENABLE_DEDICATED_SPI
3437
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
35-
#else // HAS_SDIO_CLASS
38+
#else // HAS_TEENSY_SDIO
3639
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
37-
#endif // HAS_SDIO_CLASS
40+
#endif // HAS_TEENSY_SDIO
3841

3942
#if SD_FAT_TYPE == 0
4043
SdFat sd;

examples/DirectoryFunctions/DirectoryFunctions.ino

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* Example use of chdir(), ls(), mkdir(), and rmdir().
33
*/
4+
#define DISABLE_FS_H_WARNING // Disable warning for type File not defined.
45
#include "SdFat.h"
56
#include "sdios.h"
67

@@ -28,13 +29,16 @@ const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
2829
#define SPI_CLOCK SD_SCK_MHZ(50)
2930

3031
// Try to select the best SD card configuration.
31-
#if HAS_SDIO_CLASS
32+
#if defined(HAS_TEENSY_SDIO)
3233
#define SD_CONFIG SdioConfig(FIFO_SDIO)
34+
#elif defined(RP_CLK_GPIO) && defined(RP_CMD_GPIO) && defined(RP_DAT0_GPIO)
35+
// See the Rp2040SdioSetup example for RP2040/RP2350 boards.
36+
#define SD_CONFIG SdioConfig(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO)
3337
#elif ENABLE_DEDICATED_SPI
3438
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
35-
#else // HAS_SDIO_CLASS
39+
#else // HAS_TEENSY_SDIO
3640
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
37-
#endif // HAS_SDIO_CLASS
41+
#endif // HAS_TEENSY_SDIO
3842
//------------------------------------------------------------------------------
3943

4044
#if SD_FAT_TYPE == 0

examples/ExFatLogger/ExFatLogger.ino

+9-5
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
//
44
// The maximum data rate will depend on the quality of your SD,
55
// the size of the FIFO, and using dedicated SPI.
6+
#define DISABLE_FS_H_WARNING // Disable warning for type File not defined.
7+
#include "SdFat.h"
68
#include "ExFatLogger.h"
79
#include "FreeStack.h"
8-
#include "SdFat.h"
910
//------------------------------------------------------------------------------
1011
// This example was designed for exFAT but will support FAT16/FAT32.
1112
// Note: Uno will not support SD_FAT_TYPE = 3.
@@ -69,13 +70,16 @@ const uint32_t PREALLOCATE_SIZE_MiB = 1024UL;
6970
#define SPI_CLOCK SD_SCK_MHZ(50)
7071

7172
// Try to select the best SD card configuration.
72-
#if HAS_SDIO_CLASS
73+
#if defined(HAS_TEENSY_SDIO)
7374
#define SD_CONFIG SdioConfig(FIFO_SDIO)
75+
#elif defined(RP_CLK_GPIO) && defined(RP_CMD_GPIO) && defined(RP_DAT0_GPIO)
76+
// See the Rp2040SdioSetup example for RP2040/RP2350 boards.
77+
#define SD_CONFIG SdioConfig(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO)
7478
#elif ENABLE_DEDICATED_SPI
7579
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
76-
#else // HAS_SDIO_CLASS
80+
#else // HAS_TEENSY_SDIO
7781
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
78-
#endif // HAS_SDIO_CLASS
82+
#endif // HAS_TEENSY_SDIO
7983

8084
// Save SRAM if 328.
8185
#ifdef __AVR_ATmega328P__
@@ -92,7 +96,7 @@ void logRecord(data_t* data, uint16_t overrun) {
9296
data->adc[0] = 0X8000 | overrun;
9397
} else {
9498
for (size_t i = 0; i < ADC_COUNT; i++) {
95-
data->adc[i] = analogRead(i);
99+
data->adc[i] = analogRead(A0 + i);
96100
}
97101
}
98102
}

examples/OpenNext/OpenNext.ino

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* Print size, modify date/time, and name for all files in root.
33
*/
4+
#define DISABLE_FS_H_WARNING // Disable warning for type File not defined.
45
#include "SdFat.h"
56

67
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
@@ -27,13 +28,16 @@ const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
2728
#define SPI_CLOCK SD_SCK_MHZ(50)
2829

2930
// Try to select the best SD card configuration.
30-
#if HAS_SDIO_CLASS
31+
#if defined(HAS_TEENSY_SDIO)
3132
#define SD_CONFIG SdioConfig(FIFO_SDIO)
33+
#elif defined(RP_CLK_GPIO) && defined(RP_CMD_GPIO) && defined(RP_DAT0_GPIO)
34+
// See the Rp2040SdioSetup example for RP2040/RP2350 boards.
35+
#define SD_CONFIG SdioConfig(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO)
3236
#elif ENABLE_DEDICATED_SPI
3337
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
34-
#else // HAS_SDIO_CLASS
38+
#else // HAS_TEENSY_SDIO
3539
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
36-
#endif // HAS_SDIO_CLASS
40+
#endif // HAS_TEENSY_SDIO
3741

3842
#if SD_FAT_TYPE == 0
3943
SdFat sd;

examples/ReadCsvFile/ReadCsvFile.ino

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#define DISABLE_FS_H_WARNING // Disable warning for type File not defined.
12
#include "SdFat.h"
23

34
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
@@ -24,13 +25,16 @@ const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
2425
#define SPI_CLOCK SD_SCK_MHZ(50)
2526

2627
// Try to select the best SD card configuration.
27-
#if HAS_SDIO_CLASS
28+
#if defined(HAS_TEENSY_SDIO)
2829
#define SD_CONFIG SdioConfig(FIFO_SDIO)
30+
#elif defined(RP_CLK_GPIO) && defined(RP_CMD_GPIO) && defined(RP_DAT0_GPIO)
31+
// See the Rp2040SdioSetup example for RP2040/RP2350 boards.
32+
#define SD_CONFIG SdioConfig(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO)
2933
#elif ENABLE_DEDICATED_SPI
3034
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
31-
#else // HAS_SDIO_CLASS
35+
#else // HAS_TEENSY_SDIO
3236
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
33-
#endif // HAS_SDIO_CLASS
37+
#endif // HAS_TEENSY_SDIO
3438

3539
#if SD_FAT_TYPE == 0
3640
SdFat sd;
@@ -126,7 +130,7 @@ void setup() {
126130
if (!file.open("ReadCsvDemo.csv", FILE_WRITE)) {
127131
error("open failed");
128132
}
129-
// Write test data.
133+
// Write test data. Test missing CRLF on last line.
130134
file.print(
131135
F("abc,123,456,7.89\r\n"
132136
"def,-321,654,-9.87\r\n"
@@ -143,6 +147,10 @@ void setup() {
143147
if (line[n - 1] != '\n' && n == (sizeof(line) - 1)) {
144148
error("line too long");
145149
}
150+
if (line[n - 1] == '\n') {
151+
// Remove new line.
152+
line[n -1] = 0;
153+
}
146154
if (!parseLine(line)) {
147155
error("parseLine failed");
148156
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// RP2040 PIO SDIO setup and test.
2+
/*
3+
This example requires a SDIO Card socket with the following six lines.
4+
5+
CLK - A clock signal sent to the card by the MCU.
6+
CMD - A bidirectional line for for commands and responses.
7+
DAT[0:3] - Four bidirectional lines for data transfer.
8+
9+
CLK and CMD can be connected to any GPIO pins. DAT[0:3] can be connected
10+
to any four consecutive GPIO pins in the order DAT0, DAT1, DAT2, DAT3.
11+
12+
For testing, I use several RP2040/RP3350 boards.
13+
The Adafruit Metro RP2040 which has a builtin SDIO socket.
14+
15+
https://learn.adafruit.com/adafruit-metro-rp2040
16+
17+
I use this SD socket breakout board for other boards.
18+
19+
https://learn.adafruit.com/adafruit-microsd-spi-sdio
20+
21+
Wires should be short since signals can be as faster than 50 MHz.
22+
*/
23+
#define DISABLE_FS_H_WARNING // Disable warning for type File not defined.
24+
#include "SdFat.h"
25+
//------------------------------------------------------------------------------
26+
// Example GPIO definitions I use for debug. Edit for your setup.
27+
// Run this example as is to print the symbol for your variant.
28+
//
29+
#if defined(ARDUINO_ADAFRUIT_METRO_RP2040)
30+
#define RP_CLK_GPIO 18
31+
#define RP_CMD_GPIO 19
32+
#define RP_DAT0_GPIO 20 // DAT1: GPIO21, DAT2: GPIO22, DAT3: GPIO23.
33+
#elif defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_2)
34+
#define RP_CLK_GPIO 16
35+
#define RP_CMD_GPIO 17
36+
#define RP_DAT0_GPIO 18 // DAT1: GPIO19, DAT2: GPIO20, DAT3: GPIO21.
37+
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2350_HSTX)
38+
#define RP_CLK_GPIO 11
39+
#define RP_CMD_GPIO 10
40+
#define RP_DAT0_GPIO 22 // DAT1: GPIO23, DAT2: GPIO24, DAT3: GPIO25.
41+
#endif // defined(ARDUINO_ADAFRUIT_METRO_RP2040))
42+
43+
#if defined(RP_CLK_GPIO) && defined(RP_CMD_GPIO) && defined(RP_DAT0_GPIO)
44+
#define SD_CONFIG SdioConfig(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO)
45+
#else // defined(RP_CLK_GPIO) && defined(RP_CMD_GPIO) && defined(RP_DAT0_GPIO)
46+
#warning "Undefined SD_CONFIG. Run this program for the Variant Symbol."
47+
#endif // defined(RP_CLK_GPIO) && defined(RP_CMD_GPIO) && defined(RP_DAT0_GPIO)
48+
//------------------------------------------------------------------------------
49+
// Class File is not defined by SdFat since the RP2040 system defines it.
50+
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
51+
#define SD_FAT_TYPE 3
52+
53+
#if SD_FAT_TYPE == 1
54+
SdFat32 sd;
55+
File32 file;
56+
#elif SD_FAT_TYPE == 2
57+
SdExFat sd;
58+
ExFile file;
59+
#elif SD_FAT_TYPE == 3
60+
SdFs sd;
61+
FsFile file;
62+
#else // SD_FAT_TYPE
63+
#error Invalid SD_FAT_TYPE
64+
#endif // SD_FAT_TYPE
65+
66+
void setup() {
67+
Serial.begin(9600);
68+
while (!Serial) {
69+
yield();
70+
}
71+
Serial.println("Type any character to start\n");
72+
while (!Serial.available()) {
73+
yield();
74+
}
75+
Serial.print("Variant Symbol: ");
76+
Serial.print("ARDUINO_");
77+
Serial.println(BOARD_NAME);
78+
Serial.println();
79+
#if defined(SD_CONFIG)
80+
if (!sd.begin(SD_CONFIG)) {
81+
sd.initErrorHalt(&Serial);
82+
}
83+
Serial.println("Card successfully initialized.");
84+
Serial.println("\nls:");
85+
sd.ls(LS_A | LS_DATE | LS_SIZE); // Add LS_R for recursive list.
86+
Serial.println("\nDone! Try the bench example next.");
87+
#else // #if defined(SD_CONFIG)
88+
Serial.println("Error: SD_CONFIG undefined for your board.");
89+
Serial.println("Define RP_CLK_GPIO, RP_CMD_GPIO, and RP_DAT0_GPIO above.");
90+
#endif
91+
}
92+
93+
void loop() {}

examples/RtcTimestampTest/RtcTimestampTest.ino

+6-3
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,16 @@ const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
3535
#define SPI_CLOCK SD_SCK_MHZ(50)
3636

3737
// Try to select the best SD card configuration.
38-
#if HAS_SDIO_CLASS
38+
#if defined(HAS_TEENSY_SDIO)
3939
#define SD_CONFIG SdioConfig(FIFO_SDIO)
40+
#elif defined(RP_CLK_GPIO) && defined(RP_CMD_GPIO) && defined(RP_DAT0_GPIO)
41+
// See the Rp2040SdioSetup example for RP2040/RP2350 boards.
42+
#define SD_CONFIG SdioConfig(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO)
4043
#elif ENABLE_DEDICATED_SPI
4144
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
42-
#else // HAS_SDIO_CLASS
45+
#else // HAS_TEENSY_SDIO
4346
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
44-
#endif // HAS_SDIO_CLASS
47+
#endif // HAS_TEENSY_SDIO
4548

4649
#if SD_FAT_TYPE == 0
4750
SdFat sd;

0 commit comments

Comments
 (0)