Hi,
I am trying to set up a project that continuously measures the pulse width of a signal that may or may not be present at a pin.
I want to use a Timer in capture mode that automatically starts when the edge signal changes, and generates an interrupt when the next edge is detected so it can store the value in a running array. Then after the interrupt the process starts again.
(I am using SDK 17.0.2)
Timer->GPIOTE->PPI
I am struggling a little with the config, and am wondering if this is the correct approach or not:
#include "nrfx_timer.h"
#include "nrfx_gpiote.h"
#include "nrfx_ppi.h"
#define IR_SAMPLE_SIZE 32
#define IR_GPIOTE_CHANNEL 0
static volatile uint32_t IR_PulseTimes[IR_SAMPLE_SIZE];
static volatile uint16_t IR_PulseTimesIndex;
#define TIMER_INST_IDX 4 // Or the desired timer instance index
static nrfx_timer_t timer_inst = NRFX_TIMER_INSTANCE(TIMER_INST_IDX);
static nrf_ppi_channel_t ppi_channel;
static void timer_handler(nrf_timer_event_t event_type, void *p_context)
{
(void)p_context; // Unused parameter
if (event_type == NRF_TIMER_TASK_CAPTURE0)
{
IR_PulseTimes[IR_PulseTimesIndex] = nrfx_timer_capture(&timer_inst, NRF_TIMER_CC_CHANNEL0);
if (++IR_PulseTimesIndex >= IR_SAMPLE_SIZE)
{
IR_PulseTimesIndex = 0;
}
}
}
void IR_Init(void)
{
memset((uint8_t*)IR_PulseTimes, 0x00, sizeof(IR_PulseTimes));
IR_PulseTimesIndex = 0;
nrfx_gpiote_in_config_t config = NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);
config.pull = NRF_GPIO_PIN_NOPULL;
APP_ERROR_CHECK(nrfx_gpiote_in_init(IO_IR, &config, NULL));
nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG;
timer_cfg.frequency = NRF_TIMER_FREQ_16MHz;
timer_cfg.mode = NRF_TIMER_MODE_TIMER;
timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
nrfx_timer_init(&timer_inst, &timer_cfg, timer_handler);
// Find an available PPI channel
nrfx_ppi_channel_alloc(&ppi_channel);
// Configure PPI channel to connect GPIOTE event to TIMER capture task
nrfx_ppi_channel_assign(ppi_channel,
nrfx_gpiote_in_event_addr_get(IO_IR),
nrfx_timer_capture_task_address_get(&timer_inst, NRF_TIMER_CC_CHANNEL0));
}
void IR_Enable(bool Enabled)
{
if (Enabled)
{
memset((uint8_t*)IR_PulseTimes, 0x00, sizeof(IR_PulseTimes));
IR_PulseTimesIndex = 0;
nrfx_timer_compare_int_enable(&timer_inst, NRF_TIMER_CC_CHANNEL0);
nrfx_gpiote_in_event_enable(IO_IR, true);
nrfx_timer_enable(&timer_inst);
nrf_ppi_channel_enable(ppi_channel);
}
else
{
nrf_ppi_channel_disable(ppi_channel);
nrfx_timer_disable(&timer_inst);
nrfx_gpiote_in_event_enable(IO_IR, false);
nrfx_timer_compare_int_disable(&timer_inst, NRF_TIMER_CC_CHANNEL0);
}
}
I would appreciate any pointers or examples to get this working, i cannot seem to get the interrupt firing.
Many thanks
Billy