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

Diff for: 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

Diff for: doc/Doxyfile

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

Diff for: 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

Diff for: doc/html.zip

50.3 KB
Binary file not shown.

Diff for: 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__

Diff for: 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;

Diff for: 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

Diff for: 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
}

Diff for: 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;

Diff for: 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
}

Diff for: examples/Rp2040SdioSetup/Rp2040SdioSetup.ino

+93
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() {}

Diff for: 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)