From 2dce87deaafd60fe7fc044922a045892f30df9aa Mon Sep 17 00:00:00 2001 From: dannyray019 Date: Sun, 27 Jul 2025 01:31:52 +0800 Subject: [PATCH] bsp: k230: add support for PWM driver Added a PWM driver and a test file test_pwm.c. The test uses PWM to control the LED brightness, to check if the driver works correctly. Signed-off-by: XU HU <1337858472@qq.com> --- bsp/k230/.config | 23 ++- bsp/k230/board/Kconfig | 16 ++ bsp/k230/drivers/interdrv/pwm/SConscript | 11 + bsp/k230/drivers/interdrv/pwm/drv_pwm.c | 247 +++++++++++++++++++++++ bsp/k230/drivers/interdrv/pwm/drv_pwm.h | 92 +++++++++ bsp/k230/drivers/utest/SConscript | 5 +- bsp/k230/drivers/utest/test_pwm.c | 115 +++++++++++ bsp/k230/rtconfig.h | 5 +- 8 files changed, 509 insertions(+), 5 deletions(-) create mode 100644 bsp/k230/drivers/interdrv/pwm/SConscript create mode 100644 bsp/k230/drivers/interdrv/pwm/drv_pwm.c create mode 100644 bsp/k230/drivers/interdrv/pwm/drv_pwm.h create mode 100644 bsp/k230/drivers/utest/test_pwm.c diff --git a/bsp/k230/.config b/bsp/k230/.config index c0107f79129..2658f524dc3 100644 --- a/bsp/k230/.config +++ b/bsp/k230/.config @@ -204,6 +204,9 @@ CONFIG_ARCH_MM_MMU=y CONFIG_KERNEL_VADDR_START=0xffffffc000000000 CONFIG_ARCH_RISCV=y CONFIG_ARCH_RISCV_FPU=y +CONFIG_ARCH_RISCV_VECTOR=y +CONFIG_ARCH_VECTOR_VLEN_128=y +# CONFIG_ARCH_VECTOR_VLEN_256 is not set CONFIG_ARCH_RISCV_FPU_D=y CONFIG_ARCH_RISCV64=y CONFIG_ARCH_USING_NEW_CTX_SWITCH=y @@ -706,6 +709,7 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_LHC_MODBUS is not set # CONFIG_PKG_USING_QMODBUS is not set # CONFIG_PKG_USING_PNET is not set +# CONFIG_PKG_USING_OPENER is not set # end of IoT - internet of things # @@ -839,6 +843,7 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_VOFA_PLUS is not set # CONFIG_PKG_USING_ZDEBUG is not set # CONFIG_PKG_USING_RVBACKTRACE is not set +# CONFIG_PKG_USING_HPATCHLITE is not set # end of tools packages # @@ -867,7 +872,6 @@ CONFIG_RT_USING_VDSO=y # # CONFIG_PKG_USING_CMSIS_5 is not set # CONFIG_PKG_USING_CMSIS_CORE is not set -# CONFIG_PKG_USING_CMSIS_DSP is not set # CONFIG_PKG_USING_CMSIS_NN is not set # CONFIG_PKG_USING_CMSIS_RTOS1 is not set # CONFIG_PKG_USING_CMSIS_RTOS2 is not set @@ -919,7 +923,6 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_ARM_2D is not set # CONFIG_PKG_USING_MCUBOOT is not set # CONFIG_PKG_USING_TINYUSB is not set -# CONFIG_PKG_USING_CHERRYUSB is not set # CONFIG_PKG_USING_KMULTI_RTIMER is not set # CONFIG_PKG_USING_TFDB is not set # CONFIG_PKG_USING_QPC is not set @@ -931,6 +934,7 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_SFDB is not set # CONFIG_PKG_USING_RTP is not set # CONFIG_PKG_USING_REB is not set +# CONFIG_PKG_USING_RMP is not set # CONFIG_PKG_USING_R_RHEALSTONE is not set # CONFIG_PKG_USING_HEARTBEAT is not set # end of system packages @@ -1021,12 +1025,14 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_BMI088 is not set # CONFIG_PKG_USING_HMC5883 is not set # CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_MAX31855 is not set # CONFIG_PKG_USING_TMP1075 is not set # CONFIG_PKG_USING_SR04 is not set # CONFIG_PKG_USING_CCS811 is not set # CONFIG_PKG_USING_PMSXX is not set # CONFIG_PKG_USING_RT3020 is not set # CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90382 is not set # CONFIG_PKG_USING_MLX90393 is not set # CONFIG_PKG_USING_MLX90392 is not set # CONFIG_PKG_USING_MLX90394 is not set @@ -1055,6 +1061,8 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_ICM20608 is not set # CONFIG_PKG_USING_PAJ7620 is not set # CONFIG_PKG_USING_STHS34PF80 is not set +# CONFIG_PKG_USING_P3T1755 is not set +# CONFIG_PKG_USING_QMI8658 is not set # end of sensors drivers # @@ -1146,6 +1154,9 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_BT_MX02 is not set # CONFIG_PKG_USING_GC9A01 is not set # CONFIG_PKG_USING_IK485 is not set +# CONFIG_PKG_USING_SERVO is not set +# CONFIG_PKG_USING_SEAN_WS2812B is not set +# CONFIG_PKG_USING_IC74HC165 is not set # CONFIG_PKG_USING_SPI_TOOLS is not set # end of peripheral libraries and drivers @@ -1162,6 +1173,7 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_QUEST is not set # CONFIG_PKG_USING_NAXOS is not set # CONFIG_PKG_USING_R_TINYMAIX is not set +# CONFIG_PKG_USING_LLMCHAT is not set # end of AI packages # @@ -1238,6 +1250,7 @@ CONFIG_PKG_ZLIB_VER="latest" # CONFIG_PKG_USING_KI is not set # CONFIG_PKG_USING_ARMv7M_DWT is not set # CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LIBCRC is not set # CONFIG_PKG_USING_LWGPS is not set # CONFIG_PKG_USING_STATE_MACHINE is not set # CONFIG_PKG_USING_DESIGN_PATTERN is not set @@ -1248,6 +1261,7 @@ CONFIG_PKG_ZLIB_VER="latest" # CONFIG_PKG_USING_SOEM is not set # CONFIG_PKG_USING_QPARAM is not set # CONFIG_PKG_USING_CorevMCU_CLI is not set +# CONFIG_PKG_USING_DRMP is not set # end of miscellaneous packages # @@ -1491,6 +1505,7 @@ CONFIG_PKG_ZLIB_VER="latest" # Drivers Configuration # # CONFIG_BSP_USING_ADC is not set +# CONFIG_BSP_USING_PWM is not set CONFIG_BSP_USING_HARDLOCK=y CONFIG_BSP_USING_SDIO=y CONFIG_BSP_USING_SDIO0=y @@ -1503,7 +1518,9 @@ CONFIG_BSP_SD_MNT_DEVNAME="sd0p1" # CONFIG_BSP_UTEST_DRIVERS is not set # end of Drivers Configuration -CONFIG_BOARD_fpgac908=y +CONFIG_BOARD_C908=y CONFIG___STACKSIZE__=65536 CONFIG_BSP_ROOTFS_TYPE_ELMFAT=y # CONFIG_BSP_ROOTFS_TYPE_CROMFS is not set +# CONFIG_BSP_RISCV_FPU_SOFT is not set +CONFIG_BSP_RISCV_FPU_D=y diff --git a/bsp/k230/board/Kconfig b/bsp/k230/board/Kconfig index b9207044b9f..162db76ad56 100644 --- a/bsp/k230/board/Kconfig +++ b/bsp/k230/board/Kconfig @@ -5,6 +5,22 @@ menu "Drivers Configuration" select RT_USING_ADC default n + menuconfig BSP_USING_PWM + bool "Enable PWM" + select RT_USING_PWM + default n + + if BSP_USING_PWM + config BSP_USING_PWM0 + bool "Enable PWM0" + default n + + config BSP_USING_PWM1 + bool "Enable PWM1" + default n + + endif + config BSP_USING_HARDLOCK bool "Enable Hard-Lock" default y diff --git a/bsp/k230/drivers/interdrv/pwm/SConscript b/bsp/k230/drivers/interdrv/pwm/SConscript new file mode 100644 index 00000000000..7e5c90707c9 --- /dev/null +++ b/bsp/k230/drivers/interdrv/pwm/SConscript @@ -0,0 +1,11 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + +group = DefineGroup('PWM', src, depend = ['BSP_USING_PWM'], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/k230/drivers/interdrv/pwm/drv_pwm.c b/bsp/k230/drivers/interdrv/pwm/drv_pwm.c new file mode 100644 index 00000000000..a121d0fdb38 --- /dev/null +++ b/bsp/k230/drivers/interdrv/pwm/drv_pwm.c @@ -0,0 +1,247 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Copyright (c) 2006-2025 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "riscv_io.h" +#include "board.h" +#include "ioremap.h" +#include +#include +#include "sysctl_clk.h" +#include "drv_pwm.h" +#include + +/** + * pwm0 + * ---channel 0 + * ---channel 1 + * ---channel 2 + * pwm1 + * ---channel 0 + * ---channel 1 + * ---channel 2 + */ + + /* + * 注意:K230 的 PWM 控制器有 4 个硬件 channel,其中: + * - channel 0(pwmcmp0)用于设置周期,不对应输出; + * - channel 1~3(pwmcmp1~3)用于控制占空比,是实际的输出通道。 + * 因此,驱动中将这三个通道映射为 channel 0~2。 + */ + +#define PWM_REG_OFFSET 0x40 +#define PWM_CFG_BIT_INVERT (1 << 12) +#define PWM_CFG_DEGLITCH (1 << 9) +#define PWM_MAX_SCALE 0xF +#define PWM_CMP_WIDTH 16 +#define PWM_PERIOD_BITS 16 +#define PWM_SCALE_MAX_BITS 15 +#define PWM_DEV_NUM 2 +#define PWM_MAX_CHANNELS 3 + +#define PWM0_BASE_ADDR PWM_BASE_ADDR +#define PWM1_BASE_ADDR PWM_BASE_ADDR+PWM_REG_OFFSET + +struct k230_pwm_dev +{ + struct rt_device_pwm* device; + const char *name; + rt_ubase_t base; + size_t size; + kd_pwm_t *regs; +}; + +static struct k230_pwm_dev pwm_devs[PWM_DEV_NUM] = { +#ifdef BSP_USING_PWM0 + { + .name = "pwm0", + .base = PWM0_BASE_ADDR, + .size = PWM_IO_SIZE, + }, +#endif + +#ifdef BSP_USING_PWM1 + { + .name = "pwm1", + .base = PWM1_BASE_ADDR, + .size = PWM_IO_SIZE, + } +#endif +}; + +static rt_err_t check_channel(int channel) +{ + if (channel < 0 || channel >= PWM_MAX_CHANNELS) + { + LOG_E("channel %d is not valid\n", channel); + return -RT_ERROR; + } + return channel; +} + +static rt_err_t pwm_start(kd_pwm_t *reg, int channel) +{ + int ret; + ret = check_channel(channel); + if (ret < 0) + return ret; + reg->pwmcfg |= PWM_CFG_BIT_INVERT; //default always mode + return ret; +} + +static rt_err_t pwm_stop(kd_pwm_t *reg, int channel) +{ + int ret; + ret = check_channel(channel); + if (ret < 0) + return ret; + reg->pwmcfg &= ~PWM_CFG_BIT_INVERT; + + return ret; +} + +static rt_err_t kd_pwm_get(kd_pwm_t *reg, rt_uint8_t channel, struct rt_pwm_configuration *configuration) +{ + int ret; + uint64_t pulse, period; + uint32_t pwm_pclock, pwmscale; + + ret = check_channel(channel); + if (ret < 0) + return ret; + + pwm_pclock = sysctl_clk_get_leaf_freq(SYSCTL_CLK_PWM_APB_GATE); + + pwmscale = reg->pwmcfg & 0xf; + pwm_pclock >>= pwmscale; + period = reg->pwmcmp0; + period = period * NSEC_PER_SEC / pwm_pclock; + pulse = *((®->pwmcmp1) + channel); + pulse = pulse * NSEC_PER_SEC / pwm_pclock; + + configuration->period = period; + configuration->pulse = pulse; + + return RT_EOK; +} + +static rt_err_t kd_pwm_set(kd_pwm_t *reg, int channel, struct rt_pwm_configuration *configuration) +{ + int ret; + uint64_t pulse, period, pwmcmpx_max; + uint32_t pwm_pclock, pwmscale = 0; + + ret = check_channel(channel); + if (ret < 0) + return ret; + + pwm_pclock = sysctl_clk_get_leaf_freq(SYSCTL_CLK_PWM_APB_GATE); + pulse = (uint64_t)configuration->pulse * pwm_pclock / NSEC_PER_SEC; + period = (uint64_t)configuration->period * pwm_pclock / NSEC_PER_SEC; + if (pulse > period) + return -RT_EINVAL; + + + /* Calculate duty cycle */ + pwmcmpx_max = (1 << PWM_CMP_WIDTH) - 1; + if (period > ((1 << (PWM_SCALE_MAX_BITS + PWM_PERIOD_BITS)) - 1LL)) + return -RT_EINVAL; + + while ((period >> pwmscale) > pwmcmpx_max) + pwmscale++; + if (pwmscale > PWM_MAX_SCALE) + return -RT_EINVAL; + + reg->pwmcfg |= PWM_CFG_DEGLITCH; //default always mode + reg->pwmcfg &= (~PWM_MAX_SCALE); + reg->pwmcfg |= pwmscale; //scale + reg->pwmcmp0 = (period >> pwmscale); + *((®->pwmcmp1) + channel) = reg->pwmcmp0 - (pulse >> pwmscale); + + return RT_EOK; +} + +static rt_err_t kd_pwm_control(struct rt_device_pwm *device, int cmd, void *arg) +{ + struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg; + rt_uint32_t channel = 0; + int ret; + + kd_pwm_t *reg = (kd_pwm_t *)(device->parent.user_data); + channel = configuration->channel; + + switch (cmd) + { + case PWM_CMD_ENABLE: + ret = pwm_start(reg, channel); + break; + case PWM_CMD_DISABLE: + ret = pwm_stop(reg, channel); + break; + case PWM_CMD_SET: + ret = kd_pwm_set(reg, channel, configuration); + break; + case PWM_CMD_GET: + ret = kd_pwm_get(reg, channel, configuration); + break; + default: + ret = -RT_EINVAL; + } + + return ret; +} + +static struct rt_pwm_ops drv_ops = +{ + .control = kd_pwm_control +}; + +int rt_hw_pwm_init(void) +{ +#ifdef BSP_USING_PWM0 + static struct rt_device_pwm kd_pwm0; + struct k230_pwm_dev *dev0 = &pwm_devs[0]; + dev0->regs = (kd_pwm_t *)rt_ioremap((void *)(dev0->base), dev0->size); + dev0->device = &kd_pwm0; + dev0->device->ops = &drv_ops; + rt_device_pwm_register(dev0->device, dev0->name, &drv_ops, (void*)dev0->regs); +#endif + +#ifdef BSP_USING_PWM1 + static struct rt_device_pwm kd_pwm1; + struct k230_pwm_dev *dev1 = &pwm_devs[1]; + dev1->regs = (kd_pwm_t *)rt_ioremap((void *)(dev1->base), dev1->size); + dev1->device = &kd_pwm1; + dev1->device->ops = &drv_ops; + rt_device_pwm_register(dev1->device, dev1->name, &drv_ops, (void*)dev1->regs); +#endif + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_pwm_init); \ No newline at end of file diff --git a/bsp/k230/drivers/interdrv/pwm/drv_pwm.h b/bsp/k230/drivers/interdrv/pwm/drv_pwm.h new file mode 100644 index 00000000000..e3389f24cee --- /dev/null +++ b/bsp/k230/drivers/interdrv/pwm/drv_pwm.h @@ -0,0 +1,92 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2006-2025 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef DRV_PWM_H__ +#define DRV_PWM_H__ +#include + +#define KD_PWM_CMD_ENABLE _IOW('P', 0, int) +#define KD_PWM_CMD_DISABLE _IOW('P', 1, int) +#define KD_PWM_CMD_SET _IOW('P', 2, int) +#define KD_PWM_CMD_GET _IOW('P', 3, int) +#define NSEC_PER_SEC 1000000000L +typedef struct +{ + volatile uint32_t pwmcfg; /* 0x00 */ + volatile uint32_t reserved0; + volatile uint32_t pwmcount; /* 0x08 */ + volatile uint32_t reserved1; + volatile uint32_t pwms; /* 0x10 */ + volatile uint32_t reserved2; + volatile uint32_t reserved3; + volatile uint32_t reserved4; + volatile uint32_t pwmcmp0; /* 0x20 */ + volatile uint32_t pwmcmp1; /* 0x24 */ + volatile uint32_t pwmcmp2; /* 0x28 */ + volatile uint32_t pwmcmp3; /* 0x2c */ +} kd_pwm_t; + +typedef struct +{ + uint32_t scale : 4; + uint32_t reserve: 4; + uint32_t sticky : 1; + uint32_t zerocmp : 1; + uint32_t deglitch : 1; + uint32_t reserve1 : 1; + uint32_t enalways : 1; + uint32_t enoneshot : 1; + uint32_t reserve2 : 2; + uint32_t cmp0center : 1; + uint32_t cmp1center : 1; + uint32_t cmp2center : 1; + uint32_t cmp3center : 1; + uint32_t reserve3 : 4; + uint32_t cmp0gang : 1; + uint32_t cmp1gang : 1; + uint32_t cmp2gang : 1; + uint32_t cmp3gang : 1; + uint32_t cmp0ip : 1; + uint32_t cmp1ip : 1; + uint32_t cmp2ip : 1; + uint32_t cmp3ip : 1; +} pwm_cfg_t; + +typedef struct +{ + pwm_cfg_t cfg; + uint32_t freq; + uint32_t cmp0_val; + double cmp1_duty; + double cmp2_duty; + double cmp3_duty; +} pwm_param_t; + +#endif \ No newline at end of file diff --git a/bsp/k230/drivers/utest/SConscript b/bsp/k230/drivers/utest/SConscript index 54a5845c0fc..7366f41a524 100644 --- a/bsp/k230/drivers/utest/SConscript +++ b/bsp/k230/drivers/utest/SConscript @@ -14,7 +14,10 @@ if GetDepend('RT_UTEST_USING_ALL_CASES') or GetDepend('BSP_UTEST_DRIVERS'): if GetDepend('BSP_USING_WDT'): src += ['test_wdt.c'] - + + if GetDepend('BSP_USING_PWM'): + src += ['test_pwm.c'] + group = DefineGroup('utestcases', src, depend = ['']) Return('group') diff --git a/bsp/k230/drivers/utest/test_pwm.c b/bsp/k230/drivers/utest/test_pwm.c new file mode 100644 index 00000000000..334aa8839ff --- /dev/null +++ b/bsp/k230/drivers/utest/test_pwm.c @@ -0,0 +1,115 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2006-2025 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "drv_pwm.h" +#include "drv_pinctrl.h" +#include +#include "utest.h" + +/* + * 测试 PWM 驱动对板载 LED 的亮度控制功能 + * + * 1. 查找名为 "pwm" 的 PWM 设备。 + * 2. 使用 pinctrl 将 GPIO52 映射为 PWM4 通道,并配置引脚属性: + * - 使能输出(OE); + * - 禁用输入(IE); + * - 禁用上下拉(PU/PD); + * - 设置中等驱动能力(驱动强度为 4)。 + * 3. 设置 PWM 输出周期为 100000ns(对应频率为 10kHz)。 + * 4. 通过逐步增加 PWM 的脉冲宽度(pulse),控制板载 LED 的亮度由暗到亮: + * - 从 10% 占空比(10000ns)开始; + * - 每次增加 10%,直到 100%(全亮); + * - 每次间隔 2 秒以便观察 LED 亮度变化。 + * 5. 最后禁用 PWM 输出,关闭 LED。 + * + * 硬件说明: + * - 本测试基于 K230-01studio 开发板; + * - GPIO52 已通过电路连接一颗板载 LED; + * - PWM4 通道控制该 LED 的亮灭和亮度; + * - 测试过程中,可肉眼观察 LED 明暗变化。 + * + */ + +#define PWM_DEV_NAME "pwm1" /* PWM设备名称 */ +#define PWM_DEV_CHANNEL 1 /* PWM通道 */ +#define TEST_GPIO_LED 52 + +void pwm_demo(void) +{ + rt_kprintf("set gpio52 in PWM1 start.\n"); + k230_pinctrl_set_function(TEST_GPIO_LED, IOMUX_FUNC3); + // 使能输出 + k230_pinctrl_set_oe(TEST_GPIO_LED, 1); + // 禁止输入 + k230_pinctrl_set_ie(TEST_GPIO_LED, 0); + // 禁止上拉 + k230_pinctrl_set_pu(TEST_GPIO_LED, 0); + // 禁止下拉 + k230_pinctrl_set_pd(TEST_GPIO_LED, 0); + // 设置驱动能力为4(中等强度) + k230_pinctrl_set_drv(TEST_GPIO_LED, 4); + rt_kprintf("pwm test start.\n"); + struct rt_device_pwm *pwm_dev; /* PWM设备句柄 */ + rt_uint32_t period; /* 周期, 单位为纳秒ns */ + rt_uint32_t pulse; /* PWM脉冲宽度值, 单位为纳秒ns */ + /* 查找设备 */ + pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME); + uassert_not_null(pwm_dev); + /* 设置PWM周期和脉冲宽度 */ + period = 100000; /* PWM 周期:100000ns = 100us,即 10kHz */ + /* 逐步循环提高PWM脉冲宽度 */ + for(pulse = 10000; pulse <= 100000; pulse+=10000) + { + rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse); + rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL); + sleep(2); + } + rt_pwm_disable(pwm_dev, PWM_DEV_CHANNEL); +} + +static void pwm_testcase(void) +{ + UTEST_UNIT_RUN(pwm_demo); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +UTEST_TC_EXPORT(pwm_testcase, "pwm", utest_tc_init, utest_tc_cleanup, 10); \ No newline at end of file diff --git a/bsp/k230/rtconfig.h b/bsp/k230/rtconfig.h index 29862596a10..8107b906c25 100644 --- a/bsp/k230/rtconfig.h +++ b/bsp/k230/rtconfig.h @@ -130,6 +130,8 @@ #define KERNEL_VADDR_START 0xffffffc000000000 #define ARCH_RISCV #define ARCH_RISCV_FPU +#define ARCH_RISCV_VECTOR +#define ARCH_VECTOR_VLEN_128 #define ARCH_RISCV_FPU_D #define ARCH_RISCV64 #define ARCH_USING_NEW_CTX_SWITCH @@ -565,8 +567,9 @@ #define BSP_USING_SDIO0 #define BSP_SD_MNT_DEVNAME "sd0p1" /* end of Drivers Configuration */ -#define BOARD_fpgac908 +#define BOARD_C908 #define __STACKSIZE__ 65536 #define BSP_ROOTFS_TYPE_ELMFAT +#define BSP_RISCV_FPU_D #endif