I've been trying to configure the FTM0 Flex Timer to generate centered aligned PWM. I have followed several examples I've found on the internet even on here on the forum however, I cannot get channel 0 (PORTC PTC1) to output the pulse wave. I have double, triple and quadruple checked all the register configurations and they seem correct. I've pasted my code below:
SIM_BASE_PTR->SCGC5 |= SIM_SCGC5_PORTC_MASK;
SIM_BASE_PTR->SCGC6 |= SIM_SCGC6_FTM0_MASK;
PORTC_BASE_PTR->PCR[1] = PORT_PCR_MUX(4) | PORT_PCR_DSE_MASK;
temp = FTM0_BASE_PTR->FMS;
FTM0_BASE_PTR->MODE |= FTM_MODE_WPDIS_MASK;
FTM0_BASE_PTR->MODE &= ~FTM_MODE_FTMEN_MASK;
FTM0_BASE_PTR->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK;
FTM0_BASE_PTR->CNT = 0;
FTM0_BASE_PTR->MOD = 4000;
FTM0_BASE_PTR->CNTIN = 0;
FTM0_C0SC = FTM_CnSC_ELSA_MASK;
FTM0_C0V = 2000;
FTM0_BASE_PTR->SC = FTM_SC_CPWMS_MASK | FTM_SC_CLKS(1);
What am I missing that is preventing the PWM signal from coming out on PWM0?
Solved! Go to Solution.
So it turns out that the order in which the CPWMS bit is set makes all the difference. By placing the SC register initialization before the ELSA initialization, the PWM pulse wave now appears on PTC1 CH0.
SIM_BASE_PTR->SCGC5 |= SIM_SCGC5_PORTC_MASK;
SIM_BASE_PTR->SCGC6 |= SIM_SCGC6_FTM0_MASK;
PORTC_BASE_PTR->PCR[1] = PORT_PCR_MUX(4) | PORT_PCR_DSE_MASK;
temp = FTM0_BASE_PTR->FMS;
FTM0_BASE_PTR->MODE |= FTM_MODE_WPDIS_MASK;
FTM0_BASE_PTR->MODE &= ~FTM_MODE_FTMEN_MASK;
FTM0_BASE_PTR->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK;
FTM0_BASE_PTR->CNT = 0;
FTM0_BASE_PTR->MOD = 4000;
FTM0_BASE_PTR->CNTIN = 0;
FTM0_BASE_PTR->SC = FTM_SC_CPWMS_MASK | FTM_SC_CLKS(1);
FTM0_C0SC = FTM_CnSC_ELSA_MASK;
FTM0_C0V = 2000;
According to the table on p.952 of the reference manual, you get Input Capture when MSnB:MSnA is 0. If you want high pulses from counter overflow to C0V match, I recommend setting ELSnB and MSnB.
HTH, KA
So it turns out that the order in which the CPWMS bit is set makes all the difference. By placing the SC register initialization before the ELSA initialization, the PWM pulse wave now appears on PTC1 CH0.
SIM_BASE_PTR->SCGC5 |= SIM_SCGC5_PORTC_MASK;
SIM_BASE_PTR->SCGC6 |= SIM_SCGC6_FTM0_MASK;
PORTC_BASE_PTR->PCR[1] = PORT_PCR_MUX(4) | PORT_PCR_DSE_MASK;
temp = FTM0_BASE_PTR->FMS;
FTM0_BASE_PTR->MODE |= FTM_MODE_WPDIS_MASK;
FTM0_BASE_PTR->MODE &= ~FTM_MODE_FTMEN_MASK;
FTM0_BASE_PTR->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK;
FTM0_BASE_PTR->CNT = 0;
FTM0_BASE_PTR->MOD = 4000;
FTM0_BASE_PTR->CNTIN = 0;
FTM0_BASE_PTR->SC = FTM_SC_CPWMS_MASK | FTM_SC_CLKS(1);
FTM0_C0SC = FTM_CnSC_ELSA_MASK;
FTM0_C0V = 2000;
Try to write LDOK in FTMx_PWMLOAD.
You must write to LDOK everyttime you want to change timer parameters - it couse the real write to timer registers from buffered registers
Lukas,
I'll give that a try but isn't that one of the FTM extended registers which requires FTMEN = 1 to write to? I haven't been trying to use those registers, only the TPM legacy. I've also validated that the timer is functioning in up-down mode by monitoring the CNT register. It just seems that either the CnV is not triggering or I'm still missing something to configure the pin to output.