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

Using I2C, NUS, and Two Timer Interrupts - Reading Sensor from both Timer Interrupts

  • Custom Board with MCU NordicSemi nRF51822-QFAA

  • Softdevice S110 7.1

  • IAR for ARM 7.1

  • SDK 7.2 using NUS example

  • Testing with iPhone 5S, 6 and iPad air (iOS 8.1.3)

/ Nexus 5 and Galaxy Note 3 (Android 4.4.2).

/************************************************************************/

Hi, I'm using a relative humidity + temperature sensor (SI7020-A10).

Datasheet SI7020-A10.pdf

After I connect with a test device (iOS device or Android device),

two timers starts. (Lets say I use timer timer1 and timer2.

Timer1's interval is 3 second and timer2's interval is 10 seconds.)

Both timer interrupts reads my sensor's data. Then timer1 sends the data

using NUS to the app.

One concern is that after 30 seconds (which is the least common multiple of each intervals)

both interrupts will read the sensor.

I'm worried that would it cause problems or not.

/************************************************************************/

So my questions are,

0.Does both timer interrupt has the same priority?

1.What exactly happens at each 30 seconds?

For example, when I start timer1 and timer2, even though 30 seconds pasts,

timer1 interrupt will occur first than timer2. Does the Program Counter jumps immediately

to the timer2 interrupt handler before finishing timer1 interrupt handler?

Or does it jumps later after it finishes the first interrupt handler?

2.Is this fine for each timer interrupts to read the sensor? I'm worried it is okay

whether it works properly or not.

-Regards, Mango922

Parents
  • Hi Mango922

    1. When you use the softdevice together with a timer, you must explicitly set the priority of the TIMER interrupts, i.e.

       NRF_TIMER1->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;   
       sd_nvic_SetPriority(TIMER1_IRQn, NRF_APP_PRIORITY_LOW);  
       sd_nvic_EnableIRQ(TIMER1_IRQn);
      
       NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;   
       sd_nvic_SetPriority(TIMER2_IRQn, NRF_APP_PRIORITY_LOW);  
       sd_nvic_EnableIRQ(TIMER2_IRQn);
      

    If you want to synchronize the order of events for the two timers, I guess it would be better to use two compare registers of the same timer.

    1. If you choose both timers with same priority, then they will not preempt each other, meaning that once one of them starts execution, the other one can not interrupt that execution, it will have to wait for the other one to complete. If however TIMER1 has higher priority than TIMER2, then TIMER1 interrupt can preempt exectuion of TIMER2 interrupt handler.

    • Defining NRF_APP_PRIORITY_LOW means ARM priority 3, see this thread
    • NRF_APP_PRIORITY_HIGH means ARM priority 1
    • Softdevice callbacks have ARM priority 3.
    • SVC calls (calling the softdevice with sd_*) have ARM priority 2
    • Internal softdevice operations have ARM priority 0.

    From the above, e.g. the following can be concluded:

    • Any internal softdevice operation (BLE operation) will preempt any application operation.
    • Any peripheral interrupt with NRF_APP_PRIORITY_LOW or NRF_APP_PRIORITY_HIGH will block softdevice callbacks.
    • Any peripheral with priority set to NRF_APP_PRIORITY_HIGH will preempt any execution of peripheral with priority NRF_APP_PRIORITY_LOW
    • Interrupt handler of peripheral with priority NRF_APP_PRIORITY_LOW can call a SVC softdevice function (starting with sd_*), but interrupt handler of peripheral with priority NRF_APP_PRIORITY_HIGH can not.
Reply
  • Hi Mango922

    1. When you use the softdevice together with a timer, you must explicitly set the priority of the TIMER interrupts, i.e.

       NRF_TIMER1->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;   
       sd_nvic_SetPriority(TIMER1_IRQn, NRF_APP_PRIORITY_LOW);  
       sd_nvic_EnableIRQ(TIMER1_IRQn);
      
       NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;   
       sd_nvic_SetPriority(TIMER2_IRQn, NRF_APP_PRIORITY_LOW);  
       sd_nvic_EnableIRQ(TIMER2_IRQn);
      

    If you want to synchronize the order of events for the two timers, I guess it would be better to use two compare registers of the same timer.

    1. If you choose both timers with same priority, then they will not preempt each other, meaning that once one of them starts execution, the other one can not interrupt that execution, it will have to wait for the other one to complete. If however TIMER1 has higher priority than TIMER2, then TIMER1 interrupt can preempt exectuion of TIMER2 interrupt handler.

    • Defining NRF_APP_PRIORITY_LOW means ARM priority 3, see this thread
    • NRF_APP_PRIORITY_HIGH means ARM priority 1
    • Softdevice callbacks have ARM priority 3.
    • SVC calls (calling the softdevice with sd_*) have ARM priority 2
    • Internal softdevice operations have ARM priority 0.

    From the above, e.g. the following can be concluded:

    • Any internal softdevice operation (BLE operation) will preempt any application operation.
    • Any peripheral interrupt with NRF_APP_PRIORITY_LOW or NRF_APP_PRIORITY_HIGH will block softdevice callbacks.
    • Any peripheral with priority set to NRF_APP_PRIORITY_HIGH will preempt any execution of peripheral with priority NRF_APP_PRIORITY_LOW
    • Interrupt handler of peripheral with priority NRF_APP_PRIORITY_LOW can call a SVC softdevice function (starting with sd_*), but interrupt handler of peripheral with priority NRF_APP_PRIORITY_HIGH can not.
Children
No Data
Related