Эх сурвалжийг харах

add: 先把airlink的代码临时提交一下,未完成

Wendal Chen 1 жил өмнө
parent
commit
f1aadfe618

+ 55 - 0
components/airlink/binding/luat_lib_airlink.c

@@ -0,0 +1,55 @@
+
+#include "luat_base.h"
+#include "luat_gpio.h"
+#include "luat_mem.h"
+#include "luat_mcu.h"
+#include "luat_msgbus.h"
+#include "luat_timer.h"
+#include "luat_rtos.h"
+#include "luat_mcu.h"
+#include <math.h>
+#include "luat_airlink.h"
+
+#define LUAT_LOG_TAG "airlink"
+#include "luat_log.h"
+
+static int l_airlink_start(lua_State *L) {
+    int id = luaL_checkinteger(L, 1);
+    if (id == 0) {
+        // 临时入口,先写死
+        LLOGD("启动AirLink从机模式");
+    }
+    else {
+        // 临时入口,先写死
+        LLOGD("启动AirLink主机模式");
+    }
+    luat_airlink_task_start();
+    luat_airlink_start(id);
+    return 0;
+}
+static int l_airlink_stop(lua_State *L) {
+    int id = luaL_checkinteger(L, 1);
+    if (id == 0) {
+        // 临时入口,先写死
+        LLOGD("停止AirLink从机模式");
+    }
+    else {
+        // 临时入口,先写死
+        LLOGD("停止AirLink主机模式");
+    }
+    luat_airlink_stop(id);
+    return 0;
+}
+
+#include "rotable2.h"
+static const rotable_Reg_t reg_airlink[] =
+{
+    { "start" ,        ROREG_FUNC(l_airlink_start )},
+    { "stop" ,         ROREG_FUNC(l_airlink_stop )},
+	{ NULL,             ROREG_INT(0) }
+};
+
+LUAMOD_API int luaopen_airlink( lua_State *L ) {
+    luat_newlib2(L, reg_airlink);
+    return 1;
+}

+ 33 - 0
components/airlink/include/luat_airlink.h

@@ -0,0 +1,33 @@
+#ifndef LUAT_AIRLINK_H
+#define LUAT_AIRLINK_H
+
+typedef struct luat_airlink_cmd
+{
+    uint16_t cmd; // 命令, 从0x0001开始, 到0xfffe结束
+    uint16_t len; // 数据长度,最高64k, 实际使用最高2k
+    uint64_t cmd_id; // 命令id, 起始1, 不需要ACK的指令, 可以传0, 逐个递增
+    uint32_t revert; // 预留4字节的空余区域
+    uint8_t data[0];
+}luat_airlink_cmd_t;
+
+int luat_airlink_start(int id);
+
+int luat_airlink_stop(int id);
+
+void luat_airlink_data_pack(uint8_t* buff, size_t len, uint8_t* dst);
+void luat_airlink_data_unpack(uint8_t* buff, size_t len, size_t* pkg_offset, size_t* pkg_size);
+
+void luat_airlink_task_start(void);
+void luat_airlink_print_buff(const char* tag, uint8_t* buff, size_t len);
+void luat_airlink_on_data_recv(uint8_t *data, size_t len);
+
+typedef int (*luat_airlink_cmd_exec)(luat_airlink_cmd_t* cmd, void* userdata);
+
+typedef struct luat_airlink_cmd_reg
+{
+    uint16_t id;
+    luat_airlink_cmd_exec exec;
+}luat_airlink_cmd_reg_t;
+
+
+#endif

+ 92 - 0
components/airlink/src/luat_airlink.c

@@ -0,0 +1,92 @@
+
+#include "luat_base.h"
+#include "luat_spi.h"
+#include "luat_airlink.h"
+#include "luat_mem.h"
+#include "luat_rtos.h"
+#include "luat_crypto.h"
+
+#define LUAT_LOG_TAG "airlink"
+#include "luat_log.h"
+
+int luat_airlink_start(int id) {
+    if (id == 0) {
+        extern int luat_airlink_start_slave(void);
+        luat_airlink_start_slave();
+    }
+    else {
+        extern int luat_airlink_start_master(void);
+        luat_airlink_start_master();
+    }
+    return 0;
+}
+
+int luat_airlink_stop(int id) {
+    return 0;
+}
+
+void luat_airlink_data_unpack(uint8_t* buff, size_t len, size_t* pkg_offset, size_t* pkg_size) {
+    size_t tlen = 0;
+    uint16_t crc16 = 0;
+    uint16_t crc16_data = 0;
+    for (size_t i = 0; i < len - 12; i++)
+    {
+        // magic = 0xA1B1CA66
+        if (buff[i] == 0xA1 && buff[i + 1] == 0xB1 && buff[i + 2] == 0xCA && buff[i + 3] == 0x66)
+        {
+            // 找到了magic
+            tlen = buff[i + 4] + buff[i+5] * 256;
+            crc16 = buff[i + 6] + buff[i+7] * 256;
+            LLOGD("找到magic, 且数据长度为 %d", tlen);
+            if (tlen > 0 && tlen + 4 + i + 4 <= len) {
+                // 计算crc16
+                crc16_data = luat_crc16(buff + i + 4 + 4, tlen, 0xFFFF, 0x1021, 0);
+                if (crc16_data == crc16) {
+                    LLOGD("crc16校验成功");
+                    *pkg_offset = i + 4 + 4;
+                    *pkg_size = tlen;
+                    return;
+                }
+                else {
+                    LLOGD("crc16校验失败 %d %d", crc16_data, crc16);
+                }
+            }
+            else {
+                LLOGD("数据长度错误");
+            }
+        }
+    }
+    
+}
+
+void luat_airlink_data_pack(uint8_t* buff, size_t len, uint8_t* dst) {
+    // 先写入magic
+    dst[0] = 0xA1;
+    dst[1] = 0xB1;
+    dst[2] = 0xCA;
+    dst[3] = 0x66;
+
+    // 写入长度
+    dst[4] = len & 0xFF;
+    dst[5] = (len >> 8) & 0xFF;
+
+    // 写入crc16
+    uint16_t crc16 = luat_crc16(buff, len, 0xFFFF, 0x1021, 0);
+    dst[6] = crc16 & 0xFF;
+    dst[7] = (crc16 >> 8) & 0xFF;
+
+    memcpy(dst + 8, buff, len);
+}
+
+void luat_airlink_print_buff(const char* tag, uint8_t* buff, size_t len) {
+    static char tmpbuff[1024] = {0};
+    for (size_t i = 0; i < len; i+=8)
+    {
+        // sprintf(tmpbuff + i * 2, "%02X", buff[i]);
+        // LLOGD("SPI TX[%d] 0x%02X", i, buff[i]);
+        LLOGD("AirLink %s [%04X-%04X] %02X%02X%02X%02X%02X%02X%02X%02X", tag, i, i + 8, 
+            buff[i+0], buff[i+1], buff[i+2], buff[i+3], 
+            buff[i+4], buff[i+5], buff[i+6], buff[i+7]);
+    }
+    // LLOGD("SPI0 %s", tmpbuff);
+}

+ 57 - 0
components/airlink/src/luat_airlink_cmds.c

@@ -0,0 +1,57 @@
+#include "luat_base.h"
+#include "luat_spi.h"
+#include "luat_airlink.h"
+
+
+#include "luat_rtos.h"
+#include "luat_debug.h"
+#include "luat_spi.h"
+#include "luat_pm.h"
+#include "luat_gpio.h"
+#include "luat_airlink.h"
+#include "luat_fota.h"
+
+#define LUAT_LOG_TAG "airlink"
+#include "luat_log.h"
+
+#define CMD_DEFINE(func) extern int luat_airlink_cmd_exec_##func(luat_airlink_cmd_t* cmd, void* userdata)
+#define CMD_REG(id,func) {id, luat_airlink_cmd_exec_##func}
+
+// 基础指令0x01开始
+CMD_DEFINE(ping);
+CMD_DEFINE(pong);
+CMD_DEFINE(reset);
+CMD_DEFINE(fota_init);
+CMD_DEFINE(fota_write);
+CMD_DEFINE(fota_done);
+
+// MAC和IP包指令, 0x100开始
+CMD_DEFINE(ip_pkg);
+CMD_DEFINE(set_mac);
+CMD_DEFINE(link_up);
+CMD_DEFINE(link_down);
+
+// WIFI指令, 0x200开始
+CMD_DEFINE(wlan_init);
+CMD_DEFINE(wlan_sta_connect);
+CMD_DEFINE(wlan_sta_disconnect);
+CMD_DEFINE(wlan_ap_start);
+CMD_DEFINE(wlan_ap_stop);
+CMD_DEFINE(wlan_scan);
+CMD_DEFINE(wlan_scan_result);
+
+luat_airlink_cmd_reg_t airlink_cmds[] = {
+    CMD_REG(0x01, ping),
+    CMD_REG(0x02, pong),
+    CMD_REG(0x03, reset),
+    CMD_REG(0x04, fota_init),
+    CMD_REG(0x05, fota_write),
+    CMD_REG(0x06, fota_done),
+
+    CMD_REG(0x100, ip_pkg),
+    CMD_REG(0x101, set_mac),
+    CMD_REG(0x102, link_up),
+    CMD_REG(0x103, link_down),
+
+    {0, NULL}
+};

+ 53 - 0
components/airlink/src/luat_airlink_cmds_basic.c

@@ -0,0 +1,53 @@
+#include "luat_base.h"
+#include "luat_spi.h"
+#include "luat_airlink.h"
+
+
+#include "luat_rtos.h"
+#include "luat_debug.h"
+#include "luat_spi.h"
+#include "luat_pm.h"
+#include "luat_gpio.h"
+#include "luat_airlink.h"
+#include "luat_fota.h"
+
+#define LUAT_LOG_TAG "airlink"
+#include "luat_log.h"
+
+int luat_airlink_cmd_exec_ping(luat_airlink_cmd_t* cmd, void* userdata) {
+    LLOGD("收到ping指令,返回pong");
+    // TODO 返回PONG
+    return 0;
+}
+
+int luat_airlink_cmd_exec_pong(luat_airlink_cmd_t* cmd, void* userdata) {
+    LLOGD("收到pong指令,检查数据是否匹配!!");
+    return 0;
+}
+
+int luat_airlink_cmd_exec_reset(luat_airlink_cmd_t* cmd, void* userdata) {
+    LLOGD("收到reset指令!!!");
+    luat_pm_reset();
+    return 0;
+}
+
+int luat_airlink_cmd_exec_fota_init(luat_airlink_cmd_t* cmd, void* userdata) {
+    LLOGD("收到FOTA初始化指令!!!");
+    int ret = luat_fota_init(0, 0, NULL, NULL, 0);
+    LLOGD("fota_init ret %d", ret);
+    return 0;
+}
+
+int luat_airlink_cmd_exec_fota_data(luat_airlink_cmd_t* cmd, void* userdata) {
+    LLOGD("收到FOTA数据!!!");
+    int ret = luat_fota_write(cmd->data, cmd->len);
+    LLOGD("fota_write ret %d", ret);
+    return 0;
+}
+
+int luat_airlink_cmd_exec_fota_done(luat_airlink_cmd_t* cmd, void* userdata) {
+    LLOGD("收到FOTA传输完毕指令!!!");
+    int ret = luat_fota_done();
+    LLOGD("fota_write ret %d", ret);
+    return 0;
+}

+ 0 - 0
components/airlink/src/luat_airlink_cmds_ippkg.c


+ 143 - 0
components/airlink/src/luat_airlink_spi_master_task.c

@@ -0,0 +1,143 @@
+#include "luat_base.h"
+#include "luat_spi.h"
+#include "luat_airlink.h"
+
+
+#include "luat_rtos.h"
+#include "luat_debug.h"
+#include "luat_spi.h"
+#include "luat_pm.h"
+#include "luat_gpio.h"
+#include "luat_airlink.h"
+
+#define LUAT_LOG_TAG "airlink"
+#include "luat_log.h"
+
+#ifdef CHIP_EC718
+
+#define TEST_SPI_ID   0
+#define TEST_BUFF_SIZE (1600)
+#define TEST_CS_PIN 8
+#define TEST_RDY_PIN 26
+#define TEST_BTN_PIN 0
+
+#else
+
+#define TEST_SPI_ID   0
+#define TEST_BUFF_SIZE (1600)
+#define TEST_CS_PIN 15
+#define TEST_RDY_PIN 20
+#define TEST_BTN_PIN 2
+
+#endif
+
+static uint8_t start;
+static uint8_t slave_rdy;
+static luat_rtos_task_handle spi_task_handle;
+static luat_rtos_task_handle gpio_task_handle;
+
+static int gpio_level_irq(void *data, void* args)
+{
+	start = 1;
+	return 0;
+}
+
+static int slave_rdy_irq(void *data, void* args) {
+    slave_rdy = 1;
+    luat_rtos_event_send(gpio_task_handle, 1, 2, 3, 4, 100);
+
+
+    return 0;
+}
+
+
+static void task_test_spi(void *param)
+{
+    luat_spi_t spi_conf = {
+        .id = TEST_SPI_ID,
+        .CPHA = 1,
+        .CPOL = 1,
+        .dataw = 8,
+        .bit_dict = 0,
+        .master = 1,
+        .mode = 1,             // mode设置为1,全双工
+		.bandrate = 31000000,
+        .cs = 255
+    };
+    luat_pm_iovolt_ctrl(0, 3300);
+    luat_spi_setup(&spi_conf);
+	luat_gpio_cfg_t gpio_cfg;
+
+    // 触发脚
+	luat_gpio_set_default_cfg(&gpio_cfg);
+	gpio_cfg.pin = TEST_BTN_PIN;
+	gpio_cfg.mode = LUAT_GPIO_IRQ;
+	gpio_cfg.irq_type = LUAT_GPIO_RISING_IRQ;
+	gpio_cfg.pull = LUAT_GPIO_PULLDOWN;
+	gpio_cfg.irq_cb = gpio_level_irq;
+	luat_gpio_open(&gpio_cfg);
+
+    // 从机准备好脚
+    luat_gpio_set_default_cfg(&gpio_cfg);
+    gpio_cfg.pin = TEST_RDY_PIN;
+    gpio_cfg.mode = LUAT_GPIO_IRQ;
+    gpio_cfg.irq_type = LUAT_GPIO_FALLING_IRQ;
+    gpio_cfg.pull = LUAT_GPIO_PULLUP;
+    gpio_cfg.irq_cb = slave_rdy_irq;
+    luat_gpio_open(&gpio_cfg);
+    LLOGD(" gpio rdy setup done %d", TEST_RDY_PIN);
+
+    // CS片选脚
+	luat_gpio_set_default_cfg(&gpio_cfg);
+	gpio_cfg.pin = TEST_CS_PIN;
+	gpio_cfg.mode = LUAT_GPIO_OUTPUT;
+	gpio_cfg.pull = LUAT_GPIO_PULLUP;
+    gpio_cfg.output_level = 1;
+	luat_gpio_open(&gpio_cfg);
+
+    int i;
+    size_t pkg_offset = 0;
+    size_t pkg_size = 0;
+	static uint8_t send_buf[TEST_BUFF_SIZE] = {0x90,0x80,0x70,0x60};
+    static uint8_t recv_buf[TEST_BUFF_SIZE] = {0};
+    const char* test_data = "123456789";
+    luat_airlink_data_pack((uint8_t*)test_data, strlen(test_data), send_buf);
+    luat_airlink_print_buff("TX", send_buf, 16);
+
+    while (1)
+    {
+        // TODO 从队列读取数据, 然后打包, 发送给从机
+        while(!start){luat_rtos_task_sleep(100);}
+        slave_rdy = 0;
+        luat_gpio_set(TEST_CS_PIN, 0);
+        luat_spi_transfer(TEST_SPI_ID, (const char*)send_buf, TEST_BUFF_SIZE, (char*)recv_buf, TEST_BUFF_SIZE);
+        luat_gpio_set(TEST_CS_PIN, 1);
+        luat_airlink_print_buff("RX", recv_buf, 32);
+        // 对接收到的数据进行解析
+        pkg_offset = 0;
+        pkg_size = 0;
+        luat_airlink_data_unpack(recv_buf, TEST_BUFF_SIZE, &pkg_offset, &pkg_size);
+        if (pkg_size) {
+            luat_airlink_on_data_recv(recv_buf + pkg_offset, pkg_size);
+        }
+        
+        memset(recv_buf, 0, TEST_BUFF_SIZE);
+        luat_rtos_task_sleep(300);
+        start = 0;
+    }
+}
+
+// static  void task_gpio_why(void *param) {
+//     luat_event_t event;
+//     while (1) {
+//         luat_rtos_event_recv(gpio_task_handle, 0, &event, NULL, LUAT_WAIT_FOREVER);
+//         LLOGD("GPIO IRQ %d", event.id);
+//     }
+// }
+
+
+void luat_airlink_start_master(void)
+{
+    luat_rtos_task_create(&spi_task_handle, 4 * 1024, 95, "spi", task_test_spi, NULL, 0);
+    // luat_rtos_task_create(&gpio_task_handle, 4 * 1024, 20, "gpio", task_gpio_why, NULL, 128);
+}

+ 0 - 0
components/airlink/src/luat_airlink_spi_slave_task.c


+ 51 - 0
components/airlink/src/luat_airlink_task.c

@@ -0,0 +1,51 @@
+#include "luat_base.h"
+#include "luat_spi.h"
+#include "luat_airlink.h"
+#include "luat_mem.h"
+#include "luat_rtos.h"
+#include "luat_crypto.h"
+
+#define LUAT_LOG_TAG "airlink"
+#include "luat_log.h"
+
+static luat_rtos_task_handle airlink_task_handle;
+
+void luat_airlink_on_data_recv(uint8_t *data, size_t len) {
+    void* ptr = luat_heap_opt_malloc(LUAT_HEAP_PSRAM, len);
+    if (ptr == NULL) {
+        LLOGE("airlink分配内存失败!!! %d", len);
+        return;
+    }
+    memcpy(ptr, data, len);
+    luat_rtos_event_send(airlink_task_handle, 1, (uint32_t)ptr, len, 0, 0);
+}
+
+static int luat_airlink_task(void *param) {
+    LLOGD("处理线程启动");
+    luat_event_t event;
+    void* ptr = NULL;
+    size_t len = 0;
+    while (1) {
+        luat_rtos_event_recv(airlink_task_handle, 0, &event, NULL, LUAT_WAIT_FOREVER);
+        if (event.id == 1) { // 收到数据了, 马上处理
+            // 处理数据
+            ptr = (void*)event.param1;
+            len = event.param2;
+            // TODO 真正的处理逻辑
+            LLOGD("收到指令/回复 ptr %p len %d", ptr, len);
+
+            // 处理完成, 释放内存
+            luat_heap_opt_free(LUAT_HEAP_PSRAM, ptr);
+        }
+    }
+    return 0;
+}
+
+void luat_airlink_task_start(void) {
+    if (airlink_task_handle == NULL) {
+        luat_rtos_task_create(&airlink_task_handle, 8 * 1024, 20, "airlink", luat_airlink_task, NULL, 1024);
+    }
+    else {
+        LLOGD("airlink task 已经启动过了");
+    }
+}

+ 20 - 0
demo/airlink/air780epm/main.lua

@@ -0,0 +1,20 @@
+
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "netdrv"
+VERSION = "1.0.4"
+
+
+-- sys库是标配
+_G.sys = require("sys")
+--[[特别注意, 使用mqtt库需要下列语句]]
+_G.sysplus = require("sysplus")
+
+sys.taskInit(function()
+    sys.wait(500)
+    airlink.start(1)
+end)
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 34 - 0
demo/airlink/air8101/main.lua

@@ -0,0 +1,34 @@
+
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "netdrv"
+VERSION = "1.0.4"
+
+
+-- sys库是标配
+_G.sys = require("sys")
+--[[特别注意, 使用mqtt库需要下列语句]]
+_G.sysplus = require("sysplus")
+
+sys.taskInit(function()
+    sys.wait(500)
+    airlink.start(0)
+    -- log.info("设置静态IPV4")
+    -- netdrv.ipv4(socket.LWIP_ETH, "192.168.1.129", "255.255.255.0", "192.168.1.1")
+    -- log.info("ip", socket.localIP(socket.LWIP_ETH))
+end)
+
+sys.taskInit(function()
+    -- sys.waitUntil("IP_READY")
+    -- while 1 do
+    --     sys.wait(6000)
+    --     log.info("http", http.request("GET", "http://httpbin.air32.cn/bytes/2048", nil, nil, {adapter=socket.LWIP_ETH,timeout=3000}).wait())
+    --     log.info("lua", rtos.meminfo())
+    --     log.info("sys", rtos.meminfo("sys"))
+    --     log.info("ip", socket.localIP(socket.LWIP_ETH))
+    -- end
+end)
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 4 - 0
luat/include/luat_libs.h

@@ -202,4 +202,8 @@ LUAMOD_API int luaopen_iperf( lua_State *L );
 
 /** can库*/
 LUAMOD_API int luaopen_can( lua_State *L );
+
+// airlink库
+LUAMOD_API int luaopen_airlink( lua_State *L );
+
 #endif