3333
3434#if MICROPY_HW_ENABLE_SDCARD
3535
36+ #if SOC_SDMMC_HOST_SUPPORTED
3637#include "driver/sdmmc_host.h"
38+ #endif
3739#include "driver/sdspi_host.h"
3840#include "sdmmc_cmd.h"
3941#include "esp_log.h"
@@ -69,18 +71,34 @@ typedef struct _sdcard_obj_t {
6971
7072#define _SECTOR_SIZE (self ) (self->card.csd.sector_size)
7173
74+ // Number SPI buses available for firmware app (including for SD)
75+ #define NUM_SD_SPI_BUS (SOC_SPI_PERIPH_NUM - 1)
76+
77+ #if CONFIG_IDF_TARGET_ESP32
78+ #define SD_SLOT_MIN 1
79+ #elif SOC_SDMMC_HOST_SUPPORTED
80+ #define SD_SLOT_MIN 0
81+ #else
82+ #define SD_SLOT_MIN 2
83+ #endif
84+ #define SD_SLOT_MAX (NUM_SD_SPI_BUS + 1) // Inclusive
85+
7286// SPI bus default bus and device configuration.
7387
74- static const spi_bus_config_t spi_bus_defaults [2 ] = {
88+ static const spi_bus_config_t spi_bus_defaults [NUM_SD_SPI_BUS ] = {
7589 {
7690 #if CONFIG_IDF_TARGET_ESP32
7791 .miso_io_num = GPIO_NUM_19 ,
7892 .mosi_io_num = GPIO_NUM_23 ,
7993 .sclk_io_num = GPIO_NUM_18 ,
80- #else
94+ #elif CONFIG_IDF_TARGET_ESP32S3
8195 .miso_io_num = GPIO_NUM_36 ,
8296 .mosi_io_num = GPIO_NUM_35 ,
8397 .sclk_io_num = GPIO_NUM_37 ,
98+ #else
99+ .miso_io_num = GPIO_NUM_NC ,
100+ .mosi_io_num = GPIO_NUM_NC ,
101+ .sclk_io_num = GPIO_NUM_NC ,
84102 #endif
85103 .data2_io_num = GPIO_NUM_NC ,
86104 .data3_io_num = GPIO_NUM_NC ,
@@ -92,6 +110,7 @@ static const spi_bus_config_t spi_bus_defaults[2] = {
92110 .flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_MOSI ,
93111 .intr_flags = 0 ,
94112 },
113+ #if NUM_SD_SPI_BUS > 1
95114 {
96115 .miso_io_num = GPIO_NUM_2 ,
97116 .mosi_io_num = GPIO_NUM_15 ,
@@ -106,28 +125,34 @@ static const spi_bus_config_t spi_bus_defaults[2] = {
106125 .flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_MOSI ,
107126 .intr_flags = 0 ,
108127 },
128+ #endif
109129};
110130
111131#if CONFIG_IDF_TARGET_ESP32
112- static const uint8_t spi_dma_channel_defaults [2 ] = {
132+ static const uint8_t spi_dma_channel_defaults [NUM_SD_SPI_BUS ] = {
113133 2 ,
114134 1 ,
115135};
116136#endif
117137
118- static const sdspi_device_config_t spi_dev_defaults [2 ] = {
138+ static const sdspi_device_config_t spi_dev_defaults [NUM_SD_SPI_BUS ] = {
139+ #if NUM_SD_SPI_BUS > 1
119140 {
120141 #if CONFIG_IDF_TARGET_ESP32
121142 .host_id = VSPI_HOST ,
122143 .gpio_cs = GPIO_NUM_5 ,
123- #else
144+ #elif CONFIG_IDF_TARGET_ESP32S3
124145 .host_id = SPI3_HOST ,
125146 .gpio_cs = GPIO_NUM_34 ,
147+ #else
148+ .host_id = SPI3_HOST ,
149+ .gpio_cs = GPIO_NUM_NC ,
126150 #endif
127151 .gpio_cd = SDSPI_SLOT_NO_CD ,
128152 .gpio_wp = SDSPI_SLOT_NO_WP ,
129153 .gpio_int = SDSPI_SLOT_NO_INT ,
130154 },
155+ #endif
131156 SDSPI_DEVICE_CONFIG_DEFAULT (), // HSPI (ESP32) / SPI2 (ESP32S3)
132157};
133158
@@ -159,12 +184,15 @@ static esp_err_t sdcard_ensure_card_init(sdcard_card_obj_t *self, bool force) {
159184// Expose the SD card or MMC as an object with the block protocol.
160185
161186// Create a new SDCard object
162- // The driver supports either the host SD/MMC controller (default) or SPI mode
163- // In both cases there are two "slots". Slot 0 on the SD/MMC controller is
164- // typically tied up with the flash interface in most ESP32 modules but in
165- // theory supports 1, 4 or 8-bit transfers. Slot 1 supports only 1 and 4-bit
166- // transfers. Only 1-bit is supported on the SPI interfaces.
167- // card = SDCard(slot=1, width=None, present_pin=None, wp_pin=None)
187+ //
188+ // SD/MMC or SPI mode is determined by the slot argument
189+ // 0,1 is SD/MMC mode where supported.
190+ // 2,3 is SPI mode where supported (1-bit only)
191+ //
192+ // Original ESP32 can't use 0
193+ // ESP32-C3/C6/etc can only use 2 (only one SPI bus, no SD/MMC controller)
194+ //
195+ // Consult machine.SDCard docs for more details.
168196
169197static mp_obj_t machine_sdcard_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
170198 // check arguments
@@ -183,8 +211,13 @@ static mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
183211 #endif
184212 ARG_freq ,
185213 };
214+ #if SOC_SDMMC_HOST_SUPPORTED
215+ static const int DEFAULT_SLOT = 1 ;
216+ #else
217+ static const int DEFAULT_SLOT = SD_SLOT_MAX ;
218+ #endif
186219 static const mp_arg_t allowed_args [] = {
187- { MP_QSTR_slot , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 1 } },
220+ { MP_QSTR_slot , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = DEFAULT_SLOT } },
188221 { MP_QSTR_width , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 1 } },
189222 { MP_QSTR_cd , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } },
190223 { MP_QSTR_wp , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } },
@@ -226,22 +259,35 @@ static mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
226259 #endif
227260
228261 int slot_num = arg_vals [ARG_slot ].u_int ;
229- if (slot_num < 0 || slot_num > 3 ) {
230- mp_raise_ValueError (MP_ERROR_TEXT ("slot number must be between 0 and 3 inclusive " ));
262+ if (slot_num < SD_SLOT_MIN || slot_num > SD_SLOT_MAX ) {
263+ mp_raise_ValueError (MP_ERROR_TEXT ("invalid slot number" ));
231264 }
232265
266+ #if SOC_SDMMC_HOST_SUPPORTED
233267 // Slots 0 and 1 are native SD/MMC, slots 2 and 3 are SPI
234268 bool is_spi = (slot_num >= 2 );
269+ #else
270+ bool is_spi = true;
271+ #endif
235272 if (is_spi ) {
236273 slot_num -= 2 ;
274+ assert (slot_num < NUM_SD_SPI_BUS );
237275 }
276+
238277 // Verify valid argument combinations
239278 #if SOC_SDMMC_USE_GPIO_MATRIX
240279 if (is_spi && (arg_vals [ARG_cmd ].u_obj != mp_const_none
241280 || arg_vals [ARG_data ].u_obj != mp_const_none )) {
242281 mp_raise_ValueError (MP_ERROR_TEXT ("invalid config: SPI slot with SDMMC pin arguments" ));
243282 }
244283 #endif
284+ #if SOC_SDMMC_HOST_SUPPORTED
285+ if (!is_spi && (arg_vals [ARG_miso ].u_obj != mp_const_none
286+ || arg_vals [ARG_mosi ].u_obj != mp_const_none
287+ || arg_vals [ARG_cs ].u_obj != mp_const_none )) {
288+ mp_raise_ValueError (MP_ERROR_TEXT ("invalid config: SDMMC slot with SPI pin arguments" ));
289+ }
290+ #endif
245291
246292 DEBUG_printf (" Setting up host configuration" );
247293
@@ -253,21 +299,17 @@ static mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
253299 if (is_spi ) {
254300 sdmmc_host_t _temp_host = SDSPI_HOST_DEFAULT ();
255301 _temp_host .max_freq_khz = freq / 1000 ;
302+ // SPI SDMMC sets the slot to the SPI host ID
303+ _temp_host .slot = spi_dev_defaults [slot_num ].host_id ;
256304 self -> host = _temp_host ;
257- } else {
305+ }
306+ #if SOC_SDMMC_HOST_SUPPORTED
307+ else {
258308 sdmmc_host_t _temp_host = SDMMC_HOST_DEFAULT ();
259309 _temp_host .max_freq_khz = freq / 1000 ;
260310 self -> host = _temp_host ;
261311 }
262-
263- if (is_spi ) {
264- // Needs to match spi_dev_defaults above.
265- #if CONFIG_IDF_TARGET_ESP32
266- self -> host .slot = slot_num ? HSPI_HOST : VSPI_HOST ;
267- #else
268- self -> host .slot = slot_num ? SPI2_HOST : SPI3_HOST ;
269- #endif
270- }
312+ #endif
271313
272314 DEBUG_printf (" Calling host.init()" );
273315
@@ -294,6 +336,15 @@ static mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
294336 SET_CONFIG_PIN (dev_config , gpio_cd , ARG_cd );
295337 SET_CONFIG_PIN (dev_config , gpio_wp , ARG_wp );
296338
339+ // On chips other than original ESP32 and S3, there are not
340+ // always default SPI pins assigned
341+ if (dev_config .gpio_cs == GPIO_NUM_NC
342+ || bus_config .miso_io_num == GPIO_NUM_NC
343+ || bus_config .mosi_io_num == GPIO_NUM_NC
344+ || bus_config .sclk_io_num == GPIO_NUM_NC ) {
345+ mp_raise_ValueError (MP_ERROR_TEXT ("SPI pin values required" ));
346+ }
347+
297348 DEBUG_printf (" Calling spi_bus_initialize()" );
298349 check_esp_err (spi_bus_initialize (spi_host_id , & bus_config , dma_channel ));
299350
@@ -309,7 +360,9 @@ static mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
309360 spi_bus_free (spi_host_id );
310361 mp_raise_ValueError (MP_ERROR_TEXT ("SPI bus already in use" ));
311362 }
312- } else {
363+ }
364+ #if SOC_SDMMC_HOST_SUPPORTED
365+ else {
313366 // SD/MMC interface
314367 DEBUG_printf (" Setting up SDMMC slot configuration" );
315368 sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT ();
@@ -357,6 +410,7 @@ static mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
357410 DEBUG_printf (" Calling init_slot()" );
358411 check_esp_err (sdmmc_host_init_slot (self -> host .slot , & slot_config ));
359412 }
413+ #endif // SOC_SDMMC_HOST_SUPPORTED
360414
361415 DEBUG_printf (" Returning new card object: %p" , self );
362416 return MP_OBJ_FROM_PTR (self );
0 commit comments