S32K148 - more interrupts on a single FTM

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

S32K148 - more interrupts on a single FTM

879 Views
tomasfrcek
Contributor III

Hello,

I would like to setup the FTM on S32K148 to generate two regular interrupts (10 ms and 100 ms). This is my setup code:

uint16_t ftm0_counter_roof_10ms;
uint16_t ftm0_counter_roof_100ms;

void InitRegularTimer(void)
{
uint8_t i;
float tick_time_us;

// SOSCDIV1_CLK as FTM0 clock source.
PCC->PCCn[PCC_FTM0_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_FTM0_INDEX] |= PCC_PCCn_CGC(1U) | PCC_PCCn_PCS(1U);

// Enable protected registers modification.
FTM0->MODE |= FTM_MODE_WPDIS(1U);

// Calculates the SOSCDIV1_CLK divider so that the longest interrupt period (100 ms) counter roof fits into 0xFFFF.
for (i = 0U; i < 8U; i++)
{
tick_time_us = 1.0f / (clk_sosc_div_1_mhz /* variable with SOSCDIV1_CLK value located in a different source code */ / pow(2, i));
if ((100000.0f /* 100 ms = 100000 us */) / tick_time_us < 0xFFFF)
{
break;
}
}
ftm0_counter_roof_10ms = (uint16_t)((10.0f * 1000.0f) / tick_time_us);
ftm0_counter_roof_100ms = (uint16_t)((100.0f * 1000.0f) / tick_time_us);
FTM0->SC = FTM_SC_PS(i);
FTM0->COMBINE = 0x00000000;
FTM0->POL = 0x00000000;
FTM0->MOD = ftm0_counter_roof_100ms + 1U;   // FTM Counter will reset after reaching the higher of the two roofs.

// Enables FTM in debug mode.
FTM0->CONF = FTM_CONF_BDMMODE(3U);

// Output compare mode for FTM channel 0, enables interrupt.
FTM0->CONTROLS[0U].CnSC = FTM_CnSC_CHIE(1U) | FTM_CnSC_MSA(1U);
// Writes the output compare value for 10 ms interrupt.
FTM0->CONTROLS[0U].CnV = ftm0_counter_roof_10ms;

// Output compare mode for FTM channel 1, enables interrupt.
FTM0->CONTROLS[1U].CnSC = FTM_CnSC_CHIE(1U) | FTM_CnSC_MSA(1U);
// Writes the output compare value for 100 ms interrupt.
FTM0->CONTROLS[1U].CnV = ftm0_counter_roof_100ms;

// Activates the counter.
FTM0->SC |= FTM_SC_CLKS(3U);
}

After setting up the FTM this way and enabling the interrupt, I receive the periodic FTM interrupts only for the 100 ms period. In the debug mode, I can see the different values in register CnV0 and CnV1, but the counter always counts to the CnV1 (100 ms) value.

Any idea what I'm missing?

Thanks!

Tags (2)
2 Replies

664 Views
tomasfrcek
Contributor III

Hello again,

sorry for the stupid question. It turns out that I receive the 10 ms interrupt, but only once in each 100 ms period. Logicaly, because I never modify the CnV0 register after the 10ms interrupt. After adding the following line in the interrupt handler:

FTM0->CONTROLS[0U].CnV = (FTM0->CONTROLS[0U].CnV + ftm0_counter_roof_10ms) % ftm0_counter_roof_100ms;

everything works as expected. Im keeping the thread for anyone who might find it useful, or until someone deletes it.

Cheers.

664 Views
razva_tilimpea
NXP Employee
NXP Employee

Hi Tomas,

This behavior is normal because FTM has only one counter and the interrupt is triggered every time when MOD is equal to one of CnV registers or when timer overflows.

To avoid the update of CnV register you can switch your application on LPIT because that peripheral has 4 independent channels. 

Best regards,

Razvan

0 Kudos