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

Can Softdevice RTC be used without an interrupt handler?

I want to run the realtime counter RTC2 with softdevice S132 WITHOUT an interrupt handler.  I have no purpose for an RTC2 interrupt handler in my code, as I simply want to poll the hardware based RTC2 counter.  Also, since the RTC2 clock will be set at 8192 hz, I do not want an interrupt eating up cpu cycles and consuming extra electrical power.
Is this possible?
Hardware: Nordic nrf52832
Softdevice: S132
Currently the following source code gives me a softdevice error.
#define APP_RTC_CLOCK_FREQ       8192    //hz
#define APP_APPL_CLOCK_FREQ       32      //hz
    config.prescaler = 3;     //resulting freq= 8192 hz.
    err_code = nrf_drv_rtc_init(&m_rtc, &config, NULL);
    APP_ERROR_CHECK(err_code);
RTT Viewer shows this error:
00> <error> app: ERROR 3735928559 [Unknown error code] at C:\segger_ws\nRF5_SDK\modules\nrfx\drivers\src\nrfx_rtc.c:82
The error is occurring because there is a
NRFX_ASSERT(handler);
at the top of nrfx_rtc_init() within nrfx_rtc.c module.
Whereby, the current code does not allow a NULL handler.

ALTERNATIVE SOLUTIONS:

 1.  Customize Noridic's softdevice code inside the nrfx_rtc.c module.   OPINION - DUMB.  Makes codebase very complex.  Nordic should address this, not me.

 2.  Use a bare metal solution where I setup the RTC2 counter independent of the softdevice libarary functions.   OPINION - DUMB.  There may be conflicts between softdevice operations and my custom code. 

NRF_RTC1->TASKS_STOP  = 1;
delay_mS(0.1);
NRF_RTC1->TASKS_CLEAR = 1;
NRF_RTC1->PRESCALER   = 0;
   
NRF_RTC1->EVTEN = 0x000F0003;
NRF_RTC1->INTENCLR = 0;
NRF_RTC1->EVTENCLR = 0x000F0003;
 
NRF_RTC1->TASKS_START = 1;
delay_mS(0.1);

NO GOOD SOLUTIONS... SO WHERE DOES THIS LEAVE ME?

Ken Huebner

Software Engineer

Huebner Design

Parents
  • Hi,

    I see your point, but I don't have any good workarounds here other than to suggest a few more possibilities:

    3. the rtc interrupt may be set to occur very infrequent, in other words every ~30minutes, I doubt that will be measurable on average current.

    4. you may just disable the interrupt manually after starting the clock by the driver by calling NRF_RTC1->INTENCLR (a hack I know)

    Best regards,
    Kenneth

Reply
  • Hi,

    I see your point, but I don't have any good workarounds here other than to suggest a few more possibilities:

    3. the rtc interrupt may be set to occur very infrequent, in other words every ~30minutes, I doubt that will be measurable on average current.

    4. you may just disable the interrupt manually after starting the clock by the driver by calling NRF_RTC1->INTENCLR (a hack I know)

    Best regards,
    Kenneth

Children
  • Hi,  Thanks for your notes.  My solution to avoid using an RTC handler was to call Nordic's "Softdevice 132" low level functions.  The following compiles and runs fine, with a confirmed 8192 hz RTC clock rate.  No handler required.  The one caveat is I'm not sure how stable and long lasting the API will be, recognizing these are low level functions.

    -Ken

    SOLUTION:

        //Set RTC config to default.
        nrf_drv_rtc_config_t rtc_config = NRF_DRV_RTC_DEFAULT_CONFIG;

    #define APP_RTC_CLOCK_FREQ       8192    //hz
        rtc_config.prescaler = 3;     //resulting freq= 8192 hz.

        NRFX_IRQ_PRIORITY_SET(m_rtc.irq, rtc_config.interrupt_priority);
        NRFX_IRQ_ENABLE(m_rtc.irq);
        nrf_rtc_prescaler_set(m_rtc.p_reg, rtc_config.prescaler);

        //Enable Nordic RTC.
        nrf_rtc_task_trigger(m_rtc.p_reg, NRF_RTC_TASK_START);    //RUNTIME RTC2 WORKS OK!

  • Forgot one item: place this at top of source file.

    const nrf_drv_rtc_t m_rtc = NRF_DRV_RTC_INSTANCE(2);  /**< Declaring an instance of nrf_drv_rtc for RTC2. */

  • Kenneth - Your solution #4 seems best.  If I have time, I may go with it instead.  

    One day...  maybe Nordic will provide a proper solution and allow developers to use RTC clocks without handlers. 

  • Hi Ken,
    i just implemented your solution and it works well. Thanks for providing this. 

    I want to confirm my RTC 2 clock rate with my logic analyzer. How did you do this without a handler? 

  • If my memory serves me right -- I confirmed the RTC2 clock rate by creating a program loop that polls the RTC2 clock value and toggling an IO pin.  Then while the Nordic device is running, observing the IO pin using an oscilloscope.  

    The pseudo code looks like this...

    unsigned int read_value;

    while(true)

    {

      read_value= RTC2 clock value ;

      while (read_value == RTC2 clock value)

          ;

      set IO pin = high

      read_value= RTC2 clock value ;

      while (read_value == RTC2 clock value)

          ;

      set IO pin = low

    }

    Keep in mind for the above code...  your logic analyzer will show a

    frequency rate= desired RTC2 clock rate divided by 2.

    The reason is the above code has a toggle high and a toggle low for each full wave of output signal.  I think you get the picture.

    ALTERNATIVE SOLUTION:

    One could read RTC2 clock into "read_value", then add 1000 to read_value, then poll the RTC2 clock until it reaches the value, then toggle IO pin.  This would avoid the possibility of missing clock ticks if your RTC2 clock rate is exceptionally high.  Of course in this case, your oscilloscope or logic analyzer will show a

    frequency rate= desired RTC2 clock rate divided by 2000.

    -Ken

      

     

Related