uart.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. #include "uart.h"
  2. #include "os/os_task.h"
  3. #include "libs/crc16.h"
  4. #include "libs/logger.h"
  5. #include "libs/utils.h"
  6. #define SHARK_UART_BAUDRATE 921600
  7. #ifdef GD32_DEMO
  8. #define SHARK_UART0_com USART1
  9. #define SHARK_UART0_tx_port GPIOA
  10. #define SHARK_UART0_tx_pin GPIO_PIN_2
  11. #define SHARK_UART0_rx_port GPIOA
  12. #define SHARK_UART0_rx_pin GPIO_PIN_3
  13. #define SHARK_UART0_irq USART1_IRQn
  14. #define SHARK_UART0_clk RCU_USART1
  15. #define SHARK_UART0_tx_gpio_clk RCU_GPIOA
  16. #define SHARK_UART0_rx_gpio_clk RCU_GPIOA
  17. #define SHARK_UART0_tx_dma DMA0
  18. #define SHARK_UART0_tx_dma_ch DMA_CH6
  19. #define SHARK_UART0_tx_dma_clk RCU_DMA0
  20. #define SHARK_UART0_rx_dma DMA0
  21. #define SHARK_UART0_rx_dma_ch DMA_CH5
  22. #define SHARK_UART0_rx_dma_clk RCU_DMA0
  23. #else
  24. #define SHARK_UART0_com USART2
  25. #define SHARK_UART0_tx_port GPIOB
  26. #define SHARK_UART0_tx_pin GPIO_PIN_10
  27. #define SHARK_UART0_rx_port GPIOB
  28. #define SHARK_UART0_rx_pin GPIO_PIN_11
  29. #define SHARK_UART0_irq USART2_IRQn
  30. #define SHARK_UART0_clk RCU_USART2
  31. #define SHARK_UART0_tx_gpio_clk RCU_GPIOB
  32. #define SHARK_UART0_rx_gpio_clk RCU_GPIOB
  33. #define SHARK_UART0_tx_dma DMA0
  34. #define SHARK_UART0_tx_dma_ch DMA_CH1
  35. #define SHARK_UART0_tx_dma_clk RCU_DMA0
  36. #define SHARK_UART0_rx_dma DMA0
  37. #define SHARK_UART0_rx_dma_ch DMA_CH2
  38. #define SHARK_UART0_rx_dma_clk RCU_DMA0
  39. #endif
  40. // ================================================================================
  41. #define ENABLE_RX_DMA 1
  42. static u8 shark_uart0_tx_cache[SHARK_UART_TX_MEM_SIZE];
  43. static u8 shark_uart0_rx_cache[SHARK_UART_RX_MEM_SIZE];
  44. static shark_uart_t _shark_uart[1];
  45. ///static bool uart_no_data = false;
  46. #if ENABLE_RX_DMA==1
  47. #define update_dma_w_pos(uart) circle_update_write_position(&uart->rx_queue, SHARK_UART_RX_MEM_SIZE - DMA_CHCNT(SHARK_UART0_rx_dma, uart->rx_dma_ch))
  48. #else
  49. #define update_dma_w_pos(uart){}
  50. #endif
  51. // ================================================================================
  52. static uart_enum_t _uart_index(uint32_t com){
  53. return SHARK_UART0;
  54. }
  55. static bool shark_uart_on_rx_frame(shark_uart_t *uart)
  56. {
  57. u16 crc0 = decode_u16(uart->rx_frame + uart->rx_length);
  58. u16 crc1 = crc16_get(uart->rx_frame, uart->rx_length);
  59. if (crc0 != crc1) {
  60. return false;
  61. }
  62. //protocol_recv_frame(_uart_index(uart->uart_com), (char *)uart->rx_frame, uart->rx_length);
  63. return true;
  64. }
  65. static void shark_uart_rx(shark_uart_t *uart){
  66. while(1) {
  67. u8 data;
  68. update_dma_w_pos(uart);
  69. if (circle_get_one_data(&uart->rx_queue, &data) != 1) {
  70. break;
  71. }
  72. switch(data){
  73. case CH_START:
  74. uart->rx_length = 0;
  75. uart->escape = false;
  76. uart->start = true;
  77. break;
  78. case CH_END:
  79. if (uart->rx_length > 2 && uart->rx_length != 0xFFFF){
  80. uart->rx_length -= 2; //skip crc
  81. shark_uart_on_rx_frame(uart);
  82. }
  83. uart->rx_length = 0xFFFF;
  84. uart->start = false;
  85. break;
  86. case CH_ESC:
  87. uart->escape = true;
  88. break;
  89. default:
  90. if (uart->escape) {
  91. uart->escape = false;
  92. switch (data) {
  93. case CH_ESC_START:
  94. data = CH_START;
  95. break;
  96. case CH_ESC_END:
  97. data = CH_END;
  98. break;
  99. case CH_ESC_ESC:
  100. data = CH_ESC;
  101. break;
  102. default:
  103. data = 0xFF;
  104. }
  105. }
  106. if (uart->rx_length < sizeof(uart->rx_frame)) {
  107. uart->rx_frame[uart->rx_length] = data;
  108. uart->rx_length++;
  109. } else {
  110. uart->rx_length = 0xFFFF;
  111. }
  112. }
  113. }
  114. }
  115. static void shark_uart_dma_tx(shark_uart_t *uart)
  116. {
  117. u32 value = DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch);
  118. if (value & DMA_CHXCTL_CHEN) {
  119. if (SET != dma_flag_get(SHARK_UART0_tx_dma, uart->tx_dma_ch, DMA_FLAG_FTF)) {
  120. return;
  121. }
  122. byte_queue_skip(&uart->tx_queue, uart->tx_length);
  123. DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch) = value & (~DMA_CHXCTL_CHEN);
  124. }
  125. uart->tx_length = byte_queue_peek(&uart->tx_queue);
  126. if (uart->tx_length > 0) {
  127. DMA_CHCNT(SHARK_UART0_tx_dma, uart->tx_dma_ch) = uart->tx_length;
  128. DMA_CHMADDR(SHARK_UART0_tx_dma, uart->tx_dma_ch) = (u32) byte_queue_head(&uart->tx_queue);
  129. dma_flag_clear(SHARK_UART0_tx_dma, uart->tx_dma_ch, DMA_FLAG_FTF);
  130. DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch) = value | DMA_CHXCTL_CHEN;
  131. }
  132. }
  133. static void shark_uart_write(shark_uart_t *uart, const u8 *buff, u16 size)
  134. {
  135. while (size > 0) {
  136. u16 length = byte_queue_write(&uart->tx_queue, buff, size);
  137. if (length == size) {
  138. shark_uart_dma_tx(uart);
  139. break;
  140. }
  141. shark_uart_dma_tx(uart);
  142. buff += length;
  143. size -= length;
  144. }
  145. }
  146. static void shark_uart_write_byte(shark_uart_t *uart, u8 value)
  147. {
  148. shark_uart_write(uart, &value, 1);
  149. }
  150. void shark_uart_write_log(char *buffer){
  151. int len = strlen(buffer);
  152. shark_uart_t *uart = (_shark_uart+SHARK_UART0);
  153. if (len > byte_queue_get_free(&uart->tx_queue)){
  154. return;
  155. }
  156. byte_queue_write(&uart->tx_queue, (const u8 *)buffer, len);
  157. shark_uart_dma_tx(uart);
  158. }
  159. static void shark_uart_tx_dma_init(shark_uart_t *uart){
  160. dma_parameter_struct dma_init_struct;
  161. rcu_periph_clock_enable(SHARK_UART0_tx_dma_clk);
  162. dma_deinit(SHARK_UART0_tx_dma, uart->tx_dma_ch);
  163. dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
  164. dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  165. dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
  166. dma_init_struct.periph_addr = (u32) &USART_DATA(uart->uart_com);
  167. dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  168. dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
  169. dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  170. dma_init(SHARK_UART0_tx_dma, uart->tx_dma_ch, &dma_init_struct);
  171. dma_circulation_disable(SHARK_UART0_tx_dma, uart->tx_dma_ch);
  172. dma_memory_to_memory_disable(SHARK_UART0_tx_dma, uart->tx_dma_ch);
  173. usart_dma_transmit_config(uart->uart_com, USART_DENT_ENABLE);
  174. #if 0
  175. if (uart->tx_dma_ch == DMA_CH1) {
  176. nvic_irq_enable(DMA_Channel1_2_IRQn ,4, 0);
  177. }else {
  178. nvic_irq_enable(DMA_Channel3_4_IRQn ,4, 0);
  179. }
  180. dma_interrupt_enable(uart->tx_dma_ch, DMA_INT_FTF);
  181. #endif
  182. }
  183. #if ENABLE_RX_DMA==1
  184. static void shark_uart_rx_dma_init(shark_uart_t *uart){
  185. dma_parameter_struct dma_init_struct;
  186. rcu_periph_clock_enable(SHARK_UART0_rx_dma_clk);
  187. dma_deinit(SHARK_UART0_rx_dma, uart->rx_dma_ch);
  188. dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
  189. dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  190. dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
  191. dma_init_struct.memory_addr = (u32)uart->rx_queue.buffer;
  192. dma_init_struct.number = uart->rx_queue.buffer_len;
  193. dma_init_struct.periph_addr = (u32) &USART_DATA(uart->uart_com);
  194. dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  195. dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
  196. dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  197. dma_init(SHARK_UART0_rx_dma, uart->rx_dma_ch, &dma_init_struct);
  198. dma_circulation_enable(SHARK_UART0_rx_dma, uart->rx_dma_ch);
  199. dma_memory_to_memory_disable(SHARK_UART0_rx_dma, uart->rx_dma_ch);
  200. dma_channel_enable(SHARK_UART0_rx_dma, uart->rx_dma_ch);
  201. usart_dma_receive_config(uart->uart_com, USART_DENR_ENABLE);
  202. }
  203. #endif
  204. static void shark_uart_pin_init(shark_uart_t *uart){
  205. rcu_periph_clock_enable(SHARK_UART0_clk);
  206. rcu_periph_clock_enable(SHARK_UART0_rx_gpio_clk);
  207. rcu_periph_clock_enable(SHARK_UART0_tx_gpio_clk);
  208. rcu_periph_clock_enable(RCU_AF);
  209. gpio_init(SHARK_UART0_tx_port, GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,SHARK_UART0_tx_pin);
  210. gpio_init(SHARK_UART0_rx_port, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,SHARK_UART0_rx_pin);
  211. }
  212. static void shark_uart_pin_deinit(shark_uart_t *uart){
  213. if (_uart_index(uart->uart_com) == SHARK_UART0) {
  214. gpio_init(SHARK_UART0_tx_port, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,SHARK_UART0_tx_pin);
  215. gpio_init(SHARK_UART0_rx_port, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,SHARK_UART0_rx_pin);
  216. }
  217. }
  218. static void shark_uart_device_init(shark_uart_t *uart){
  219. usart_deinit(uart->uart_com);
  220. usart_baudrate_set(uart->uart_com, SHARK_UART_BAUDRATE);
  221. usart_word_length_set(uart->uart_com, USART_WL_8BIT);
  222. usart_stop_bit_set(uart->uart_com, USART_STB_1BIT);
  223. usart_parity_config(uart->uart_com, USART_PM_NONE);
  224. usart_hardware_flow_rts_config(uart->uart_com, USART_RTS_DISABLE);
  225. usart_hardware_flow_cts_config(uart->uart_com, USART_CTS_DISABLE);
  226. usart_receive_config(uart->uart_com, USART_RECEIVE_ENABLE);
  227. usart_transmit_config(uart->uart_com, USART_TRANSMIT_ENABLE);
  228. #if ENABLE_RX_DMA==0
  229. usart_lin_mode_disable(uart->uart_com);
  230. usart_receiver_timeout_disable(uart->uart_com);
  231. usart_interrupt_enable(uart->uart_com,USART_INT_RBNE);
  232. #endif
  233. }
  234. static u32 shark_uart_task(void *args)
  235. {
  236. shark_uart_t *uart = (shark_uart_t *)args;
  237. if(uart->uart_com != 0) {
  238. shark_uart_rx(uart);
  239. shark_uart_dma_tx(uart);
  240. }
  241. return 0;
  242. }
  243. void shark_uart_flush(void){
  244. shark_uart_t *uart = _shark_uart + SHARK_UART0;
  245. if (uart->uart_com != 0) {
  246. while(!byte_queue_empty(&uart->tx_queue)) {
  247. shark_uart_dma_tx(uart);
  248. }
  249. }
  250. }
  251. #if 0
  252. void DMA_Channel1_2_IRQHandler(void){
  253. shark_uart_t *uart = _shark_uart + SHARK_UART0;
  254. if (dma_interrupt_flag_get(uart->tx_dma_ch, DMA_INT_FLAG_FTF) != RESET){
  255. shark_uart_dma_tx(uart);
  256. dma_interrupt_flag_clear(uart->tx_dma_ch, DMA_INT_FLAG_FTF);
  257. }
  258. }
  259. void DMA_Channel3_4_IRQHandler(void){
  260. shark_uart_t *uart = _shark_uart + SHARK_UART1;
  261. if (dma_interrupt_flag_get(uart->tx_dma_ch, DMA_INT_FLAG_FTF) != RESET){
  262. shark_uart_dma_tx(uart);
  263. dma_interrupt_flag_clear(uart->tx_dma_ch, DMA_INT_FLAG_FTF);
  264. }
  265. }
  266. #endif
  267. static u8 *tx_cache_addr(uart_enum_t uart_no){
  268. return shark_uart0_tx_cache;
  269. }
  270. static u8 *rx_cache_addr(uart_enum_t uart_no){
  271. return shark_uart0_rx_cache;
  272. }
  273. void shark_uart_deinit(uart_enum_t uart_no){
  274. shark_uart_t *uart = _shark_uart + uart_no;
  275. if (uart->uart_com != 0) {
  276. usart_disable(uart->uart_com);
  277. usart_deinit(uart->uart_com);
  278. rcu_periph_clock_disable(SHARK_UART0_clk);
  279. dma_channel_disable(SHARK_UART0_rx_dma, uart->rx_dma_ch);
  280. dma_channel_disable(SHARK_UART0_tx_dma, uart->tx_dma_ch);
  281. rcu_periph_clock_disable(SHARK_UART0_tx_dma_clk);
  282. rcu_periph_clock_disable(SHARK_UART0_rx_dma_clk);
  283. shark_uart_pin_deinit(uart);
  284. }
  285. #if ENABLE_RX_DMA==0
  286. nvic_irq_disable(SHARK_UART0_irq);
  287. #endif
  288. }
  289. bool shark_uart_timeout(void){
  290. #if UART_NUM==2
  291. return (_shark_uart[0].uart_no_data && _shark_uart[1].uart_no_data)?TRUE:FALSE;
  292. #else
  293. return (_shark_uart[0].uart_no_data)?TRUE:FALSE;
  294. #endif
  295. }
  296. void shark_uart_init(uart_enum_t uart_no)
  297. {
  298. shark_uart_t *uart = _shark_uart + uart_no;
  299. uart->escape = false;
  300. uart->rx_length = 0;
  301. uart->tx_length = 0;
  302. uart->uart_com = SHARK_UART0_com;
  303. circle_buffer_init(&uart->rx_queue, rx_cache_addr(uart_no), SHARK_UART_RX_MEM_SIZE);
  304. byte_queue_init(&uart->tx_queue,tx_cache_addr(uart_no), SHARK_UART_TX_MEM_SIZE);
  305. uart->rx_dma_ch = SHARK_UART0_rx_dma_ch;
  306. uart->tx_dma_ch = SHARK_UART0_tx_dma_ch;
  307. shark_uart_pin_init(uart);
  308. shark_uart_device_init(uart);
  309. #if ENABLE_RX_DMA==1
  310. shark_uart_rx_dma_init(uart);
  311. #endif
  312. shark_uart_tx_dma_init(uart);
  313. usart_enable(uart->uart_com);
  314. shark_task_create(shark_uart_task, uart);
  315. #if ENABLE_RX_DMA==0
  316. nvic_irq_enable(SHARK_UART0_irq, 3, 0);
  317. #endif
  318. uart->uart_no_data = false;
  319. }
  320. #if ENABLE_RX_DMA==0
  321. void USART3_IRQHandler(void){
  322. if(usart_flag_get(USART0, USART_FLAG_RBNE) == SET){
  323. shark_uart_t *uart = _shark_uart + SHARK_UART0;
  324. u8 c = usart_data_receive(USART0);
  325. circle_put_one_data(&uart->rx_queue, c);
  326. }
  327. }
  328. #endif
  329. static void shark_uart_write_byte_esc(shark_uart_t *uart, u8 value)
  330. {
  331. switch (value) {
  332. case CH_START:
  333. shark_uart_write_byte(uart, CH_ESC);
  334. value = CH_ESC_START;
  335. break;
  336. case CH_END:
  337. shark_uart_write_byte(uart, CH_ESC);
  338. value = CH_ESC_END;
  339. break;
  340. case CH_ESC:
  341. shark_uart_write_byte(uart, CH_ESC);
  342. value = CH_ESC_ESC;
  343. break;
  344. }
  345. shark_uart_write_byte(uart, value);
  346. }
  347. static void shark_uart_write_esc(shark_uart_t *uart, const u8 *buff, u16 length)
  348. {
  349. const u8 *buff_end;
  350. for (buff_end = buff + length; buff < buff_end; buff++) {
  351. shark_uart_write_byte_esc(uart, *buff);
  352. }
  353. }
  354. static void shark_uart_tx_start(shark_uart_t *uart)
  355. {
  356. shark_uart_write_byte(uart, CH_START);
  357. uart->tx_crc16 = 0;
  358. }
  359. static void shark_uart_tx_continue(shark_uart_t *uart, const void *buff, u16 length)
  360. {
  361. shark_uart_write_esc(uart, (const u8 *) buff, length);
  362. uart->tx_crc16 = crc16_update(uart->tx_crc16, (const u8 *) buff, length);
  363. }
  364. static void shark_uart_tx_end(shark_uart_t *uart)
  365. {
  366. shark_uart_write_esc(uart, (u8 *)&uart->tx_crc16, sizeof(uart->tx_crc16));
  367. shark_uart_write_byte(uart, CH_END);
  368. }
  369. void shark_uart_write_frame(uart_enum_t uart_no, uint8_t *bytes, int len){
  370. shark_uart_t *uart = _shark_uart + uart_no;
  371. shark_uart_tx_start(uart);
  372. shark_uart_tx_continue(uart, bytes, len);
  373. shark_uart_tx_end(uart);
  374. }
  375. void shark_uart_frame_start(uart_enum_t uart_no, uint8_t *bytes, int len){
  376. shark_uart_t *uart = _shark_uart + uart_no;
  377. shark_uart_tx_start(uart);
  378. shark_uart_tx_continue(uart, bytes, len);
  379. }
  380. void shark_uart_frame_continue(uart_enum_t uart_no, uint8_t *bytes, int len){
  381. shark_uart_t *uart = _shark_uart + uart_no;
  382. shark_uart_tx_continue(uart, bytes, len);
  383. }
  384. void shark_uart_frame_end(uart_enum_t uart_no){
  385. shark_uart_tx_end(_shark_uart + uart_no);
  386. }
  387. void shark_uart_write_bytes(uart_enum_t uart_no, u8 *buff, u16 size){
  388. shark_uart_write(_shark_uart + uart_no, buff, size);
  389. }
  390. int fputc(int c, FILE *fp){
  391. shark_uart_write_byte(_shark_uart+SHARK_UART0, (u8)c);
  392. return 1;
  393. }