220 lines
8.7 KiB
C
220 lines
8.7 KiB
C
/*
|
|
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
|
* Copyright 2016-2022 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "fsl_debug_console.h"
|
|
#include "pin_mux.h"
|
|
#include "board.h"
|
|
#include "fsl_pwm.h"
|
|
|
|
#include "fsl_xbara.h"
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
/* The PWM base address */
|
|
#define BOARD_PWM_BASEADDR PWM1
|
|
|
|
#define PWM_SRC_CLK_FREQ CLOCK_GetFreq(kCLOCK_IpgClk)
|
|
/* Definition for default PWM frequence in hz. */
|
|
#ifndef APP_DEFAULT_PWM_FREQUENCE
|
|
#define APP_DEFAULT_PWM_FREQUENCE (1000UL)
|
|
#endif
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
static void PWM_DRV_Init3PhPwm(void)
|
|
{
|
|
uint16_t deadTimeVal;
|
|
pwm_signal_param_t pwmSignal[2];
|
|
uint32_t pwmSourceClockInHz;
|
|
uint32_t pwmFrequencyInHz = APP_DEFAULT_PWM_FREQUENCE;
|
|
|
|
pwmSourceClockInHz = PWM_SRC_CLK_FREQ;
|
|
|
|
/* Set deadtime count, we set this to about 650ns */
|
|
deadTimeVal = ((uint64_t)pwmSourceClockInHz * 650) / 1000000000;
|
|
|
|
pwmSignal[0].pwmChannel = kPWM_PwmA;
|
|
pwmSignal[0].level = kPWM_HighTrue;
|
|
pwmSignal[0].dutyCyclePercent = 50; /* 1 percent dutycycle */
|
|
pwmSignal[0].deadtimeValue = deadTimeVal;
|
|
pwmSignal[0].faultState = kPWM_PwmFaultState0;
|
|
pwmSignal[0].pwmchannelenable = true;
|
|
|
|
pwmSignal[1].pwmChannel = kPWM_PwmB;
|
|
pwmSignal[1].level = kPWM_HighTrue;
|
|
/* Dutycycle field of PWM B does not matter as we are running in PWM A complementary mode */
|
|
pwmSignal[1].dutyCyclePercent = 50;
|
|
pwmSignal[1].deadtimeValue = deadTimeVal;
|
|
pwmSignal[1].faultState = kPWM_PwmFaultState0;
|
|
pwmSignal[1].pwmchannelenable = true;
|
|
|
|
/*********** PWMA_SM0 - phase A, configuration, setup 2 channel as an example ************/
|
|
PWM_SetupPwm(BOARD_PWM_BASEADDR, kPWM_Module_0, pwmSignal, 2, kPWM_SignedCenterAligned, pwmFrequencyInHz,
|
|
pwmSourceClockInHz);
|
|
|
|
/*********** PWMA_SM1 - phase B configuration, setup PWM A channel only ************/
|
|
#ifdef DEMO_PWM_CLOCK_DEVIDER
|
|
PWM_SetupPwm(BOARD_PWM_BASEADDR, kPWM_Module_1, pwmSignal, 1, kPWM_SignedCenterAligned, pwmFrequencyInHz,
|
|
pwmSourceClockInHz / (1 << DEMO_PWM_CLOCK_DEVIDER));
|
|
#else
|
|
PWM_SetupPwm(BOARD_PWM_BASEADDR, kPWM_Module_1, pwmSignal, 1, kPWM_SignedCenterAligned, pwmFrequencyInHz,
|
|
pwmSourceClockInHz);
|
|
#endif
|
|
|
|
/*********** PWMA_SM2 - phase C configuration, setup PWM A channel only ************/
|
|
#ifdef DEMO_PWM_CLOCK_DEVIDER
|
|
PWM_SetupPwm(BOARD_PWM_BASEADDR, kPWM_Module_2, pwmSignal, 1, kPWM_SignedCenterAligned, pwmFrequencyInHz,
|
|
pwmSourceClockInHz / (1 << DEMO_PWM_CLOCK_DEVIDER));
|
|
#else
|
|
PWM_SetupPwm(BOARD_PWM_BASEADDR, kPWM_Module_2, pwmSignal, 1, kPWM_SignedCenterAligned, pwmFrequencyInHz,
|
|
pwmSourceClockInHz);
|
|
#endif
|
|
}
|
|
|
|
/*!
|
|
* @brief Main function
|
|
*/
|
|
int main(void)
|
|
{
|
|
/* Structure of initialize PWM */
|
|
pwm_config_t pwmConfig;
|
|
pwm_fault_param_t faultConfig;
|
|
uint32_t pwmVal = 4;
|
|
|
|
/* Board pin, clock, debug console init */
|
|
BOARD_ConfigMPU();
|
|
BOARD_InitBootPins();
|
|
BOARD_InitBootClocks();
|
|
BOARD_InitDebugConsole();
|
|
|
|
CLOCK_SetDiv(kCLOCK_AhbDiv, 0x2); /* Set AHB PODF to 2, divide by 3 */
|
|
CLOCK_SetDiv(kCLOCK_IpgDiv, 0x3); /* Set IPG PODF to 3, divede by 4 */
|
|
|
|
/* Set the PWM Fault inputs to a low value */
|
|
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);
|
|
|
|
PRINTF("FlexPWM driver example\n");
|
|
|
|
/*
|
|
* 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_GetDefaultConfig(&pwmConfig);
|
|
|
|
#ifdef DEMO_PWM_CLOCK_DEVIDER
|
|
pwmConfig.prescale = DEMO_PWM_CLOCK_DEVIDER;
|
|
#endif
|
|
|
|
/* Use full cycle reload */
|
|
pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle;
|
|
/* PWM A & PWM B form a complementary PWM pair */
|
|
pwmConfig.pairOperation = kPWM_ComplementaryPwmA;
|
|
pwmConfig.enableDebugMode = true;
|
|
|
|
/* Initialize submodule 0 */
|
|
if (PWM_Init(BOARD_PWM_BASEADDR, kPWM_Module_0, &pwmConfig) == kStatus_Fail)
|
|
{
|
|
PRINTF("PWM initialization failed\n");
|
|
return 1;
|
|
}
|
|
|
|
/* Initialize submodule 1, make it use same counter clock as submodule 0. */
|
|
pwmConfig.clockSource = kPWM_Submodule0Clock;
|
|
pwmConfig.prescale = kPWM_Prescale_Divide_1;
|
|
pwmConfig.initializationControl = kPWM_Initialize_MasterSync;
|
|
if (PWM_Init(BOARD_PWM_BASEADDR, kPWM_Module_1, &pwmConfig) == kStatus_Fail)
|
|
{
|
|
PRINTF("PWM initialization failed\n");
|
|
return 1;
|
|
}
|
|
|
|
/* Initialize submodule 2 the same way as submodule 1 */
|
|
if (PWM_Init(BOARD_PWM_BASEADDR, kPWM_Module_2, &pwmConfig) == kStatus_Fail)
|
|
{
|
|
PRINTF("PWM initialization failed\n");
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* config->faultClearingMode = kPWM_Automatic;
|
|
* config->faultLevel = false;
|
|
* config->enableCombinationalPath = true;
|
|
* config->recoverMode = kPWM_NoRecovery;
|
|
*/
|
|
PWM_FaultDefaultConfig(&faultConfig);
|
|
|
|
#ifdef DEMO_PWM_FAULT_LEVEL
|
|
faultConfig.faultLevel = DEMO_PWM_FAULT_LEVEL;
|
|
#endif
|
|
|
|
/* Sets up the PWM fault protection */
|
|
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_0, &faultConfig);
|
|
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_1, &faultConfig);
|
|
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_2, &faultConfig);
|
|
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_3, &faultConfig);
|
|
|
|
/* Set PWM fault disable mapping for submodule 0/1/2 */
|
|
PWM_SetupFaultDisableMap(BOARD_PWM_BASEADDR, kPWM_Module_0, kPWM_PwmA, kPWM_faultchannel_0,
|
|
kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3);
|
|
PWM_SetupFaultDisableMap(BOARD_PWM_BASEADDR, kPWM_Module_1, kPWM_PwmA, kPWM_faultchannel_0,
|
|
kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3);
|
|
PWM_SetupFaultDisableMap(BOARD_PWM_BASEADDR, kPWM_Module_2, kPWM_PwmA, kPWM_faultchannel_0,
|
|
kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3);
|
|
|
|
/* Call the init function with demo configuration */
|
|
PWM_DRV_Init3PhPwm();
|
|
|
|
/* Set the load okay bit for all submodules to load registers from their buffer */
|
|
PWM_SetPwmLdok(BOARD_PWM_BASEADDR, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2, true);
|
|
|
|
/* Start the PWM generation from Submodules 0, 1 and 2 */
|
|
PWM_StartTimer(BOARD_PWM_BASEADDR, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2);
|
|
|
|
while (1U)
|
|
{
|
|
/* Delay at least 100 PWM periods. */
|
|
SDK_DelayAtLeastUs((1000000U / APP_DEFAULT_PWM_FREQUENCE) * 100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
|
|
|
|
pwmVal = pwmVal + 4;
|
|
|
|
/* Reset the duty cycle percentage */
|
|
if (pwmVal > 100)
|
|
{
|
|
pwmVal = 4;
|
|
}
|
|
|
|
/* Update duty cycles for all 3 PWM signals */
|
|
PWM_UpdatePwmDutycycle(BOARD_PWM_BASEADDR, kPWM_Module_0, kPWM_PwmA, kPWM_SignedCenterAligned, pwmVal);
|
|
PWM_UpdatePwmDutycycle(BOARD_PWM_BASEADDR, kPWM_Module_1, kPWM_PwmA, kPWM_SignedCenterAligned, (pwmVal >> 1));
|
|
PWM_UpdatePwmDutycycle(BOARD_PWM_BASEADDR, kPWM_Module_2, kPWM_PwmA, kPWM_SignedCenterAligned, (pwmVal >> 2));
|
|
|
|
/* Set the load okay bit for all submodules to load registers from their buffer */
|
|
PWM_SetPwmLdok(BOARD_PWM_BASEADDR, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2, true);
|
|
}
|
|
}
|