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

nrf51822 app timer

Hi

I am trying to broadcast manufacturer data (beacon example) while changing data from second to second. For that I am trying to use timer2 (as timer 0 is used by SD, right).

...


void start_timer(void)
{
NRF_TIMER2->MODE = TIMER_MODE_MODE_Counter; // Set the timer in Counter Mode
NRF_TIMER2->TASKS_CLEAR = 1; // clear the task first to be usable for later
NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit; //Set counter to 16 bit resolution
NRF_TIMER2->CC[0] = 5000; //Set value for TIMER2 compare register 0
NRF_TIMER2->CC[1] = 5; //Set value for TIMER2 compare register 1

// Enable interrupt on Timer 2, both for CC[0] and CC[1] compare match events
NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos) | (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
NVIC_EnableIRQ(TIMER2_IRQn);

NRF_TIMER2->TASKS_START = 1; // Start TIMER2
}

//IMTER2 peripheral interrupt handler. This interrupt handler is called whenever there it a TIMER2 interrupt

void TIMER2_IRQHandler(void)
{
if ((NRF_TIMER2->EVENTS_COMPARE[0] != 0) && ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0))
{
NRF_TIMER2->EVENTS_COMPARE[0] = 0; //Clear compare register 0 event
nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); //Set LED
}

if ((NRF_TIMER2->EVENTS_COMPARE[1] != 0) && ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE1_Msk) != 0))
{
NRF_TIMER2->EVENTS_COMPARE[1] = 0; //Clear compare register 1 event
nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); //Clear LED
}
}


int main(void)
{
//Initialization Zone
leds_init();


start_timer();

ble_stack_init();
advertising_init();
// Start execution.
advertising_start();
// Enter main loop.
for (;;)
{
power_manage();

}
}

No compiling errors but

If I call start_timer(); the whole program hangs (LED does not light)

Please, how to use timer?

Env: old rev nrf51822, softdevice 110 version 7 (recent SD make the app not work :-(   and SDK 6)

Imo

Parents
  • Thanks for your explanation. Very clear!

    PS: I called app timer on the subject due to "app layer" timer creation but it seems that there is an code class to address it with the same name. Thanks! I am going to read about it

  • Yeah, I know you didn't literally mean app_timer.  That was just my bad attempt at a pun.

    This is based on SDK11, but I think it is similar for all. Everything can be put in main.c if you wish.

    #include "app_timer.h"

    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);

    APP_TIMER_DEF(m_your_timer_id);
    err_code = app_timer_create(&m_your_timer_id, APP_TIMER_MODE_REPEATED, your_timer_handler);
    APP_ERROR_CHECK(err_code);
                    
    err_code = app_timer_start(m_your_timer_id, APP_TIMER_TICKS(3630000, APP_TIMER_PRESCALER), NULL);
    APP_ERROR_CHECK(err_code);

    static void your_timer_handler(void * p_context)
    {
       Your code goes here;
    }

    Most of the examples utilize the app_timer so you may not be able to change the prescaler.  But basically you can use the app_timer to make as many timers as you wish with different attributes and different handlers.  The prescaler sets the basic resolution of the timer or systick. Then you are always creating a timer based on how many ticks it requires. You can always change advertising data on the fly since you are just changing the info in the data structure it points to.

    Depending on the type of device you are creating (eg, beacon), you could also approach your solution using Radio Notification. With radio notification a system event generates an interrupt for getting ready to transmit and also for finished transmitting.  I find radio notification very handy since I know the state of the radio when I wish to modify something.

Reply
  • Yeah, I know you didn't literally mean app_timer.  That was just my bad attempt at a pun.

    This is based on SDK11, but I think it is similar for all. Everything can be put in main.c if you wish.

    #include "app_timer.h"

    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);

    APP_TIMER_DEF(m_your_timer_id);
    err_code = app_timer_create(&m_your_timer_id, APP_TIMER_MODE_REPEATED, your_timer_handler);
    APP_ERROR_CHECK(err_code);
                    
    err_code = app_timer_start(m_your_timer_id, APP_TIMER_TICKS(3630000, APP_TIMER_PRESCALER), NULL);
    APP_ERROR_CHECK(err_code);

    static void your_timer_handler(void * p_context)
    {
       Your code goes here;
    }

    Most of the examples utilize the app_timer so you may not be able to change the prescaler.  But basically you can use the app_timer to make as many timers as you wish with different attributes and different handlers.  The prescaler sets the basic resolution of the timer or systick. Then you are always creating a timer based on how many ticks it requires. You can always change advertising data on the fly since you are just changing the info in the data structure it points to.

    Depending on the type of device you are creating (eg, beacon), you could also approach your solution using Radio Notification. With radio notification a system event generates an interrupt for getting ready to transmit and also for finished transmitting.  I find radio notification very handy since I know the state of the radio when I wish to modify something.

Children
No Data
Related