Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SDCard insert and mount

SDK 17

Soft device 7.2.0

nRF52840

Started with the 'fatfs' example, updated it to allow uninit, and to not reinit the IO if init is called multiple times.

it's working well. mount / unmount / remount, read / write, dir all works

However, if I eject the sd card and then reinsert it, now mounting; 'f_mount(%fs, "",1);'  fails with a FR_DISK_ERR in ff.c find volume()

Any ideas? is this a SPI issue?

Thanks

Keith Vasilakes

  • Hi Keith

    An FR_DISK_ERR from the find_volume() function points to an error in the disk I/O layer. What I'm guessing is happening, is that the mount process is already in progress when you reinsert the SD card, causing the mount to have a disk error. Can you try adding a reset when this occurs, so it can try mounting again, as I think the mount starting over should return successfully. Alternatively, wait for the SD card to be detected before starting the mount process.

    Best regards,

    Simon

  • "Wait for the SD card to be detected?" I don't have the detect line connected to any code.

    Everything is done manually through a CLLI at this point

    Before removing the code I un-initialize and unmount the card:

    static void sdEject(void)
    {
       if (f_mount(NULL, "", 0))
       {
          NRF_LOG_INFO("UnMount failed\r\n");
       }
       else
       {
          NRF_LOG_INFO("SD Card UnMounted");
          SDCinited = false;
    
          for (uint32_t retries = 3; retries && m_disk_state; --retries)
          {
             m_disk_state = disk_uninitialize(0);
    
          }
    
          if (m_disk_state)
          {
             NRF_LOG_INFO("Disk uninitialization failed.");
             return;
          }
    
          NRF_LOG_INFO("disk state : %d", m_disk_state);
          NRF_LOG_INFO("disk unitialized");
       }
    }

    I'm manually  calling init() from the CLI after I put the disk in

    static bool is_sd_present(void)
    {
       bool pin = false;
    
       if( GPIOinited)
       {
          //detect pin grounded when sd card inserted
          pin =  nrf_gpio_pin_read(SDC_CD_PIN) == 0;
       }
       else { NRF_LOG_INFO("SD Card IO not inited");}
    
       return pin;
    }

    void SDInit(nrf_cli_t const * p_cli, size_t argc, char ** argv)
    {
        FRESULT ff_result;
        static bool registered;
    
        if(false == SDCinited)
        {
           GPIOInit();
    
           NRF_LOG_INFO("Initializing SD Card");
    
           if(is_sd_present())
           {
           
              if(false == registered)
              {
                 registered = true;
    
                 // Initialize FATFS disk I/O interface by providing the block device.
                 static diskio_blkdev_t drives[] =
                 {
                      DISKIO_BLOCKDEV_CONFIG(NRF_BLOCKDEV_BASE_ADDR(m_SDCard_block_dev_sdc, block_dev), NULL),
                 };
    
                 diskio_blockdev_register(drives, ARRAY_SIZE(drives));
              }
    
              m_disk_state = STA_NOINIT;
    
              NRF_LOG_INFO("Initializing disk 0 (SDC)...");
              for (uint32_t retries = 3; retries && m_disk_state; --retries)
              {
                 NRF_LOG_INFO("retry.");
                  m_disk_state = disk_initialize(0);
              }
              if (m_disk_state)
              {
                  NRF_LOG_INFO("Disk initialization failed: %x", m_disk_state);
                  return;
              }
    
              uint32_t blocks_per_mb = (1024uL * 1024uL) / m_SDCard_block_dev_sdc.block_dev.p_ops->geometry(&m_SDCard_block_dev_sdc.block_dev)->blk_size;
              uint32_t capacity = m_SDCard_block_dev_sdc.block_dev.p_ops->geometry(&m_SDCard_block_dev_sdc.block_dev)->blk_count / blocks_per_mb;
              NRF_LOG_INFO("Capacity: %d MB", capacity);
    
              NRF_LOG_INFO("Mounting volume...");
    
              memset(&fs, 0, sizeof(fs));
    
              ff_result = f_mount(&fs, "", 1);
              if (ff_result)
              {
                  NRF_LOG_INFO("Mount failed; %x", ff_result);
                  return;
              }
              else
              {
                   NRF_LOG_INFO("Mount succeeded");
              }
     
              SDCinited = true;
    
          }
          else
          {
             NRF_LOG_INFO("No SD Card Inserted!");
          }
       }
       else
       {
          NRF_LOG_INFO("SD Card already initialized!");
       }
    
    
        return;
    }

    I don't see a reset() anywhere in the Fat files (ff.c) or the disk files (diskio_blkdev.c) Do you mean a processor reset???

  • Found it. In the eject function I was never calling disk_uninitialize() due to the check against m_disk_state being wrong it should look like this:

    for (uint32_t retries = 3; retries && (m_disk_state != STA_NOINIT); --retries)
          {
             m_disk_state = disk_uninitialize(0);
    
          }
    
          if (m_disk_state != STA_NOINIT)
          {
             NRF_LOG_INFO("Disk uninitialization failed.");
             return;
          }

Related