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.