summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShicheng Chu <[email protected]>2023-10-30 01:17:25 +0800
committerGitHub <[email protected]>2023-10-29 13:17:25 -0400
commit1554888c0b004bac7098e2a92a32603dd26b452c (patch)
tree3a3ccc3cae20d81a60cb33079a805e1ca51185e2
parentde779b1804034da3cc946d277c980faffa22a20c (diff)
[bsp][pico]: add pwm driver (#8178)
Co-authored-by: Meco Man <[email protected]>
-rw-r--r--bsp/raspberry-pico/Kconfig160
-rw-r--r--bsp/raspberry-pico/drivers/SConscript3
-rw-r--r--bsp/raspberry-pico/drivers/drv_pwm.c229
-rw-r--r--bsp/raspberry-pico/drivers/drv_pwm.h18
4 files changed, 410 insertions, 0 deletions
diff --git a/bsp/raspberry-pico/Kconfig b/bsp/raspberry-pico/Kconfig
index 523fa9f2ad..1e61d7ce03 100644
--- a/bsp/raspberry-pico/Kconfig
+++ b/bsp/raspberry-pico/Kconfig
@@ -237,6 +237,166 @@ menu "On-chip Peripheral Drivers"
default n
endif
+ menuconfig BSP_USING_PWM
+ bool "Enable PWM(A:CH_0 B:CH_1)"
+ default n
+ select RT_USING_PWM
+ if BSP_USING_PWM
+ config BSP_USING_PWM0
+ bool "Enable PWM0"
+ default n
+ if BSP_USING_PWM0
+ config BSP_PWM0_A_PIN
+ int "pwm slice A pin number (GP)"
+ range 0 29
+ default 0
+ config BSP_PWM0_B_PIN
+ int "pwm slice B pin number (GP)"
+ range 0 29
+ default 1
+ config BSP_PWM0_A_ALL
+ bool "pwm slice use all A pin"
+ default n
+ config BSP_PWM0_B_ALL
+ bool "pwm slice use all B pin"
+ default n
+ endif
+
+ config BSP_USING_PWM1
+ bool "Enable PWM1"
+ default n
+ if BSP_USING_PWM1
+ config BSP_PWM_A_PIN
+ int "pwm slice A pin number (GP)"
+ range 0 29
+ default 2
+ config BSP_PWM1_B_PIN
+ int "pwm slice B pin number (GP)"
+ range 0 29
+ default 3
+ config BSP_PWM1_A_ALL
+ bool "pwm slice use all A pin"
+ default n
+ config BSP_PWM1_B_ALL
+ bool "pwm slice use all B pin"
+ default n
+ endif
+
+ config BSP_USING_PWM2
+ bool "Enable PWM2"
+ default n
+ if BSP_USING_PWM2
+ config BSP_PWM2_A_PIN
+ int "pwm slice A pin number (GP)"
+ range 0 29
+ default 4
+ config BSP_PWM2_B_PIN
+ int "pwm slice B pin number (GP)"
+ range 0 29
+ default 5
+ config BSP_PWM2_A_ALL
+ bool "pwm slice use all A pin"
+ default n
+ config BSP_PWM2_B_ALL
+ bool "pwm slice use all B pin"
+ default n
+ endif
+
+ config BSP_USING_PWM3
+ bool "Enable PWM3"
+ default n
+ if BSP_USING_PWM3
+ config BSP_PWM3_A_PIN
+ int "pwm slice A pin number (GP)"
+ range 0 29
+ default 6
+ config BSP_PWM3_B_PIN
+ int "pwm slice B pin number (GP)"
+ range 0 29
+ default 7
+ config BSP_PWM3_A_ALL
+ bool "pwm slice use all A pin"
+ default n
+ config BSP_PWM3_B_ALL
+ bool "pwm slice use all B pin"
+ default n
+ endif
+
+ config BSP_USING_PWM4
+ bool "Enable PWM4"
+ default n
+ if BSP_USING_PWM4
+ config BSP_PWM4_A_PIN
+ int "pwm slice A pin number (GP)"
+ range 0 29
+ default 8
+ config BSP_PWM4_B_PIN
+ int "pwm slice B pin number (GP)"
+ range 0 29
+ default 9
+ config BSP_PWM4_A_ALL
+ bool "pwm slice use all A pin"
+ default n
+ config BSP_PWM4_B_ALL
+ bool "pwm slice use all B pin"
+ default n
+ endif
+
+ config BSP_USING_PWM5
+ bool "Enable PWM5"
+ default n
+ if BSP_USING_PWM5
+ config BSP_PWM5_A_PIN
+ int "pwm slice A pin number (GP)"
+ range 0 29
+ default 10
+ config BSP_PWM5_B_PIN
+ int "pwm slice B pin number (GP)"
+ range 0 29
+ default 11
+ config BSP_PWM5_A_ALL
+ bool "pwm slice use all A pin"
+ default n
+ config BSP_PWM5_B_ALL
+ bool "pwm slice use all B pin"
+ default n
+ endif
+
+ config BSP_USING_PWM6
+ bool "Enable PWM6"
+ default n
+ if BSP_USING_PWM6
+ config BSP_PWM6_A_PIN
+ int "pwm slice A pin number (GP)"
+ range 0 29
+ default 12
+ config BSP_PWM6_B_PIN
+ int "pwm slice B pin number (GP)"
+ range 0 29
+ default 13
+ config BSP_PWM6_A_ALL
+ bool "pwm slice use all A pin"
+ default n
+ config BSP_PWM6_B_ALL
+ bool "pwm slice use all B pin"
+ default n
+ endif
+
+ config BSP_USING_PWM7
+ bool "Enable PWM7"
+ default n
+ if BSP_USING_PWM7
+ config BSP_PWM7_A_PIN
+ int "pwm slice A pin number (GP)"
+ range 0 29
+ default 14
+ config BSP_PWM7_B_PIN
+ int "pwm slice B pin number (GP)"
+ range 0 29
+ default 15
+ endif
+ endif
+
menuconfig BSP_USING_I2C
bool "Enable I2C"
select RT_USING_I2C
diff --git a/bsp/raspberry-pico/drivers/SConscript b/bsp/raspberry-pico/drivers/SConscript
index 63f598cd84..a05cd2aed2 100644
--- a/bsp/raspberry-pico/drivers/SConscript
+++ b/bsp/raspberry-pico/drivers/SConscript
@@ -31,6 +31,9 @@ if GetDepend('BSP_USING_I2C'):
if GetDepend('BSP_USING_ON_CHIP_FLASH'):
src += ['drv_flash.c']
+if GetDepend('BSP_USING_PWM'):
+ src += ['drv_pwm.c']
+
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
diff --git a/bsp/raspberry-pico/drivers/drv_pwm.c b/bsp/raspberry-pico/drivers/drv_pwm.c
new file mode 100644
index 0000000000..22251aa42a
--- /dev/null
+++ b/bsp/raspberry-pico/drivers/drv_pwm.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-10-20 ChuShicheng first version
+ */
+#include "drv_pwm.h"
+#include "board.h"
+#include "hardware/pwm.h"
+
+#ifdef BSP_USING_PWM
+
+#define DBG_LEVEL DBG_LOG
+#include <rtdbg.h>
+#define LOG_TAG "DRV.PWM"
+
+struct pico_pwm
+{
+ struct rt_device_pwm pwm_device;
+ rt_uint8_t slice_num;
+ rt_uint8_t pin_a;
+ rt_uint8_t pin_b;
+ rt_uint8_t a_all_flag; /* 1: Two pins simultaneously output PWM A channel */
+ rt_uint8_t b_all_flag; /* 1: Two pins simultaneously output PWM B channel */
+ char *name;
+};
+
+static struct pico_pwm pico_pwm_obj[] =
+{
+#ifdef BSP_USING_PWM0
+ {
+ .name = "pwm0",
+ .slice_num = 0,
+ .pin_a = BSP_PWM0_A_PIN,
+ .pin_b = BSP_PWM0_B_PIN,
+#ifdef BSP_PWM0_A_ALL
+ .a_all_flag = 1,
+#endif /* BSP_PWM0_A_ALL */
+#ifdef BSP_PWM0_B_ALL
+ .b_all_flag = 1,
+#endif /* BSP_PWM0_B_ALL */
+ },
+#endif /* BSP_USING_PWM0 */
+#ifdef BSP_USING_PWM1
+ {
+ .name = "pwm1",
+ .slice_num = 1,
+ .pin_a = BSP_PWM1_A_PIN,
+ .pin_b = BSP_PWM1_B_PIN,
+#ifdef BSP_PWM1_A_ALL
+ .a_all_flag = 1,
+#endif /* BSP_PWM1_A_ALL */
+#ifdef BSP_PWM1_B_ALL
+ .b_all_flag = 1,
+#endif /* BSP_PWM1_B_ALL */
+ },
+#endif /* BSP_USING_PWM1 */
+#ifdef BSP_USING_PWM2
+ {
+ .name = "pwm2",
+ .slice_num = 2,
+ .pin_a = BSP_PWM2_A_PIN,
+ .pin_b = BSP_PWM2_B_PIN,
+#ifdef BSP_PWM2_A_ALL
+ .a_all_flag = 1,
+#endif /* BSP_PWM2_A_ALL */
+#ifdef BSP_PWM2_B_ALL
+ .b_all_flag = 1,
+#endif /* BSP_PWM2_B_ALL */
+ },
+#endif /* BSP_USING_PWM2 */
+#ifdef BSP_USING_PWM3
+ {
+ .name = "pwm3",
+ .slice_num = 3,
+ .pin_a = BSP_PWM3_A_PIN,
+ .pin_b = BSP_PWM3_B_PIN,
+#ifdef BSP_PWM3_A_ALL
+ .a_all_flag = 1,
+#endif /* BSP_PWM3_A_ALL */
+#ifdef BSP_PWM3_B_ALL
+ .b_all_flag = 1,
+#endif /* BSP_PWM3_B_ALL */
+ },
+#endif /* BSP_USING_PWM3 */
+#ifdef BSP_USING_PWM4
+ {
+ .name = "pwm4",
+ .slice_num = 4,
+ .pin_a = BSP_PWM4_A_PIN,
+ .pin_b = BSP_PWM4_B_PIN,
+#ifdef BSP_PWM4_A_ALL
+ .a_all_flag = 1,
+#endif /* BSP_PWM4_A_ALL */
+#ifdef BSP_PWM4_B_ALL
+ .b_all_flag = 1,
+#endif /* BSP_PWM4_B_ALL */
+ },
+#endif /* BSP_USING_PWM4 */
+#ifdef BSP_USING_PWM5
+ {
+ .name = "pwm5",
+ .slice_num = 5,
+ .pin_a = BSP_PWM5_A_PIN,
+ .pin_b = BSP_PWM5_B_PIN,
+#ifdef BSP_PWM5_A_ALL
+ .a_all_flag = 1,
+#endif /* BSP_PWM5_A_ALL */
+#ifdef BSP_PWM5_B_ALL
+ .b_all_flag = 1,
+#endif /* BSP_PWM5_B_ALL */
+ },
+#endif /* BSP_USING_PWM5 */
+#ifdef BSP_USING_PWM6
+ {
+ .name = "pwm6",
+ .slice_num = 6,
+ .pin_a = BSP_PWM6_A_PIN,
+ .pin_b = BSP_PWM6_B_PIN,
+#ifdef BSP_PWM6_A_ALL
+ .a_all_flag = 1,
+#endif /* BSP_PWM6_A_ALL */
+#ifdef BSP_PWM6_B_ALL
+ .b_all_flag = 1,
+#endif /* BSP_PWM6_B_ALL */
+ },
+#endif /* BSP_USING_PWM6 */
+#ifdef BSP_USING_PWM7
+ {
+ .name = "pwm7",
+ .slice_num = 7,
+ .pin_a = BSP_PWM7_A_PIN,
+ .pin_b = BSP_PWM7_B_PIN,
+ },
+#endif /* BSP_USING_PWM7 */
+};
+
+
+static rt_err_t _pwm_set(rt_uint8_t slice_num, struct rt_pwm_configuration *configuration)
+{
+ uint32_t period_hz = 1000000000 / configuration->period;
+ uint32_t pulse = 1000000000 / configuration->pulse;
+
+ pwm_config config = pwm_get_default_config();
+ pwm_config_set_clkdiv(&config, 1.33f);
+ pwm_init(slice_num, &config, true);
+ pwm_set_wrap(slice_num, 100000000 / period_hz);
+ pwm_set_chan_level(slice_num, configuration->channel, 100000000 / pulse);
+
+ return RT_EOK;
+}
+
+static rt_err_t _pwm_get(rt_uint8_t slice_num, struct rt_pwm_configuration *configuration)
+{
+ uint32_t period_hz = pwm_hw->slice[slice_num].top;
+
+ configuration->period = period_hz * 10;
+
+ configuration->pulse = pwm_hw->slice[slice_num].cc * 10;
+
+ return RT_EOK;
+}
+
+static rt_err_t _pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
+{
+ struct pico_pwm *_pwm = rt_container_of(device, struct pico_pwm, pwm_device);
+ struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
+
+ switch (cmd)
+ {
+ case PWM_CMD_ENABLE:
+ pwm_set_enabled (_pwm->slice_num, RT_TRUE);
+ return RT_EOK;
+ case PWM_CMD_DISABLE:
+ pwm_set_enabled (_pwm->slice_num, RT_FALSE);
+ return RT_EOK;
+ case PWM_CMD_SET:
+ return _pwm_set(_pwm->slice_num, configuration);
+ case PWM_CMD_GET:
+ return _pwm_get(_pwm->slice_num, configuration);
+ default:
+ return -RT_EINVAL;
+ }
+}
+
+static struct rt_pwm_ops _pwm_ops =
+{
+ _pwm_control
+};
+
+int rt_hw_pwm_init(void)
+{
+ int result = RT_EOK;
+
+ for (int i = 0; i < sizeof(pico_pwm_obj) / sizeof(pico_pwm_obj[0]); i++)
+ {
+ if(pico_pwm_obj[i].a_all_flag)
+ {
+ gpio_set_function(pico_pwm_obj[i].slice_num * 2, GPIO_FUNC_PWM);
+ gpio_set_function(pico_pwm_obj[i].slice_num * 2 + 16, GPIO_FUNC_PWM);
+ }
+ else
+ {
+ gpio_set_function(pico_pwm_obj[i].pin_a, GPIO_FUNC_PWM);
+ }
+ if(pico_pwm_obj[i].b_all_flag)
+ {
+ gpio_set_function(pico_pwm_obj[i].slice_num * 2 + 1, GPIO_FUNC_PWM);
+ gpio_set_function(pico_pwm_obj[i].slice_num * 2 + 17, GPIO_FUNC_PWM);
+ }
+ else
+ {
+ gpio_set_function(pico_pwm_obj[i].pin_b, GPIO_FUNC_PWM);
+ }
+ result = rt_device_pwm_register(&pico_pwm_obj[i].pwm_device, pico_pwm_obj[i].name, &_pwm_ops, 0);
+ if(result != RT_EOK)
+ {
+ LOG_E("%s register fail.", pico_pwm_obj[i].name);
+ }
+ }
+
+ return result;
+}
+INIT_DEVICE_EXPORT(rt_hw_pwm_init);
+
+#endif /* BSP_USING_PWM */
diff --git a/bsp/raspberry-pico/drivers/drv_pwm.h b/bsp/raspberry-pico/drivers/drv_pwm.h
new file mode 100644
index 0000000000..b624008b7c
--- /dev/null
+++ b/bsp/raspberry-pico/drivers/drv_pwm.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-10-20 ChuShicheng first version
+ */
+
+#ifndef __DRV_PWM_H__
+#define __DRV_PWM_H__
+
+#include <rtdevice.h>
+
+int rt_hw_pwm_init(void);
+
+#endif /* __DRV_PWM_H__ */