I am using PWM2 on iMX.RT to control an RGB LED which is working ok except that when I turn the LED off using the following call, the outputs are randomly HIGH or LOW depending on the PWM value when it was turned off.
PWM_StopTimer(PWM2, kPWM_Control_Module_0 | kPWM_Control_Module_1);
I have had a look on the forum and the closest related question is this one.
I have a feeling it's something to do with the XBAR but I am not sure and am confused why the XBAR should be involved when using the PWM anyway. The PWM SDK example for the iMX.RT1052 is quite lengthy for something I would expect to be quite simple.
Here's the code I use to set up the three channels of the PWM. I have a separate timer that I use for blinking/flashing of the RGB LED and it is there that I call PWM_StartTimer or PWM_StopTimer accordingly.
I basically want to ensure that when the PWM is stopped all outputs are LOW.
pwm_signal_param_t pwmSignal[3];
pwm_config_t pwmConfig;
pwm_fault_param_t faultConfig;
uint32_t pwmSourceClockInHz;
uint32_t pwmFrequencyInHz = LED_PWM_FREQUENCY_IN_HZ;
// set the PWM Fault inputs to a low value
#if 1
XBARA_Init(XBARA1);
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm2Fault0);
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm2Fault1);
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault2);
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault3);
#endif
PWM_GetDefaultConfig(&pwmConfig);
pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle; // use full cycle reload
pwmConfig.enableDebugMode = true; // turn on debug mode
pwmConfig.pairOperation = kPWM_Independent; // we don't want complementary pair
pwmConfig.prescale = kPWM_Prescale_Divide_8; // divide input clock by 8
/* initialise both of the sub modules that we are going to be using */
if (PWM_Init(PWM2, kPWM_Module_0, &pwmConfig) == kStatus_Fail)
{
LOG_WARN("PWM initialization failed for submodule 0.");
}
if (PWM_Init(PWM2, kPWM_Module_1, &pwmConfig) == kStatus_Fail)
{
LOG_WARN("PWM initialization failed for submodule 1.");
}
#if 0
PWM2->SM[kPWM_Module_0].DISMAP[0] = 0;
PWM2->SM[kPWM_Module_0].DISMAP[1] = 0;
PWM2->SM[kPWM_Module_1].DISMAP[0] = 0;
PWM2->SM[kPWM_Module_1].DISMAP[1] = 0;
#endif
PWM_FaultDefaultConfig(&faultConfig);
#if 0
faultConfig.faultLevel = true;
faultConfig.enableCombinationalPath = false;
#endif
/* Sets up the PWM fault protection */
PWM_SetupFaults(PWM2, kPWM_Fault_0, &faultConfig);
PWM_SetupFaults(PWM2, kPWM_Fault_1, &faultConfig);
PWM_SetupFaults(PWM2, kPWM_Fault_2, &faultConfig);
PWM_SetupFaults(PWM2, kPWM_Fault_3, &faultConfig);
#if 1
/* Set PWM fault disable mapping for channels and submodules we're using */
PWM_SetupFaultDisableMap(PWM2, kPWM_Module_0, kPWM_PwmA, kPWM_faultchannel_0,
kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3);
PWM_SetupFaultDisableMap(PWM2, kPWM_Module_0, kPWM_PwmB, kPWM_faultchannel_0,
kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3);
PWM_SetupFaultDisableMap(PWM2, kPWM_Module_1, kPWM_PwmA, kPWM_faultchannel_0,
kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3);
#endif
pwmSourceClockInHz = PWM_SRC_CLK_FREQ;
// configuration for RED component
pwmSignal[0].level = kPWM_HighTrue;
pwmSignal[0].deadtimeValue = 0;
pwmSignal[0].faultState = kPWM_PwmFaultState0;
pwmSignal[0].pwmChannel = kPWM_PwmA;
pwmSignal[0].dutyCyclePercent = 0;
// configuration for GREEN component
pwmSignal[1].level = kPWM_HighTrue;
pwmSignal[1].deadtimeValue = 0;
pwmSignal[1].faultState = kPWM_PwmFaultState0;
pwmSignal[1].pwmChannel = kPWM_PwmB;
pwmSignal[1].dutyCyclePercent = 0;
if (PWM_SetupPwm(PWM2, kPWM_Module_0, pwmSignal, 2, kPWM_CenterAligned, pwmFrequencyInHz, pwmSourceClockInHz) == kStatus_Fail)
{
LOG_WARN("PWM setup failed.");
}
// configuration for BLUE component
pwmSignal[2].level = kPWM_HighTrue;
pwmSignal[2].deadtimeValue = 0;
pwmSignal[2].faultState = kPWM_PwmFaultState0;
pwmSignal[2].pwmChannel = kPWM_PwmA;
pwmSignal[2].dutyCyclePercent = 0;
if (PWM_SetupPwm(PWM2, kPWM_Module_1, &pwmSignal[2], 1, kPWM_CenterAligned, pwmFrequencyInHz, pwmSourceClockInHz) == kStatus_Fail)
{
LOG_WARN("PWM setup failed.");
}
/* Set the load okay bit for both submodules to load registers from their buffer */
PWM_SetPwmLdok(PWM2, kPWM_Control_Module_0 | kPWM_Control_Module_1, true);
/* Start the PWM generation from Submodules 0 and 1 */
PWM_StartTimer(PWM2, kPWM_Control_Module_0 | kPWM_Control_Module_1);
已解决! 转到解答。
Hi,
I suggest you clear the corresponding bits in PWM OUTEN register, which will disable the PWM signal output, but the PWM module continues to work.
You can use the code to write the register.
PWM2->OUTEN=0x00;
If you connect a external pull-down resistor or set the PWM signal pin as pull-down mode, the pin will be low logic.
Hope it can help you
BR
XiangJun Rong
I think one of the problems I had was that the PWM pin was configured by default for KEEPER when it needed to be PULL. This meant the 100k pull-down wasn't being used. It does pay to be careful when configuring pins because it's not safe to assume that the configuration will be correct if you set a pin to use a peripheral such as PWM, you still have to make sure the other settings are correct. So for I2C etc you will want to make sure you have open drain etc.
Thanks for taking the time to reply.
Yes that does work. I am surprised the fsl_pwm PWM driver doesn't have a function to set/clear the OUTEN bits if this is something that is obviously important.
I am also confused as to why I needed to add an external pull-down resistor because all the PWM pins have a 100K pull-down enabled in the pin configuration. I am assuming that this pull-down is still used when the pin is configured for PWM and not a general purpose GPIO?
Hi,
I suppose that you can set SW_PAD_CTL_PAD_xxx register to enable on-chip pull-down resistor to get low logic of the PWM pin when the PWM outputting function is disabled. But it is a common design to connect pull-down resistor for each PWM pins.
Hope it can help you
BR
XiangJun Rong
Hi,
I suggest you clear the corresponding bits in PWM OUTEN register, which will disable the PWM signal output, but the PWM module continues to work.
You can use the code to write the register.
PWM2->OUTEN=0x00;
If you connect a external pull-down resistor or set the PWM signal pin as pull-down mode, the pin will be low logic.
Hope it can help you
BR
XiangJun Rong