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

update:usb透传收发和消息回调,虚拟串口扩展到3个

alienwalker 1 месяц назад
Родитель
Сommit
5abbbcef42
3 измененных файлов с 177 добавлено и 18 удалено
  1. 11 2
      luat/include/luat_usb.h
  2. 1 1
      luat/modules/luat_lib_uart.c
  3. 165 15
      luat/modules/luat_lib_usb.c

+ 11 - 2
luat/include/luat_usb.h

@@ -10,10 +10,15 @@ enum
 	LUAT_USB_CLASS_CDC_ACM = 0,
 	LUAT_USB_CLASS_AUDIO,
 	LUAT_USB_CLASS_CAMERA,
-	LUAT_USB_CLASS_HIB,
+	LUAT_USB_CLASS_HID,
 	LUAT_USB_CLASS_MSC,
 	LUAT_USB_CLASS_WINUSB,
-
+	LUAT_USB_EVENT_NEW_RX	= 0,
+	LUAT_USB_EVENT_TX_DONE,
+	LUAT_USB_EVENT_CONNECT,
+	LUAT_USB_EVENT_DISCONNECT,
+	LUAT_USB_EVENT_SUSPEND,
+	LUAT_USB_EVENT_RESUME,
 };
 
 typedef void (*usb_callback_t)(int id, int event, uint8_t *data, uint32_t len);
@@ -31,4 +36,8 @@ int luat_usb_get_free_ep_num(int id);
 int luat_usb_clear_class(int id);
 
 int luat_usb_set_callback(int id, usb_callback_t callback);
+
+int luat_usb_tx(int id, uint8_t class, const void *data, uint32_t len);
+int luat_usb_hid_tx(int id, const char *string, uint32_t len);
+int luat_usb_rx(int id, uint8_t class, void *data, uint32_t len);
 #endif

+ 1 - 1
luat/modules/luat_lib_uart.c

@@ -37,7 +37,7 @@
 #define MAX_DEVICE_COUNT 9
 #endif
 
-#define MAX_USB_DEVICE_COUNT 1
+#define MAX_USB_DEVICE_COUNT 3
 
 typedef struct luat_uart_cb {
     int received;//回调函数

+ 165 - 15
luat/modules/luat_lib_usb.c

@@ -16,6 +16,8 @@ usb.mode(0, usb.DEVICE)		--usb设置成从机模式
 usb.add_class(0, usb.CDC_ACM, 1)	--使用1个CDC-ACM虚拟串口功能
 usb.add_class(0, usb.WINUSB, 1)		--使用1个WINUSB功能
 pm.power(pm.USB, true)		--USB上电初始化开始工作
+--说明
+目前设备类只有usb.HID和usb.WINUSB可以通过usb操作库api和对端通讯,usb.CDC-ACM虚拟串口直接使用uart api
 ]]
 */
 #include "luat_base.h"
@@ -28,6 +30,108 @@ pm.power(pm.USB, true)		--USB上电初始化开始工作
 #include "luat_log.h"
 #include "rotable2.h"
 
+#define MAX_USB_DEVICE_COUNT 2
+static int l_usb_cb[MAX_USB_DEVICE_COUNT];
+
+int l_usb_handler(lua_State *L, void* ptr) {
+    (void)ptr;
+    rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
+    lua_pop(L, 1);
+    int usb_id = msg->arg1 & 0x000000ff;
+    int class_id = (msg->arg1 & 0x0000ff00) >> 8;
+    if (l_usb_cb[usb_id] && usb_id < MAX_USB_DEVICE_COUNT)
+    {
+        lua_geti(L, LUA_REGISTRYINDEX, l_usb_cb[usb_id]);
+        lua_pushinteger(L, usb_id);
+        lua_pushinteger(L, msg->arg2);
+        if (class_id != 0x000000ff)
+        {
+        	lua_pushinteger(L, class_id);
+        }
+        else
+        {
+        	lua_pushnil(L);
+        }
+        lua_call(L, 3, 0);
+    }
+    // 给rtos.recv方法返回个空数据
+    lua_pushinteger(L, 0);
+    return 1;
+}
+
+
+/*
+USB发送数据,目前仅限于HID和WINUSB设备,CDC-ACM虚拟串口直接使用串口API操作
+@api usb.tx(id, data, class)
+@int 设备id,默认为0
+@zbuff or string 需要发送的数据
+@int 设备类
+@return bool 成功返回true,否则返回false,总线id填错,所填设备类不支持直接发送数据等情况下返回错误
+@usage
+-- HID上传数据
+usb.tx(0, "1234", usb.HID) -- usb hid上传0x31 0x32 0x33 0x34  + N个0
+*/
+static int l_usb_tx(lua_State* L) {
+	int result;
+    uint8_t class = luaL_optinteger(L, 3, LUAT_USB_CLASS_WINUSB);
+    int usb_id = luaL_optinteger(L, 1, 0);
+    const char *buf;
+    luat_zbuff_t *buff = NULL;
+    if(lua_isuserdata(L, 2)) {
+        buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
+        result = luat_usb_tx(usb_id, class, buff->addr, buff->used);
+    } else {
+    	size_t len;
+    	buf = luaL_checklstring(L, 2, &len);
+    	if (LUAT_USB_CLASS_HID == class)
+    	{
+    		result = luat_usb_hid_tx(usb_id, buf, len);
+    	}
+    	else
+    	{
+    		result = luat_usb_tx(usb_id, class, buf, len);
+    	}
+        lua_pushboolean(L, !result);
+    }
+    return 1;
+}
+
+/*
+buff形式读接收到的数据,一次读出全部数据存入buff中,如果buff空间不够会自动扩展
+@api usb.rx(id, buff, class)
+@int 设备id,默认为0
+@zbuff zbuff对象
+@int 设备类
+@return int 返回读到的长度,并把zbuff指针后移
+@usage
+usb.rx(0, buff, usb.HID)
+*/
+static int l_usb_rx(lua_State *L)
+{
+    uint8_t class = luaL_optinteger(L, 3, LUAT_USB_CLASS_WINUSB);
+    int usb_id = luaL_optinteger(L, 1, 0);
+
+    if(lua_isuserdata(L, 2)){//zbuff对象特殊处理
+    	luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
+        int result = luat_usb_rx(usb_id, class, NULL, 0);	//读出当前缓存的长度
+        if (result > (buff->len - buff->used))
+        {
+        	__zbuff_resize(buff, buff->len + result);
+        }
+        result = luat_usb_rx(usb_id, class, buff->addr + buff->used, result);
+        lua_pushinteger(L, result);
+        buff->used += result;
+        return 1;
+    }
+    else
+    {
+        lua_pushinteger(L, 0);
+        return 1;
+    }
+    return 1;
+}
+
+
 /*
 设置USB工作模式,必须在USB外设掉电不工作时进行设置
 @api usb.mode(id, mode)
@@ -45,6 +149,37 @@ static int l_usb_mode(lua_State* L) {
     return 1;
 }
 
+/*
+注册USB事件回调
+@api usb.on(id, func)
+@int usb总线id,默认0,如果芯片只有1条USB线,填0
+@function 回调方法
+@return nil 无返回值
+@usage
+usb.on(0, function(id, class, event)
+    log.info("usb", id, class, event)
+end)
+--回调参数有3个
+1、usb总线id
+2、event,见usb.EV_XXX
+3、如果event是usb.EV_RX或usb.EV_TX,则第三个参数表示哪个设备类,目前只有usb.HID和usb.WINUSB
+*/
+static int l_usb_on(lua_State *L) {
+    int usb_id = luaL_optinteger(L, 1, 0);
+    if (usb_id >= MAX_USB_DEVICE_COUNT) return 0;
+    if (l_usb_cb[usb_id])
+    {
+    	luaL_unref(L, LUA_REGISTRYINDEX, l_usb_cb[usb_id]);
+    }
+	if (lua_isfunction(L, 2)) {
+		lua_pushvalue(L, 2);
+		l_usb_cb[usb_id] = luaL_ref(L, LUA_REGISTRYINDEX);
+	}
+    return 0;
+}
+
+
+
 /*
 设置/获取USB的VID,必须在USB外设掉电不工作时进行设置,获取没有限制
 @api usb.vid(id, vid)
@@ -161,31 +296,46 @@ static int l_usb_get_free_ep_num(lua_State* L) {
 
 static const rotable_Reg_t reg_usb[] =
 {
-	{ "mode" ,         ROREG_FUNC(l_usb_mode)},
-	{ "vid" ,         ROREG_FUNC(l_usb_vid)},
-	{ "pid" ,         ROREG_FUNC(l_usb_pid)},
-	{ "add_class" ,         ROREG_FUNC(l_usb_add_class)},
-	{ "clear_all_class" ,         ROREG_FUNC(l_usb_clear_all_class)},
-	{ "get_free_ep_num" ,         ROREG_FUNC(l_usb_get_free_ep_num)},
+	{ "tx",					ROREG_FUNC(l_usb_tx)},
+	{ "rx",					ROREG_FUNC(l_usb_rx)},
+	{ "mode",				ROREG_FUNC(l_usb_mode)},
+	{ "add_class",      	ROREG_FUNC(l_usb_add_class)},
+	{ "on",         		ROREG_FUNC(l_usb_on)},
+	{ "vid",         		ROREG_FUNC(l_usb_vid)},
+	{ "pid",         		ROREG_FUNC(l_usb_pid)},
+	{ "clear_all_class" ,   ROREG_FUNC(l_usb_clear_all_class)},
+	{ "get_free_ep_num" ,   ROREG_FUNC(l_usb_get_free_ep_num)},
 	//@const HOST number USB主机模式
-    { "HOST",        ROREG_INT(LUAT_USB_MODE_HOST)},
+    { "HOST",        		ROREG_INT(LUAT_USB_MODE_HOST)},
 	//@const DEVICE number USB从机模式
-    { "DEVICE",       ROREG_INT(LUAT_USB_MODE_DEVICE)},
+    { "DEVICE",       		ROREG_INT(LUAT_USB_MODE_DEVICE)},
 	//@const OTG number USB otg模式
-    { "OTG",       ROREG_INT(LUAT_USB_MODE_OTG)},
+    { "OTG",       			ROREG_INT(LUAT_USB_MODE_OTG)},
 	//@const CDC_ACM number cdc_acm 虚拟串口类
-    { "CDC_ACM",        ROREG_INT(LUAT_USB_CLASS_CDC_ACM)},
+    { "CDC_ACM",        	ROREG_INT(LUAT_USB_CLASS_CDC_ACM)},
 	//@const AUDIO number audio音频类
-    { "AUDIO",       ROREG_INT(LUAT_USB_CLASS_AUDIO)},
+    { "AUDIO",       		ROREG_INT(LUAT_USB_CLASS_AUDIO)},
 	//@const CAMERA number 摄像头类
-    { "CAMERA",        ROREG_INT(LUAT_USB_CLASS_CAMERA)},
+    { "CAMERA",        		ROREG_INT(LUAT_USB_CLASS_CAMERA)},
 	//@const HID number HID设备类,只支持键盘和自定义
-    { "HID",       ROREG_INT(LUAT_USB_CLASS_HIB)},
+    { "HID",       			ROREG_INT(LUAT_USB_CLASS_HID)},
 	//@const MSC number 大容量存储类,也就是U盘,TF卡
-    { "MSC",       ROREG_INT(LUAT_USB_CLASS_MSC)},
+    { "MSC",       			ROREG_INT(LUAT_USB_CLASS_MSC)},
 	//@const WINUSB number WINUSB类,透传数据
-    { "WINUSB",       ROREG_INT(LUAT_USB_CLASS_MSC)},
+    { "WINUSB",       		ROREG_INT(LUAT_USB_CLASS_WINUSB)},
 
+	//@const EV_RX number  有新的数据到来
+    { "EV_RX",       		ROREG_INT(LUAT_USB_EVENT_NEW_RX)},
+	//@const EV_TX number 所有数据都已发送
+    { "EV_TX",        		ROREG_INT(LUAT_USB_EVENT_TX_DONE)},
+	//@const EV_CONNECT number usb从机已经连接上并且枚举成功
+    { "EV_CONNECT",       	ROREG_INT(LUAT_USB_EVENT_CONNECT)},
+	//@const EV_DISCONNECT number usb从机断开
+    { "EV_DISCONNECT",      ROREG_INT(LUAT_USB_EVENT_DISCONNECT)},
+	//@const EV_SUSPEND number usb从机挂起
+    { "EV_SUSPEND",       	ROREG_INT(LUAT_USB_EVENT_SUSPEND)},
+	//@const EV_RESUME number usb从机恢复
+    { "EV_RESUME",       	ROREG_INT(LUAT_USB_EVENT_RESUME)},
     { NULL,         ROREG_INT(0) }
 };