Hello all,
I'm writing an unloadable driver for the PWM functionality of the FTM of my K60 (using the TWRK60N512 and CodeWarrior). When unloading the driver, I want it to leave the FTM and all channels in a clean state so that the next user of the PWM facility cannot ever get a first cycle with yesterday's stale duty cycle. However, I can't manage to make the value of CnV stick.
Code snippet (uses MQX delay function, otherwise bare metal):
uint_32 dummy; FTM_MemMapPtr pRegs = FTM0_BASE_PTR; // 1. switch on the clocks // a. for the port module SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK; // b. for the FTM SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK; // configure port multiplexer PORTC_PCR1 = PORT_PCR_MUX(4); PORTC_PCR2 = PORT_PCR_MUX(4); // a. make writable (must read bit WPEN of FTMx_FMS, // then write a 1 to WPDIS of FTMx_MODE) dummy = pRegs->FMS; pRegs->MODE |= FTM_MODE_WPDIS_MASK; // b. clear FTMEN flag, requires WPDIS to be set. pRegs->MODE &= ~FTM_MODE_FTMEN_MASK; // c. disable quadrature encoder pRegs->QDCTRL &= ~FTM_QDCTRL_QUADEN_MASK; // d. reset counter pRegs->CNT = 0; pRegs->MOD = 6000; pRegs->CNTIN = 0; // counter starts at 0, nothing fancy FTM0_C1V = 1000; // set Prescaler and use so-called system clock. FTM0_SC = (3 & FTM_SC_PS_MASK) | (0x1 << FTM_SC_CLKS_SHIFT) // FTM system clock, i.e. Kinetis bus-clock ; FTM0_C1SC = (0 << FTM_CnSC_DMA_SHIFT) | (0 << FTM_CnSC_ELSA_SHIFT ) | (1 << FTM_CnSC_ELSB_SHIFT ) | (0 << FTM_CnSC_MSA_SHIFT ) | (1 << FTM_CnSC_MSB_SHIFT ) | (0 << FTM_CnSC_CHIE_SHIFT ); FTM0_C1V = 4000; _time_delay(5000); // turn your head towards the oscilloscope // shut down the counter FTM0_SC = 0; // shut down the channel FTM0_C1SC = 0; FTM0_C1V = 0; _time_delay(10); // let it settle _time_delay(1000);
I expect the debugger to read FTM0_C1V as 0 after the line "let it settle". At least that's what I've concluded from The Book, chapter 39.4.10.3, "CnV Register Update", verse "If CLKS[1:0]=0:0 then CnV register is updated when CnV register is written". However, I still read the old value.
In order to minimize debugger impact on FTM, I've only set breakpoints before the 5000ms delay and after the "let it settle".
Am I doing it wrong, is the FTM wrong, is the debugger wrong, or should I just not worry about stale PWM cycles?
Thanks in advance, KA.
Thanks to the effects of having posted a public question, I've found a sequence which works:
I had a similar problem. There are actually a few ways you could do it, depending on your needs. Look for "Register Update" under the FTM section in the manual for your particular chip and you'll see the options you have.
I also tried enabling the advanced FTM registers in order to perform a software trigger, with no better results. Perhaps if I had combined that attempt with the reversed order of the access to CnSC and CnV, it would have worked. Whatever -- I only need very basic EPWM.