Hi
I tried to program a simple dual frequency meter - TIMER3 as gate, and TIMER1 and TIMER2 counting external signals on pins
I do not know why this didn't count - reading always 0
#include "freq_meter.h"
#include "nrfx_gpiote.h"
#include "nrfx_ppi.h"
#define TILT_PIN NRF_DT_GPIOTE_INST(DT_NODELABEL(tilt_int1), gpios)
#define IN_PIN NRF_DT_GPIOTE_INST(DT_NODELABEL(in_int1), gpios)
const struct gpio_dt_spec int1_tilt = GPIO_DT_SPEC_GET(DT_NODELABEL(tilt_int1), gpios);
const struct gpio_dt_spec int1_in = GPIO_DT_SPEC_GET(DT_NODELABEL(in_int1), gpios);
nrfx_timer_t timer1 = NRFX_TIMER_INSTANCE(1);
nrfx_timer_t timer2 = NRFX_TIMER_INSTANCE(2);
nrfx_timer_t timer3 = NRFX_TIMER_INSTANCE(3);
uint8_t tilt_channel, in_channel;
void counter_init(nrfx_timer_t *p_timer)
{
uint32_t base_frequency = NRF_TIMER_BASE_FREQUENCY_GET(p_timer->p_reg);
nrfx_timer_config_t timer_config = NRFX_TIMER_DEFAULT_CONFIG(base_frequency);
//timer_config.frequency=NRF_TIMER_FREQ_16MHz;
timer_config.bit_width=NRF_TIMER_BIT_WIDTH_24;
// Inicjalizacja timera
nrfx_timer_init(p_timer, &timer_config, NULL);
// Włączenie przerwań dla timera
//nrfx_timer_int_enable(p_timer, NRF_TIMER_INT_COMPARE0_MASK);
// Uruchomienie timera
nrfx_timer_enable(p_timer);
}
void counter1_init(void)
{
counter_init(&timer1);
}
void counter2_init(void)
{
counter_init(&timer2);
}
void timer_init(nrfx_timer_event_handler_t irq_handler)
{
uint32_t base_frequency = NRF_TIMER_BASE_FREQUENCY_GET(timer3.p_reg);
nrfx_timer_config_t timer_config = NRFX_TIMER_DEFAULT_CONFIG(base_frequency);
//timer_config.frequency=NRF_TIMER_FREQ_16MHz;
timer_config.bit_width=NRF_TIMER_BIT_WIDTH_24;
// Inicjalizacja timera
nrfx_timer_init(&timer3, &timer_config, irq_handler);
// Konfiguracja wartości do porównania (62500 - 1s)
uint32_t ticks = nrfx_timer_us_to_ticks(&timer3, 1000000);
nrfx_timer_extended_compare(&timer3, NRF_TIMER_CC_CHANNEL0, ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
// Włączenie przerwań dla porównania 0
nrfx_timer_compare_int_enable(&timer3,0);
// Uruchomienie timera
nrfx_timer_enable(&timer3);
}
void gpiote_init(uint32_t pin_tilt, uint32_t pin_in)
{
nrfx_gpiote_init(NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY);
nrfx_gpiote_channel_alloc(&tilt_channel);
nrfx_gpiote_channel_alloc(&in_channel);
nrfx_gpiote_input_config_t config = NRFX_GPIOTE_DEFAULT_INPUT_CONFIG;
config.pull = NRF_GPIO_PIN_NOPULL;
nrfx_gpiote_input_configure(pin_tilt, &config,NRFX_GPIOTE_TRIGGER_LOTOHI,NULL);
nrfx_gpiote_input_configure(pin_in, &config,NRFX_GPIOTE_TRIGGER_LOTOHI,NULL);
/*
NRF_GPIOTE->CONFIG[tilt_channel] = 0x01 << 0;
NRF_GPIOTE->CONFIG[tilt_channel] = pin_tilt << 8;
NRF_GPIOTE->CONFIG[tilt_channel] = 1 << 16;
NRF_GPIOTE->CONFIG[in_channel] = 0x01 << 0;
NRF_GPIOTE->CONFIG[in_channel] = pin_tilt << 8;
NRF_GPIOTE->CONFIG[in_channel] = 1 << 16;
*/
}
void ppi_timer_stop_counter_init(void)
{
static uint8_t stop1_channel,stop2_channel;
nrfx_ppi_channel_alloc(&stop1_channel);
nrfx_ppi_channel_alloc(&stop2_channel);
nrfx_ppi_channel_assign(
stop1_channel,
nrfx_timer_event_address_get(&timer3,NRF_TIMER_EVENT_COMPARE0),
nrfx_timer_task_address_get(&timer1,NRF_TIMER_TASK_STOP)
);
nrfx_ppi_channel_assign(
stop2_channel,
nrfx_timer_event_address_get(&timer3,NRF_TIMER_EVENT_COMPARE0),
nrfx_timer_task_address_get(&timer2,NRF_TIMER_TASK_STOP)
);
nrfx_ppi_channel_enable(stop1_channel);
nrfx_ppi_channel_enable(stop2_channel);
}
void ppi_timer_start_counter_init(void) {
static uint8_t start1_channel,start2_channel;
nrfx_ppi_channel_alloc(&start1_channel);
nrfx_ppi_channel_alloc(&start2_channel);
nrfx_ppi_channel_assign(
start1_channel,
nrfx_timer_event_address_get(&timer3,NRF_TIMER_EVENT_COMPARE1),
nrfx_timer_task_address_get(&timer1,NRF_TIMER_TASK_START)
);
nrfx_ppi_channel_assign(
start2_channel,
nrfx_timer_event_address_get(&timer3,NRF_TIMER_EVENT_COMPARE1),
nrfx_timer_task_address_get(&timer2,NRF_TIMER_TASK_START)
);
nrfx_ppi_channel_enable(start1_channel);
nrfx_ppi_channel_enable(start2_channel);
}
void ppi_gpiote_counter_init(void)
{
/**/
static uint8_t count1_channel,count2_channel;
nrfx_ppi_channel_alloc(&count1_channel);
nrfx_ppi_channel_alloc(&count2_channel);
//uint32_t e_addr_tilt = (uint32_t)&NRF_GPIOTE->EVENTS_IN[tilt_channel];
//uint32_t e_addr_in = (uint32_t)&NRF_GPIOTE->EVENTS_IN[in_channel];
nrfx_ppi_channel_assign(
count1_channel,
nrfx_gpiote_in_event_address_get(int1_tilt.pin),
nrfx_timer_task_address_get(&timer1,NRF_TIMER_TASK_COUNT)
);
nrfx_ppi_channel_assign(
count2_channel,
nrfx_gpiote_in_event_address_get(int1_in.pin),
nrfx_timer_task_address_get(&timer2,NRF_TIMER_TASK_COUNT)
);
nrfx_ppi_channel_enable(count1_channel);
nrfx_ppi_channel_enable(count2_channel);
}
/* main.c - Application main entry point */
/*
* Copyright (c) 2015-2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/types.h>
#include <stddef.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/poweroff.h>
#include <soc.h>
#include <stdio.h>
#include <string.h>
#include <hal/nrf_gpio.h>
#include <hal/nrf_power.h>
#include <nrfx_nvmc.h>
#include <nrfx_timer.h>
#include "freq_meter.h"
volatile uint16_t tilt_counter = 0;
volatile uint16_t in_counter = 0;
volatile uint32_t total_tilt_counter = 0;
volatile uint32_t total_in_counter = 0;
//DEBUG
volatile uint16_t num_int = 0;
static void timer_handler(nrf_timer_event_t event_type, void* p_context)
{
num_int++;
if (event_type == NRF_TIMER_EVENT_COMPARE0)
{
tilt_counter=nrfx_timer_capture(&timer1,0);
total_tilt_counter+=tilt_counter;
in_counter=nrfx_timer_capture(&timer2,0);
total_in_counter+=in_counter;
nrfx_timer_clear(&timer1);
nrfx_timer_clear(&timer2);
}
/*
//my_printk("Timer0 INT\r\n");
if (NRF_TIMER3->EVENTS_COMPARE[0] != 0)
{
NRF_TIMER3->EVENTS_COMPARE[0] = 0;
NRF_TIMER3->EVENTS_COMPARE[1] = 0;
NRF_TIMER1->TASKS_CAPTURE[0] = 1;
NRF_TIMER2->TASKS_CAPTURE[0] = 1;
tilt_counter = NRF_TIMER1->CC[0];
total_tilt_counter+=tilt_counter;
in_counter = NRF_TIMER2->CC[0];
total_in_counter+=in_counter;
NRF_TIMER3->TASKS_CLEAR = 1;
NRF_TIMER1->TASKS_CLEAR = 1;
NRF_TIMER2->TASKS_CLEAR = 1;
NRF_TIMER3->TASKS_START = 1;
}
*/
}
#define TIMER_INST_IDX 3
int main(void)
{
nrf_gpio_cfg_input(int1_tilt.pin, NRF_GPIO_PIN_NOPULL);
nrf_gpio_cfg_input(int1_in.pin, NRF_GPIO_PIN_NOPULL);
IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_TIMER_INST_GET(TIMER_INST_IDX)), IRQ_PRIO_LOWEST,
NRFX_TIMER_INST_HANDLER_GET(TIMER_INST_IDX), 0);
counter1_init();
counter2_init();
timer_init(timer_handler);
gpiote_init(int1_tilt.pin, int1_in.pin);
ppi_timer_stop_counter_init();
ppi_timer_start_counter_init();
ppi_gpiote_counter_init();
uint32_t capt;
do {
capt = nrfx_timer_capture(&timer2,1);
printk("Captured %d num_int %d\r\n", capt, num_int);
printk("tilt counter %d\n", tilt_counter);
printk("in counter %d\n", in_counter);
k_sleep(K_MSEC(1000));
} while (1);
return 0;
}