SDHC SPI Send Command

Hello.

I have a custom board featuring nRF5340. I placed a microSD card reader in my board connected to SPI. I followed the fatfs zephyr example, but I'm struggling in mounting the disk.

I can correctly see the block count, sector size and capacity of the microSD, but as soon as I try to run fs_mount(&mp), the board resets.

When debugging, I saw that the board resets as it tries to run the function sdhc_spi_send_cmd

I don't know where the problem can be, since as I said I can correctly see the capacity of the card (I'm using a Premium microSDHC 32gb card by Verbatim )

I already tried to format the card both with Windows10 and the program SDCardFormatter, but nothing changed.

My devicetree for the spi/sd device is 

&spi1 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	cs-gpios = < &gpio0 7 GPIO_ACTIVE_LOW >;
	sck-pin = < 8 >;
	mosi-pin = < 9 >;
	miso-pin = < 10 >;
	sdhc0: sdhc@0 {
		compatible = "zephyr,sdhc-spi-slot";
		reg = <0>;
		status = "okay";
		label = "SDHC0";
		mmc {
			compatible = "zephyr,sdmmc-disk";
			status = "okay";
		};
		spi-max-frequency = <16000000>;
	};	
};

And my connector is the following

Parents
  • Hi

    Hmm, that's very strange, a few more things you can try:

    • Have you tested this on a Development kit yet. That way we can narrow this down to whether it's a HW or SW issue at least.
    • You can also try to set the frequency even lower (1MHz for example) to see if you still see the storage init ERROR with that frequency setting as well.
    • Another thing I noticed is that you're using a deprecated way of setting your pins on. Please try using the pin control to set the SPI pins. You can see how it can be done in this SPI example by my colleague Torbjørn.
    • If possible, it could also be helpful to get a scope trace of the SPI pins to see that the expected data is output on them, and what exactly happens before and as the device resets.

    Best regards,

    Simon

  • I updated the overlay as it follows:

    &spi1 {
    	compatible = "nordic,nrf-spim";
    	status = "okay";
    	cs-gpios = < &gpio0 7 GPIO_ACTIVE_LOW >;
    	pinctrl-0 = <&spi1_default>;
    	pinctrl-names = "default";
    	sdhc0: sdhc@0 {
    		compatible = "zephyr,sdhc-spi-slot";
    		reg = <0>;
    		status = "okay";
    		label = "SDHC0";
    		mmc {
    			compatible = "zephyr,sdmmc-disk";
    			status = "okay";
    		};
    		spi-max-frequency = <16000000>;		
    	};	
    };
    
    

    Using pinctrl as:

    spi1_default: spi1_default{
    	group1 {
    		psels = <NRF_PSEL(SPIM_SCK, 0, 8)>,
    			<NRF_PSEL(SPIM_MISO, 0, 10)>,
    			<NRF_PSEL(SPIM_MOSI, 0, 9)>;
    	};
    
    };

    With this setting (16MHz), I now encounter the storage init error, so there is something odd.

    I do not have a uSD slot that I can plug into the devkit, so It would be prone to errors to unsolder my socket and hand soldering all the connections to the dk pins.

    Should I init in some way the SPI in my code? Even tough in the example there is not any kind of initialization

  • dario.sortino said:
    I now encounter the storage init error

    What error exactly is this? What function returns the error, and what error code do you see? Did you try to set the frequency even lower (1MHz for example) to see if you still see the storage init ERROR with that frequency setting as well. If possible, can you get a scope trace of the SPI pins to see that the expected data is output on them, and what exactly happens before and as the device resets.

    Best regards,

    Simon

Reply
  • dario.sortino said:
    I now encounter the storage init error

    What error exactly is this? What function returns the error, and what error code do you see? Did you try to set the frequency even lower (1MHz for example) to see if you still see the storage init ERROR with that frequency setting as well. If possible, can you get a scope trace of the SPI pins to see that the expected data is output on them, and what exactly happens before and as the device resets.

    Best regards,

    Simon

Children
  • I call the following function in my main 

    void mount_disk(){
    
    	do {
    		static const char *disk_pdrv = "SD";
    		uint64_t memory_size_mb;
    		uint32_t block_count;
    		uint32_t block_size;
    
    		if (disk_access_init(disk_pdrv) != 0) {
    			printk("Storage init ERROR %d!\n",disk_access_init(disk_pdrv));
    			break;
    		}
    
    		if (disk_access_ioctl(disk_pdrv,
    				DISK_IOCTL_GET_SECTOR_COUNT, &block_count)) {
    			printk("Unable to get sector count");
    			break;
    		}
    		printk("Block count %u", block_count);
    
    		if (disk_access_ioctl(disk_pdrv,
    				DISK_IOCTL_GET_SECTOR_SIZE, &block_size)) {
    			printk("Unable to get sector size");
    			break;
    		}
    		printk("Sector size %u\n", block_size);
    
    		memory_size_mb = (uint64_t)block_count * block_size;
    		printk("Memory Size(MB) %u\n", (uint32_t)(memory_size_mb >> 20));
    	} while (0);
    
    	mp.mnt_point = disk_mount_pt;
    
    	int res = fs_mount(&mp);
    
    	if (res == FR_OK) {
    		printk("Disk mounted.\n");
    		lsdir(disk_mount_pt);
    	}
    	else {
    		printk("Error mounting disk.\n");
    	}
    }

    The first if(disk_access_init..) returns -22.

    If I jump in disk_access_init, I then enter in disk_access_get_di, and I can see that it returns 0

    This fails to let me enter in the following if, thus returning -22.

    I am quite sure that it is a configuration problem of the SPI device, just because in my first tests I could at least print the Memory Size. Now I encounter this problem for every spi-max-freq that I set (1Mhz, 4Mhz, 8Mhz, 16Mhz)

    I'm planning to attach some logic analyzer probes asap, but I'm expecting to see no data being exchanged because of above.

    I tried to get rid of the mmc definition in the dts, but that didn't work.

    About the proj.conf, here there are the related config

    CONFIG_DISK_DRIVER_SDMMC=y
    CONFIG_DISK_ACCESS=y
    CONFIG_FILE_SYSTEM=y
    CONFIG_FAT_FILESYSTEM_ELM=y
    CONFIG_SPI=y

    Is there anything that I'm missing? Is there anything that can create conflict?

Related