uart.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  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 230400
  7. #ifdef DEBUG_PORT_UART1
  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. #define SHARK_UART0_DMA_TX_IRQ DMA0_Channel6_IRQn
  24. #define UART_DMA_IRQHandler DMA0_Channel6_IRQHandler
  25. #else
  26. #define SHARK_UART0_com USART3
  27. #define SHARK_UART0_tx_port GPIOB
  28. #define SHARK_UART0_tx_pin GPIO_PIN_10
  29. #define SHARK_UART0_rx_port GPIOB
  30. #define SHARK_UART0_rx_pin GPIO_PIN_11
  31. #define SHARK_UART0_irq USART3_IRQn
  32. #define SHARK_UART0_clk RCC_APB1_PERIPH_USART3
  33. #define SHARK_UART0_tx_gpio_clk RCC_APB2_PERIPH_GPIOB
  34. #define SHARK_UART0_rx_gpio_clk RCC_APB2_PERIPH_GPIOB
  35. #define SHARK_UART0_tx_dma DMA1
  36. #define SHARK_UART0_tx_dma_ch DMA1_CH2
  37. #define SHARK_UART0_tx_dma_clk RCC_AHB_PERIPH_DMA1
  38. #define SHARK_UART0_rx_dma DMA0
  39. #define SHARK_UART0_rx_dma_ch DMA1_CH3
  40. #define SHARK_UART0_rx_dma_clk RCC_AHB_PERIPH_DMA1
  41. #define SHARK_UART0_DMA_TX_IRQ DMA0_Channel1_IRQn
  42. #define USARTy_Tx_DMA_FLAG DMA1_FLAG_TC2
  43. #define USARTy_Rx_DMA_FLAG DMA1_FLAG_TC3
  44. #define UART_DMA_IRQHandler DMA0_Channel1_IRQHandler
  45. #endif
  46. // ================================================================================
  47. #define ENABLE_RX_DMA 1
  48. static u8 shark_uart0_tx_cache[SHARK_UART_TX_MEM_SIZE];
  49. static u8 shark_uart0_rx_cache[SHARK_UART_RX_MEM_SIZE];
  50. static shark_uart_t _shark_uart[1];
  51. ///static bool uart_no_data = false;
  52. #if ENABLE_RX_DMA==1
  53. #define update_dma_w_pos(uart) circle_update_write_position(&uart->rx_queue, SHARK_UART_RX_MEM_SIZE - DMA_GetCurrDataCounter(SHARK_UART0_rx_dma_ch))
  54. #else
  55. #define update_dma_w_pos(uart){}
  56. #endif
  57. // ================================================================================
  58. static bool shark_uart_on_rx_frame(shark_uart_t *uart)
  59. {
  60. u16 crc0 = decode_u16(uart->rx_frame + uart->rx_length);
  61. u16 crc1 = crc16_get(uart->rx_frame, uart->rx_length);
  62. if (crc0 != crc1) {
  63. return false;
  64. }
  65. //protocol_recv_frame(_uart_index(uart->uart_com), (char *)uart->rx_frame, uart->rx_length);
  66. return true;
  67. }
  68. static void shark_uart_rx(shark_uart_t *uart){
  69. while(1) {
  70. u8 data = 0;
  71. update_dma_w_pos(uart);
  72. if (circle_get_one_data(&uart->rx_queue, &data) != 1) {
  73. return;
  74. }
  75. switch(data){
  76. case CH_START:
  77. uart->rx_length = 0;
  78. uart->escape = false;
  79. uart->start = true;
  80. break;
  81. case CH_END:
  82. if (uart->rx_length > 2 && uart->rx_length != 0xFFFF){
  83. uart->rx_length -= 2; //skip crc
  84. shark_uart_on_rx_frame(uart);
  85. }
  86. uart->rx_length = 0xFFFF;
  87. uart->start = false;
  88. break;
  89. case CH_ESC:
  90. uart->escape = true;
  91. break;
  92. default:
  93. if (uart->escape) {
  94. uart->escape = false;
  95. switch (data) {
  96. case CH_ESC_START:
  97. data = CH_START;
  98. break;
  99. case CH_ESC_END:
  100. data = CH_END;
  101. break;
  102. case CH_ESC_ESC:
  103. data = CH_ESC;
  104. break;
  105. default:
  106. data = 0xFF;
  107. }
  108. }
  109. if (uart->rx_length < sizeof(uart->rx_frame)) {
  110. uart->rx_frame[uart->rx_length] = data;
  111. uart->rx_length++;
  112. } else {
  113. uart->rx_length = 0xFFFF;
  114. }
  115. }
  116. }
  117. }
  118. #define DMA_CHCTL(SHARK_UART0_tx_dma, tx_dma_ch) (tx_dma_ch->CHCFG)
  119. static void shark_uart_dma_tx(shark_uart_t *uart)
  120. {
  121. u32 value = DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch);
  122. if (value & DMA_CHCFG1_CHEN) {
  123. if (SET != DMA_GetFlagStatus(USARTy_Tx_DMA_FLAG, SHARK_UART0_tx_dma)) {
  124. return;
  125. }
  126. DMA_ClearFlag(USARTy_Tx_DMA_FLAG, SHARK_UART0_tx_dma);
  127. byte_queue_skip(&uart->tx_queue, uart->tx_length);
  128. DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch) = value & (~DMA_CHCFG1_CHEN);
  129. }
  130. uart->tx_length = byte_queue_peek(&uart->tx_queue);
  131. if (uart->tx_length > 0) {
  132. DMA_SetCurrDataCounter(uart->tx_dma_ch, uart->tx_length);
  133. uart->tx_dma_ch->MADDR = (u32) byte_queue_head(&uart->tx_queue);
  134. DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch) = value | DMA_CHCFG1_CHEN;
  135. }
  136. }
  137. static void shark_uart_write(shark_uart_t *uart, const u8 *buff, u16 size)
  138. {
  139. while (size > 0) {
  140. u16 length = byte_queue_write(&uart->tx_queue, buff, size);
  141. if (length == size) {
  142. shark_uart_dma_tx(uart);
  143. break;
  144. }
  145. shark_uart_dma_tx(uart);
  146. buff += length;
  147. size -= length;
  148. }
  149. }
  150. static void shark_uart_write_byte(shark_uart_t *uart, u8 value)
  151. {
  152. byte_queue_write(&uart->tx_queue, &value, 1);
  153. }
  154. void shark_uart_write_log(char *buffer){
  155. int len = strlen(buffer);
  156. shark_uart_t *uart = (_shark_uart+SHARK_UART0);
  157. if (len > byte_queue_get_free(&uart->tx_queue)){
  158. return;
  159. }
  160. byte_queue_write(&uart->tx_queue, (const u8 *)buffer, len);
  161. shark_uart_dma_tx(uart);
  162. }
  163. static void shark_uart_tx_dma_init(shark_uart_t *uart){
  164. rcu_ahb_periph_clock_enable(SHARK_UART0_tx_dma_clk);
  165. DMA_InitType DMA_InitStructure;
  166. /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
  167. DMA_DeInit(SHARK_UART0_tx_dma_ch);
  168. DMA_InitStructure.PeriphAddr = (u32)uart->uart_com + 0x04;
  169. DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;
  170. DMA_InitStructure.BufSize = 0;
  171. DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
  172. DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
  173. DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
  174. DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;
  175. DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
  176. DMA_InitStructure.Priority = DMA_PRIORITY_VERY_HIGH;
  177. DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
  178. DMA_Init(SHARK_UART0_tx_dma_ch, &DMA_InitStructure);
  179. USART_EnableDMA(uart->uart_com, USART_DMAREQ_TX, ENABLE);
  180. }
  181. #if ENABLE_RX_DMA==1
  182. static void shark_uart_rx_dma_init(shark_uart_t *uart){
  183. rcu_ahb_periph_clock_enable(SHARK_UART0_rx_dma_clk);
  184. DMA_InitType DMA_InitStructure;
  185. /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
  186. DMA_DeInit(SHARK_UART0_rx_dma_ch);
  187. DMA_InitStructure.PeriphAddr = (u32)uart->uart_com + 0x04;
  188. DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
  189. DMA_InitStructure.BufSize = uart->rx_queue.buffer_len;
  190. DMA_InitStructure.MemAddr = (u32)uart->rx_queue.buffer;
  191. DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
  192. DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
  193. DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
  194. DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;
  195. DMA_InitStructure.CircularMode = DMA_MODE_CIRCULAR;
  196. DMA_InitStructure.Priority = DMA_PRIORITY_VERY_HIGH;
  197. DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
  198. DMA_Init(SHARK_UART0_rx_dma_ch, &DMA_InitStructure);
  199. USART_EnableDMA(uart->uart_com, USART_DMAREQ_RX, ENABLE);
  200. }
  201. #endif
  202. static void shark_uart_pin_init(shark_uart_t *uart){
  203. rcu_apb1_periph_clock_enable(SHARK_UART0_clk);
  204. rcu_apb2_periph_clock_enable(SHARK_UART0_rx_gpio_clk);
  205. rcu_apb2_periph_clock_enable(SHARK_UART0_tx_gpio_clk);
  206. rcu_apb2_periph_clock_enable(RCU_AF);
  207. gpio_init(SHARK_UART0_tx_port, GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,SHARK_UART0_tx_pin);
  208. gpio_init(SHARK_UART0_rx_port, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,SHARK_UART0_rx_pin);
  209. }
  210. static void shark_uart_device_init(shark_uart_t *uart){
  211. USART_InitType USART_InitStructure;
  212. USART_StructInit(&USART_InitStructure);
  213. USART_InitStructure.BaudRate = SHARK_UART_BAUDRATE;
  214. USART_InitStructure.WordLength = USART_WL_8B;
  215. USART_InitStructure.StopBits = USART_STPB_1;
  216. USART_InitStructure.Parity = USART_PE_NO;
  217. USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
  218. USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
  219. /* Configure USARTy and USARTz */
  220. USART_Init(uart->uart_com, &USART_InitStructure);
  221. USART_Enable(uart->uart_com, ENABLE);
  222. }
  223. static u32 shark_uart_task(void *args)
  224. {
  225. shark_uart_t *uart = (shark_uart_t *)args;
  226. if(uart->uart_com != 0) {
  227. shark_uart_rx(uart);
  228. shark_uart_dma_tx(uart);
  229. }
  230. return 0;
  231. }
  232. void shark_uart_flush(void){
  233. shark_uart_t *uart = _shark_uart + SHARK_UART0;
  234. if (uart->uart_com != 0) {
  235. while(!byte_queue_empty(&uart->tx_queue)) {
  236. shark_uart_dma_tx(uart);
  237. }
  238. }
  239. }
  240. static u8 *tx_cache_addr(uart_enum_t uart_no){
  241. return shark_uart0_tx_cache;
  242. }
  243. static u8 *rx_cache_addr(uart_enum_t uart_no){
  244. return shark_uart0_rx_cache;
  245. }
  246. void shark_uart_deinit(uart_enum_t uart_no){
  247. }
  248. bool shark_uart_timeout(void){
  249. #if UART_NUM==2
  250. return (_shark_uart[0].uart_no_data && _shark_uart[1].uart_no_data)?TRUE:FALSE;
  251. #else
  252. return (_shark_uart[0].uart_no_data)?TRUE:FALSE;
  253. #endif
  254. }
  255. void shark_uart_init(uart_enum_t uart_no)
  256. {
  257. shark_uart_t *uart = _shark_uart + uart_no;
  258. uart->escape = false;
  259. uart->rx_length = 0;
  260. uart->tx_length = 0;
  261. uart->uart_com = SHARK_UART0_com;
  262. circle_buffer_init(&uart->rx_queue, rx_cache_addr(uart_no), SHARK_UART_RX_MEM_SIZE);
  263. byte_queue_init(&uart->tx_queue,tx_cache_addr(uart_no), SHARK_UART_TX_MEM_SIZE);
  264. uart->rx_dma_ch = SHARK_UART0_rx_dma_ch;
  265. uart->tx_dma_ch = SHARK_UART0_tx_dma_ch;
  266. shark_uart_pin_init(uart);
  267. shark_uart_device_init(uart);
  268. shark_uart_rx_dma_init(uart);
  269. shark_uart_tx_dma_init(uart);
  270. shark_task_create(shark_uart_task, uart);
  271. uart->uart_no_data = false;
  272. }
  273. void UART_DMA_IRQHandler(void) {
  274. }
  275. static void shark_uart_write_byte_esc(shark_uart_t *uart, u8 value)
  276. {
  277. switch (value) {
  278. case CH_START:
  279. shark_uart_write_byte(uart, CH_ESC);
  280. value = CH_ESC_START;
  281. break;
  282. case CH_END:
  283. shark_uart_write_byte(uart, CH_ESC);
  284. value = CH_ESC_END;
  285. break;
  286. case CH_ESC:
  287. shark_uart_write_byte(uart, CH_ESC);
  288. value = CH_ESC_ESC;
  289. break;
  290. }
  291. shark_uart_write_byte(uart, value);
  292. }
  293. static void shark_uart_write_esc(shark_uart_t *uart, const u8 *buff, u16 length)
  294. {
  295. const u8 *buff_end;
  296. for (buff_end = buff + length; buff < buff_end; buff++) {
  297. shark_uart_write_byte_esc(uart, *buff);
  298. }
  299. }
  300. static void shark_uart_tx_start(shark_uart_t *uart)
  301. {
  302. shark_uart_write_byte(uart, CH_START);
  303. uart->tx_crc16 = 0;
  304. }
  305. static void shark_uart_tx_continue(shark_uart_t *uart, const void *buff, u16 length)
  306. {
  307. shark_uart_write_esc(uart, (const u8 *) buff, length);
  308. uart->tx_crc16 = crc16_update(uart->tx_crc16, (const u8 *) buff, length);
  309. }
  310. static void shark_uart_tx_end(shark_uart_t *uart)
  311. {
  312. shark_uart_write_esc(uart, (u8 *)&uart->tx_crc16, sizeof(uart->tx_crc16));
  313. shark_uart_write_byte(uart, CH_END);
  314. }
  315. void shark_uart_write_frame(uart_enum_t uart_no, uint8_t *bytes, int len){
  316. shark_uart_t *uart = _shark_uart + uart_no;
  317. shark_uart_tx_start(uart);
  318. shark_uart_tx_continue(uart, bytes, len);
  319. shark_uart_tx_end(uart);
  320. shark_uart_dma_tx(uart);
  321. }
  322. void shark_uart_frame_start(uart_enum_t uart_no, uint8_t *bytes, int len){
  323. shark_uart_t *uart = _shark_uart + uart_no;
  324. shark_uart_tx_start(uart);
  325. shark_uart_tx_continue(uart, bytes, len);
  326. }
  327. void shark_uart_frame_continue(uart_enum_t uart_no, uint8_t *bytes, int len){
  328. shark_uart_t *uart = _shark_uart + uart_no;
  329. shark_uart_tx_continue(uart, bytes, len);
  330. }
  331. void shark_uart_frame_end(uart_enum_t uart_no){
  332. shark_uart_tx_end(_shark_uart + uart_no);
  333. }
  334. void shark_uart_write_bytes(uart_enum_t uart_no, u8 *buff, u16 size){
  335. shark_uart_write(_shark_uart + uart_no, buff, size);
  336. }
  337. int fputc(int c, FILE *fp){
  338. shark_uart_write_byte(_shark_uart+SHARK_UART0, (u8)c);
  339. return 1;
  340. }