diff --git a/bsp/cvitek/c906_little/board/Kconfig b/bsp/cvitek/c906_little/board/Kconfig index 3e0bc027c8..689cc4285d 100755 --- a/bsp/cvitek/c906_little/board/Kconfig +++ b/bsp/cvitek/c906_little/board/Kconfig @@ -40,9 +40,31 @@ menu "General Drivers Configuration" default 32 endif - menuconfig BSP_USING_ADC + config BSP_USING_ADC bool "Using ADC" select RT_USING_ADC default n + menuconfig BSP_USING_PWM + bool "Using PWM" + select RT_USING_PWM + default n + + if BSP_USING_PWM + config BSP_USING_PWM0 + bool "Enable PWM 0" + default n + + config BSP_USING_PWM1 + bool "Enable PWM 1" + default n + + config BSP_USING_PWM2 + bool "Enable PWM 2" + default n + + config BSP_USING_PWM3 + bool "Enable PWM 3" + default n + endif endmenu diff --git a/bsp/cvitek/cv1800b/board/Kconfig b/bsp/cvitek/cv1800b/board/Kconfig index a5305cbd24..82f7886f09 100755 --- a/bsp/cvitek/cv1800b/board/Kconfig +++ b/bsp/cvitek/cv1800b/board/Kconfig @@ -32,9 +32,33 @@ menu "General Drivers Configuration" endif - menuconfig BSP_USING_ADC + config BSP_USING_ADC bool "Using ADC" select RT_USING_ADC default n + menuconfig BSP_USING_PWM + bool "Using PWM" + select RT_USING_PWM + default n + + if BSP_USING_PWM + config BSP_USING_PWM0 + bool "Enable PWM 0" + default n + + config BSP_USING_PWM1 + bool "Enable PWM 1" + default n + + config BSP_USING_PWM2 + bool "Enable PWM 2" + default n + + config BSP_USING_PWM3 + bool "Enable PWM 3" + default n + + endif + endmenu diff --git a/bsp/cvitek/drivers/SConscript b/bsp/cvitek/drivers/SConscript index 0fa4fa9c54..9f342e1385 100755 --- a/bsp/cvitek/drivers/SConscript +++ b/bsp/cvitek/drivers/SConscript @@ -18,6 +18,9 @@ if GetDepend('BSP_USING_I2C'): if GetDepend('BSP_USING_ADC'): src += ['drv_adc.c'] +if GetDepend('BSP_USING_PWM'): + src += ['drv_pwm.c'] + CPPPATH += [cwd + r'/cv1800b/pwm'] CPPDEFINES += ['-DCONFIG_64BIT'] group = DefineGroup('drivers', src, depend = [''], CPPDEFINES = CPPDEFINES, CPPPATH = CPPPATH) diff --git a/bsp/cvitek/drivers/cv1800b/pwm/cvi_pwm.h b/bsp/cvitek/drivers/cv1800b/pwm/cvi_pwm.h new file mode 100644 index 0000000000..27d49df1a3 --- /dev/null +++ b/bsp/cvitek/drivers/cv1800b/pwm/cvi_pwm.h @@ -0,0 +1,266 @@ +#ifndef __CVI_PWM_H__ +#define __CVI_PWM_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +#define CVI_PWM0_BASE 0x03060000 +#define CVI_PWM1_BASE 0x03061000 +#define CVI_PWM2_BASE 0x03062000 +#define CVI_PWM3_BASE 0x03063000 + +typedef enum { + PWM_CHANNEL_0 = 0U, + PWM_CHANNEL_1, + PWM_CHANNEL_2, + PWM_CHANNEL_3, + PWM_CHANNEL_4, + PWM_CHANNEL_5, + PWM_CHANNEL_6, + PWM_CHANNEL_7, + PWM_CHANNEL_8, + PWM_CHANNEL_9, + PWM_CHANNEL_10, + PWM_CHANNEL_11, + PWM_CHANNEL_12, + PWM_CHANNEL_13, + PWM_CHANNEL_14, + PWM_CHANNEL_15, + PWM_CHANNEL_NUM +} cvi_pwm_channel_t; + + +struct cvi_pwm_regs_t { + uint32_t HLPERIOD0; + uint32_t PERIOD0; + uint32_t HLPERIOD1; + uint32_t PERIOD1; + uint32_t HLPERIOD2; + uint32_t PERIOD2; + uint32_t HLPERIOD3; + uint32_t PERIOD3; + uint32_t CAP_FREQNUM; + uint32_t CAP_FREQDATA; + uint32_t POLARITY; + uint32_t PWMSTART; + uint32_t PWMDONE; + uint32_t PWMUPDATE; + uint32_t PCOUNT0; + uint32_t PCOUNT1; + uint32_t PCOUNT2; + uint32_t PCOUNT3; + uint32_t PULSECOUNT0; + uint32_t PULSECOUNT1; + uint32_t PULSECOUNT2; + uint32_t PULSECOUNT3; + uint32_t SHIFTCOUNT0; + uint32_t SHIFTCOUNT1; + uint32_t SHIFTCOUNT2; + uint32_t SHIFTCOUNT3; + uint32_t SHIFTSTART; + uint32_t CAP_FREQEN; + uint32_t CAP_FREQDONE_NUM; + uint32_t PWM_OE; +}; + + +static struct cvi_pwm_regs_t cv182x_pwm_reg = { + .HLPERIOD0 = 0x0, + .PERIOD0 = 0x4, + .HLPERIOD1 = 0x8, + .PERIOD1 = 0xc, + .HLPERIOD2 = 0x10, + .PERIOD2 = 0x14, + .HLPERIOD3 = 0x18, + .PERIOD3 = 0x1c, + .CAP_FREQNUM = 0x20, + .CAP_FREQDATA = 0x24, + .POLARITY = 0x40, + .PWMSTART = 0x44, + .PWMDONE = 0x48, + .PWMUPDATE = 0x4c, + .PCOUNT0 = 0x50, + .PCOUNT1 = 0x54, + .PCOUNT2 = 0x58, + .PCOUNT3 = 0x5c, + .PULSECOUNT0 = 0x60, + .PULSECOUNT1 = 0x64, + .PULSECOUNT2 = 0x68, + .PULSECOUNT3 = 0x6c, + .SHIFTCOUNT0 = 0x80, + .SHIFTCOUNT1 = 0x84, + .SHIFTCOUNT2 = 0x88, + .SHIFTCOUNT3 = 0x8c, + .SHIFTSTART = 0x90, + .CAP_FREQEN = 0x9c, + .CAP_FREQDONE_NUM = 0xC0, + .PWM_OE = 0xd0, +}; + +static struct cvi_pwm_regs_t *cvi_pwm_reg = &cv182x_pwm_reg; + +#define PWM_HLPERIOD0(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->HLPERIOD0)) +#define PWM_PERIOD0(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PERIOD0)) +#define PWM_HLPERIOD1(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->HLPERIOD1)) +#define PWM_PERIOD1(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PERIOD1)) +#define PWM_HLPERIOD2(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->HLPERIOD2)) +#define PWM_PERIOD2(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PERIOD2)) +#define PWM_HLPERIOD3(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->HLPERIOD3)) +#define PWM_PERIOD3(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PERIOD3)) +#define PWM_HLPERIODX(reg_base, _ch_) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->HLPERIOD0 + (_ch_ << 3))) +#define PWM_PERIODX(reg_base, _ch_) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PERIOD0 * (1 + (_ch_ << 1)))) + +#define CAP_FREQNUM(reg_base, _ch_) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->CAP_FREQNUM + _ch_ * 8)) +#define CAP_FREQDATA(reg_base, _ch_) *((__IM uint32_t *)(reg_base + cvi_pwm_reg->CAP_FREQDATA + _ch_ * 8)) + +#define PWM_POLARITY(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->POLARITY)) +#define PWM_PWMSTART(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PWMSTART)) +#define PWM_PWMDONE(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PWMDONE)) +#define PWM_PWMUPDATE(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PWMUPDATE)) + +#define PWM_PCOUNT0(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PCOUNT0)) +#define PWM_PCOUNT1(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PCOUNT1)) +#define PWM_PCOUNT2(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PCOUNT2)) +#define PWM_PCOUNT3(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PCOUNT3)) + +#define PWM_PULSECOUNT0(reg_base) *((__IM uint32_t *)(reg_base + cvi_pwm_reg->PULSECOUNT0)) +#define PWM_PULSECOUNT1(reg_base) *((__IM uint32_t *)(reg_base + cvi_pwm_reg->PULSECOUNT1)) +#define PWM_PULSECOUNT2(reg_base) *((__IM uint32_t *)(reg_base + cvi_pwm_reg->PULSECOUNT2)) +#define PWM_PULSECOUNT3(reg_base) *((__IM uint32_t *)(reg_base + cvi_pwm_reg->PULSECOUNT3)) + +#define PWM_SHIFTCOUNT0(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->SHIFTCOUNT0)) +#define PWM_SHIFTCOUNT1(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->SHIFTCOUNT1)) +#define PWM_SHIFTCOUNT2(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->SHIFTCOUNT2)) +#define PWM_SHIFTCOUNT3(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->SHIFTCOUNT3)) +#define PWM_SHIFTSTART(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->SHIFTSTART)) + +#define CAP_FREQEN(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->CAP_FREQEN)) +#define CAP_FREQDONE_NUM(reg_base, _ch_) *((__IM uint32_t *)(reg_base + cvi_pwm_reg->CAP_FREQDONE_NUM + _ch_ * 4)) + +#define PWM_PWM_OE(reg_base) *((__IOM uint32_t *)(reg_base + cvi_pwm_reg->PWM_OE)) + + +/*! PWM Configure Register, offset: 0x00 */ +#define CVI_PWM_HIGH_PERIOD_Pos (0U) +#define CVI_PWM_HIGH_PERIOD_Msk (0xffffffff) + +#define CVI_PWM_PERIOD_Pos (0U) +#define CVI_PWM_PERIOD_Msk (0xffffffff) + +#define CVI_PWM_POLARITY_CH_Pos(_ch_) (_ch_) +#define CVI_PWM_POLARITY_CH_Msk(_ch_) (1U << CVI_PWM_POLARITY_CH_Pos(_ch_)) +#define CVI_PWM_POLARITY_CH_HIGH(_ch_) CVI_PWM_POLARITY_CH_Msk(_ch_) + +#define CVI_PWM_START_CH_Pos(_ch_) (_ch_) +#define CVI_PWM_START_CH_Msk(_ch_) (1U << CVI_PWM_START_CH_Pos(_ch_)) +#define CVI_PWM_START_CH_EN(_ch_) CVI_PWM_START_CH_Msk(_ch_) + +#define CVI_PWM_OUTPUT_CH_Pos(_ch_) (_ch_) +#define CVI_PWM_OUTPUT_CH_Msk(_ch_) (1U << CVI_PWM_OUTPUT_CH_Pos(_ch_)) +#define CVI_PWM_OUTPUT_CH_EN(_ch_) CVI_PWM_OUTPUT_CH_Msk(_ch_) + +#define CVI_CAP_FREQNUM_CH_Pos (0U) +#define CVI_CAP_FREQNUM_CH_Msk (0xffffffff) + +#define CVI_CAP_FREQEN_Pos(_ch_) (_ch_) +#define CVI_CAP_FREQEN_Msk(_ch_) (1U << CVI_CAP_FREQEN_Pos(_ch_)) +#define CVI_CAP_FREQEN(_ch_) CVI_CAP_FREQEN_Msk(_ch_) + +#define CVI_CAP_FREQDONE_NUM_Poa (0U) +#define CVI_CAP_FREQDONE_NUM_Msk (0xffffffff) + +#define CVI_CAP_FREQDATA_pos (0U) +#define CVI_CAP_FREQDATA_msk (0xffffffff) + +static inline void cvi_pwm_set_high_period_ch(unsigned long reg_base, uint32_t ch, unsigned long long value) +{ + PWM_HLPERIODX(reg_base, ch) = value; +} + +static inline unsigned long long cvi_pwm_get_high_period_ch(unsigned long reg_base, uint32_t ch) +{ + return PWM_HLPERIODX(reg_base, ch); +} + +static inline void cvi_pwm_set_period_ch(unsigned long reg_base, uint32_t ch, unsigned long long value) +{ + PWM_PERIODX(reg_base, ch) = value; +} + +static inline unsigned long long cvi_pwm_get_period_ch(unsigned long reg_base, uint32_t ch) +{ + return PWM_PERIODX(reg_base, ch); +} + +static inline void cvi_pwm_set_polarity_high_ch(unsigned long reg_base, uint32_t ch) +{ + PWM_POLARITY(reg_base) |= CVI_PWM_POLARITY_CH_HIGH(ch); +} + +static inline void cvi_pwm_set_polarity_low_ch(unsigned long reg_base, uint32_t ch) +{ + PWM_POLARITY(reg_base) &= ~CVI_PWM_POLARITY_CH_HIGH(ch); +} + +static inline uint32_t cvi_pwm_get_polarity(unsigned long reg_base, uint32_t ch) +{ + return (PWM_POLARITY(reg_base) & CVI_PWM_POLARITY_CH_Msk(ch)); +} + +static inline void cvi_pwm_start_en_ch(unsigned long reg_base, uint32_t ch) +{ + PWM_PWMSTART(reg_base) |= CVI_PWM_START_CH_EN(ch); +} + +static inline void cvi_pwm_start_dis_ch(unsigned long reg_base, uint32_t ch) +{ + PWM_PWMSTART(reg_base) &= ~CVI_PWM_START_CH_EN(ch); +} + +static inline void cvi_pwm_output_en_ch(unsigned long reg_base, uint32_t ch) +{ + PWM_PWM_OE(reg_base) |= CVI_PWM_OUTPUT_CH_EN(ch); +} + +static inline void cvi_pwm_input_en_ch(unsigned long reg_base, uint32_t ch) +{ + PWM_PWM_OE(reg_base) &= ~CVI_PWM_OUTPUT_CH_EN(ch); +} + +static inline void cvi_cap_set_freqnum_ch(unsigned long reg_base, uint32_t ch, uint32_t value) +{ + CAP_FREQNUM(reg_base, ch) = value; +} + +static inline void cvi_cap_freq_en_ch(unsigned long reg_base, uint32_t ch) +{ + CAP_FREQEN(reg_base) |= CVI_CAP_FREQEN(ch); +} + +static inline void cvi_cap_freq_dis_ch(unsigned long reg_base, uint32_t ch) +{ + CAP_FREQEN(reg_base) &= ~CVI_CAP_FREQEN(ch); +} + +static inline uint32_t cvi_cap_get_freq_done_num_ch(unsigned long reg_base, uint32_t ch) +{ + return CAP_FREQDONE_NUM(reg_base, ch); +} + +static inline uint32_t cvi_cap_get_freq_data_ch(unsigned long reg_base, uint32_t ch) +{ + return CAP_FREQDATA(reg_base, ch); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/cvitek/drivers/drv_pwm.c b/bsp/cvitek/drivers/drv_pwm.c new file mode 100644 index 0000000000..98db8d8eeb --- /dev/null +++ b/bsp/cvitek/drivers/drv_pwm.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024/02/19 flyingcys first version + */ +#include +#include +#include "drv_pwm.h" + +#ifdef BSP_USING_PWM + +#define DBG_LEVEL DBG_LOG +#include +#define LOG_TAG "DRV.PWM" + +struct cvi_pwm_dev +{ + struct rt_device_pwm device; + const char *name; + rt_ubase_t reg_base; +}; + +static const uint64_t count_unit = 100000000; // 100M count per second +static const uint64_t NSEC_COUNT = 1000000000; // ns + +static void cvi_pwm_set_config(rt_ubase_t reg_base, struct rt_pwm_configuration *cfg) +{ + unsigned long long duty_clk, period_clk; + + cvi_pwm_set_polarity_low_ch(reg_base, (cfg->channel & PWM_MAX_CH)); + + duty_clk = (cfg->pulse * count_unit) / NSEC_COUNT; + cvi_pwm_set_high_period_ch(reg_base, (cfg->channel & PWM_MAX_CH), duty_clk); + + period_clk = (cfg->period * count_unit) / NSEC_COUNT; + cvi_pwm_set_period_ch(reg_base, (cfg->channel & PWM_MAX_CH), period_clk); + + cvi_pwm_output_en_ch(reg_base, cfg->channel & PWM_MAX_CH); +} + +static void cvi_pwm_get_config(rt_ubase_t reg_base, struct rt_pwm_configuration *cfg) +{ + unsigned long long duty_clk, period_clk; + + duty_clk = cvi_pwm_get_high_period_ch(reg_base, (cfg->channel & PWM_MAX_CH)); + cfg->pulse = duty_clk * NSEC_COUNT / count_unit; + + period_clk = cvi_pwm_get_period_ch(reg_base, (cfg->channel & PWM_MAX_CH)); + cfg->period = period_clk * NSEC_COUNT / count_unit; +} +static rt_err_t _pwm_control(struct rt_device_pwm *device, int cmd, void *arg) +{ + struct rt_pwm_configuration *cfg = (struct rt_pwm_configuration *)arg; + struct cvi_pwm_dev *pwm_dev = (struct cvi_pwm_dev *)device->parent.user_data; + unsigned long long duty_clk, period_clk; + const uint64_t count_unit = 100000000; // 100M count per second + const uint64_t NSEC_COUNT = 1000000000; // ns + + if (cfg->channel > PWM_MAX_CH) + return -RT_EINVAL; + + switch (cmd) + { + case PWM_CMD_ENABLE: + cvi_pwm_start_en_ch(pwm_dev->reg_base, cfg->channel & PWM_MAX_CH); + break; + + case PWM_CMD_DISABLE: + cvi_pwm_start_dis_ch(pwm_dev->reg_base, cfg->channel & PWM_MAX_CH); + break; + + case PWM_CMD_SET: + cvi_pwm_set_config(pwm_dev->reg_base, cfg); + break; + + case PWM_CMD_GET: + cvi_pwm_get_config(pwm_dev->reg_base, cfg); + break; + + case PWM_CMD_SET_PERIOD: + period_clk = (cfg->period * count_unit) / NSEC_COUNT; + cvi_pwm_set_period_ch(pwm_dev->reg_base, (cfg->channel & PWM_MAX_CH), period_clk); + break; + + case PWM_CMD_SET_PULSE: + duty_clk = (cfg->pulse * count_unit) / NSEC_COUNT; + cvi_pwm_set_high_period_ch(pwm_dev->reg_base, (cfg->channel & PWM_MAX_CH), duty_clk); + break; + + default: + LOG_D("cmd: %x channel: %d period: %d pulse: %d", cmd, cfg->channel, cfg->period, cfg->pulse); + break; + } + + return RT_EOK; +} + +const static struct rt_pwm_ops cvi_pwm_ops = +{ + .control = &_pwm_control +}; + +static struct cvi_pwm_dev cvi_pwm[] = +{ +#ifdef BSP_USING_PWM0 + { + .name = "pwm0", + .reg_base = CVI_PWM0_BASE, + }, +#endif + +#ifdef BSP_USING_PWM1 + { + .name = "pwm1", + .reg_base = CVI_PWM1_BASE, + }, +#endif + +#ifdef BSP_USING_PWM2 + { + .name = "pwm2", + .reg_base = CVI_PWM2_BASE, + }, +#endif + +#ifdef BSP_USING_PWM3 + { + .name = "pwm3", + .reg_base = CVI_PWM3_BASE, + }, +#endif +}; + +int rt_hw_pwm_init(void) +{ + int result = RT_EOK; + uint8_t i; + + for (i = 0; i < sizeof(cvi_pwm) / sizeof(cvi_pwm[0]); i++) + { + result = rt_device_pwm_register(&cvi_pwm[i].device, cvi_pwm[i].name, &cvi_pwm_ops, &cvi_pwm[i]); + if (result != RT_EOK) + { + LOG_E("device %s register failed", cvi_pwm[i].name); + return -RT_ERROR; + } + } + return RT_EOK; +#if 0 +#ifdef BSP_USING_PWM0 + static struct cvi_pwm_dev cvi_pwm0; + + cvi_pwm0.name = "pwm0"; + cvi_pwm0.reg_base = CVI_PWM0_BASE; + + result = rt_device_pwm_register(&cvi_pwm0.device, cvi_pwm0.name, &cvi_pwm_ops, &cvi_pwm0); + if (result != RT_EOK) + { + LOG_E("device %s register failed.", cvi_pwm0.name); + return result; + } +#endif + +#ifdef BSP_USING_PWM1 + static struct cvi_pwm_dev cvi_pwm1; + cvi_pwm1.name = "pwm1"; + cvi_pwm1.reg_base = CVI_PWM1_BASE; + + result = rt_device_pwm_register(&cvi_pwm1.device, cvi_pwm1.name, &cvi_pwm_ops, &cvi_pwm1); + if (result != RT_EOK) + { + LOG_E("device %s register failed.", cvi_pwm1.name); + return result; + } +#endif + +#ifdef BSP_USING_PWM2 + static struct cvi_pwm_dev cvi_pwm2; + cvi_pwm2.name = "pwm2"; + cvi_pwm2.reg_base = CVI_PWM2_BASE; + + result = rt_device_pwm_register(&cvi_pwm2.device, cvi_pwm2.name, &cvi_pwm_ops, &cvi_pwm2); + if (result != RT_EOK) + { + LOG_E("device %s register failed.", cvi_pwm2.name); + return result; + } +#endif + +#ifdef BSP_USING_PWM3 + static struct cvi_pwm_dev cvi_pwm3; + cvi_pwm3.name = "pwm3"; + cvi_pwm3.reg_base = CVI_PWM3_BASE; + + result = rt_device_pwm_register(&cvi_pwm3.device, cvi_pwm3.name, &cvi_pwm_ops, &cvi_pwm3); + if (result != RT_EOK) + { + LOG_E("device %s register failed.", cvi_pwm3.name); + return result; + } +#endif + + return RT_EOK; +#endif +} +INIT_BOARD_EXPORT(rt_hw_pwm_init); + +#endif /* BSP_USING_PWM */ diff --git a/bsp/cvitek/drivers/drv_pwm.h b/bsp/cvitek/drivers/drv_pwm.h new file mode 100755 index 0000000000..379bd3f17e --- /dev/null +++ b/bsp/cvitek/drivers/drv_pwm.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024/02/19 flyingcys first version + */ +#ifndef __DRV_PWM_H__ +#define __DRV_PWM_H__ + +#include "cvi_pwm.h" + +#define PWM_MAX_CH 3 + +int rt_hw_pwm_init(void); + +#endif /* __DRV_PWM_H__ */