luat_uart_air105.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  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 "app_interface.h"
  23. #include "luat_malloc.h"
  24. #include "luat_msgbus.h"
  25. #include "luat_uart.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. uint32_t rs485_param;
  38. struct
  39. {
  40. uint32_t wait_time:30;
  41. uint32_t rx_level:1;
  42. uint32_t is_485used:1;
  43. }rs485_param_bit;
  44. };
  45. uint16_t unused;
  46. uint8_t rx_mark;
  47. uint8_t rs485_pin;
  48. }serials_info;
  49. static serials_info serials[MAX_DEVICE_COUNT+1] ={0};
  50. static int32_t luat_uart_wait_timer_cb(void *pData, void *pParam)
  51. {
  52. uint32_t uartid = (uint32_t)pParam;
  53. rtos_msg_t msg;
  54. msg.handler = l_uart_handler;
  55. msg.arg1 = uartid;
  56. msg.arg2 = 0;
  57. msg.ptr = NULL;
  58. luat_msgbus_put(&msg, 1);
  59. if (serials[uartid].rs485_param_bit.is_485used) {
  60. GPIO_Output(serials[uartid].rs485_pin, serials[uartid].rs485_param_bit.rx_level);
  61. }
  62. }
  63. int luat_uart_exist(int uartid){
  64. if (uartid >= LUAT_VUART_ID_0) uartid = MAX_DEVICE_COUNT;
  65. if (uartid < 1 || uartid > MAX_DEVICE_COUNT){
  66. return 0;
  67. }
  68. return 1;
  69. }
  70. static int32_t luat_uart_cb(void *pData, void *pParam){
  71. rtos_msg_t msg;
  72. uint32_t uartid = (uint32_t)pData;
  73. uint32_t State = (uint32_t)pParam;
  74. uint32_t len;
  75. // LLOGD("luat_uart_cb pData:%d pParam:%d ",uartid,State);
  76. switch (State){
  77. case UART_CB_TX_BUFFER_DONE:
  78. break;
  79. case UART_CB_TX_ALL_DONE:
  80. if (serials[uartid].rs485_param_bit.is_485used && serials[uartid].rs485_param_bit.wait_time)
  81. {
  82. Timer_StartUS(serials[uartid].rs485_timer, serials[uartid].rs485_param_bit.wait_time, 0);
  83. }
  84. else
  85. {
  86. msg.handler = l_uart_handler;
  87. msg.arg1 = uartid;
  88. msg.arg2 = 0;
  89. msg.ptr = NULL;
  90. luat_msgbus_put(&msg, 1);
  91. if (serials[uartid].rs485_param_bit.is_485used && Uart_IsTSREmpty(uartid)) {
  92. GPIO_Output(serials[uartid].rs485_pin, serials[uartid].rs485_param_bit.rx_level);
  93. }
  94. }
  95. break;
  96. case UART_CB_RX_BUFFER_FULL:
  97. case UART_CB_RX_TIMEOUT:
  98. if (serials[uartid].rx_mark) return 0;
  99. serials[uartid].rx_mark = 1;
  100. len = Uart_RxBufferRead(uartid, NULL, 0);
  101. msg.handler = l_uart_handler;
  102. msg.ptr = NULL;
  103. msg.arg1 = uartid;
  104. msg.arg2 = len;
  105. luat_msgbus_put(&msg, 1);
  106. break;
  107. case UART_CB_RX_NEW:
  108. break;
  109. case DMA_CB_DONE:
  110. break;
  111. case UART_CB_ERROR:
  112. break;
  113. case DMA_CB_ERROR:
  114. LLOGD("%x", Uart_GetLastError(uartid));
  115. break;
  116. }
  117. }
  118. static int usb_uart_handler(lua_State *L, void* ptr,int arg1) {
  119. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  120. lua_pop(L, 1);
  121. int uart_id = msg->arg1;
  122. // LLOGD("msg->arg1: %d,msg->arg2: %d",msg->arg1,msg->arg2);
  123. if (msg->arg2 == 1) {
  124. lua_getglobal(L, "sys_pub");
  125. lua_pushstring(L, "USB_UART_INC");
  126. lua_pushinteger(L, uart_id);
  127. lua_pushinteger(L, 1);
  128. lua_call(L, 3, 0);
  129. }
  130. else if(msg->arg2 == 2){
  131. lua_getglobal(L, "sys_pub");
  132. lua_pushstring(L, "USB_UART_INC");
  133. lua_pushinteger(L, uart_id);
  134. lua_pushinteger(L, 0);
  135. lua_call(L, 3, 0);
  136. }
  137. // 给rtos.recv方法返回个空数据
  138. // lua_pushinteger(L, 0);
  139. return 0;
  140. }
  141. static int32_t luat_uart_usb_cb(void *pData, void *pParam){
  142. rtos_msg_t msg = {0};
  143. uint32_t uartid = (uint32_t)pData;
  144. uint32_t State = (uint32_t)pParam;
  145. uint32_t len;
  146. // LLOGD("luat_uart_cb pData:%d pParam:%d ",uartid,State);
  147. switch (State){
  148. case UART_CB_TX_BUFFER_DONE:
  149. break;
  150. case UART_CB_TX_ALL_DONE:
  151. msg.handler = l_uart_handler;
  152. msg.arg1 = LUAT_VUART_ID_0;
  153. msg.arg2 = 0;
  154. msg.ptr = NULL;
  155. luat_msgbus_put(&msg, 1);
  156. break;
  157. case UART_CB_RX_BUFFER_FULL:
  158. break;
  159. case UART_CB_RX_TIMEOUT:
  160. break;
  161. case UART_CB_RX_NEW:
  162. if (serials[MAX_DEVICE_COUNT].rx_mark) return 0;
  163. serials[MAX_DEVICE_COUNT].rx_mark = 1;
  164. len = Core_VUartRxBufferRead(VIRTUAL_UART0,NULL,0);
  165. msg.handler = l_uart_handler;
  166. msg.ptr = NULL;
  167. msg.arg1 = LUAT_VUART_ID_0;
  168. msg.arg2 = len;
  169. luat_msgbus_put(&msg, 1);
  170. break;
  171. case DMA_CB_DONE:
  172. break;
  173. case UART_CB_ERROR:
  174. // LLOGI("usb disconnect");
  175. Core_VUartBufferTxStop(VIRTUAL_UART0);
  176. msg.handler = usb_uart_handler;
  177. msg.ptr = NULL;
  178. msg.arg1 = LUAT_VUART_ID_0;
  179. msg.arg2 = 2;
  180. luat_msgbus_put(&msg, 1);
  181. break;
  182. case UART_CB_CONNECTED:
  183. //对方打开串口工具
  184. msg.handler = usb_uart_handler;
  185. msg.ptr = NULL;
  186. msg.arg1 = LUAT_VUART_ID_0;
  187. msg.arg2 = 1;
  188. luat_msgbus_put(&msg, 1);
  189. break;
  190. }
  191. }
  192. int luat_uart_setup(luat_uart_t *uart){
  193. int parity = 0;
  194. if (uart->id > MAX_DEVICE_COUNT){
  195. return -1;
  196. }
  197. switch (uart->id){
  198. case UART_ID0:
  199. break;
  200. case UART_ID1:
  201. GPIO_Iomux(GPIOC_01, 3);
  202. GPIO_Iomux(GPIOC_00, 3);
  203. break;
  204. case UART_ID2:
  205. GPIO_Iomux(GPIOD_13, 0);
  206. GPIO_Iomux(GPIOD_12, 0);
  207. break;
  208. case UART_ID3:
  209. GPIO_Iomux(GPIOE_08, 2);
  210. GPIO_Iomux(GPIOE_09, 2);
  211. break;
  212. default:
  213. break;
  214. }
  215. if (uart->parity == 1)parity = UART_PARITY_ODD;
  216. else if (uart->parity == 2)parity = UART_PARITY_EVEN;
  217. int stop_bits = (uart->stop_bits)==1?UART_STOP_BIT1:UART_STOP_BIT2;
  218. if (uart->id >= MAX_DEVICE_COUNT) {
  219. serials[MAX_DEVICE_COUNT].rx_mark = 0;
  220. Core_VUartInit(VIRTUAL_UART0, uart->baud_rate, 1, (uart->data_bits), parity, stop_bits, NULL);
  221. } else {
  222. serials[uart->id].rx_mark = 0;
  223. Uart_BaseInit(uart->id, uart->baud_rate, 1, (uart->data_bits), parity, stop_bits, NULL);
  224. Uart_SetRxBufferSize(uart->id, uart->bufsz);
  225. serials[uart->id].rs485_param_bit.is_485used = (uart->pin485 < GPIO_NONE)?1:0;
  226. serials[uart->id].rs485_pin = uart->pin485;
  227. serials[uart->id].rs485_param_bit.rx_level = uart->rx_level;
  228. serials[uart->id].rs485_param_bit.wait_time = uart->delay;
  229. if (!serials[uart->id].rs485_timer) {
  230. serials[uart->id].rs485_timer = Timer_Create(luat_uart_wait_timer_cb, uart->id, NULL);
  231. }
  232. GPIO_Config(serials[uart->id].rs485_pin, 0, serials[uart->id].rs485_param_bit.rx_level);
  233. #ifndef UART_RX_USE_DMA
  234. Uart_EnableRxIrq(uart->id);
  235. #endif
  236. }
  237. return 0;
  238. }
  239. int luat_uart_write(int uartid, void *data, size_t length){
  240. //printf("uid:%d,data:%s,length = %d\r\n",uartid, (char *)data, length);
  241. if (!luat_uart_exist(uartid)){
  242. return 0;
  243. }
  244. if (uartid >= MAX_DEVICE_COUNT) {
  245. Core_VUartBufferTx(VIRTUAL_UART0, (const uint8_t *)data, length);
  246. }
  247. else {
  248. if (serials[uartid].rs485_param_bit.is_485used) GPIO_Output(serials[uartid].rs485_pin, !serials[uartid].rs485_param_bit.rx_level);
  249. Uart_BufferTx(uartid, (const uint8_t *)data, length);
  250. }
  251. return length;
  252. }
  253. int luat_uart_read(int uartid, void *buffer, size_t length){
  254. int ret = 0;
  255. if (!luat_uart_exist(uartid)){
  256. return 0;
  257. }
  258. if (uartid >= LUAT_VUART_ID_0) uartid = MAX_DEVICE_COUNT;
  259. serials[uartid].rx_mark = 0;
  260. if (uartid >= MAX_DEVICE_COUNT)
  261. ret = Core_VUartRxBufferRead(VIRTUAL_UART0, (uint8_t *)buffer,length);
  262. else
  263. ret = Uart_RxBufferRead(uartid, (uint8_t *)buffer,length);
  264. // LLOGD("uartid:%d buffer:%s ret:%d ",uartid,buffer, ret);
  265. return ret;
  266. }
  267. void luat_uart_clear_rx_cache(int uartid)
  268. {
  269. int ret = 0;
  270. if (!luat_uart_exist(uartid)){
  271. return;
  272. }
  273. if (uartid >= LUAT_VUART_ID_0) uartid = MAX_DEVICE_COUNT;
  274. serials[uartid].rx_mark = 0;
  275. if (uartid >= MAX_DEVICE_COUNT)
  276. Core_VUartRxBufferClear(VIRTUAL_UART0);
  277. else
  278. Uart_RxBufferClear(uartid);
  279. // LLOGD("uartid:%d buffer:%s ret:%d ",uartid,buffer, ret);
  280. return;
  281. }
  282. int luat_uart_close(int uartid){
  283. if (!luat_uart_exist(uartid)){
  284. return 0;
  285. }
  286. if (uartid >= LUAT_VUART_ID_0) uartid = MAX_DEVICE_COUNT;
  287. serials[uartid].rs485_param_bit.is_485used = 0;
  288. if (uartid >= MAX_DEVICE_COUNT)
  289. Core_VUartDeInit(VIRTUAL_UART0);
  290. else
  291. Uart_DeInit(uartid);
  292. return 0;
  293. }
  294. int luat_setup_cb(int uartid, int received, int sent){
  295. if (!luat_uart_exist(uartid)){
  296. return -1;
  297. }
  298. if (uartid >= MAX_DEVICE_COUNT)
  299. Core_VUartSetCb(VIRTUAL_UART0, luat_uart_usb_cb);
  300. else {
  301. Uart_SetCb(uartid, luat_uart_cb);
  302. //#ifndef UART_RX_USE_DMA
  303. // Uart_EnableRxIrq(uartid);
  304. //#endif
  305. }
  306. return 0;
  307. }
  308. int luat_uart_wait_485_tx_done(int uartid)
  309. {
  310. int cnt = 0;
  311. if (luat_uart_exist(uartid)){
  312. if (serials[uartid].rs485_param_bit.is_485used){
  313. while(!Uart_IsTSREmpty(uartid)) {cnt++;}
  314. GPIO_Output(serials[uartid].rs485_pin, serials[uartid].rs485_param_bit.rx_level);
  315. }
  316. }
  317. return cnt;
  318. }
  319. #ifdef LUAT_USE_SOFT_UART
  320. #ifdef __AIR105_BSP__
  321. #include "air105.h"
  322. #include "air105_conf.h"
  323. #endif
  324. #ifndef __BSP_COMMON_H__
  325. #include "c_common.h"
  326. #endif
  327. static void __FUNC_IN_RAM__ prvHWTimer_IrqHandler(int32_t Line, void *pData)
  328. {
  329. CommonFun_t callback = (CommonFun_t )pData;
  330. uint8_t hwtimer_id = HWTimer_GetIDFromIrqline(Line);
  331. volatile uint32_t clr;
  332. clr = TIMM0->TIM[hwtimer_id].EOI;
  333. callback();
  334. }
  335. int luat_uart_soft_setup_hwtimer_callback(int hwtimer_id, CommonFun_t callback)
  336. {
  337. int irq_line = HWTimer_GetIrqLine(hwtimer_id);
  338. TIMM0->TIM[hwtimer_id].ControlReg = 0;
  339. ISR_OnOff(irq_line, 0);
  340. ISR_Clear(irq_line);
  341. if (callback)
  342. {
  343. ISR_SetHandler(irq_line, prvHWTimer_IrqHandler, callback);
  344. ISR_SetPriority(irq_line, 3);
  345. ISR_OnOff(irq_line, 1);
  346. }
  347. return 0;
  348. }
  349. void __FUNC_IN_RAM__ luat_uart_soft_gpio_fast_output(int pin, uint8_t value)
  350. {
  351. GPIO_Output(pin, value);
  352. }
  353. uint8_t __FUNC_IN_RAM__ luat_uart_soft_gpio_fast_input(int pin)
  354. {
  355. return GPIO_Input(pin);
  356. }
  357. void luat_uart_soft_gpio_fast_irq_set(int pin, uint8_t on_off)
  358. {
  359. if (on_off)
  360. {
  361. GPIO_ExtiConfig(pin, 0, 0, 1);
  362. }
  363. else
  364. {
  365. GPIO_ExtiConfig(pin, 0, 0, 0);
  366. }
  367. }
  368. uint32_t luat_uart_soft_cal_baudrate(uint32_t baudrate)
  369. {
  370. return (48000000/baudrate);
  371. }
  372. void __FUNC_IN_RAM__ luat_uart_soft_hwtimer_onoff(int hwtimer_id, uint32_t period)
  373. {
  374. TIMM0->TIM[hwtimer_id].ControlReg = 0;
  375. // Enable TIMER IRQ
  376. if (period)
  377. {
  378. TIMM0->TIM[hwtimer_id].LoadCount = period - 1;
  379. TIMM0->TIM[hwtimer_id].ControlReg = TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_MODE;
  380. }
  381. }
  382. void __FUNC_IN_RAM__ luat_uart_soft_sleep_enable(uint8_t is_enable)
  383. {
  384. PM_SetDriverRunFlag(PM_DRV_SOFT_UART, !is_enable);
  385. }
  386. #endif