diff --git a/bsp/k230/.config b/bsp/k230/.config index c0107f79129..d385532be31 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 @@ -946,12 +950,44 @@ CONFIG_RT_USING_VDSO=y # # STM32 HAL & SDK Drivers # +# CONFIG_PKG_USING_STM32F0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F1_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F1_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F2_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F2_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F3_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F3_CMSIS_DRIVER is not set # CONFIG_PKG_USING_STM32F4_HAL_DRIVER is not set # CONFIG_PKG_USING_STM32F4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32F7_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32F7_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32G0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32G0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32G4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32G4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H5_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H7_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H7_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32H7RS_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32H7RS_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32L0_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L0_CMSIS_DRIVER is not set # CONFIG_PKG_USING_STM32L4_HAL_DRIVER is not set # CONFIG_PKG_USING_STM32L4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32L5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32L5_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32U5_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32U5_CMSIS_DRIVER is not set # CONFIG_PKG_USING_STM32WB55_SDK is not set # CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_STM32WL_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32WL_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32WB_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32WB_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_STM32MP1_M4_HAL_DRIVER is not set +# CONFIG_PKG_USING_STM32MP1_M4_CMSIS_DRIVER is not set # end of STM32 HAL & SDK Drivers # @@ -984,6 +1020,60 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_NRFX is not set # CONFIG_PKG_USING_NUCLEI_SDK is not set # CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_MM32 is not set + +# +# WCH HAL & SDK Drivers +# +# CONFIG_PKG_USING_CH32V20x_SDK is not set +# CONFIG_PKG_USING_CH32V307_SDK is not set +# end of WCH HAL & SDK Drivers + +# +# AT32 HAL & SDK Drivers +# +# CONFIG_PKG_USING_AT32A403A_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32A403A_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32A423_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32A423_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F45x_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F45x_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F402_405_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F402_405_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F403A_407_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F403A_407_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F413_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F413_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F415_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F415_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F421_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F421_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F423_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F423_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F425_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F425_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32F435_437_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32F435_437_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_AT32M412_416_HAL_DRIVER is not set +# CONFIG_PKG_USING_AT32M412_416_CMSIS_DRIVER is not set +# end of AT32 HAL & SDK Drivers + +# +# HC32 DDL Drivers +# +# end of HC32 DDL Drivers + +# +# NXP HAL & SDK Drivers +# +# CONFIG_PKG_USING_NXP_MCX_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_NXP_MCX_SERIES_DRIVER is not set +# CONFIG_PKG_USING_NXP_LPC_DRIVER is not set +# CONFIG_PKG_USING_NXP_LPC55S_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMX6SX_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMX6UL_DRIVER is not set +# CONFIG_PKG_USING_NXP_IMXRT_DRIVER is not set +# end of NXP HAL & SDK Drivers # end of HAL & SDK Drivers # @@ -1021,12 +1111,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 +1147,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 +1240,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 +1259,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 +1336,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 +1347,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 +1591,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 +1604,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..4ad6ee4454a --- /dev/null +++ b/bsp/k230/drivers/interdrv/pwm/drv_pwm.c @@ -0,0 +1,243 @@ +/* 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 + * + * Note: + * The K230 PWM controller has 4 hardware channels: + * - Channel 0 (pwmcmp0) is used to set the period and does not generate output. + * - Channels 1 to 3 (pwmcmp1~3) are used to control the duty cycle and produce output signals. + * Therefore, the driver maps these output channels (1~3) as logical channels 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; +}; + +static struct k230_pwm_dev pwm_devs[] = { +#ifdef BSP_USING_PWM0 + { + .name = "pwm0", + .base = PWM0_BASE_ADDR, + }, +#endif + +#ifdef BSP_USING_PWM1 + { + .name = "pwm1", + .base = PWM1_BASE_ADDR, + }, +#endif + +#if !defined(BSP_USING_PWM0) && !defined(BSP_USING_PWM1) +#error "No pwm device defined!" +#endif +}; + +static int 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) +{ + rt_err_t ret; + ret = (rt_err_t)check_channel(channel); + if (ret < 0) + return ret; + reg->pwmcfg |= PWM_CFG_BIT_INVERT; /* default always mode */ + return RT_EOK; +} + +static rt_err_t pwm_stop(kd_pwm_t *reg, int channel) +{ + rt_err_t ret; + ret = (rt_err_t)check_channel(channel); + if (ret < 0) + return ret; + reg->pwmcfg &= ~PWM_CFG_BIT_INVERT; + + return RT_EOK; +} + +static rt_err_t kd_pwm_get(kd_pwm_t *reg, int 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; + int channel = 0; + int ret; + + struct k230_pwm_dev *pwm_dev = rt_container_of(device, struct k230_pwm_dev, device); + kd_pwm_t *reg = (kd_pwm_t *)pwm_dev->base; + 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) +{ + rt_err_t ret; + for (int i = 0; i < sizeof(pwm_devs)/sizeof(struct k230_pwm_dev); i++) + { + struct k230_pwm_dev *dev = &pwm_devs[i]; + dev->base = (rt_ubase_t)rt_ioremap((void *)(dev->base), sizeof(kd_pwm_t)); + ret = rt_device_pwm_register(&dev->device, dev->name, &drv_ops, RT_NULL); + if (ret != RT_EOK) + { + LOG_E("Failed to register PWM device %s, error code: %d\n", dev->name, ret); + return ret; + } + } + 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..c76d5d61dda --- /dev/null +++ b/bsp/k230/drivers/interdrv/pwm/drv_pwm.h @@ -0,0 +1,88 @@ +/* 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 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..61e04da5614 100644 --- a/bsp/k230/drivers/utest/SConscript +++ b/bsp/k230/drivers/utest/SConscript @@ -15,6 +15,9 @@ 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') +Return('group') \ No newline at end of file diff --git a/bsp/k230/drivers/utest/test_pwm.c b/bsp/k230/drivers/utest/test_pwm.c new file mode 100644 index 00000000000..8d9be04af63 --- /dev/null +++ b/bsp/k230/drivers/utest/test_pwm.c @@ -0,0 +1,120 @@ +/* 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) +{ + LOG_I("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); + LOG_I("pwm test start.\n"); + struct rt_device_pwm *pwm_dev; /* PWM设备句柄 */ + rt_uint32_t period; /* 周期, 单位为纳秒ns */ + rt_uint32_t pulse; /* PWM脉冲宽度值, 单位为纳秒ns */ + rt_err_t ret; + /* 查找设备 */ + 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) + { + ret = rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse); + uassert_int_equal(ret, RT_EOK); + ret = rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL); + uassert_int_equal(ret, RT_EOK); + sleep(2); + } + ret = rt_pwm_disable(pwm_dev, PWM_DEV_CHANNEL); + uassert_int_equal(ret, RT_EOK); +} + +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..386e7089efa 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 @@ -476,6 +478,22 @@ /* Kendryte SDK */ /* end of Kendryte SDK */ + +/* WCH HAL & SDK Drivers */ + +/* end of WCH HAL & SDK Drivers */ + +/* AT32 HAL & SDK Drivers */ + +/* end of AT32 HAL & SDK Drivers */ + +/* HC32 DDL Drivers */ + +/* end of HC32 DDL Drivers */ + +/* NXP HAL & SDK Drivers */ + +/* end of NXP HAL & SDK Drivers */ /* end of HAL & SDK Drivers */ /* sensors drivers */ @@ -565,8 +583,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