luat_lib_spislave.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. @module spislave
  3. @summary SPI从机
  4. @version 1.0
  5. @date 2024.3.27
  6. @demo spislave
  7. @tag LUAT_USE_SPI_SLAVE
  8. @usage
  9. -- 请查阅demo
  10. -- 当前仅XT804系列支持, 例如 Air101/Air103/Air601
  11. */
  12. #include "luat_base.h"
  13. #include "rotable2.h"
  14. #include "luat_zbuff.h"
  15. #include "luat_msgbus.h"
  16. #include "luat_timer.h"
  17. #include "luat_spi_slave.h"
  18. #define LUAT_LOG_TAG "spislave"
  19. #include "luat_log.h"
  20. // 存放回调函数
  21. static int lua_cb_ref;
  22. /*
  23. 初始化SPI从机
  24. @api spislave.setup(id, opts)
  25. @int 从机SPI的编号,注意与SPI主机的编号的差异,这个与具体设备相关
  26. @table opts 扩展配置参数,当前无参数
  27. @return boolean true表示成功,其他失败
  28. @usage
  29. -- 当前仅XT804系列支持, 例如 Air101/Air103/Air601/Air690
  30. -- Air101为例, 初始化SPI从机, 编号为2, SPI模式
  31. spislave.setup(2)
  32. -- Air101为例, 初始化SPI从机, 编号为3, SDIO模式
  33. spislavve.setup(3)
  34. */
  35. static int l_spi_slave_setup(lua_State *L) {
  36. luat_spi_slave_conf_t conf = {
  37. .id = luaL_checkinteger(L, 1)
  38. };
  39. int ret = luat_spi_slave_open(&conf);
  40. if (ret) {
  41. lua_pushboolean(L, 0);
  42. lua_pushinteger(L, ret);
  43. return 2;
  44. }
  45. lua_pushboolean(L, 1);
  46. return 1;
  47. }
  48. /*
  49. 是否可写
  50. @api spislave.ready(id)
  51. @int 从机SPI的编号
  52. @return boolean true表示可写,其他不可写
  53. */
  54. static int l_spi_slave_ready(lua_State *L) {
  55. luat_spi_slave_conf_t conf = {
  56. .id = luaL_checkinteger(L, 1)
  57. };
  58. int ret = luat_spi_slave_writable(&conf);
  59. if (ret) {
  60. lua_pushboolean(L, 1);
  61. return 1;
  62. }
  63. return 0;
  64. }
  65. /*
  66. 注册事件回调函数
  67. @api spislave.on(id, cb)
  68. @int 从机SPI的编号
  69. @function 回调函数
  70. */
  71. static int l_spi_slave_on(lua_State *L) {
  72. if (lua_cb_ref) {
  73. luaL_unref(L, LUA_REGISTRYINDEX, lua_cb_ref);
  74. lua_cb_ref = 0;
  75. }
  76. if (lua_isfunction(L, 2)) {
  77. lua_pushvalue(L, 2);
  78. lua_cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  79. }
  80. return 0;
  81. }
  82. /*
  83. 读取数据
  84. @api spislave.read(id, ptr, buff, len)
  85. @int 从机SPI的编号
  86. @userdata 用户数据指针, 从回调函数得到
  87. @int zbuff缓冲对象
  88. @int 读取长度,从回调函数得到
  89. @return int 读取到字节数,通常与期望读取的长度相同
  90. @return int 错误码, 仅当出错时返回
  91. */
  92. static int l_spi_slave_read(lua_State *L) {
  93. luat_spi_slave_conf_t conf = {
  94. .id = luaL_checkinteger(L, 1)
  95. };
  96. void* ptr = lua_touserdata(L, 2);
  97. luat_zbuff_t* zbuf = (luat_zbuff_t *)luaL_checkudata(L, 3, LUAT_ZBUFF_TYPE);
  98. int len = luaL_checkinteger(L, 4);
  99. int ret = luat_spi_slave_read(&conf, ptr, zbuf->addr, len);
  100. if (ret >= 0 ){
  101. lua_pushinteger(L, ret);
  102. return 1;
  103. }
  104. lua_pushinteger(L, 0);
  105. lua_pushinteger(L, ret);
  106. return 2;
  107. }
  108. /*
  109. 写入数据
  110. @api spislave.write(id, ptr, buff, len)
  111. @int 从机SPI的编号
  112. @userdata 用户数据指针, 当前传nil
  113. @int zbuff缓冲对象
  114. @int 写入长度,注意不能超过硬件限制,通常是1500字节
  115. @return boolean true表示成功,其他失败
  116. @return int 错误码, 仅当出错时返回
  117. */
  118. static int l_spi_slave_write(lua_State *L) {
  119. luat_spi_slave_conf_t conf = {
  120. .id = luaL_checkinteger(L, 1)
  121. };
  122. luat_zbuff_t* zbuf = (luat_zbuff_t *)luaL_checkudata(L, 3, LUAT_ZBUFF_TYPE);
  123. int len = luaL_checkinteger(L, 4);
  124. int ret = luat_spi_slave_write(&conf, zbuf->addr, len);
  125. if (ret == 0 ){
  126. lua_pushboolean(L, 1);
  127. return 1;
  128. }
  129. lua_pushboolean(L, 0);
  130. lua_pushinteger(L, ret);
  131. return 2;
  132. }
  133. static const rotable_Reg_t reg_spi_slave[] = {
  134. { "setup", ROREG_FUNC(l_spi_slave_setup)},
  135. { "ready", ROREG_FUNC(l_spi_slave_ready)},
  136. { "read", ROREG_FUNC(l_spi_slave_read)},
  137. { "write", ROREG_FUNC(l_spi_slave_write)},
  138. { "on", ROREG_FUNC(l_spi_slave_on)},
  139. { NULL, ROREG_INT(0)}
  140. };
  141. LUAMOD_API int luaopen_spislave(lua_State *L)
  142. {
  143. luat_newlib2(L, reg_spi_slave);
  144. return 1;
  145. }
  146. static int l_spi_slave_event_handler(lua_State *L, void* ptr) {
  147. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  148. if (!lua_cb_ref) {
  149. return 0; // 没设置回调函数, 直接退出
  150. }
  151. lua_rawgeti(L, LUA_REGISTRYINDEX, lua_cb_ref);
  152. if (!lua_isfunction(L, -1)) {
  153. return 0; // 没设置回调函数, 直接退出
  154. }
  155. lua_pushinteger(L, msg->arg1);
  156. lua_pushlightuserdata(L, msg->ptr);
  157. lua_pushinteger(L, msg->arg2);
  158. lua_call(L, 3, 0);
  159. return 0;
  160. }
  161. int l_spi_slave_event(int id, int event, void* buff, size_t max_size) {
  162. rtos_msg_t msg = {
  163. .handler = l_spi_slave_event_handler,
  164. .arg1 = id | event,
  165. .arg2 = max_size,
  166. .ptr = buff,
  167. };
  168. luat_msgbus_put(&msg, 0);
  169. return 0;
  170. }