mirror of https://github.com/RT-Thread/rt-thread
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>
This commit is contained in:
parent
95bd6854db
commit
c209173061
109
bsp/k230/.config
109
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
|
@ -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 <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include "riscv_io.h"
|
||||
#include "board.h"
|
||||
#include "ioremap.h"
|
||||
#include <rtdbg.h>
|
||||
#include <stdbool.h>
|
||||
#include "sysctl_clk.h"
|
||||
#include "drv_pwm.h"
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/**
|
||||
*
|
||||
* 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);
|
|
@ -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 <stdint.h>
|
||||
|
||||
#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
|
|
@ -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')
|
|
@ -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 <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <drivers/dev_pwm.h>
|
||||
#include "drv_pwm.h"
|
||||
#include "drv_pinctrl.h"
|
||||
#include <rtdbg.h>
|
||||
#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);
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue