When setting up a pin to toggle on the RTC's TICK event through the PPI and constantly reading the RTC's COUNTER on the nRF52832, my team observed frequent glitches on the pin signal. Here's a screenshot from our digital oscilloscope:
When not reading the RTC's COUNTER, we do not observe a single glitch.
Here's the code we used:
#include <stdbool.h> #include <stdint.h> #include "nrf_gpiote.h" #include "nrf_drv_ppi.h" #include "nrfx_gpiote.h" #include "nrfx_rtc.h" #include "nrfx_clock.h" #include "app_error.h" #define GPIO_OUTPUT_PIN_NUMBER 31 // RTC1 instance static const nrfx_rtc_t m_rtc = NRFX_RTC_INSTANCE(1); // Dummy handlers static void rtc_dummy_handler(nrfx_rtc_int_type_t int_type) {} static void clock_dummy_handler(nrfx_clock_evt_type_t event) {} static void rtc_init(void) { nrfx_err_t err_code; // Start the internal LFCLK XTAL oscillator. err_code = nrfx_clock_init(clock_dummy_handler); APP_ERROR_CHECK(err_code); nrf_clock_lf_src_set(NRF_CLOCK_LFCLK_Xtal); nrfx_clock_lfclk_start(); // Initialize RTC instance nrfx_rtc_config_t config = NRFX_RTC_DEFAULT_CONFIG; err_code = nrfx_rtc_init(&m_rtc, &config, rtc_dummy_handler); APP_ERROR_CHECK(err_code); // Enable tick event, disable interrupt nrfx_rtc_tick_enable(&m_rtc, false); } /** * @brief Setup PPI channel with event from RTC compare and task GPIOTE pin toggle. */ static void blinking_setup() { nrfx_err_t err_code; nrfx_gpiote_out_config_t config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(false); err_code = nrfx_gpiote_out_init(GPIO_OUTPUT_PIN_NUMBER, &config); APP_ERROR_CHECK(err_code); nrf_ppi_channel_t ppi_channel; err_code = nrfx_ppi_channel_alloc(&ppi_channel); APP_ERROR_CHECK(err_code); uint32_t rtc_tick_evt_addr = nrfx_rtc_event_address_get(&m_rtc, NRF_RTC_EVENT_TICK); uint32_t gpiote_task_addr = nrfx_gpiote_out_task_addr_get(GPIO_OUTPUT_PIN_NUMBER); err_code = nrfx_ppi_channel_assign(ppi_channel, rtc_tick_evt_addr, gpiote_task_addr); APP_ERROR_CHECK(err_code); err_code = nrfx_ppi_channel_enable(ppi_channel); APP_ERROR_CHECK(err_code); nrfx_gpiote_out_task_enable(GPIO_OUTPUT_PIN_NUMBER); } int main(void) { uint32_t err_code; err_code = nrf_drv_ppi_init(); APP_ERROR_CHECK(err_code); err_code = nrfx_gpiote_init(); APP_ERROR_CHECK(err_code); // RTC init rtc_init(); // Set up PPI channel with event from RTC compare and task GPIOTE pin toggle. blinking_setup(); // Power on RTC instance nrfx_rtc_enable(&m_rtc); uint32_t counter; while (true) { // Comment this line to fix glitch counter = nrfx_rtc_counter_get(&m_rtc); } }
We are testing this on PCA10040, version 1.2.4, which has an nRF52 marked QFAAE0. We are using SDK 16.0, no SoftDevice and GCC with O0.
I looked at the nRF52832 errata but didn't see anything that would explain this. It looks like a hardware bug to me, but I've been wrong before. Is that the case?
We were hoping to do some fairly precise timings with the RTC and I am now worried that reading the RTC's COUNTER may affect its reliability for timekeeping by causing it to jump ahead or skip cycles.