165 lines
3.9 KiB
C
165 lines
3.9 KiB
C
|
|
#include "includes.h"
|
|||
|
|
#include "usart.h"
|
|||
|
|
|
|||
|
|
#define BUFF_SIZE 512
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD>ȽϺ꣺<CFBA><EAA3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> volatile<6C><65><EFBFBD><EFBFBD>
|
|||
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>η<EFBFBD><EFBFBD><EFBFBD> volatile <EFBFBD><EFBFBD><EFBFBD><EFBFBD> Pa082 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
#define IS_FULL(head, tail) ((((head) + 1) % BUFF_SIZE) == (tail))
|
|||
|
|
#define IS_EMPTY(head, tail) ((head) == (tail))
|
|||
|
|
|
|||
|
|
/* ==================== <20><><EFBFBD>ζ<EFBFBD><CEB6>нṹ<D0BD><E1B9B9> ==================== */
|
|||
|
|
|
|||
|
|
/* һ<><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD>Ļ<EFBFBD><C4BB>ζ<EFBFBD><CEB6>У<EFBFBD><D0A3>շ<EFBFBD><D5B7><EFBFBD>һ<EFBFBD><D2BB> */
|
|||
|
|
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; /* <20><><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>裨USART2 / UART4<54><34> */
|
|||
|
|
} uart_ring_t;
|
|||
|
|
|
|||
|
|
/* USART2 <20><> UART4 <20><>һ<EFBFBD><D2BB>ʵ<EFBFBD><CAB5> */
|
|||
|
|
static uart_ring_t uart2;
|
|||
|
|
static uart_ring_t uart4;
|
|||
|
|
|
|||
|
|
/* <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>裨<EFBFBD><E8A3A8> wk_usart2_init / wk_uart4_init <20><><EFBFBD>ã<EFBFBD> */
|
|||
|
|
void uart_ring_usart2_init(void)
|
|||
|
|
{
|
|||
|
|
uart2.usart = USART2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void uart_ring_uart4_init(void)
|
|||
|
|
{
|
|||
|
|
uart4.usart = UART4;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* ==================== ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================== */
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD>ӣ<EFBFBD>ISR <20><><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD> volatile ֵ<>ٲ<EFBFBD><D9B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 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; /* <20><><EFBFBD><EFBFBD><F2B6AAA3><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
rb->rx_buff[h] = c;
|
|||
|
|
rb->rx_head = (h + 1) % BUFF_SIZE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD>ӣ<EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>̵߳<DFB3><CCB5>ã<EFBFBD> */
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* д<><D0B4> tx <20><><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD>ǰӦ<C7B0>ѹ<EFBFBD><D1B9>жϣ<D0B6><CFA3><EFBFBD>ֹ ISR ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD> */
|
|||
|
|
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; /* <20><> tx <20><><EFBFBD><EFBFBD> */
|
|||
|
|
rb->tx_buff[h] = data[i];
|
|||
|
|
h = (h + 1) % BUFF_SIZE;
|
|||
|
|
}
|
|||
|
|
rb->tx_head = h; /* <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>д<EFBFBD><D0B4> volatile */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* ==================== <20><><EFBFBD>ͽӿڣ<D3BF><DAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD> ==================== */
|
|||
|
|
|
|||
|
|
/* ͨ<>÷<EFBFBD><C3B7>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>ж<EFBFBD> <20><> д<><D0B4><EFBFBD><EFBFBD> <20><> <20><> TDBE <20>жϴ<D0B6><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
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); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> */
|
|||
|
|
|
|||
|
|
rt_hw_interrupt_enable(level);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* USART2 <20><><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>⣬midi_send.c <20><><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD> */
|
|||
|
|
void USART2_SendData(uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
uart_ring_send(&uart2, data, len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* UART4 <20><><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>⣩ */
|
|||
|
|
void USART4_SendData(uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
uart_ring_send(&uart4, data, len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* USART2 <20><><EFBFBD>ճ<EFBFBD><D5B3>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD>⣩ */
|
|||
|
|
uint8_t USART2_RxPop(uint8_t *c)
|
|||
|
|
{
|
|||
|
|
return ring_rx_pop(&uart2, c);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* UART4 <20><><EFBFBD>ճ<EFBFBD><D5B3>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD>⣩ */
|
|||
|
|
uint8_t UART4_RxPop(uint8_t *c)
|
|||
|
|
{
|
|||
|
|
return ring_rx_pop(&uart4, c);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* ==================== <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> ==================== */
|
|||
|
|
|
|||
|
|
static void uart_ring_isr(uart_ring_t *rb)
|
|||
|
|
{
|
|||
|
|
/* <20><><EFBFBD>գ<EFBFBD><D5A3>յ<EFBFBD><D5B5>ֽ<EFBFBD> <20><> <20><> rx <20><><EFBFBD><EFBFBD> */
|
|||
|
|
if(usart_flag_get(rb->usart, USART_RDBF_FLAG) == SET)
|
|||
|
|
{
|
|||
|
|
uint8_t data = usart_data_receive(rb->usart); /* <20><><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3>Զ<EFBFBD><D4B6><EFBFBD> RDBF<42><46> */
|
|||
|
|
ring_rx_push(rb, data);
|
|||
|
|
if(rb->usart == UART4)
|
|||
|
|
{
|
|||
|
|
rt_sem_release(UART4_sem);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD>ͣ<EFBFBD>tx <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><>һ<EFBFBD><D2BB><EFBFBD>ֽڣ<D6BD><DAA3><EFBFBD><EFBFBD><EFBFBD> <20><> <20><> TDBE <20>ж<EFBFBD> */
|
|||
|
|
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); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> */
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϿ<D0B6><CFBF><EFBFBD> */
|
|||
|
|
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();
|
|||
|
|
}
|