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);