K1Guitar/project/src/usart.c

179 lines
4.1 KiB
C
Raw Normal View History

#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))
{
/* <20><><EFBFBD><EFBFBD>պ<EFBFBD><D5BA>ٵ<EFBFBD><D9B5><EFBFBD>λ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
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();
}