NETCPU timer interrupt issues

Hi,

I have an issue with interrupts on TIMER1 on nrf5340 NETCPU. My setup involves 2 timers that are linked via DPPI, TIMER2 counting microseconds and TIMER1 counting milliseconds. I also have 2 DPPI channels routed via IPC, one each way. The IPC events works, so no issue there. However, I am unable to get an interrupt on capture on TIMER1. A capture is made, and the value in the corresponding CC reg is updated. But nothing happens in the EVENTS_COMPARE register, and no interrupt is generated. On TIMER2 it works just fine. Any idea what is wrong? Just to be super clear: the same event and the same setup fires the interrupt for TIMER2 as expected, but for TIMER1 there is no interrupt.

On a related note: On TIMER2 I found that I had to write the corresponding CC reg to clear the interrupt. I write EVENTS_CAPTURE to 0, and read it back. In addition I also tried to read the CC. Only when I added a write to CC did the interrupt clear. I write 0xffffffff, which is the  only value I have tested. Any idea what this is about?

Device marking is QKAAD0 (I think, small letters...).

A bit of code to describe my setup:

// Set up IPC, DPPI and subscribe to capture
NRF_IPC->PUBLISH_RECEIVE[I2S_FRAME_TICK_IPC_CHANNEL] = I2S_FRAME_TICK_DPPI_CHANNEL | (1 << 31);
NRF_IPC->RECEIVE_CNF[I2S_FRAME_TICK_IPC_CHANNEL] = (1 << I2S_FRAME_TICK_IPC_CHANNEL);
NRF_DPPIC->CHENSET = (1 << I2S_FRAME_TICK_DPPI_CHANNEL);
NRF_TIMER1->SUBSCRIBE_CAPTURE[FRAME_TICK_TS_CC] = I2S_FRAME_TICK_DPPI_CHANNEL | (1 << 31);
NRF_TIMER2->SUBSCRIBE_CAPTURE[FRAME_TICK_HS_CC] = I2S_FRAME_TICK_DPPI_CHANNEL | (1 << 31);
NRF_TIMER2->INTENSET = 1 << (FRAME_TICK_HS_CC + TIMER_INTENSET_COMPARE0_Pos);
NRF_TIMER1->INTENSET = 1 << (FRAME_TICK_TS_CC + TIMER_INTENSET_COMPARE0_Pos);
IRQ_DIRECT_CONNECT(TIMER2_IRQn, 2, frame_tick_handler, 0);
irq_enable(TIMER2_IRQn);
IRQ_DIRECT_CONNECT(TIMER1_IRQn, 0, frame_tick_handler2, 0);
irq_enable(TIMER1_IRQn);

/* Count / timestamp timer */
NRF_TIMER1->TASKS_STOP = 1;
NRF_TIMER1->TASKS_CLEAR = 1;
NRF_TIMER1->PRESCALER = 0;
NRF_TIMER1->MODE = TIMER_MODE_MODE_Counter << TIMER_MODE_MODE_Pos;
NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;
NRF_TIMER1->TASKS_START = 1;    

/* Publish the capture compare match on the count (ms) timer to dppi */
NRF_TIMER1->PUBLISH_COMPARE[0] = TIMESTAMP_TO_IPC_CC_DPPI_CHANNEL | (1 << 31);

/* and subscribe ipc channel 8 to the same channel */
NRF_IPC->SUBSCRIBE_SEND[START_EVENT_IPC_CHANNEL] = TIMESTAMP_TO_IPC_CC_DPPI_CHANNEL | (1 << 31);
NRF_IPC->SEND_CNF[START_EVENT_IPC_CHANNEL] = (1 << START_EVENT_IPC_CHANNEL);

/* Aaand enable dppi channel */
NRF_DPPIC->CHENSET = (1 << TIMESTAMP_TO_IPC_CC_DPPI_CHANNEL);

HS_TIMER->PUBLISH_COMPARE[0] = (HS_TO_TIMESTAMP_COUNT_DPPI_CHANNEL) | (1 << 31);
NRF_TIMER1->SUBSCRIBE_COUNT = (HS_TO_TIMESTAMP_COUNT_DPPI_CHANNEL) | (1 << 31);
NRF_DPPIC->CHENSET = (1 << HS_TO_TIMESTAMP_COUNT_DPPI_CHANNEL);

NRF_TIMER2->TASKS_STOP = 1;
NRF_TIMER2->TASKS_CLEAR = 1;
NRF_TIMER2->PRESCALER = HS_TIMER_PRESCALER;
NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;
NRF_TIMER2->CC[0] = TIME_SYNC_TIMER_MAX_VAL;
NRF_TIMER2->CC[1] = 0xFFFFFFFF;
NRF_TIMER2->CC[2] = 0xFFFFFFFF;
NRF_TIMER2->CC[3] = 0xFFFFFFFF;
NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk | TIMER_SHORTS_COMPARE2_CLEAR_Msk;
NRF_TIMER2->TASKS_START = 1;

Parents Reply
  • No, my last comment is not a fix, it was simply about your readability.

    Even if I remove the IPC/DPPI stuff for triggering the interrupt, and do a NRF_TIMER1->TASKS_CAPTURE[n] the interrupt will only run execute for TIMER2. I've also tried to run it in normal mode (not counter mode) and without the DPPI chaining of timers.

    I also checked the relevant isr_tables.c to see that my ISR is included.

    Any ideas as to next steps?

Children
Related