luat_uart_air105.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. * Copyright (c) 2022 OpenLuat & AirM2M
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. * this software and associated documentation files (the "Software"), to deal in
  6. * the Software without restriction, including without limitation the rights to
  7. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. * the Software, and to permit persons to whom the Software is furnished to do so,
  9. * subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  16. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  17. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  18. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. #include "luat_base.h"
  22. #include "luat_malloc.h"
  23. #include "luat_msgbus.h"
  24. #include "luat_uart.h"
  25. #include "app_interface.h"
  26. #define LUAT_LOG_TAG "luat.uart"
  27. #include "luat_log.h"
  28. // #define UART_RX_USE_DMA
  29. //串口数量,编号从0开始
  30. #define MAX_DEVICE_COUNT UART_MAX
  31. //存放串口设备句柄
  32. typedef struct
  33. {
  34. timer_t *rs485_timer;
  35. union
  36. {
  37. uint16_t rs485_param;
  38. struct
  39. {
  40. uint16_t wait_time:14;
  41. uint16_t rx_level:1;
  42. uint16_t is_485used:1;
  43. }rs485_param_bit;
  44. };
  45. uint8_t rx_mark;
  46. uint8_t rs485_pin;
  47. }serials_info;
  48. static serials_info serials[MAX_DEVICE_COUNT+1] ={0};
  49. static int32_t luat_uart_wait_timer_cb(void *pData, void *pParam)
  50. {
  51. uint32_t uartid = (uint32_t)pParam;
  52. rtos_msg_t msg;
  53. msg.handler = l_uart_handler;
  54. msg.arg1 = uartid;
  55. msg.arg2 = 0;
  56. msg.ptr = NULL;
  57. luat_msgbus_put(&msg, 1);
  58. if (serials[uartid].rs485_param_bit.is_485used) {
  59. GPIO_Output(serials[uartid].rs485_pin, serials[uartid].rs485_param_bit.rx_level);
  60. }
  61. }
  62. int luat_uart_exist(int uartid){
  63. if (uartid >= LUAT_VUART_ID_0) uartid = MAX_DEVICE_COUNT;
  64. if (uartid < 1 || uartid > MAX_DEVICE_COUNT){
  65. return 0;
  66. }
  67. return 1;
  68. }
  69. static int32_t luat_uart_cb(void *pData, void *pParam){
  70. rtos_msg_t msg;
  71. uint32_t uartid = (uint32_t)pData;
  72. uint32_t State = (uint32_t)pParam;
  73. uint32_t len;
  74. // LLOGD("luat_uart_cb pData:%d pParam:%d ",uartid,State);
  75. switch (State){
  76. case UART_CB_TX_BUFFER_DONE:
  77. break;
  78. case UART_CB_TX_ALL_DONE:
  79. if (serials[uartid].rs485_param_bit.is_485used && serials[uartid].rs485_param_bit.wait_time)
  80. {
  81. Timer_StartUS(serials[uartid].rs485_timer, serials[uartid].rs485_param_bit.wait_time, 0);
  82. }
  83. else
  84. {
  85. msg.handler = l_uart_handler;
  86. msg.arg1 = uartid;
  87. msg.arg2 = 0;
  88. msg.ptr = NULL;
  89. luat_msgbus_put(&msg, 1);
  90. if (serials[uartid].rs485_param_bit.is_485used && Uart_IsTSREmpty(uartid)) {
  91. GPIO_Output(serials[uartid].rs485_pin, serials[uartid].rs485_param_bit.rx_level);
  92. }
  93. }
  94. break;
  95. case UART_CB_RX_BUFFER_FULL:
  96. case UART_CB_RX_TIMEOUT:
  97. if (serials[uartid].rx_mark) return 0;
  98. serials[uartid].rx_mark = 1;
  99. len = Uart_RxBufferRead(uartid, NULL, 0);
  100. msg.handler = l_uart_handler;
  101. msg.ptr = NULL;
  102. msg.arg1 = uartid;
  103. msg.arg2 = len;
  104. luat_msgbus_put(&msg, 1);
  105. break;
  106. case UART_CB_RX_NEW:
  107. break;
  108. case DMA_CB_DONE:
  109. break;
  110. case UART_CB_ERROR:
  111. break;
  112. case DMA_CB_ERROR:
  113. LLOGD("%x", Uart_GetLastError(uartid));
  114. break;
  115. }
  116. }
  117. static int usb_uart_handler(lua_State *L, void* ptr,int arg1) {
  118. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  119. lua_pop(L, 1);
  120. int uart_id = msg->arg1;
  121. // LLOGD("msg->arg1: %d,msg->arg2: %d",msg->arg1,msg->arg2);
  122. if (msg->arg2 == 1) {
  123. lua_getglobal(L, "sys_pub");
  124. lua_pushstring(L, "USB_UART_INC");
  125. lua_pushinteger(L, uart_id);
  126. lua_pushinteger(L, 1);
  127. lua_call(L, 3, 0);
  128. }
  129. else if(msg->arg2 == 2){
  130. lua_getglobal(L, "sys_pub");
  131. lua_pushstring(L, "USB_UART_INC");
  132. lua_pushinteger(L, uart_id);
  133. lua_pushinteger(L, 0);
  134. lua_call(L, 3, 0);
  135. }
  136. // 给rtos.recv方法返回个空数据
  137. // lua_pushinteger(L, 0);
  138. return 0;
  139. }
  140. static int32_t luat_uart_usb_cb(void *pData, void *pParam){
  141. rtos_msg_t msg = {0};
  142. uint32_t uartid = (uint32_t)pData;
  143. uint32_t State = (uint32_t)pParam;
  144. uint32_t len;
  145. // LLOGD("luat_uart_cb pData:%d pParam:%d ",uartid,State);
  146. switch (State){
  147. case UART_CB_TX_BUFFER_DONE:
  148. break;
  149. case UART_CB_TX_ALL_DONE:
  150. msg.handler = l_uart_handler;
  151. msg.arg1 = LUAT_VUART_ID_0;
  152. msg.arg2 = 0;
  153. msg.ptr = NULL;
  154. luat_msgbus_put(&msg, 1);
  155. break;
  156. case UART_CB_RX_BUFFER_FULL:
  157. break;
  158. case UART_CB_RX_TIMEOUT:
  159. break;
  160. case UART_CB_RX_NEW:
  161. if (serials[MAX_DEVICE_COUNT].rx_mark) return 0;
  162. serials[MAX_DEVICE_COUNT].rx_mark = 1;
  163. len = Core_VUartRxBufferRead(VIRTUAL_UART0,NULL,0);
  164. msg.handler = l_uart_handler;
  165. msg.ptr = NULL;
  166. msg.arg1 = LUAT_VUART_ID_0;
  167. msg.arg2 = len;
  168. luat_msgbus_put(&msg, 1);
  169. break;
  170. case DMA_CB_DONE:
  171. break;
  172. case UART_CB_ERROR:
  173. // LLOGI("usb disconnect");
  174. Core_VUartBufferTxStop(VIRTUAL_UART0);
  175. msg.handler = usb_uart_handler;
  176. msg.ptr = NULL;
  177. msg.arg1 = LUAT_VUART_ID_0;
  178. msg.arg2 = 2;
  179. luat_msgbus_put(&msg, 1);
  180. break;
  181. case UART_CB_CONNECTED:
  182. //对方打开串口工具
  183. msg.handler = usb_uart_handler;
  184. msg.ptr = NULL;
  185. msg.arg1 = LUAT_VUART_ID_0;
  186. msg.arg2 = 1;
  187. luat_msgbus_put(&msg, 1);
  188. break;
  189. }
  190. }
  191. int luat_uart_setup(luat_uart_t *uart){
  192. int parity = 0;
  193. if (uart->id > MAX_DEVICE_COUNT){
  194. return -1;
  195. }
  196. switch (uart->id){
  197. case UART_ID0:
  198. break;
  199. case UART_ID1:
  200. GPIO_Iomux(GPIOC_01, 3);
  201. GPIO_Iomux(GPIOC_00, 3);
  202. break;
  203. case UART_ID2:
  204. GPIO_Iomux(GPIOD_13, 0);
  205. GPIO_Iomux(GPIOD_12, 0);
  206. break;
  207. case UART_ID3:
  208. GPIO_Iomux(GPIOE_08, 2);
  209. GPIO_Iomux(GPIOE_09, 2);
  210. break;
  211. default:
  212. break;
  213. }
  214. if (uart->parity == 1)parity = UART_PARITY_ODD;
  215. else if (uart->parity == 2)parity = UART_PARITY_EVEN;
  216. int stop_bits = (uart->stop_bits)==1?UART_STOP_BIT1:UART_STOP_BIT2;
  217. if (uart->id >= MAX_DEVICE_COUNT) {
  218. serials[MAX_DEVICE_COUNT].rx_mark = 0;
  219. Core_VUartInit(VIRTUAL_UART0, uart->baud_rate, 1, (uart->data_bits), parity, stop_bits, NULL);
  220. } else {
  221. serials[uart->id].rx_mark = 0;
  222. Uart_BaseInit(uart->id, uart->baud_rate, 1, (uart->data_bits), parity, stop_bits, NULL);
  223. serials[uart->id].rs485_param_bit.is_485used = (uart->pin485 < GPIO_NONE)?1:0;
  224. serials[uart->id].rs485_pin = uart->pin485;
  225. serials[uart->id].rs485_param_bit.rx_level = uart->rx_level;
  226. serials[uart->id].rs485_param_bit.wait_time = uart->delay;
  227. if (!serials[uart->id].rs485_timer) {
  228. serials[uart->id].rs485_timer = Timer_Create(luat_uart_wait_timer_cb, uart->id, NULL);
  229. }
  230. GPIO_Config(serials[uart->id].rs485_pin, 0, serials[uart->id].rs485_param_bit.rx_level);
  231. #ifndef UART_RX_USE_DMA
  232. Uart_EnableRxIrq(uart->id);
  233. #endif
  234. }
  235. return 0;
  236. }
  237. int luat_uart_write(int uartid, void *data, size_t length){
  238. //printf("uid:%d,data:%s,length = %d\r\n",uartid, (char *)data, length);
  239. if (!luat_uart_exist(uartid)){
  240. return 0;
  241. }
  242. if (uartid >= MAX_DEVICE_COUNT) {
  243. Core_VUartBufferTx(VIRTUAL_UART0, (const uint8_t *)data, length);
  244. }
  245. else {
  246. if (serials[uartid].rs485_param_bit.is_485used) GPIO_Output(serials[uartid].rs485_pin, !serials[uartid].rs485_param_bit.rx_level);
  247. Uart_BufferTx(uartid, (const uint8_t *)data, length);
  248. }
  249. return length;
  250. }
  251. int luat_uart_read(int uartid, void *buffer, size_t length){
  252. int ret = 0;
  253. if (!luat_uart_exist(uartid)){
  254. return 0;
  255. }
  256. if (uartid >= LUAT_VUART_ID_0) uartid = MAX_DEVICE_COUNT;
  257. serials[uartid].rx_mark = 0;
  258. if (uartid >= MAX_DEVICE_COUNT)
  259. ret = Core_VUartRxBufferRead(VIRTUAL_UART0, (uint8_t *)buffer,length);
  260. else
  261. ret = Uart_RxBufferRead(uartid, (uint8_t *)buffer,length);
  262. // LLOGD("uartid:%d buffer:%s ret:%d ",uartid,buffer, ret);
  263. return ret;
  264. }
  265. int luat_uart_close(int uartid){
  266. if (!luat_uart_exist(uartid)){
  267. return 0;
  268. }
  269. if (uartid >= LUAT_VUART_ID_0) uartid = MAX_DEVICE_COUNT;
  270. serials[uartid].rs485_param_bit.is_485used = 0;
  271. if (uartid >= MAX_DEVICE_COUNT)
  272. Core_VUartDeInit(VIRTUAL_UART0);
  273. else
  274. Uart_DeInit(uartid);
  275. return 0;
  276. }
  277. int luat_setup_cb(int uartid, int received, int sent){
  278. if (!luat_uart_exist(uartid)){
  279. return -1;
  280. }
  281. if (uartid >= MAX_DEVICE_COUNT)
  282. Core_VUartSetCb(VIRTUAL_UART0, luat_uart_usb_cb);
  283. else {
  284. Uart_SetCb(uartid, luat_uart_cb);
  285. //#ifndef UART_RX_USE_DMA
  286. // Uart_EnableRxIrq(uartid);
  287. //#endif
  288. }
  289. return 0;
  290. }
  291. int luat_uart_wait_485_tx_done(int uartid)
  292. {
  293. int cnt = 0;
  294. if (luat_uart_exist(uartid)){
  295. if (serials[uartid].rs485_param_bit.is_485used){
  296. while(!Uart_IsTSREmpty(uartid)) {cnt++;}
  297. GPIO_Output(serials[uartid].rs485_pin, serials[uartid].rs485_param_bit.rx_level);
  298. }
  299. }
  300. return cnt;
  301. }