This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SD Card, FATFS, nRF52832 -> Can't initialize if first initialization fails.

Hello,

I'm currently working on a project that requires data to be stored to an microSD.  I'm using a custom board with the nRF52832 chipset and a Molex micro SD card holder.  I can successfully initialize the SD card via FATFS once the firmware boots up, but only if the SD card is inserted before power is turned on. If I have the SD card inserted when I power on, I can successfully write and read from the SD card, no issues there.  The issue is if I attempt to insert the SD card after the device has turned on, for the life of me I can't initialize it.

The idea is that if the user doesn't have the card inserted at startup it will fail initialization (that's fine), if the user inserts the card afterwards and attempts to record data, the firmware will attempt to initialize FATFS again (via disk_initialize(0)).  This always fails.  Is there a way to to initialize FATFS after an initialization has already failed?

Thanks,

Daniel

Parents
  • Hi,

    I have reproduced this on my side as well using DK 15.2. It seems the internal state of nrf_block_dev_sdc.c (m_active_sdc_dev) becomes invalid, as it is not uninitialized. Therefore, it will always return NRF_ERROR_BUSY after the first unsuccessful attempt. The following two minor diffs shows what seems like a quick fix:

    diff --git a/external/fatfs/port/diskio_blkdev.c b/external/fatfs/port/diskio_blkdev.c
    index 43b0a7e..2323f8c 100644
    --- a/external/fatfs/port/diskio_blkdev.c
    +++ b/external/fatfs/port/diskio_blkdev.c
    @@ -125,6 +125,10 @@ DSTATUS disk_initialize(BYTE drv)
                 m_drives[drv].state &= ~STA_NOINIT;
             }
         }
    +    else
    +    {
    +        ret_code_t err_code = nrf_blk_dev_uninit(m_drives[drv].config.p_block_device);
    +    }
     
         return m_drives[drv].state;
     }
    

    diff --git a/modules/nrfx/drivers/src/nrfx_spim.c b/modules/nrfx/drivers/src/nrfx_spim.c
    index 13128c3..ab41134 100644
    --- a/modules/nrfx/drivers/src/nrfx_spim.c
    +++ b/modules/nrfx/drivers/src/nrfx_spim.c
    @@ -350,6 +350,12 @@ nrfx_err_t nrfx_spim_init(nrfx_spim_t  const * const p_instance,
     void nrfx_spim_uninit(nrfx_spim_t const * const p_instance)
     {
         spim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
    +
    +    if (p_cb->state == NRFX_DRV_STATE_UNINITIALIZED)
    +    {
    +        return;
    +    }
    +
         NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
     
         if (p_cb->handler)
    

    I will report this internally as a bug.

Reply
  • Hi,

    I have reproduced this on my side as well using DK 15.2. It seems the internal state of nrf_block_dev_sdc.c (m_active_sdc_dev) becomes invalid, as it is not uninitialized. Therefore, it will always return NRF_ERROR_BUSY after the first unsuccessful attempt. The following two minor diffs shows what seems like a quick fix:

    diff --git a/external/fatfs/port/diskio_blkdev.c b/external/fatfs/port/diskio_blkdev.c
    index 43b0a7e..2323f8c 100644
    --- a/external/fatfs/port/diskio_blkdev.c
    +++ b/external/fatfs/port/diskio_blkdev.c
    @@ -125,6 +125,10 @@ DSTATUS disk_initialize(BYTE drv)
                 m_drives[drv].state &= ~STA_NOINIT;
             }
         }
    +    else
    +    {
    +        ret_code_t err_code = nrf_blk_dev_uninit(m_drives[drv].config.p_block_device);
    +    }
     
         return m_drives[drv].state;
     }
    

    diff --git a/modules/nrfx/drivers/src/nrfx_spim.c b/modules/nrfx/drivers/src/nrfx_spim.c
    index 13128c3..ab41134 100644
    --- a/modules/nrfx/drivers/src/nrfx_spim.c
    +++ b/modules/nrfx/drivers/src/nrfx_spim.c
    @@ -350,6 +350,12 @@ nrfx_err_t nrfx_spim_init(nrfx_spim_t  const * const p_instance,
     void nrfx_spim_uninit(nrfx_spim_t const * const p_instance)
     {
         spim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
    +
    +    if (p_cb->state == NRFX_DRV_STATE_UNINITIALIZED)
    +    {
    +        return;
    +    }
    +
         NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
     
         if (p_cb->handler)
    

    I will report this internally as a bug.

Children
  • This solved the problem.  I should've mentioned I'm currently using SDK 14.2.0, but I found the corresponding lines to fix (nrf_drv_spi.c -> nrf_drv_spi_uninit and diskio_blkdev.c-> disk_initialize).

    Thank you.

    Edit: It stopped working a few days later and it took me a little while to figure out why. The SD card isn't the only peripheral on the bus, and at some point the pull configuration changed.  In the sdk_config.h you need to set the NRF_SPI_DRV_MISO_PULLUP_CFG flag to 3 (pullup). If you use NOPULL or PULLDOWN it won't work.

Related