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
  • I'm using custom hw.

    I've created a quick example for NRF5340dk, which modifies the blinky example from zephyr. Please see how only one led blinks. By removing/toggling TIMERn->TASKS_CAPTURE in the main function you can change the behaviour.There is also terminal output you can look at.

    Please also note that you need to write the CC reg in the ISR to clear the interrupt. This is not documented in the DS afaik.

    0523.blinky.zip

Children
Related