diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c103a0..2dac887 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,15 @@ file(GLOB SOURCES src/littlefs/*.c) list(APPEND SOURCES src/esp_littlefs.c src/littlefs_esp_part.c src/littlefs_sdmmc.c src/lfs_config.c) if(IDF_VERSION_MAJOR GREATER_EQUAL 5) - list(APPEND pub_requires esp_partition sdmmc) + if (CONFIG_LITTLEFS_SDMMC_SUPPORT) + list(APPEND pub_requires esp_partition sdmmc) + else() + list(APPEND pub_requires esp_partition sdmmc) + endif() else() list(APPEND pub_requires spi_flash) endif() -list(APPEND priv_requires esptool_py spi_flash vfs sdmmc) +list(APPEND priv_requires esptool_py spi_flash vfs) idf_component_register( SRCS ${SOURCES} diff --git a/Kconfig b/Kconfig index 2cdce46..2048a8c 100644 --- a/Kconfig +++ b/Kconfig @@ -1,5 +1,12 @@ menu "LittleFS" + config LITTLEFS_SDMMC_SUPPORT + bool "SDMMC support (requires ESP-IDF v5+)" + default n + help + Toggle SD card support + This requires IDF v5+ as older ESP-IDF do not support SD card erase. + config LITTLEFS_MAX_PARTITIONS int "Maximum Number of Partitions" default 3 diff --git a/include/esp_littlefs.h b/include/esp_littlefs.h index 2aacdd3..f5ecfe8 100644 --- a/include/esp_littlefs.h +++ b/include/esp_littlefs.h @@ -27,7 +27,11 @@ typedef struct { const char *base_path; /**< Mounting point. */ const char *partition_label; /**< Label of partition to use. */ const esp_partition_t* partition; /**< partition to use if partition_label is NULL */ + +#ifdef CONFIG_LITTLEFS_SDMMC_SUPPORT sdmmc_card_t *sdcard; /**< SD card handle to use if both esp_partition handle & partition label is NULL */ +#endif + uint8_t format_if_mount_failed:1; /**< Format the file system if it fails to mount. */ uint8_t read_only : 1; /**< Mount the partition as read-only. */ uint8_t dont_mount:1; /**< Don't attempt to mount.*/ diff --git a/src/esp_littlefs.c b/src/esp_littlefs.c index d3da311..94578a6 100644 --- a/src/esp_littlefs.c +++ b/src/esp_littlefs.c @@ -694,6 +694,8 @@ static void esp_littlefs_take_efs_lock(void) { xSemaphoreTake(_efs_lock, portMAX_DELAY); } + +#ifdef CONFIG_LITTLEFS_SDMMC_SUPPORT static esp_err_t esp_littlefs_init_sdcard(esp_littlefs_t** efs, sdmmc_card_t* sdcard, bool read_only) { /* Allocate Context */ @@ -749,6 +751,7 @@ static esp_err_t esp_littlefs_init_sdcard(esp_littlefs_t** efs, sdmmc_card_t* sd return ESP_OK; } +#endif // CONFIG_LITTLEFS_SDMMC_SUPPORT static esp_err_t esp_littlefs_init_efs(esp_littlefs_t** efs, const esp_partition_t* partition, bool read_only) { @@ -850,6 +853,7 @@ static esp_err_t esp_littlefs_init(const esp_vfs_littlefs_conf_t* conf) goto exit; } partition = conf->partition; +#ifdef CONFIG_LITTLEFS_SDMMC_SUPPORT } else if (conf->sdcard) { ESP_LOGI(ESP_LITTLEFS_TAG, "Using SD card handle %p for LittleFS mount", conf->sdcard); err = sdmmc_get_status(conf->sdcard); @@ -857,18 +861,26 @@ static esp_err_t esp_littlefs_init(const esp_vfs_littlefs_conf_t* conf) ESP_LOGE(ESP_LITTLEFS_TAG, "Failed when checking SD card status: 0x%x", err); goto exit; } +#endif } else { ESP_LOGE(ESP_LITTLEFS_TAG, "No partition specified in configuration"); err = ESP_ERR_INVALID_ARG; goto exit; } - if (!conf->sdcard) { +#ifdef CONFIG_LITTLEFS_SDMMC_SUPPORT + if (conf->sdcard) { + err = esp_littlefs_init_sdcard(&efs, conf->sdcard, conf->read_only); + if(err != ESP_OK) { + goto exit; + } + } else { +#endif uint32_t flash_page_size = g_rom_flashchip.page_size; uint32_t log_page_size = CONFIG_LITTLEFS_PAGE_SIZE; if (log_page_size % flash_page_size != 0) { ESP_LOGE(ESP_LITTLEFS_TAG, "LITTLEFS_PAGE_SIZE is not multiple of flash chip page size (%u)", - (unsigned int) flash_page_size); + (unsigned int) flash_page_size); err = ESP_ERR_INVALID_ARG; goto exit; } @@ -878,12 +890,10 @@ static esp_err_t esp_littlefs_init(const esp_vfs_littlefs_conf_t* conf) if(err != ESP_OK) { goto exit; } - } else { - err = esp_littlefs_init_sdcard(&efs, conf->sdcard, conf->read_only); - if(err != ESP_OK) { - goto exit; - } + +#ifdef CONFIG_LITTLEFS_SDMMC_SUPPORT } +#endif // Mount and Error Check _efs[index] = efs; diff --git a/src/littlefs_api.h b/src/littlefs_api.h index 43bece7..adf6e36 100644 --- a/src/littlefs_api.h +++ b/src/littlefs_api.h @@ -46,7 +46,11 @@ typedef struct _vfs_littlefs_file_t { typedef struct { lfs_t *fs; /*!< Handle to the underlying littlefs */ SemaphoreHandle_t lock; /*!< FS lock */ + +#ifdef CONFIG_LITTLEFS_SDMMC_SUPPORT sdmmc_card_t *sdcard; /*!< The SD card driver handle on which littlefs is located */ +#endif + const esp_partition_t* partition; /*!< The partition on which littlefs is located */ char base_path[ESP_VFS_PATH_MAX+1]; /*!< Mount point */ @@ -102,6 +106,8 @@ int littlefs_esp_part_erase(const struct lfs_config *c, lfs_block_t block); */ int littlefs_esp_part_sync(const struct lfs_config *c); +#ifdef CONFIG_LITTLEFS_SDMMC_SUPPORT + /** * @brief Read a region in a block on SD card * @@ -144,6 +150,8 @@ int littlefs_sdmmc_erase(const struct lfs_config *c, lfs_block_t block); */ int littlefs_sdmmc_sync(const struct lfs_config *c); +#endif // CONFIG_LITTLEFS_SDMMC_SUPPORT + #ifdef __cplusplus } #endif diff --git a/src/littlefs_sdmmc.c b/src/littlefs_sdmmc.c index 28a0648..88732fa 100644 --- a/src/littlefs_sdmmc.c +++ b/src/littlefs_sdmmc.c @@ -8,14 +8,18 @@ #include #include "littlefs_api.h" +#if CONFIG_LITTLEFS_SDMMC_SUPPORT && ESP_IDF_VERSION_MAJOR < 5 +#error "SDMMC feature is only supported in ESP-IDF v5+, see: https://github.com/joltwallet/esp_littlefs/pull/170#issuecomment-1882484668" +#endif + int littlefs_sdmmc_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { esp_littlefs_t * efs = c->context; - size_t part_off = (block * c->block_size) + off; + uint32_t part_off = (block * c->block_size) + off; esp_err_t ret = sdmmc_read_sectors(efs->sdcard, buffer, block, MIN(size / efs->cfg.read_size, 1)); if (ret != ESP_OK) { - ESP_LOGE(ESP_LITTLEFS_TAG, "failed to read addr %08x, size %08x, err=0x%x", (unsigned int) part_off, (unsigned int) size, ret); + ESP_LOGE(ESP_LITTLEFS_TAG, "Failed to read addr 0x%08lx: off 0x%08lx, block 0x%08lx, size %lu, err=0x%x", part_off, off, block, size, ret); return LFS_ERR_IO; } @@ -25,11 +29,11 @@ int littlefs_sdmmc_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t int littlefs_sdmmc_write(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { esp_littlefs_t * efs = c->context; - size_t part_off = (block * c->block_size) + off; + uint32_t part_off = (block * c->block_size) + off; esp_err_t ret = sdmmc_write_sectors(efs->sdcard, buffer, block, MIN(size / efs->cfg.prog_size, 1)); if (ret != ESP_OK) { - ESP_LOGE(ESP_LITTLEFS_TAG, "failed to write addr %08x, size %08x, err=0x%x", (unsigned int) part_off, (unsigned int) size, ret); + ESP_LOGE(ESP_LITTLEFS_TAG, "Failed to write addr 0x%08lx: off 0x%08lx, block 0x%08lx, size %lu, err=0x%x", part_off, off, block, size, ret); return LFS_ERR_IO; }