serial.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include "hal/uart2.h"
  2. #include "libs/utils.h"
  3. #include "libs/task.h"
  4. #include "serial.h"
  5. static uart_t uart2;
  6. static u32 uart_poll_task(void);
  7. void serial_init(void){
  8. circle_buffer_init(&uart2.c_tx_buff , uart2.tx_buf, sizeof(uart2.tx_buf));
  9. circle_buffer_init(&uart2.c_rx_buff , uart2.rx_buf, sizeof(uart2.rx_buf));
  10. UART2_Init();
  11. task_start(uart_poll_task, 0);
  12. }
  13. void serial_write(u8 *data, int len){
  14. circle_put_data(&uart2.c_tx_buff, data, len);
  15. UART2_EnableTx();
  16. }
  17. __weak void protocol_recv_frame(u8 *data, u16 rx_len) {}
  18. static bool uart_on_rx_frame(uart_t *uart)
  19. {
  20. u16 crc0 = shark_decode_u16(uart->rx_frame + uart->rx_length);
  21. u16 crc1 = shark_crc16_check(uart->rx_frame, uart->rx_length);
  22. if (crc0 != crc1) {
  23. return false;
  24. }
  25. protocol_recv_frame((u8 *)uart->rx_frame, uart->rx_length);
  26. return true;
  27. }
  28. static void uart_rx_poll(uart_t *uart) {
  29. u8 data;
  30. while(1) {
  31. if (circle_get_one_data(&uart->c_rx_buff, &data) != 1) {
  32. break;
  33. }
  34. switch(data){
  35. case CH_START:
  36. uart->rx_length = 0;
  37. uart->escape = false;
  38. break;
  39. case CH_END:
  40. if (uart->rx_length > 2 && uart->rx_length != 0xFFFF){
  41. uart->rx_length -= 2; //skip crc
  42. uart_on_rx_frame(uart);
  43. }
  44. uart->rx_length = 0xFFFF;
  45. break;
  46. case CH_ESC:
  47. uart->escape = true;
  48. break;
  49. default:
  50. if (uart->escape) {
  51. uart->escape = false;
  52. switch (data) {
  53. case CH_ESC_START:
  54. data = CH_START;
  55. break;
  56. case CH_ESC_END:
  57. data = CH_END;
  58. break;
  59. case CH_ESC_ESC:
  60. data = CH_ESC;
  61. break;
  62. default:
  63. data = 0xFF;
  64. }
  65. }
  66. if (uart->rx_length < sizeof(uart->rx_frame)) {
  67. uart->rx_frame[uart->rx_length] = data;
  68. uart->rx_length++;
  69. } else {
  70. uart->rx_length = 0xFFFF;
  71. }
  72. }
  73. }
  74. }
  75. static u32 uart_poll_task(void){
  76. uart_rx_poll(&uart2);
  77. return 0;
  78. }
  79. static void uart_write_byte(uart_t *uart, u8 value)
  80. {
  81. circle_put_data(&uart->c_tx_buff, &value, 1);
  82. }
  83. static void uart_write_byte_esc(uart_t *uart, u8 value)
  84. {
  85. switch (value) {
  86. case CH_START:
  87. uart_write_byte(uart, CH_ESC);
  88. value = CH_ESC_START;
  89. break;
  90. case CH_END:
  91. uart_write_byte(uart, CH_ESC);
  92. value = CH_ESC_END;
  93. break;
  94. case CH_ESC:
  95. uart_write_byte(uart, CH_ESC);
  96. value = CH_ESC_ESC;
  97. break;
  98. }
  99. uart_write_byte(uart, value);
  100. }
  101. static void uart_write_esc(uart_t *uart, const u8 *buff, u16 length)
  102. {
  103. const u8 *buff_end;
  104. for (buff_end = buff + length; buff < buff_end; buff++) {
  105. uart_write_byte_esc(uart, *buff);
  106. }
  107. }
  108. static void uart_tx_start(uart_t *uart)
  109. {
  110. uart_write_byte(uart, CH_START);
  111. uart->tx_crc16 = 0;
  112. }
  113. static void uart_tx_continue(uart_t *uart, const void *buff, u16 length)
  114. {
  115. uart_write_esc(uart, (const u8 *) buff, length);
  116. uart->tx_crc16 = shark_crc16_update(uart->tx_crc16, (const u8 *) buff, length);
  117. }
  118. static void uart_tx_end(uart_t *uart)
  119. {
  120. uart_write_esc(uart, (u8 *)&uart->tx_crc16, sizeof(uart->tx_crc16));
  121. uart_write_byte(uart, CH_END);
  122. UART2_EnableTx();
  123. }
  124. void uart_write_frame(uint8_t *bytes, int len){
  125. uart_t *uart = &uart2;
  126. uart_tx_start(uart);
  127. uart_tx_continue(uart, bytes, len);
  128. uart_tx_end(uart);
  129. }
  130. bool uart_tx_finished(void) {
  131. u8 data;
  132. if (circle_get_one_data(&uart2.c_tx_buff, &data) <= 0){
  133. return true;
  134. }
  135. UART2_TxData(data);
  136. return false;
  137. }
  138. void uart_rx_put(u8 ch) {
  139. circle_put_one_data(&uart2.c_rx_buff, ch);
  140. }
  141. int fputc(int c, FILE *fp){
  142. u8 data = c;
  143. serial_write(&data, 1);
  144. return 1;
  145. }