FlexTimer (FTM): CnV seems to be buffered in output compare modes too

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FlexTimer (FTM): CnV seems to be buffered in output compare modes too

1,164 Views
ferencvalenta
Contributor III

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.

0 Kudos
6 Replies

1,141 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

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.

Table 47-5. Channel Modes Selection.png

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?

update CnV.png

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.
-------------------------------------------------------------------------------

1,136 Views
ferencvalenta
Contributor III

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

 

0 Kudos

1,121 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

I think you can use LPTMR to achieve it. 

Would you please attach the Output Compare test project?

1,118 Views
ferencvalenta
Contributor III

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:

static inline void SchedulerTimer(void)
{
    bool        timeout_set = false;
    node_handle n           = master_timer_list.head;
    FOREVER
    {
        time_type now = GetCurrentTime();
        while(!IS_LIST_END(n&& TIMER_EXPIRED(NODE_TO_TIMEOUT(n)->timenow))
        {
            /* Timeout expired. Execute the action and move to the next one */
            /* Note: to improve performance, the master timer list is only updated before exiting.
             */
            timeout_handle to = NODE_TO_TIMEOUT(n);
            ActivateTask(to->task);
            to->active  = false;
            timeout_set = false;
            n           = n->next;
        }
        if(IS_LIST_END(n))
        {
            AckTimerInterrupt();
            /* List is now empty */
            master_timer_list.head     = n;
            master_timer_list.tailpred = (node_handle)&master_timer_list;
            break;
        }
        else if(!timeout_set)
        {
            /* Configure the hardware counter for the upcoming timeout. */
            /* We'll have to check the timeout again, because the counter match might have been
             * missed during processing. */
            SetTimerInterrupt(NODE_TO_TIMEOUT(n)->time);
            AckTimerInterrupt();
            timeout_set = true;
        }
        else
        {
            /* Next timeout configured. Update the list and exit. */
            master_timer_list.head = n;
            n->prev                = (node_handle)(&master_timer_list);
            break;
        }
    }
}

 

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.

0 Kudos

1,101 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

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.

oc_pal_s32k144 FTM0_CH0 PTD15 pin2 J2.png

FTM0_CH2 PTD0 pin6 J2.pngPins tool FTM0_CH0 FTM0_CH2.png

NewFile0.bmp

FTMEN=1 SYNCEN = 0

Table 47-11. CnV register update.png

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.
-------------------------------------------------------------------------------

1,092 Views
ferencvalenta
Contributor III

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!

0 Kudos