How to count external events with flex timer Module [K64F+KDS]

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

How to count external events with flex timer Module [K64F+KDS]

跳至解决方案
1,932 次查看
hunt
Contributor II

Good morning,

I don't know if this is the correct section fow asking this question.

 

I have a FRDM k64F board and I wanted to count external event (the rising edges of an external square-wave).

I wanted to connect it to FTM2_CH0  (also PTB18) as input, so I tried with processor Expert to instantiate the component EventCntr_LDD but is impossible to select such pin,

I can only select the clock_in pins (PTB16, PTB17, PTA18, PTA19)....

How can I do it??

 

16606_16606.jpg1.jpg

标签 (1)
0 项奖励
1 解答
725 次查看
ZhangJennie
NXP TechSupport
NXP TechSupport

Hello hunt.

If you want to count external events (rising edges of a signal) you must use an FTM counter with an external clock pin selected. The FTM channels contain compare registers only (there are not counters) and these channels cannot be used for counting external events (you can use FTM channel in input capture mode only - the counter value is capture on external event - see the detailed description in the K64 Sub-Family Reference Manual).
Therefore you can use the EventCntr_LDD component and select one of the Counter input pin only (PTB16, PTB17, PTA18, PTA19) to count external events (FTM channels are not used in this mode). This is the standard functionality that is provided by the FTM.



====================================

if this answer helps, please click on "Correct Answer " button. thanks!



Best Regards,

Zhang Jun

在原帖中查看解决方案

0 项奖励
3 回复数
726 次查看
ZhangJennie
NXP TechSupport
NXP TechSupport

Hello hunt.

If you want to count external events (rising edges of a signal) you must use an FTM counter with an external clock pin selected. The FTM channels contain compare registers only (there are not counters) and these channels cannot be used for counting external events (you can use FTM channel in input capture mode only - the counter value is capture on external event - see the detailed description in the K64 Sub-Family Reference Manual).
Therefore you can use the EventCntr_LDD component and select one of the Counter input pin only (PTB16, PTB17, PTA18, PTA19) to count external events (FTM channels are not used in this mode). This is the standard functionality that is provided by the FTM.



====================================

if this answer helps, please click on "Correct Answer " button. thanks!



Best Regards,

Zhang Jun

0 项奖励
32 次查看
DaveTonyCook
Contributor IV

Hi,

I'm using the K24. I was unaware of the limitations of the FTM and was forced to use the module because the signal of interest had already been routed to pin 64, PTA3, FTM 1 Ch0.

Problem:

Measure a 1MHz square wave and determine if it is within +/- 5% of the selected frequency.  This should have been straight forward.  Using the FTM in continuous capture mode was not an option because the interrupt frequency on rising edges would have been to high at one interrupt every 1us.

The K24 has does not have a dedicated pulse counter like the ColdFire. Instead you can use the external clock input to drive the counter and interrupt on counter overflow (TOF bit).

My solution was to use the FTM in capture mode and use a PIT to start the capture every 500ms. The FTM ISR runs for 2 rising edges then disables itself. 

I believe that the module can be set to run in one-shot mode but it is unclear on how to use this.  

Also, the results that I get are not very good in terms of accuracy, stability and resolution. The duration of FTM ISR is different each time it executes!

Can anyone see a mistake or omission in the supplied code that would explain why I get poor results from this hardware? 

The SDK does not implement the driver for input capture so I had to I had to write this layer myself.  This has caught out both myself and the hardware engineer.  My solution is set out below for anyone who is interested:

/*!
***************************************************************************
@brief Function Name : FTM1_IRQHandler

@brief Description :
Implementation of FTM1 handler defined in tx_initialize_low_level.s
Captures the Freq_monitor signal. If the period between captured
events remains within expected bounds no fault is reported. However,
it flags a fault if this condition is violated for an extended period.

Used on TF heads where the Frequency monitor signal enters the UCB on
Pin 21 of J8 from the DDS chip and is nominally 1MHz.

Capture count is always set to 0 at start.

@brief Parameters :
@brief

@brief

***************************************************************************
*/
void FTM1_IRQHandler(void)
{
#ifdef DBG_FTM_FRQ_MON_CAPT // IQ4HPH-90
static uint32_t n = 0;
#endif

// Read the captured value
captureValue = FTM1_C0V;

captureCount++;

// Calculate period on 2nd rising edge
if (captureCount >= 2)
{
captureCount = 0; // Reset capture count for the next period

captureStarted = false; // Reset capture started flag used by application

// Stop counter. Started by PIT3 interrupt handler every 500ms
FTM1_SC &= ~FTM_SC_CLKS(7); // Select NO clock. Using RMW on SC reg.

NVIC_ClearPendingIRQ(g_ftmIrqId[HW_FTM1]);

// Calculate frequency only when two capture events have occurred
tempCaptureValue = captureValue;
period = tempCaptureValue - lastCaptureValue;

// No idea why the counts are so low. Driven by sys_clock at 120MHz (apparently!)
// I would expect 1us / 8.3ns = 120 at 120MHz clock. Counts are not stable
// and vary between limits 2 to 9. Also, see input filter calc in init code.
if( (period>2) && (period<9))
{
count = 0;
}
else
{
count++;
}

if (count > 20)
{
__disable_irq();
freq_mon_fault = true; // shared resource
__enable_irq();
count = 0;
}

#ifdef DBG_FTM_FRQ_MON_CAPT // IQ4HPH-90
__ITM_EVENT8(2,n++); // Output itm trace to timeline
#endif
}
else // 1st rising edge
{
// Update last captured value for the next calculation
lastCaptureValue = captureValue;

#ifdef DBG_FTM_FRQ_MON_CAPT // IQ4HPH-90
__ITM_EVENT8(2,n++); // Output itm trace to timeline
#endif
}

// Clear Channel Flag to ack interrupt
FTM1_C0SC &= ~FTM_CnSC_CHF_MASK;
}

/*!
***************************************************************************
@brief Function Name : FTM1_DRV_InputCaptureInit()

@brief Description : This function is the public interface to the FTM1
Input Capture driver initialization routine.

Configures the timer in capture mode to interrrupt
on rising edge of input signal.

Interrupts are enabled but clock source is deffered
to the PIT timer interrupt so does not run until the
PIT ISR starts the FTM by selecting the FTM clock
source.

Uses the CMSIS Peripheral Access Layer for MK24F12
instead of the HAL and is specific for FTM1 Ch0


@brief Parameters : None

NB: for some reason system clock seems to be 60MHz not 120MHz
***************************************************************************
*/
void FTM1_DRV_InputCaptureInit(void)
{
// Enable clock to the FTM1 module
SIM_SCGC6 |= SIM_SCGC6_FTM1_MASK;

// Configure pin 64 and its alternate function for FTM1 Ch 0. pin PTA12 (64)
PORTA_PCR12 = PORT_PCR_MUX(3);

// Disable write protection for FTM1 registers
FTM1_MODE |= FTM_MODE_WPDIS_MASK;

// Configure FTM1 as input capture
FTM1_SC = 0; // Ensure FTM1 is disabled for setup
FTM1_SC &= ~FTM_SC_TOIE_MASK; // Disable Timer Overflow Interrupt
FTM1_SC &= ~FTM_SC_TOF_MASK; // Clear Timer Overflow Event flag
FTM1_CNTIN = 0; // Count reset to 0
FTM1_MOD = 0xFFFF; // Set the modulo register for maximum count

// The clk source is set by FTM1_DRV_CaptureStart() to 60MHz which starts the capture
FTM1_SC &= ~FTM_SC_CLKS(7); // Select NO clock. Using RMW on SC reg.
FTM1_SC |= FTM_SC_PS(0); // Select NO prescaler.

// Configure FTM1 Channel 0 for input capture on rising edge only
FTM1_C0SC = FTM_CnSC_ELSA_MASK; // Capture on rising edge
FTM1_C0SC |= FTM_CnSC_CHIE_MASK; // Enable channel interrupts

FTM1_FILTER |= FTM_FILTER_CH0FVAL(7); // (60MHz / 4) x FVAL = 500ns ie half the input period
// FVAL = 500 / 66.67 = 7.5. Val = 8 stop operation.
// I have no idea why using SYS_CLK / 2 works (ie 60MHz).

#ifdef DEBUG_CPT
// Enable CAPTEST mode for FTM1 (simulate input capture events internally)
FTM1_CONF |= FTM_CONF_CAPTEST_MASK;
#endif

/* Configure NVIC. Register interrupt into Ram Vector table */
os_install_int_handler (g_ftmIrqId[HW_FTM1], FTM1_ISR);

NVIC_SetPriority(FTM1_IRQn, 1); // ISR runs every 500ms for ?ns

NVIC_ClearPendingIRQ(g_ftmIrqId[HW_FTM1]);

/* Enable FTM interrupt in NVIC level.*/
INT_SYS_EnableIRQ(g_ftmIrqId[HW_FTM1]);

count = 0;
freq_mon_fault = false;
}

/*!
***************************************************************************
@brief Function Name : FTM1_DRV_CaptureStart()

@brief Description : Starts the FTM1 Ch0 capture by selecting the clock.
Clock starts count. Also, clears the count and sets
the global capture started flag that's used by
the application

Uses the CMSIS Peripheral Access Layer for MK24F12
instead of the HAL and is specific to FTM1 Ch0


@brief Parameters : None

***************************************************************************
*/
void FTM1_DRV_CaptureStart(void)
{
captureStarted = true; // Used by PIT3 isr handler

// Start counter
FTM1_SC |= FTM_SC_CLKS(1); // Select Sys clock. 60MHz !?
FTM1_SC |= FTM_SC_PS(4); // Select NO prescaler.

FTM1_CNT = 0; // Reset the counter
}

 

Thanks

0 项奖励
725 次查看
hunt
Contributor II

Thank you very much, for your help.

The problem of the clock pins (it was my first choice) is that any of these pins, is connected to the output connector (please correct me if I'm wrong)

I solved using the LPTMR unit that allows counting events using the PTC5 pin (LPTMR0_ALT2).

Anyway, thank you again for your help. 

0 项奖励