uart_rb_demo.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /*================================================================
  2. Copyright (c) 2022, Quectel Wireless Solutions Co., Ltd. All rights reserved.
  3. Quectel Wireless Solutions Proprietary and Confidential.
  4. =================================================================*/
  5. /*=================================================================
  6. EDIT HISTORY FOR MODULE
  7. This section contains comments describing changes made to the module.
  8. Notice that changes are listed in reverse chronological order.
  9. WHEN WHO WHAT, WHERE, WHY
  10. ------------ ------- -------------------------------------------------------------------------------
  11. =================================================================*/
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "ql_api_osi.h"
  16. #include "ql_log.h"
  17. #include "ql_uart.h"
  18. #include "ql_gpio.h"
  19. #include "ql_pin_cfg.h"
  20. /*===========================================================================
  21. *Definition
  22. ===========================================================================*/
  23. #define QL_UART_DEMO_LOG_LEVEL QL_LOG_LEVEL_INFO
  24. #define QL_UART_DEMO_LOG(msg, ...) QL_LOG(QL_UART_DEMO_LOG_LEVEL, "main_uart", msg, ##__VA_ARGS__)
  25. #define QL_UART_TASK_STACK_SIZE 4096
  26. #define QL_UART_TASK_PRIO APP_PRIORITY_NORMAL
  27. #define QL_UART_TASK_EVENT_CNT 5
  28. #define QL_UART_RX_BUFF_SIZE 2048
  29. #define QL_UART_TX_BUFF_SIZE 2048
  30. #define QL_RING_BUFF_SIZE 4096
  31. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  32. /*===========================================================================
  33. * Variate
  34. ===========================================================================*/
  35. typedef struct
  36. {
  37. unsigned char *buff;
  38. volatile unsigned int wp;
  39. volatile unsigned int rp;
  40. volatile unsigned int length;
  41. unsigned int size;
  42. } ring_buff_t;
  43. static ring_buff_t ql_ringbuf = {0};
  44. static ql_task_t uart_task_main = NULL;
  45. static ql_task_t uart_process_task = NULL;
  46. static ql_timer_t uart_process_timer = NULL;
  47. static ql_sem_t process_data_sem = NULL;
  48. /*===========================================================================
  49. * Functions
  50. ===========================================================================*/
  51. void rb_init(ring_buff_t *rb, unsigned char *buff, unsigned int size);
  52. void rb_clear(ring_buff_t *rb);
  53. unsigned int rb_write(ring_buff_t *rb, const unsigned char *data, unsigned int write_len);
  54. unsigned int rb_read(ring_buff_t *rb, unsigned char *data, unsigned int read_len);
  55. unsigned int rb_used_len(ring_buff_t *rb);
  56. unsigned int rb_free_len(ring_buff_t *rb);
  57. /**
  58. * @Brief : Initialize the ringbuffer object
  59. * @param rb
  60. * @param buff
  61. * @param size
  62. */
  63. void rb_init(ring_buff_t *rb, unsigned char *buff, unsigned int size)
  64. {
  65. rb->buff = buff;
  66. rb->size = size;
  67. rb->length = 0;
  68. rb->rp = 0;
  69. rb->wp = 0;
  70. memset(rb->buff, 0, rb->size);
  71. }
  72. /**
  73. * @Brief : Clearing a specified ringbuffer
  74. * @param rb
  75. */
  76. void rb_clear(ring_buff_t *rb)
  77. {
  78. memset(rb->buff, 0, rb->size);
  79. rb->length = 0;
  80. rb->rp = 0;
  81. rb->wp = 0;
  82. }
  83. /**
  84. * @Brief : Writes data to a ringbuffer
  85. * @param rb
  86. * @param data
  87. * @param write_len
  88. * @return unsigned int
  89. */
  90. unsigned int rb_write(ring_buff_t *rb, const unsigned char *data, unsigned int write_len)
  91. {
  92. unsigned int write_a, write_b;
  93. if (rb == NULL || data == NULL)
  94. {
  95. return 0;
  96. }
  97. if (rb->length + write_len > rb->size)
  98. {
  99. return 0;
  100. }
  101. if (rb->size - rb->wp < write_len)
  102. {
  103. write_a = rb->size - rb->wp;
  104. write_b = write_len - write_a;
  105. }
  106. else
  107. {
  108. write_a = write_len;
  109. write_b = 0;
  110. }
  111. if (write_b != 0)
  112. {
  113. memcpy(rb->buff + rb->wp, data, write_a);
  114. memcpy(rb->buff, data + write_a, write_b);
  115. rb->length += write_len;
  116. rb->wp = write_b;
  117. }
  118. else
  119. {
  120. memcpy(rb->buff + rb->wp, data, write_a);
  121. rb->length += write_len;
  122. rb->wp += write_a;
  123. if (rb->wp == rb->size)
  124. rb->wp = 0;
  125. }
  126. return write_len;
  127. }
  128. /**
  129. * @Brief : Read data from a circular ringbuffer
  130. * @param rb
  131. * @param data
  132. * @param read_len
  133. * @return unsigned int
  134. */
  135. unsigned int rb_read(ring_buff_t *rb, unsigned char *data, unsigned int read_len)
  136. {
  137. unsigned int real_len, read_a, read_b;
  138. if (rb == NULL || data == NULL)
  139. {
  140. return 0;
  141. }
  142. real_len = MIN(rb->length, read_len);
  143. if (rb->rp + real_len > rb->size)
  144. {
  145. read_a = rb->size - rb->rp;
  146. read_b = real_len - read_a;
  147. }
  148. else
  149. {
  150. read_a = real_len;
  151. read_b = 0;
  152. }
  153. if (read_b != 0)
  154. {
  155. memcpy(data, rb->buff + rb->rp, read_a);
  156. memcpy(data + read_a, rb->buff, read_b);
  157. rb->rp = read_b;
  158. rb->length -= real_len;
  159. }
  160. else
  161. {
  162. memcpy(data, rb->buff + rb->rp, read_a);
  163. rb->rp += read_a;
  164. rb->length -= real_len;
  165. if (rb->rp == rb->size)
  166. rb->rp = 0;
  167. }
  168. return real_len;
  169. }
  170. /**
  171. * @Brief : Returns the size of the stored space
  172. * @param rb
  173. * @return unsigned int
  174. */
  175. unsigned int rb_used_len(ring_buff_t *rb)
  176. {
  177. return rb->length;
  178. }
  179. /**
  180. * @Brief : Returns the size of free space
  181. * @param rb
  182. * @return unsigned int
  183. */
  184. unsigned int rb_free_len(ring_buff_t *rb)
  185. {
  186. return (rb->size - rb->length);
  187. }
  188. static void uart_process_callback(void *ctx)
  189. {
  190. ql_rtos_semaphore_release(process_data_sem);
  191. }
  192. void ql_uart_notify_cb(unsigned int ind_type, ql_uart_port_number_e port, unsigned int size)
  193. {
  194. unsigned char *recv_buff = calloc(1, QL_UART_RX_BUFF_SIZE + 1);
  195. unsigned int real_size = 0;
  196. int read_len = 0;
  197. QL_UART_DEMO_LOG("UART port %d receive ind type:0x%x, receive data size:%d", port, ind_type, size);
  198. switch (ind_type)
  199. {
  200. case QUEC_UART_RX_OVERFLOW_IND: // rx buffer overflow
  201. case QUEC_UART_RX_RECV_DATA_IND: {
  202. while (size > 0)
  203. {
  204. if (ql_rtos_timer_is_running(uart_process_timer))
  205. {
  206. ql_rtos_timer_stop(uart_process_timer);
  207. }
  208. memset(recv_buff, 0, QL_UART_RX_BUFF_SIZE + 1);
  209. real_size = MIN(size, QL_UART_RX_BUFF_SIZE);
  210. read_len = ql_uart_read(port, recv_buff, real_size);
  211. QL_UART_DEMO_LOG("read_len=%d, recv_data=%s", read_len, recv_buff);
  212. // put the read UART data into the RingBuffer
  213. rb_write(&ql_ringbuf, recv_buff, read_len);
  214. // You can modify the timeout to use as a frame of data
  215. ql_rtos_timer_start(uart_process_timer, 50, 0);
  216. if ((read_len > 0) && (size >= read_len))
  217. {
  218. size -= read_len;
  219. }
  220. else
  221. {
  222. break;
  223. }
  224. }
  225. break;
  226. }
  227. case QUEC_UART_TX_FIFO_COMPLETE_IND: {
  228. QL_UART_DEMO_LOG("tx fifo complete");
  229. break;
  230. }
  231. }
  232. free(recv_buff);
  233. recv_buff = NULL;
  234. }
  235. static void ql_uart_main(void *param)
  236. {
  237. int ret = 0;
  238. QlOSStatus err = 0;
  239. ql_uart_config_s uart_cfg = {0};
  240. ql_event_t event = {0};
  241. QL_UART_DEMO_LOG("ql_uart_demo_main comming\n");
  242. uart_cfg.baudrate = QL_UART_BAUD_115200;
  243. uart_cfg.flow_ctrl = QL_FC_NONE;
  244. uart_cfg.data_bit = QL_UART_DATABIT_8;
  245. uart_cfg.stop_bit = QL_UART_STOP_1;
  246. uart_cfg.parity_bit = QL_UART_PARITY_NONE;
  247. ret = ql_uart_set_dcbconfig(QL_UART_PORT_1, &uart_cfg);
  248. if (QL_UART_SUCCESS != ret)
  249. {
  250. QL_UART_DEMO_LOG("ql_uart_set_dcbconfig fail\n");
  251. goto exit;
  252. }
  253. ret = ql_uart_open(QL_UART_PORT_1);
  254. QL_UART_DEMO_LOG("ret: 0x%x", ret);
  255. if (QL_UART_SUCCESS == ret)
  256. {
  257. ret = ql_uart_register_cb(QL_UART_PORT_1, ql_uart_notify_cb);
  258. if (QL_UART_SUCCESS != ret)
  259. {
  260. goto exit;
  261. }
  262. }
  263. while (1)
  264. {
  265. ql_event_try_wait(&event);
  266. QL_UART_DEMO_LOG("enter task, id is %d", event.id);
  267. }
  268. exit:
  269. QL_UART_DEMO_LOG("exit uart task\n");
  270. err = ql_rtos_task_delete(NULL);
  271. if (err != QL_OSI_SUCCESS)
  272. {
  273. QL_UART_DEMO_LOG("task deleted failed");
  274. }
  275. }
  276. static void ql_uart_process(void *param)
  277. {
  278. QlOSStatus err = 0;
  279. unsigned char *rb_buf = NULL;
  280. unsigned char *read_buf = NULL;
  281. unsigned int valid_size = 0;
  282. rb_buf = (unsigned char *)calloc(1, QL_RING_BUFF_SIZE);
  283. if (rb_buf == NULL)
  284. {
  285. QL_UART_DEMO_LOG("No memory");
  286. goto exit;
  287. }
  288. rb_init(&ql_ringbuf, rb_buf, QL_RING_BUFF_SIZE);
  289. while (1)
  290. {
  291. ql_rtos_semaphore_wait(process_data_sem, QL_WAIT_FOREVER);
  292. valid_size = rb_used_len(&ql_ringbuf);
  293. if (valid_size != 0)
  294. {
  295. read_buf = (unsigned char *)calloc(1, valid_size + 1);
  296. err = rb_read(&ql_ringbuf, read_buf, valid_size);
  297. //Process your data
  298. QL_UART_DEMO_LOG("rb read len:%d,buf=%s", err, read_buf);
  299. }
  300. if (read_buf != NULL)
  301. {
  302. free(read_buf);
  303. read_buf = NULL;
  304. }
  305. }
  306. exit:
  307. QL_UART_DEMO_LOG("exit uart process task\n");
  308. err = ql_rtos_task_delete(NULL);
  309. if (err != QL_OSI_SUCCESS)
  310. {
  311. QL_UART_DEMO_LOG("task deleted failed");
  312. }
  313. }
  314. void ql_uart_rb_app_init(void)
  315. {
  316. QlOSStatus err = 0;
  317. err = ql_rtos_task_create(&uart_task_main, QL_UART_TASK_STACK_SIZE, QL_UART_TASK_PRIO, "uart_task", ql_uart_main, NULL, QL_UART_TASK_EVENT_CNT);
  318. if (err != QL_OSI_SUCCESS)
  319. {
  320. QL_UART_DEMO_LOG("Uart Task created failed");
  321. return;
  322. }
  323. err = ql_rtos_task_create(&uart_process_task, QL_UART_TASK_STACK_SIZE * 4, QL_UART_TASK_PRIO, "uart_process_task", ql_uart_process, NULL, QL_UART_TASK_EVENT_CNT);
  324. if (err != QL_OSI_SUCCESS)
  325. {
  326. QL_UART_DEMO_LOG("Uart process Task created failed");
  327. return;
  328. }
  329. err = ql_rtos_timer_create(&uart_process_timer, uart_task_main, uart_process_callback, NULL);
  330. if (err != QL_OSI_SUCCESS)
  331. {
  332. QL_UART_DEMO_LOG("timer created failed");
  333. return;
  334. }
  335. err = ql_rtos_semaphore_create_ex(&process_data_sem, 0, 1);
  336. if (err != QL_OSI_SUCCESS)
  337. {
  338. QL_UART_DEMO_LOG("sem created failed");
  339. return;
  340. }
  341. }