If you're debugging an application on the Kinetis KV30 MCU (and, I'm guessing, other members of the family) using the on-chip debugger...
...And you're generating PWM using one of the Flex-Timer Modules...
...And you hit a breakpoint...
...The timer ceases to generate PWM. You'd think: hardware-type peripheral continues running while the CPU is stopped at the breakpoint. But you'd be wrong.
So far, I haven't seen it stop with the output HIGH; if the behavior is consistent, with the output always LOW when at a breakpoint, it's possible (for some applications) to design around that, and not have adverse hardware consequences when a breakpoint is encountered.
But, if some hardware design optimization dictates that the "safe" condition is output-HIGH, then hitting a breakpoint could result in a ruptured smoke bushing.
I recall running into some related issue when debugging on an AVR... over a decade ago. But the FTM is an 8-bit peripheral grafted into a 32-bit MCU, so what should I expect?
(It's also possible that I have something misconfigured at the library level, given that the output is waking up at the default-configured duty cycle and my attempts to change it on the fly don't appear to have any effect. Once I sort that out, I'll have to address the problem of the high-level library taking an integer percentage for the duty cycle, when I really need to have finer-grained control.)
Update: OK, so I was missing something. Behavior is configurable; there are four BDM modes, and BDM Mode 3 is what I was expecting; the others are meant to go "safe" at breakpoints. So that's working now. Yet to be sorted out: why the duty cycle isn't updating, and/or why some configuration options cause the FTM to generate an unhandled interrupt upon initialization.
Update 2: Awright, got it updating and using full resolution now, mainly by bypassing the peripheral-driver layer after initialization.
Import the necessary:
#include "fsl_ftm_hal.h" #define FTM0 (g_ftmBase[0])
During initialization:
// Set the PWM divisor to a known 4096 instead of some calculated value FTM_HAL_SetMod(FTM0, 4096);
To set the actual PWM pulse width in clock ticks:
FTM_HAL_SetChnCountVal(FTM0, 2, pwm1val); FTM_HAL_SetChnCountVal(FTM0, 4, pwm2val); // Now trigger the update of the actual FTM registers FTM_HAL_SetSoftwareTriggerCmd(FTM0, 1);
Seems to be doing what I want. The documentation isn't very clear, and the peripheral driver is missing that all-important "change the dang duty cycle" function - if you're using that level of driver, you have to call FTM_DRV_PwmStop and then FTM_DRV_PwmStart, because repeated calls to FTM_DRV_PwmStart don't result in actual changes of duty cycle. Also, if you're using multiple channels, you have to call FTM_DRV_PwmStop in between the ...Start calls for the channels. Or something like that. It's all very confusing, really.
Comments