#include "includes.h" #include "usart.h" #define BUFF_SIZE 512 /* ?????????????????????????????? volatile???? ?????????????????? volatile ???? Pa082 ????????? */ #define IS_FULL(head, tail) ((((head) + 1) % BUFF_SIZE) == (tail)) #define IS_EMPTY(head, tail) ((head) == (tail)) /* ==================== ???????????? ==================== */ /* ????????????????????????????? */ typedef struct { uint8_t rx_buff[BUFF_SIZE]; volatile uint16_t rx_head; volatile uint16_t rx_tail; uint8_t tx_buff[BUFF_SIZE]; volatile uint16_t tx_head; volatile uint16_t tx_tail; usart_type *usart; /* ??????????????USART2 / UART4?? */ } uart_ring_t; /* USART2 ?? UART4 ???????? */ static uart_ring_t uart2; static uart_ring_t uart4; /* ?????????????????????? wk_usart2_init / wk_uart4_init ????? */ void uart_ring_usart2_init(void) { uart2.usart = USART2; } void uart_ring_uart4_init(void) { uart4.usart = UART4; } /* ==================== ??????/???????????????? ==================== */ /* ????ISR ???????????? volatile ???????????? Pa082 */ static void ring_rx_push(uart_ring_t *rb, uint8_t c) { uint16_t h = rb->rx_head; uint16_t t = rb->rx_tail; if(IS_FULL(h, t)) return; /* ???????????????????? */ rb->rx_buff[h] = c; rb->rx_head = (h + 1) % BUFF_SIZE; } /* ??????????????? */ static uint8_t ring_rx_pop(uart_ring_t *rb, uint8_t *c) { uint16_t h = rb->rx_head; uint16_t t = rb->rx_tail; if(IS_EMPTY(h, t)) return 0; *c = rb->rx_buff[t]; rb->rx_tail = (t + 1) % BUFF_SIZE; return 1; } /* ???? tx ??????????????????????? ISR ?????? */ static void ring_tx_write(uart_ring_t *rb, uint8_t *data, uint16_t len) { uint16_t h = rb->tx_head; uint16_t t = rb->tx_tail; for(uint16_t i = 0; i < len; i++) { if(IS_FULL(h, t)) break; /* ?? tx ???? */ rb->tx_buff[h] = data[i]; h = (h + 1) % BUFF_SIZE; } rb->tx_head = h; /* ???????????? volatile */ } /* ==================== ?????????????????? ==================== */ /* ?????????????? ?? ?????? ?? ?? TDBE ??????????? */ static void uart_ring_send(uart_ring_t *rb, uint8_t *data, uint16_t len) { rt_base_t level = rt_hw_interrupt_disable(); ring_tx_write(rb, data, len); usart_interrupt_enable(rb->usart, USART_TDBE_INT, TRUE); /* ?????????? */ rt_hw_interrupt_enable(level); } /* USART2 ?????????midi_send.c ??????? */ void USART2_SendData(uint8_t *data, uint16_t len) { uart_ring_send(&uart2, data, len); } /* UART4 ????????? */ void USART4_SendData(uint8_t *data, uint16_t len) { uart_ring_send(&uart4, data, len); } void USART4_WaitTxIdle(uint32_t timeout_ms) { uint32_t t0 = rt_tick_get(); while ((rt_tick_get() - t0) < rt_tick_from_millisecond(timeout_ms ? timeout_ms : 1)) { uint16_t h = uart4.tx_head; uint16_t t = uart4.tx_tail; if (IS_EMPTY(h, t)) { /* ����պ��ٵ���λ�Ĵ������� */ if (usart_flag_get(uart4.usart, USART_TDC_FLAG) == SET) return; } rt_thread_mdelay(1); } } /* USART2 ???????????? */ uint8_t USART2_RxPop(uint8_t *c) { return ring_rx_pop(&uart2, c); } /* UART4 ???????????? */ uint8_t UART4_RxPop(uint8_t *c) { return ring_rx_pop(&uart4, c); } /* ==================== ???????? ==================== */ static void uart_ring_isr(uart_ring_t *rb) { if(usart_flag_get(rb->usart, USART_RDBF_FLAG) == SET) { uint8_t data = usart_data_receive(rb->usart); ring_rx_push(rb, data); if(rb->usart == UART4) { rt_sem_release(UART4_sem); } } if(usart_flag_get(rb->usart, USART_TDBE_FLAG) == SET) { uint16_t h = rb->tx_head; uint16_t t = rb->tx_tail; if(!IS_EMPTY(h, t)) { usart_data_transmit(rb->usart, rb->tx_buff[t]); rb->tx_tail = (t + 1) % BUFF_SIZE; } else { usart_interrupt_enable(rb->usart, USART_TDBE_INT, FALSE); } } if(usart_flag_get(rb->usart, USART_ROERR_FLAG) == SET) usart_flag_clear(rb->usart, USART_ROERR_FLAG); } void USART2_IRQHandler(void) { rt_interrupt_enter(); uart_ring_isr(&uart2); rt_interrupt_leave(); } void UART4_IRQHandler(void) { rt_interrupt_enter(); uart_ring_isr(&uart4); rt_interrupt_leave(); }