|
|
@@ -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);
|
|
|
+}
|
|
|
+
|