PWM Initialization
void pwmInit(void)
{
uint32_t pwmFrequencyInHz = DEFAULT_PWM_FREQUENCY;
uint32_t pwmSourceClockInHz = PWM_SRC_CLK_FREQ;
/*===============================
1. Clock Setup (Reusing Previous Settings)
===============================*/
// CLOCK_SetDiv(kCLOCK_IpgDiv, 11); // IPG clock = 600MHz / (11+1) = 50MHz
// CLOCK_SetDiv(kCLOCK_AhbDiv, 0x2); // AHB clock = 600MHz / 3 = 200MHz
// CLOCK_SetDiv(kCLOCK_IpgDiv, 0x3); // IPG clock = 200MHz / 4 = 50MHz
/*===============================
2. Pin Configuration (IOMUXC_GPIO_AD_B0_10_FLEXPWM1_PWMA03 -> FlexPWM1_PWMA03)
===============================*/
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_10_FLEXPWM1_PWMA03, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_10_FLEXPWM1_PWMA03, 0x10B0U);
/*===============================
3. XBARA Configuration (Disable Fault Inputs)
===============================*/
XBARA_Init(XBARA1);
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1Fault0);
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1Fault1);
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault2);
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault3);
/*===============================
4. FlexPWM Configuration
pwmConfig.enableDebugMode = false;
pwmConfig.enableWait = false;
pwmConfig.reloadSelect = kPWM_LocalReload;
pwmConfig.clockSource = kPWM_BusClock;
pwmConfig.prescale = kPWM_Prescale_Divide_1;
pwmConfig.initializationControl = kPWM_Initialize_LocalSync;
pwmConfig.forceTrigger = kPWM_Force_Local;
pwmConfig.reloadFrequency = kPWM_LoadEveryOportunity;
pwmConfig.reloadLogic = kPWM_ReloadImmediate;
pwmConfig.pairOperation = kPWM_Independent;
===============================*/
pwm_config_t pwmConfig;
PWM_GetDefaultConfig(&pwmConfig);
/*===============================
PWM Configuration: Independent Mode, 50% Duty Cycle, 20kHz
===============================*/
pwmConfig.enableDebugMode = true; // Enable debug mode
pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle; // Reload after full cycle
pwmConfig.pairOperation = kPWM_Independent;
pwmConfig.clockSource = kPWM_BusClock; // Use IPG clock (150MHz)
pwmConfig.prescale = kPWM_Prescale_Divide_2; // If divide is 1, 150MHz/2000 results in 75000, which exceeds 2-byte 65535, causing incorrect frequency output.
/*===============================
Initialize FlexPWM1 Submodule 3
===============================*/
PWM_Init(PWM_BASEADDR, kPWM_Module_3, &pwmConfig);
/*===============================
config->faultClearingMode = kPWM_Automatic;
config->faultLevel = false;
config->enableCombinationalPath = true;
config->recoverMode = kPWM_NoRecovery;
===============================*/
pwm_fault_param_t faultConfig;
PWM_FaultDefaultConfig(&faultConfig);
PWM_SetupFaults(PWM_BASEADDR, kPWM_Fault_3, &faultConfig);
PWM_OutputTriggerEnable(PWM_BASEADDR, kPWM_Module_3, kPWM_ValueRegister_3, true);
/*===============================
===============================*/
pwm_signal_param_t pwmSignal;
pwmSignal.pwmChannel = kPWM_PwmA; // Use Channel A
pwmSignal.level = kPWM_HighTrue; // High True output
pwmSignal.dutyCyclePercent = 50; // 50% duty cycle
pwmSignal.faultState = kPWM_PwmFaultState0;
pwmSignal.pwmchannelenable = true;
PWM_SetupPwm(PWM_BASEADDR, kPWM_Module_3, &pwmSignal, 1, kPWM_SignedCenterAligned, pwmFrequencyInHz, pwmSourceClockInHz);
PWM_EnableDMAWrite(PWM_BASEADDR, kPWM_Module_3, true);
// Start PWM
PWM_SetPwmLdok(PWM_BASEADDR, kPWM_Control_Module_3, true);
PWM_StartTimer(PWM_BASEADDR, kPWM_Control_Module_3);
}
DMA Initialization and Callback Function
void dmaInit(void)
{
edma_config_t dmaConfig;
edma_transfer_config_t transferConfig;
// DMAMUX Initialization
DMAMUX_Init(DMAMUX);
DMAMUX_SetSource(DMAMUX, 0, kDmaRequestMuxFlexPWM1ValueSub3);
DMAMUX_EnableChannel(DMAMUX, 0);
// DMA Initialization
EDMA_GetDefaultConfig(&dmaConfig);
dmaConfig.enableContinuousLinkMode = true;
dmaConfig.enableRoundRobinArbitration = true;
EDMA_Init(DMA0, &dmaConfig);
EDMA_CreateHandle(&g_edmaHandle, DMA0, 0);
EDMA_SetCallback(&g_edmaHandle, DMA_Callback, NULL);
// DMA Transfer Configuration (Transfer data to PWM VALx register)
EDMA_PrepareTransfer(&transferConfig,
pwmDutyBuffer, 2,
(void *)&PWM_BASEADDR->SM[kPWM_Module_3].VAL3, 2,
2, sizeof(pwmDutyBuffer),
kEDMA_MemoryToPeripheral);
EDMA_SetModulo(DMA0, 0, kEDMA_Modulo32bytes, kEDMA_ModuloDisable);
EDMA_SubmitTransfer(&g_edmaHandle, &transferConfig);
EDMA_StartTransfer(&g_edmaHandle);
EDMA_EnableChannelRequest(DMA0, 0);
// Second DMA channel for LDOK setting (optional)
// Additional DMA channel for setting MCTRL[LDOK]
}
void DMA_Callback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
if (transferDone)
{
// Set LDOK bit
PWM_SetPwmLdok(PWM_BASEADDR, kPWM_Control_Module_3, true);
}
}
Could you please review the source code? It is not working as expected.