Hi
I want to set up FTM0 as a free-running counter, and generate interrupts when CNT matches CnV. In the interrupt handler update CnV for the next timeout and generate another interrupt, and so on.
The issue is that CnV does not seem to be updating immediately (at the next CNT increment), only at overflow. Disabling the clock and putting FTM into "init mode" when updating CnV works, but that affects accuracy. What am I doing wrong?
The software ensures that the next interrupt is due at least 20 timer increments later than the current time (CnV is set to at least CNT+20) and double-checks the time after configuring the timeout. All registers not mentioned below are at their reset value (0). Confirmed with debugger.
FTM0->MODE = FTM_MODE_WPDIS_MASK;
FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PS(6); // this yields 1MHz @64MHz PLL
FTM0->CONTROLS[0].CnSC = FTM_CnSC_CHIE_MASK | FTM_CnSC_MSA_MASK;
Updating CnV in the interrupt handler:
FTM0->SC = 0u;
FTM0->CONTROLS[0].CnV = alarm;
FTM0->SC = SCHTIMER_SC;
This works. However if the clock is not disabled before updating CnV, the new CnV takes effect only after the timer wrapped around to 0, and instead of 1ms, the next interrupt comes 66ms later.
The manual says that output compare mode (MSB:MSA=01 and FTMEN=0) disables the buffer for CnV, it should update at each timer tick. It does not.
Hi ferencvalenta,
Please check if you configure ELSB and ELSA. According to the description of the "Table 47-5. Channel Modes Selection", you cannot left ELSB and ELSA to 0.
I am a bit confused about the function you want to achieve. Do you need to update a larger CnV in this period(MOD) and then make the output pin flip again?
Best Regards,
Robin
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Hi Robin,
Thanks for the quick response!
Setting ELSA has no effect, CnV is still buffered. Other combinations I did not try (yet).
I don't want to control any output pins, just generate timing interrupts for my software. What I need is a 32-bit, fre-running, up-counting timer, that generates interrupts at certain points of time. There are many (on this target probably up to 50) timeouts and they're not periodic, that's why the interrupt handler always needs to program the following expiry point into CnV.
This timer is 16-bits, that's OK. Emulating 32-bit works on other targets. But CnV needs to be updated immediately. Buffering it and updating at overflow only won't work. MOD is always buffered, it's not updated immediately in any modes.
Any other idea? I looked at the other timer peripherals too but they don't seem to offer a better solution.
Ferenc
I think you can use LPTMR to achieve it.
Would you please attach the Output Compare test project?
Hi Robin,
No good: "When the LPTMR is enabled, the CMR can be altered only when CSR[TCF] is set."
This causes a very similar problem. If a timeout is running, and a shorter one needs to be set, the timer has to be disabled, and clock cycles are lost.
LPIT is no good either because it cannot be read outside of the interrupt handler.
Maybe the RTC peripheral could work here?
A possible solution is using 2 FTM timers. One free-running, providing the absolute time, and another one generating the interrupts. The second one can be enabled/disabled without compromising accuracy.
The current solution might be OK, too. Losing some cycles does not seem to be disturbing anything in our system. We don't need microsecond resolution, ms is good enough.
The current FTM0 interrupt handler:
SetTimerInterrupt() is expected to update CnV immediately with the new timeout.After configuring CnV, the timeout is checked again, and if expired we move to the following timeout. This is needed to prevent missing compare matches. GetCurrentTime() also returns a bit later time (configurable), because on some micros the timer value seen by the core might be lagging behind the real value.
AckTimerInterrupt() clears the pending interrupt request in FTM.
I have try to increase CnV in FTM0_CH0 interrupt, the output compare can toggle when counter match new CnV in the same MOD period.
Add FTM0_CH2(blue) as a reference.
The FTM0_CH2 is configured same MOD period and toggle at half of MOD.
You can see the FTM0_CH0(yellow) toggle several times.
FTMEN=1 SYNCEN = 0
I am using oc_pal_s32k144 example of S32SDK S32K1XX RTM 4.0.1.
Best Regards,
Robin
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Hi Robin,
Unfortunately my longer response with memory dump was lost by this forum engine
The good news is that it's finally working. I set FTMEN=1, MOD=0xffff and perform software triggering after updating CnV. Got the idea from the S32 Studio driver code what your demo is using, they also perform SW trigger when in SW trigger mode.
With FTMEN=0 the SW trigger has no effect (that's normal). CnV did not update immediately (that's not OK). I feel that there is a mismatch between the HW and the datasheet, but it can be made working.
My issue is now resolved. Thanks for your quick support. Have a nice day!