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

Unpredictable behaviour of RTC2 on nRF24le1

I found a problem using the RTC2 on the nRF24le1 which i dont know how to solve it.

I am using the RTC2 on the master to generate a TICK interrupt exactly every 1s. With the formula on page 97, i set the compare register RTC2CMP1:RTC2CMP1 to 7FFE which should generate interrupts exactly every 1s. But the behaviour is in two points different as expected.

  1. The RTC2 generates interrupts 3-6 ms earlier, so the interval is like 0,996869s which corresponds to 7F98 and not 7FFE.

  2. The interval decreases every second one RTC2 tick (like 7F97, 7F96, 7F95, ...). Is this a bug?

How can i solve this, especially the point 2.? I need a constant interval.

Regards

  • What is your LF clock source? If you use the internal 32k RC oscillator then the accuracy is not very good (+/- 5% if I remember correctly, this can be found in the datasheet).
    For issue 2), could you attach the code you use to initialize the RTC, and the code running in the interrupt?

  • Hi Torgjorn, sorry for my late reply.

    My LF clock source is RCOSC32K because my module does not have an external 32k quarz. I does not find a upload button so i post the code here:

    // nRF24LE1 SPI Master #include <nordic_common.h> #include "hal_nrf.h" #include "hal_clk.h" #include "hal_delay.h"

    #define RTC2_TIMEOUT 32767 // 1s

    // Global variables uint8_t rtccount = 0;

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

    • Interrupt service routines ****************************/ TICK_ISR() // interrupt INTERRUPT_TICK (Internal wakeup interrupt (0x6b)) { P04 = 0; // Set Low, for starting logic analyzer trigger rtccount = 255;

      //WUF = 0; // Cleared automatically }

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

    • Functions *************************************/ void RTC2_init(uint16_t time) { //CLKCTRL = ?? CLKLFCTRL = 0x01; // RCOSC32K is used

      RTC2CON = 0x06; // Bit 2-1 (11): Compare mode: IRQ is set when equal. // When IRQ is assigned, Timer value is then reset RTC2CMP0 = (time & 0xFF); // Lowbyte of (value + 1 / 32768) (0x7FFF ~1s) RTC2CMP1 = (time >> 8) & 0xFF; // Highbyte }

    void RTC2_start(void) { WUCON &= ~(BIT_4 | BIT_5); // 00: Enable wakeup on TICK if WUIRQ is enabled WUIRQ = 1; // Enable TICK Interrupt (IEN1.5)

    RTC2CON |= BIT_0; // Bit 0: = 1: RTC2 is enabled }

    void RTC2_stop(void) { RTC2CON &= ~BIT_0; // Bit 0: = 0: RTC2 is disabled

    WUIRQ = 0; // Disable TICK Interrupt (IEN1.5) WUCON |= (BIT_4 | BIT_5); // 11: Ignore TICK (Bit 5-4) WUF = 0; // Clear interrupt }

    void MCU_init(void) { // P0.4 used for Logic analyzer start P0DIR &= ~BIT_4; // Set pin P0.4 as output (used for trigger Start) P0CON = 0x04; // Activate P0.4 (Digital output buffer on, normal drive strength) P04 = 1; // Set to High, due to active low behaviour

    RFCKEN = 1; // Enable the radio clock (RFCON.2) RF = 1; // Enable RF interrupt EA = 1; // Enable global interrupts }

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

    • Main routine *************************************/ void main(void) { MCU_init(); // Initialize MCU

      RTC2_stop(); // Stop RTC2 timer (Clear bits) RTC2_init(RTC2_TIMEOUT); // Init RTC2 with default timeout 1s RTC2_start(); // Start RTC2

      while(1) { if(rtccount > 0) { --rtccount;

         if(rtccount == 0)
            P04 = 1;                            // Set to High, due to active low behaviour
      }
      

      } }

  • I need the exact interval of 1s, so i think i have to use one of the other timer (TIMER1, TIMER2) to generate my needed interval. I think it is not possible to avoid the unpredictable behaviour of the RCOSC32K, or is it?

  • Hi Ewan

    For a high level of accuracy you need an external crystal oscillator. The internal ones are highly inaccurate, and can only be used when you don't care much about the accuracy.

    Without an external 32kHz crystal the only option is to synthesize the LF clock from the high frequency crystal, which you can select by writing 0x02 to the CLKLFCTRL register. Please keep in mind that this will keep the external HF crystal running at all times, which will increase the current consumption significantly.

    I am able to get your code running, and I see a 1 second toggle when selecting the right clock source. The only change I made to the code was to add a GPIO toggle in the interrupt, to be able to measure the interrupt timing accurately.

    I have not been able to reproduce your second issue, where you see the interval change over time. Are you still experiencing this issue?

    Best regards
    Torbjørn

  • Hi Torbjørn,

    i have changed the behaviour of the master and the slaves depending of your infos.

    The master does not need power down mode, because it is waiting for connections, so i used the synthsized clock which is very accurate for me (differs in 1-3 micro seconds).

    For the slaves i am using the standby mode at the moment (instead of the register retention) simulating a power down mode, until i will add a external 32kHz crystal. I think it is not possible to avoid using an external 32kHz crystal or an external RTC module. Soldering an external 32kHz crystal i think is the best method.

    Thanks and Regards Ewan

Related