luat_lib_lora.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /*
  2. @module lora2
  3. @summary lora2驱动模块(支持多挂)
  4. @version 1.0
  5. @date 2022.06.24
  6. @demo lora
  7. @tag LUAT_USE_LORA2
  8. */
  9. #include "luat_base.h"
  10. #include "luat_rtos.h"
  11. #include "luat_gpio.h"
  12. #include "luat_spi.h"
  13. #include "luat_malloc.h"
  14. #include "sx126x/radio.h"
  15. #include "sx126x/sx126x.h"
  16. #include "sx126x/sx126x-board.h"
  17. #define LUAT_LOG_TAG "lora"
  18. #include "luat_log.h"
  19. enum{
  20. LORA_TX_DONE,
  21. LORA_RX_DONE,
  22. LORA_TX_TIMEOUT,
  23. LORA_RX_TIMEOUT,
  24. LORA_RX_ERROR,
  25. };
  26. #define LUAT_LORA_TYPE "LORA*"
  27. static lora_device_t * get_lora_device(lua_State *L){
  28. if (luaL_testudata(L, 1, LUAT_LORA_TYPE)){
  29. return ((lora_device_t *)luaL_checkudata(L, 1, LUAT_LORA_TYPE));
  30. }else{
  31. return ((lora_device_t *)lua_touserdata(L, 1));
  32. }
  33. }
  34. typedef struct lora_data{
  35. uint16_t size;
  36. uint8_t payload[];
  37. }lora_data_t;
  38. static int l_lora_handler(lua_State* L, void* ptr) {
  39. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  40. lora_device_t *lora_device =(lora_device_t *)msg->ptr;
  41. int event = msg->arg1;
  42. lua_geti(L, LUA_REGISTRYINDEX, lora_device->lora_cb);
  43. if (lua_isfunction(L, -1)) {
  44. lua_geti(L, LUA_REGISTRYINDEX, lora_device->lora_ref);
  45. switch (event){
  46. case LORA_TX_DONE:
  47. lua_pushstring(L, "tx_done");
  48. lua_call(L, 2, 0);
  49. break;
  50. case LORA_RX_DONE:
  51. lua_pushstring(L, "rx_done");
  52. lora_data_t* rx_buff = (lora_data_t*)msg->arg2;
  53. lua_pushlstring(L, rx_buff->payload,rx_buff->size);
  54. lua_pushinteger(L, rx_buff->size);
  55. lua_call(L, 4, 0);
  56. luat_heap_free(rx_buff);
  57. break;
  58. case LORA_TX_TIMEOUT:
  59. lua_pushstring(L, "tx_timeout");
  60. lua_call(L, 2, 0);
  61. break;
  62. case LORA_RX_TIMEOUT:
  63. lua_pushstring(L, "rx_timeout");
  64. lua_call(L, 2, 0);
  65. break;
  66. case LORA_RX_ERROR:
  67. lua_pushstring(L, "rx_error");
  68. lua_call(L, 2, 0);
  69. break;
  70. }
  71. }
  72. return 0;
  73. }
  74. static void OnTxDone( lora_device_t* lora_device ){
  75. rtos_msg_t msg = {0};
  76. msg.handler = l_lora_handler;
  77. msg.ptr = lora_device;
  78. msg.arg1 = LORA_TX_DONE;
  79. msg.arg2 = 0;
  80. luat_msgbus_put(&msg, 1);
  81. }
  82. static void OnRxDone( lora_device_t* lora_device,uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ){
  83. // LLOGD("RxDone size:%d rssi:%d snr:%d",size,rssi,snr);
  84. // LLOGD("RxDone payload: %.*s",size,payload);
  85. lora_data_t* rx_buff = luat_heap_malloc(sizeof(lora_data_t)+ size);
  86. rx_buff->size = size;
  87. memcpy( rx_buff->payload, payload, size );
  88. rtos_msg_t msg = {0};
  89. msg.handler = l_lora_handler;
  90. msg.ptr = lora_device;
  91. msg.arg1 = LORA_RX_DONE;
  92. msg.arg2 = rx_buff;
  93. luat_msgbus_put(&msg, 1);
  94. }
  95. static void OnTxTimeout( lora_device_t* lora_device ){
  96. rtos_msg_t msg = {0};
  97. msg.handler = l_lora_handler;
  98. msg.ptr = lora_device;
  99. msg.arg1 = LORA_TX_TIMEOUT;
  100. msg.arg2 = 0;
  101. luat_msgbus_put(&msg, 1);
  102. }
  103. static void OnRxTimeout( lora_device_t* lora_device ){
  104. rtos_msg_t msg = {0};
  105. msg.handler = l_lora_handler;
  106. msg.ptr = lora_device;
  107. msg.arg1 = LORA_RX_TIMEOUT;
  108. msg.arg2 = 0;
  109. luat_msgbus_put(&msg, 1);
  110. }
  111. static void OnRxError( lora_device_t* lora_device ){
  112. rtos_msg_t msg = {0};
  113. msg.handler = l_lora_handler;
  114. msg.ptr = lora_device;
  115. msg.arg1 = LORA_RX_ERROR;
  116. msg.arg2 = 0;
  117. luat_msgbus_put(&msg, 1);
  118. }
  119. #define META_SPI "SPI*"
  120. /*
  121. lora初始化
  122. @api lora2.init(ic, loraconfig,spiconfig)
  123. @string lora 型号,当前支持:<br>llcc68<br>sx1268
  124. @table lora配置参数,与具体设备有关
  125. @return userdata 若成功会返回lora对象,否则返回nil
  126. @usage
  127. spi_lora = spi.deviceSetup(spi_id,pin_cs,0,0,8,10*1000*1000,spi.MSB,1,0)
  128. lora_device = lora2.init("llcc68",{res = pin_reset,busy = pin_busy,dio1 = pin_dio1},spi_lora)
  129. */
  130. static int luat_lora_init(lua_State *L){
  131. size_t len = 0;
  132. const char* lora_ic = luaL_checklstring(L, 1, &len);
  133. if(strcmp("llcc68",lora_ic)== 0||strcmp("LLCC68",lora_ic)== 0||strcmp("sx1268",lora_ic)== 0||strcmp("SX1268",lora_ic)== 0){
  134. lora_device_t *lora_device = (lora_device_t *)lua_newuserdata(L, sizeof(lora_device_t));
  135. if (!lora_device){
  136. LLOGE("out of memory when malloc lora_device");
  137. return 0;
  138. }
  139. RadioEvents_t RadioEvents;
  140. uint8_t id = 0,cs = 0,res = 0,busy = 0,dio1 = 0;
  141. lora_device->lora_init = true;
  142. if (lua_istable(L, 2)) {
  143. lua_pushstring(L, "id");
  144. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  145. id = luaL_checkinteger(L, -1);
  146. }
  147. lua_pop(L, 1);
  148. lua_pushstring(L, "cs");
  149. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  150. cs = luaL_checkinteger(L, -1);
  151. }
  152. lua_pop(L, 1);
  153. lua_pushstring(L, "res");
  154. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  155. res = luaL_checkinteger(L, -1);
  156. }
  157. lua_pop(L, 1);
  158. lua_pushstring(L, "busy");
  159. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  160. busy = luaL_checkinteger(L, -1);
  161. }
  162. lua_pop(L, 1);
  163. lua_pushstring(L, "dio1");
  164. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  165. dio1 = luaL_checkinteger(L, -1);
  166. }
  167. lua_pop(L, 1);
  168. lua_pushstring(L, "lora_init");
  169. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  170. lora_device->lora_init = lua_toboolean(L, -1);
  171. }
  172. lua_pop(L, 1);
  173. }
  174. if (luaL_testudata(L, 3, META_SPI)){
  175. lora_device->lora_spi_id = 255;
  176. lora_device->lora_spi_device = (luat_spi_device_t*)lua_touserdata(L, 3);
  177. }else{
  178. lora_device->lora_spi_id = id;
  179. lora_device->lora_pin_cs = cs;
  180. luat_gpio_mode(lora_device->lora_pin_cs, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  181. }
  182. lora_device->lora_pin_rst = res;
  183. lora_device->lora_pin_busy = busy;
  184. lora_device->lora_pin_dio1 = dio1;
  185. luat_gpio_mode(lora_device->lora_pin_rst, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  186. luat_gpio_mode(lora_device->lora_pin_busy, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
  187. luat_gpio_mode(lora_device->lora_pin_dio1, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
  188. RadioEvents.TxDone = OnTxDone;
  189. RadioEvents.RxDone = OnRxDone;
  190. RadioEvents.TxTimeout = OnTxTimeout;
  191. RadioEvents.RxTimeout = OnRxTimeout;
  192. RadioEvents.RxError = OnRxError;
  193. RadioEventsInit2(lora_device,&RadioEvents);
  194. if (lora_device->lora_init) Radio2.Init( lora_device,&RadioEvents );
  195. luat_rtos_timer_create(&lora_device->timer);
  196. luat_rtos_timer_start(lora_device->timer, 10, 1, Radio2.IrqProcess, lora_device);
  197. luaL_setmetatable(L, LUAT_LORA_TYPE);
  198. lua_pushvalue(L, -1);
  199. lora_device->lora_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  200. return 1;
  201. }
  202. else {
  203. LLOGE("no such ic %s", lora_ic);
  204. }
  205. return 0;
  206. }
  207. /*
  208. 设置频道频率
  209. @api lora_device:set_channel(freq)
  210. @number 频率
  211. @usage
  212. lora_device:set_channel(433000000)
  213. */
  214. static int luat_lora_set_channel(lua_State *L){
  215. lora_device_t * lora_device = get_lora_device(L);
  216. uint32_t freq = luaL_optinteger(L, 2,433000000);
  217. Radio2.SetChannel(lora_device,freq);
  218. return 0;
  219. }
  220. /*
  221. lora配置发送参数
  222. @api lora_device:set_txconfig(txconfig)
  223. @table lora发送配置参数,与具体设备有关
  224. @usage
  225. lora_device:set_txconfig(
  226. {
  227. mode=1,
  228. power=22,
  229. fdev=0,
  230. bandwidth=0,
  231. datarate=9,
  232. coderate=4,
  233. preambleLen=8,
  234. fixLen=false,
  235. crcOn=true,
  236. freqHopOn=0,
  237. hopPeriod=0,
  238. iqInverted=false,
  239. timeout=3000
  240. }
  241. )
  242. */
  243. static int luat_lora_set_txconfig(lua_State *L){
  244. uint8_t mode = 1,power = 0,fdev = 0,bandwidth = 0,datarate = 9,coderate = 4,preambleLen = 8,freqHopOn = 0,hopPeriod = 0;
  245. uint32_t timeout = 0;
  246. bool fixLen = false,crcOn = true,iqInverted = false,rateOptimize = false;
  247. lora_device_t * lora_device = get_lora_device(L);
  248. if (lua_istable(L, 2)) {
  249. lua_pushstring(L, "mode");
  250. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  251. mode = luaL_optinteger(L, -1,1);
  252. }
  253. lua_pop(L, 1);
  254. lua_pushstring(L, "power");
  255. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  256. power = luaL_optinteger(L, -1,22);
  257. }
  258. lua_pop(L, 1);
  259. lua_pushstring(L, "fdev");
  260. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  261. fdev = luaL_optinteger(L, -1,0);
  262. }
  263. lua_pop(L, 1);
  264. lua_pushstring(L, "bandwidth");
  265. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  266. bandwidth = luaL_optinteger(L, -1,0);
  267. }
  268. lua_pop(L, 1);
  269. lua_pushstring(L, "datarate");
  270. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  271. datarate = luaL_optinteger(L, -1,9);
  272. }
  273. lua_pop(L, 1);
  274. lua_pushstring(L, "coderate");
  275. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  276. coderate = luaL_optinteger(L, -1,4);
  277. }
  278. lua_pop(L, 1);
  279. lua_pushstring(L, "preambleLen");
  280. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  281. preambleLen = luaL_optinteger(L, -1,8);
  282. }
  283. lua_pop(L, 1);
  284. lua_pushstring(L, "fixLen");
  285. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  286. fixLen = lua_toboolean(L, -1);
  287. }
  288. lua_pop(L, 1);
  289. lua_pushstring(L, "crcOn");
  290. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  291. crcOn = lua_toboolean(L, -1);
  292. }
  293. lua_pop(L, 1);
  294. lua_pushstring(L, "freqHopOn");
  295. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  296. freqHopOn = luaL_optinteger(L, -1,0);
  297. }
  298. lua_pop(L, 1);
  299. lua_pushstring(L, "hopPeriod");
  300. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  301. hopPeriod = luaL_optinteger(L, -1,0);
  302. }
  303. lua_pop(L, 1);
  304. lua_pushstring(L, "iqInverted");
  305. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  306. iqInverted = lua_toboolean(L, -1);
  307. }
  308. lua_pop(L, 1);
  309. lua_pushstring(L, "timeout");
  310. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  311. timeout = luaL_optinteger(L, -1,3000);
  312. }
  313. lua_pop(L, 1);
  314. lua_pushstring(L, "rateOptimize");
  315. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  316. rateOptimize = lua_toboolean(L, -1);
  317. }
  318. lua_pop(L, 1);
  319. }
  320. Radio2.SetTxConfig( lora_device,mode, power, fdev, bandwidth,
  321. datarate, coderate,
  322. preambleLen, fixLen,
  323. crcOn, freqHopOn, hopPeriod, iqInverted, timeout ,rateOptimize);
  324. return 0;
  325. }
  326. /*
  327. lora配置接收参数
  328. @api lora_device:set_rxconfig(set_rxconfig)
  329. @table lora接收配置参数,与具体设备有关
  330. @usage
  331. lora_device:set_rxconfig(
  332. {
  333. mode=1,
  334. bandwidth=0,
  335. datarate=9,
  336. coderate=4,
  337. bandwidthAfc=0,
  338. preambleLen=8,
  339. symbTimeout=0,
  340. fixLen=false,
  341. payloadLen=0,
  342. crcOn=true,
  343. freqHopOn=0,
  344. hopPeriod=0,
  345. iqInverted=false,
  346. rxContinuous=false
  347. }
  348. )
  349. */
  350. static int luat_lora_set_rxconfig(lua_State *L){
  351. uint8_t mode = 1,bandwidth = 0,datarate = 9,coderate = 4,bandwidthAfc = 0,preambleLen = 8,symbTimeout = 0,payloadLen = 0,freqHopOn = 0,hopPeriod = 0;
  352. uint32_t frequency = 433000000,timeout = 0;
  353. bool fixLen = false,crcOn = true,iqInverted = false,rxContinuous = false,rateOptimize = false;
  354. lora_device_t * lora_device = get_lora_device(L);
  355. if (lua_istable(L, 2)) {
  356. lua_pushstring(L, "mode");
  357. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  358. mode = luaL_optinteger(L, -1,1);
  359. }
  360. lua_pop(L, 1);
  361. lua_pushstring(L, "bandwidth");
  362. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  363. bandwidth = luaL_optinteger(L, -1,0);
  364. }
  365. lua_pop(L, 1);
  366. lua_pushstring(L, "datarate");
  367. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  368. datarate = luaL_optinteger(L, -1,9);
  369. }
  370. lua_pop(L, 1);
  371. lua_pushstring(L, "coderate");
  372. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  373. coderate = luaL_optinteger(L, -1,4);
  374. }
  375. lua_pop(L, 1);
  376. lua_pushstring(L, "bandwidthAfc");
  377. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  378. bandwidthAfc = luaL_optinteger(L, -1,0);
  379. }
  380. lua_pop(L, 1);
  381. lua_pushstring(L, "preambleLen");
  382. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  383. preambleLen = luaL_optinteger(L, -1,8);
  384. }
  385. lua_pop(L, 1);
  386. lua_pushstring(L, "symbTimeout");
  387. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  388. symbTimeout = luaL_optinteger(L, -1,0);
  389. }
  390. lua_pop(L, 1);
  391. lua_pushstring(L, "fixLen");
  392. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  393. fixLen = lua_toboolean(L, -1);
  394. }
  395. lua_pop(L, 1);
  396. lua_pushstring(L, "payloadLen");
  397. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  398. payloadLen = luaL_optinteger(L, -1,0);
  399. }
  400. lua_pop(L, 1);
  401. lua_pushstring(L, "crcOn");
  402. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  403. crcOn = lua_toboolean(L, -1);
  404. }
  405. lua_pop(L, 1);
  406. lua_pushstring(L, "freqHopOn");
  407. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  408. freqHopOn = luaL_optinteger(L, -1,0);
  409. }
  410. lua_pop(L, 1);
  411. lua_pushstring(L, "hopPeriod");
  412. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  413. hopPeriod = luaL_optinteger(L, -1,0);
  414. }
  415. lua_pop(L, 1);
  416. lua_pushstring(L, "iqInverted");
  417. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  418. iqInverted = lua_toboolean(L, -1);
  419. }
  420. lua_pop(L, 1);
  421. lua_pushstring(L, "rxContinuous");
  422. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  423. rxContinuous = lua_toboolean(L, -1);
  424. }
  425. lua_pop(L, 1);
  426. lua_pushstring(L, "rateOptimize");
  427. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  428. rateOptimize = lua_toboolean(L, -1);
  429. }
  430. lua_pop(L, 1);
  431. }
  432. Radio2.SetRxConfig( lora_device,mode, bandwidth, datarate,
  433. coderate, bandwidthAfc, preambleLen,
  434. symbTimeout, fixLen,
  435. payloadLen, crcOn, freqHopOn, hopPeriod, iqInverted, rxContinuous ,rateOptimize);
  436. return 0;
  437. }
  438. /*
  439. 发数据
  440. @api lora_device:send(data)
  441. @string 写入的数据
  442. @usage
  443. lora_device:send("PING")
  444. */
  445. static int luat_lora_send(lua_State *L){
  446. lora_device_t * lora_device = get_lora_device(L);
  447. size_t len;
  448. const char* send_buff = luaL_checklstring(L, 2, &len);
  449. Radio2.Standby(lora_device);
  450. Radio2.Send( lora_device,send_buff, len);
  451. return 0;
  452. }
  453. /*
  454. 开启收数据
  455. @api lora_device:recv(timeout)
  456. @number 超时时间,默认1000 单位ms
  457. @usage
  458. sys.subscribe("LORA_RX_DONE", function(data, size)
  459. log.info("LORA_RX_DONE: ", data, size)
  460. lora_device:send("PING")
  461. end)
  462. lora_device:recv(1000)
  463. */
  464. static int luat_lora_recv(lua_State *L){
  465. lora_device_t * lora_device = get_lora_device(L);
  466. int rx_timeout = luaL_optinteger(L, 2, 1000);
  467. Radio2.Standby(lora_device);
  468. Radio2.Rx(lora_device,rx_timeout);
  469. return 0;
  470. }
  471. /*
  472. 设置进入模式(休眠,正常等)
  473. @api lora_device:mode(mode)
  474. @number 模式 正常模式:lora.STANDBY 休眠模式:lora.SLEEP 默认为正常模式
  475. @usage
  476. lora_device:mode(lora.STANDBY)
  477. */
  478. static int luat_lora_mode(lua_State *L){
  479. lora_device_t * lora_device = get_lora_device(L);
  480. int mode = luaL_optinteger(L, 2, 1);
  481. if (mode == 1){
  482. Radio2.Standby(lora_device);
  483. }else if (mode == 0){
  484. Radio2.Sleep(lora_device);
  485. }
  486. return 0;
  487. }
  488. /*
  489. 注册lora回调
  490. @api lora_device:on(cb)
  491. @function cb lora回调,参数包括lora_device, event, data, size
  492. @return nil 无返回值
  493. @usage
  494. lora_device:on(function(lora_device, event, data, size)
  495. log.info("lora", "event", event, lora_device, data, size)
  496. if event == "tx_done" then
  497. lora_device:recv(1000)
  498. elseif event == "rx_done" then
  499. lora_device:send("PING")
  500. elseif event == "tx_timeout" then
  501. elseif event == "rx_timeout" then
  502. lora_device:recv(1000)
  503. elseif event == "rx_error" then
  504. end
  505. end)
  506. --[[
  507. event可能出现的值有
  508. tx_done -- 发送完成
  509. rx_done -- 接收完成
  510. tx_timeout -- 发送超时
  511. rx_timeout -- 接收超时
  512. rx_error -- 接收错误
  513. ]]
  514. */
  515. static int luat_lora_on(lua_State *L){
  516. lora_device_t *lora_device = get_lora_device(L);
  517. if (lora_device->lora_cb != 0) {
  518. luaL_unref(L, LUA_REGISTRYINDEX, lora_device->lora_cb);
  519. lora_device->lora_cb = 0;
  520. }
  521. if (lua_isfunction(L, 2)) {
  522. lua_pushvalue(L, 2);
  523. lora_device->lora_cb = luaL_ref(L, LUA_REGISTRYINDEX);
  524. }
  525. return 0;
  526. }
  527. static int _lora_struct_newindex(lua_State *L);
  528. void luat_lora_struct_init(lua_State *L) {
  529. luaL_newmetatable(L, LUAT_LORA_TYPE);
  530. lua_pushcfunction(L, _lora_struct_newindex);
  531. lua_setfield( L, -2, "__index" );
  532. lua_pop(L, 1);
  533. }
  534. #include "rotable2.h"
  535. static const rotable_Reg_t reg_lora[] =
  536. {
  537. { "init", ROREG_FUNC(luat_lora_init)},
  538. { "set_channel", ROREG_FUNC(luat_lora_set_channel)},
  539. { "set_txconfig",ROREG_FUNC(luat_lora_set_txconfig)},
  540. { "set_rxconfig",ROREG_FUNC(luat_lora_set_rxconfig)},
  541. { "on", ROREG_FUNC(luat_lora_on)},
  542. { "send", ROREG_FUNC(luat_lora_send)},
  543. { "recv", ROREG_FUNC(luat_lora_recv)},
  544. { "mode", ROREG_FUNC(luat_lora_mode)},
  545. //@const SLEEP number SLEEP模式
  546. { "SLEEP", ROREG_INT(0)},
  547. //@const STANDBY number STANDBY模式
  548. { "STANDBY", ROREG_INT(1)},
  549. { NULL, ROREG_INT(0)}
  550. };
  551. static int _lora_struct_newindex(lua_State *L) {
  552. const rotable_Reg_t* reg = reg_lora;
  553. const char* key = luaL_checkstring(L, 2);
  554. while (1) {
  555. if (reg->name == NULL)
  556. return 0;
  557. if (!strcmp(reg->name, key)) {
  558. lua_pushcfunction(L, reg->value.value.func);
  559. return 1;
  560. }
  561. reg ++;
  562. }
  563. }
  564. LUAMOD_API int luaopen_lora2( lua_State *L ) {
  565. luat_newlib2(L, reg_lora);
  566. luat_lora_struct_init(L);
  567. return 1;
  568. }