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!

  • 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

  • Thanks for your help. After fixing the problem you mentioned above, my application can start properly. However when I enable nrf_drv_timer_enable(&TIMER_LED);, mobile phone still disconnect once it connects to the 51822. My whole code is here github.com/.../main.c

  • I will check your code later, common mistake when starting app_timer, have you increased APP_TIMER_MAX_TIMERS ? this needs to be done to allocate buffers for it.

  • 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);
    
  • Thank you very much. So any code relates to TIMER0 should be TIMER1? I have modified my code as you suggested, and set timer as 10000ms. Then program execute to case NRF_TIMER_EVENT_COMPARE1 immediately after the phone connect to 51822, rather than waiting 10 seconds.

Related