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

add:i2s回调和异步接收功能

alienwalker 3 лет назад
Родитель
Сommit
7cef7615d1
2 измененных файлов с 118 добавлено и 10 удалено
  1. 1 0
      luat/include/luat_i2s.h
  2. 117 10
      luat/modules/luat_lib_i2s.c

+ 1 - 0
luat/include/luat_i2s.h

@@ -21,5 +21,6 @@ int luat_i2s_setup(luat_i2s_conf_t *conf);
 int luat_i2s_send(uint8_t id, char* buff, size_t len);
 int luat_i2s_recv(uint8_t id, char* buff, size_t len);
 int luat_i2s_close(uint8_t id);
+int32_t luat_i2s_rx_cb(void *pdata, void *param);
 
 #endif

+ 117 - 10
luat/modules/luat_lib_i2s.c

@@ -9,9 +9,64 @@
 #include "luat_malloc.h"
 #include "luat_i2s.h"
 #include "luat_zbuff.h"
-
+#include "c_common.h"
 #define LUAT_LOG_TAG "i2s"
 #include "luat_log.h"
+#ifndef I2S_DEVICE_MAX_CNT
+#define I2S_DEVICE_MAX_CNT 2
+#endif
+static int i2s_cbs[I2S_DEVICE_MAX_CNT];
+static luat_zbuff_t *i2s_rx_buffer[I2S_DEVICE_MAX_CNT];
+
+
+int l_i2s_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 i2s_id = msg->arg1;
+    lua_geti(L, LUA_REGISTRYINDEX, i2s_cbs[i2s_id]);
+    if (lua_isfunction(L, -1)) {
+        if (msg->arg2 == 0) {
+            //LLOGD("uart%ld sent callback", i2s_id);
+    		lua_pushnil(L);
+    		lua_call(L, 1, 0);
+        }
+        else {
+        	lua_pushlightuserdata(L, i2s_rx_buffer[i2s_id]);
+            lua_call(L, 1, 0);
+        }
+    }
+    // 给rtos.recv方法返回个空数据
+    lua_pushinteger(L, 0);
+    return 1;
+}
+
+int32_t luat_i2s_rx_cb(void *pdata, void *param)
+{
+	Buffer_Struct *buffer = (Buffer_Struct *)pdata;
+	int id = (int)param;
+	if (!i2s_rx_buffer[id] || !i2s_cbs[id])
+	{
+		return -1;
+	}
+	if (buffer && (buffer->Pos))
+	{
+		uint32_t len = (buffer->Pos > i2s_rx_buffer[id]->len)?i2s_rx_buffer[id]->len:buffer->Pos;
+		memcpy(i2s_rx_buffer[id]->addr, buffer->Data, len);
+		i2s_rx_buffer[id]->used = len;
+        rtos_msg_t msg;
+        msg.handler = l_i2s_handler;
+        msg.ptr = NULL;
+        msg.arg1 = id;
+        msg.arg2 = len;
+        int re = luat_msgbus_put(&msg, 0);
+		buffer->Pos = 0;
+
+	}
+
+	return 0;
+}
 
 /*
 初始化i2s
@@ -87,20 +142,36 @@ static int l_i2s_send(lua_State *L) {
     return 2;
 }
 
-// 暂不支持读取
+/*
+接收i2s数据,注意在数据在回调时已经存放在zbuff里,目前只有air780e系列支持
+@api i2s.recv(id, buffer, len)
+@int 通道id
+@zbuff 数据缓存区
+@int 单次返回的数据长度,单位字节,必须与传入的zbuff的大小一致
+@return boolean 成功与否
+@usage
+local buffer = zbuff.create(3200)
+local succ = i2s.recv(0, buffer, 3200);
+*/
 static int l_i2s_recv(lua_State *L) {
     luaL_Buffer buff;
     int id = luaL_checkinteger(L, 1);
-    size_t len = luaL_checkinteger(L, 2);
-    char* buff2 = luaL_buffinitsize(L, &buff, len);
-    int ret = luat_i2s_recv(id, buff2, len);
-    if (ret > 0)
-        luaL_pushresultsize(&buff, ret);
+    if (id >= I2S_DEVICE_MAX_CNT)
+    {
+    	lua_pushboolean(L, 0);
+        return 1;
+    }
+    if (lua_isuserdata(L, 2)) {
+        luat_zbuff_t* zbuff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
+        i2s_rx_buffer[id] = zbuff;
+    }
     else {
-        lua_pushstring(L, "");
+    	i2s_rx_buffer[id] = NULL;
     }
-    lua_pushinteger(L, ret);
-    return 2;
+
+    size_t len = luaL_checkinteger(L, 2);
+	lua_pushboolean(L, !luat_i2s_recv(id, NULL, len));
+    return 1;
 }
 
 /*
@@ -117,6 +188,41 @@ static int l_i2s_close(lua_State *L) {
     return 0;
 }
 
+/*
+注册I2S事件回调
+@api    i2s.on(id, func)
+@int i2s id, i2s0写0, i2s1写1
+@function 回调方法
+@return nil 无返回值
+@usage
+i2s.on(0, function(id, buff)
+	if buff then
+		log.info("i2s get data in zbuff")
+	else
+		log.info("i2s tx one block done")
+	end
+end)
+*/
+static int l_i2s_on(lua_State *L) {
+    int i2s_id = luaL_checkinteger(L, 1);
+    int org_i2s_id = i2s_id;
+
+    if (i2s_id >= I2S_DEVICE_MAX_CNT)
+    {
+        lua_pushliteral(L, "no such i2s id");
+        return 1;
+    }
+    if (i2s_cbs[i2s_id] != 0)
+    {
+    	luaL_unref(L, LUA_REGISTRYINDEX, i2s_cbs[i2s_id]);
+    }
+    if (lua_isfunction(L, 2)) {
+        lua_pushvalue(L, 2);
+        i2s_cbs[i2s_id] = luaL_ref(L, LUA_REGISTRYINDEX);
+    }
+    return 0;
+}
+
 int l_i2s_play(lua_State *L);
 int l_i2s_pause(lua_State *L);
 int l_i2s_stop(lua_State *L);
@@ -145,6 +251,7 @@ static const rotable_Reg_t reg_i2s[] =
     { "send",       ROREG_FUNC(l_i2s_send)},
     { "recv",       ROREG_FUNC(l_i2s_recv)},
     { "close",      ROREG_FUNC(l_i2s_close)},
+	{ "on",       ROREG_FUNC(l_i2s_on)},
     // 以下为兼容扩展功能,待定
     { "play",       ROREG_FUNC(l_i2s_play)},
     { "pause",      ROREG_FUNC(l_i2s_pause)},