nrf52840 usb msc qspi slow writing speed and losing frames

Hi, I have recently acquire an nrf52840 development board to prototype a usbd msc. With the example provided in sdk17.02-USBD_MSC, for saving every 1000 frames of data, 100 frames of data are lost.

The flash chip is mx25r6435.

// here saving_num = 1000.

if((saving_count < saving_num)&& writing_flag)
{

   char temp_value[100];
   sprintf(temp_value,"%d",time_count);
   memcpy(temp_value + strlen(temp_value),ENDLINE_STRING,sizeof(ENDLINE_STRING));
   NRF_LOG_INFO("%s",temp_value)
   ff_result = f_write(&file, temp_value, strlen(temp_value) - 1, (UINT *) &bytes_written);
   if (ff_result == FR_OK)
   {
       NRF_LOG_INFO("%d bytes written.", bytes_written);
    }
   else
   { 
       NRF_LOG_INFO("writing failed");
    }
   writing_flag = false;
   saving_count = saving_count +1;
    }
   if (saving_count == saving_num)
   {
       saving_count = saving_count +1;
       ff_result = f_sync(&file);
       if (ff_result == FR_OK)
       { 
          NRF_LOG_INFO("sync success.");
       }
  }

  • Hi

    Have you done an debugging to see if the QSPI writes report any "writing failed" messages at all. Can you upload a log so we can get a better picture of what's going on exactly? And what does this graph represent exactly?

    The slow write speed is a typical characteristic of NOR flash memory devices such as the mx25r6435. High read speed and slow write/erase speed. The mx25r6435 is perfect for execute in place (XIP) that executes program code directly from external flash.

    Best regards,

    Simon

  • hello Simon, thank you very for your response. I have set two Timers in the code. One is used to save the data into flash every 10ms. The other timer is 1ms and used to calculate the duration of saving.

    static void tx_timeout_handler(nrf_timer_event_t event_type, void * p_context)
    {
        ret_code_t err_code;
        switch (event_type)
        {
           case NRF_TIMER_EVENT_COMPARE0:
                    time_count_10ms = time_count_10ms + 1;
                   NRF_LOG_INFO("time out count = %d", time_count_10ms);
                   writing_flag = true;
                  break;
            default:
                  break;
       }
    }
    static void tx_timeout_handler_(nrf_timer_event_t event_type, void * p_context)
    {
        ret_code_t err_code;
    switch (event_type)
    {
         case NRF_TIMER_EVENT_COMPARE0:
                time_count_1ms = time_count_1ms + 1;
                break;
           default:
                 break;
       }
    }
    static void timers_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
        uint32_t time_ticks;
        uint32_t time_ms = 100;
        nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
        err_code = nrf_drv_timer_init(&TIMER_SEND, &timer_cfg, tx_timeout_handler);
        time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_SEND, time_ms);
        nrf_drv_timer_extended_compare(&TIMER_SEND, NRF_TIMER_CC_CHANNEL0, time_ticks,               NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);

        time_ms = 1;
        err_code = nrf_drv_timer_init(&TIMER_RECORD, &timer_cfg, tx_timeout_handler_);
        time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_RECORD, time_ms);
        nrf_drv_timer_extended_compare(&TIMER_RECORD, NRF_TIMER_CC_CHANNEL0, time_ticks,       NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
    }

    here is the code for saving, which is in main loop.

    if((saving_count < saving_num)&&writing_flag)
    {
        time_record_pre = time_count_1ms;
        NRF_LOG_INFO("COME TO WRITE TIME=%d",time_count_10ms);
        char temp_value[300];
        sprintf(temp_value,"%d",time_count_10ms);
        memcpy(temp_value + strlen(temp_value),ENDLINE_STRING,sizeof(ENDLINE_STRING));
        ff_result = f_write(&file, temp_value, strlen(temp_value) - 1, (UINT *) &bytes_written);
        if(ff_result == FR_OK)
         {
              NRF_LOG_INFO("%d bytes written.", bytes_written);
          }
         else
         {
                NRF_LOG_INFO("writing failed");
         }
        saving_count = saving_count +1;
        writing_flag = false;
         NRF_LOG_INFO("diff time = %d",time_count_1ms - time_record_pre);
        }
     if(saving_count == saving_num)
       {
              saving_count = saving_count +1;
              nrf_drv_timer_disable(&TIMER_SEND);
              ff_result = f_sync(&file);
        }

    As you see, sometimes the timer interrupt works and the writing_flag is changed. But in the main loop, the saving job doesn't work.

  • if I set the first timer interrupt to 100ms. Most of the time the saving duration is 0, but sometimes is 108. All of these projects are running with NRF52840 DK.

  • Hi again

    As mentioned in my last reply, our QSPI peripheral is not really suited for writing a bunch of data onto an external flash in quick succession.

    Either way, I think you should add some checks to check the return values of various functions to get a better picture of what functions are taking this extra time during some writes. It could be that it takes some extra time whenever a page is full or some other functions are also done in the time between the timer begins and the data is written and trigs the diff time.

    Best regards,

    Simon

Related