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

Flash and BLE simultaneously creating hardfault

I am using nrf51822. Separately BLE and flash are working perfectly alright. But when I comment  err_code = ble_advertising_start(BLE_ADV_MODE_FAST); this line flash is working alright. Vice versa when I comment  flash_packet_transfer(arr,sizeof(arr)); this line BLE working fine. But simultaneously creating hardfault. 

uint8_t arr[18] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17};
int main(void)
{
    ble_stack_init();
    gap_params_init();
    services_init();
    advertising_init();
    conn_params_init();
    err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    for(;;){
          
          flash_packet_transfer(arr,sizeof(arr));
          packet_num++;
          nrf_delay_ms(5000); 
          NRF_LOG_FLUSH();
    }
}
void flash_packet_transfer(uint8_t *data,uint8_t len)
{
    uint32_t  addr;
    uint32_t   pg_size;
    uint32_t   flash_write_word;
    
    uint32_t   pg_num;
    uint32_t flash_addr;
    uint32_t *ptr;
    uint8_t buf_count;
    uint8_t previous_date = 0;
    uint8_t date_count =0;
    
    data_buffer_t data_buf;
    uint32_t flash_add_storage_location = 0x33800;
  
    pg_size = NRF_FICR->CODEPAGESIZE;
    addr = (FLASH_START_ADDR+ (packet_num * (len+2)));
    
   
    flash_page_erase((uint32_t *)flash_add_storage_location);
    flash_word_write((uint32_t *)flash_add_storage_location, addr);
   
    if(addr % pg_size ==0){
      flash_page_erase((uint32_t *)addr);
      
    }
    ptr = (uint32_t *)addr;
    
    for(uint8_t i=0;i<len;i=i+4){ 
      flash_write_word = ((data[i+3] << 24) | (data[i+2] << 16) | (data[i+1] << 8) | data[i]);
      flash_word_write(ptr,flash_write_word);
      ptr = ptr+1;
    }
}

  • Hi,

    When the SoftDevice is enabled, the functions sd_flash_erase/write have to be used for erase/write operations. If you try to access the NVMC directly when the SoftDevice is enabled, it will result in a hardfault. See this, this and this link.

  • I changed my APIs with sd_flash_write but still having hardfault. Even normal 

    void flash_packet_transfer(uint8_t *data,uint8_t len)
    {
        uint32_t  addr;
        uint32_t   pg_size;
        uint32_t   flash_write_word;
        
        uint32_t   pg_num;
        uint32_t flash_addr;
        uint32_t *ptr = NULL;
        uint8_t buf_count;
        uint8_t previous_date = 0;
        uint8_t date_count =0;
        
        data_buffer_t data_buf;
        uint32_t flash_add_storage_location = 0x33800;
      
        pg_size = NRF_FICR->CODEPAGESIZE;
        addr = (FLASH_START_ADDR+ (packet_num * (len+2)));
        
       
       
        sd_flash_page_erase(206);
        sd_flash_write((uint32_t *)flash_add_storage_location,(uint32_t *)addr,1);
       
       
        if(addr % pg_size ==0){
            sd_flash_page_erase(207);
        }
        ptr = (uint32_t *)addr;
        
        for(uint8_t i=0;i<len;i=i+4){ 
          flash_write_word = ((data[i+3] << 24) | (data[i+2] << 16) | (data[i+1] << 8) | data[i]);
          sd_flash_write(ptr,(uint32_t *)flash_write_word,1);
          ptr = ptr+1;
        }
    }
    flash read and write not working with this. What should I include to work with this APIs

  • What SDK version are you using ?

    What is the value of FLASH_START_ADDR in the code snippet you posted ?

    Could you upload a project that shows this issue ?

  • I have solved my problem here is my code. When BLE is turned on and as soon as you stop your code using
    breakpoint and start it again, it's missed hundreds of ticks during which it had things it needed to do,
     the internal checks inside the softdevice then fail and the device faults, errors or hardfaults.

    void flash_packet_transfer(uint8_t *data,uint8_t len)
    {
        static uint32_t  addr;                  /*sd_flash_write function does not keep the data pointer alive, the variable needs to be static */
        static uint32_t   flash_write_word;
        uint32_t   pg_size;
        uint32_t *ptr;
        uint8_t days_count=0;
        
        data_buffer_t data_buf;
        uint32_t flash_add_storage_location = 0x33800;
      
        pg_size = NRF_FICR->CODEPAGESIZE;
        addr = (FLASH_START_ADDR+ (packet_num * len));
    
        while(sd_flash_page_erase(flash_add_storage_location/pg_size)== NRF_ERROR_BUSY);
        nrf_delay_ms(1000);
    
        while(sd_flash_write((uint32_t *)flash_add_storage_location,&addr,1)== NRF_ERROR_BUSY);  /* This will store flash latest location which has been filled */
        nrf_delay_ms(1000);
    
        if(addr % pg_size ==0){
          while(sd_flash_page_erase(addr/pg_size)== NRF_ERROR_BUSY);
          nrf_delay_ms(1000);
        }
        ptr = (uint32_t *)addr;
        
        for(uint8_t i=0;i<len;i=i+4){ 
          flash_write_word = ((data[i+3] << 24) | (data[i+2] << 16) | (data[i+1] << 8) | data[i]);
          while(sd_flash_write(ptr,&flash_write_word,1)== NRF_ERROR_BUSY);
          nrf_delay_ms(1000);
          ptr = ptr+1;
        }
        packet_num++;
    }
    

Related