luat_lib_lora.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. /*
  2. @module lora
  3. @summary lora驱动模块
  4. @version 1.0
  5. @date 2022.06.24
  6. @demo lora
  7. */
  8. #include "luat_base.h"
  9. #include "luat_rtos.h"
  10. #include "luat_gpio.h"
  11. #include "luat_spi.h"
  12. #include "luat_malloc.h"
  13. #include "sx126x/radio.h"
  14. #include "sx126x/sx126x.h"
  15. #include "sx126x/sx126x-board.h"
  16. #define LUAT_LOG_TAG "lora"
  17. #include "luat_log.h"
  18. extern uint8_t SX126xSpi;
  19. extern uint8_t SX126xCsPin;
  20. extern uint8_t SX126xResetPin;
  21. extern uint8_t SX126xBusyPin;
  22. extern uint8_t SX126xDio1Pin;
  23. static RadioEvents_t RadioEvents;
  24. enum{
  25. LORA_TX_DONE,
  26. LORA_RX_DONE,
  27. LORA_TX_TIMEOUT,
  28. LORA_RX_TIMEOUT,
  29. LORA_RX_ERROR,
  30. };
  31. static int l_lora_handler(lua_State* L, void* ptr) {
  32. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  33. int event = msg->arg1;
  34. lua_getglobal(L, "sys_pub");
  35. if (lua_isnil(L, -1)) {
  36. lua_pushinteger(L, 0);
  37. return 1;
  38. }
  39. switch (event){
  40. case LORA_TX_DONE:
  41. /*
  42. @sys_pub lora
  43. LORA 发送完成
  44. LORA_TX_DONE
  45. @usage
  46. sys.subscribe("LORA_TX_DONE", function()
  47. lora.recive(1000)
  48. end)
  49. */
  50. lua_pushstring(L, "LORA_TX_DONE");
  51. lua_call(L, 1, 0);
  52. break;
  53. case LORA_RX_DONE:
  54. /*
  55. @sys_pub lora
  56. LORA 接收完成
  57. LORA_RX_DONE
  58. @usage
  59. sys.subscribe("LORA_RX_DONE", function(data, size)
  60. log.info("LORA_RX_DONE: ", data, size)
  61. lora.send("PING")
  62. end)
  63. */
  64. lua_pushstring(L, "LORA_RX_DONE");
  65. lua_pushlstring(L, (const char *)msg->ptr,msg->arg2);
  66. lua_pushinteger(L, msg->arg2);
  67. lua_call(L, 3, 0);
  68. luat_heap_free(msg->ptr);
  69. break;
  70. case LORA_TX_TIMEOUT:
  71. /*
  72. @sys_pub lora
  73. LORA 发送超时
  74. LORA_TX_TIMEOUT
  75. @usage
  76. sys.subscribe("LORA_TX_TIMEOUT", function()
  77. lora.recive(1000)
  78. end)
  79. */
  80. lua_pushstring(L, "LORA_TX_TIMEOUT");
  81. lua_call(L, 1, 0);
  82. break;
  83. case LORA_RX_TIMEOUT:
  84. /*
  85. @sys_pub lora
  86. LORA 接收超时
  87. LORA_RX_TIMEOUT
  88. @usage
  89. sys.subscribe("LORA_RX_TIMEOUT", function()
  90. lora.recive(1000)
  91. end)
  92. */
  93. lua_pushstring(L, "LORA_RX_TIMEOUT");
  94. lua_call(L, 1, 0);
  95. break;
  96. case LORA_RX_ERROR:
  97. /*
  98. @sys_pub lora
  99. LORA 接收错误
  100. LORA_RX_ERROR
  101. @usage
  102. sys.subscribe("LORA_RX_ERROR", function()
  103. lora.recive(1000)
  104. end)
  105. */
  106. lua_pushstring(L, "LORA_RX_ERROR");
  107. lua_call(L, 1, 0);
  108. break;
  109. }
  110. return 0;
  111. }
  112. void OnTxDone( void ){
  113. rtos_msg_t msg;
  114. msg.handler = l_lora_handler;
  115. msg.ptr = NULL;
  116. msg.arg1 = LORA_TX_DONE;
  117. msg.arg2 = 0;
  118. luat_msgbus_put(&msg, 1);
  119. }
  120. void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ){
  121. // printf("RxDone size:%d rssi:%d snr:%d\n",size,rssi,snr);
  122. // printf("RxDone payload: %.*s",size,payload);
  123. char* rx_buff = luat_heap_malloc(size);
  124. memcpy( rx_buff, payload, size );
  125. rtos_msg_t msg;
  126. msg.handler = l_lora_handler;
  127. msg.ptr = rx_buff;
  128. msg.arg1 = LORA_RX_DONE;
  129. msg.arg2 = size;
  130. luat_msgbus_put(&msg, 1);
  131. }
  132. void OnTxTimeout( void ){
  133. rtos_msg_t msg;
  134. msg.handler = l_lora_handler;
  135. msg.ptr = NULL;
  136. msg.arg1 = LORA_TX_TIMEOUT;
  137. msg.arg2 = 0;
  138. luat_msgbus_put(&msg, 1);
  139. }
  140. void OnRxTimeout( void ){
  141. rtos_msg_t msg;
  142. msg.handler = l_lora_handler;
  143. msg.ptr = NULL;
  144. msg.arg1 = LORA_RX_TIMEOUT;
  145. msg.arg2 = 0;
  146. luat_msgbus_put(&msg, 1);
  147. }
  148. void OnRxError( void ){
  149. rtos_msg_t msg;
  150. msg.handler = l_lora_handler;
  151. msg.ptr = NULL;
  152. msg.arg1 = LORA_RX_ERROR;
  153. msg.arg2 = 0;
  154. luat_msgbus_put(&msg, 1);
  155. }
  156. extern void RadioEventsInit(RadioEvents_t *events);
  157. /*
  158. lora初始化
  159. @api lora.init(ic, loraconfig,spiconfig)
  160. @string lora 型号,当前支持:<br>llcc68<br>sx1268
  161. @table lora配置参数,与具体设备有关
  162. @table 硬件配置参数,与具体设备有关
  163. @usage
  164. lora.init("llcc68",
  165. {id = 0,cs = pin.PB04,res = pin.PB00,busy = pin.PB01,dio1 = pin.PB06,lora_init = true}
  166. )
  167. */
  168. static int luat_lora_init(lua_State *L){
  169. size_t len = 0;
  170. const char* lora_ic = luaL_checklstring(L, 1, &len);
  171. if(strcmp("llcc68",lora_ic)== 0||strcmp("LLCC68",lora_ic)== 0||strcmp("sx1268",lora_ic)== 0||strcmp("SX1268",lora_ic)== 0){
  172. uint8_t id = 0,cs = 0,res = 0,busy = 0,dio1 = 0;
  173. bool lora_init = true;
  174. if (lua_istable(L, 2)) {
  175. lua_pushstring(L, "id");
  176. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  177. id = luaL_checkinteger(L, -1);
  178. }
  179. lua_pop(L, 1);
  180. lua_pushstring(L, "cs");
  181. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  182. cs = luaL_checkinteger(L, -1);
  183. }
  184. lua_pop(L, 1);
  185. lua_pushstring(L, "res");
  186. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  187. res = luaL_checkinteger(L, -1);
  188. }
  189. lua_pop(L, 1);
  190. lua_pushstring(L, "busy");
  191. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  192. busy = luaL_checkinteger(L, -1);
  193. }
  194. lua_pop(L, 1);
  195. lua_pushstring(L, "dio1");
  196. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  197. dio1 = luaL_checkinteger(L, -1);
  198. }
  199. lua_pop(L, 1);
  200. lua_pushstring(L, "lora_init");
  201. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  202. lora_init = lua_toboolean(L, -1);
  203. }
  204. lua_pop(L, 1);
  205. }
  206. luat_spi_t sx126x_spi = {0};
  207. sx126x_spi.id = id;
  208. sx126x_spi.CPHA = 0;
  209. sx126x_spi.CPOL = 0;
  210. sx126x_spi.dataw = 8;
  211. sx126x_spi.bit_dict = 1;
  212. sx126x_spi.master = 1;
  213. sx126x_spi.mode = 0;
  214. sx126x_spi.bandrate = 20000000;
  215. sx126x_spi.cs = Luat_GPIO_MAX_ID;
  216. luat_spi_setup(&sx126x_spi);
  217. SX126xSpi = id;
  218. SX126xCsPin = cs;
  219. SX126xResetPin = res;
  220. SX126xBusyPin = busy;
  221. SX126xDio1Pin = dio1;
  222. luat_gpio_mode(SX126xCsPin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  223. luat_gpio_mode(SX126xResetPin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  224. luat_gpio_mode(SX126xBusyPin, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
  225. luat_gpio_mode(SX126xDio1Pin, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
  226. RadioEvents.TxDone = OnTxDone;
  227. RadioEvents.RxDone = OnRxDone;
  228. RadioEvents.TxTimeout = OnTxTimeout;
  229. RadioEvents.RxTimeout = OnRxTimeout;
  230. RadioEvents.RxError = OnRxError;
  231. RadioEventsInit(&RadioEvents);
  232. if (lora_init) Radio.Init( &RadioEvents );
  233. luat_start_rtos_timer(luat_create_rtos_timer(Radio.IrqProcess, NULL, NULL), 10, 1);
  234. }
  235. return 0;
  236. }
  237. /*
  238. 设置频道频率
  239. @api lora.set_channel(freq)
  240. @number 频率
  241. @usage
  242. lora.set_channel(433000000)
  243. */
  244. static int luat_lora_set_channel(lua_State *L){
  245. uint32_t freq = luaL_optinteger(L, 1,433000000);
  246. Radio.SetChannel(freq);
  247. return 0;
  248. }
  249. /*
  250. lora配置发送参数
  251. @api lora.set_txconfig(ic, txconfig)
  252. @string lora 型号,当前支持:<br>llcc68<br>sx1268
  253. @table lora发送配置参数,与具体设备有关
  254. @usage
  255. lora.set_txconfig("llcc68",
  256. {mode=1,power=22,fdev=0,bandwidth=0,datarate=9,coderate=4,preambleLen=8,
  257. fixLen=false,crcOn=true,freqHopOn=0,hopPeriod=0,iqInverted=false,timeout=3000}
  258. )
  259. */
  260. static int luat_lora_set_txconfig(lua_State *L){
  261. size_t len = 0;
  262. const char* lora_ic = luaL_checklstring(L, 1, &len);
  263. if(strcmp("llcc68",lora_ic)== 0||strcmp("LLCC68",lora_ic)== 0||strcmp("sx1268",lora_ic)== 0||strcmp("SX1268",lora_ic)== 0){
  264. uint8_t mode = 1,power = 0,fdev = 0,bandwidth = 0,datarate = 9,coderate = 4,preambleLen = 8,freqHopOn = 0,hopPeriod = 0;
  265. uint32_t timeout = 0;
  266. bool fixLen = false,crcOn = true,iqInverted = false;
  267. if (lua_istable(L, 2)) {
  268. lua_pushstring(L, "mode");
  269. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  270. mode = luaL_optinteger(L, -1,1);
  271. }
  272. lua_pop(L, 1);
  273. lua_pushstring(L, "power");
  274. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  275. power = luaL_optinteger(L, -1,22);
  276. }
  277. lua_pop(L, 1);
  278. lua_pushstring(L, "fdev");
  279. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  280. fdev = luaL_optinteger(L, -1,0);
  281. }
  282. lua_pop(L, 1);
  283. lua_pushstring(L, "bandwidth");
  284. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  285. bandwidth = luaL_optinteger(L, -1,0);
  286. }
  287. lua_pop(L, 1);
  288. lua_pushstring(L, "datarate");
  289. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  290. datarate = luaL_optinteger(L, -1,9);
  291. }
  292. lua_pop(L, 1);
  293. lua_pushstring(L, "coderate");
  294. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  295. coderate = luaL_optinteger(L, -1,4);
  296. }
  297. lua_pop(L, 1);
  298. lua_pushstring(L, "preambleLen");
  299. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  300. preambleLen = luaL_optinteger(L, -1,8);
  301. }
  302. lua_pop(L, 1);
  303. lua_pushstring(L, "fixLen");
  304. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  305. fixLen = lua_toboolean(L, -1);
  306. }
  307. lua_pop(L, 1);
  308. lua_pushstring(L, "crcOn");
  309. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  310. crcOn = lua_toboolean(L, -1);
  311. }
  312. lua_pop(L, 1);
  313. lua_pushstring(L, "freqHopOn");
  314. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  315. freqHopOn = luaL_optinteger(L, -1,0);
  316. }
  317. lua_pop(L, 1);
  318. lua_pushstring(L, "hopPeriod");
  319. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  320. hopPeriod = luaL_optinteger(L, -1,0);
  321. }
  322. lua_pop(L, 1);
  323. lua_pushstring(L, "iqInverted");
  324. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  325. iqInverted = lua_toboolean(L, -1);
  326. }
  327. lua_pop(L, 1);
  328. lua_pushstring(L, "timeout");
  329. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  330. timeout = luaL_optinteger(L, -1,3000);
  331. }
  332. lua_pop(L, 1);
  333. }
  334. Radio.SetTxConfig( mode, power, fdev, bandwidth,
  335. datarate, coderate,
  336. preambleLen, fixLen,
  337. crcOn, freqHopOn, hopPeriod, iqInverted, timeout );
  338. }
  339. return 0;
  340. }
  341. /*
  342. lora配置接收参数
  343. @api lora.set_rxconfig(ic, set_rxconfig)
  344. @string lora 型号,当前支持:<br>llcc68<br>sx1268
  345. @table lora接收配置参数,与具体设备有关
  346. @usage
  347. lora.set_rxconfig("llcc68",
  348. {mode=1,bandwidth=0,datarate=9,coderate=4,bandwidthAfc=0,preambleLen=8,symbTimeout=0,fixLen=false,
  349. payloadLen=0,crcOn=true,freqHopOn=0,hopPeriod=0,iqInverted=false,rxContinuous=false}
  350. )
  351. */
  352. static int luat_lora_set_rxconfig(lua_State *L){
  353. size_t len = 0;
  354. const char* lora_ic = luaL_checklstring(L, 1, &len);
  355. if(strcmp("llcc68",lora_ic)== 0||strcmp("LLCC68",lora_ic)== 0||strcmp("sx1268",lora_ic)== 0||strcmp("SX1268",lora_ic)== 0){
  356. uint8_t mode = 1,bandwidth = 0,datarate = 9,coderate = 4,bandwidthAfc = 0,preambleLen = 8,symbTimeout = 0,payloadLen = 0,freqHopOn = 0,hopPeriod = 0;
  357. uint32_t frequency = 433000000,timeout = 0;
  358. bool fixLen = false,crcOn = true,iqInverted = false,rxContinuous = false;
  359. if (lua_istable(L, 2)) {
  360. lua_pushstring(L, "mode");
  361. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  362. mode = luaL_optinteger(L, -1,1);
  363. }
  364. lua_pop(L, 1);
  365. lua_pushstring(L, "bandwidth");
  366. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  367. bandwidth = luaL_optinteger(L, -1,0);
  368. }
  369. lua_pop(L, 1);
  370. lua_pushstring(L, "datarate");
  371. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  372. datarate = luaL_optinteger(L, -1,9);
  373. }
  374. lua_pop(L, 1);
  375. lua_pushstring(L, "coderate");
  376. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  377. coderate = luaL_optinteger(L, -1,4);
  378. }
  379. lua_pop(L, 1);
  380. lua_pushstring(L, "bandwidthAfc");
  381. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  382. bandwidthAfc = luaL_optinteger(L, -1,0);
  383. }
  384. lua_pop(L, 1);
  385. lua_pushstring(L, "preambleLen");
  386. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  387. preambleLen = luaL_optinteger(L, -1,8);
  388. }
  389. lua_pop(L, 1);
  390. lua_pushstring(L, "symbTimeout");
  391. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  392. symbTimeout = luaL_optinteger(L, -1,0);
  393. }
  394. lua_pop(L, 1);
  395. lua_pushstring(L, "fixLen");
  396. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  397. fixLen = lua_toboolean(L, -1);
  398. }
  399. lua_pop(L, 1);
  400. lua_pushstring(L, "payloadLen");
  401. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  402. payloadLen = luaL_optinteger(L, -1,0);
  403. }
  404. lua_pop(L, 1);
  405. lua_pushstring(L, "crcOn");
  406. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  407. crcOn = lua_toboolean(L, -1);
  408. }
  409. lua_pop(L, 1);
  410. lua_pushstring(L, "freqHopOn");
  411. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  412. freqHopOn = luaL_optinteger(L, -1,0);
  413. }
  414. lua_pop(L, 1);
  415. lua_pushstring(L, "hopPeriod");
  416. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  417. hopPeriod = luaL_optinteger(L, -1,0);
  418. }
  419. lua_pop(L, 1);
  420. lua_pushstring(L, "iqInverted");
  421. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  422. iqInverted = lua_toboolean(L, -1);
  423. }
  424. lua_pop(L, 1);
  425. lua_pushstring(L, "rxContinuous");
  426. if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  427. rxContinuous = lua_toboolean(L, -1);
  428. }
  429. lua_pop(L, 1);
  430. }
  431. Radio.SetRxConfig( mode, bandwidth, datarate,
  432. coderate, bandwidthAfc, preambleLen,
  433. symbTimeout, fixLen,
  434. payloadLen, crcOn, freqHopOn, hopPeriod, iqInverted, rxContinuous );
  435. }
  436. return 0;
  437. }
  438. /*
  439. 发数据
  440. @api lora.send(data)
  441. @string 写入的数据
  442. @usage
  443. lora.send("PING")
  444. */
  445. static int luat_lora_send(lua_State *L){
  446. size_t len;
  447. const char* send_buff = luaL_checklstring(L, 1, &len);
  448. Radio.Standby();
  449. Radio.Send( send_buff, len);
  450. return 0;
  451. }
  452. /*
  453. 开启收数据
  454. @api lora.recive(timeout)
  455. @number 超时时间,默认1000 单位ms
  456. @usage
  457. sys.subscribe("LORA_RX_DONE", function(data, size)
  458. log.info("LORA_RX_DONE: ", data, size)
  459. lora.send("PING")
  460. end)
  461. lora.recive(1000)
  462. */
  463. static int luat_lora_recive(lua_State *L){
  464. int rx_timeout = luaL_optinteger(L, 1, 1000);
  465. Radio.Standby();
  466. Radio.Rx(rx_timeout);
  467. return 0;
  468. }
  469. /*
  470. 设置进入模式(休眠,正常等)
  471. @api lora.mode(mode)
  472. @number 模式 正常模式:lora.STANDBY 休眠模式:lora.SLEEP 默认为正常模式
  473. @usage
  474. lora.mode(lora.STANDBY)
  475. */
  476. static int luat_lora_mode(lua_State *L){
  477. int mode = luaL_optinteger(L, 1, 1);
  478. if (mode == 1){
  479. Radio.Standby();
  480. }else if (mode == 0){
  481. Radio.Sleep();
  482. }
  483. return 0;
  484. }
  485. #include "rotable2.h"
  486. static const rotable_Reg_t reg_lora[] =
  487. {
  488. { "init", ROREG_FUNC(luat_lora_init)},
  489. { "set_channel", ROREG_FUNC(luat_lora_set_channel)},
  490. { "set_txconfig",ROREG_FUNC(luat_lora_set_txconfig)},
  491. { "set_rxconfig",ROREG_FUNC(luat_lora_set_rxconfig)},
  492. { "send", ROREG_FUNC(luat_lora_send)},
  493. { "recive", ROREG_FUNC(luat_lora_recive)},
  494. { "mode", ROREG_FUNC(luat_lora_mode)},
  495. //@const SLEEP number SLEEP模式
  496. { "SLEEP", ROREG_INT(0)},
  497. //@const STANDBY number STANDBY模式
  498. { "STANDBY", ROREG_INT(1)},
  499. { NULL, {}}
  500. };
  501. LUAMOD_API int luaopen_lora( lua_State *L ) {
  502. luat_newlib2(L, reg_lora);
  503. return 1;
  504. }