Просмотр исходного кода

fix: air640w支持pwm https://gitee.com/openLuat/LuatOS/issues/I2777Z

Wendal Chen 5 лет назад
Родитель
Сommit
dd533b4a00

+ 27 - 0
bsp/air640w/demo/14.pwm/main.lua

@@ -0,0 +1,27 @@
+
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "pwmdemo"
+VERSION = "1.0.0"
+
+-- 引入必要的库文件(lua编写), 内部库不需要require
+local sys = require "sys"
+
+log.info("main", "hello world")
+
+print(_VERSION)
+
+-- Air640w的固件,在2020-11-27开始支持PWM,之前的版本不带PWM
+-- W600规格书 http://www.winnermicro.com/upload/1/editor/1594026750682.pdf
+--[[
+    // PWM4 --> PB8      channel 5
+    // PWM3 --> PB15     channel 4
+    // PWM1 --> PA1      channel 2
+    // PWM0 --> PA0      channel 1
+]]
+-- 注意PWM4的channel值是5, 对应PB8
+pwm.open(5, 1000, 50)
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 28 - 0
bsp/air640w/rtt/drivers/drv_pwm.c

@@ -115,6 +115,34 @@ static rt_err_t wm_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
     if (channel > 4)
         return RT_EINVAL;
 
+    //----------------------------------------------
+    // PWM4 --> PB8
+    // PWM3 --> PB15
+    // PWM1 --> PA1
+    // PWM0 --> PA0
+    if (channel == 2) {
+            return RT_EINVAL;
+    }
+    if (cmd == PWM_CMD_SET) {
+        switch (channel)
+        {
+        case 0:
+            wm_pwm1_config(WM_IO_PA_00);
+            break;
+        case 1:
+            wm_pwm2_config(WM_IO_PA_01);
+            break;
+        case 3:
+            wm_pwm4_config(WM_IO_PB_15);
+            break;
+        case 4:
+            wm_pwm5_config(WM_IO_PB_08);
+            break;
+        }
+    }
+
+    //----------------------------------------------
+
     switch (cmd)
     {
     case PWM_CMD_ENABLE:

+ 2 - 2
bsp/air640w/rtt/drivers/pin_config.h

@@ -43,8 +43,8 @@
 
 // soft i2c
 #ifdef SOC_W600_A8xx
-    #define SOFT_I2C1_SCL_PIN 18         // PA13 : I2C1_SCL
-    #define SOFT_I2C1_SDA_PIN 19         // PA14 : I2C1_SDA
+    #define SOFT_I2C1_SCL_PIN 18         // PB13 : I2C1_SCL
+    #define SOFT_I2C1_SDA_PIN 19         // PB14 : I2C1_SDA
     #define SOFT_I2C2_SCL_PIN 25         // PA2 : I2C2_SCL
     #define SOFT_I2C2_SDA_PIN 24         // PA1 : I2C2_SDA
 #else

+ 16 - 8
luat/rtt/luat_pwm_rtt.c

@@ -2,15 +2,13 @@
 #include "luat_base.h"
 #include "luat_pwm.h"
 
-#include "luat_log.h"
 
 #include "rtthread.h"
 #include "rthw.h"
 #include "rtdevice.h"
 
-#define DBG_TAG           "luat.pwm"
-#define DBG_LVL           DBG_WARN
-#include <rtdbg.h>
+#define LUAT_LOG_TAG "rtt.pwm"
+#include "luat_log.h"
 
 #ifdef RT_USING_PWM
 
@@ -32,14 +30,16 @@ static int luat_pwm_rtt_init() {
     {
         name[3] = '0' + i;
         pwm_devs[i] = (struct rt_device_pwm *)rt_device_find(name);
-        LOG_D("search pwm name=%s ptr=0x%08X", name, pwm_devs[i]);
+        if (pwm_devs[i])
+            LLOGD("found pwm name=%s ptr=0x%08X", name, pwm_devs[i]);
     }
     // 看看有没有pwm
     if (pwm_devs[0] == RT_NULL) {
         pwm_devs[0] = (struct rt_device_pwm *)rt_device_find("pwm");
-        LOG_D("search pwm name=%s ptr=0x%08X", "pwm", pwm_devs[0]);
+        if (pwm_devs[0])
+            LLOGD("found pwm name=%s ptr=0x%08X", "pwm", pwm_devs[0]);
     }
-		return 0;
+	return 0;
 }
 
 INIT_COMPONENT_EXPORT(luat_pwm_rtt_init);
@@ -67,12 +67,20 @@ int luat_pwm_open(int channel, size_t period, size_t pulse) {
     int n = channel - (i * 10);
     if (i < 0 || i >= DEVICE_ID_MAX )
         return -1;
+    if (period < 1 || period > 1000000)
+        return -1;
+    if (pulse > 100)
+        pulse = 100;
 
     struct rt_device_pwm *dev = pwm_devs[i];
     if(RT_NULL == dev)
         return -1;
+
+    // 与Luat的定义不同, rtt的period和pulse是按时长作为单位的,单位是ns,即1/1000000000秒
+    // rt_period = 1000000000 / luat_period
+    // rt_pulse = (1000000000 / luat_period) * pulse / 100
     
-    rt_pwm_set(dev, n, period, pulse);
+    rt_pwm_set(dev, n, 1000000000 / period, (1000000000 / period) * pulse / 100);
     rt_pwm_enable(dev, n);
 
     return 0;

+ 3 - 0
luat/rtt/luat_rtt_base.c

@@ -73,6 +73,9 @@ static const luaL_Reg loadedlibs[] = {
 #endif
 #ifdef RT_USING_HWCRYPTO
   {"crypto", luaopen_crypto},          // 加密和hash库
+#endif
+#ifdef RT_USING_PWM
+  {"pwm", luaopen_pwm},                //  PWM
 #endif
   {"fs",   luaopen_fs},                // 文件系统库
   {NULL, NULL}