Просмотр исходного кода

dos to unix format

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 5 лет назад
Родитель
Сommit
3a783ada34
1 измененных файлов с 478 добавлено и 478 удалено
  1. 478 478
      Application/bsp/uart.c

+ 478 - 478
Application/bsp/uart.c

@@ -1,478 +1,478 @@
-#include "uart.h"
-#include "bsp/shark_bsp.h"
-#include "bsp/gpio.h"
-#include "libs/shark_libs.h"
-
-#define SHARK_UART_BAUDRATE				38400
-
-#define SHARK_UART0_com					USART0
-#define SHARK_UART0_tx_port				GPIOB
-#define SHARK_UART0_tx_pin				GPIO_PIN_6
-#define SHARK_UART0_rx_port				GPIOB
-#define SHARK_UART0_rx_pin				GPIO_PIN_7
-#define SHARK_UART0_irq					USART0_IRQn
-#define SHARK_UART0_clk					RCU_USART0
-#define SHARK_UART0_tx_gpio_clk			RCU_GPIOB
-#define SHARK_UART0_rx_gpio_clk			RCU_GPIOB
-#define SHARK_UART0_tx_dma				DMA
-#define SHARK_UART0_tx_dma_ch			DMA_CH1
-#define SHARK_UART0_tx_dma_clk			RCU_DMA
-#define SHARK_UART0_rx_dma				DMA
-#define SHARK_UART0_rx_dma_ch			DMA_CH2
-#define SHARK_UART0_rx_dma_clk			RCU_DMA
-
-#define SHARK_UART1_com					USART1
-#define SHARK_UART1_tx_port				GPIOA
-#define SHARK_UART1_tx_pin				GPIO_PIN_2
-#define SHARK_UART1_rx_port				GPIOA
-#define SHARK_UART1_rx_pin				GPIO_PIN_3
-#define SHARK_UART1_irq					USART1_IRQn
-#define SHARK_UART1_clk					RCU_USART1
-#define SHARK_UART1_tx_gpio_clk			RCU_GPIOA
-#define SHARK_UART1_rx_gpio_clk			RCU_GPIOA
-#define SHARK_UART1_tx_dma				DMA
-#define SHARK_UART1_tx_dma_ch			DMA_CH3
-#define SHARK_UART1_tx_dma_clk			RCU_DMA
-#define SHARK_UART1_rx_dma				DMA
-#define SHARK_UART1_rx_dma_ch			DMA_CH4
-#define SHARK_UART1_rx_dma_clk			RCU_DMA
-
-// ================================================================================
-
-static u8 shark_uart0_tx_cache[SHARK_UART_TX_MEM_SIZE];
-#if UART_NUM==2
-static u8 shark_uart1_tx_cache[SHARK_UART_TX_MEM_SIZE];
-#endif
-static u8 shark_uart_rx_cache[SHARK_UART_RX_MEM_SIZE];
-static shark_uart_t _shark_uart[UART_NUM];
-static shark_task_t _uart_task;
-static u64 _rx_time;
-///static bool uart_no_data = false;
-#define update_dma_w_pos(uart) circle_update_write_position(&uart->rx_queue, SHARK_UART_RX_MEM_SIZE - DMA_CHCNT(uart->rx_dma_ch))
-extern void protocol_recv_frame(uart_enum_t uart_no, char *data, int len);
-extern void protocol_old_recv_frame(uart_enum_t uart_no, uint8_t *data, int len);
-// ================================================================================
-static uart_enum_t _uart_index(uint32_t com){
-	return com == SHARK_UART0_com?SHARK_UART0:SHARK_UART1;
-}
-static bool shark_uart_on_rx_frame(shark_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(_uart_index(uart->uart_com), (char *)uart->rx_frame, uart->rx_length);
-	return true;
-}
-
-static void shark_uart_rx(shark_uart_t *uart){
-	while(1) {
-		u8 data;
-		update_dma_w_pos(uart);
-		if (circle_get_one_data(&uart->rx_queue, &data) != 1) {
-			if (shark_get_mseconds() >= (30 + _rx_time)) {
-				//_rx_time = 0xFFFFFFFFFFFFL;
-				if (uart->rx_length_old_prot > 0){
-					protocol_old_recv_frame(_uart_index(uart->uart_com), uart->rx_frame_old_prot, uart->rx_length_old_prot);
-					uart->rx_length_old_prot = 0;
-				}
-			}
-			
-			if (shark_get_mseconds() >= (UART_TIMEOUT + _rx_time)){
-				uart->uart_no_data = true;
-
-			}else {
-				uart->uart_no_data = false;
-			}
-			break;
-		}
-		_rx_time = shark_get_mseconds();
-		uart->rx_frame_old_prot[uart->rx_length_old_prot ++] = data;
-		if (uart->rx_length_old_prot == sizeof(uart->rx_frame_old_prot)){
-			uart->rx_length_old_prot = 0;
-		}
-		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
-					shark_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 void shark_uart_dma_tx(shark_uart_t *uart)
-{
-	u32 value = DMA_CHCTL(uart->tx_dma_ch);
-
-	if (value & DMA_CHXCTL_CHEN) {
-		if (SET != dma_flag_get(uart->tx_dma_ch, DMA_FLAG_FTF)) {
-			return;
-		}
-
-		byte_queue_skip(&uart->tx_queue, uart->tx_length);
-		DMA_CHCTL(uart->tx_dma_ch) = value & (~DMA_CHXCTL_CHEN);
-	}
-
-	uart->tx_length = byte_queue_peek(&uart->tx_queue);
-	if (uart->tx_length > 0) {
-		DMA_CHCNT(uart->tx_dma_ch) = uart->tx_length;
-		DMA_CHMADDR(uart->tx_dma_ch) = (u32) byte_queue_head(&uart->tx_queue);
-
-		dma_flag_clear(uart->tx_dma_ch, DMA_FLAG_FTF);
-		DMA_CHCTL(uart->tx_dma_ch) = value | DMA_CHXCTL_CHEN;
-	}
-}
-
-
-
-static void shark_uart_write(shark_uart_t *uart, const u8 *buff, u16 size)
-{
-	while (size > 0) {
-		u16 length = byte_queue_write(&uart->tx_queue, buff, size);
-
-		if (length == size) {
-			shark_uart_dma_tx(uart);
-			break;
-		}
-
-		shark_uart_dma_tx(uart);
-		buff += length;
-		size -= length;
-	}
-}
-
-static void shark_uart_write_byte(shark_uart_t *uart, u8 value)
-{
-	shark_uart_write(uart, &value, 1);
-}
-
-
-static void shark_uart_tx_dma_init(shark_uart_t *uart){
-	dma_parameter_struct dma_init_struct;
-	rcu_periph_clock_enable(_uart_index(uart->uart_com)== SHARK_UART0?SHARK_UART0_tx_dma_clk:SHARK_UART1_tx_dma_clk);
-	dma_deinit(uart->tx_dma_ch);
-	dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
-	dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
-	dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
-	dma_init_struct.periph_addr = (u32) &USART_TDATA(uart->uart_com);
-	dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
-	dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
-	dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
-	dma_init(uart->tx_dma_ch, &dma_init_struct);
-	dma_circulation_disable(uart->tx_dma_ch);
-	dma_memory_to_memory_disable(uart->tx_dma_ch);
-	usart_dma_transmit_config(uart->uart_com, USART_DENT_ENABLE);
-#if 0
-	if (uart->tx_dma_ch == DMA_CH1) {
-		nvic_irq_enable(DMA_Channel1_2_IRQn ,4, 0);
-	}else {
-		nvic_irq_enable(DMA_Channel3_4_IRQn ,4, 0);
-	}
-	dma_interrupt_enable(uart->tx_dma_ch, DMA_INT_FTF);
-#endif
-}
-
-
-static void shark_uart_rx_dma_init(shark_uart_t *uart){
-	dma_parameter_struct dma_init_struct;
-	rcu_periph_clock_enable(_uart_index(uart->uart_com)== SHARK_UART0?SHARK_UART0_rx_dma_clk:SHARK_UART1_rx_dma_clk);
-	dma_deinit(uart->rx_dma_ch);
-	dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
-	dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
-	dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
-	dma_init_struct.memory_addr = (u32)uart->rx_queue.buffer;
-	dma_init_struct.number = uart->rx_queue.buffer_len;
-	dma_init_struct.periph_addr = (u32) &USART_RDATA(uart->uart_com);
-	dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
-	dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
-	dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
-	dma_init(uart->rx_dma_ch, &dma_init_struct);
-	dma_circulation_enable(uart->rx_dma_ch);
-	dma_memory_to_memory_disable(uart->rx_dma_ch);
-	dma_channel_enable(uart->rx_dma_ch);
-	usart_dma_receive_config(uart->uart_com, USART_DENR_ENABLE);
-}
-
-static void shark_uart_pin_init(shark_uart_t *uart){
-	if (_uart_index(uart->uart_com) == SHARK_UART0) {
-		rcu_periph_clock_enable(SHARK_UART0_clk);
-		rcu_periph_clock_enable(SHARK_UART0_rx_gpio_clk);
-		rcu_periph_clock_enable(SHARK_UART0_tx_gpio_clk);
-		gpio_af_set(SHARK_UART0_tx_port, GPIO_AF_0,SHARK_UART0_tx_pin);
-		gpio_mode_set(SHARK_UART0_tx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, SHARK_UART0_tx_pin);
-		gpio_output_options_set(SHARK_UART0_tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SHARK_UART0_tx_pin);
-		gpio_af_set(SHARK_UART0_rx_port, GPIO_AF_0,SHARK_UART0_rx_pin);
-		gpio_mode_set(SHARK_UART0_rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, SHARK_UART0_rx_pin);
-		gpio_output_options_set(SHARK_UART0_rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,SHARK_UART0_rx_pin);
-	}else {
-		rcu_periph_clock_enable(SHARK_UART1_clk);
-		rcu_periph_clock_enable(SHARK_UART1_rx_gpio_clk);
-		rcu_periph_clock_enable(SHARK_UART1_tx_gpio_clk);
-		gpio_af_set(SHARK_UART1_tx_port, GPIO_AF_1,SHARK_UART1_tx_pin);
-		gpio_mode_set(SHARK_UART1_tx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, SHARK_UART1_tx_pin);
-		gpio_output_options_set(SHARK_UART1_tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SHARK_UART1_tx_pin);
-		gpio_af_set(SHARK_UART1_rx_port, GPIO_AF_1,SHARK_UART1_rx_pin);
-		gpio_mode_set(SHARK_UART1_rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, SHARK_UART1_rx_pin);
-		gpio_output_options_set(SHARK_UART1_rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,SHARK_UART1_rx_pin);
-	}
-}
-
-static void shark_uart_pin_deinit(shark_uart_t *uart){
-	if (_uart_index(uart->uart_com) == SHARK_UART0) {
-		gpio_mode_set(SHARK_UART0_tx_port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SHARK_UART0_tx_pin);
-		gpio_bit_set(SHARK_UART0_tx_port, SHARK_UART0_tx_pin);
-		gpio_mode_set(SHARK_UART0_rx_port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SHARK_UART0_rx_pin);
-	}else {
-		gpio_mode_set(SHARK_UART1_tx_port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SHARK_UART1_tx_pin);
-		gpio_bit_set(SHARK_UART1_tx_port, SHARK_UART1_tx_pin);
-		gpio_mode_set(SHARK_UART1_rx_port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SHARK_UART1_rx_pin);
-	}
-}
-
-
-static void shark_uart_device_init(shark_uart_t *uart){
-	usart_deinit(uart->uart_com);
-	usart_baudrate_set(uart->uart_com, SHARK_UART_BAUDRATE);
-
-	usart_word_length_set(uart->uart_com, USART_WL_8BIT);
-	usart_stop_bit_set(uart->uart_com, USART_STB_1BIT);
-	usart_parity_config(uart->uart_com, USART_PM_NONE);
-	usart_hardware_flow_rts_config(uart->uart_com, USART_RTS_DISABLE);
-	usart_hardware_flow_cts_config(uart->uart_com, USART_CTS_DISABLE);
-	usart_receive_config(uart->uart_com, USART_RECEIVE_ENABLE);
-	usart_transmit_config(uart->uart_com, USART_TRANSMIT_ENABLE);
-	
-}
-
-static u32 shark_uart_handler(void)
-{
-	shark_uart_t *uart = _shark_uart + SHARK_UART0;
-	if (uart->uart_com != 0) {
-		shark_uart_rx(uart);
-		shark_uart_dma_tx(uart);
-	}
-#if UART_NUM==2	
-	uart = _shark_uart + SHARK_UART1;
-	if (uart->uart_com != 0) {
-		shark_uart_rx(uart);
-		shark_uart_dma_tx(uart);
-	}
-#endif	
-	return 0;
-}
-
-void shark_uart_flush(void){
-	shark_uart_t *uart = _shark_uart + SHARK_UART0;
-	if (uart->uart_com != 0) {
-		shark_uart_dma_tx(uart);
-	}
-#if UART_NUM==2	
-	uart = _shark_uart + SHARK_UART1;
-	if (uart->uart_com != 0) {
-		shark_uart_dma_tx(uart);
-	}
-#endif	
-}
-
-
-#if 0
-void DMA_Channel1_2_IRQHandler(void){
-	shark_uart_t *uart = _shark_uart + SHARK_UART0;
-	if (dma_interrupt_flag_get(uart->tx_dma_ch, DMA_INT_FLAG_FTF) != RESET){
-		shark_uart_dma_tx(uart);
-		dma_interrupt_flag_clear(uart->tx_dma_ch, DMA_INT_FLAG_FTF);
-	}
-}
-
-void DMA_Channel3_4_IRQHandler(void){
-	shark_uart_t *uart = _shark_uart + SHARK_UART1;
-	if (dma_interrupt_flag_get(uart->tx_dma_ch, DMA_INT_FLAG_FTF) != RESET){
-		shark_uart_dma_tx(uart);
-		dma_interrupt_flag_clear(uart->tx_dma_ch, DMA_INT_FLAG_FTF);
-	}
-}
-#endif
-
-static u8 *tx_cache_addr(uart_enum_t uart_no){
-#if UART_NUM==2
-	return (uart_no == SHARK_UART0)?shark_uart0_tx_cache:shark_uart1_tx_cache;
-#else
-	return shark_uart0_tx_cache;
-#endif
-}
-
-void shark_uart_deinit(uart_enum_t uart_no){
-	shark_uart_t *uart = _shark_uart + uart_no;
-	if (uart->uart_com != 0) {
-		usart_disable(uart->uart_com);
-		usart_deinit(uart->uart_com);
-		rcu_periph_clock_disable(uart_no == SHARK_UART0?SHARK_UART0_clk:SHARK_UART1_clk);
-		dma_channel_disable(uart->rx_dma_ch);
-		dma_channel_disable(uart->tx_dma_ch);
-		rcu_periph_clock_disable(uart_no == SHARK_UART0?SHARK_UART0_tx_dma_clk:SHARK_UART1_tx_dma_clk);
-		rcu_periph_clock_disable(uart_no == SHARK_UART0?SHARK_UART0_rx_dma_clk:SHARK_UART1_rx_dma_clk);
-		shark_uart_pin_deinit(uart);
-	}
-	if (uart_no == SHARK_UART0) {
-		UART0_IR_EN(0);
-	}else {
-		UART1_IR_EN(0);
-	}
-}
-
-
-bool shark_uart_timeout(void){
-#if UART_NUM==2	
-	return (_shark_uart[0].uart_no_data && _shark_uart[1].uart_no_data)?TRUE:FALSE;
-#else
-	return (_shark_uart[0].uart_no_data)?TRUE:FALSE;
-#endif
-}
-void shark_uart_init(uart_enum_t uart_no)
-{
-	shark_uart_t *uart = _shark_uart + uart_no;
-	uart->escape = false;
-	uart->rx_length = 0;
-	uart->tx_length = 0;
-	uart->uart_com = (uart_no == SHARK_UART0)?SHARK_UART0_com:SHARK_UART1_com;
-
-	circle_buffer_init(&uart->rx_queue, shark_uart_rx_cache, SHARK_UART_TX_MEM_SIZE);
-	byte_queue_init(&uart->tx_queue,tx_cache_addr(uart_no), SHARK_UART_TX_MEM_SIZE);
-
-	uart->rx_dma_ch = (uart_no == SHARK_UART0)?SHARK_UART0_rx_dma_ch:SHARK_UART1_rx_dma_ch;
-	uart->tx_dma_ch = (uart_no == SHARK_UART0)?SHARK_UART0_tx_dma_ch:SHARK_UART1_tx_dma_ch;
-
-	shark_uart_pin_init(uart);
-	shark_uart_device_init(uart);
-	shark_uart_rx_dma_init(uart);
-	shark_uart_tx_dma_init(uart);
-	usart_enable(uart->uart_com);
-	
-	if (_uart_task.handler == NULL) {
-		_uart_task.handler = shark_uart_handler;
-		shark_task_add(&_uart_task);
-	}
-	if (uart_no == SHARK_UART0) {
-		UART0_IR_EN(1);
-	}else {
-		UART1_IR_EN(1);
-	}
-	_rx_time = shark_get_mseconds();
-	uart->uart_no_data = false;
-}
-
-static void shark_uart_write_byte_esc(shark_uart_t *uart, u8 value)
-{
-	switch (value) {
-	case CH_START:
-		shark_uart_write_byte(uart, CH_ESC);
-		value = CH_ESC_START;
-		break;
-
-	case CH_END:
-		shark_uart_write_byte(uart, CH_ESC);
-		value = CH_ESC_END;
-		break;
-
-	case CH_ESC:
-		shark_uart_write_byte(uart, CH_ESC);
-		value = CH_ESC_ESC;
-		break;
-	}
-
-	shark_uart_write_byte(uart, value);
-}
-
-static void shark_uart_write_esc(shark_uart_t *uart, const u8 *buff, u16 length)
-{
-	const u8 *buff_end;
-
-	for (buff_end = buff + length; buff < buff_end; buff++) {
-		shark_uart_write_byte_esc(uart, *buff);
-	}
-}
-
-static void shark_uart_tx_start(shark_uart_t *uart)
-{
-	shark_uart_write_byte(uart, CH_START);
-	uart->tx_crc16 = 0;
-}
-
-static void shark_uart_tx_continue(shark_uart_t *uart, const void *buff, u16 length)
-{
-	shark_uart_write_esc(uart, (const u8 *) buff, length);
-	uart->tx_crc16 = shark_crc16_update(uart->tx_crc16, (const u8 *) buff, length);
-}
-
-static void shark_uart_tx_end(shark_uart_t *uart)
-{
-	shark_uart_write_esc(uart, (u8 *)&uart->tx_crc16, sizeof(uart->tx_crc16));
-	shark_uart_write_byte(uart, CH_END);
-}
-
-void shark_uart_write_frame(uart_enum_t uart_no, uint8_t *bytes, int len){
-	shark_uart_t *uart = _shark_uart + uart_no;
-	shark_uart_tx_start(uart);
-	shark_uart_tx_continue(uart, bytes, len);
-	shark_uart_tx_end(uart);
-}
-
-void shark_uart_frame_start(uart_enum_t uart_no, uint8_t *bytes, int len){
-	shark_uart_t *uart = _shark_uart + uart_no;
-	shark_uart_tx_start(uart);
-	shark_uart_tx_continue(uart, bytes, len);
-}
-
-void shark_uart_frame_continue(uart_enum_t uart_no, uint8_t *bytes, int len){
-	shark_uart_t *uart = _shark_uart + uart_no;
-	shark_uart_tx_continue(uart, bytes, len);
-}
-
-void shark_uart_frame_end(uart_enum_t uart_no){
-	shark_uart_tx_end(_shark_uart + uart_no);
-}
-
-void shark_uart_write_bytes(uart_enum_t uart_no, u8 *buff, u16 size){
-	shark_uart_write(_shark_uart + uart_no, buff, size);
-}
-
+#include "uart.h"
+#include "bsp/shark_bsp.h"
+#include "bsp/gpio.h"
+#include "libs/shark_libs.h"
+
+#define SHARK_UART_BAUDRATE				38400
+
+#define SHARK_UART0_com					USART0
+#define SHARK_UART0_tx_port				GPIOB
+#define SHARK_UART0_tx_pin				GPIO_PIN_6
+#define SHARK_UART0_rx_port				GPIOB
+#define SHARK_UART0_rx_pin				GPIO_PIN_7
+#define SHARK_UART0_irq					USART0_IRQn
+#define SHARK_UART0_clk					RCU_USART0
+#define SHARK_UART0_tx_gpio_clk			RCU_GPIOB
+#define SHARK_UART0_rx_gpio_clk			RCU_GPIOB
+#define SHARK_UART0_tx_dma				DMA
+#define SHARK_UART0_tx_dma_ch			DMA_CH1
+#define SHARK_UART0_tx_dma_clk			RCU_DMA
+#define SHARK_UART0_rx_dma				DMA
+#define SHARK_UART0_rx_dma_ch			DMA_CH2
+#define SHARK_UART0_rx_dma_clk			RCU_DMA
+
+#define SHARK_UART1_com					USART1
+#define SHARK_UART1_tx_port				GPIOA
+#define SHARK_UART1_tx_pin				GPIO_PIN_2
+#define SHARK_UART1_rx_port				GPIOA
+#define SHARK_UART1_rx_pin				GPIO_PIN_3
+#define SHARK_UART1_irq					USART1_IRQn
+#define SHARK_UART1_clk					RCU_USART1
+#define SHARK_UART1_tx_gpio_clk			RCU_GPIOA
+#define SHARK_UART1_rx_gpio_clk			RCU_GPIOA
+#define SHARK_UART1_tx_dma				DMA
+#define SHARK_UART1_tx_dma_ch			DMA_CH3
+#define SHARK_UART1_tx_dma_clk			RCU_DMA
+#define SHARK_UART1_rx_dma				DMA
+#define SHARK_UART1_rx_dma_ch			DMA_CH4
+#define SHARK_UART1_rx_dma_clk			RCU_DMA
+
+// ================================================================================
+
+static u8 shark_uart0_tx_cache[SHARK_UART_TX_MEM_SIZE];
+#if UART_NUM==2
+static u8 shark_uart1_tx_cache[SHARK_UART_TX_MEM_SIZE];
+#endif
+static u8 shark_uart_rx_cache[SHARK_UART_RX_MEM_SIZE];
+static shark_uart_t _shark_uart[UART_NUM];
+static shark_task_t _uart_task;
+static u64 _rx_time;
+///static bool uart_no_data = false;
+#define update_dma_w_pos(uart) circle_update_write_position(&uart->rx_queue, SHARK_UART_RX_MEM_SIZE - DMA_CHCNT(uart->rx_dma_ch))
+extern void protocol_recv_frame(uart_enum_t uart_no, char *data, int len);
+extern void protocol_old_recv_frame(uart_enum_t uart_no, uint8_t *data, int len);
+// ================================================================================
+static uart_enum_t _uart_index(uint32_t com){
+	return com == SHARK_UART0_com?SHARK_UART0:SHARK_UART1;
+}
+static bool shark_uart_on_rx_frame(shark_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(_uart_index(uart->uart_com), (char *)uart->rx_frame, uart->rx_length);
+	return true;
+}
+
+static void shark_uart_rx(shark_uart_t *uart){
+	while(1) {
+		u8 data;
+		update_dma_w_pos(uart);
+		if (circle_get_one_data(&uart->rx_queue, &data) != 1) {
+			if (shark_get_mseconds() >= (30 + _rx_time)) {
+				//_rx_time = 0xFFFFFFFFFFFFL;
+				if (uart->rx_length_old_prot > 0){
+					protocol_old_recv_frame(_uart_index(uart->uart_com), uart->rx_frame_old_prot, uart->rx_length_old_prot);
+					uart->rx_length_old_prot = 0;
+				}
+			}
+			
+			if (shark_get_mseconds() >= (UART_TIMEOUT + _rx_time)){
+				uart->uart_no_data = true;
+
+			}else {
+				uart->uart_no_data = false;
+			}
+			break;
+		}
+		_rx_time = shark_get_mseconds();
+		uart->rx_frame_old_prot[uart->rx_length_old_prot ++] = data;
+		if (uart->rx_length_old_prot == sizeof(uart->rx_frame_old_prot)){
+			uart->rx_length_old_prot = 0;
+		}
+		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
+					shark_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 void shark_uart_dma_tx(shark_uart_t *uart)
+{
+	u32 value = DMA_CHCTL(uart->tx_dma_ch);
+
+	if (value & DMA_CHXCTL_CHEN) {
+		if (SET != dma_flag_get(uart->tx_dma_ch, DMA_FLAG_FTF)) {
+			return;
+		}
+
+		byte_queue_skip(&uart->tx_queue, uart->tx_length);
+		DMA_CHCTL(uart->tx_dma_ch) = value & (~DMA_CHXCTL_CHEN);
+	}
+
+	uart->tx_length = byte_queue_peek(&uart->tx_queue);
+	if (uart->tx_length > 0) {
+		DMA_CHCNT(uart->tx_dma_ch) = uart->tx_length;
+		DMA_CHMADDR(uart->tx_dma_ch) = (u32) byte_queue_head(&uart->tx_queue);
+
+		dma_flag_clear(uart->tx_dma_ch, DMA_FLAG_FTF);
+		DMA_CHCTL(uart->tx_dma_ch) = value | DMA_CHXCTL_CHEN;
+	}
+}
+
+
+
+static void shark_uart_write(shark_uart_t *uart, const u8 *buff, u16 size)
+{
+	while (size > 0) {
+		u16 length = byte_queue_write(&uart->tx_queue, buff, size);
+
+		if (length == size) {
+			shark_uart_dma_tx(uart);
+			break;
+		}
+
+		shark_uart_dma_tx(uart);
+		buff += length;
+		size -= length;
+	}
+}
+
+static void shark_uart_write_byte(shark_uart_t *uart, u8 value)
+{
+	shark_uart_write(uart, &value, 1);
+}
+
+
+static void shark_uart_tx_dma_init(shark_uart_t *uart){
+	dma_parameter_struct dma_init_struct;
+	rcu_periph_clock_enable(_uart_index(uart->uart_com)== SHARK_UART0?SHARK_UART0_tx_dma_clk:SHARK_UART1_tx_dma_clk);
+	dma_deinit(uart->tx_dma_ch);
+	dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
+	dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
+	dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
+	dma_init_struct.periph_addr = (u32) &USART_TDATA(uart->uart_com);
+	dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
+	dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
+	dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
+	dma_init(uart->tx_dma_ch, &dma_init_struct);
+	dma_circulation_disable(uart->tx_dma_ch);
+	dma_memory_to_memory_disable(uart->tx_dma_ch);
+	usart_dma_transmit_config(uart->uart_com, USART_DENT_ENABLE);
+#if 0
+	if (uart->tx_dma_ch == DMA_CH1) {
+		nvic_irq_enable(DMA_Channel1_2_IRQn ,4, 0);
+	}else {
+		nvic_irq_enable(DMA_Channel3_4_IRQn ,4, 0);
+	}
+	dma_interrupt_enable(uart->tx_dma_ch, DMA_INT_FTF);
+#endif
+}
+
+
+static void shark_uart_rx_dma_init(shark_uart_t *uart){
+	dma_parameter_struct dma_init_struct;
+	rcu_periph_clock_enable(_uart_index(uart->uart_com)== SHARK_UART0?SHARK_UART0_rx_dma_clk:SHARK_UART1_rx_dma_clk);
+	dma_deinit(uart->rx_dma_ch);
+	dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
+	dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
+	dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
+	dma_init_struct.memory_addr = (u32)uart->rx_queue.buffer;
+	dma_init_struct.number = uart->rx_queue.buffer_len;
+	dma_init_struct.periph_addr = (u32) &USART_RDATA(uart->uart_com);
+	dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
+	dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
+	dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
+	dma_init(uart->rx_dma_ch, &dma_init_struct);
+	dma_circulation_enable(uart->rx_dma_ch);
+	dma_memory_to_memory_disable(uart->rx_dma_ch);
+	dma_channel_enable(uart->rx_dma_ch);
+	usart_dma_receive_config(uart->uart_com, USART_DENR_ENABLE);
+}
+
+static void shark_uart_pin_init(shark_uart_t *uart){
+	if (_uart_index(uart->uart_com) == SHARK_UART0) {
+		rcu_periph_clock_enable(SHARK_UART0_clk);
+		rcu_periph_clock_enable(SHARK_UART0_rx_gpio_clk);
+		rcu_periph_clock_enable(SHARK_UART0_tx_gpio_clk);
+		gpio_af_set(SHARK_UART0_tx_port, GPIO_AF_0,SHARK_UART0_tx_pin);
+		gpio_mode_set(SHARK_UART0_tx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, SHARK_UART0_tx_pin);
+		gpio_output_options_set(SHARK_UART0_tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SHARK_UART0_tx_pin);
+		gpio_af_set(SHARK_UART0_rx_port, GPIO_AF_0,SHARK_UART0_rx_pin);
+		gpio_mode_set(SHARK_UART0_rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, SHARK_UART0_rx_pin);
+		gpio_output_options_set(SHARK_UART0_rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,SHARK_UART0_rx_pin);
+	}else {
+		rcu_periph_clock_enable(SHARK_UART1_clk);
+		rcu_periph_clock_enable(SHARK_UART1_rx_gpio_clk);
+		rcu_periph_clock_enable(SHARK_UART1_tx_gpio_clk);
+		gpio_af_set(SHARK_UART1_tx_port, GPIO_AF_1,SHARK_UART1_tx_pin);
+		gpio_mode_set(SHARK_UART1_tx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, SHARK_UART1_tx_pin);
+		gpio_output_options_set(SHARK_UART1_tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SHARK_UART1_tx_pin);
+		gpio_af_set(SHARK_UART1_rx_port, GPIO_AF_1,SHARK_UART1_rx_pin);
+		gpio_mode_set(SHARK_UART1_rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, SHARK_UART1_rx_pin);
+		gpio_output_options_set(SHARK_UART1_rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,SHARK_UART1_rx_pin);
+	}
+}
+
+static void shark_uart_pin_deinit(shark_uart_t *uart){
+	if (_uart_index(uart->uart_com) == SHARK_UART0) {
+		gpio_mode_set(SHARK_UART0_tx_port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SHARK_UART0_tx_pin);
+		gpio_bit_set(SHARK_UART0_tx_port, SHARK_UART0_tx_pin);
+		gpio_mode_set(SHARK_UART0_rx_port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SHARK_UART0_rx_pin);
+	}else {
+		gpio_mode_set(SHARK_UART1_tx_port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SHARK_UART1_tx_pin);
+		gpio_bit_set(SHARK_UART1_tx_port, SHARK_UART1_tx_pin);
+		gpio_mode_set(SHARK_UART1_rx_port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SHARK_UART1_rx_pin);
+	}
+}
+
+
+static void shark_uart_device_init(shark_uart_t *uart){
+	usart_deinit(uart->uart_com);
+	usart_baudrate_set(uart->uart_com, SHARK_UART_BAUDRATE);
+
+	usart_word_length_set(uart->uart_com, USART_WL_8BIT);
+	usart_stop_bit_set(uart->uart_com, USART_STB_1BIT);
+	usart_parity_config(uart->uart_com, USART_PM_NONE);
+	usart_hardware_flow_rts_config(uart->uart_com, USART_RTS_DISABLE);
+	usart_hardware_flow_cts_config(uart->uart_com, USART_CTS_DISABLE);
+	usart_receive_config(uart->uart_com, USART_RECEIVE_ENABLE);
+	usart_transmit_config(uart->uart_com, USART_TRANSMIT_ENABLE);
+	
+}
+
+static u32 shark_uart_handler(void)
+{
+	shark_uart_t *uart = _shark_uart + SHARK_UART0;
+	if (uart->uart_com != 0) {
+		shark_uart_rx(uart);
+		shark_uart_dma_tx(uart);
+	}
+#if UART_NUM==2	
+	uart = _shark_uart + SHARK_UART1;
+	if (uart->uart_com != 0) {
+		shark_uart_rx(uart);
+		shark_uart_dma_tx(uart);
+	}
+#endif	
+	return 0;
+}
+
+void shark_uart_flush(void){
+	shark_uart_t *uart = _shark_uart + SHARK_UART0;
+	if (uart->uart_com != 0) {
+		shark_uart_dma_tx(uart);
+	}
+#if UART_NUM==2	
+	uart = _shark_uart + SHARK_UART1;
+	if (uart->uart_com != 0) {
+		shark_uart_dma_tx(uart);
+	}
+#endif	
+}
+
+
+#if 0
+void DMA_Channel1_2_IRQHandler(void){
+	shark_uart_t *uart = _shark_uart + SHARK_UART0;
+	if (dma_interrupt_flag_get(uart->tx_dma_ch, DMA_INT_FLAG_FTF) != RESET){
+		shark_uart_dma_tx(uart);
+		dma_interrupt_flag_clear(uart->tx_dma_ch, DMA_INT_FLAG_FTF);
+	}
+}
+
+void DMA_Channel3_4_IRQHandler(void){
+	shark_uart_t *uart = _shark_uart + SHARK_UART1;
+	if (dma_interrupt_flag_get(uart->tx_dma_ch, DMA_INT_FLAG_FTF) != RESET){
+		shark_uart_dma_tx(uart);
+		dma_interrupt_flag_clear(uart->tx_dma_ch, DMA_INT_FLAG_FTF);
+	}
+}
+#endif
+
+static u8 *tx_cache_addr(uart_enum_t uart_no){
+#if UART_NUM==2
+	return (uart_no == SHARK_UART0)?shark_uart0_tx_cache:shark_uart1_tx_cache;
+#else
+	return shark_uart0_tx_cache;
+#endif
+}
+
+void shark_uart_deinit(uart_enum_t uart_no){
+	shark_uart_t *uart = _shark_uart + uart_no;
+	if (uart->uart_com != 0) {
+		usart_disable(uart->uart_com);
+		usart_deinit(uart->uart_com);
+		rcu_periph_clock_disable(uart_no == SHARK_UART0?SHARK_UART0_clk:SHARK_UART1_clk);
+		dma_channel_disable(uart->rx_dma_ch);
+		dma_channel_disable(uart->tx_dma_ch);
+		rcu_periph_clock_disable(uart_no == SHARK_UART0?SHARK_UART0_tx_dma_clk:SHARK_UART1_tx_dma_clk);
+		rcu_periph_clock_disable(uart_no == SHARK_UART0?SHARK_UART0_rx_dma_clk:SHARK_UART1_rx_dma_clk);
+		shark_uart_pin_deinit(uart);
+	}
+	if (uart_no == SHARK_UART0) {
+		UART0_IR_EN(0);
+	}else {
+		UART1_IR_EN(0);
+	}
+}
+
+
+bool shark_uart_timeout(void){
+#if UART_NUM==2	
+	return (_shark_uart[0].uart_no_data && _shark_uart[1].uart_no_data)?TRUE:FALSE;
+#else
+	return (_shark_uart[0].uart_no_data)?TRUE:FALSE;
+#endif
+}
+void shark_uart_init(uart_enum_t uart_no)
+{
+	shark_uart_t *uart = _shark_uart + uart_no;
+	uart->escape = false;
+	uart->rx_length = 0;
+	uart->tx_length = 0;
+	uart->uart_com = (uart_no == SHARK_UART0)?SHARK_UART0_com:SHARK_UART1_com;
+
+	circle_buffer_init(&uart->rx_queue, shark_uart_rx_cache, SHARK_UART_TX_MEM_SIZE);
+	byte_queue_init(&uart->tx_queue,tx_cache_addr(uart_no), SHARK_UART_TX_MEM_SIZE);
+
+	uart->rx_dma_ch = (uart_no == SHARK_UART0)?SHARK_UART0_rx_dma_ch:SHARK_UART1_rx_dma_ch;
+	uart->tx_dma_ch = (uart_no == SHARK_UART0)?SHARK_UART0_tx_dma_ch:SHARK_UART1_tx_dma_ch;
+
+	shark_uart_pin_init(uart);
+	shark_uart_device_init(uart);
+	shark_uart_rx_dma_init(uart);
+	shark_uart_tx_dma_init(uart);
+	usart_enable(uart->uart_com);
+	
+	if (_uart_task.handler == NULL) {
+		_uart_task.handler = shark_uart_handler;
+		shark_task_add(&_uart_task);
+	}
+	if (uart_no == SHARK_UART0) {
+		UART0_IR_EN(1);
+	}else {
+		UART1_IR_EN(1);
+	}
+	_rx_time = shark_get_mseconds();
+	uart->uart_no_data = false;
+}
+
+static void shark_uart_write_byte_esc(shark_uart_t *uart, u8 value)
+{
+	switch (value) {
+	case CH_START:
+		shark_uart_write_byte(uart, CH_ESC);
+		value = CH_ESC_START;
+		break;
+
+	case CH_END:
+		shark_uart_write_byte(uart, CH_ESC);
+		value = CH_ESC_END;
+		break;
+
+	case CH_ESC:
+		shark_uart_write_byte(uart, CH_ESC);
+		value = CH_ESC_ESC;
+		break;
+	}
+
+	shark_uart_write_byte(uart, value);
+}
+
+static void shark_uart_write_esc(shark_uart_t *uart, const u8 *buff, u16 length)
+{
+	const u8 *buff_end;
+
+	for (buff_end = buff + length; buff < buff_end; buff++) {
+		shark_uart_write_byte_esc(uart, *buff);
+	}
+}
+
+static void shark_uart_tx_start(shark_uart_t *uart)
+{
+	shark_uart_write_byte(uart, CH_START);
+	uart->tx_crc16 = 0;
+}
+
+static void shark_uart_tx_continue(shark_uart_t *uart, const void *buff, u16 length)
+{
+	shark_uart_write_esc(uart, (const u8 *) buff, length);
+	uart->tx_crc16 = shark_crc16_update(uart->tx_crc16, (const u8 *) buff, length);
+}
+
+static void shark_uart_tx_end(shark_uart_t *uart)
+{
+	shark_uart_write_esc(uart, (u8 *)&uart->tx_crc16, sizeof(uart->tx_crc16));
+	shark_uart_write_byte(uart, CH_END);
+}
+
+void shark_uart_write_frame(uart_enum_t uart_no, uint8_t *bytes, int len){
+	shark_uart_t *uart = _shark_uart + uart_no;
+	shark_uart_tx_start(uart);
+	shark_uart_tx_continue(uart, bytes, len);
+	shark_uart_tx_end(uart);
+}
+
+void shark_uart_frame_start(uart_enum_t uart_no, uint8_t *bytes, int len){
+	shark_uart_t *uart = _shark_uart + uart_no;
+	shark_uart_tx_start(uart);
+	shark_uart_tx_continue(uart, bytes, len);
+}
+
+void shark_uart_frame_continue(uart_enum_t uart_no, uint8_t *bytes, int len){
+	shark_uart_t *uart = _shark_uart + uart_no;
+	shark_uart_tx_continue(uart, bytes, len);
+}
+
+void shark_uart_frame_end(uart_enum_t uart_no){
+	shark_uart_tx_end(_shark_uart + uart_no);
+}
+
+void shark_uart_write_bytes(uart_enum_t uart_no, u8 *buff, u16 size){
+	shark_uart_write(_shark_uart + uart_no, buff, size);
+}
+