Hello. I'm trying to toggle a GPIO pin at a predefined frequency in order to measure the accuracy of out RTC clock. This code uses the GPIOTE, RTC, and PPI peripherals in order to avoid firmware callbacks being used. This code compiles, and everything seems to be configured properly, but nothing is output on the proper GPIO pin. Any advice is appreciated.
/* * * @file RTC Counter implementation * */ #include <zephyr/kernel.h> #include <zephyr/init.h> #include <nrfx_rtc.h> #include <nrfx_ppi.h> #include <nrfx_gpiote.h> #include <hal/nrf_gpio.h> #include <hal/nrf_rtc.h> #include <zephyr/logging/log.h> LOG_MODULE_REGISTER(rtc_counter, CONFIG_LOG_DEFAULT_LEVEL); // Define RTC instance #define RTC_INSTANCE_ID 2 static const nrfx_rtc_t rtc_instance = NRFX_RTC_INSTANCE(RTC_INSTANCE_ID); // Define GPIO pin #define TOGGLE_PIN NRF_GPIO_PIN_MAP(0, 13) // HW0 static void rtc_handler(nrfx_rtc_int_type_t int_type) { } static void configure_gpiote(void) { nrfx_err_t err_code; if(!nrfx_gpiote_is_init()) { err_code = nrfx_gpiote_init(NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY); if (err_code != NRFX_SUCCESS) { LOG_WRN("GPIOTE initialization error: %d", err_code); return; } } nrfx_gpiote_output_config_t config = { .drive = NRF_GPIO_PIN_S0S1, .input_connect = NRF_GPIO_PIN_INPUT_DISCONNECT, .pull = NRF_GPIO_PIN_NOPULL, }; nrfx_gpiote_task_config_t task_config = { .task_ch = 0, .polarity = NRF_GPIOTE_POLARITY_TOGGLE, .init_val = NRF_GPIOTE_INITIAL_VALUE_LOW, }; err_code = nrfx_gpiote_output_configure(TOGGLE_PIN, &config, &task_config); if (err_code != NRFX_SUCCESS) { LOG_ERR("GPIOTE output configure failed: %d", err_code); return; } LOG_WRN("GPIOTE configured successfully"); } static void configure_rtc(void) { nrfx_rtc_config_t rtc_config = NRFX_RTC_DEFAULT_CONFIG; rtc_config.prescaler = 4095; // RTC frequency: 32768 Hz / (prescaler + 1) = 8 Hz nrfx_err_t err_code = nrfx_rtc_init(&rtc_instance, &rtc_config, rtc_handler); if (err_code != NRFX_SUCCESS) { LOG_ERR("RTC initialization failed: %d", err_code); return; } nrfx_rtc_tick_enable(&rtc_instance, false); // nrfx_rtc_overflow_enable(&rtc_instance, true); nrfx_rtc_enable(&rtc_instance); LOG_WRN("RTC configured successfully"); } static void configure_ppi(void) { nrfx_err_t err_code; nrf_ppi_channel_t ppi_channel; // Configure PPI err_code = nrfx_ppi_channel_alloc(&ppi_channel); if (err_code != NRFX_SUCCESS) { LOG_ERR("PPI channel allocation failed: %d", err_code); return; } // Connect RTC overflow event to GPIO toggle task uint32_t rtc_event_addr = nrfx_rtc_event_address_get(&rtc_instance, NRF_RTC_EVENT_TICK); uint32_t gpiote_task_addr = nrfx_gpiote_out_task_address_get(TOGGLE_PIN); nrfx_gpiote_out_task_enable(TOGGLE_PIN); err_code = nrfx_ppi_channel_assign(ppi_channel, rtc_event_addr, gpiote_task_addr); if (err_code != NRFX_SUCCESS) { LOG_ERR("PPI channel assignment failed: %d", err_code); return; } // Enable PPI channel err_code = nrfx_ppi_channel_enable(ppi_channel); if (err_code != NRFX_SUCCESS) { LOG_ERR("PPI channel enabling failed: %d", err_code); return; } LOG_WRN("PPI configured successfully"); } static int _RTC_Init(){ configure_gpiote(); configure_rtc(); configure_ppi(); return 0; } SYS_INIT(_RTC_Init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);