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

add: airlink,drv,完成uart适配, 测试uart11自收自发正常, uart10/uart12未测

Wendal Chen 11 месяцев назад
Родитель
Сommit
4fda072538

+ 60 - 2
components/airlink/src/driver/luat_airlink_drv_uart.c

@@ -10,13 +10,16 @@
 #include "luat_gpio.h"
 #include "luat_airlink.h"
 #include "luat_mem.h"
+#include "luat_msgbus.h"
 
 #define LUAT_LOG_TAG "airlink.uart"
 #include "luat_log.h"
 
+int l_uart_handler(lua_State *L, void* ptr);
+
 
 int luat_airlink_drv_uart_setup(luat_uart_t* conf) {
-    LLOGD("执行uart setup %d baud_rate %d", conf->id, conf->baud_rate);
+    // LLOGD("执行uart setup %d baud_rate %d", conf->id, conf->baud_rate);
     uint64_t luat_airlink_next_cmd_id = luat_airlink_get_next_cmd_id();
     airlink_queue_item_t item = {
         .len = sizeof(luat_uart_t) + sizeof(luat_airlink_cmd_t) + 8
@@ -34,7 +37,7 @@ int luat_airlink_drv_uart_setup(luat_uart_t* conf) {
 }
 
 int luat_airlink_drv_uart_write(int uart_id, void* data, size_t length) {
-    LLOGD("执行uart write %d %p %d", uart_id, data, length);
+    // LLOGD("执行uart write %d %p %d", uart_id, data, length);
     uint64_t luat_airlink_next_cmd_id = luat_airlink_get_next_cmd_id();
     size_t total_len = length + sizeof(luat_airlink_cmd_t) + 8 + 1;
     airlink_queue_item_t item = {.len = total_len};
@@ -70,7 +73,62 @@ int luat_airlink_drv_uart_close(int uart_id) {
     return 0;
 }
 
+typedef struct drv_uart_buff {
+    size_t remain;
+    size_t buff_size;
+    uint8_t buff[4];
+}drv_uart_buff_t;
+static drv_uart_buff_t* uart_rx_buffs[10];
+
 int luat_airlink_drv_uart_data_cb(int uart_id, void* buffer, size_t length) {
     // TODO 要接收UART BUFF数据, 返回给用户代码
+    if (uart_id >= 10 && uart_id <= 19) {
+        uint8_t realy_id = uart_id - 10;
+        if (uart_rx_buffs[realy_id] == NULL) {
+            uart_rx_buffs[realy_id] = luat_heap_malloc(4096 + sizeof(drv_uart_buff_t));
+            if (uart_rx_buffs[realy_id] == NULL) {
+                LLOGE("内存分配失败!!");
+                return -101;
+            }
+            uart_rx_buffs[realy_id]->buff_size = 4096;
+            uart_rx_buffs[realy_id]->remain = 0;
+        }
+        if (uart_rx_buffs[realy_id]->remain + length > uart_rx_buffs[realy_id]->buff_size) {
+            LLOGE("RX OVERFLOW remain %d income %d", uart_rx_buffs[realy_id]->remain, length);
+            memmove(uart_rx_buffs[realy_id]->buff, uart_rx_buffs[realy_id]->buff + uart_rx_buffs[realy_id]->remain, uart_rx_buffs[realy_id]->buff_size - uart_rx_buffs[realy_id]->remain);
+            uart_rx_buffs[realy_id]->remain = uart_rx_buffs[realy_id]->buff_size - length;
+        }
+        memcpy(uart_rx_buffs[realy_id]->buff + uart_rx_buffs[realy_id]->remain,  buffer, length);
+        uart_rx_buffs[realy_id]->remain += length;
+        
+        rtos_msg_t msg = {0};
+        msg.handler = l_uart_handler;
+        msg.ptr = NULL;
+        msg.arg1 = uart_id;
+        msg.arg2 = uart_rx_buffs[realy_id]->remain;
+        luat_msgbus_put(&msg, 0);
+        return 0;
+    }
+    return 0;
+}
+
+int luat_airlink_drv_uart_read(int uart_id, void* data, size_t length) {
+    if (uart_id >= 10 && uart_id <= 19) {
+        uint8_t realy_id = uart_id - 10;
+        if (uart_rx_buffs[realy_id] == NULL) {
+            return 0;
+        }
+        if (data == NULL) {
+            return uart_rx_buffs[realy_id]->remain;
+        }
+        if (length > uart_rx_buffs[realy_id]->remain) {
+            length = uart_rx_buffs[realy_id]->remain;
+        }
+        memcpy(data, uart_rx_buffs[realy_id]->buff, length);
+        memmove(uart_rx_buffs[realy_id]->buff, uart_rx_buffs[realy_id]->buff + length, uart_rx_buffs[realy_id]->remain - length);
+        uart_rx_buffs[realy_id]->remain -= length;
+        // LLOGD("uart[%d] read %d bytes remain %d", uart_id, length, uart_rx_buffs[realy_id]->remain);
+        return length;
+    }
     return 0;
 }

+ 82 - 6
components/airlink/src/exec/luat_airlink_cmd_exec_uart.c

@@ -10,20 +10,87 @@
 #include "luat_gpio.h"
 #include "luat_airlink.h"
 #include "luat_uart.h"
+#include "luat_msgbus.h"
 
 #define LUAT_LOG_TAG "airlink"
 #include "luat_log.h"
 
 // 前8字节是指令id, 用于返回执行结果, 待定.
+static luat_rtos_queue_t rx_queue;
+
+static luat_rtos_task_handle rx_thread;
+
+
+static void rx_data_input(int uart_id, uint32_t data_len) {
+    if (!rx_queue) {
+        return;
+    }
+    uint32_t id = (uint32_t)uart_id;
+    luat_rtos_queue_send(rx_queue, &id, 0, 0);
+}
+
+static void rx_data_input2(int uart_id, uint32_t data_len) {
+    // LLOGD("执行uart read %d %d", uart_id, data_len);
+    uint64_t luat_airlink_next_cmd_id = 0;
+    size_t length = data_len;
+    uint8_t buff[1024];
+    while (length > 0) {
+        size_t rsize = length;
+        if (rsize > 1024) {
+            rsize = 1024;
+        }
+        rsize = luat_uart_read(uart_id, buff, rsize);
+        // LLOGD("uart read out %d %d", uart_id, rsize);
+        if (rsize < 1) {
+            break;
+        }
+        length -= rsize;
+
+        size_t total_len = rsize + sizeof(luat_airlink_cmd_t) + 8 + 1;
+        airlink_queue_item_t item = {.len = total_len};
+        luat_airlink_cmd_t* cmd = luat_airlink_cmd_new(0x410, rsize + 1 + 8);
+        if (cmd == NULL) {
+            LLOGE("内存分配失败!!");
+            return;
+        }
+        luat_airlink_next_cmd_id = luat_airlink_get_next_cmd_id();
+        memcpy(cmd->data, &luat_airlink_next_cmd_id, 8);
+        uint8_t tmp = (uint8_t)uart_id;
+        memcpy(cmd->data + 8, &tmp, 1);
+        memcpy(cmd->data + 9, buff, rsize);
+        item.cmd = cmd;
+        luat_airlink_queue_send(LUAT_AIRLINK_QUEUE_CMD, &item);
+    }
+    
+    return;
+}
+
+static void rx_thread_main(void* params) {
+    uint32_t id = 0;
+    int ret = 0;
+    luat_rtos_queue_create(&rx_queue, 1024, sizeof(uint32_t));
+    while (1) {
+        ret = luat_rtos_queue_recv(rx_queue, &id, 0, LUAT_WAIT_FOREVER);
+        if (ret == 0) {
+            rx_data_input2(id, 4096);
+        }
+    }
+}
 
 int luat_airlink_cmd_exec_uart_setup(luat_airlink_cmd_t* cmd, void* userdata) {
     luat_uart_t* uart = cmd->data + 8;
     if (uart->id >= 10) {
         uart->id -= 10;
     }
-    LLOGD("uart[%d] setup", uart->id);
+    // LLOGD("uart[%d] setup", uart->id);
     int ret = luat_uart_setup(uart);
     LLOGD("uart[%d] setup baud_rate %d ret %d", uart->id, uart->baud_rate, ret);
+    if (ret == 0) {
+        if (rx_thread == NULL) {
+            luat_rtos_task_create(&rx_thread, 4 * 1024, 50, "airlink_rx", rx_thread_main, NULL, 0);
+        }
+        luat_uart_ctrl(uart->id, LUAT_UART_SET_RECV_CALLBACK, rx_data_input);
+    }
     return ret;
 }
 
@@ -32,9 +99,9 @@ int luat_airlink_cmd_exec_uart_write(luat_airlink_cmd_t* cmd, void* userdata) {
     if (id >= 10) {
         id -= 10;
     }
-    LLOGD("uart[%d] write %d bytes", id, cmd->len - 9);
+    // LLOGD("uart[%d] write %d bytes", id, cmd->len - 9);
     int ret = luat_uart_write(id, cmd->data + 9, cmd->len - 9);
-    LLOGD("uart[%d] write ret %d", id, ret);
+    // LLOGD("uart[%d] write ret %d", id, ret);
     return ret;
 }
 int luat_airlink_cmd_exec_uart_close(luat_airlink_cmd_t* cmd, void* userdata) {
@@ -42,11 +109,20 @@ int luat_airlink_cmd_exec_uart_close(luat_airlink_cmd_t* cmd, void* userdata) {
     if (id >= 10) {
         id -= 10;
     }
-    LLOGD("uart[%d] close", id);
+    // LLOGD("uart[%d] close", id);
     int ret = luat_uart_close(id);
-    LLOGD("uart[%d] close ret %d", id, ret);
+    // LLOGD("uart[%d] close ret %d", id, ret);
     return ret;
 }
+
+// 注意, 这个函数是调用端的回调函数, 用于接收数据
+extern int luat_airlink_drv_uart_data_cb(int uart_id, void* buffer, size_t length);
 int luat_airlink_cmd_exec_uart_data_cb(luat_airlink_cmd_t* cmd, void* userdata) {
+    if (cmd->len < 9) {
+        return 0;
+    }
+    uint8_t id = cmd->data[8];
+    // LLOGD("uart数据输入 %d %d", id, cmd->len - 9);
+    luat_airlink_drv_uart_data_cb(id + 10, cmd->data + 9, cmd->len - 9);
     return 0;
-}
+}

+ 1 - 1
components/airlink/src/task/luat_airlink_spi_master_task.c

@@ -244,7 +244,7 @@ __USER_FUNC_IN_RAM__ void airlink_wait_and_prepare_data(uint8_t *txbuff)
     }
     if (item.len > 0 && item.cmd != NULL)
     {
-        LLOGD("发送待传输的数据, 塞入SPI的FIFO cmd id 0x%04X", item.cmd->cmd);
+        // LLOGD("发送待传输的数据, 塞入SPI的FIFO cmd id 0x%04X", item.cmd->cmd);
         luat_airlink_data_pack(item.cmd, item.len, txbuff);
         luat_airlink_cmd_free(item.cmd);
     }

+ 69 - 0
demo/airlink/air8000_uart/main.lua

@@ -0,0 +1,69 @@
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "air8000_gpio_ext"
+VERSION = "1.0.5"
+
+-- sys库是标配
+_G.sys = require("sys")
+--[[特别注意, 使用http库需要下列语句]]
+
+PWR8000S = function(level)
+    gpio.set(23, level)
+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)
+
+local uartid = 11
+local buff = zbuff.create(1024)
+function uart_on()
+    local result = uart.on(uartid, "receive", function(id, len)
+        local s = ""
+        log.info("uart", "recv", id, len)
+        repeat
+            -- s = uart.read(id, 128)
+            uart.rx(id, buff)
+            s = buff:query()
+            if s and #s > 0 then -- #s 是取字符串的长度
+                -- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到
+                -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
+                log.info("uart", "receive", id, #s, s)
+                -- log.info("uart", "receive", id, #s, s:toHex())
+                buff:del()
+            else
+                break
+            end
+        until s == ""
+    end)
+    log.info("uart.on", result)
+end
+
+sys.taskInit(function()
+    sys.wait(1000)
+    airlink.debug(1)
+    local ret = uart.setup(uartid, 115200)
+    log.info("执行初始化", ret);
+    uart_on()
+    while 1 do
+        uart.write(uartid, "1234123412341234")
+        -- gpio.setup(164, 0, gpio.PULLDOWN)
+        sys.wait(1000)
+        -- break
+        -- airlink.statistics()
+    end
+    -- while 1 do
+    --     uart.write(11, "ABC\r\n")
+    --     sys.wait(1000)
+    -- end
+end)
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 62 - 18
luat/modules/luat_lib_uart.c

@@ -30,8 +30,15 @@
 #ifndef LUAT_UART_RX_MAX_LEN
 #define LUAT_UART_RX_MAX_LEN 0x10000
 #endif
+
+#ifdef LUAT_USE_DRV_UART
+#define MAX_DEVICE_COUNT 19
+#else
 #define MAX_DEVICE_COUNT 9
+#endif
+
 #define MAX_USB_DEVICE_COUNT 1
+
 typedef struct luat_uart_cb {
     int received;//回调函数
     int sent;//回调函数
@@ -323,14 +330,16 @@ void luat_uart_set_app_recv(int id, luat_uart_recv_callback_t cb) {
 
 int l_uart_handler(lua_State *L, void* ptr) {
     (void)ptr;
-    //LLOGD("l_uart_handler");
     rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
     lua_pop(L, 1);
     int uart_id = msg->arg1;
+    // LLOGD("l_uart_handler %d", uart_id);
+	#ifndef LUAT_USE_DRV_UART
     if (!luat_uart_exist(uart_id)) {
         //LLOGW("not exist uart id=%ld but event fired?!", uart_id);
         return 0;
     }
+	#endif
     int org_uart_id = uart_id;
 	#if !defined(LUAT_USE_WINDOWS) && !defined(LUAT_USE_LINUX) && !defined(LUAT_USE_MACOS)
     if (uart_id >= LUAT_VUART_ID_0)
@@ -340,7 +349,7 @@ int l_uart_handler(lua_State *L, void* ptr) {
 	#endif
     // sent event
     if (msg->arg2 == 0) {
-        //LLOGD("uart%ld sent callback", uart_id);
+        LLOGD("uart%ld sent callback", uart_id);
         if (uart_cbs[uart_id].sent) {
             lua_geti(L, LUA_REGISTRYINDEX, uart_cbs[uart_id].sent);
             if (lua_isfunction(L, -1)) {
@@ -361,11 +370,11 @@ int l_uart_handler(lua_State *L, void* ptr) {
                 lua_call(L, 2, 0);
             }
             else {
-                //LLOGD("uart%ld received callback not function", uart_id);
+                LLOGD("uart%ld received callback not function", uart_id);
             }
         }
         else {
-            //LLOGD("uart%ld no received callback", uart_id);
+            LLOGD("uart%ld no received callback", uart_id);
         }
     }
 
@@ -520,13 +529,14 @@ static int l_uart_read(lua_State *L)
 {
     uint8_t id = luaL_checkinteger(L, 1);
     uint32_t length = luaL_optinteger(L, 2, 1024);
+	int result = 0;
     if(lua_isuserdata(L, 3)){//zbuff对象特殊处理
         luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 3, LUAT_ZBUFF_TYPE));
         uint8_t* recv = buff->addr+buff->cursor;
-        if(length > buff->len - buff->cursor)
+        if(length > buff->len - buff->cursor) {
             length = buff->len - buff->cursor;
+		}
 #ifdef LUAT_USE_SOFT_UART
-		int result;
 		if (prv_uart_soft && (prv_uart_soft->uart_id == id))
 		{
 			result = luat_uart_soft_read(recv, length);
@@ -536,10 +546,15 @@ static int l_uart_read(lua_State *L)
 			result = luat_uart_read(id, recv, length);
 		}
 #else
-        int result = luat_uart_read(id, recv, length);
+#ifdef LUAT_USE_DRV_UART
+		result = luat_drv_uart_read(id, recv, length);
+#else
+        result = luat_uart_read(id, recv, length);
+#endif
 #endif
-        if(result < 0)
+        if(result < 0) {
             result = 0;
+		}
         buff->cursor += result;
         lua_pushinteger(L, result);
         return 1;
@@ -574,7 +589,6 @@ static int l_uart_read(lua_State *L)
     while(read_length < length)//循环读完
     {
 #ifdef LUAT_USE_SOFT_UART
-		int result;
 		if (prv_uart_soft && (prv_uart_soft->uart_id == id))
 		{
 			result = luat_uart_soft_read((void*)(recv + read_length), length - read_length);
@@ -584,7 +598,11 @@ static int l_uart_read(lua_State *L)
 			result = luat_uart_read(id, (void*)(recv + read_length), length - read_length);
 		}
 #else
-        int result = luat_uart_read(id, (void*)(recv + read_length), length - read_length);
+#ifdef LUAT_USE_DRV_UART
+		result = luat_drv_uart_read(id, (void*)(recv + read_length), length - read_length);
+#else
+        result = luat_uart_read(id, (void*)(recv + read_length), length - read_length);
+#endif
 #endif
         if (result > 0) {
             read_length += result;
@@ -635,8 +653,12 @@ static int l_uart_close(lua_State *L)
 		luat_uart_close(id);
 	}
 	return 0;
+#else
+#ifdef LUAT_USE_DRV_UART
+	luat_drv_uart_close(id);
 #else
 	luat_uart_close(id);
+#endif
     return 0;
 #endif
 }
@@ -664,16 +686,20 @@ static int l_uart_on(lua_State *L) {
 	}
 	else
 	{
+		#ifndef LUAT_USE_DRV_UART
 		if (!luat_uart_exist(uart_id)) {
 			lua_pushliteral(L, "no such uart id");
 			return 1;
 		}
+		#endif
 	}
 #else
+#ifndef LUAT_USE_DRV_UART
     if (!luat_uart_exist(uart_id)) {
         lua_pushliteral(L, "no such uart id");
         return 1;
     }
+#endif
 #endif
     if (uart_id >= LUAT_VUART_ID_0)
     {
@@ -764,11 +790,11 @@ uart.rx(1, buff)
 static int l_uart_rx(lua_State *L)
 {
     uint8_t id = luaL_checkinteger(L, 1);
-
+	int result;
     if(lua_isuserdata(L, 2)){//zbuff对象特殊处理
     	luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
 #ifdef LUAT_USE_SOFT_UART
-		int result;
+		
 		if (prv_uart_soft && (prv_uart_soft->uart_id == id))
 		{
 			result = prv_uart_soft->rx_buffer.Pos;
@@ -778,7 +804,11 @@ static int l_uart_rx(lua_State *L)
 			result = luat_uart_read(id, NULL, 0);
 		}
 #else
-    	int result = luat_uart_read(id, NULL, 0);
+#ifdef LUAT_USE_DRV_UART
+		result = luat_drv_uart_read(id, NULL, 0);
+#else
+    	result = luat_uart_read(id, NULL, 0);
+#endif
 #endif
         if (result > (buff->len - buff->used))
         {
@@ -794,7 +824,11 @@ static int l_uart_rx(lua_State *L)
 			luat_uart_read(id, buff->addr + buff->used, result);
 		}
 #else
-        luat_uart_read(id, buff->addr + buff->used, result);
+#ifdef LUAT_USE_DRV_UART
+        luat_drv_uart_read(id, buff->addr + buff->used, result);
+#else
+		luat_uart_read(id, buff->addr + buff->used, result);
+#endif
 #endif
         lua_pushinteger(L, result);
         buff->used += result;
@@ -819,8 +853,8 @@ local size = uart.rxSize(1)
 static int l_uart_rx_size(lua_State *L)
 {
     uint8_t id = luaL_checkinteger(L, 1);
-#ifdef LUAT_USE_SOFT_UART
 	int result;
+#ifdef LUAT_USE_SOFT_UART
 	if (prv_uart_soft && (prv_uart_soft->uart_id == id))
 	{
 		result = prv_uart_soft->rx_buffer.Pos;
@@ -831,7 +865,12 @@ static int l_uart_rx_size(lua_State *L)
 	}
 	lua_pushinteger(L, result);
 #else
-    lua_pushinteger(L, luat_uart_read(id, NULL, 0));
+#ifdef LUAT_USE_DRV_UART
+	result = luat_drv_uart_read(id, NULL, 0);
+#else
+	result = luat_uart_read(id, NULL, 0);
+#endif
+    lua_pushinteger(L, result);
 #endif
     return 1;
 }
@@ -883,6 +922,7 @@ static int l_uart_tx(lua_State *L)
     size_t start, len;
     // const char *buf;
     luat_zbuff_t *buff;
+	int result;
     uint8_t id = luaL_checkinteger(L, 1);
     if(lua_isuserdata(L, 2))
     {
@@ -905,7 +945,7 @@ static int l_uart_tx(lua_State *L)
     	len = buff->len - start;
     }
 #ifdef LUAT_USE_SOFT_UART
-    int result;
+    
     if (prv_uart_soft && (prv_uart_soft->uart_id == id))
     {
     	result = luat_uart_soft_write((const uint8_t*)(buff->addr + start), len);
@@ -916,7 +956,11 @@ static int l_uart_tx(lua_State *L)
     }
     lua_pushinteger(L, result);
 #else
-    int result = luat_uart_write(id, buff->addr + start, len);
+#ifdef LUAT_USE_DRV_UART
+	result = luat_drv_uart_write(id, buff->addr + start, len);
+#else
+    result = luat_uart_write(id, buff->addr + start, len);
+#endif
     lua_pushinteger(L, result);
 #endif
     return 1;