44 * SPDX-License-Identifier: Apache-2.0
55 */
66
7+ #include <string.h>
78#include "driver/gpio.h"
89#include "driver/ledc.h"
910#include "driver/spi_master.h"
@@ -60,7 +61,8 @@ static esp_lcd_panel_handle_t panel_handle = NULL;
6061#endif // (BSP_CONFIG_NO_GRAPHIC_LIB == 0)
6162
6263static esp_lcd_touch_handle_t tp ; // LCD touch handle
63- sdmmc_card_t * bsp_sdcard = NULL ; // Global SD card handler
64+ static sdmmc_card_t * bsp_sdcard = NULL ; // Global uSD card handler
65+ static bool spi_sd_initialized = false;
6466
6567/**
6668 * @brief I2C handle for BSP usage
@@ -185,8 +187,78 @@ esp_err_t bsp_spiffs_unmount(void)
185187 return esp_vfs_spiffs_unregister (CONFIG_BSP_SPIFFS_PARTITION_LABEL );
186188}
187189
188- esp_err_t bsp_sdcard_mount (void )
190+ sdmmc_card_t * bsp_sdcard_get_handle (void )
191+ {
192+ return bsp_sdcard ;
193+ }
194+
195+ void bsp_sdcard_get_sdmmc_host (const int slot , sdmmc_host_t * config )
196+ {
197+ assert (config );
198+
199+ sdmmc_host_t host_config = SDMMC_HOST_DEFAULT ();
200+
201+ memcpy (config , & host_config , sizeof (sdmmc_host_t ));
202+ }
203+
204+ void bsp_sdcard_get_sdspi_host (const int slot , sdmmc_host_t * config )
205+ {
206+ assert (config );
207+
208+ sdmmc_host_t host_config = SDSPI_HOST_DEFAULT ();
209+ host_config .slot = slot ;
210+
211+ memcpy (config , & host_config , sizeof (sdmmc_host_t ));
212+ }
213+
214+ void bsp_sdcard_sdmmc_get_slot (const int slot , sdmmc_slot_config_t * config )
215+ {
216+ assert (config );
217+ memset (config , 0 , sizeof (sdmmc_slot_config_t ));
218+
219+ /* SD card is connected to Slot 0 pins. Slot 0 uses IO MUX, so not specifying the pins here */
220+ config -> cd = SDMMC_SLOT_NO_CD ;
221+ config -> wp = SDMMC_SLOT_NO_WP ;
222+ config -> cmd = BSP_SD_CMD ;
223+ config -> clk = BSP_SD_CLK ;
224+ config -> d0 = BSP_SD_D0 ;
225+ config -> d1 = BSP_SD_D1 ;
226+ config -> d2 = BSP_SD_D2 ;
227+ config -> d3 = BSP_SD_D3 ;
228+ config -> width = 4 ;
229+ config -> flags = 0 ;
230+ }
231+
232+ void bsp_sdcard_sdspi_get_slot (const spi_host_device_t spi_host , sdspi_device_config_t * config )
233+ {
234+ assert (config );
235+ memset (config , 0 , sizeof (sdspi_device_config_t ));
236+
237+ config -> gpio_cs = BSP_SD_SPI_CS ;
238+ config -> gpio_cd = SDSPI_SLOT_NO_CD ;
239+ config -> gpio_wp = SDSPI_SLOT_NO_WP ;
240+ config -> gpio_int = GPIO_NUM_NC ;
241+ config -> host_id = spi_host ;
242+ #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL (5 , 2 , 0 )
243+ config -> gpio_wp_polarity = SDSPI_IO_ACTIVE_LOW ;
244+ #endif
245+ }
246+
247+ esp_err_t bsp_sdcard_sdmmc_mount (bsp_sdcard_cfg_t * cfg )
189248{
249+ sdmmc_host_t sdhost = {0 };
250+ sdmmc_slot_config_t sdslot = {0 };
251+ const esp_vfs_fat_sdmmc_mount_config_t mount_config = {
252+ #ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL
253+ .format_if_mount_failed = true,
254+ #else
255+ .format_if_mount_failed = false,
256+ #endif
257+ .max_files = 5 ,
258+ .allocation_unit_size = 16 * 1024
259+ };
260+ assert (cfg );
261+
190262 gpio_config_t power_gpio_config = {
191263 .mode = GPIO_MODE_OUTPUT ,
192264 .pin_bit_mask = 1ULL << BSP_SD_POWER
@@ -196,6 +268,31 @@ esp_err_t bsp_sdcard_mount(void)
196268 /* SD card power on first */
197269 ESP_ERROR_CHECK (gpio_set_level (BSP_SD_POWER , 0 ));
198270
271+ if (!cfg -> mount ) {
272+ cfg -> mount = & mount_config ;
273+ }
274+
275+ if (!cfg -> host ) {
276+ bsp_sdcard_get_sdmmc_host (SDMMC_HOST_SLOT_0 , & sdhost );
277+ cfg -> host = & sdhost ;
278+ }
279+
280+ if (!cfg -> slot .sdmmc ) {
281+ bsp_sdcard_sdmmc_get_slot (SDMMC_HOST_SLOT_0 , & sdslot );
282+ cfg -> slot .sdmmc = & sdslot ;
283+ }
284+
285+ #if !CONFIG_FATFS_LONG_FILENAMES
286+ ESP_LOGW (TAG , "Warning: Long filenames on SD card are disabled in menuconfig!" );
287+ #endif
288+
289+ return esp_vfs_fat_sdmmc_mount (BSP_SD_MOUNT_POINT , cfg -> host , cfg -> slot .sdmmc , cfg -> mount , & bsp_sdcard );
290+ }
291+
292+ esp_err_t bsp_sdcard_sdspi_mount (bsp_sdcard_cfg_t * cfg )
293+ {
294+ sdmmc_host_t sdhost = {0 };
295+ sdspi_device_config_t sdslot = {0 };
199296 const esp_vfs_fat_sdmmc_mount_config_t mount_config = {
200297#ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL
201298 .format_if_mount_failed = true,
@@ -205,23 +302,71 @@ esp_err_t bsp_sdcard_mount(void)
205302 .max_files = 5 ,
206303 .allocation_unit_size = 16 * 1024
207304 };
305+ assert (cfg );
208306
209- sdmmc_host_t host = SDMMC_HOST_DEFAULT ();
210- sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT ();
211- slot_config .width = 4 ;
212- slot_config .cmd = BSP_SD_CMD ;
213- slot_config .clk = BSP_SD_CLK ;
214- slot_config .d0 = BSP_SD_D0 ;
215- slot_config .d1 = BSP_SD_D1 ;
216- slot_config .d2 = BSP_SD_D2 ;
217- slot_config .d3 = BSP_SD_D3 ;
307+ gpio_config_t power_gpio_config = {
308+ .mode = GPIO_MODE_OUTPUT ,
309+ .pin_bit_mask = 1ULL << BSP_SD_POWER
310+ };
311+ ESP_ERROR_CHECK (gpio_config (& power_gpio_config ));
218312
219- return esp_vfs_fat_sdmmc_mount (BSP_SD_MOUNT_POINT , & host , & slot_config , & mount_config , & bsp_sdcard );
313+ /* SD card power on first */
314+ ESP_ERROR_CHECK (gpio_set_level (BSP_SD_POWER , 0 ));
315+
316+ ESP_LOGD (TAG , "Initialize SPI bus" );
317+ const spi_bus_config_t buscfg = {
318+ .sclk_io_num = BSP_SD_SPI_CLK ,
319+ .mosi_io_num = BSP_SD_SPI_MOSI ,
320+ .miso_io_num = BSP_SD_SPI_MISO ,
321+ .quadwp_io_num = GPIO_NUM_NC ,
322+ .quadhd_io_num = GPIO_NUM_NC ,
323+ .max_transfer_sz = 4000 ,
324+ };
325+ ESP_RETURN_ON_ERROR (spi_bus_initialize (BSP_SDSPI_HOST , & buscfg , SPI_DMA_CH_AUTO ), TAG , "SPI init failed" );
326+ spi_sd_initialized = true;
327+
328+ if (!cfg -> mount ) {
329+ cfg -> mount = & mount_config ;
330+ }
331+
332+ if (!cfg -> host ) {
333+ bsp_sdcard_get_sdspi_host (SDMMC_HOST_SLOT_0 , & sdhost );
334+ cfg -> host = & sdhost ;
335+ }
336+
337+ if (!cfg -> slot .sdspi ) {
338+ bsp_sdcard_sdspi_get_slot (BSP_SDSPI_HOST , & sdslot );
339+ cfg -> slot .sdspi = & sdslot ;
340+ }
341+
342+ #if !CONFIG_FATFS_LONG_FILENAMES
343+ ESP_LOGW (TAG , "Warning: Long filenames on SD card are disabled in menuconfig!" );
344+ #endif
345+
346+ return esp_vfs_fat_sdspi_mount (BSP_SD_MOUNT_POINT , cfg -> host , cfg -> slot .sdspi , cfg -> mount , & bsp_sdcard );
347+ }
348+
349+ esp_err_t bsp_sdcard_mount (void )
350+ {
351+ bsp_sdcard_cfg_t cfg = {0 };
352+ return bsp_sdcard_sdmmc_mount (& cfg );
220353}
221354
222355esp_err_t bsp_sdcard_unmount (void )
223356{
224- return esp_vfs_fat_sdcard_unmount (BSP_SD_MOUNT_POINT , bsp_sdcard );
357+ esp_err_t ret = ESP_OK ;
358+
359+ ret |= esp_vfs_fat_sdcard_unmount (BSP_SD_MOUNT_POINT , bsp_sdcard );
360+ bsp_sdcard = NULL ;
361+
362+ if (spi_sd_initialized ) {
363+ ret |= spi_bus_free (BSP_SDSPI_HOST );
364+ spi_sd_initialized = false;
365+ }
366+
367+ gpio_reset_pin (BSP_SD_POWER );
368+
369+ return ret ;
225370}
226371
227372esp_codec_dev_handle_t bsp_audio_codec_speaker_init (void )
0 commit comments