Browse Source

[bsp][nxp][mcxa153] add pwm driver

hywing 11 months ago
parent
commit
61a2bf6154

+ 129 - 0
bsp/nxp/mcx/mcxa/Libraries/drivers/drv_pwm.c

@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2006-2024, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2024-08-1      hywing       Initial version.
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "fsl_ctimer.h"
+
+#ifdef RT_USING_PWM
+
+typedef struct
+{
+    struct rt_device_pwm pwm_device;
+    CTIMER_Type *ct_instance;
+	uint32_t timerClock;
+	const ctimer_match_t pwmPeriodChannel;
+    ctimer_match_t matchChannel;
+	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,
+        .name = "pwm0",
+    }
+#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);
+    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);
+    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);
+    return 0;
+}
+
+static rt_err_t mcx_drv_pwm_control(struct rt_device_pwm *device, int cmd, void *args)
+{
+    mcx_pwm_obj_t *pwm = device->parent.user_data;
+    struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)args;
+
+    switch (cmd)
+    {
+    case PWM_CMD_ENABLE:
+        return mcx_drv_pwm_enable(pwm, configuration);
+
+    case PWM_CMD_DISABLE:
+        return mcx_drv_pwm_disable(pwm, configuration);
+
+    case PWM_CMD_SET:
+        return mcx_drv_pwm_set(pwm, configuration);
+
+    case PWM_CMD_GET:
+        return mcx_drv_pwm_get(pwm, configuration);
+
+    default:
+        return -RT_EINVAL;
+    }
+
+    return RT_EOK;
+}
+
+static struct rt_pwm_ops mcx_pwm_ops =
+{
+    .control = mcx_drv_pwm_control,
+};
+
+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++)
+    {
+        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)
+        {
+            return ret;
+        }
+    }
+    return RT_EOK;
+}
+
+INIT_DEVICE_EXPORT(mcx_pwm_init);
+
+#endif /* RT_USING_PWM */

+ 19 - 0
bsp/nxp/mcx/mcxa/Libraries/drivers/drv_pwm.h

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2006-2024, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2024-02-26     Yilin Sun    Initial version.
+ */
+
+#ifndef __DRV_PWM_H__
+#define __DRV_PWM_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+int mcx_pwm_init(void);
+
+#endif

+ 4 - 20
bsp/nxp/mcx/mcxa/frdm-mcxa153/board/Kconfig

@@ -125,28 +125,12 @@ menu "On-chip Peripheral Drivers"
         config BSP_USING_PWM
         config BSP_USING_PWM
             bool "Enable PWM"
             bool "Enable PWM"
             select RT_USING_PWM
             select RT_USING_PWM
-            default y
+            default N
 
 
             if BSP_USING_PWM
             if BSP_USING_PWM
-                config BSP_USING_CTIMER1_MAT0
-                    bool "Enable CIMER1 Match0 as PWM output"
-                    default y
-
-                config BSP_USING_CTIMER2_MAT0
-                    bool "Enable CIMER2 Match0 as PWM output"
-                    default n
-
-                config BSP_USING_CTIMER2_MAT1
-                    bool "Enable CIMER2 Match1 as PWM output"
-                    default n
-
-                config BSP_USING_CTIMER2_MAT2
-                    bool "Enable CIMER2 Match2 as PWM output"
-                    default n
-
-                config BSP_USING_CTIMER3_MAT2
-                    bool "Enable CIMER3 Match2 as PWM output"
-                    default n
+                config BSP_USING_PWM0
+                    bool "Enable PWM0"
+                    default N
             endif
             endif
 endmenu
 endmenu
 
 

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

@@ -43,10 +43,15 @@ void BOARD_InitPins(void)
     CLOCK_EnableClock(kCLOCK_GateGPIO1);
     CLOCK_EnableClock(kCLOCK_GateGPIO1);
     CLOCK_EnableClock(kCLOCK_GateGPIO2);
     CLOCK_EnableClock(kCLOCK_GateGPIO2);
     CLOCK_EnableClock(kCLOCK_GateGPIO3);
     CLOCK_EnableClock(kCLOCK_GateGPIO3);
+	
+	CLOCK_SetClockDiv(kCLOCK_DivCTIMER1, 1u);
+    CLOCK_AttachClk(kFRO_HF_to_CTIMER1);
 
 
     RESET_ReleasePeripheralReset(kLPUART0_RST_SHIFT_RSTn);
     RESET_ReleasePeripheralReset(kLPUART0_RST_SHIFT_RSTn);
     RESET_ReleasePeripheralReset(kLPUART1_RST_SHIFT_RSTn);
     RESET_ReleasePeripheralReset(kLPUART1_RST_SHIFT_RSTn);
     RESET_ReleasePeripheralReset(kLPUART2_RST_SHIFT_RSTn);
     RESET_ReleasePeripheralReset(kLPUART2_RST_SHIFT_RSTn);
+	
+	RESET_ReleasePeripheralReset(kCTIMER1_RST_SHIFT_RSTn);
 
 
     RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn);
     RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn);
     RESET_ReleasePeripheralReset(kPORT1_RST_SHIFT_RSTn);
     RESET_ReleasePeripheralReset(kPORT1_RST_SHIFT_RSTn);
@@ -107,4 +112,33 @@ void BOARD_InitPins(void)
                                                     kPORT_UnlockRegister};
                                                     kPORT_UnlockRegister};
     /* PORT0_3 (pin 52) is configured as LPUART0_TXD */
     /* PORT0_3 (pin 52) is configured as LPUART0_TXD */
     PORT_SetPinConfig(PORT0, 3U, &port0_3_pin52_config);
     PORT_SetPinConfig(PORT0, 3U, &port0_3_pin52_config);
+	
+#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 */
+                                                    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 CT1_MAT2 */
+                                                    kPORT_MuxAlt4,
+                                                    /* 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);
+#endif
 }
 }