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

add timer in ble_app_uart

I am working on adding a timer in the ble_app_uart sample, aiming on disconnect with device which doesn't send any data in specific time, such as 5 seconds.

Now I have found an example "timer_pca10028", and try to insert useful part into my application. here is my mofified main function:

int main(void)
{
    uint32_t err_code;
    bool erase_bonds;
    uint8_t  start_string[] = START_STRING;
    
    // Initialize.
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false);
    uart_init();
    buttons_leds_init(&erase_bonds);
    ble_stack_init();
    gap_params_init();
    services_init();
    advertising_init();
    conn_params_init();
    
    printf("%s",start_string);

		err_code = nrf_drv_timer_init(&TIMER_LED, NULL, timer_data_receive_event_handler);
    //APP_ERROR_CHECK(err_code);
    
		uint32_t time_ticks;
    time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_LED, DATA_RECEIVE_TIMEOUT);
    
    nrf_drv_timer_extended_compare(
         &TIMER_LED, NRF_TIMER_CC_CHANNEL0, DATA_RECEIVE_TIMEOUT, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
    
		err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);
    // Enter main loop.
    for (;;)
    {
        power_manage();
    }
}

timer_data_receive_event_handler is my timer event handler, when I find the time is out and it doesn't get any message, 51822 terminates connection, :

void timer_data_receive_event_handler(nrf_timer_event_t event_type, void* p_context)
{ 
    switch(event_type)
    {
				uint32_t  err_code;
        case NRF_TIMER_EVENT_COMPARE0:
						if (!is_received_data){
							err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
							APP_ERROR_CHECK(err_code);
							nrf_drv_timer_disable(&TIMER_LED);
						}
            
            break;
        default:
            //Do nothing.
            break;
    }    
}

is_received_data is used for marking if I have received the data in nus_data_handler()

when the connection is established, I will start a timer like that:

static void on_ble_evt(ble_evt_t * p_ble_evt)
{
    uint32_t                         err_code;
    
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
						
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
						printf("%s","Device Connected:");
						nrf_drv_timer_enable(&TIMER_LED);
            break;
            ...
            ...

Now I have two problem:

  1. Does the sample "timer_pca10028" match my purpose? Can I set a timer imitating the sample code?
  2. nrf_drv_timer_enable(&TIMER_LED) in on_ble_evt cause the disconnection with mobile phone. If I remove this line, my application works as a normal ble_app_uart application at least. However when I enable it, the nrf UART app connects to the 51822 and disconnect automatically at the same time. But the LED on the dongle shows it is in a connected mode.

Could anyone help me? Thanks in advance!

Parents
  • I have not gone through the whole code, but these are the mistakes I could point out

    nrf_drv_timer_extended_compare(
             &TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks , NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
    

    The above function takes ticks values NOT DATA_RECEIVE_TIMEOUT

    1. which function is reseting is_received_data, i think it should be done in timer handler

      case NRF_TIMER_EVENT_COMPARE0: if (!is_received_data){ err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); APP_ERROR_CHECK(err_code); nrf_drv_timer_disable(&TIMER_LED); } else { is_received_data = 0; // reset it so that it is useful for next comparision }

    update_28.07.15

    I copied your code into ble_app_uart and added just one printf , it just worked ok image description The device is advertising and no hangs. I used S130 available in SDK9.0 on pca_100028. Check if you have not changed anything in app_uart, or better, try your code on fresh SDK9.0

  • OK, found the problem, you cannot use TIMER0 as it is reserved by softdevice. Please read the softdevice reference manual. In old softdevices this would have hardfaulted, but since the newer version does not write anything to UICR.CLENR0, the hardware protection is not enabled. So it is upto users to understand which peripherals are used by softdevice and not touch them. In your code , change

    const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(0);
    

    to

    const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(1);
    
Reply
  • OK, found the problem, you cannot use TIMER0 as it is reserved by softdevice. Please read the softdevice reference manual. In old softdevices this would have hardfaulted, but since the newer version does not write anything to UICR.CLENR0, the hardware protection is not enabled. So it is upto users to understand which peripherals are used by softdevice and not touch them. In your code , change

    const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(0);
    

    to

    const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(1);
    
Children
No Data
Related