Browse Source

add: airlink,gpio,获取电平,能跑,但当前实现的实时性不佳

Wendal Chen 9 months ago
parent
commit
3560b78d60

+ 15 - 2
components/airlink/src/driver/luat_airlink_drv_gpio.c

@@ -56,17 +56,20 @@ luat_rtos_semaphore_t g_drv_gpio_sem;
 uint64_t g_drv_gpio_input_level = 0;
 extern luat_airlink_dev_info_t g_airlink_ext_dev_info;
 int luat_airlink_drv_gpio_get(int pin, int* val) {
+    int ret = 0;
     if (pin >= 128) {
         pin -= 128;
     }
     if (pin >= 64) {
         LLOGE("invaild pin %d/%d", pin, pin + 128);
+        *val = 0;
         return 0;
     }
     uint32_t version;
     memcpy(&version, &g_airlink_ext_dev_info.wifi.version, 4);
     if (version < 9) {
         LLOGE("wifi version < 9, not support gpio.set");
+        *val = 0;
         return 0;
     }
     uint64_t seq_id = luat_airlink_get_next_cmd_id();
@@ -80,14 +83,24 @@ int luat_airlink_drv_gpio_get(int pin, int* val) {
     }
     if (g_drv_gpio_sem == NULL) {
         luat_rtos_semaphore_create(&g_drv_gpio_sem, 0);
+        luat_rtos_semaphore_take(g_drv_gpio_sem, 100);
     }
     memcpy(cmd->data, &seq_id, 8);
     uint8_t* data = cmd->data + 8;
     data[0] = (uint8_t)pin;
     item.cmd = cmd;
     luat_airlink_queue_send(LUAT_AIRLINK_QUEUE_CMD, &item);
-    luat_rtos_semaphore_take(g_drv_gpio_sem, 100);
-    return (g_drv_gpio_input_level >> pin) & 1;
+    // LLOGI("g_drv_gpio_sem take");
+    ret = luat_rtos_semaphore_take(g_drv_gpio_sem, 100);
+    // LLOGI("g_drv_gpio_sem take %d", ret);
+    uint64_t tmp = pin;
+    LLOGD("g_drv_gpio_input_level %d %08X", pin, g_drv_gpio_input_level);
+    LLOGD("g_drv_gpio_input_level %d is %d", pin, (g_drv_gpio_input_level >> tmp) & 1);
+    *val = (g_drv_gpio_input_level >> tmp) & 1;
+    if (ret) {
+        LLOGW("gpio.get timeout!! pin %d", pin);
+    }
+    return ret;
 }
 
 int luat_airlink_drv_gpio_driver_yhm27xx(uint32_t Pin, uint8_t ChipID, uint8_t RegAddress, uint8_t IsRead, uint8_t *Data) 

+ 21 - 12
components/airlink/src/exec/luat_airlink_cmd_exec_gpio.c

@@ -55,10 +55,10 @@ int luat_airlink_cmd_exec_gpio_set(luat_airlink_cmd_t* cmd, void* userdata) {
 }
 
 
-int luat_airlink_cmd_exec_gpio_get(luat_airlink_cmd_t* cmd, void* userdata) {
+int luat_airlink_cmd_exec_gpio_get(luat_airlink_cmd_t* reqcmd, void* userdata) {
     LLOGD("收到GPIO读取指令!!!");
     uint8_t params[10];
-    memcpy(params, cmd->data, 9);
+    memcpy(params, reqcmd->data, 9);
     if (params[0] >= 128) {
         params[0] -= 128;
     }
@@ -75,11 +75,16 @@ int luat_airlink_cmd_exec_gpio_get(luat_airlink_cmd_t* cmd, void* userdata) {
         return -101;
     }
     memcpy(cmd2->data, &seq_id, 8);
-    memcpy(cmd2->data + 8, cmd->data, 8);
+    memcpy(cmd2->data + 8, reqcmd->data, 8);
     uint8_t* data = cmd2->data + 16;
     data[0] = (uint8_t)params[8];
     data[1] = (uint8_t)params[9];
-    item.cmd = cmd;
+    item.cmd = cmd2;
+    LLOGD("发送回复 %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X",
+        cmd2->data[0],  cmd2->data[1], cmd2->data[2], cmd2->data[3],  cmd2->data[4],  cmd2->data[5],  cmd2->data[6],  cmd2->data[7],
+        cmd2->data[8],  cmd2->data[9], cmd2->data[0], cmd2->data[11], cmd2->data[12], cmd2->data[13], cmd2->data[14], cmd2->data[15], 
+        cmd2->data[16], cmd2->data[17]
+    );
     luat_airlink_queue_send(LUAT_AIRLINK_QUEUE_CMD, &item);
     return 0;
 }
@@ -97,23 +102,27 @@ int luat_airlink_cmd_exec_gpio_get_result(luat_airlink_cmd_t* cmd, void* userdat
         return 0;
     }
     // TODO 打印出发送和收到的seq id, 匹配一下, 验证数据
+    LLOGD("收到回复 %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X",
+        cmd->data[0],  cmd->data[1], cmd->data[2], cmd->data[3],  cmd->data[4],  cmd->data[5],  cmd->data[6],  cmd->data[7],
+        cmd->data[8],  cmd->data[9], cmd->data[0], cmd->data[11], cmd->data[12], cmd->data[13], cmd->data[14], cmd->data[15], 
+        cmd->data[16], cmd->data[17]
+    );
 
     // 读取数据, pin 及 输入值
-    uint8_t params[2];
-    memcpy(params, cmd->data + 8 + 8, 2);
-    uint8_t pin = params[0];
-    uint8_t level = params[1];
-    LLOGI("gpio(%d) input %d", pin, level);
+    uint8_t pin = cmd->data[16];
+    uint8_t level = cmd->data[17];
+    // LLOGI("gpio(%d) input %d", pin, level);
     if (pin < 64) {
+        uint64_t tmp = pin;
         if (level) {
             // bit set
-            g_drv_gpio_input_level |= (1ULL << pin);
+            g_drv_gpio_input_level |= (1ULL << tmp);
         }
         else {
             // bit clean
-            g_drv_gpio_input_level &= ~(1ULL << pin);
+            g_drv_gpio_input_level &= ~(1ULL << tmp);
         }
-        luat_rtos_semaphore_release(&g_drv_gpio_sem);
+        luat_rtos_semaphore_release(g_drv_gpio_sem);
     }
     return 0;
 }

+ 1 - 0
components/drv/src/luat_drv_gpio.c

@@ -41,6 +41,7 @@ int luat_drv_gpio_set(int pin, int level) {
 int luat_drv_gpio_setup(luat_gpio_t* gpio) {
     LLOGD("执行luat_drv_gpio_setup pin %d mode %d", gpio->pin, gpio->mode);
     if (gpio == NULL) {
+        LLOGE("gpio is NULL");
         return -1;
     }
     if (gpio->pin < 0 || gpio->pin >= 255) {

+ 17 - 13
luat/demo/airlink/air8000_gpio/main.lua

@@ -7,25 +7,29 @@ VERSION = "1.0.5"
 _G.sys = require("sys")
 --[[特别注意, 使用http库需要下列语句]]
 
-PWR8000S = gpio.setup(23, 0, gpio.PULLUP) -- 关闭Air8000S的LDO供电
+-- 通过boot按键方便刷Air8000S
+function PWR8000S(val)
+    gpio.set(23, val)
+end
 
-sys.taskInit(function()
-    -- 稍微缓一下
-    sys.wait(10)
-    -- 初始化airlink
-    airlink.init()
-    -- 启动底层线程, 从机模式
-    airlink.start(1)
-    PWR8000S(1)
+gpio.debounce(0, 1000)
+gpio.setup(0, function()
+    sys.taskInit(function()
+        log.info("复位Air8000S")
+        PWR8000S(0)
+        sys.wait(20)
+        PWR8000S(1)
+    end)
+end, gpio.PULLDOWN)
 
+sys.taskInit(function()
     -- 闪灯开始
     sys.wait(100)
+    pin = 164
     while 1 do
-        gpio.setup(109, 0, gpio.PULLUP)
-        gpio.setup(108, 1, gpio.PULLUP)
+        gpio.setup(pin, 0, gpio.PULLUP)
         sys.wait(500)
-        gpio.setup(109, 1, gpio.PULLUP)
-        gpio.setup(108, 0, gpio.PULLUP)
+        gpio.setup(pin, 1, gpio.PULLUP)
         sys.wait(500)
     end
 end)

+ 43 - 0
luat/demo/airlink/air8000_gpio_get/main.lua

@@ -0,0 +1,43 @@
+
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "air8000_gpio_get"
+VERSION = "1.0.5"
+
+-- sys库是标配
+_G.sys = require("sys")
+--[[特别注意, 使用http库需要下列语句]]
+
+-- 通过boot按键方便刷Air8000S
+function PWR8000S(val)
+    gpio.set(23, val)
+end
+
+gpio.debounce(0, 1000)
+gpio.setup(0, function()
+    sys.taskInit(function()
+        log.info("复位Air8000S")
+        PWR8000S(0)
+        sys.wait(20)
+        PWR8000S(1)
+    end)
+end, gpio.PULLDOWN)
+
+sys.taskInit(function()
+
+    -- GPIO153 输出电平
+    -- GPIO160 读取电平
+    sys.wait(3000)
+    IN = gpio.setup(160, nil, gpio.PULLUP)
+    OUT = gpio.setup(153, 0, gpio.PULLUP)
+    while 1 do
+        gpio.toggle(153)
+        log.info("gpio", "读出的值是", gpio.get(160)) 
+        sys.wait(1000)
+    end
+end)
+
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 4 - 4
luat/modules/luat_lib_gpio.c

@@ -285,12 +285,12 @@ static int l_gpio_setup(lua_State *L) {
     	conf.alt_func = -1;
     }
     #ifdef LUAT_USE_DRV_GPIO
-    int re = luat_drv_gpio_setup(&conf);
+    int ret = luat_drv_gpio_setup(&conf);
     #else
-    int re = luat_gpio_setup(&conf);
+    int ret = luat_gpio_setup(&conf);
     #endif
-    if (re != 0) {
-        LLOGW("gpio setup fail pin=%d", conf.pin);
+    if (ret != 0) {
+        LLOGW("gpio setup fail pin=%d ret %d", conf.pin, ret);
         return 0;
     }
     if (conf.mode == Luat_GPIO_IRQ) {