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>
This commit is contained in:
Du Huanpeng 2020-07-03 15:54:03 +08:00
parent 4108836a90
commit cde1e5d940
2 changed files with 138 additions and 0 deletions

View File

@ -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 <rtthread.h>
#include <rtdevice.h>
#include <ls2k1000.h>
#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*/

View File

@ -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);