Hello,
I'm currently trying to get a realtime regulation algorithm for the PWM0 module running. I use bare metal programming for the PWM and interrupts. My intention is to trigger an interrupt after each PWM period end, so that I can manually calculate the next PWM cycle (simple calculation within only a couple of cycles). My PWM counter top is configured to 1023, prescaler running at DIV_1 which means 16 MHz. So the interrupt should be triggered with a period of 16 kHz. The PWM generation works just fine (I can update the PWM memory location from within a Zephyr task, but this doesn't satisfy our realtime requirements.
Now I tried to add the interrupt. According to the documentation, I used the following Zephyr declaration:
For now, the interrupt shall just increase a memory variable and then return to the calling context.
I configured and enabled the interrupt this after configuring and starting PWM generation (last three lines of the following code block):
Just to be sure, I activated Zero Latency Interrupts by adding the following line to prj.conf (if you have a look above, I set the interrupt priority to 0 which is highest priority):
The interrupt is triggered, I can debug the code and set a breakpoint at the interrupt handler. The variable is also increased steadily (the interrupt handler is calles repeatedly). Now, the problem is that the interrupt seems to be starving the whole system. My threads are not executed anymore, the call stack at the interrupt handler's breakpoint shows the same layout all the time. If I use the "Step Over" function of the debugger, I end up in my thread's code for a short moment, but immediately execution is interrupted again and the statement does not advance anymore. (Some times in the beginning, the thread seemed to advance one line between each interrupt (or couple of interrupts), but then it stopped.)
I tried adding the NVIC_Cllear_Pending_IRQ() call to my interrupt handler, but it did not help. I also tried to set the prescaler of my PWM configuration to DIV_16 (which should lower the interrupt period to 1 ms), but this also did not help.
Does anyone have an idea what is going wrong here? How can I continue processing my thread's code? For a 128 MHz MCU, a 16 kHz interrupt which just increments a single memory location should not be an issue in my opinion. Especially if I further decrese the period to 1 kHz.
The Nordic plugin also does not help very much. I tried to check the NVIC peripheral, but Visual Studio Code just shows some garbage values that don't make any sense for the register content (all ISER/ICER registers have the same value):
I also tried to check the CLOCK configuration (which is a bit confusing because the module shown in the debugger screen is called CLOCK_NS... I hope the data is still valid? HFCLKSTAT suggests that the HFCLK is not running at all?????
By the way, I started my implementation based on the sample with three threads which was suggested on one of the "getting started" pages from Nordic. At least some weeks ago, it wasn't possible to start a new project if you didn't use an existing project as a template. Maybe this information can help tracking down my problem...
I really hope for quick help on this topic, as my colleagues are waiting for the interrupt based software framework. Thank you very much