I am playing with the TIMER peripheral and I am seeing that I must call the function "nrf_timer_event_clear" in order to get the TIMER interrupt to stop firing once a COMPARE_EVENT has occurred. This behavior isn't documented in the OPS, where it seems like you should be able to have a timer reset autonomously by configuring the SHORTS register to fire the CLEAR/STOP event every time a COMPARE_EVENT occurs. I would expect this to de-assert the COMPARE_EVENT because the peripheral counter would no longer equal the CC register.
Is there a way to avoid needing an ISR to clear the COMPARE_EVENT?
I'm including my example code here:
#include <zephyr.h>
#include <hal/nrf_timer.h>
#define TIMER_BASE_ADDR (NRF_TIMER0)
#define TIMER_CHANNEL (0)
/* Uncomment this to have the interrupt fire continuously once it fires once */
//#define BREAK_EXAMPLE
static void timer_interrupt(void*param) {
static unsigned int count = 0;
#ifndef BREAK_EXAMPLE
nrf_timer_event_clear(TIMER_BASE_ADDR,NRF_TIMER_EVENT_COMPARE0);
#endif /* BREAK_EXAMPLE */
printk("interrupt %u\n",count++);
}
void main(void) {
printk("The sample has started\n");
IRQ_CONNECT(DT_NORDIC_NRF_TIMER_2_IRQ_0,
DT_NORDIC_NRF_TIMER_2_IRQ_0_PRIORITY,
timer_interrupt, NULL, 0);
irq_enable(DT_NORDIC_NRF_TIMER_2_IRQ_0);
nrf_timer_mode_set(TIMER_BASE_ADDR,NRF_TIMER_MODE_TIMER);
nrf_timer_frequency_set(TIMER_BASE_ADDR,NRF_TIMER_FREQ_16MHz);
nrf_timer_bit_width_set(TIMER_BASE_ADDR,NRF_TIMER_BIT_WIDTH_32);
/* Reset timer automatically when it fires (or almost reset it...) */
nrf_timer_shorts_enable(TIMER_BASE_ADDR,NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK);
/* Fire every 1s */
nrf_timer_cc_write(TIMER_BASE_ADDR,TIMER_CHANNEL,nrf_timer_ms_to_ticks(1000,NRF_TIMER_FREQ_16MHz));
nrf_timer_int_enable(TIMER_BASE_ADDR,nrf_timer_compare_int_get(TIMER_CHANNEL));
nrf_timer_task_trigger(TIMER_BASE_ADDR,NRF_TIMER_TASK_CLEAR);
nrf_timer_task_trigger(TIMER_BASE_ADDR,NRF_TIMER_TASK_START);
}