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

add: netdrv,ch390,支持中断模式,默认轮询模式

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

+ 9 - 4
components/network/netdrv/binding/luat_lib_netdrv.c

@@ -35,9 +35,13 @@
 -- Air8101初始化内部以太网控制器
 -- Air8101初始化内部以太网控制器
 netdrv.setup(socket.LWIP_ETH)
 netdrv.setup(socket.LWIP_ETH)
 
 
--- Air8000/Air780EPM初始化CH390H/D作为LAN口, 单一使用.不含WAN.
+-- Air8000/Air780EPM初始化CH390H/D作为LAN/WAN
+-- 支持多个CH390H, 使用不同的CS脚区分不同网口
 netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=0,cs=8})
 netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=0,cs=8})
 netdrv.dhcp(socket.LWIP_ETH, true)
 netdrv.dhcp(socket.LWIP_ETH, true)
+-- 支持CH390H的中断模式, 能提供响应速度, 但是需要外接中断引脚
+-- 实测对总网速没有帮助, 轻负载时能降低功耗, 让模组能进入低功耗模式
+netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=0,cs=8,irq=20})
 */
 */
 static int l_netdrv_setup(lua_State *L) {
 static int l_netdrv_setup(lua_State *L) {
     luat_netdrv_conf_t conf = {0};
     luat_netdrv_conf_t conf = {0};
@@ -311,14 +315,15 @@ static const rotable_Reg_t reg_netdrv[] =
 
 
     //@const CH390 number 南京沁恒CH390系列,支持CH390D/CH390H, SPI通信
     //@const CH390 number 南京沁恒CH390系列,支持CH390D/CH390H, SPI通信
     { "CH390",          ROREG_INT(1)},
     { "CH390",          ROREG_INT(1)},
-    { "CH395",          ROREG_INT(2)}, // 考虑兼容Air724UG/Air820UG的老客户
-    { "W5500",          ROREG_INT(3)}, // 考虑兼容Air780EXXX/Air105的老客户
     { "UART",           ROREG_INT(16)}, // UART形式的网卡, 不带MAC, 直接IP包
     { "UART",           ROREG_INT(16)}, // UART形式的网卡, 不带MAC, 直接IP包
-    { "SPINET",         ROREG_INT(32)}, // SPI形式的网卡, 可以带MAC, 也可以不带
+    //@const WHALE number 虚拟网卡
     { "WHALE",          ROREG_INT(64)}, // 通用WHALE设备
     { "WHALE",          ROREG_INT(64)}, // 通用WHALE设备
 
 
+    //@const CTRL_RESET number 控制类型-复位,当前仅支持CH390H
     { "CTRL_RESET",     ROREG_INT(LUAT_NETDRV_CTRL_RESET)},
     { "CTRL_RESET",     ROREG_INT(LUAT_NETDRV_CTRL_RESET)},
+    //@const CTRL_RESET number 请求对网卡硬复位,当前仅支持CH390H
     { "RESET_HARD",     ROREG_INT(0x101)},
     { "RESET_HARD",     ROREG_INT(0x101)},
+    //@const CTRL_RESET number 请求对网卡硬复位,当前仅支持CH390H
     { "RESET_SOFT",     ROREG_INT(0x102)},
     { "RESET_SOFT",     ROREG_INT(0x102)},
 	{ NULL,             ROREG_INT(0) }
 	{ NULL,             ROREG_INT(0) }
 };
 };

+ 54 - 2
components/network/netdrv/src/ch390h_task.c

@@ -40,10 +40,29 @@ static luat_rtos_queue_t qt;
 static uint64_t warn_vid_pid_tm;
 static uint64_t warn_vid_pid_tm;
 static uint64_t warn_msg_tm;
 static uint64_t warn_msg_tm;
 
 
+static uint32_t s_ch390h_mode; // 0 -- PULL 模式, 1 == IRQ 模式
+
 static int pkg_mem_type = LUAT_HEAP_AUTO;
 static int pkg_mem_type = LUAT_HEAP_AUTO;
 
 
+static int ch390h_irq_cb(void *data, void *args) {
+    uint32_t len = 0;
+    luat_rtos_queue_get_cnt(qt, &len);
+    if (len > 4) {
+        return 0;
+    }
+    pkg_evt_t evt = {
+        .id = 2
+    };
+    luat_rtos_queue_send(qt, &evt, sizeof(pkg_evt_t), 0);
+    return 0;
+}
+
 static int ch390h_bootup(ch390h_t* ch) {
 static int ch390h_bootup(ch390h_t* ch) {
+    if (ch->ulwip.netif != NULL) {
+        return 0;
+    }
     // 初始化SPI设备, 由外部代码初始化, 因为不同bsp的速度不一样, 就不走固定值了
     // 初始化SPI设备, 由外部代码初始化, 因为不同bsp的速度不一样, 就不走固定值了
+    luat_gpio_cfg_t gpio_cfg = {0};
 
 
     // 初始化CS脚
     // 初始化CS脚
     luat_gpio_t gpio = {0};
     luat_gpio_t gpio = {0};
@@ -53,7 +72,21 @@ static int ch390h_bootup(ch390h_t* ch) {
     gpio.irq = 1;
     gpio.irq = 1;
     luat_gpio_setup(&gpio);
     luat_gpio_setup(&gpio);
 
 
-    // TODO 初始化INT脚
+    // 初始化INT脚
+    if (ch->intpin != 0xff) {
+        luat_gpio_set_default_cfg(&gpio_cfg);
+        gpio_cfg.pin = ch->intpin;
+        gpio_cfg.mode = LUAT_GPIO_IRQ;
+        gpio_cfg.irq_type = LUAT_GPIO_RISING_IRQ;
+        gpio_cfg.pull = 0;
+        gpio_cfg.irq_cb = ch390h_irq_cb;
+        luat_gpio_open(&gpio_cfg);
+        LLOGI("enable irq mode in pin %d", ch->intpin);
+        s_ch390h_mode = 1;
+    }
+    else {
+        // LLOGI("enable pull mode, use pool mode");
+    }
 
 
     // 初始化dhcp相关资源
     // 初始化dhcp相关资源
     ch->ulwip.netif = ch->netif;
     ch->ulwip.netif = ch->netif;
@@ -249,6 +282,9 @@ static int task_loop_one(ch390h_t* ch, luat_ch390h_cstring_t* cs) {
         luat_ch390h_basic_config(ch);
         luat_ch390h_basic_config(ch);
         luat_ch390h_set_phy(ch, 1);
         luat_ch390h_set_phy(ch, 1);
         luat_ch390h_set_rx(ch, 1);
         luat_ch390h_set_rx(ch, 1);
+        if (ch->intpin != 255) {
+            luat_ch390h_write_reg(ch, 0x7F, 1); // 开启接收中断
+        }
         return 0; // 等待下一个周期
         return 0; // 等待下一个周期
     }
     }
     if (check_vid_pid(ch)) {
     if (check_vid_pid(ch)) {
@@ -318,6 +354,9 @@ static int task_loop_one(ch390h_t* ch, luat_ch390h_cstring_t* cs) {
             luat_ch390h_basic_config(ch);
             luat_ch390h_basic_config(ch);
             luat_ch390h_set_phy(ch, 1);
             luat_ch390h_set_phy(ch, 1);
             luat_ch390h_set_rx(ch, 1);
             luat_ch390h_set_rx(ch, 1);
+            if (ch->intpin != 255) {
+                luat_ch390h_write_reg(ch, 0x7F, 1); // 开启接收中断
+            }
             return 0;
             return 0;
         }
         }
         if (len > 0) {
         if (len > 0) {
@@ -346,6 +385,10 @@ static int task_loop_one(ch390h_t* ch, luat_ch390h_cstring_t* cs) {
     else {
     else {
         // LLOGD("没有数据待读取");
         // LLOGD("没有数据待读取");
     }
     }
+
+    if (ch->intpin != 255) {
+        luat_ch390h_write_reg(ch, 0x7E, 0x3F); // 清除中断
+    }
     
     
     // 这一轮处理完成了
     // 这一轮处理完成了
     // 如果rx有数据, 那就不要等待, 立即开始下一轮
     // 如果rx有数据, 那就不要等待, 立即开始下一轮
@@ -376,6 +419,7 @@ static int task_wait_msg(uint32_t timeout) {
     ch390h_t *ch = NULL;
     ch390h_t *ch = NULL;
     pkg_evt_t evt = {0};
     pkg_evt_t evt = {0};
     int ret = luat_rtos_queue_recv(qt, &evt, sizeof(pkg_evt_t), timeout);
     int ret = luat_rtos_queue_recv(qt, &evt, sizeof(pkg_evt_t), timeout);
+    // LLOGD("evt id %d ret %d timeout %d", evt.id, ret, timeout);
     if (ret == 0 && evt.id == 1) {
     if (ret == 0 && evt.id == 1) {
         // 收到消息了
         // 收到消息了
         ch = (ch390h_t *)evt.ch;
         ch = (ch390h_t *)evt.ch;
@@ -390,6 +434,9 @@ static int task_wait_msg(uint32_t timeout) {
         return 1; // 拿到消息, 那队列里可能还有消息, 马上执行下一轮操作
         return 1; // 拿到消息, 那队列里可能还有消息, 马上执行下一轮操作
     }
     }
     else {
     else {
+        // if (evt.id == 2) {
+        //     LLOGD("CH390中断触发");
+        // }
         ret = task_loop(NULL, NULL);
         ret = task_loop(NULL, NULL);
     }
     }
     return ret;
     return ret;
@@ -411,7 +458,12 @@ static void ch390_task_main(void* args) {
             }
             }
             count = 0;
             count = 0;
         }
         }
-        ret = task_wait_msg(5);
+        if (s_ch390h_mode == 0) {
+            ret = task_wait_msg(5);
+        }
+        else {
+            ret = task_wait_msg(1000);
+        }
     }
     }
 }
 }
 
 

+ 10 - 1
demo/airlink/air8000_wifi_eth/main.lua

@@ -84,7 +84,7 @@ function eth_wan()
         0,--CPHA
         0,--CPHA
         0,--CPOL
         0,--CPOL
         8,--数据宽度
         8,--数据宽度
-        25600000--,--波特率
+        51200000--,--波特率
     )
     )
     log.info("main", "open spi",result)
     log.info("main", "open spi",result)
     if result ~= 0 then--返回值为0,表示打开成功
     if result ~= 0 then--返回值为0,表示打开成功
@@ -94,6 +94,15 @@ function eth_wan()
 
 
     netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=1,cs=12})
     netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=1,cs=12})
     netdrv.dhcp(socket.LWIP_ETH, true)
     netdrv.dhcp(socket.LWIP_ETH, true)
+
+    while 1 do
+        local ip = netdrv.ipv4(socket.LWIP_ETH)
+        if ip and ip ~= "0.0.0.0" then
+            break
+        end
+        sys.wait(100)
+    end
+    iperf.server(socket.LWIP_ETH)
 end
 end
 
 
 sys.taskInit(function()
 sys.taskInit(function()