Skip to content

Commit 452ef17

Browse files
Replace ESP8266SdFat w/SdFat 2.3.0, SDIO, ExFAT (#2764)
* Replace ESP8266SdFat w/SdFat 2.3.0, add SDIO and ExFAT support Remove ESP8266SdFat fork and replaces with upstream SdFat to simplify maintenance. This 2.3.0 version adds SDIO support and enables exFAT support. Also upgraded FAT filename support to 256 chars, identical to LittleFS. * Add SDIO support to SD and SDFS, documentation, and examples * Update SD examples to all support SPI0, SPI1, or SDIO
1 parent 4785c16 commit 452ef17

File tree

16 files changed

+246
-85
lines changed

16 files changed

+246
-85
lines changed

.gitmodules

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
[submodule "libraries/LittleFS/lib/littlefs"]
1111
path = libraries/LittleFS/lib/littlefs
1212
url = https://github.com/littlefs-project/littlefs.git
13-
[submodule "libraries/SdFat"]
14-
path = libraries/ESP8266SdFat
15-
url = https://github.com/earlephilhower/ESP8266SdFat.git
1613
[submodule "libraries/Keyboard"]
1714
path = libraries/HID_Keyboard
1815
url = https://github.com/earlephilhower/Keyboard.git
@@ -49,3 +46,6 @@
4946
[submodule "libraries/ESPHost"]
5047
path = libraries/ESPHost
5148
url = https://github.com/Networking-for-Arduino/ESPHost.git
49+
[submodule "libraries/SdFat"]
50+
path = libraries/SdFat
51+
url = https://github.com/greiman/SdFat.git

docs/fs.rst

+17
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,23 @@ second SPI port, ``SPI1``. Just use the following call in place of
174174
175175
SD.begin(cspin, SPI1);
176176
177+
Enabling SDIO operation for SD
178+
------------------------------
179+
SDIO support is available thanks to SdFat implementing a PIO-based SDIO controller.
180+
This mode can significantly increase IO performance to SD cards but it requires that
181+
all 4 DAT0..DAT3 lines to be wired to the Pico (most SD breakout boards only provide
182+
1-but SPI mode of operation).
183+
184+
To enable SDIO mode, simply specify the SD_CLK, SD_CMD, and SD_DAT0 GPIO pins. The clock
185+
and command pins can be any GPIO (not limited to legal SPI pins). The DAT0 pin can be any
186+
GPIO with remaining DAT1...3 pins consecutively connected.
187+
188+
..code:: cpp
189+
190+
SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO);
191+
192+
No other changes are required in the application to take advantage of this high
193+
performance mode.
177194

178195
Using VFS (Virtual File System) for POSIX support
179196
-------------------------------------------------

libraries/ESP8266SdFat

-1
This file was deleted.

libraries/SD/examples/CardInfo/CardInfo.ino

+26-16
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ const int _MOSI = 7; // AKA SPI TX
3737
const int _CS = 5;
3838
const int _SCK = 6;
3939

40+
// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode
41+
const int RP_CLK_GPIO = -1; // Set to CLK GPIO
42+
const int RP_CMD_GPIO = -1; // Set to CMD GPIO
43+
const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected.
44+
4045
// include the SD library:
4146
#include <SPI.h>
4247
#include <SD.h>
@@ -54,21 +59,26 @@ void setup() {
5459
Serial.println("\nInitializing SD card...");
5560

5661
bool sdInitialized = false;
57-
// Ensure the SPI pinout the SD card is connected to is configured properly
58-
// Select the correct SPI based on _MISO pin for the RP2040
59-
if (_MISO == 0 || _MISO == 4 || _MISO == 16) {
60-
SPI.setRX(_MISO);
61-
SPI.setTX(_MOSI);
62-
SPI.setSCK(_SCK);
63-
sdInitialized = SD.begin(_CS);
64-
} else if (_MISO == 8 || _MISO == 12) {
65-
SPI1.setRX(_MISO);
66-
SPI1.setTX(_MOSI);
67-
SPI1.setSCK(_SCK);
68-
sdInitialized = SD.begin(_CS, SPI1);
62+
if (RP_CLK_GPIO >= 0) {
63+
// No special requirements on pin locations, this is PIO programmed
64+
sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO);
6965
} else {
70-
Serial.println(F("ERROR: Unknown SPI Configuration"));
71-
return;
66+
// Ensure the SPI pinout the SD card is connected to is configured properly
67+
// Select the correct SPI based on _MISO pin for the RP2040
68+
if (_MISO == 0 || _MISO == 4 || _MISO == 16) {
69+
SPI.setRX(_MISO);
70+
SPI.setTX(_MOSI);
71+
SPI.setSCK(_SCK);
72+
sdInitialized = SD.begin(_CS);
73+
} else if (_MISO == 8 || _MISO == 12) {
74+
SPI1.setRX(_MISO);
75+
SPI1.setTX(_MOSI);
76+
SPI1.setSCK(_SCK);
77+
sdInitialized = SD.begin(_CS, SPI1);
78+
} else {
79+
Serial.println(F("ERROR: Unknown SPI Configuration"));
80+
return;
81+
}
7282
}
7383

7484
if (!sdInitialized) {
@@ -114,7 +124,7 @@ void setup() {
114124
Serial.println();
115125

116126
// print the type and size of the first FAT-type volume
117-
uint32_t volumesize;
127+
uint64_t volumesize;
118128
Serial.print("Volume type is: FAT");
119129
Serial.println(SD.fatType(), DEC);
120130

@@ -130,7 +140,7 @@ void setup() {
130140
Serial.println((float)volumesize / 1024.0);
131141

132142
Serial.print("Card size: ");
133-
Serial.println((float)SD.size() / 1000);
143+
Serial.println((float)SD.size64() / 1000);
134144

135145
FSInfo fs_info;
136146
SDFS.info(fs_info);

libraries/SD/examples/Datalogger/Datalogger.ino

+28-5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ const int _MOSI = 7;
3030
const int _CS = 5;
3131
const int _SCK = 6;
3232

33+
// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode
34+
const int RP_CLK_GPIO = -1; // Set to CLK GPIO
35+
const int RP_CMD_GPIO = -1; // Set to CMD GPIO
36+
const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected.
37+
3338
#include <SPI.h>
3439
#include <SD.h>
3540

@@ -39,13 +44,31 @@ void setup() {
3944

4045
Serial.print("Initializing SD card...");
4146

42-
// Ensure the SPI pinout the SD card is connected to is configured properly
43-
SPI.setRX(_MISO);
44-
SPI.setTX(_MOSI);
45-
SPI.setSCK(_SCK);
47+
bool sdInitialized = false;
48+
if (RP_CLK_GPIO >= 0) {
49+
// No special requirements on pin locations, this is PIO programmed
50+
sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO);
51+
} else {
52+
// Ensure the SPI pinout the SD card is connected to is configured properly
53+
// Select the correct SPI based on _MISO pin for the RP2040
54+
if (_MISO == 0 || _MISO == 4 || _MISO == 16) {
55+
SPI.setRX(_MISO);
56+
SPI.setTX(_MOSI);
57+
SPI.setSCK(_SCK);
58+
sdInitialized = SD.begin(_CS);
59+
} else if (_MISO == 8 || _MISO == 12) {
60+
SPI1.setRX(_MISO);
61+
SPI1.setTX(_MOSI);
62+
SPI1.setSCK(_SCK);
63+
sdInitialized = SD.begin(_CS, SPI1);
64+
} else {
65+
Serial.println(F("ERROR: Unknown SPI Configuration"));
66+
return;
67+
}
68+
}
4669

4770
// see if the card is present and can be initialized:
48-
if (!SD.begin(_CS)) {
71+
if (!sdInitialized) {
4972
Serial.println("Card failed, or not present");
5073
// don't do anything more:
5174
return;

libraries/SD/examples/DumpFile/DumpFile.ino

+28-5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ const int _MOSI = 7;
3030
const int _CS = 5;
3131
const int _SCK = 6;
3232

33+
// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode
34+
const int RP_CLK_GPIO = -1; // Set to CLK GPIO
35+
const int RP_CMD_GPIO = -1; // Set to CMD GPIO
36+
const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected.
37+
3338
#include <SPI.h>
3439
#include <SD.h>
3540

@@ -39,13 +44,31 @@ void setup() {
3944

4045
Serial.print("Initializing SD card...");
4146

42-
// Ensure the SPI pinout the SD card is connected to is configured properly
43-
SPI.setRX(_MISO);
44-
SPI.setTX(_MOSI);
45-
SPI.setSCK(_SCK);
47+
bool sdInitialized = false;
48+
if (RP_CLK_GPIO >= 0) {
49+
// No special requirements on pin locations, this is PIO programmed
50+
sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO);
51+
} else {
52+
// Ensure the SPI pinout the SD card is connected to is configured properly
53+
// Select the correct SPI based on _MISO pin for the RP2040
54+
if (_MISO == 0 || _MISO == 4 || _MISO == 16) {
55+
SPI.setRX(_MISO);
56+
SPI.setTX(_MOSI);
57+
SPI.setSCK(_SCK);
58+
sdInitialized = SD.begin(_CS);
59+
} else if (_MISO == 8 || _MISO == 12) {
60+
SPI1.setRX(_MISO);
61+
SPI1.setTX(_MOSI);
62+
SPI1.setSCK(_SCK);
63+
sdInitialized = SD.begin(_CS, SPI1);
64+
} else {
65+
Serial.println(F("ERROR: Unknown SPI Configuration"));
66+
return;
67+
}
68+
}
4669

4770
// see if the card is present and can be initialized:
48-
if (!SD.begin(_CS)) {
71+
if (!sdInitialized) {
4972
Serial.println("Card failed, or not present");
5073
// don't do anything more:
5174
return;

libraries/SD/examples/Files/Files.ino

+28-5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ const int _MOSI = 7;
2828
const int _CS = 5;
2929
const int _SCK = 6;
3030

31+
// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode
32+
const int RP_CLK_GPIO = -1; // Set to CLK GPIO
33+
const int RP_CMD_GPIO = -1; // Set to CMD GPIO
34+
const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected.
35+
3136
#include <SPI.h>
3237
#include <SD.h>
3338

@@ -39,12 +44,30 @@ void setup() {
3944

4045
Serial.print("Initializing SD card...");
4146

42-
// Ensure the SPI pinout the SD card is connected to is configured properly
43-
SPI.setRX(_MISO);
44-
SPI.setTX(_MOSI);
45-
SPI.setSCK(_SCK);
47+
bool sdInitialized = false;
48+
if (RP_CLK_GPIO >= 0) {
49+
// No special requirements on pin locations, this is PIO programmed
50+
sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO);
51+
} else {
52+
// Ensure the SPI pinout the SD card is connected to is configured properly
53+
// Select the correct SPI based on _MISO pin for the RP2040
54+
if (_MISO == 0 || _MISO == 4 || _MISO == 16) {
55+
SPI.setRX(_MISO);
56+
SPI.setTX(_MOSI);
57+
SPI.setSCK(_SCK);
58+
sdInitialized = SD.begin(_CS);
59+
} else if (_MISO == 8 || _MISO == 12) {
60+
SPI1.setRX(_MISO);
61+
SPI1.setTX(_MOSI);
62+
SPI1.setSCK(_SCK);
63+
sdInitialized = SD.begin(_CS, SPI1);
64+
} else {
65+
Serial.println(F("ERROR: Unknown SPI Configuration"));
66+
return;
67+
}
68+
}
4669

47-
if (!SD.begin(_CS)) {
70+
if (!sdInitialized) {
4871
Serial.println("initialization failed!");
4972
return;
5073
}

libraries/SD/examples/ReadWrite/ReadWrite.ino

+28-5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ const int _MOSI = 7;
2828
const int _CS = 5;
2929
const int _SCK = 6;
3030

31+
// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode
32+
const int RP_CLK_GPIO = -1; // Set to CLK GPIO
33+
const int RP_CMD_GPIO = -1; // Set to CMD GPIO
34+
const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected.
35+
3136
#include <SPI.h>
3237
#include <SD.h>
3338

@@ -39,12 +44,30 @@ void setup() {
3944

4045
Serial.print("Initializing SD card...");
4146

42-
// Ensure the SPI pinout the SD card is connected to is configured properly
43-
SPI.setRX(_MISO);
44-
SPI.setTX(_MOSI);
45-
SPI.setSCK(_SCK);
47+
bool sdInitialized = false;
48+
if (RP_CLK_GPIO >= 0) {
49+
// No special requirements on pin locations, this is PIO programmed
50+
sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO);
51+
} else {
52+
// Ensure the SPI pinout the SD card is connected to is configured properly
53+
// Select the correct SPI based on _MISO pin for the RP2040
54+
if (_MISO == 0 || _MISO == 4 || _MISO == 16) {
55+
SPI.setRX(_MISO);
56+
SPI.setTX(_MOSI);
57+
SPI.setSCK(_SCK);
58+
sdInitialized = SD.begin(_CS);
59+
} else if (_MISO == 8 || _MISO == 12) {
60+
SPI1.setRX(_MISO);
61+
SPI1.setTX(_MOSI);
62+
SPI1.setSCK(_SCK);
63+
sdInitialized = SD.begin(_CS, SPI1);
64+
} else {
65+
Serial.println(F("ERROR: Unknown SPI Configuration"));
66+
return;
67+
}
68+
}
4669

47-
if (!SD.begin(_CS)) {
70+
if (!sdInitialized) {
4871
Serial.println("initialization failed!");
4972
return;
5073
}

libraries/SD/examples/listfiles/listfiles.ino

+24-14
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ const int _MOSI = 7; // AKA SPI TX
4242
const int _CS = 5;
4343
const int _SCK = 6;
4444

45+
// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode
46+
const int RP_CLK_GPIO = -1; // Set to CLK GPIO
47+
const int RP_CMD_GPIO = -1; // Set to CMD GPIO
48+
const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected.
49+
4550
#include <SPI.h>
4651
#include <SD.h>
4752

@@ -58,21 +63,26 @@ void setup() {
5863
Serial.println("\nInitializing SD card...");
5964

6065
bool sdInitialized = false;
61-
// Ensure the SPI pinout the SD card is connected to is configured properly
62-
// Select the correct SPI based on _MISO pin for the RP2040
63-
if (_MISO == 0 || _MISO == 4 || _MISO == 16) {
64-
SPI.setRX(_MISO);
65-
SPI.setTX(_MOSI);
66-
SPI.setSCK(_SCK);
67-
sdInitialized = SD.begin(_CS);
68-
} else if (_MISO == 8 || _MISO == 12) {
69-
SPI1.setRX(_MISO);
70-
SPI1.setTX(_MOSI);
71-
SPI1.setSCK(_SCK);
72-
sdInitialized = SD.begin(_CS, SPI1);
66+
if (RP_CLK_GPIO >= 0) {
67+
// No special requirements on pin locations, this is PIO programmed
68+
sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO);
7369
} else {
74-
Serial.println(F("ERROR: Unknown SPI Configuration"));
75-
return;
70+
// Ensure the SPI pinout the SD card is connected to is configured properly
71+
// Select the correct SPI based on _MISO pin for the RP2040
72+
if (_MISO == 0 || _MISO == 4 || _MISO == 16) {
73+
SPI.setRX(_MISO);
74+
SPI.setTX(_MOSI);
75+
SPI.setSCK(_SCK);
76+
sdInitialized = SD.begin(_CS);
77+
} else if (_MISO == 8 || _MISO == 12) {
78+
SPI1.setRX(_MISO);
79+
SPI1.setTX(_MOSI);
80+
SPI1.setSCK(_SCK);
81+
sdInitialized = SD.begin(_CS, SPI1);
82+
} else {
83+
Serial.println(F("ERROR: Unknown SPI Configuration"));
84+
return;
85+
}
7686
}
7787

7888
if (!sdInitialized) {

libraries/SD/src/SD.h

+6
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,17 @@ class SDClass {
3636
SDFS.setConfig(SDFSConfig(csPin, SPI_HALF_SPEED, spi));
3737
return SDFS.begin();
3838
}
39+
3940
bool begin(uint8_t csPin, uint32_t cfg = SPI_HALF_SPEED, HardwareSPI &spi = SPI) {
4041
SDFS.setConfig(SDFSConfig(csPin, cfg, spi));
4142
return SDFS.begin();
4243
}
4344

45+
bool begin(uint8_t clkPin, uint8_t cmdPin, uint8_t dat0Pin, uint32_t cfg = SD_SCK_MHZ(50)) {
46+
SDFS.setConfig(SDFSConfig(clkPin, cmdPin, dat0Pin, cfg));
47+
return SDFS.begin();
48+
}
49+
4450
void end(bool endSPI = true) {
4551
SDFS.end();
4652
if (endSPI && _spi) {

0 commit comments

Comments
 (0)