How to correctly re-start the SD Card interface (SPI)

Hey all,

I'm working on a project where data gets written to an SD Card regularly. At reset, power to 3.3V to the SD card is activated and all runs relatively well.

I'd like to be able to turn off the SD card power when the system is not logging, and go through the SD card reactivation process once I need to start logging again. I'm not planning to reset the microcontroller (NRF52840), instead, just running the minimum apps and threads possible. I'll look into low power modes later on.

The problem I'm facing is that the SPI interface to the SD card does not get reset after toggling power to the SD card power domain. On a system reset everything works fine.

With the following options:

CONFIG_SD_LOG_LEVEL_DBG=y
CONFIG_SDHC_LOG_LEVEL_DBG=y

I can see at reset time (this is just debug information about all working well):

[00:00:02.404,815] <dbg> sd: sd_init_io: Resetting power to card
[00:00:02.408,447] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd0 arg 0x0
[00:00:02.409,210] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd8 arg 0x1aa
[00:00:02.409,942] <dbg> sd: sd_send_interface_condition: Found SDHC with CMD8 support
[00:00:02.409,973] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd59 arg 0x1
[00:00:02.410,705] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd58 arg 0x0
[00:00:02.411,560] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.412,292] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.423,095] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.423,858] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.434,661] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.435,394] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.446,197] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.446,929] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.457,733] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.458,526] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.469,299] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.470,062] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.480,895] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.481,658] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.492,492] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.493,255] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.504,089] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.504,852] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.515,686] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.516,448] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.527,343] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.528,076] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
--- 13 messages dropped ---
[00:00:02.609,252] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.620,056] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.620,819] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd41 arg 0x40000000
[00:00:02.621,582] <dbg> sd: sdmmc_send_ocr: SDMMC responded to ACMD41 after 18 attempts
[00:00:02.622,192] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd58 arg 0x40000000
[00:00:02.622,955] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd10 arg 0x0
[00:00:02.624,359] <dbg> sd: card_read_cid: Card MID: 0x3, OID: DS
[00:00:02.624,389] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd9 arg 0x0
[00:00:02.625,732] <dbg> sd: sdmmc_read_csd: Card block count 62333952, block size 512
[00:00:02.625,732] <inf> sd: Maximum SD clock is under 25MHz, using clock of 4000000Hz
[00:00:02.625,762] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd55 arg 0x0
[00:00:02.626,098] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd51 arg 0x0
[00:00:02.626,739] <dbg> sd: sdmmc_read_scr: SD reports specification version 8
[00:00:02.626,770] <inf> sd_card: Storage init OK!
[00:00:02.626,831] <inf> sd_card: Block count 62333952
[00:00:02.626,861] <inf> sd_card: Sector size 512
[00:00:02.626,861] <inf> sd_card: Memory Size(MB) 30436
[00:00:02.626,953] <dbg> sd: card_read: READ: Sector = 0, Count = 1
[00:00:02.626,983] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd17 arg 0x0
[00:00:02.630,035] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd13 arg 0x0
[00:00:02.630,218] <dbg> sd: card_read: READ: Sector = 8192, Count = 1
[00:00:02.630,249] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd17 arg 0x2000
[00:00:02.633,056] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd13 arg 0x0
[00:00:02.633,178] <dbg> sd: card_read: READ: Sector = 8193, Count = 1
[00:00:02.633,209] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd17 arg 0x2001
[00:00:02.635,986] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd13 arg 0x0
[00:00:02.736,175] <inf> sd_card: SD Card Init!

You see that the SPI functions are being called to read the SD card, especially the "sd_init_io" part.

After a no-activity timeout I dismount the SD card and turn off the 3.3V domain where the SD card lives.

static void deinit_peripherals(void)
{
    sd_deinit();
    k_sleep(K_MSEC(50));
    disable_3v3_domain();
    peripherals_initd = false;
}

int sd_deinit(void)
{
	int res = fs_unmount(&mp);

	if (res != FR_OK)
	{
		LOG_ERR("Error unmounting disk.");
        return -1;
	}
    
	/* raw disk i/o */
	LOG_INF("SD Card unmounted!");
    k_thread_abort(sd_card_tid);
    return 0;
}

The functions are called OK, as I get no errors returning from them.

Now comes the issue, if I turn on the 3.3V domain, wait a moment and then try to use the SD card, it seems to me from the logs that all the SPI initialisation is avoided, as I get only this instead of the debug messages above:

[00:00:43.332,519] <inf> sd_card: Storage init OK!
[00:00:43.332,550] <inf> sd_card: Block count 62333952
[00:00:43.332,550] <inf> sd_card: Sector size 512
[00:00:43.332,611] <inf> sd_card: Memory Size(MB) 30436
[00:00:43.332,641] <dbg> sd: card_read: READ: Sector = 0, Count = 1
[00:00:43.332,702] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd17 arg 0x0
[00:00:43.333,282] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd17 arg 0x0
[00:00:43.333,923] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd17 arg 0x0
[00:00:43.334,472] <dbg> sdhc_spi: sdhc_spi_send_cmd: cmd17 arg 0x0
[00:00:43.335,083] <err> sd: Failed to read from SDMMC -116
[00:00:43.335,083] <err> sd: Card read failed
[00:00:43.335,113] <err> fs: fs mount error (-5)
[00:00:43.335,113] <err> sd_card: Error mounting disk.

My question then is, how can I tell the SD card system to reinitialise everything, SPI interface, etc? I'm happy to do a full reset of any peripheral related to the SD card, that is, SPI0, if that works, but basically I'd like to have a clean slate for the SD Card driver.

Any help is appreciated.

Cheers,

Alberto

Related