MCU/Board: nRF54L15 (custom, cpuapp)
SDK/Zephyr: nRF Connect SDK v3.0.2 (*** Using Zephyr OS v4.0.99-f791c49f492c ***)
FS stack: FATFS (Elm) over SD SPI slot (zephyr,sdhc-spi-slot)
Interface: SPI via spi21 to micro-SD socket, 3.0 V rail
Goal: mount /SD: reliably at boot; write WAV/CSV
Symptom
Cold boot frequently fails SD card identification:
-
Sometimes CMD8 returns a normal R7 echo (printed as
a11d/0x1AA) and then later fails withCMD58 No OCR. -
Other times CMD8 times out and the driver prints “Legacy card detected, no CMD8 support”.
-
Ultimately
disk_access_init('SD') -> -134.
Warm reset occasionally makes it succeed (hence my suspicion about power/CS timing).
Representative logs:
[00:00:00.022] <dbg> sd: sd_init_io: Resetting power to card
[00:00:02.024] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd0 arg 0x0
[00:00:02.025] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 a11d <-- R7 looks OK
...
[00:00:53.608] <dbg> sd: sdmmc_spi_send_ocr: No OCR detected
[00:00:53.608] <inf> sdstore: disk_access_init('SD') -> -134
-- on other boots --
[00:10:15.728] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
[00:10:15.728] <dbg> sd: sd_send_interface_condition: Legacy card detected, no CMD8 support
(repeats cmd0/cmd8/legacy...)
Also noticed:
-
The stack requests 400 kHz during identification; actual on-wire is ~250 kHz (expected: nRF SPIM can’t do 400 kHz exactly).
-
Log prints “Host controller support 3.3V max”; my card VDD is 3.0 V (within 2.7–3.6 V SD spec).
Hardware
-
micro-SD socket wired to
spi21: SCK=P2.06, MOSI=P2.09, MISO=P2.xx (not shown below), CS=P2.10 -
Card VDD 3.0 V controlled by a load switch from P2.07
-
Pull-ups present on CS; MISO pull-up available if needed
-
Level shifters not used (direct 3.0 V domain)
&spi21 {
status = "okay";
pinctrl-0 = <&spi21_default>;
pinctrl-1 = <&spi21_sleep>;
pinctrl-names = "default", "sleep";
sdhc0: sdhc@0 {
compatible = "zephyr,sdhc-spi-slot";
reg = <0>;
status = "okay";
/* I have tested both ACTIVE_HIGH and ACTIVE_LOW here */
pwr-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>;
power-delay-ms = <300>; /* tried 300..3000 */
/* I have tried cs-gpios both on the bus and here on the device.
Currently placing it here to let the slot driver own CS: */
cs-gpios = <&gpio2 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
spi-hold-cs;
spi-cs-setup-delay-us = <10>;
spi-cs-hold-delay-us = <10>;
/* Start conservative; later will raise to 12–24 MHz */
spi-max-frequency = <400000>;
mmc: mmc {
compatible = "zephyr,sdmmc-disk";
status = "okay";
disk-name = "SD";
};
};
};
Kconfig (storage/logging relevant bits)
# ========================= # Kernel / stacks # ========================= CONFIG_MAIN_STACK_SIZE=4096 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 CONFIG_ISR_STACK_SIZE=2048 CONFIG_THREAD_NAME=y # ========================= # Logging (RTT console) # ========================= CONFIG_LOG=y CONFIG_PRINTK=y CONFIG_CONSOLE=y CONFIG_USE_SEGGER_RTT=y CONFIG_LOG_BACKEND_RTT=y CONFIG_RTT_CONSOLE=y # Per-subsystem log levels (turn up only what we care about) CONFIG_SD_LOG_LEVEL_DBG=y CONFIG_SDHC_LOG_LEVEL_DBG=y CONFIG_DISK_LOG_LEVEL_DBG=y # CONFIG_SPI_LOG_LEVEL_DBG=y # Optional: bigger RTT buffers while debugging SD spam # CONFIG_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE=2048 # CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=8192 # Global override when diagnosing: # CONFIG_LOG_OVERRIDE_LEVEL=4 # ========================= # Drivers / peripherals # ========================= CONFIG_GPIO=y CONFIG_GPIO_NRFX=y CONFIG_I2C=y CONFIG_SPI=y # IO expander CONFIG_GPIO_PCAL64XXA=y # SAADC & timers (nrfx direct) CONFIG_ADC=n CONFIG_NRFX_SAADC=y CONFIG_NRFX_TIMER22=y CONFIG_NRFX_GPPI=y # ========================= # Filesystem & SD over SPI/SDMMC # ========================= CONFIG_DISK_ACCESS=y CONFIG_FILE_SYSTEM=y CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_DISK_DRIVER_SDMMC=y CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=64 CONFIG_SDMMC_SUBSYS=y CONFIG_DEBUG_OPTIMIZATIONS=y # CONFIG_SDMMC_VOLUME_NAME="SD" # Demonstrate filesystem time integration # CONFIG_FS_FATFS_HAS_RTC=y # Optional FAT features: # CONFIG_FAT_FILESYSTEM_ELM_EXFAT=y # CONFIG_FS_FATFS_LFN=y # CONFIG_FS_FATFS_MAX_LFN=255 # ========================= # SD stack timeouts/retries (numbers ONLY) — enable as needed # ========================= # CONFIG_SD_INIT_TIMEOUT=5000 # CONFIG_SD_RETRY_COUNT=20 # CONFIG_SD_OCR_RETRY_COUNT=5000 # CONFIG_SD_CMD_TIMEOUT=500 # CONFIG_SD_DATA_TIMEOUT=15000 # CONFIG_SD_CMD_RETRIES=3 # CONFIG_SD_DATA_RETRIES=5
When it hits disk_access_init() returns -134. Running SDK V3.0.2