0

NRF Timers not working on Feather NRF52
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

NRF Timers not working on Feather NRF52

by simonem on Sun Oct 22, 2017 4:36 pm

Hello,

I'm trying to add a timer to my arduino sketch to generate an interrupt every 1ms.

Code: Select all | TOGGLE FULL SIZE
setup(void)
{
    Serial.println("Configuring timer");
    // 32-bit timer
    NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;
 
   // 1us timer period
    NRF_TIMER0->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos;
 
  // 1000 us compare value, generates EVENTS_COMPARE[0]
    NRF_TIMER0->CC[0] = 10000;
 
    // Enable IRQ on EVENTS_COMPARE[0]
    NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;
 
    // Clear the timer when COMPARE0 event is triggered
    NRF_TIMER0->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
 
    NVIC_EnableIRQ(TIMER0_IRQn);
    NRF_TIMER0->TASKS_START = 1;                                                            // Start TIMER
    Serial.println("Timer configured");
  }

void TIMER0_IRQHandler(void)
{
    if (NRF_TIMER0->EVENTS_COMPARE[0] == 1)
    {   
        Serial.println("This works!");

        NRF_TIMER0->EVENTS_COMPARE[0] = 0;
    }
}


The code compiles OK but it does not work, the device keeps on rebooting itself.
I'm using Feather nRF52 with Arduino core
Any hints?

Thanks
Simone

simonem
 
Posts: 10
Joined: Wed Apr 20, 2016 1:04 pm

Re: NRF Timers not working on Feather NRF52

by adafruit_support_mike on Mon Oct 23, 2017 12:05 am

You generally can't use the Serial interface inside an interrupt handler. The board might be hanging because it's waiting for Serial interrupts that are blocked by the calling ISR, and rebooting from a watchdog interrupt.

Try setting a flag in your ISR and using Serial in your main code.

adafruit_support_mike
 
Posts: 58856
Joined: Thu Feb 11, 2010 2:51 pm

Re: NRF Timers not working on Feather NRF52

by simonem on Mon Oct 23, 2017 2:46 am

Thanks! I fixed the code but it still doesn't work

Code: Select all | TOGGLE FULL SIZE
#include <bluefruit.h>
int flag = 0;

void setup() {
  Serial.begin(115200);
  Serial.println("Configuring timer");
    // 32-bit timer
    NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;
 
   // 1us timer period
    NRF_TIMER0->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos;
 
  // 1000 us compare value, generates EVENTS_COMPARE[0]
    NRF_TIMER0->CC[0] = 10000;
 
    // Enable IRQ on EVENTS_COMPARE[0]
    NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;
 
    // Clear the timer when COMPARE0 event is triggered
    NRF_TIMER0->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
 
    NVIC_EnableIRQ(TIMER0_IRQn);
    NRF_TIMER0->TASKS_START = 1;                                                            // Start TIMER
    Serial.println("Timer configured");
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(flag);
  delay(100);

}

void TIMER0_IRQHandler(void)
{
    if (NRF_TIMER0->EVENTS_COMPARE[0] == 1)
    {   
        flag++;
        NRF_TIMER0->EVENTS_COMPARE[0] = 0;
    }
}


The serial terminal just prints:

Code: Select all | TOGGLE FULL SIZE
Configuring timer
Timer configured
0

simonem
 
Posts: 10
Joined: Wed Apr 20, 2016 1:04 pm

Re: NRF Timers not working on Feather NRF52

by adafruit_support_mike on Tue Oct 24, 2017 1:31 am

I'm afraid that's all I've got. We haven't gone deep-diving into the nRF52's timer settings and interrupt behavior.

You might want to check with the folks at Nordic:

https://devzone.nordicsemi.com/questions/

adafruit_support_mike
 
Posts: 58856
Joined: Thu Feb 11, 2010 2:51 pm

Re: NRF Timers not working on Feather NRF52

by simonem on Tue Oct 24, 2017 4:08 pm

Thanks. I tried the code on a micocontroller based on NRF51 (Simblee) and it works OK.
On the Feather NRF52 it just freezes the board once the interrupt is generated.
Will ask Nordic.

simonem
 
Posts: 10
Joined: Wed Apr 20, 2016 1:04 pm

Re: NRF Timers not working on Feather NRF52

by hathach on Fri Oct 27, 2017 11:07 am

you can use the SoftwareTimer module from freeRTOS, it is mentioned multiple times in the forum.

hathach
 
Posts: 1020
Joined: Tue Apr 23, 2013 1:02 am

Re: NRF Timers not working on Feather NRF52

by simonem on Wed Nov 01, 2017 5:54 am

Thanks hathach!
The SoftwareTimer module from freeRTOS solved all my problems! :D

Had no idea that this was included in Feather NRF52

simonem
 
Posts: 10
Joined: Wed Apr 20, 2016 1:04 pm

Re: NRF Timers not working on Feather NRF52

by hathach on Wed Nov 01, 2017 6:22 am

You are welcome, happy hacking :)

hathach
 
Posts: 1020
Joined: Tue Apr 23, 2013 1:02 am

Re: NRF Timers not working on Feather NRF52

by euclidprime on Sun Dec 24, 2017 12:02 am

I had this same problem and came across this post. The SoftwareTimer won't work for my application since it only has 1ms resolution. After 3 days I got it to work. TIMER0 never did work so I ended up using TIMER2. Finally I had to use:

Code: Select all | TOGGLE FULL SIZE
extern "C"
{
   void TIMER2_IRQHandler()
  {
     // body of callback function here
  }
}


Apparently C++ name mangling causes the ISR to never be called. 3 days ...

euclidprime
 
Posts: 1
Joined: Sat Dec 23, 2017 11:46 pm

Re: NRF Timers not working on Feather NRF52

by philbeeson on Sat Dec 30, 2017 2:49 pm

euclidprime wrote:TIMER0 never did work so I ended up using TIMER2. Finally I had to use:

Code: Select all | TOGGLE FULL SIZE
extern "C"
{
   void TIMER2_IRQHandler()
  {
     // body of callback function here
  }
}


Apparently C++ name mangling causes the ISR to never be called. 3 days ...


Looking on the bright side, I doubt you'll forget that in a hurry so you'll be better able to resolve next time.
With reference to the Timer0 not working - If you have Nordic's SoftDevice installed and enabled, then access to Timer0 is blocked as it's used by the soft device. There's a whole list of other peripheral restrictions in the soft device specification. Not sure if that's relevant to your application but it might assist someone else.

philbeeson
 
Posts: 1
Joined: Sat Dec 30, 2017 2:38 pm

Re: NRF Timers not working on Feather NRF52

by aazahn on Fri Aug 02, 2019 5:03 pm

I know I'm digging this up pretty hard, but I'm interested to know how the extern "C" works I've been trying to get interrupts to work on this but it hasn't been working out. Here's my current code.

Code: Select all | TOGGLE FULL SIZE
int flag = 0;

void setup() {
  Serial.begin(115200);
 
  pinMode(LED_BUILTIN, OUTPUT);
 
  //NRF52 Timer setup
  NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;
  NRF_TIMER2->TASKS_CLEAR = 1;             //Clear the task first so it's usable later
  NRF_TIMER2->PRESCALER = 6;                //I'm not completely sure what this means.... devided by 6? I'm used to doing it with bytes....
  NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit; //Set 16 bit timer resolution
  NRF_TIMER2->CC[0] = 20;                    //Set these to the compare values
  NRF_TIMER2->CC[1] = 65535;

  //Enable interrupt on timer for both C[0] and C[1]
  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;

}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(flag);

}

//Use extern C with some other stuff to make sure that the right stuff actually gets called
extern "C" {
  void timer2_IRQHandler() {
    if (NRF_TIMER2->EVENTS_COMPARE[0] !=0) {
      NRF_TIMER2->EVENTS_COMPARE[0] = 0;    //Clear compare register 0 event
      flag++;
    }

    if (NRF_TIMER2->EVENTS_COMPARE[1] !=0) {
      NRF_TIMER2->EVENTS_COMPARE[1] = 0;    //Clear compare register 1 event
      //digitalWrite(LED_BUILTIN,LOW);
    }
  }
}

void toggleLED(){
  digitalWrite(LED_BUILTIN,HIGH);
}

aazahn
 
Posts: 3
Joined: Thu May 16, 2019 7:28 pm

Re: NRF Timers not working on Feather NRF52

by adafruit_support_mike on Sat Aug 03, 2019 1:17 pm

That basically tells the C++ compiler not to mess things up.

In C, function and variable names have to be unique within their scope. If you declare a function or variable named 'foo()', the compiler associates it with every appearance of 'foo()' within the appropriate scope.

C++ changed that with function overloading. It lets you declare foo(int), foo(float), foo(uint32_t), etc, and the compiler is supposed to work out the function you want from the name and the variable type of the value you use as an argument.

To make that work, C++ compilers do something called 'name mangling': they change the names of functions behind the scenes so the list of functions above become more like 'foo_int(int)', 'foo_float(float)', 'foo_uint32_t(uint32_t)', and so on. Then the compiler can map 'foo(300)' to 'foo_int()' and 'foo(300.0)' to 'foo_float()' as it reads the code.

That can play hell with item defined using the 'extern' keyword, which C uses to make functions or variables visible outside the file where they were defined.

The file that uses an external function would declare it as 'extern foo(int)', and the C++ compiler would record that as use of a function named 'foo(int)'.. just like the source code says.

The file that defines that same external function would declare it as 'extern foo(int)', and a C++ compiler would silently rewrite that as 'foo_int(int)'. Then it would refuse to connect 'foo_int(int)' to the 'foo(int)' call in the other file because the functions have different names (despite being literally identical in the source code).

The 'extern "C"' declaration tells the C++ compiler to knock it off. Functions and variables declared in an 'extern "C"' block aren't subject to name mangling, so 'foo(int)' remains 'foo(int)', and the linker can connect the definition in one file with the use in another file.

adafruit_support_mike
 
Posts: 58856
Joined: Thu Feb 11, 2010 2:51 pm

Please be positive and constructive with your questions and comments.