feat(p4): montage microSD (SDMMC 1-bit) sur /sdcard
CI / platformio (pull_request) Failing after 6m0s
CI / platformio (pull_request) Failing after 6m0s
Nouveau composant sd_storage : monte la carte microSD du Freenove en SDMMC 1-bit (CMD=38, CLK=39, D0=40 — pinout FREENOVE_SDMMC_* du firmware Arduino) sur /sdcard via esp_vfs_fat_sdmmc_mount. Best-effort au boot : carte absente = non fatal, fallback LittleFS. Lève le plafond LittleFS 5 Mo pour les assets. Validé sur Freenove : carte ~3839 MiB montée à /sdcard au boot. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
## Zacus sd_storage — microSD (SDMMC 1-bit) FAT mount at /sdcard (P4).
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"sd_storage.c"
|
||||
INCLUDE_DIRS
|
||||
"."
|
||||
REQUIRES
|
||||
fatfs
|
||||
sdmmc
|
||||
esp_driver_sdmmc
|
||||
)
|
||||
@@ -0,0 +1,74 @@
|
||||
#include "sd_storage.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_vfs_fat.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
|
||||
static const char *TAG = "sd_storage";
|
||||
|
||||
// Freenove ESP32-S3 WROOM N16R8 microSD (SDMMC 1-bit). Mirrors
|
||||
// ui_freenove_allinone/include/ui_freenove_config.h FREENOVE_SDMMC_*.
|
||||
#define SD_PIN_CMD 38
|
||||
#define SD_PIN_CLK 39
|
||||
#define SD_PIN_D0 40
|
||||
|
||||
static sdmmc_card_t *s_card = NULL;
|
||||
|
||||
esp_err_t sd_storage_mount(void) {
|
||||
if (s_card != NULL) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
const esp_vfs_fat_sdmmc_mount_config_t mount_cfg = {
|
||||
.format_if_mount_failed = false, // never wipe a user's card
|
||||
.max_files = 5,
|
||||
.allocation_unit_size = 16 * 1024,
|
||||
};
|
||||
|
||||
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
|
||||
host.flags = SDMMC_HOST_FLAG_1BIT; // Freenove wires D0 only
|
||||
host.max_freq_khz = SDMMC_FREQ_DEFAULT;
|
||||
|
||||
sdmmc_slot_config_t slot = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||
slot.width = 1;
|
||||
slot.clk = SD_PIN_CLK;
|
||||
slot.cmd = SD_PIN_CMD;
|
||||
slot.d0 = SD_PIN_D0;
|
||||
slot.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
|
||||
|
||||
esp_err_t err = esp_vfs_fat_sdmmc_mount(SD_STORAGE_MOUNT_POINT, &host,
|
||||
&slot, &mount_cfg, &s_card);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGW(TAG, "mount failed: %s — no card inserted or wiring issue",
|
||||
esp_err_to_name(err));
|
||||
s_card = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "microSD mounted at %s — %lu MiB (%s)",
|
||||
SD_STORAGE_MOUNT_POINT, (unsigned long) sd_storage_capacity_mb(),
|
||||
s_card->cid.name);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t sd_storage_unmount(void) {
|
||||
if (s_card == NULL) {
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_err_t err = esp_vfs_fat_sdcard_unmount(SD_STORAGE_MOUNT_POINT, s_card);
|
||||
s_card = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
bool sd_storage_ready(void) {
|
||||
return s_card != NULL;
|
||||
}
|
||||
|
||||
uint32_t sd_storage_capacity_mb(void) {
|
||||
if (s_card == NULL) {
|
||||
return 0U;
|
||||
}
|
||||
uint64_t bytes = (uint64_t) s_card->csd.capacity * s_card->csd.sector_size;
|
||||
return (uint32_t) (bytes / (1024ULL * 1024ULL));
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Zacus sd_storage — microSD mount for the Freenove ESP32-S3 master.
|
||||
//
|
||||
// The Freenove WROOM N16R8 exposes the card on the SDMMC peripheral in
|
||||
// 1-bit mode (CMD=GPIO38, CLK=GPIO39, D0=GPIO40 — mirrors the Arduino
|
||||
// `ui_freenove_allinone` FREENOVE_SDMMC_* pinout). Mounts FAT at /sdcard so
|
||||
// media_manager and the asset endpoints can stage large assets off the 5 MB
|
||||
// LittleFS partition (P4). Mount is best-effort: a missing card is not fatal.
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SD_STORAGE_MOUNT_POINT "/sdcard"
|
||||
|
||||
// Mount the microSD card (SDMMC 1-bit) at /sdcard. Returns ESP_OK on success;
|
||||
// ESP_ERR_NOT_FOUND / ESP_FAIL when no card is present or wiring is wrong.
|
||||
esp_err_t sd_storage_mount(void);
|
||||
|
||||
// Unmount and release the card.
|
||||
esp_err_t sd_storage_unmount(void);
|
||||
|
||||
// True once a card is mounted.
|
||||
bool sd_storage_ready(void);
|
||||
|
||||
// Card capacity in MiB (0 when not mounted).
|
||||
uint32_t sd_storage_capacity_mb(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -6,6 +6,7 @@ idf_component_register(
|
||||
REQUIRES
|
||||
joltwallet__littlefs
|
||||
ota_server
|
||||
sd_storage
|
||||
media_manager
|
||||
npc_engine
|
||||
hints_client
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "ota_server.h"
|
||||
#include "media_manager.h"
|
||||
#include "sd_storage.h"
|
||||
#include "npc_engine.h"
|
||||
#include "hints_client.h"
|
||||
#include "voice_pipeline.h"
|
||||
@@ -484,6 +485,13 @@ void app_main(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// P4: best-effort microSD mount (SDMMC 1-bit on /sdcard). A missing card
|
||||
// is non-fatal — assets fall back to LittleFS.
|
||||
if (sd_storage_mount() == ESP_OK) {
|
||||
ESP_LOGI(TAG, "microSD ready (%lu MiB) at %s",
|
||||
(unsigned long) sd_storage_capacity_mb(), SD_STORAGE_MOUNT_POINT);
|
||||
}
|
||||
|
||||
if (mount_littlefs() == ESP_OK) {
|
||||
list_littlefs_root();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user