Using FTM compare

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

Using FTM compare

900 Views
mauriziospagni
Contributor II

I want to use one timer (FTM2 in my case) of a MKE02Z32VLC2 to set a flag after a specified time. In this case, just for testing, it's fixed at 10000 timer steps but in practice it will be variable.

The standard procedure, used thousand of times in other projects with many other processors, is replicated in this processor as follows:

FTM2_C0SC = FTM_CnSC_MSA_MASK; // MS = 0:1 (compare), ELS = 0:0, interrupt disabled

FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_PS(6); // System clock, prescaler 64

while (1)

{

   // Output pin Toggle

   FTM2_C0V = FTM2_CNT + 10000; // Set the compare value

   FTM2_C0SC &= ~FTM_CnSC_CHF_MASK; // Reset of the event flag

   do {} while ((FTM2_C0SC & FTM_CnSC_CHF_MASK) == 0); // Wait for the compare event

}

But in this case it doesn't work. I see the output toggling every timer rollover. It seems that FTM2_C0V is not set.

I know that FTM2_C0V is really updated only after the timer has advanced one step, but here it seems it's simply ignored.

By the way: the timer clock is much slower than the CPU clock.

I was unable to find any example on the 'net.

Any idea?

0 Kudos
6 Replies

789 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi Maurizio Spagni,

It seems that you only need the timer set a flag after a specified time, don't need one pin output waveform.
Then I recommend you use PIT instead of use FTM Output Compare mode.

PIT.png

FTM Output Compare mode.png

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

789 Views
mauriziospagni
Contributor II

Hi Robin,

Robin_Shen wrote:

It seems that you only need the timer set a flag after a specified time, don't need one pin output waveform.

Yes, right that, but the thing is absolutely a-periodical.

I mean: sometime in the program execution I neet to know when some time has passed, so I set the compare at (current time + delay) (i.e. FTM2_C0V = FTM2_CNT + delta) then the program does something else and, synchronously, periodically polls the event flag (FTM_CnSC_CHF).

That's common practice since the times of Motorola HC08.

And the thing doesn't change even if I use the interrupts.

My question is more specifically addressed on: why the FTM behaves in this odd mode? What I overlooked?

Regards

Maurizio

0 Kudos

789 Views
mauriziospagni
Contributor II

This works:

FTM2_C0SC = FTM_CnSC_MSA_MASK; // MS = 0:1 (compare), ELS = 0:0, interrupt disabled

FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_PS(6); // System clock, prescaler 64

while (1)

{

  uint32_t foo;

   // Output pin Toggle

   foo = FTM2_CNT;

   FTM2_C0V = foo + 10000; // Set the compare value

   do {} while (foo == FTM2_CNT); // Wait for the actual loading of FTM2_C0V

   FTM2_C0SC &= ~FTM_CnSC_CHF_MASK; // Reset of the event flag

   do {} while ((FTM2_C0SC & FTM_CnSC_CHF_MASK) == 0); // Wait for the compare event

}

but it's absurd I need to waste time waiting for FTM2_C0V to be loaded.

0 Kudos

789 Views
mauriziospagni
Contributor II

It seems that I'm not alone!

The problem was already met here.

I missed that post when I browsed the community because I was looking for "compare".

Anyway, as far as I understand, the problem was not solved.

N.B. A slightly better (but still completely unsatisfactory) way to make it work is as follow:

while (1)

{

  uint16_t foo;

   // Output pin Toggle

   foo = FTM2_CNT + 10000;

   FTM2_C0V = foo; // Set the compare value

   do {} while (FTM2_C0V != foo); // Wait for the actual loading of FTM2_C0V

   FTM2_C0SC &= ~FTM_CnSC_CHF_MASK; // Reset of the event flag

   do {} while ((FTM2_C0SC & FTM_CnSC_CHF_MASK) == 0); // Wait for the compare event

}

0 Kudos

789 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

26.4.10.3 CnV register update.png

Since the thing is absolutely a-periodical, would you please try:

first 

FTM2_C0V = 10000;

then

FTM2_SC |= FTM_SC_CLKS(1);

 

789 Views
mauriziospagni
Contributor II

In a nutshell: stop the timer when updating FTM2_C0V.

In my case:

void SetShortTimeout(uint16_t us)
{
  FTM2_SC = FTM_SC_CLKS(0) | FTM_SC_PS(6); // Stop the timer
  FTM2_C0V = FTM2_CNT + us;                               // New compare value
  FTM2_C0SC &= ~FTM_CnSC_CHF_MASK;          // Reset of the event flag
  FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_PS(6); // Restart the timer
}

Good workaround... perfect for me and in this case. Thank you very much.

But this operation disturbs the main counter, i.e. all the 8 channels!

How awful...

0 Kudos