From cde1e5d940ee1caaeb6051e3a9941591338e41a9 Mon Sep 17 00:00:00 2001 From: Du Huanpeng <548708880@qq.com> Date: Fri, 3 Jul 2020 15:54:03 +0800 Subject: [PATCH] bsp: ls2k: pwm driver attach probe of the oscilloscope too the 3.3v & PWM3 like below: jack ------| |---| |-| |---- |o o 3.3v |eth1| |eth0| |o o |o o |o o PWM3 |o o type commands below to rt-thread console: msh /> pwm_enable pwm0 3 msh /> pwm_set pwm0 3 140 90 turn off pwm: msh /> pwm_disable pwm0 3 Signed-off-by: Du Huanpeng <548708880@qq.com> --- bsp/ls2kdev/drivers/drv_pwm.c | 136 +++++++++++++++++++++++++++++++++ bsp/ls2kdev/drivers/ls2k1000.h | 2 + 2 files changed, 138 insertions(+) create mode 100644 bsp/ls2kdev/drivers/drv_pwm.c 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);