Skip to content

Commit 8bc0d1e

Browse files
hywingRbb666
authored andcommitted
[bsp][nxp][mcxa153] the full implementation of eFlexPWM
1 parent acaf753 commit 8bc0d1e

File tree

3 files changed

+160
-46
lines changed

3 files changed

+160
-46
lines changed

bsp/nxp/mcx/mcxa/Libraries/drivers/drv_pwm.c

Lines changed: 95 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,72 +5,95 @@
55
*
66
* Change Logs:
77
* Date Author Notes
8-
* 2024-08-1 hywing Initial version.
8+
* 2024-12-18 hywing Initial version.
99
*/
1010

1111
#include <rtthread.h>
1212
#include <rtdevice.h>
13-
#include "fsl_ctimer.h"
13+
#include "fsl_pwm.h"
1414

1515
#ifdef RT_USING_PWM
1616

17+
#define BOARD_PWM_BASEADDR (FLEXPWM0)
18+
#define PWM_SRC_CLK_FREQ (CLOCK_GetFreq(kCLOCK_BusClk))
19+
#define FLEX_PWM_CLOCK_DEVIDER (kPWM_Prescale_Divide_2)
20+
#define FLEX_PWM_FAULT_LEVEL true
21+
1722
typedef struct
1823
{
1924
struct rt_device_pwm pwm_device;
20-
CTIMER_Type *ct_instance;
21-
uint32_t timerClock;
22-
const ctimer_match_t pwmPeriodChannel;
23-
ctimer_match_t matchChannel;
25+
pwm_submodule_t submodule;
26+
pwm_module_control_t control;
27+
pwm_channels_t channel;
28+
pwm_clock_prescale_t prescale;
2429
char *name;
2530
} mcx_pwm_obj_t;
2631

2732
static mcx_pwm_obj_t mcx_pwm_list[]=
2833
{
2934
#ifdef BSP_USING_PWM0
3035
{
31-
.ct_instance = CTIMER1,
32-
.timerClock = 0,
33-
.pwmPeriodChannel = kCTIMER_Match_3,
34-
.matchChannel = kCTIMER_Match_2,
36+
.submodule = kPWM_Module_0,
37+
.control = kPWM_Control_Module_0,
38+
.channel = kPWM_PwmA,
39+
.prescale = FLEX_PWM_CLOCK_DEVIDER,
3540
.name = "pwm0",
36-
}
41+
},
42+
#endif
43+
#ifdef BSP_USING_PWM1
44+
{
45+
.submodule = kPWM_Module_1,
46+
.control = kPWM_Control_Module_1,
47+
.channel = kPWM_PwmA,
48+
.prescale = FLEX_PWM_CLOCK_DEVIDER,
49+
.name = "pwm1",
50+
},
51+
#endif
52+
#ifdef BSP_USING_PWM2
53+
{
54+
.submodule = kPWM_Module_2,
55+
.control = kPWM_Control_Module_2,
56+
.channel = kPWM_PwmA,
57+
.prescale = FLEX_PWM_CLOCK_DEVIDER,
58+
.name = "pwm2",
59+
},
3760
#endif
3861
};
3962

40-
volatile uint32_t g_pwmPeriod = 0U;
41-
volatile uint32_t g_pulsePeriod = 0U;
42-
4363
static rt_err_t mcx_drv_pwm_get(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration)
4464
{
4565
return RT_EOK;
4666
}
4767

48-
status_t CTIMER_GetPwmPeriodValue(uint32_t pwmFreqHz, uint8_t dutyCyclePercent, uint32_t timerClock_Hz)
49-
{
50-
g_pwmPeriod = (timerClock_Hz / pwmFreqHz) - 1U;
51-
g_pulsePeriod = (g_pwmPeriod + 1U) * (100 - dutyCyclePercent) / 100;
52-
return kStatus_Success;
53-
}
54-
5568
static rt_err_t mcx_drv_pwm_set(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration)
5669
{
57-
CTIMER_Type *ct = pwm->ct_instance;
58-
uint32_t pwmFreqHz = 1000000000 / configuration->period;
5970
uint8_t dutyCyclePercent = configuration->pulse * 100 / configuration->period;
60-
CTIMER_GetPwmPeriodValue(pwmFreqHz, dutyCyclePercent, pwm->timerClock);
61-
CTIMER_SetupPwmPeriod(ct, kCTIMER_Match_3, kCTIMER_Match_2, g_pwmPeriod, g_pulsePeriod, false);
71+
pwm_signal_param_t pwmSignal[1];
72+
uint32_t pwmFrequencyInHz = 1000000000 / configuration->period;
73+
74+
pwmSignal[0].pwmChannel = pwm->channel;
75+
pwmSignal[0].level = kPWM_HighTrue;
76+
pwmSignal[0].dutyCyclePercent = dutyCyclePercent;
77+
pwmSignal[0].deadtimeValue = 0;
78+
pwmSignal[0].faultState = kPWM_PwmFaultState0;
79+
pwmSignal[0].pwmchannelenable = true;
80+
81+
PWM_SetupPwm(BOARD_PWM_BASEADDR, pwm->submodule, pwmSignal, 1, kPWM_SignedCenterAligned, pwmFrequencyInHz, PWM_SRC_CLK_FREQ);
82+
PWM_UpdatePwmDutycycle(BOARD_PWM_BASEADDR, pwm->submodule, pwm->channel, kPWM_SignedCenterAligned, dutyCyclePercent);
83+
PWM_SetPwmLdok(BOARD_PWM_BASEADDR, pwm->control, true);
84+
6285
return 0;
6386
}
6487

6588
static rt_err_t mcx_drv_pwm_enable(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration)
6689
{
67-
CTIMER_StartTimer(pwm->ct_instance);
90+
PWM_StartTimer(BOARD_PWM_BASEADDR, pwm->control);
6891
return 0;
6992
}
7093

7194
static rt_err_t mcx_drv_pwm_disable(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration)
7295
{
73-
CTIMER_StopTimer(pwm->ct_instance);
96+
PWM_StopTimer(BOARD_PWM_BASEADDR, pwm->control);
7497
return 0;
7598
}
7699

@@ -108,21 +131,55 @@ static struct rt_pwm_ops mcx_pwm_ops =
108131
int mcx_pwm_init(void)
109132
{
110133
rt_err_t ret;
111-
char name_buf[8];
112-
113-
ctimer_config_t config;
114-
CTIMER_GetDefaultConfig(&config);
115-
for (uint8_t i = 0; i < ARRAY_SIZE(mcx_pwm_list); i++)
134+
pwm_config_t pwmConfig;
135+
pwm_fault_param_t faultConfig;
136+
PWM_GetDefaultConfig(&pwmConfig);
137+
pwmConfig.prescale = FLEX_PWM_CLOCK_DEVIDER;
138+
pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle;
139+
140+
int i;
141+
for (i = 0; i < sizeof(mcx_pwm_list) / sizeof(mcx_pwm_list[0]); i++)
116142
{
117-
mcx_pwm_list[i].timerClock = CLOCK_GetCTimerClkFreq(1U) / (config.prescale + 1);
118-
CTIMER_Init(mcx_pwm_list[i].ct_instance, &config);
119-
ret = rt_device_pwm_register(&mcx_pwm_list[i].pwm_device, mcx_pwm_list[i].name, &mcx_pwm_ops, &mcx_pwm_list[i]);
120-
if (ret != RT_EOK)
143+
pwm_config_t pwmConfig;
144+
pwm_fault_param_t faultConfig;
145+
PWM_GetDefaultConfig(&pwmConfig);
146+
pwmConfig.prescale = mcx_pwm_list[i].prescale;
147+
pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle;
148+
if (PWM_Init(BOARD_PWM_BASEADDR, mcx_pwm_list[i].submodule, &pwmConfig) == kStatus_Fail)
121149
{
122-
return ret;
150+
rt_kprintf("PWM Init Failed\n");
123151
}
152+
ret = rt_device_pwm_register(&mcx_pwm_list[i].pwm_device, mcx_pwm_list[i].name, &mcx_pwm_ops, &mcx_pwm_list[i]);
124153
}
125-
return RT_EOK;
154+
155+
/*
156+
* config->faultClearingMode = kPWM_Automatic;
157+
* config->faultLevel = false;
158+
* config->enableCombinationalPath = true;
159+
* config->recoverMode = kPWM_NoRecovery;
160+
*/
161+
PWM_FaultDefaultConfig(&faultConfig);
162+
faultConfig.faultLevel = FLEX_PWM_FAULT_LEVEL;
163+
164+
/* Sets up the PWM fault protection */
165+
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_0, &faultConfig);
166+
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_1, &faultConfig);
167+
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_2, &faultConfig);
168+
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_3, &faultConfig);
169+
170+
/* Set PWM fault disable mapping for submodule 0/1/2 */
171+
PWM_SetupFaultDisableMap(BOARD_PWM_BASEADDR, kPWM_Module_0, kPWM_PwmA, kPWM_faultchannel_0,
172+
kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3);
173+
PWM_SetupFaultDisableMap(BOARD_PWM_BASEADDR, kPWM_Module_1, kPWM_PwmA, kPWM_faultchannel_0,
174+
kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3);
175+
PWM_SetupFaultDisableMap(BOARD_PWM_BASEADDR, kPWM_Module_2, kPWM_PwmA, kPWM_faultchannel_0,
176+
kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3);
177+
178+
179+
/* Set the load okay bit for all submodules to load registers from their buffer */
180+
PWM_SetPwmLdok(BOARD_PWM_BASEADDR, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2, true);
181+
182+
return ret;
126183
}
127184

128185
INIT_DEVICE_EXPORT(mcx_pwm_init);

bsp/nxp/mcx/mcxa/frdm-mcxa153/board/Kconfig

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,13 @@ menu "On-chip Peripheral Drivers"
129129

130130
if BSP_USING_PWM
131131
config BSP_USING_PWM0
132-
bool "Enable PWM0"
132+
bool "Enable eFlex PWM0"
133+
default N
134+
config BSP_USING_PWM1
135+
bool "Enable eFlex PWM1"
136+
default N
137+
config BSP_USING_PWM2
138+
bool "Enable eFlex PWM2"
133139
default N
134140
endif
135141
endmenu

bsp/nxp/mcx/mcxa/frdm-mcxa153/board/MCUX_Config/board/pin_mux.c

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ void BOARD_InitPins(void)
6060
RESET_ReleasePeripheralReset(kLPSPI1_RST_SHIFT_RSTn);
6161

6262
RESET_ReleasePeripheralReset(kLPI2C0_RST_SHIFT_RSTn);
63+
RESET_ReleasePeripheralReset(kFLEXPWM0_RST_SHIFT_RSTn);
6364

6465
RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn);
6566
RESET_ReleasePeripheralReset(kPORT1_RST_SHIFT_RSTn);
@@ -225,9 +226,7 @@ void BOARD_InitPins(void)
225226
#endif
226227

227228
#ifdef BSP_USING_PWM0
228-
ctimer_config_t config;
229-
CTIMER_Init(CTIMER1, &config);
230-
const port_pin_config_t port1_4_pin62_config = {/* Internal pull-up/down resistor is disabled */
229+
const port_pin_config_t port3_0_pin46_config = {/* Internal pull-up/down resistor is disabled */
231230
kPORT_PullDisable,
232231
/* Low internal pull resistor value is selected. */
233232
kPORT_LowPullResistor,
@@ -241,16 +240,68 @@ void BOARD_InitPins(void)
241240
kPORT_LowDriveStrength,
242241
/* Normal drive strength is configured */
243242
kPORT_NormalDriveStrength,
244-
/* Pin is configured as CT1_MAT2 */
245-
kPORT_MuxAlt4,
243+
/* Pin is configured as PWM0_A0 */
244+
kPORT_MuxAlt5,
246245
/* Digital input enabled */
247246
kPORT_InputBufferEnable,
248247
/* Digital input is not inverted */
249248
kPORT_InputNormal,
250249
/* Pin Control Register fields [15:0] are not locked */
251250
kPORT_UnlockRegister};
252-
/* PORT1_4 (pin 62) is configured as CT1_MAT2 */
253-
PORT_SetPinConfig(PORT1, 4U, &port1_4_pin62_config);
251+
/* PORT3_0 (pin 38) is configured as PWM0_A0 */
252+
PORT_SetPinConfig(PORT3, 0U, &port3_0_pin46_config);
253+
#endif
254+
#ifdef BSP_USING_PWM1
255+
const port_pin_config_t port3_8_pin42_config = {/* Internal pull-up/down resistor is disabled */
256+
kPORT_PullDisable,
257+
/* Low internal pull resistor value is selected. */
258+
kPORT_LowPullResistor,
259+
/* Fast slew rate is configured */
260+
kPORT_FastSlewRate,
261+
/* Passive input filter is disabled */
262+
kPORT_PassiveFilterDisable,
263+
/* Open drain output is disabled */
264+
kPORT_OpenDrainDisable,
265+
/* Low drive strength is configured */
266+
kPORT_LowDriveStrength,
267+
/* Normal drive strength is configured */
268+
kPORT_NormalDriveStrength,
269+
/* Pin is configured as PWM0_A0 */
270+
kPORT_MuxAlt5,
271+
/* Digital input enabled */
272+
kPORT_InputBufferEnable,
273+
/* Digital input is not inverted */
274+
kPORT_InputNormal,
275+
/* Pin Control Register fields [15:0] are not locked */
276+
kPORT_UnlockRegister};
277+
/* PORT3_8 (pin 42) is configured as PWM0_A1 */
278+
PORT_SetPinConfig(PORT3, 8U, &port3_8_pin42_config);
279+
#endif
280+
#ifdef BSP_USING_PWM2
281+
const port_pin_config_t port3_10_pin40_config = {/* Internal pull-up/down resistor is disabled */
282+
kPORT_PullDisable,
283+
/* Low internal pull resistor value is selected. */
284+
kPORT_LowPullResistor,
285+
/* Fast slew rate is configured */
286+
kPORT_FastSlewRate,
287+
/* Passive input filter is disabled */
288+
kPORT_PassiveFilterDisable,
289+
/* Open drain output is disabled */
290+
kPORT_OpenDrainDisable,
291+
/* Low drive strength is configured */
292+
kPORT_LowDriveStrength,
293+
/* Normal drive strength is configured */
294+
kPORT_NormalDriveStrength,
295+
/* Pin is configured as PWM0_A0 */
296+
kPORT_MuxAlt5,
297+
/* Digital input enabled */
298+
kPORT_InputBufferEnable,
299+
/* Digital input is not inverted */
300+
kPORT_InputNormal,
301+
/* Pin Control Register fields [15:0] are not locked */
302+
kPORT_UnlockRegister};
303+
/* PORT3_10 (pin 40) is configured as PWM0_A2 */
304+
PORT_SetPinConfig(PORT3, 10U, &port3_10_pin40_config);
254305
#endif
255306

256307
#ifdef BSP_USING_SPI0

0 commit comments

Comments
 (0)