33
33
34
34
#if MICROPY_HW_ENABLE_SDCARD
35
35
36
+ #if SOC_SDMMC_HOST_SUPPORTED
36
37
#include "driver/sdmmc_host.h"
38
+ #endif
37
39
#include "driver/sdspi_host.h"
38
40
#include "sdmmc_cmd.h"
39
41
#include "esp_log.h"
@@ -69,18 +71,34 @@ typedef struct _sdcard_obj_t {
69
71
70
72
#define _SECTOR_SIZE (self ) (self->card.csd.sector_size)
71
73
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
+
72
86
// SPI bus default bus and device configuration.
73
87
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 ] = {
75
89
{
76
90
#if CONFIG_IDF_TARGET_ESP32
77
91
.miso_io_num = GPIO_NUM_19 ,
78
92
.mosi_io_num = GPIO_NUM_23 ,
79
93
.sclk_io_num = GPIO_NUM_18 ,
80
- #else
94
+ #elif CONFIG_IDF_TARGET_ESP32S3
81
95
.miso_io_num = GPIO_NUM_36 ,
82
96
.mosi_io_num = GPIO_NUM_35 ,
83
97
.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 ,
84
102
#endif
85
103
.data2_io_num = GPIO_NUM_NC ,
86
104
.data3_io_num = GPIO_NUM_NC ,
@@ -92,6 +110,7 @@ static const spi_bus_config_t spi_bus_defaults[2] = {
92
110
.flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_MOSI ,
93
111
.intr_flags = 0 ,
94
112
},
113
+ #if NUM_SD_SPI_BUS > 1
95
114
{
96
115
.miso_io_num = GPIO_NUM_2 ,
97
116
.mosi_io_num = GPIO_NUM_15 ,
@@ -106,28 +125,34 @@ static const spi_bus_config_t spi_bus_defaults[2] = {
106
125
.flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_MOSI ,
107
126
.intr_flags = 0 ,
108
127
},
128
+ #endif
109
129
};
110
130
111
131
#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 ] = {
113
133
2 ,
114
134
1 ,
115
135
};
116
136
#endif
117
137
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
119
140
{
120
141
#if CONFIG_IDF_TARGET_ESP32
121
142
.host_id = VSPI_HOST ,
122
143
.gpio_cs = GPIO_NUM_5 ,
123
- #else
144
+ #elif CONFIG_IDF_TARGET_ESP32S3
124
145
.host_id = SPI3_HOST ,
125
146
.gpio_cs = GPIO_NUM_34 ,
147
+ #else
148
+ .host_id = SPI3_HOST ,
149
+ .gpio_cs = GPIO_NUM_NC ,
126
150
#endif
127
151
.gpio_cd = SDSPI_SLOT_NO_CD ,
128
152
.gpio_wp = SDSPI_SLOT_NO_WP ,
129
153
.gpio_int = SDSPI_SLOT_NO_INT ,
130
154
},
155
+ #endif
131
156
SDSPI_DEVICE_CONFIG_DEFAULT (), // HSPI (ESP32) / SPI2 (ESP32S3)
132
157
};
133
158
@@ -159,12 +184,15 @@ static esp_err_t sdcard_ensure_card_init(sdcard_card_obj_t *self, bool force) {
159
184
// Expose the SD card or MMC as an object with the block protocol.
160
185
161
186
// 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.
168
196
169
197
static 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 ) {
170
198
// check arguments
@@ -183,8 +211,13 @@ static mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
183
211
#endif
184
212
ARG_freq ,
185
213
};
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
186
219
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 } },
188
221
{ MP_QSTR_width , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 1 } },
189
222
{ MP_QSTR_cd , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } },
190
223
{ 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
226
259
#endif
227
260
228
261
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" ));
231
264
}
232
265
266
+ #if SOC_SDMMC_HOST_SUPPORTED
233
267
// Slots 0 and 1 are native SD/MMC, slots 2 and 3 are SPI
234
268
bool is_spi = (slot_num >= 2 );
269
+ #else
270
+ bool is_spi = true;
271
+ #endif
235
272
if (is_spi ) {
236
273
slot_num -= 2 ;
274
+ assert (slot_num < NUM_SD_SPI_BUS );
237
275
}
276
+
238
277
// Verify valid argument combinations
239
278
#if SOC_SDMMC_USE_GPIO_MATRIX
240
279
if (is_spi && (arg_vals [ARG_cmd ].u_obj != mp_const_none
241
280
|| arg_vals [ARG_data ].u_obj != mp_const_none )) {
242
281
mp_raise_ValueError (MP_ERROR_TEXT ("invalid config: SPI slot with SDMMC pin arguments" ));
243
282
}
244
283
#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
245
291
246
292
DEBUG_printf (" Setting up host configuration" );
247
293
@@ -253,21 +299,17 @@ static mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
253
299
if (is_spi ) {
254
300
sdmmc_host_t _temp_host = SDSPI_HOST_DEFAULT ();
255
301
_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 ;
256
304
self -> host = _temp_host ;
257
- } else {
305
+ }
306
+ #if SOC_SDMMC_HOST_SUPPORTED
307
+ else {
258
308
sdmmc_host_t _temp_host = SDMMC_HOST_DEFAULT ();
259
309
_temp_host .max_freq_khz = freq / 1000 ;
260
310
self -> host = _temp_host ;
261
311
}
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
271
313
272
314
DEBUG_printf (" Calling host.init()" );
273
315
@@ -294,6 +336,15 @@ static mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
294
336
SET_CONFIG_PIN (dev_config , gpio_cd , ARG_cd );
295
337
SET_CONFIG_PIN (dev_config , gpio_wp , ARG_wp );
296
338
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
+
297
348
DEBUG_printf (" Calling spi_bus_initialize()" );
298
349
check_esp_err (spi_bus_initialize (spi_host_id , & bus_config , dma_channel ));
299
350
@@ -309,7 +360,9 @@ static mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
309
360
spi_bus_free (spi_host_id );
310
361
mp_raise_ValueError (MP_ERROR_TEXT ("SPI bus already in use" ));
311
362
}
312
- } else {
363
+ }
364
+ #if SOC_SDMMC_HOST_SUPPORTED
365
+ else {
313
366
// SD/MMC interface
314
367
DEBUG_printf (" Setting up SDMMC slot configuration" );
315
368
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
357
410
DEBUG_printf (" Calling init_slot()" );
358
411
check_esp_err (sdmmc_host_init_slot (self -> host .slot , & slot_config ));
359
412
}
413
+ #endif // SOC_SDMMC_HOST_SUPPORTED
360
414
361
415
DEBUG_printf (" Returning new card object: %p" , self );
362
416
return MP_OBJ_FROM_PTR (self );
0 commit comments