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