Browse Source

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>
Du Huanpeng 5 years ago
parent
commit
cde1e5d940
2 changed files with 138 additions and 0 deletions
  1. 136 0
      bsp/ls2kdev/drivers/drv_pwm.c
  2. 2 0
      bsp/ls2kdev/drivers/ls2k1000.h

+ 136 - 0
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 <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*/

+ 2 - 0
bsp/ls2kdev/drivers/ls2k1000.h

@@ -22,6 +22,8 @@
 #define PLL_SYS_BASE 0xFFFFFFFFBFE10480
 #define PLL_SYS_BASE 0xFFFFFFFFBFE10480
 #define RTC_BASE 0xFFFFFFFFBFE07820
 #define RTC_BASE 0xFFFFFFFFBFE07820
 
 
+#define GEN_CONFIG0_REG 0xFFFFFFFFBfe10420
+
 void rt_hw_timer_handler(void);
 void rt_hw_timer_handler(void);
 void rt_hw_uart_init(void);
 void rt_hw_uart_init(void);