summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author螺丝松掉的人 <[email protected]>2023-03-01 06:37:09 +0800
committerGitHub <[email protected]>2023-02-28 17:37:09 -0500
commit3a08336cb50988175bd143f0839a91aca44cd696 (patch)
treea98fca6767b42843da20bf87abbee8b353aefa53
parent75c3261181d5fa12c0ceead8abc88429ef2b1ee6 (diff)
[bsp][lpc55sxx] update pwm driver
-rw-r--r--bsp/lpc55sxx/Libraries/drivers/drv_pwm.c246
-rw-r--r--bsp/lpc55sxx/Libraries/drivers/drv_pwm.h2
-rw-r--r--bsp/lpc55sxx/lpc55s69_nxp_evk/applications/arduino_pinout/pins_arduino.c4
-rw-r--r--bsp/lpc55sxx/lpc55s69_nxp_evk/board/Kconfig12
-rw-r--r--bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.c17
-rw-r--r--bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.h10
6 files changed, 226 insertions, 65 deletions
diff --git a/bsp/lpc55sxx/Libraries/drivers/drv_pwm.c b/bsp/lpc55sxx/Libraries/drivers/drv_pwm.c
index 4abb65b1d0..0f8a4bb16a 100644
--- a/bsp/lpc55sxx/Libraries/drivers/drv_pwm.c
+++ b/bsp/lpc55sxx/Libraries/drivers/drv_pwm.c
@@ -7,12 +7,18 @@
* Date Author Notes
* 2019-04-28 tyustli first version
* 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>
#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) && \
!defined(BSP_USING_CTIMER2_MAT2)
#error "Please define at least one BSP_USING_CTIMERx_MATx"
@@ -30,6 +36,67 @@
#define DEFAULT_DUTY 50
#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 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;
-#ifdef BSP_USING_CTIMER2
/* 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);
- 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_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 */
/* 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 */
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;
+ }
- /* 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;
@@ -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;
+ 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;
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 */
if (DEFAULT_DUTY == 0)
@@ -183,21 +301,57 @@ int rt_hw_pwm_init(void)
{
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)
+ {
+ CTIMER_SetupPwmPeriod(tim, kCTIMER_Match_3 , kCTIMER_Match_0, pwmPeriod, pulsePeriod, false);
+ }
+ if (channel & 0x02)
{
- LOG_E("%s register failed", "pwm2");
+ 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;
}
-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 */
diff --git a/bsp/lpc55sxx/Libraries/drivers/drv_pwm.h b/bsp/lpc55sxx/Libraries/drivers/drv_pwm.h
index 264d464e76..7b1c5ea777 100644
--- a/bsp/lpc55sxx/Libraries/drivers/drv_pwm.h
+++ b/bsp/lpc55sxx/Libraries/drivers/drv_pwm.h
@@ -14,6 +14,4 @@
#include <rtdevice.h>
-int rt_hw_pwm_init(void);
-
#endif
diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/applications/arduino_pinout/pins_arduino.c b/bsp/lpc55sxx/lpc55s69_nxp_evk/applications/arduino_pinout/pins_arduino.c
index 2d7d8bd4f9..430e32a289 100644
--- a/bsp/lpc55sxx/lpc55s69_nxp_evk/applications/arduino_pinout/pins_arduino.c
+++ b/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)},
{D4, GET_PINS(1,7), "pwm2", 2}, /* 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)},
{D9, GET_PINS(1,5)},
{D10, GET_PINS(1,1)},
diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/Kconfig b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/Kconfig
index ed014dbc0d..aff50947c0 100644
--- a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/Kconfig
+++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/Kconfig
@@ -212,21 +212,13 @@ menu "On-chip Peripheral Drivers"
default y
if BSP_USING_PWM
- config BSP_USING_CTIMER0_MAT3
- bool "Enable CIMER0 Match3 as PWM output"
- default y
-
config BSP_USING_CTIMER1_MAT0
bool "Enable CIMER1 Match0 as PWM output"
default y
- config BSP_USING_CTIMER1_MAT3
- bool "Enable CIMER1 Match3 as PWM output"
- default n
-
config BSP_USING_CTIMER2_MAT0
bool "Enable CIMER2 Match0 as PWM output"
- default y
+ default n
config BSP_USING_CTIMER2_MAT1
bool "Enable CIMER2 Match1 as PWM output"
@@ -272,11 +264,9 @@ menu "Onboard Peripheral Drivers"
select BSP_USING_ADC0
select BSP_USING_PWM
select BSP_USING_CTIMER1_MAT0
- select BSP_USING_CTIMER1_MAT3
select BSP_USING_CTIMER2_MAT0
select BSP_USING_CTIMER2_MAT1
select BSP_USING_CTIMER2_MAT2
- select BSP_USING_CTIMER3_MAT2
select BSP_USING_I2C
select BSP_USING_I2C1
imply RTDUINO_USING_SERVO
diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.c b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.c
index f04b9753f5..2e717ceecb 100644
--- a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.c
+++ b/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)))
/* 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.
* : Digital mode, digital input is enabled. */
| 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 */
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);
diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.h b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.h
index 6a9b78dc1c..39846c8c10 100644
--- a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/MCUX_Config/board/pin_mux.h
+++ b/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. */
#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.