#include "hal/uart2.h" #include "libs/utils.h" #include "libs/task.h" #include "serial.h" static uart_t uart2; static u32 uart_poll_task(void); void serial_init(void){ circle_buffer_init(&uart2.c_tx_buff , uart2.tx_buf, sizeof(uart2.tx_buf)); circle_buffer_init(&uart2.c_rx_buff , uart2.rx_buf, sizeof(uart2.rx_buf)); UART2_Init(); task_start(uart_poll_task, 0); } void serial_write(u8 *data, int len){ circle_put_data(&uart2.c_tx_buff, data, len); UART2_EnableTx(); } __weak void protocol_recv_frame(u8 *data, u16 rx_len) {} static bool uart_on_rx_frame(uart_t *uart) { u16 crc0 = shark_decode_u16(uart->rx_frame + uart->rx_length); u16 crc1 = shark_crc16_check(uart->rx_frame, uart->rx_length); if (crc0 != crc1) { return false; } protocol_recv_frame((u8 *)uart->rx_frame, uart->rx_length); return true; } static void uart_rx_poll(uart_t *uart) { u8 data; while(1) { if (circle_get_one_data(&uart->c_rx_buff, &data) != 1) { break; } switch(data){ case CH_START: uart->rx_length = 0; uart->escape = false; break; case CH_END: if (uart->rx_length > 2 && uart->rx_length != 0xFFFF){ uart->rx_length -= 2; //skip crc uart_on_rx_frame(uart); } uart->rx_length = 0xFFFF; break; case CH_ESC: uart->escape = true; break; default: if (uart->escape) { uart->escape = false; switch (data) { case CH_ESC_START: data = CH_START; break; case CH_ESC_END: data = CH_END; break; case CH_ESC_ESC: data = CH_ESC; break; default: data = 0xFF; } } if (uart->rx_length < sizeof(uart->rx_frame)) { uart->rx_frame[uart->rx_length] = data; uart->rx_length++; } else { uart->rx_length = 0xFFFF; } } } } static u32 uart_poll_task(void){ uart_rx_poll(&uart2); return 0; } static void uart_write_byte(uart_t *uart, u8 value) { circle_put_data(&uart->c_tx_buff, &value, 1); } static void uart_write_byte_esc(uart_t *uart, u8 value) { switch (value) { case CH_START: uart_write_byte(uart, CH_ESC); value = CH_ESC_START; break; case CH_END: uart_write_byte(uart, CH_ESC); value = CH_ESC_END; break; case CH_ESC: uart_write_byte(uart, CH_ESC); value = CH_ESC_ESC; break; } uart_write_byte(uart, value); } static void uart_write_esc(uart_t *uart, const u8 *buff, u16 length) { const u8 *buff_end; for (buff_end = buff + length; buff < buff_end; buff++) { uart_write_byte_esc(uart, *buff); } } static void uart_tx_start(uart_t *uart) { uart_write_byte(uart, CH_START); uart->tx_crc16 = 0; } static void uart_tx_continue(uart_t *uart, const void *buff, u16 length) { uart_write_esc(uart, (const u8 *) buff, length); uart->tx_crc16 = shark_crc16_update(uart->tx_crc16, (const u8 *) buff, length); } static void uart_tx_end(uart_t *uart) { uart_write_esc(uart, (u8 *)&uart->tx_crc16, sizeof(uart->tx_crc16)); uart_write_byte(uart, CH_END); UART2_EnableTx(); } void uart_write_frame(uint8_t *bytes, int len){ uart_t *uart = &uart2; uart_tx_start(uart); uart_tx_continue(uart, bytes, len); uart_tx_end(uart); } bool uart_tx_finished(void) { u8 data; if (circle_get_one_data(&uart2.c_tx_buff, &data) <= 0){ return true; } UART2_TxData(data); return false; } void uart_rx_put(u8 ch) { circle_put_one_data(&uart2.c_rx_buff, ch); } int fputc(int c, FILE *fp){ u8 data = c; serial_write(&data, 1); return 1; }