SD Card error using fs_sample zephyr example code

Hi I am trying to get an SD card hooked up to my nrf52840 devkit. I am using nRF Connect v2.6.1 and I was trying to get the sample code working, so I used the sample in ncs/v2.6.1/zephyr/subsys/fs/fs_sample

Unfortunately I get this error when trying to run the program

Here's a capture of what the signals look like talking to the SD card over SPI:

Oddly, the CS line is low during the initial "boot up" phase of the device; however, I thought that the CS line is supposed to be held at high voltage level during this initial boot-up? Even if it is used as active low in later communications (as defined here).

Here is my custom conf file which I've named "nrf52840dk_SDCard.conf"

#
# Copyright (c) 2023 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
#

CONFIG_NORDIC_QSPI_NOR=n
# The erase page size
CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
CONFIG_DISK_DRIVERS=y
CONFIG_DISK_DRIVER_FLASH=y
# There may be no files on internal SoC flash, so this Kconfig
# options has ben enabled to create some if listing does not
# find in the first place.
CONFIG_FS_SAMPLE_CREATE_SOME_ENTRIES=y
CONFIG_DISK_ACCESS=y
CONFIG_SPI=y
CONFIG_DISK_DRIVER_SDMMC=y

Here is my board overlay file:

&spi1 {
    status = "okay";
    cs-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
    sdhc0: sdhc@0 {
        compatible = "zephyr,sdhc-spi-slot";
        reg = <0>;
        status = "okay";
        mmc {
            compatible = "zephyr,mmc-disk";
            status = "okay";
        };
        spi-max-frequency = <25000000>;
    };
};

Here is my "prj.conf" file:

CONFIG_DISK_ACCESS=y
CONFIG_LOG=y
CONFIG_FILE_SYSTEM=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_PRINTK=y
CONFIG_MAIN_STACK_SIZE=2048

# SD
CONFIG_MMC_STACK=y
CONFIG_SD_LOG_LEVEL_DEFAULT=y

CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=8
CONFIG_SDHC=y
CONFIG_SDHC_LOG_LEVEL_DEFAULT=y
CONFIG_NRFX_SPI1=y

I'm not really sure what's going on here... I've tried this with 2 different SD cards as well. Is there a bug in Zephyr or am I missing something in my config...? I appreciate any help on what might be going wrong here.

Thank you,

Louis

Parents
  • I updated my board overlay in the following way:

    &spi1 {
        status = "okay";
        cs-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
        sdhc0: sdhc@0 {
            compatible = "zephyr,sdhc-spi-slot";
            reg = <0>;
            status = "okay";
            mmc {
                compatible = "zephyr,sdmmc-disk"; # Changed to sdmmc-disk from mmc-disk
                status = "okay";
            };
            spi-max-frequency = <25000000>;
        };
    };

    Changing from "zephyr,mmc-disk" to "zephyr,sdmmc-disk" fixed this issue for me on 2 of my SD cards; however it still does not work on one of my SD cards. I have a Lexar 64GB microSDXC and a SanDisk 64GB microSDXC both formatted with a 30GB Fat32 partition and it works fine. I have a Samsung 32GB microSDHC card and it still fails on this card. This card is not corrupt as I can plug it into a PC and see the files. 

    I'm still wondering if this is related to the initialization procedure I mentioned in my previous post...

  • Everything looks fine according the to konfiguration. Do you have anything more info regarding the samsung SDHC card? I'm just wondering if it could be something like in this issue where the card uses a different voltage. 

    It would be interresting if you could add 

    CONFIG_SD_LOG_LEVEL_DBG=y
    CONFIG_SDHC_LOG_LEVEL_DBG=y
    CONFIG_SDMMC_LOG_LEVEL_DBG=y

    and run it again to see if we get more information

    Regards

    Runar

  • Thanks for the good data. I'm discussing this internally it appear to be the same issue as you linked https://github.com/zephyrproject-rtos/zephyr/issues/29946. I will update you as soon as I have something

    Regards

    Runar

  • Thank you.

    If it helps here is the location where the SPI bus is supposed to set the CS line to active high.

    ncs\v2.6.1\zephyr\drivers\sdhc.c line 127-157:

    static int sdhc_spi_init_card(const struct device *dev)
    {
    	/* SD spec requires at least 74 clocks be send to SD to start it.
    	 * for SPI protocol, this will be performed by sending 10 0xff values
    	 * to the card (this should result in 80 SCK cycles)
    	 */
    	const struct sdhc_spi_config *config = dev->config;
    	struct sdhc_spi_data *data = dev->data;
    	struct spi_config *spi_cfg = data->spi_cfg;
    	int ret;
    
    	if (spi_cfg->frequency == 0) {
    		/* Use default 400KHZ frequency */
    		spi_cfg->frequency = SDMMC_CLOCK_400KHZ;
    	}
    	/* the initial 74 clocks must be sent while CS is high */
    	spi_cfg->operation |= SPI_CS_ACTIVE_HIGH;
        LOG_DBG("Initializing SPI CS PIN: %d", spi_cfg->cs.gpio.pin);  // I ADDED FOR DEBUGGING
        LOG_DBG("SPI operation flags: %x", spi_cfg->operation);        // I ADDED FOR DEBUGGING
    	ret = sdhc_spi_rx(config->spi_dev, spi_cfg, data->scratch, 10);
    	if (ret != 0) {
    		spi_cfg->operation &= ~SPI_CS_ACTIVE_HIGH;
    		return ret;
    	}
    	/* Release lock on SPI bus */
    	ret = spi_release(config->spi_dev, spi_cfg);
    	spi_cfg->operation &= ~SPI_CS_ACTIVE_HIGH;
        LOG_DBG("Initializing SPI CS PIN: %d", spi_cfg->cs.gpio.pin);  // I ADDED FOR DEBUGGING
        LOG_DBG("SPI operation flags: %x", spi_cfg->operation);        // I ADDED FOR DEBUGGING
    	return ret;
    }

    Now, when running this code I can see the CS active high bit is getting flipped as expected in my log output:

    ...
    [00:00:00.267,242] <dbg> sd: sd_init_io: Host controller support 3.3V max
    [00:00:00.267,242] <dbg> sd: sd_init_io: Resetting power to card
    [00:00:00.268,341] <dbg> sdhc_spi: sdhc_spi_init_card: Initializing SPI CS PIN: 28
    [00:00:00.268,371] <dbg> sdhc_spi: sdhc_spi_init_card: SPI operation flags: 7100         // bit 14 is set high
    [00:00:00.268,768] <dbg> sdhc_spi: sdhc_spi_init_card: DONE Initializing SPI CS PIN: 28
    [00:00:00.268,768] <dbg> sdhc_spi: sdhc_spi_init_card: DONE SPI operation flags: 3100    // bit 14 set back to low after init
    [00:00:00.270,996] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd0 arg 0x0
    [00:00:00.271,728] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    ...

    However when probing the CS line I can see that it is still being treated as active low.

    Thanks,

    Louis

  • Hi  

    Thank you for your patience. It's proven more difficult than what I thought to find someone who has experienced this issue before. 

    As it works on a reset I would suggest that you add a 

    void k_busy_wait(uint32_t usec_to_wait);
    inside the init function to the SDCard driver as it looks like the boot time might be the issue. It might be also be possible to ask on the Zephyr discord if anyone has seen the issue there. I would however first test if adding the delay fixes the issue. 

    Regards

    Runar

  • Runar,

    Adding the wait to sd init did not solve this issue. Please let me know if you find anything else that may resolve this issue.

    Thanks,

    Louis

  • I will try to see if I can find anything. Just as a good to know. I also saw you asked on the zephyr discord thats good. 

    Regards

    Runar

Reply Children
No Data
Related