This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

RTC in repeat mode with no CPU involvement ( SDK v13 )

Hi Everyone,

The custom device I am working on is a BLE peripheral device and uses softdevice S132,

therefore to get accurate triggering of ADC sampling and to avoid periodic CPU blocking by the radio, 

I am trying to get RTC to trigger the ADC without any CPU involvement. Also currently, the custom function

I use for ADC sampling is a blocking function ( increased power consumption from CPU idling ) therefore I hope by using PPI and RTC, I can also reduce the

overall power consumption.

Looking at the RTC example provided in SDK v13, I can see that that rtc in repeat mode is done by calling the rtc_cc_set function

in the rtc interrupt on compare event. 

My question is this, will I be able to run the RTC in repeat mode without the use of the interrupt function as it can be blocked by the radio interrupt?

I can disable the rtc interrupt ( SDK v13 requires an interrupt handler to be passed ) and use rtc clear task with PPI to reset the rtc counter , but I can see that the cc value is set in the rtc_cc_set function in the interrupt.

Is this required ? if I set the cc value once, I presume it will be retained even after calling the rtc clear task?

In the IRQ handler for rtc, the compare event register is cleared, if I were to disable the interrupt, then there would be no way of clearing this register using PPI.

However, is it necessary to clear the compare event register manually, would it go low if were to clear the counter and then high again?

In summary what I would likely to do is to set the cc value once, clear the counter using ppi on compare event ( forked to trigger adc sampling ) and wait for the next compare event.

Alternatively, I can leave the interrupt as it is with the rtc_cc_set function but then do the clearing with PPI, as long as the counter is cleared straightaway and the compare event register

and cc value is cleared/set a few cycles before the counter reaches the cc value ( ie cc time interval <  1/sampling_freq ) then this would be fine?

Thanks.

Parents
  • Hi,

    It is not required to call nrf_drv_rtc_cc_set() in the event handler to set the CC value, the reason that this function is called in the handler is to re-enable the event and interrupts. In the IRQ Handler in the RTC driver, the events and interrupts are disabled when the COMPARE event is detected:

    nrf_rtc_event_disable(p_reg,int_mask);
    nrf_rtc_int_disable(p_reg,int_mask);

    If you disable the interrupt and clear the RTC through PPI (fork), the code in the interrupt handler will not be run, and the CC register will not be changed.

    Note that you will likely not be able to achieve low power SAADC sampling and sampling with precise timing at the same time. The SAADC will have high current consumption when it is STARTED, which is required in order to sample through PPI. We have some low power examples, but this will stop the SAADC between each sample, and it must be restarted by the software.

    You may be able to achieve something semi-precise and low power by triggering the START task through PPI and connect the SAADC STARTED event to the SAMPLE task, but I have not tested this. This approach is also not supported by the SAADC driver, so you would need to write your own custom implementation. In this solution, you need to make sure that the CPU provides a new buffer for the SAADC to sample to between the STARTED event and the next triggering of START task over PPI, to prevent the previous buffer from being overwritten.

    Best regards,
    Jørgen

  • Hi,

    bryanhsieh said:
    The main thing I wanted to check was whether the compare flag would get retriggered once the counter of the RTC has been cleared via PPI, but looking at the hardware implementation of the RTC which is slightly different to other peripherals, it looks like event flag is latched by the register so has to be manually cleared by the CPU.

    The event registers are usually latched when the event signal is generated by the HW peripheral, and needs to be cleared by the CPU. However, the peripheral can normally regenerate the signal event if the register is already set, see Events:

    "Events can be generated by the peripheral even when the event register is set to '1'."

    bryanhsieh said:
    By disabling the interrupt wouldn't the RTC stop running after the first compare event?

    The event register needs to be cleared by the CPU in order to trigger a new interrupt, see Interrupts. If interrupts are disabled, and the events are connected to tasks through PPI, there is no need to clear the event registers for a new event to be generated.

    bryanhsieh said:

    My current implementation ( see attached file ) is this, I have 3 PPIs, one to trigger the ADC start task and forked to clear RTC counter.

    Another PPI to trigger the start sample task on ADC started event.

    And the final PPI to trigger the stop task on events end event.

    The RTC interrupt calls cc_set which clears the compare flag.

    The ADC interrupt clears each individual event and in the case of ADC stopped it uninits and restarts the ADC module before initializing it. 

    For sanity check, with the above implementation would you agree that the ADC sampling would be accurate as long as the compare flag is cleared and ADC result is moved to an array before the next sampling period is up?

    Most likely it will work and give accurate sampling time, but there may occur a race condition/issue in case your interrupt handling is delayed long enough. The RTC events/interrupts may be disabled right before the RTC hits the CC value, and enabled again after the CC value is passed. Since you do not clear the RTC in the event handler, the RTC will run until it overflows and hit the CC value value a second time before the event is generated.

    Best regards,
    Jørgen

Reply
  • Hi,

    bryanhsieh said:
    The main thing I wanted to check was whether the compare flag would get retriggered once the counter of the RTC has been cleared via PPI, but looking at the hardware implementation of the RTC which is slightly different to other peripherals, it looks like event flag is latched by the register so has to be manually cleared by the CPU.

    The event registers are usually latched when the event signal is generated by the HW peripheral, and needs to be cleared by the CPU. However, the peripheral can normally regenerate the signal event if the register is already set, see Events:

    "Events can be generated by the peripheral even when the event register is set to '1'."

    bryanhsieh said:
    By disabling the interrupt wouldn't the RTC stop running after the first compare event?

    The event register needs to be cleared by the CPU in order to trigger a new interrupt, see Interrupts. If interrupts are disabled, and the events are connected to tasks through PPI, there is no need to clear the event registers for a new event to be generated.

    bryanhsieh said:

    My current implementation ( see attached file ) is this, I have 3 PPIs, one to trigger the ADC start task and forked to clear RTC counter.

    Another PPI to trigger the start sample task on ADC started event.

    And the final PPI to trigger the stop task on events end event.

    The RTC interrupt calls cc_set which clears the compare flag.

    The ADC interrupt clears each individual event and in the case of ADC stopped it uninits and restarts the ADC module before initializing it. 

    For sanity check, with the above implementation would you agree that the ADC sampling would be accurate as long as the compare flag is cleared and ADC result is moved to an array before the next sampling period is up?

    Most likely it will work and give accurate sampling time, but there may occur a race condition/issue in case your interrupt handling is delayed long enough. The RTC events/interrupts may be disabled right before the RTC hits the CC value, and enabled again after the CC value is passed. Since you do not clear the RTC in the event handler, the RTC will run until it overflows and hit the CC value value a second time before the event is generated.

    Best regards,
    Jørgen

Children
Related