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

Stop and restart APP_TIMER doesn't work with SDK12

I use an app_timer to periodically update sensor reading in my application. There is a characteristic used to change updating rate by stopping and restarting the app_timer:

app_timer_stop(m_our_char_timer_id);
app_timer_start(m_our_char_timer_id, APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER), NULL); //1000ms
			

It works fine with SDK11. But with SDK12, I couldn't receive any data package after stopping and restarting the app_timer. Weird thing is, usually after 5 to 6 minutes, it resumes updating again.

Any help is appreciated. Thanks.

  • I started a new project with SDK12 and copied lines from the project with SDK11. Here are the lines related to app_timer in my project.

    APP_TIMER_DEF(m_our_char_timer_id);
    #define OUR_CHAR_TIMER_INTERVAL     APP_TIMER_TICKS(100, APP_TIMER_PRESCALER)
    
    static void timer_timeout_handler(void * p_context)
    {
          flag = true;
    }
    
    static void timers_init(void)
    {
               APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
               app_timer_create(&m_our_char_timer_id, APP_TIMER_MODE_REPEATED, timer_timeout_handler);
     }
    
     static void application_timers_start(void)
     {
            app_timer_start(m_our_char_timer_id, OUR_CHAR_TIMER_INTERVAL, NULL);
      }
    
     int main(void)
     {
                timers_init();
                application_timers_start();
      }
    
  • Here is the part changing interval using a characteristic

        // Update rate characteristic handler
    if(p_ble_evt->evt.gatts_evt.params.write.handle == p_our_service->char_handles_rate.value_handle)
    {
    	timer = true;
    	// Get data
    	sd_ble_gatts_value_get(p_our_service->conn_handle, p_our_service->char_handles_rate.value_handle, &rx_data);
    	switch(data_buffer){
    		case 0x10:// 10Hz
    		app_timer_stop(m_our_char_timer_id);
    		app_timer_start(m_our_char_timer_id, OUR_CHAR_TIMER_INTERVAL, NULL);
    		break;
    		case 0x02://2Hz
    		app_timer_stop(m_our_char_timer_id);
    		app_timer_start(m_our_char_timer_id, APP_TIMER_TICKS(500, APP_TIMER_PRESCALER), NULL); // 500ms
    		break;
    		case 0x05://5Hz
    		app_timer_stop(m_our_char_timer_id);
    		app_timer_start(m_our_char_timer_id, APP_TIMER_TICKS(200, APP_TIMER_PRESCALER), NULL); //200ms
    		break;
    		case 0x01://1Hz
    		app_timer_stop(m_our_char_timer_id);
    		app_timer_start(m_our_char_timer_id, APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER), NULL); //1000ms
    		break;
    		default:
    		break;
    	}
     }
    
  • I can’t see anything directly wrong with your code. But, you are not checking the return values of the function calls. So then you won’t get notified if thing goes wrong for some reason. I suggest that you modify your code to check for error codes, and then try debugging afterwards to check if you run into the error-handler.

    I.e. :

    uint32_t                err_code;
    
    
    err_code = sd_ble_gatts_value_get(p_our_service->conn_handle, p_our_service->char_handles_rate.value_handle, &rx_data);
    
    APP_ERROR_CHECK(err_code);
    
    
    err_code = app_timer_stop(m_our_char_timer_id);
    
    APP_ERROR_CHECK(err_code);
    	
    	
    err_code = app_timer_start(m_our_char_timer_id, OUR_CHAR_TIMER_INTERVAL, NULL);
    
    APP_ERROR_CHECK(err_code);
    
  • I'll try that. Questions about the debugging setup, from app_error.c the app_error_handler doesn't look like the same as before. Where should I place a break point now?

    void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
    {
          error_info_t error_info =
        {
            .line_num    = line_num,
            .p_file_name = p_file_name,
             .err_code    = error_code,
         };
           app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
    
         UNUSED_VARIABLE(error_info);
     }
    

    Another question is I'm using Eclipse and GCC instead of Keil, where should I define DEBUG?

  • You should place it in the function app_error_save_and_stop() in app_error.c. Line 141 ( while (loop); ).

    You should define debug in the makefile. I.e. CFLAGS += -DDEBUG

    In order to debug you need to have the -g3 flag and remove compiler optimization (to get expected debug results). So you need to have CFLAGS += -Wall -Werror -O0 -g3

Related