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...

Reply
  • 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...

Children
  • 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

  • Here is a link to the exact card which I am having issues with here.

    I realized that when the Samsung card is first initialized it fails and then if I reset the board it then works as expected... The other two cards however succeed on the first attempt. Here are the steps I took to produce those logs:

    1. Power on board with SD card slot empty.
    2. insert the Samsung SD card.
    3. Click the reset button on the devkit
    4. SD card init fails...
    5. wait 1 second
    6. click the reset button on the devkit again
    7. SD card init success!

    *** Booting nRF Connect SDK v3.5.99-ncs1-1 ***
    [00:00:00.251,953] <dbg> sd: sd_init_io: Host controller support 3.3V max
    [00:00:00.251,953] <dbg> sd: sd_init_io: Resetting power to card
    [00:00:00.255,554] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd0 arg 0x0
    [00:00:00.256,317] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.257,049] <inf> sd: Legacy card detected, no CMD8 support
    [00:00:00.257,049] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.257,781] <inf> sd: Legacy card detected, no CMD8 support
    [00:00:00.257,812] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.258,544] <inf> sd: Legacy card detected, no CMD8 support
    [00:00:00.258,575] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.259,307] <inf> sd: Legacy card detected, no CMD8 support
    [00:00:00.259,338] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.260,040] <inf> sd: Legacy card detected, no CMD8 support
    [00:00:00.260,070] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.260,803] <inf> sd: Legacy card detected, no CMD8 support
    [00:00:00.260,833] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.261,566] <inf> sd: Legacy card detected, no CMD8 support
    [00:00:00.261,596] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.262,329] <inf> sd: Legacy card detected, no CMD8 support
    [00:00:00.262,329] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.263,061] <inf> sd: Legacy card detected, no CMD8 support
    [00:00:00.263,092] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.263,824] <inf> sd: Legacy card detected, no CMD8 support
    [00:00:00.263,854] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.264,587] <inf> sd: Legacy card detected, no CMD8 support
    [00:00:00.264,587] <inf> sd: Card does not support CMD8, assuming legacy card
    [00:00:00.264,617] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd0 arg 0x0
    [00:00:00.265,350] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd58 arg 0x0
    [00:00:00.266,204] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
    [00:00:00.266,937] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x0
    [00:00:00.267,669] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd58 arg 0x0
    [00:00:00.268,432] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd10 arg 0x0
    [00:00:00.268,768] <dbg> sd: sdmmc_spi_read_cxd: CMD10 failed: -22
    [00:00:00.268,798] <dbg> sd: card_read_cid: Card MID: 0x0, OID:
    [00:00:00.268,829] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd9 arg 0x0
    [00:00:00.269,165] <dbg> sd: sdmmc_spi_read_cxd: CMD9 failed: -22
    [00:00:00.269,195] <dbg> sd: sdmmc_read_csd: Card block count 0, block size 512
    [00:00:00.269,195] <inf> sd: Maximum SD clock is under 25MHz, using clock of 8000000Hz
    [00:00:00.269,226] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
    *** Booting nRF Connect SDK v3.5.99-ncs1-1 ***
    [00:00:00.251,983] <dbg> sd: sd_init_io: Host controller support 3.3V max
    [00:00:00.252,014] <dbg> sd: sd_init_io: Resetting power to card
    [00:00:00.255,584] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd0 arg 0x0
    [00:00:00.256,347] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
    [00:00:00.257,080] <dbg> sd: sd_send_interface_condition: Found SDHC with CMD8 support
    [00:00:00.257,110] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd59 arg 0x1
    [00:00:00.257,843] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd58 arg 0x0
    [00:00:00.258,697] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
    [00:00:00.259,429] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
    [00:00:00.270,233] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
    [00:00:00.270,996] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
    [00:00:00.271,728] <dbg> sd: sdmmc_send_ocr: SDMMC responded to ACMD41 after 1 attempts
    [00:00:00.271,728] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd58 arg 0x40000000
    [00:00:00.272,491] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd10 arg 0x0
    [00:00:00.273,742] <dbg> sd: card_read_cid: Card MID: 0x1b, OID: MS
    [00:00:00.273,773] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd9 arg 0x0
    [00:00:00.275,024] <dbg> sd: sdmmc_read_csd: Card block count 62521344, block size 512
    [00:00:00.275,054] <inf> sd: Maximum SD clock is under 25MHz, using clock of 8000000Hz
    [00:00:00.275,085] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
    [00:00:00.275,207] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd51 arg 0x0
    [00:00:00.275,390] <dbg> sd: sdmmc_read_scr: SD reports specification version 8
    [00:00:00.275,390] <inf> main: Block count 62521344
    Sector size 512
    Memory Size(MB) 30528
    [00:00:00.275,482] <dbg> sd: card_read: READ: Sector = 0, Count = 1
    [00:00:00.275,512] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd17 arg 0x0
    [00:00:00.278,320] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd13 arg 0x0
    [00:00:00.278,442] <dbg> sd: card_read: READ: Sector = 2048, Count = 1
    [00:00:00.278,442] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd17 arg 0x800
    [00:00:00.280,426] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd13 arg 0x0
    [00:00:00.280,548] <dbg> sd: card_read: READ: Sector = 2049, Count = 1
    [00:00:00.280,548] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd17 arg 0x801
    [00:00:00.282,531] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd13 arg 0x0
    Disk mounted.
    
    Listing dir /SD: ...
    [00:00:00.282,714] <dbg> sd: card_read: READ: Sector = 34816, Count = 1
    [00:00:00.282,745] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd17 arg 0x8800
    [00:00:00.284,698] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd13 arg 0x0
    [DIR ] SYSTEM~1
    [FILE] TEST.TXT (size = 24)

    Looking at the logic analyzer the 2 signals from the above procedure look almost identical except the SD card's response to the CMD8 SD command is not correct the first time (see the SD card's response on the MISO line):

    After step 3 above:

    After step 6 above:

    I took your suggestion and looked into the voltage levels and you can see that the voltage lines are at 3V voltage level in the analog waveform which is within spec for the Samsung card linked above.

    To ensure it is not by board causing issues could this be tested with the Nordic 5340 Audio Devkit which has a built in SD card slot?

  • 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

Related