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

SD card only works at 8MHz with FatFS and FreeRTOS

Hello,

I'm working on NRF52840 drivers for custom hardware using Nordic's FatFS / SDIO drivers and a tickless FreeRTOS configuration. When I load the demo code (fatfs demo, no FreeRTOS) I am able to run the SD card at any speed I want up to the max 8MHz. However, when I load my code, the SD card gets initialized but when the first command is issued (f_mount), it gets stuck in default_wait_func under diskio_blkdev.c and loops forever i.e  block_dev_handler never gets triggered and the busy bit remains true. I am running f_mount out of the main task, not from an interrupt and the hardware seems to work just fine at 8MHz. I am concerned that this issue may cause problems with robustness of my code down the road so would like to get to the bottom of it. Hope you can provide some advice as to where I should look to debug this further, thanks in advance!

  • Which SDK version are you using? it seems that an FDS event has been missed to handle which was an issue with earlier SDK versions when combined with FreeRTOS. This is mentioned here. If you see this in the latest SDK 16 , then it must be something else that we need to investigate

  • Hi Susheel, thanks for your response, my project is based on SDK 15.2, we were running into some issues with compatibility with our version of Keil and SDK 16, therefore, have not updated yet. In either case, I implemented the fix from the post you linked and it solved the problem ... I would have never guessed that this was it. Thank you!

    For reference, here's the solution:

    void SD_EVT_IRQHandler(void)
    {
         BaseType_t xYieldRequired;
    
         //xYieldRequired = xTaskResumeFromISR( m_softdevice_task );
         vTaskNotifyGiveFromISR(m_softdevice_task, &xYieldRequired);
    
         if( xYieldRequired == pdTRUE )
         {
             portYIELD_FROM_ISR(xYieldRequired);
         }
    }
    
    
    /* This function gets events from the SoftDevice and processes them. */
    static void softdevice_task(void * pvParameter)
    {
        NRF_LOG_DEBUG("Enter softdevice_task.");
    
        if (m_task_hook != NULL)
        {
            m_task_hook(pvParameter);
        }
    
        while (true)
        {
            nrf_sdh_evts_poll(); // Let the handlers run first, in case the EVENT occured before creating this task.
            //vTaskSuspend(NULL);
    
          (void) ulTaskNotifyTake(pdTRUE,         /* Clear the notification value before exiting (equivalent to the binary semaphore). */
                          portMAX_DELAY); /* Block indefinitely (INCLUDE_vTaskSuspend has to be enabled).*/
    
        }
    }

Related