My board is nRF5340Dk with NCS 2.6.1 and toolchain 2.6.1.
At this development stage I want to measure continuously incoming frequency ranging from 1Hz to 1MHz with high accuracy possible. I have tried looking into some previous similar question and implemented the code from that project on to my project but I could not get past the NRF_PPI section, which I believe now is NRF_DPPI for nrf5340 boards. But how do I implement NRF_DPPI without extensively changing existing code? Because the way NRF_PPI was used is not similar to NRF_DPPI.
Is there a best way to measure up to 6 frequencies through GPIOS?
This is the current code :
#include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <string.h> #include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/sys/printk.h> #include <helpers/nrfx_gppi.h> #include <nrfx_timer.h> #include <nrfx_gpiote.h> #include <nrfx_dppi.h> #define FREQ_MEASURE_PIN 7 uint32_t time = 1; // timer time in seconds static void timer_init() { uint32_t counter; counter = (16000000 >> 8)*time; NRF_TIMER1->TASKS_STOP = 1; NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer; NRF_TIMER1->PRESCALER = 8; // f_hck / 2^8 NRF_TIMER1->CC[0] = counter; NRF_TIMER1->BITMODE = (TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos); NRF_TIMER1->TASKS_CLEAR = 1; NRF_TIMER1->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos); NRF_TIMER1->EVENTS_COMPARE[0] = 0; } static void counter_init() { NRF_TIMER2->TASKS_STOP = 1; NRF_TIMER2->MODE = TIMER_MODE_MODE_Counter; NRF_TIMER2->BITMODE = (TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos); NRF_TIMER2->TASKS_CLEAR = 1; NRF_TIMER2->EVENTS_COMPARE[0] = 0; } static void gpiote_init(uint32_t pin) { NRF_GPIOTE->CONFIG[0] = 0x01 << 0; // MODE: Event NRF_GPIOTE->CONFIG[0] |= pin << 8; // Pin number NRF_GPIOTE->CONFIG[0] |= NRF_GPIOTE_POLARITY_LOTOHI << 16; // Event rising edge } static void ppi_timer_stop_counter_init() { NRF_DPPI->CHEN |= 1 << 0; *(&(NRF_DPPI->CH[1].EEP)) = (uint32_t)&NRF_TIMER1->EVENTS_COMPARE[0]; *(&(NRF_DPPI->CH[1].TEP)) = (uint32_t)&NRF_TIMER2->TASKS_STOP; NRF_DPPI->CHENSET |= 1 << 0; } static void ppi_gpiote_counter_init() { NRF_DPPI->CHEN |= 1 << 1; *(&(NRF_DPPI->CH[1].EEP)) = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0]; *(&(NRF_DPPI->CH[1].TEP)) = (uint32_t)&NRF_TIMER2->TASKS_COUNT; NRF_DPPI->CHENSET |= 1 << 1; } int main() { // Start clock for accurate frequencies NRF_CLOCK->TASKS_HFCLKSTART = 1; // Wait for clock to start while(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); printk("Timer Test"); NVIC_EnableIRQ(TIMER1_IRQn); NVIC_SetPriority(TIMER1_IRQn, 3); nrf_gpio_cfg_input(FREQ_MEASURE_PIN, NRF_GPIO_PIN_NOPULL); counter_init(); timer_init(); gpiote_init(FREQ_MEASURE_PIN); ppi_gpiote_counter_init(); ppi_timer_stop_counter_init(); NRF_TIMER1->TASKS_START = 1; NRF_TIMER2->TASKS_START = 1; } void TIMER1_IRQHandler(void) { if (NRF_TIMER1->EVENTS_COMPARE[0] != 0) { //nrf_drv_gpiote_out_toggle(LED_GREEN); NRF_TIMER1->EVENTS_COMPARE[0] = 0; NRF_TIMER2->TASKS_CAPTURE[0] = 1; printk("%u Hz", NRF_TIMER2->CC[0]*time); NRF_TIMER1->TASKS_CLEAR = 1; NRF_TIMER2->TASKS_CLEAR = 1; NRF_TIMER2->TASKS_START = 1; } }
and prj.conf
CONFIG_GPIO=y CONFIG_LOG=y
This code/project primarily has been taken from this question on devzone which was running on nRF52840 and a different SDK.
I have issues in
static void ppi_timer_stop_counter_init() { NRF_DPPI->CHEN |= 1 << 0; *(&(NRF_DPPI->CH[1].EEP)) = (uint32_t)&NRF_TIMER1->EVENTS_COMPARE[0]; *(&(NRF_DPPI->CH[1].TEP)) = (uint32_t)&NRF_TIMER2->TASKS_STOP; NRF_DPPI->CHENSET |= 1 << 0; } static void ppi_gpiote_counter_init() { NRF_DPPI->CHEN |= 1 << 1; *(&(NRF_DPPI->CH[1].EEP)) = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0]; *(&(NRF_DPPI->CH[1].TEP)) = (uint32_t)&NRF_TIMER2->TASKS_COUNT; NRF_DPPI->CHENSET |= 1 << 1; }
Although, I have changed the name, NRF_PPI to NRF_DPPI in my code to check if that works, it doesn't and I have no clue how to implement that EEP or TEP.
It would be helpful to get some directions on these requirements.