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

nRF52840 crashes when changing manufacturer data from SAADC handler callback

Hi everyone,


I am using an nRF52840 dongle (MakerDiary) with SDK15.0 & SoftDevice S140 v6.0.0, and trying to change the BLE advertising manufacturer's data with the information from the SAADC reading. I wrote a small function "set_mfg_data()" that stops BLE advertising, updates the manufacturer's data, and then restarts the advertising. In my project, I made it so that when the button on the dongle is pressed, the button handler calls "nrf_drv_saadc_sample()" to start the ADC conversion, and the SAADC event handler function looks for the  "NRF_DRV_SAADC_EVT_DONE" event, and when that event occurs, it calls my "set_mfg_data()" function to update the manufactuerer's data with the new SAADC reading. However, in this configuration, the nRF52840 crashes when it's trying to update the manufacturer's data, and just goes into the DFU/bootloader mode.

I confirmed that my "set_mfg_data()" function works properly by moving it out of the SAADC event handler callback function, to the button_press event handler function. With each press, I am seeing the advertised manufacturer's data change as expected. Can anyone shed any light as to why the device might be crashing when I attempt to change advertised manufacturer's data from within the SAADC event handler callback function?

Here is some of my code, here is the "set_mfg_data()" function:

static void set_mfg_data(nrf_saadc_value_t adc_bits)
{
    ret_code_t    err_code;
	
    adv_manuf_data_data[0] = (uint8_t)((adc_bits & 0xFF00) >> 8);
    adv_manuf_data_data[1] = (uint8_t)(adc_bits & 0x00FF);

    
    err_code = sd_ble_gap_adv_stop(m_adv_handle); //Stop advertising
    APP_ERROR_CHECK(err_code);

    adv_manuf_data.data.p_data        = adv_manuf_data_data;
    adv_manuf_data.data.size          = sizeof(adv_manuf_data_data);
    //adv_manuf_data.company_identifier = 0x0059; //Nordic's company ID

    //sprintf(adv_manuf_data_data,"%f", 3.123);

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG); //Restart advertising
    APP_ERROR_CHECK(err_code);
    
}

Here is the SAADC event handler callback function that seems to crash the device. When the line with "set_mfg_data()" is commented out, it doesn't crash:

void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
    ret_code_t err_code;
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)                                                        //Capture offset calibration complete event
    {		
        set_mfg_data(m_buffer_pool[0][0]);
        bsp_board_led_on(ADVERTISING_LED);
        //set_mfg_data((nrf_saadc_value_t)0xAA55);
        
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], 1);             //Set buffer so the SAADC can write to it again. 
        APP_ERROR_CHECK(err_code);
    }
}

  • I actually figured it out. I was calling a different function that changes advertising interval right after kicking off the SAADC conversion. So I think what was happenning was that there was a race condition, and the SAADC was finishing the conversion, and calling my "set_mfg_data()" function at the same time as when the other function changing advertising interval was running, and this was most likely causing the crash. Both functions interact with the SoftDevice, and I am pretty sure this is what was causing the crash. I hope this helps others!

Related