Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bsp][nxp][mcxa153] the full implementation of eFlexPWM #9788

Merged
merged 3 commits into from
Dec 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 95 additions & 38 deletions bsp/nxp/mcx/mcxa/Libraries/drivers/drv_pwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,72 +5,95 @@
*
* Change Logs:
* Date Author Notes
* 2024-08-1 hywing Initial version.
* 2024-12-18 hywing Initial version.
*/

#include <rtthread.h>
#include <rtdevice.h>
#include "fsl_ctimer.h"
#include "fsl_pwm.h"

#ifdef RT_USING_PWM

#define BOARD_PWM_BASEADDR (FLEXPWM0)
#define PWM_SRC_CLK_FREQ (CLOCK_GetFreq(kCLOCK_BusClk))
#define FLEX_PWM_CLOCK_DEVIDER (kPWM_Prescale_Divide_2)
#define FLEX_PWM_FAULT_LEVEL true

typedef struct
{
struct rt_device_pwm pwm_device;
CTIMER_Type *ct_instance;
uint32_t timerClock;
const ctimer_match_t pwmPeriodChannel;
ctimer_match_t matchChannel;
pwm_submodule_t submodule;
pwm_module_control_t control;
pwm_channels_t channel;
pwm_clock_prescale_t prescale;
char *name;
} mcx_pwm_obj_t;

static mcx_pwm_obj_t mcx_pwm_list[]=
{
#ifdef BSP_USING_PWM0
{
.ct_instance = CTIMER1,
.timerClock = 0,
.pwmPeriodChannel = kCTIMER_Match_3,
.matchChannel = kCTIMER_Match_2,
.submodule = kPWM_Module_0,
.control = kPWM_Control_Module_0,
.channel = kPWM_PwmA,
.prescale = FLEX_PWM_CLOCK_DEVIDER,
.name = "pwm0",
}
},
#endif
#ifdef BSP_USING_PWM1
{
.submodule = kPWM_Module_1,
.control = kPWM_Control_Module_1,
.channel = kPWM_PwmA,
.prescale = FLEX_PWM_CLOCK_DEVIDER,
.name = "pwm1",
},
#endif
#ifdef BSP_USING_PWM2
{
.submodule = kPWM_Module_2,
.control = kPWM_Control_Module_2,
.channel = kPWM_PwmA,
.prescale = FLEX_PWM_CLOCK_DEVIDER,
.name = "pwm2",
},
#endif
};

volatile uint32_t g_pwmPeriod = 0U;
volatile uint32_t g_pulsePeriod = 0U;

static rt_err_t mcx_drv_pwm_get(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration)
{
return RT_EOK;
}

status_t CTIMER_GetPwmPeriodValue(uint32_t pwmFreqHz, uint8_t dutyCyclePercent, uint32_t timerClock_Hz)
{
g_pwmPeriod = (timerClock_Hz / pwmFreqHz) - 1U;
g_pulsePeriod = (g_pwmPeriod + 1U) * (100 - dutyCyclePercent) / 100;
return kStatus_Success;
}

static rt_err_t mcx_drv_pwm_set(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration)
{
CTIMER_Type *ct = pwm->ct_instance;
uint32_t pwmFreqHz = 1000000000 / configuration->period;
uint8_t dutyCyclePercent = configuration->pulse * 100 / configuration->period;
CTIMER_GetPwmPeriodValue(pwmFreqHz, dutyCyclePercent, pwm->timerClock);
CTIMER_SetupPwmPeriod(ct, kCTIMER_Match_3, kCTIMER_Match_2, g_pwmPeriod, g_pulsePeriod, false);
pwm_signal_param_t pwmSignal[1];
uint32_t pwmFrequencyInHz = 1000000000 / configuration->period;

pwmSignal[0].pwmChannel = pwm->channel;
pwmSignal[0].level = kPWM_HighTrue;
pwmSignal[0].dutyCyclePercent = dutyCyclePercent;
pwmSignal[0].deadtimeValue = 0;
pwmSignal[0].faultState = kPWM_PwmFaultState0;
pwmSignal[0].pwmchannelenable = true;

PWM_SetupPwm(BOARD_PWM_BASEADDR, pwm->submodule, pwmSignal, 1, kPWM_SignedCenterAligned, pwmFrequencyInHz, PWM_SRC_CLK_FREQ);
PWM_UpdatePwmDutycycle(BOARD_PWM_BASEADDR, pwm->submodule, pwm->channel, kPWM_SignedCenterAligned, dutyCyclePercent);
PWM_SetPwmLdok(BOARD_PWM_BASEADDR, pwm->control, true);

return 0;
}

static rt_err_t mcx_drv_pwm_enable(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration)
{
CTIMER_StartTimer(pwm->ct_instance);
PWM_StartTimer(BOARD_PWM_BASEADDR, pwm->control);
return 0;
}

static rt_err_t mcx_drv_pwm_disable(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration)
{
CTIMER_StopTimer(pwm->ct_instance);
PWM_StopTimer(BOARD_PWM_BASEADDR, pwm->control);
return 0;
}

Expand Down Expand Up @@ -108,21 +131,55 @@ static struct rt_pwm_ops mcx_pwm_ops =
int mcx_pwm_init(void)
{
rt_err_t ret;
char name_buf[8];

ctimer_config_t config;
CTIMER_GetDefaultConfig(&config);
for (uint8_t i = 0; i < ARRAY_SIZE(mcx_pwm_list); i++)
pwm_config_t pwmConfig;
pwm_fault_param_t faultConfig;
PWM_GetDefaultConfig(&pwmConfig);
pwmConfig.prescale = FLEX_PWM_CLOCK_DEVIDER;
pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle;

int i;
for (i = 0; i < sizeof(mcx_pwm_list) / sizeof(mcx_pwm_list[0]); i++)
{
mcx_pwm_list[i].timerClock = CLOCK_GetCTimerClkFreq(1U) / (config.prescale + 1);
CTIMER_Init(mcx_pwm_list[i].ct_instance, &config);
ret = rt_device_pwm_register(&mcx_pwm_list[i].pwm_device, mcx_pwm_list[i].name, &mcx_pwm_ops, &mcx_pwm_list[i]);
if (ret != RT_EOK)
pwm_config_t pwmConfig;
pwm_fault_param_t faultConfig;
PWM_GetDefaultConfig(&pwmConfig);
pwmConfig.prescale = mcx_pwm_list[i].prescale;
pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle;
if (PWM_Init(BOARD_PWM_BASEADDR, mcx_pwm_list[i].submodule, &pwmConfig) == kStatus_Fail)
{
return ret;
rt_kprintf("PWM Init Failed\n");
}
ret = rt_device_pwm_register(&mcx_pwm_list[i].pwm_device, mcx_pwm_list[i].name, &mcx_pwm_ops, &mcx_pwm_list[i]);
}
return RT_EOK;

/*
* config->faultClearingMode = kPWM_Automatic;
* config->faultLevel = false;
* config->enableCombinationalPath = true;
* config->recoverMode = kPWM_NoRecovery;
*/
PWM_FaultDefaultConfig(&faultConfig);
faultConfig.faultLevel = FLEX_PWM_FAULT_LEVEL;

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


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

return ret;
}

INIT_DEVICE_EXPORT(mcx_pwm_init);
Expand Down
8 changes: 7 additions & 1 deletion bsp/nxp/mcx/mcxa/frdm-mcxa153/board/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,13 @@ menu "On-chip Peripheral Drivers"

if BSP_USING_PWM
config BSP_USING_PWM0
bool "Enable PWM0"
bool "Enable eFlex PWM0"
default N
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

N建议统一改成小写的

config BSP_USING_PWM1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

注意下缩进

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好了,改了

bool "Enable eFlex PWM1"
default N
config BSP_USING_PWM2
bool "Enable eFlex PWM2"
default N
endif
endmenu
Expand Down
65 changes: 58 additions & 7 deletions bsp/nxp/mcx/mcxa/frdm-mcxa153/board/MCUX_Config/board/pin_mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void BOARD_InitPins(void)
RESET_ReleasePeripheralReset(kLPSPI1_RST_SHIFT_RSTn);

RESET_ReleasePeripheralReset(kLPI2C0_RST_SHIFT_RSTn);
RESET_ReleasePeripheralReset(kFLEXPWM0_RST_SHIFT_RSTn);

RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn);
RESET_ReleasePeripheralReset(kPORT1_RST_SHIFT_RSTn);
Expand Down Expand Up @@ -225,9 +226,7 @@ void BOARD_InitPins(void)
#endif

#ifdef BSP_USING_PWM0
ctimer_config_t config;
CTIMER_Init(CTIMER1, &config);
const port_pin_config_t port1_4_pin62_config = {/* Internal pull-up/down resistor is disabled */
const port_pin_config_t port3_0_pin46_config = {/* Internal pull-up/down resistor is disabled */
kPORT_PullDisable,
/* Low internal pull resistor value is selected. */
kPORT_LowPullResistor,
Expand All @@ -241,16 +240,68 @@ void BOARD_InitPins(void)
kPORT_LowDriveStrength,
/* Normal drive strength is configured */
kPORT_NormalDriveStrength,
/* Pin is configured as CT1_MAT2 */
kPORT_MuxAlt4,
/* Pin is configured as PWM0_A0 */
kPORT_MuxAlt5,
/* Digital input enabled */
kPORT_InputBufferEnable,
/* Digital input is not inverted */
kPORT_InputNormal,
/* Pin Control Register fields [15:0] are not locked */
kPORT_UnlockRegister};
/* PORT1_4 (pin 62) is configured as CT1_MAT2 */
PORT_SetPinConfig(PORT1, 4U, &port1_4_pin62_config);
/* PORT3_0 (pin 38) is configured as PWM0_A0 */
PORT_SetPinConfig(PORT3, 0U, &port3_0_pin46_config);
#endif
#ifdef BSP_USING_PWM1
const port_pin_config_t port3_8_pin42_config = {/* Internal pull-up/down resistor is disabled */
kPORT_PullDisable,
/* Low internal pull resistor value is selected. */
kPORT_LowPullResistor,
/* Fast slew rate is configured */
kPORT_FastSlewRate,
/* Passive input filter is disabled */
kPORT_PassiveFilterDisable,
/* Open drain output is disabled */
kPORT_OpenDrainDisable,
/* Low drive strength is configured */
kPORT_LowDriveStrength,
/* Normal drive strength is configured */
kPORT_NormalDriveStrength,
/* Pin is configured as PWM0_A0 */
kPORT_MuxAlt5,
/* Digital input enabled */
kPORT_InputBufferEnable,
/* Digital input is not inverted */
kPORT_InputNormal,
/* Pin Control Register fields [15:0] are not locked */
kPORT_UnlockRegister};
/* PORT3_8 (pin 42) is configured as PWM0_A1 */
PORT_SetPinConfig(PORT3, 8U, &port3_8_pin42_config);
#endif
#ifdef BSP_USING_PWM2
const port_pin_config_t port3_10_pin40_config = {/* Internal pull-up/down resistor is disabled */
kPORT_PullDisable,
/* Low internal pull resistor value is selected. */
kPORT_LowPullResistor,
/* Fast slew rate is configured */
kPORT_FastSlewRate,
/* Passive input filter is disabled */
kPORT_PassiveFilterDisable,
/* Open drain output is disabled */
kPORT_OpenDrainDisable,
/* Low drive strength is configured */
kPORT_LowDriveStrength,
/* Normal drive strength is configured */
kPORT_NormalDriveStrength,
/* Pin is configured as PWM0_A0 */
kPORT_MuxAlt5,
/* Digital input enabled */
kPORT_InputBufferEnable,
/* Digital input is not inverted */
kPORT_InputNormal,
/* Pin Control Register fields [15:0] are not locked */
kPORT_UnlockRegister};
/* PORT3_10 (pin 40) is configured as PWM0_A2 */
PORT_SetPinConfig(PORT3, 10U, &port3_10_pin40_config);
#endif

#ifdef BSP_USING_SPI0
Expand Down
Loading