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

disconnect with reason BLE_HCI_CONNECTION_TIMEOUT after battery ADC

Hello,

I recently tested the nRF51822 with a non-Nordic BLE devices and encountered some problems. When testing with Nordic the connection is maintained with no problem, but while testing using TI's dongle or an android phone the connection is getting dropped. I traced the problem down to an ADC event for the battery read. It seems the ADC IRQ is causing a slight delay which the nordic pca100000 dongle can compensate for but other vendor devices do not.

soft device s110 6.0.0 sdk 5.1.0 target board pac10001 v2.2.0 2014.06

I added some debug signals on gpio to the radio_notification_event and I see 1 mS delay in the radio notification after the ADC event.

If I remove the TASKS_START=1 from the battery_start() routine the connection does not drop, therefore the ADC is certainly related to the problem.

This problem happens even when the connection interval is increased to 500 or slave latency is increased to 1.

/@brief Function for initializing the Radio Notification event handler. */ static void radio_notification_init(void) { uint32_t err_code; err_code = ble_radio_notification_init(NRF_APP_PRIORITY_HIGH, NRF_RADIO_NOTIFICATION_DISTANCE_4560US, on_radio_active_evt); APP_ERROR_CHECK(err_code); } Here is some relevant code: /@brief Function for initializing the Radio Notification event handler. */ static uint8_t radio_pending; void on_radio_active_evt(bool radio_active) { radio_pending = radio_active; if (radio_active) { nrf_gpio_pin_set(DEBUG_LED_1); scale_timer_started=0; } else { //radio not active nrf_gpio_pin_clear(DEBUG_LED_1); if (do_battery_read) { battery_start(); do_battery_read=0; } }

static void batt_meas_timeout_handler(void * p_context) { UNUSED_PARAMETER(p_context); if (radio_pending ) { do_battery_read=1; } else { battery_start(); do_battery_read=0; } }

/**@brief Function for making the ADC start a battery level conversion. */ void battery_start(void) { uint32_t err_code; nrf_gpio_pin_set(DEBUG_LED_0); while(NRF_ADC->BUSY) {} // Configure ADC NRF_ADC->INTENSET = ADC_INTENSET_END_Msk; NRF_ADC->CONFIG = (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos) | (BATTERY_MEASURE_INPSEL << ADC_CONFIG_INPSEL_Pos) | (BATTERY_MEASURE_REFSEL << ADC_CONFIG_REFSEL_Pos) | (BATTERY_MEASURE_PSEL << ADC_CONFIG_PSEL_Pos) | (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); NRF_ADC->EVENTS_END = 0; NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;

// Enable ADC interrupt
err_code = sd_nvic_ClearPendingIRQ(ADC_IRQn);
APP_ERROR_CHECK(err_code);

err_code = sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);
APP_ERROR_CHECK(err_code);

err_code = sd_nvic_EnableIRQ(ADC_IRQn);
APP_ERROR_CHECK(err_code);

NRF_ADC->EVENTS_END  = 0;    // Stop any running conversions.
NRF_ADC->TASKS_START = 1;

}

void ADC_IRQHandler(void) { if (NRF_ADC->EVENTS_END != 0) { uint16_t adc_result; NRF_ADC->EVENTS_END = 0; adc_result = NRF_ADC->RESULT; NRF_ADC->TASKS_STOP = 1; #if 0 battery_convert_adc_to_level(adc_result); scale_adc_config(); #endif nrf_gpio_pin_clear(DEBUG_LED_0); }

Parents
  • Hi, I am also concerned if this issue will be a problem when moving from iphone to android implementation. What I read is that there is some differences in how iOS and android implements BLE, but should today be no problem in android 4.x.

    First I was woundering what the functions called in ADC irq handler was doing, not a good practice to do lengthy jobs in irq handler, better set a flag or value and execute in main loop or put sched event i this case with Nordic sdk code.

    But couldn't this be the issue with calling BLE stack sd_ functions from a higher priority level? The function battery_start (with sd calls) is called from the radio_notify_evt which in prio high. Search for Hard falt, or does this high level restriction just apply certain sd (softdevice) function calls??

    My understanding of calling ble stack/soft device with a higher priority is that it can be busy and doesn't allow any higer level "user land" code override and alter the ble internal state, therefor it catch it as hard falt cause it can be "unsafe"?

Reply
  • Hi, I am also concerned if this issue will be a problem when moving from iphone to android implementation. What I read is that there is some differences in how iOS and android implements BLE, but should today be no problem in android 4.x.

    First I was woundering what the functions called in ADC irq handler was doing, not a good practice to do lengthy jobs in irq handler, better set a flag or value and execute in main loop or put sched event i this case with Nordic sdk code.

    But couldn't this be the issue with calling BLE stack sd_ functions from a higher priority level? The function battery_start (with sd calls) is called from the radio_notify_evt which in prio high. Search for Hard falt, or does this high level restriction just apply certain sd (softdevice) function calls??

    My understanding of calling ble stack/soft device with a higher priority is that it can be busy and doesn't allow any higer level "user land" code override and alter the ble internal state, therefor it catch it as hard falt cause it can be "unsafe"?

Children
No Data
Related