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

App timer in mesh

Hi everyone.

In mesh light switch example., i try to add timer0 (or any timer).

After initialize timer, application always jump to timeout event, and i don't know why.

My code working perfectly in nRF SDK v15, but not working in Mesh SDK.

Any body have a solution to add timer into mesh project?

Here is my timer_config function.

const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(0);
void timeout_config(uint32_t milisecond)
{
    uint32_t time_ms = milisecond; //Time(in miliseconds) between consecutive compare events.
    uint32_t time_ticks;
    uint32_t err_code = NRF_SUCCESS;
    
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    err_code = nrf_drv_timer_init(&TIMER_PROVISION, &timer_cfg, provision_timeout_event_handler);
    APP_ERROR_CHECK(err_code);

    // time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_PROVISION, time_ms);

    nrfx_timer_compare(&TIMER_PROVISION,
                        NRF_TIMER_CC_CHANNEL1,
                        time_ms,
                        true);
     nrf_drv_timer_enable(&TIMER_PROVISION);
}

 

My event handle function

void provision_timeout_event_handler(nrf_timer_event_t event_type, void* p_context)
{
    switch (event_type)
    {
        case NRF_TIMER_EVENT_COMPARE0:
            bsp_board_led_invert(1);
            break;

        default:
            //Do nothing.
            break;
    }
}


main:

int main()
{
    timeout_config(5000);       // 5000ms
    timeout_start();
    initialize();
    execution_start(start);
    while(1) {}
}

Thank you so much!

Parents Reply Children
  • I was preparing a long answer, to give you an intuition of how the TIMER peripheral/TIMER driver works, but it seems like you found the core of the problem. However, I will provide the answer anyways:

    In the code I provided the TIMER is in Timer mode, and in Timer mode the TIMER's counter register will be incremented for every tick generated by the timer. The TIMER peripheral also has compare registers, which can be set to a value. Then, by comparing the counter register to this value, a COMPARE event can be triggered.

    But what decides how often a tick is generated? The frequency f_timer decides this (ticks/second), which can be calculated in the following manner(if f_timer is above 1 MHz):

    When calling nrf_drv_timer_init(..) the frequency will be sent in as an argument (timer_cfg.frequency in the code provided), then the PRESCALER will be set accordingly such that f_timer corresponds to that frequency. This function requires an argument of type nrf_drv_timer_config_t, which can be set through NRF_DRV_TIMER_DEFAULT_CONFIG, which will fetch the values used in the sdk_config.h file. Then it is important to check if  these values is according to your needs. For example the bit width, which was the cause of your problem. If this is not set to 32 bits, then the whole compare register wont be used, and the compare value might be different from what intended.

    In the next step, the following code is executed:

    time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_PROXY, time_ms);
    
    nrf_drv_timer_extended_compare(&TIMER_PROXY,
                        NRF_TIMER_CC_CHANNEL1,
                        time_ticks,
                        NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK,
                        true);
    nrf_drv_timer_enable(&TIMER_PROXY);

    The function nrf_drv_timer_ms_to_ticks(..) will convert milliseconds to ticks, by using the formula provided above. Then the compare register will be set to the calculated ticks through the function nrf_drv_timer_extended_compare(..). Eventually the timer is enabled through nrf_drv_timer_enable(..).

    Best regards, Simon

Related