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

HW timer issue

Hi,

  I'm trying to enable a HW timer (TIMER1) in my BLE application.  I'm using SDK 16, and following the pattern shown in examples/peripherals/timer.  However, when I get to nrf_drv_timer_enable(), I get a system reset before exiting this function.  Here is the relevant parts of my code -

const nrf_drv_timer_t SYSTEM_HW_TIMER = NRF_DRV_TIMER_INSTANCE(1);

static void _system_hw_timer_callback(nrf_timer_event_t event_type, void* p_context)
{
    switch (event_type)
    {
        case NRF_TIMER_EVENT_COMPARE0:
            ...
            
            break;

        default:
            break;
    }
}

static void system_timer_tick_init(void)
{
    ...

    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    uint32_t err_code = nrf_drv_timer_init(&SYSTEM_HW_TIMER, 
                                           &timer_cfg, 
                                           _system_hw_timer_callback);
    APP_ERROR_CHECK(err_code);

    uint32_t time_ticks = nrf_drv_timer_ms_to_ticks(&SYSTEM_HW_TIMER, 
                                                    SYSTEM_TIMER_TICK_TIME_MS);

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

    nrf_drv_timer_enable(&SYSTEM_HW_TIMER);  // This function never completes!!!
}

int main(void)
{
    ...
    // Initialize BLE
    ...
    system_timer_tick_init();
    ...
}
In sdk_config.h, I've enabled the timer, like this -
#ifndef NRFX_TIMER_ENABLED
#define NRFX_TIMER_ENABLED 1
#endif
// <q> NRFX_TIMER0_ENABLED  - Enable TIMER0 instance
 

#ifndef NRFX_TIMER0_ENABLED
#define NRFX_TIMER0_ENABLED 1
#endif

// <q> NRFX_TIMER1_ENABLED  - Enable TIMER1 instance
 

#ifndef NRFX_TIMER1_ENABLED
#define NRFX_TIMER1_ENABLED 1
#endif
  Note that I have removed all of the legacy defines in this file, including TIMER_ENABLED.
  Not sure if it's relevant, but I'm also using FreeRTOS in my project, although the scheduler has not been started when I hit this issue.  
  Any idea why my system crashes when I try to enable the hardware timer?
  Thanks...
Brian
Parents
  • Note that I have removed all of the legacy defines in this file, including TIMER_ENABLED.

     When you say that you have removed them, did you comment them out/delete them, or set them to 0? The reason I ask is because of a file called apply_old_config.h. Check it out.

    Did you enable logging in your project? Does your log say anything?

     

    I get a system reset before exiting this function.

     It sounds like the error handler is being called. Is that the case?

  • Hi Edvin,

      Yes - I've seen the legacy vs new peripheral defines.  I've removed the old ones rather than set them to 0.  However, I've also tried to go back and add the old timer configurations just for a test, but no difference in behavior. 

      I do not have the NRF logging enabled, but I have re-directed the logging output from the error handlers to the serial port.  So assert_nrf_callback is defined and should output serial data.  I've set a breakpoint on this function, in addition to app_error_fault_handler, but I never get to either of them.  Are there other error handlers I should be looking at?

      I'm using Timer1 and IRQ priority 6, which I believe should be fine as far as the S140 softdevice is concerned.  Are there other considerations I need to take into account?

      Thanks...

    Brian

  • You are not trying to use TIMER0 for your application, right? Remember that TIMER0 and RTC0 are used by the softdevice.

    Have you tried to set a breakpoint in the error handler? I suggest that you define "DEBUG" in your preprocessor definitions, and set a breakpoint on app_error_fault_handler() (line 57 in app_error.c). Try to put an APP_ERROR_CHECK(1) in your main() function to test that this breakpoint works properly. Also, use this to check if you need to disable optimization in order to see where the error handler comes from.

    Either way, what does nrf_drv_timer_enable return? If not NRF_SUCCESS, then what function call inside returns the error?

    BR,

    Edvin

  • Hi Edvin,

      I am using TIMER1, not TIMER0.

      I have set a breakpoint in app_error_fault_handler, but my code never hits the breakpoint.  I added the call to APP_ERROR_CHECK(1) for a test, and I do hit the breakpoint in that case.  I can see that app_error_fault_handler is called by app_error_handler, although this is the top of the stack.  I don't see where app_error_handler is being called from.  I have changed my compile optimization from -Og to -O0, with the same results.

      I have DEBUG already defined in my build.

      nrf_drv_timer_enable() is mapped to nrfx_timer_enable() in nrf_drv_timer.h.  This function is 4 lines long -

    void nrfx_timer_enable(nrfx_timer_t const * const p_instance)
    {
        NRFX_ASSERT(m_cb[p_instance->instance_id].state == NRFX_DRV_STATE_INITIALIZED);
        nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_START);
        m_cb[p_instance->instance_id].state = NRFX_DRV_STATE_POWERED_ON;
        NRFX_LOG_INFO("Enabled instance: %d.", p_instance->instance_id);
    }

        I can single-step into this function.  When I step from the 1st line to the 2nd line (which I believe starts the timer), the CPU resets and I go back to main.  I have set a breakpoint on the 3rd line of this function and I never hit it.  I have tried to set a long timeout for the timer (several seconds), but this has no affect.

      I've tested the code I'm using to setup the timer directly in the ble_app_hrs_freertos example code.  This code works fine.  The only other change I had to make was to enable the timer in sdk_config.h (#define TIMER1_ENABLED 1).  Bringing my version of sdk_config.h into this code causes it to also fail.  Therefore, it appears there is something in my sdk_config (attached several messages earlier) that is causing this problem.  I just have not been able to figure out which setting is causing the problem.

      So to answer your last question, nrf_drv_timer_enable never returns, nor does any function inside this function return an error.  The only thing I can see is the MCU resetting when I hit the 2nd line of this function.

      Any ideas on what to try next?

      Thanks...

    Brian

  • Only time for a cursory read, but it seems you would do well by replacing the default assert handler which is probably causing the reset; then it's easier to debug the code by putting a breakpoint on the handler. Add this to main.c:

    // Override the default handler which causes a reset, but track occurrences in case they need investigating
    static uint32_t ErrorHandlerCounter = 0;
    static uint32_t LastError_id = 0;
    static uint32_t LastError_pc = 0;
    void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
    {
       ErrorHandlerCounter++;
       LastError_id = id;
       LastError_pc = pc;
       NRF_LOG_INFO("Error: id %u, pc %u, count %u", LastError_id, LastError_pc, ErrorHandlerCounter);
    }

  • Brian said:
      I can single-step into this function.  When I step from the 1st line to the 2nd line (which I believe starts the timer), the CPU resets and I go back to main. 

     Does this mean that it resets during the NRFX_ASSERT(m_cb[p_instance->instance_id].state == NRFX_DRV_STATE_INITALIZED);?

    If so, then it is the assert. The timer is not initialized.

     

    Brian said:
      I've tested the code I'm using to setup the timer directly in the ble_app_hrs_freertos example code.  This code works fine.  The only other change I had to make was to enable the timer in sdk_config.h (#define TIMER1_ENABLED 1).

     I am sorry. It is hard to say what the issue is only by looking at the sdk_config.h file. Check if 's suggestion points to the assert. If it does, try to initialize the timer first.

    BR,

    Edvin

  • Thanks for the suggestions.  I've resolved the problem.  I'm using Monitor Mode Debugging, and breakpoints within ISR's do not seem to work as expected.  I actually was getting to the timer interrupt handler, but I was not using the FreeRTOS "FromISR" version of the function to release a semaphore.  Once I changed this code in the timer ISR, everything worked fine.

Reply Children
No Data
Related