浏览代码

[bsp][lpc55sxx] update pwm driver

螺丝松掉的人 2 年之前
父节点
当前提交
3a08336cb5

+ 200 - 46
bsp/lpc55sxx/Libraries/drivers/drv_pwm.c

@@ -7,12 +7,18 @@
  * Date           Author       Notes
  * Date           Author       Notes
  * 2019-04-28     tyustli      first version
  * 2019-04-28     tyustli      first version
  * 2019-07-15     Magicoe      The first version for LPC55S6x, we can also use SCT as PWM
  * 2019-07-15     Magicoe      The first version for LPC55S6x, we can also use SCT as PWM
- *
+ * 2023-02-28     Z8MAN8       Update docking to the RT-Thread device frame
  */
  */
 
 
 #include <rtthread.h>
 #include <rtthread.h>
 
 
 #ifdef RT_USING_PWM
 #ifdef RT_USING_PWM
+#if !defined(BSP_USING_CTIMER1_MAT0) && !defined(BSP_USING_CTIMER1_MAT1) && \
+    !defined(BSP_USING_CTIMER1_MAT2)
+#error "Please define at least one BSP_USING_CTIMERx_MATx"
+#else
+    #define BSP_USING_CTIMER1
+#endif
 #if !defined(BSP_USING_CTIMER2_MAT0) && !defined(BSP_USING_CTIMER2_MAT1) && \
 #if !defined(BSP_USING_CTIMER2_MAT0) && !defined(BSP_USING_CTIMER2_MAT1) && \
     !defined(BSP_USING_CTIMER2_MAT2)
     !defined(BSP_USING_CTIMER2_MAT2)
 #error "Please define at least one BSP_USING_CTIMERx_MATx"
 #error "Please define at least one BSP_USING_CTIMERx_MATx"
@@ -30,6 +36,67 @@
 #define DEFAULT_DUTY                  50
 #define DEFAULT_DUTY                  50
 #define DEFAULT_FREQ                  1000
 #define DEFAULT_FREQ                  1000
 
 
+enum
+{
+#ifdef BSP_USING_CTIMER1
+    PWM1_INDEX,
+#endif
+#ifdef BSP_USING_CTIMER2
+    PWM2_INDEX,
+#endif
+};
+
+struct lpc_pwm
+{
+    struct rt_device_pwm pwm_device;
+    CTIMER_Type *    tim;
+    uint32_t channel;
+    char *name;
+};
+
+static struct lpc_pwm lpc_pwm_obj[] =
+{
+#if defined(BSP_USING_CTIMER1_MAT0) || defined(BSP_USING_CTIMER1_MAT1) || \
+        defined(BSP_USING_CTIMER1_MAT2)
+    {
+       .tim                     = CTIMER1,
+       .name                    = "pwm1",
+       .channel                 = RT_NULL
+    },
+#endif
+
+#if defined(BSP_USING_CTIMER2_MAT0) || defined(BSP_USING_CTIMER2_MAT1) || \
+        defined(BSP_USING_CTIMER2_MAT2)
+    {
+       .tim                     = CTIMER2,
+       .name                    = "pwm2",
+       .channel                 = RT_NULL
+    },
+#endif
+};
+
+static void pwm_get_channel(void)
+{
+#ifdef BSP_USING_CTIMER1_MAT0
+    lpc_pwm_obj[PWM1_INDEX].channel |= 1 << 0;
+#endif
+#ifdef BSP_USING_CTIMER1_MAT1
+    lpc_pwm_obj[PWM1_INDEX].channel |= 1 << 1;
+#endif
+#ifdef BSP_USING_CTIMER1_MAT2
+    lpc_pwm_obj[PWM1_INDEX].channel |= 1 << 2;
+#endif
+#ifdef BSP_USING_CTIMER2_MAT0
+    lpc_pwm_obj[PWM2_INDEX].channel |= 1 << 0;
+#endif
+#ifdef BSP_USING_CTIMER2_MAT1
+    lpc_pwm_obj[PWM2_INDEX].channel |= 1 << 1;
+#endif
+#ifdef BSP_USING_CTIMER2_MAT2
+    lpc_pwm_obj[PWM2_INDEX].channel |= 1 << 2;
+#endif
+}
+
 static rt_err_t lpc_drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
 static rt_err_t lpc_drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
 
 
 static struct rt_pwm_ops lpc_drv_ops =
 static struct rt_pwm_ops lpc_drv_ops =
@@ -66,18 +133,32 @@ static rt_err_t lpc_drv_pwm_get(struct rt_device_pwm *device, struct rt_pwm_conf
 
 
     base = (CTIMER_Type *)device->parent.user_data;
     base = (CTIMER_Type *)device->parent.user_data;
 
 
-#ifdef BSP_USING_CTIMER2
     /* get frequence */
     /* get frequence */
-    pwmClock = CLOCK_GetCTimerClkFreq(2U) ;
-#endif
-
+    if (base == CTIMER1)
+    {
+        pwmClock = CLOCK_GetCTimerClkFreq(1U) ;
+    }
+    else if(base == CTIMER2)
+    {
+        pwmClock = CLOCK_GetCTimerClkFreq(2U) ;
+    }
     get_frequence = pwmClock / (base->MR[kCTIMER_Match_3] + 1);
     get_frequence = pwmClock / (base->MR[kCTIMER_Match_3] + 1);
 
 
-    if(configuration->channel == 1)
+    if(configuration->channel == 0)
+    {
+        /* get dutycycle */
+        get_duty = (100*(base->MR[kCTIMER_Match_3] + 1 - base->MR[kCTIMER_Match_0]))/(base->MR[kCTIMER_Match_3] + 1);
+    }
+    else if(configuration->channel == 1)
     {
     {
         /* get dutycycle */
         /* get dutycycle */
         get_duty = (100*(base->MR[kCTIMER_Match_3] + 1 - base->MR[kCTIMER_Match_1]))/(base->MR[kCTIMER_Match_3] + 1);
         get_duty = (100*(base->MR[kCTIMER_Match_3] + 1 - base->MR[kCTIMER_Match_1]))/(base->MR[kCTIMER_Match_3] + 1);
     }
     }
+    else if(configuration->channel == 2)
+    {
+        /* get dutycycle */
+        get_duty = (100*(base->MR[kCTIMER_Match_3] + 1 - base->MR[kCTIMER_Match_2]))/(base->MR[kCTIMER_Match_3] + 1);
+    }
 
 
     /* get dutycycle */
     /* get dutycycle */
     /* conversion */
     /* conversion */
@@ -106,23 +187,38 @@ static rt_err_t lpc_drv_pwm_set(struct rt_device_pwm *device, struct rt_pwm_conf
     /* Timer counter is incremented on every APB bus clock */
     /* Timer counter is incremented on every APB bus clock */
     config.prescale = 0;
     config.prescale = 0;
 
 
-    if(configuration->channel == 1)
+    /* Get the PWM period match value and pulse width match value of DEFAULT_FREQ PWM signal with DEFAULT_DUTY dutycycle */
+    /* Calculate PWM period match value */
+    double tmp = configuration->period;
+    /* Target frequence. */
+    tmp = 1000000000/tmp;
+    if (base == CTIMER1)
+    {
+        pwmPeriod = (( CLOCK_GetCTimerClkFreq(1U) / (config.prescale + 1) ) / (uint32_t)tmp) - 1;
+    }
+    else if (base == CTIMER2)
     {
     {
-        /* Get the PWM period match value and pulse width match value of DEFAULT_FREQ PWM signal with DEFAULT_DUTY dutycycle */
-        /* Calculate PWM period match value */
-        double tmp = configuration->period;
-        /* Target frequence. */
-        tmp = 1000000000/tmp;
         pwmPeriod = (( CLOCK_GetCTimerClkFreq(2U) / (config.prescale + 1) ) / (uint32_t)tmp) - 1;
         pwmPeriod = (( CLOCK_GetCTimerClkFreq(2U) / (config.prescale + 1) ) / (uint32_t)tmp) - 1;
+    }
 
 
-        /* Calculate pulse width match value */
-        tmp = configuration->pulse;
-        pulsePeriod = (1.0 - tmp / configuration->period) * pwmPeriod;
-        /* Match on channel 3 will define the PWM period */
-        base->MR[kCTIMER_Match_3] = pwmPeriod;
-        /* This will define the PWM pulse period */
-        base->MR[kCTIMER_Match_1] = pulsePeriod;
+    /* Calculate pulse width match value */
+    tmp = configuration->pulse;
+    pulsePeriod = (1.0 - tmp / configuration->period) * pwmPeriod;
+    /* Match on channel 3 will define the PWM period */
+    base->MR[kCTIMER_Match_3] = pwmPeriod;
 
 
+    /* This will define the PWM pulse period */
+    if(configuration->channel == 0)
+    {
+        base->MR[kCTIMER_Match_0] = pulsePeriod;
+    }
+    else if(configuration->channel == 1)
+    {
+        base->MR[kCTIMER_Match_1] = pulsePeriod;
+    }
+    else if(configuration->channel == 2)
+    {
+        base->MR[kCTIMER_Match_2] = pulsePeriod;
     }
     }
 
 
     return RT_EOK;
     return RT_EOK;
@@ -147,32 +243,54 @@ static rt_err_t lpc_drv_pwm_control(struct rt_device_pwm *device, int cmd, void
     }
     }
 }
 }
 
 
-int rt_hw_pwm_init(void)
+static rt_err_t rt_hw_pwm_init(struct lpc_pwm *device)
 {
 {
     rt_err_t ret = RT_EOK;
     rt_err_t ret = RT_EOK;
+    CTIMER_Type *tim = RT_NULL;
+    uint32_t channel = RT_NULL;
 
 
-#ifdef BSP_USING_CTIMER2
-
-    static struct rt_device_pwm pwm2_device;
+    static struct rt_device_pwm pwm_device;
     ctimer_config_t config;
     ctimer_config_t config;
     uint32_t pwmPeriod, pulsePeriod;
     uint32_t pwmPeriod, pulsePeriod;
 
 
-    /* Use 12 MHz clock for some of the Ctimers */
-    CLOCK_AttachClk(kMAIN_CLK_to_CTIMER2);
 
 
-    /* Run as a timer */
-    config.mode = kCTIMER_TimerMode;
-    /* This field is ignored when mode is timer */
-    config.input = kCTIMER_Capture_0;
-    /* Timer counter is incremented on every APB bus clock */
-    config.prescale = 0;
+    tim = device->tim;
+    channel = device->channel;
 
 
-    CTIMER_Init(CTIMER2, &config);
+    if(tim == CTIMER1)
+    {
+        /* Use 12 MHz clock for some of the Ctimers */
+        CLOCK_AttachClk(kMAIN_CLK_to_CTIMER1);
 
 
-#ifdef BSP_USING_CTIMER2_MAT1
-    /* Get the PWM period match value and pulse width match value of DEFAULT_FREQ PWM signal with DEFAULT_DUTY dutycycle */
-    /* Calculate PWM period match value */
-    pwmPeriod = (( CLOCK_GetCTimerClkFreq(2U) / (config.prescale + 1) ) / DEFAULT_FREQ) - 1;
+        /* Run as a timer */
+        config.mode = kCTIMER_TimerMode;
+        /* This field is ignored when mode is timer */
+        config.input = kCTIMER_Capture_0;
+        /* Timer counter is incremented on every APB bus clock */
+        config.prescale = 0;
+
+        CTIMER_Init(CTIMER1, &config);
+        /* Get the PWM period match value and pulse width match value of DEFAULT_FREQ PWM signal with DEFAULT_DUTY dutycycle */
+        /* Calculate PWM period match value */
+        pwmPeriod = (( CLOCK_GetCTimerClkFreq(1U) / (config.prescale + 1) ) / DEFAULT_FREQ) - 1;
+    }
+    else if (tim == CTIMER2)
+    {
+        /* Use 12 MHz clock for some of the Ctimers */
+        CLOCK_AttachClk(kMAIN_CLK_to_CTIMER2);
+
+        /* Run as a timer */
+        config.mode = kCTIMER_TimerMode;
+        /* This field is ignored when mode is timer */
+        config.input = kCTIMER_Capture_0;
+        /* Timer counter is incremented on every APB bus clock */
+        config.prescale = 0;
+
+        CTIMER_Init(CTIMER2, &config);
+        /* Get the PWM period match value and pulse width match value of DEFAULT_FREQ PWM signal with DEFAULT_DUTY dutycycle */
+        /* Calculate PWM period match value */
+        pwmPeriod = (( CLOCK_GetCTimerClkFreq(2U) / (config.prescale + 1) ) / DEFAULT_FREQ) - 1;
+    }
 
 
     /* Calculate pulse width match value */
     /* Calculate pulse width match value */
     if (DEFAULT_DUTY == 0)
     if (DEFAULT_DUTY == 0)
@@ -183,21 +301,57 @@ int rt_hw_pwm_init(void)
     {
     {
         pulsePeriod = ((pwmPeriod + 1) * (100 - DEFAULT_DUTY)) / 100;
         pulsePeriod = ((pwmPeriod + 1) * (100 - DEFAULT_DUTY)) / 100;
     }
     }
-    CTIMER_SetupPwmPeriod(CTIMER2, kCTIMER_Match_3 , kCTIMER_Match_1, pwmPeriod, pulsePeriod, false);
-#endif
-
-    ret = rt_device_pwm_register(&pwm2_device, "pwm2", &lpc_drv_ops, CTIMER2);
 
 
-    if (ret != RT_EOK)
+    if (channel & 0x01)
     {
     {
-        LOG_E("%s register failed", "pwm2");
+        CTIMER_SetupPwmPeriod(tim, kCTIMER_Match_3 , kCTIMER_Match_0, pwmPeriod, pulsePeriod, false);
+        }
+    if (channel & 0x02)
+    {
+        CTIMER_SetupPwmPeriod(tim, kCTIMER_Match_3 , kCTIMER_Match_1, pwmPeriod, pulsePeriod, false);
+    }
+    if (channel & 0x04)
+    {
+        CTIMER_SetupPwmPeriod(tim, kCTIMER_Match_3 , kCTIMER_Match_2, pwmPeriod, pulsePeriod, false);
     }
     }
-
-#endif /* BSP_USING_CTIMER2 */
-
     return ret;
     return ret;
 }
 }
 
 
-INIT_DEVICE_EXPORT(rt_hw_pwm_init);
+static int lpc_pwm_init(void)
+{
+    int i = 0;
+    int result = RT_EOK;
 
 
+    pwm_get_channel();
+
+    for (i = 0; i < sizeof(lpc_pwm_obj) / sizeof(lpc_pwm_obj[0]); i++)
+    {
+        /* pwm init */
+        if (rt_hw_pwm_init(&lpc_pwm_obj[i]) != RT_EOK)
+        {
+            LOG_E("%s init failed", lpc_pwm_obj[i].name);
+            result = -RT_ERROR;
+            goto __exit;
+        }
+        else
+        {
+            LOG_D("%s init success", lpc_pwm_obj[i].name);
+
+            /* register pwm device */
+            if (rt_device_pwm_register(&lpc_pwm_obj[i].pwm_device, lpc_pwm_obj[i].name, &lpc_drv_ops, lpc_pwm_obj[i].tim) == RT_EOK)
+            {
+                LOG_D("%s register success", lpc_pwm_obj[i].name);
+            }
+            else
+            {
+                LOG_E("%s register failed", lpc_pwm_obj[i].name);
+                result = -RT_ERROR;
+            }
+        }
+    }
+
+__exit:
+    return result;
+}
+INIT_DEVICE_EXPORT(lpc_pwm_init);
 #endif /* RT_USING_PWM */
 #endif /* RT_USING_PWM */

+ 0 - 2
bsp/lpc55sxx/Libraries/drivers/drv_pwm.h

@@ -14,6 +14,4 @@
 
 
 #include <rtdevice.h>
 #include <rtdevice.h>
 
 
-int rt_hw_pwm_init(void);
-
 #endif
 #endif

+ 2 - 2
bsp/lpc55sxx/lpc55s69_nxp_evk/applications/arduino_pinout/pins_arduino.c

@@ -29,8 +29,8 @@ const pin_map_t pin_map_table[]=
     {D3, GET_PINS(1,6)},
     {D3, GET_PINS(1,6)},
     {D4, GET_PINS(1,7), "pwm2", 2},     /* PWM */
     {D4, GET_PINS(1,7), "pwm2", 2},     /* PWM */
     {D5, GET_PINS(1,4), "pwm2", 1},     /* PWM */
     {D5, GET_PINS(1,4), "pwm2", 1},     /* PWM */
-    {D6, GET_PINS(1,10)},
-    {D7, GET_PINS(1,9), "pwm1", 0},     /* PWM */
+    {D6, GET_PINS(1,10), "pwm1", 0},    /* PWM */
+    {D7, GET_PINS(1,9)},
     {D8, GET_PINS(1,8)},
     {D8, GET_PINS(1,8)},
     {D9, GET_PINS(1,5)},
     {D9, GET_PINS(1,5)},
     {D10, GET_PINS(1,1)},
     {D10, GET_PINS(1,1)},

+ 1 - 11
bsp/lpc55sxx/lpc55s69_nxp_evk/board/Kconfig

@@ -212,21 +212,13 @@ menu "On-chip Peripheral Drivers"
             default y
             default y
 
 
             if BSP_USING_PWM
             if BSP_USING_PWM
-                config BSP_USING_CTIMER0_MAT3
-                    bool "Enable CIMER0 Match3 as PWM output"
-                    default y
-
                 config BSP_USING_CTIMER1_MAT0
                 config BSP_USING_CTIMER1_MAT0
                     bool "Enable CIMER1 Match0 as PWM output"
                     bool "Enable CIMER1 Match0 as PWM output"
                     default y
                     default y
 
 
-                config BSP_USING_CTIMER1_MAT3
-                    bool "Enable CIMER1 Match3 as PWM output"
-                    default n
-
                 config BSP_USING_CTIMER2_MAT0
                 config BSP_USING_CTIMER2_MAT0
                     bool "Enable CIMER2 Match0 as PWM output"
                     bool "Enable CIMER2 Match0 as PWM output"
-                    default y
+                    default n
 
 
                 config BSP_USING_CTIMER2_MAT1
                 config BSP_USING_CTIMER2_MAT1
                     bool "Enable CIMER2 Match1 as PWM output"
                     bool "Enable CIMER2 Match1 as PWM output"
@@ -272,11 +264,9 @@ menu "Onboard Peripheral Drivers"
         select BSP_USING_ADC0
         select BSP_USING_ADC0
         select BSP_USING_PWM
         select BSP_USING_PWM
         select BSP_USING_CTIMER1_MAT0
         select BSP_USING_CTIMER1_MAT0
-        select BSP_USING_CTIMER1_MAT3
         select BSP_USING_CTIMER2_MAT0
         select BSP_USING_CTIMER2_MAT0
         select BSP_USING_CTIMER2_MAT1
         select BSP_USING_CTIMER2_MAT1
         select BSP_USING_CTIMER2_MAT2
         select BSP_USING_CTIMER2_MAT2
-        select BSP_USING_CTIMER3_MAT2
         select BSP_USING_I2C
         select BSP_USING_I2C
         select BSP_USING_I2C1
         select BSP_USING_I2C1
         imply RTDUINO_USING_SERVO
         imply RTDUINO_USING_SERVO

+ 15 - 2
bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.c

@@ -338,13 +338,26 @@ void BOARD_InitPins(void)
                          (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK)))
                          (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK)))
 
 
                         /* Selects pin function.
                         /* Selects pin function.
-                         * : PORT17 (pin 9) is configured as PIO1_7. */
-                        | IOCON_PIO_FUNC(PIO1_7_FUNC_ALT0)
+                         * : PORT17 (pin 9) is configured as CTIMER2_MAT2. */
+                        | IOCON_PIO_FUNC(PIO1_7_FUNC_ALT3)
 
 
                         /* Select Digital mode.
                         /* Select Digital mode.
                          * : Digital mode, digital input is enabled. */
                          * : Digital mode, digital input is enabled. */
                         | IOCON_PIO_DIGIMODE(PIO1_7_DIGIMODE_DIGITAL));
                         | IOCON_PIO_DIGIMODE(PIO1_7_DIGIMODE_DIGITAL));
 
 
+    IOCON->PIO[1][10] = ((IOCON->PIO[1][10] &
+                          /* Mask bits to zero which are setting */
+                          (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK)))
+
+                        /* Selects pin function.
+                         * : PORT110 (pin 40) is configured as CTIMER1_MAT0. */
+                        | IOCON_PIO_FUNC(PIO1_10_FUNC_ALT3)
+
+                        /* Select Digital mode.
+                         * : Enable Digital mode.
+                         * Digital input is enabled. */
+                        | IOCON_PIO_DIGIMODE(PIO1_10_DIGIMODE_DIGITAL));
+
     /* I2C4 */
     /* I2C4 */
     IOCON_PinMuxSet(IOCON, 1U, 20, 5 | IOCON_PIO_MODE_INACT | IOCON_PIO_SLEW_STANDARD | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | IOCON_PIO_OPENDRAIN_DI);
     IOCON_PinMuxSet(IOCON, 1U, 20, 5 | IOCON_PIO_MODE_INACT | IOCON_PIO_SLEW_STANDARD | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | IOCON_PIO_OPENDRAIN_DI);
     IOCON_PinMuxSet(IOCON, 1U, 21, 5 | IOCON_PIO_MODE_INACT | IOCON_PIO_SLEW_STANDARD | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | IOCON_PIO_OPENDRAIN_DI);
     IOCON_PinMuxSet(IOCON, 1U, 21, 5 | IOCON_PIO_MODE_INACT | IOCON_PIO_SLEW_STANDARD | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | IOCON_PIO_OPENDRAIN_DI);

+ 8 - 2
bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.h

@@ -174,8 +174,14 @@ void BOARD_InitBootPins(void);
  * @brief Select Digital mode.: Digital mode, digital input is enabled. */
  * @brief Select Digital mode.: Digital mode, digital input is enabled. */
 #define PIO1_7_DIGIMODE_DIGITAL 0x01u
 #define PIO1_7_DIGIMODE_DIGITAL 0x01u
 /*!
 /*!
- * @brief Selects pin function.: Alternative connection 0. */
-#define PIO1_7_FUNC_ALT0 0x00u
+ * @brief Selects pin function.: Alternative connection 3. */
+#define PIO1_7_FUNC_ALT3 0x03u
+/*!
+ * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */
+#define PIO1_10_DIGIMODE_DIGITAL 0x01u
+/*!
+ * @brief Selects pin function.: Alternative connection 3. */
+#define PIO1_10_FUNC_ALT3 0x03u
 
 
 /*!
 /*!
  * @brief Configures pin routing and optionally pin electrical features.
  * @brief Configures pin routing and optionally pin electrical features.