| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- #include "uart.h"
- #include "bsp/shark_bsp.h"
- #include "libs/shark_libs.h"
- #define SHARK_UART_BAUDRATE 38400
- #define SHARK_UART0_com USART0
- #define SHARK_UART0_tx_port GPIOA
- #define SHARK_UART0_tx_pin GPIO_PIN_9
- #define SHARK_UART0_rx_port GPIOA
- #define SHARK_UART0_rx_pin GPIO_PIN_10
- #define SHARK_UART0_irq USART0_IRQn
- #define SHARK_UART0_clk RCU_USART0
- #define SHARK_UART0_tx_gpio_clk RCU_GPIOA
- #define SHARK_UART0_rx_gpio_clk RCU_GPIOA
- #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
- #define SHARK_UART_com SHARK_UART0_com
- #define SHARK_UART_tx_port SHARK_UART0_tx_port
- #define SHARK_UART_tx_pin SHARK_UART0_tx_pin
- #define SHARK_UART_rx_port SHARK_UART0_rx_port
- #define SHARK_UART_rx_pin SHARK_UART0_rx_pin
- #define SHARK_UART_irq SHARK_UART0_irq
- #define SHARK_UART_clk SHARK_UART0_clk
- #define SHARK_UART_tx_gpio_clk SHARK_UART0_tx_gpio_clk
- #define SHARK_UART_rx_gpio_clk SHARK_UART0_rx_gpio_clk
- // #define SHARK_UART_tx_dma SHARK_UART0_tx_dma
- #define SHARK_UART_tx_dma_ch SHARK_UART0_tx_dma_ch
- #define SHARK_UART_tx_dma_clk SHARK_UART0_tx_dma_clk
- // #define SHARK_UART_rx_dma SHARK_UART0_rx_dma
- #define SHARK_UART_rx_dma_ch SHARK_UART0_rx_dma_ch
- #define SHARK_UART_rx_dma_clk SHARK_UART0_rx_dma_clk
- // ================================================================================
- #define SHARK_UART_CACHE_SIZE \
- (SHARK_UART_TX_MEM_SIZE + SHARK_UART_RX_MEM_SIZE)
- #define SHARK_UART_DMA_ADDR(index) \
- (SHARK_UART_com + 0x04)
- #define SHARK_UART_DMA_CHCTL_TX() \
- DMA_CHCTL(SHARK_UART_tx_dma_ch)
- #define SHARK_UART_DMA_CHCNT_TX() \
- DMA_CHCNT(SHARK_UART_tx_dma_ch)
- #define SHARK_UART_DMA_CHMADDR_TX() \
- DMA_CHMADDR(SHARK_UART_tx_dma_ch)
- #define SHARK_UART_DMA_CHCTL_RX() \
- DMA_CHCTL(SHARK_UART_rx_dma_ch)
- #define SHARK_UART_DMA_CHCNT_RX() \
- DMA_CHCNT(SHARK_UART_rx_dma_ch)
- #define SHARK_UART_DMA_CHMADDR_RX() \
- DMA_CHMADDR(SHARK_UART_rx_dma_ch)
- // ================================================================================
- static u8 shark_uart_tx_cache[SHARK_UART_TX_MEM_SIZE];
- static u8 shark_uart_rx_cache[SHARK_UART_RX_MEM_SIZE];
- static u16 shark_uart_tx_length;
- static u16 shark_uart_tx_crc16;
- static u16 shark_uart_rx_index;
- static byte_queue_t shark_uart_tx_queue;
- // ================================================================================
- static bool shark_uart_on_frame_received(u8 *buff, u16 length)
- {
- u16 crc0 = shark_decode_u16(buff + length);
- u16 crc1 = shark_crc16_check(buff, length);
- if (crc0 != crc1) {
- return false;
- }
- return true;
- }
- static void shark_uart_on_data_received(u8 *buff, u16 size)
- {
- static bool escape = false;
- static u8 length = 0xFF;
- static u8 frame[16];
- u8 *buff_end;
- for (buff_end = buff + size; buff < buff_end; buff++) {
- u8 value = *buff;
- switch (value) {
- case CH_START:
- length = 0;
- escape = false;
- break;
- case CH_END:
- if (length > 2 && length != 0xFF) {
- shark_uart_on_frame_received(frame, length - 2);
- }
- length = 0xFF;
- break;
- case CH_ESC:
- escape = true;
- break;
- default:
- if (escape) {
- escape = false;
- switch (value) {
- case CH_ESC_START:
- value = CH_START;
- break;
- case CH_ESC_END:
- value = CH_END;
- break;
- case CH_ESC_ESC:
- value = CH_ESC;
- break;
- default:
- length = 0xFF;
- }
- }
- if (length < sizeof(frame)) {
- frame[length] = value;
- length++;
- } else {
- length = 0xFF;
- }
- }
- }
- }
- static void shark_uart_dma_tx(void)
- {
- u32 value = SHARK_UART_DMA_CHCTL_TX();
- if (value & DMA_CHXCTL_CHEN) {
- if (SET != dma_flag_get(SHARK_UART_tx_dma_ch, DMA_FLAG_FTF)) {
- return;
- }
- byte_queue_skip(&shark_uart_tx_queue, shark_uart_tx_length);
- SHARK_UART_DMA_CHCTL_TX() = value & (~DMA_CHXCTL_CHEN);
- }
- shark_uart_tx_length = byte_queue_peek(&shark_uart_tx_queue);
- if (shark_uart_tx_length > 0) {
- SHARK_UART_DMA_CHCNT_TX() = shark_uart_tx_length;
- SHARK_UART_DMA_CHMADDR_TX() = (u32) byte_queue_head(&shark_uart_tx_queue);
- dma_flag_clear(SHARK_UART_tx_dma_ch, DMA_FLAG_FTF);
- SHARK_UART_DMA_CHCTL_TX() = value | DMA_CHXCTL_CHEN;
- }
- }
- static void shark_uart_dma_rx(void)
- {
- u16 index = shark_uart_rx_index;
- shark_uart_rx_index = sizeof(shark_uart_rx_cache) - SHARK_UART_DMA_CHCNT_RX();
- if (shark_uart_rx_index < index) {
- shark_uart_on_data_received(shark_uart_rx_cache + index, sizeof(shark_uart_rx_cache) - index);
- shark_uart_on_data_received(shark_uart_rx_cache, shark_uart_rx_index);
- } else {
- shark_uart_on_data_received(shark_uart_rx_cache + index, shark_uart_rx_index - index);
- }
- }
- void shark_uart_write(const u8 *buff, u16 size)
- {
- while (size > 0) {
- u16 length = byte_queue_write(&shark_uart_tx_queue, buff, size);
- if (length == size) {
- break;
- }
- shark_uart_dma_tx();
- buff += length;
- size -= length;
- }
- }
- void shark_uart_write_byte(u8 value)
- {
- shark_uart_write(&value, 1);
- }
- void shark_uart_dma_init(dma_channel_enum channelx, u8 direction, u32 periph_addr, void *memory_addr, u16 length)
- {
- u32 ctl;
- DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN;
- /* configure peripheral base address */
- DMA_CHPADDR(channelx) = periph_addr;
- /* configure memory base address */
- DMA_CHMADDR(channelx) = (u32) memory_addr;
- /* configure the number of remaining data to be transferred */
- DMA_CHCNT(channelx) = length;
- /* configure peripheral transfer width,memory transfer width and priority */
- ctl = DMA_CHCTL(channelx);
- ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO);
- ctl |= (DMA_PERIPHERAL_WIDTH_8BIT | DMA_MEMORY_WIDTH_8BIT | DMA_PRIORITY_ULTRA_HIGH);
- DMA_CHCTL(channelx) = ctl;
- /* configure peripheral increasing mode */
- DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA;
- /* configure memory increasing mode */
- DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA;
- /* configure the direction of data transfer */
- if (DMA_PERIPHERAL_TO_MEMORY == direction) {
- DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR;
- } else {
- DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR;
- }
- }
- static u32 shark_uart_handler(void)
- {
- shark_uart_dma_rx();
- shark_uart_dma_tx();
- return 0;
- }
- static shark_task_t shark_uart_task = {
- .handler = shark_uart_handler
- };
- void shark_uart_init(void)
- {
- byte_queue_init(&shark_uart_tx_queue, shark_uart_tx_cache, sizeof(shark_uart_tx_cache));
- rcu_periph_clock_enable(SHARK_UART_clk);
- rcu_periph_clock_enable(SHARK_UART_rx_gpio_clk);
- rcu_periph_clock_enable(SHARK_UART_tx_gpio_clk);
- gpio_mode_set(SHARK_UART_tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, SHARK_UART_tx_pin);
- gpio_mode_set(SHARK_UART_rx_port, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, SHARK_UART_rx_pin);
- usart_deinit(SHARK_UART_com);
- usart_baudrate_set(SHARK_UART_com, SHARK_UART_BAUDRATE);
- usart_word_length_set(SHARK_UART_com, USART_WL_8BIT);
- usart_stop_bit_set(SHARK_UART_com, USART_STB_1BIT);
- usart_parity_config(SHARK_UART_com, USART_PM_NONE);
- usart_hardware_flow_rts_config(SHARK_UART_com, USART_RTS_DISABLE);
- usart_hardware_flow_cts_config(SHARK_UART_com, USART_CTS_DISABLE);
- usart_receive_config(SHARK_UART_com, USART_RECEIVE_ENABLE);
- usart_transmit_config(SHARK_UART_com, USART_TRANSMIT_ENABLE);
- rcu_periph_clock_enable(SHARK_UART_tx_dma_clk);
- shark_uart_dma_init(SHARK_UART_tx_dma_ch, DMA_MEMORY_TO_PERIPHERAL, SHARK_UART_DMA_ADDR(), shark_uart_tx_cache, 0);
- dma_circulation_disable(SHARK_UART_tx_dma_ch);
- usart_dma_transmit_config(SHARK_UART_com, USART_DENT_ENABLE);
- rcu_periph_clock_enable(SHARK_UART_rx_dma_clk);
- shark_uart_dma_init(SHARK_UART_rx_dma_ch, DMA_PERIPHERAL_TO_MEMORY, SHARK_UART_DMA_ADDR(), shark_uart_rx_cache, sizeof(shark_uart_rx_cache));
- dma_circulation_enable(SHARK_UART_rx_dma_ch);
- dma_channel_enable(SHARK_UART_rx_dma_ch);
- usart_dma_receive_config(SHARK_UART_com, USART_DENR_ENABLE);
- usart_enable(SHARK_UART_com);
- shark_task_add(&shark_uart_task);
- }
- void shark_uart_write_byte_esc(u8 value)
- {
- switch (value) {
- case CH_START:
- shark_uart_write_byte(CH_ESC);
- value = CH_ESC_START;
- break;
- case CH_END:
- shark_uart_write_byte(CH_ESC);
- value = CH_ESC_END;
- break;
- case CH_ESC:
- shark_uart_write_byte(CH_ESC);
- value = CH_ESC_ESC;
- break;
- }
- shark_uart_write_byte(value);
- }
- void shark_uart_write_esc(const u8 *buff, u16 length)
- {
- const u8 *buff_end;
- for (buff_end = buff + length; buff < buff_end; buff++) {
- shark_uart_write_byte_esc(*buff);
- }
- }
- void shark_uart_tx_start(void)
- {
- shark_uart_write_byte(CH_START);
- shark_uart_tx_crc16 = 0;
- }
- void shark_uart_tx_continue(const void *buff, u16 length)
- {
- shark_uart_write_esc((const u8 *) buff, length);
- shark_uart_tx_crc16 = shark_crc16_update(shark_uart_tx_crc16, (const u8 *) buff, length);
- }
- void shark_uart_tx_end(void)
- {
- shark_uart_write_esc((u8 *) &shark_uart_tx_crc16, sizeof(shark_uart_tx_crc16));
- shark_uart_write_byte(CH_END);
- }
|