diff --git a/bsp/ls2kdev/drivers/drv_pwm.c b/bsp/ls2kdev/drivers/drv_pwm.c new file mode 100644 index 00000000000..f703d7834aa --- /dev/null +++ b/bsp/ls2kdev/drivers/drv_pwm.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright(c) 2020, Du Huanpeng<548708880@qq.com> + * + */ + +#include +#include +#include + +#ifdef RT_USING_PWM + +#define PWM0_BASE (0xFFFFFFFFBFe02000) +#define PWM1_BASE (0xFFFFFFFFBFe02010) +#define PWM2_BASE (0xFFFFFFFFBFe02020) +#define PWM3_BASE (0xFFFFFFFFBFe02030) + +#define CTRL_EN (1UL<<0) +#define CTRL_OE (1UL<<3) +#define CTRL_SINGL (1UL<<4) +#define CTRL_INTE (1UL<<5) +#define CTRL_INT (1UL<<6) +#define CTRL_RST (1UL<<7) +#define CTRL_CAPTE (1UL<<8) +#define CTRL_INVERT (1UL<<9) +#define CTRL_DZONE (1UL<<10) + +struct loongson_pwm { + rt_uint32_t __PAD0; + rt_uint32_t low_buffer; + rt_uint32_t full_buffer; + rt_uint32_t ctrl; +}; + +rt_err_t loongson_pwm_enable(struct rt_device_pwm *device, int channel) +{ + int **priv; + struct loongson_pwm *chip; + volatile rt_uint64_t *config0; + rt_uint64_t m; + + channel %= 4; + + config0 = (void *)GEN_CONFIG0_REG; + m = 1ULL << 12 << channel; + *config0 |= m; + + priv = device->parent.user_data; + chip = (void *)priv[channel]; + chip->ctrl = CTRL_EN; + + return RT_EOK; +} + +rt_err_t loongson_pwm_disable(struct rt_device_pwm *device, int channel) +{ + struct loongson_pwm **chip; + rt_uint64_t m; + + chip = device->parent.user_data; + channel %= 4; + chip[channel]->ctrl &= ~CTRL_EN; + + return RT_EOK; +} + +rt_err_t loongson_pwm_set(struct rt_device_pwm *device, int channel, rt_uint32_t period, rt_uint32_t pulse) +{ + struct loongson_pwm *chip; + rt_uint32_t **priv; + + priv = device->parent.user_data; + channel %= 4; + chip = (void *)priv[channel]; + + chip->ctrl &= ~CTRL_EN; + chip->full_buffer = period; + chip->low_buffer = pulse; + chip->ctrl |= CTRL_EN; + + return RT_EOK; +} + +static rt_err_t loongson_pwm_ioctl(struct rt_device_pwm *device, int cmd, void *arg) +{ + rt_err_t rc; + struct rt_pwm_configuration *cfg; + + cfg = (void *)arg; + + switch (cmd) { + case PWM_CMD_ENABLE: + rc = loongson_pwm_enable(device, cfg->channel); + break; + case PWM_CMD_DISABLE: + rc = loongson_pwm_disable(device, cfg->channel); + break; + case PWM_CMD_SET: + rc = loongson_pwm_set(device, cfg->channel, cfg->period, cfg->pulse); + break; + case PWM_CMD_GET: + rc = RT_ENOSYS; + break; + default: + rc = RT_EINVAL; + break; + } + return rc; +} + +struct rt_pwm_ops loongson_pwm_ops = { + .control = loongson_pwm_ioctl, +}; + +struct rt_device_pwm loongson_pwm = { + .ops = &loongson_pwm_ops, +}; + +int loongson_pwm_init(void) +{ + int rc = RT_EOK; + static rt_uint32_t *priv[] = { + (void *)PWM0_BASE, + (void *)PWM1_BASE, + (void *)PWM2_BASE, + (void *)PWM3_BASE + }; + rc = rt_device_pwm_register(&loongson_pwm, "pwm0", &loongson_pwm_ops, &priv); + return rc; +} +INIT_DEVICE_EXPORT(loongson_pwm_init); + +#endif /*RT_USING_PWM*/ diff --git a/bsp/ls2kdev/drivers/ls2k1000.h b/bsp/ls2kdev/drivers/ls2k1000.h index 40c0496ba9c..24396e7d3b9 100644 --- a/bsp/ls2kdev/drivers/ls2k1000.h +++ b/bsp/ls2kdev/drivers/ls2k1000.h @@ -22,6 +22,8 @@ #define PLL_SYS_BASE 0xFFFFFFFFBFE10480 #define RTC_BASE 0xFFFFFFFFBFE07820 +#define GEN_CONFIG0_REG 0xFFFFFFFFBfe10420 + void rt_hw_timer_handler(void); void rt_hw_uart_init(void);