430 lines
9.4 KiB
C
430 lines
9.4 KiB
C
/*
|
|
File Name : yc_uart.c
|
|
Author : Yichip
|
|
Version : V1.0
|
|
Date : 2019/12/4
|
|
Description : UART encapsulation.
|
|
*/
|
|
#include "yc_uart.h"
|
|
|
|
#define uart_DMA_buf_len 1024
|
|
uint8_t uart0_DMA_buf[uart_DMA_buf_len] = {0};
|
|
uint8_t uart1_DMA_buf[uart_DMA_buf_len] = {0};
|
|
|
|
#define RX_ENABLE_BIT 0
|
|
#define RX_ENABLE (1 << RX_ENABLE_BIT)
|
|
|
|
#define UART_DMA_ENABLE_BIT 31
|
|
#define UART_DMA_ENABLE (1 << UART_DMA_ENABLE_BIT)
|
|
|
|
#define TX_INTR_ENABLE_BIT 31
|
|
#define TX_INTR_ENABLE ((uint32_t)1 << TX_INTR_ENABLE_BIT)
|
|
|
|
#define Set_RxITNum_Mask 0xff00
|
|
#define Statu_RxNum_Mask (uint32_t)0xffff0000
|
|
|
|
void UART_AutoFlowCtrlCmd(UART_TypeDef UARTx, FunctionalState NewState)
|
|
{
|
|
_ASSERT(IS_UART(UARTx));
|
|
|
|
if (NewState == ENABLE)
|
|
{
|
|
switch (UARTx)
|
|
{
|
|
case UART0:
|
|
UART0_CTRL |= FlowCtrl_Enable;
|
|
break;
|
|
case UART1:
|
|
UART1_CTRL |= FlowCtrl_Enable;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (UARTx)
|
|
{
|
|
case UART0:
|
|
UART0_CTRL &= (~FlowCtrl_Enable);
|
|
break;
|
|
case UART1:
|
|
UART1_CTRL &= (~FlowCtrl_Enable);
|
|
break;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
void UART_ClearIT(UART_TypeDef UARTx)
|
|
{
|
|
uint8_t ITType = UART_GetITIdentity(UARTx);
|
|
UART_ITConfig(UARTx, ITType, DISABLE);
|
|
}
|
|
|
|
void UART_DeInit(UART_TypeDef UARTx)
|
|
{
|
|
_ASSERT(IS_UART(UARTx));
|
|
|
|
switch (UARTx)
|
|
{
|
|
case UART0:
|
|
UART0_CTRL = 0;
|
|
break;
|
|
case UART1:
|
|
UART1_CTRL = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void UART_DMASendBuf(UART_TypeDef UARTx, uint8_t *buf, int len)
|
|
{
|
|
_ASSERT(IS_UART(UARTx));
|
|
_ASSERT(NULL != buf);
|
|
_ASSERT((len < 0xffff));
|
|
|
|
if (UARTx == UART0)
|
|
{
|
|
DMA_SRC_ADDR(DMACH_UART0) = (int)buf;
|
|
DMA_LEN(DMACH_UART0) = (DMA_LEN(DMACH_UART0) & 0xffff) | len << 16;
|
|
DMA_START(DMACH_UART0) = (1 << DMA_START_BIT);
|
|
}
|
|
else
|
|
{
|
|
DMA_SRC_ADDR(DMACH_UART1) = (int)buf;
|
|
DMA_LEN(DMACH_UART1) = (DMA_LEN(DMACH_UART1) & 0xffff) | len << 16;
|
|
DMA_START(DMACH_UART1) = (1 << DMA_START_BIT);
|
|
}
|
|
}
|
|
|
|
uint8_t UART_GetITIdentity(UART_TypeDef UARTx)
|
|
{
|
|
uint8_t IT_Mode = 0;
|
|
switch (UARTx)
|
|
{
|
|
case UART0:
|
|
{
|
|
if (((UART0_CTRL & Set_RxITNum_Mask) > 0) && ((UART0_STATUS >> 16) > 0))
|
|
{
|
|
IT_Mode = UART_IT_RX;
|
|
}
|
|
else
|
|
{
|
|
if ((UART0_CTRL & (uint32_t)TX_INTR_ENABLE))
|
|
{
|
|
IT_Mode = UART_IT_TX;
|
|
}
|
|
else
|
|
{
|
|
IT_Mode = FALSE;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case UART1:
|
|
{
|
|
if (((UART1_CTRL & Set_RxITNum_Mask) > 0) && ((UART1_STATUS >> 16) > 0))
|
|
{
|
|
IT_Mode = UART_IT_RX;
|
|
}
|
|
else
|
|
{
|
|
if (UART1_CTRL & TX_INTR_ENABLE)
|
|
{
|
|
IT_Mode = UART_IT_TX;
|
|
}
|
|
else
|
|
{
|
|
IT_Mode = FALSE;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return IT_Mode;
|
|
}
|
|
|
|
void UART_Init(UART_TypeDef UARTx, UART_InitTypeDef *UART_InitStruct)
|
|
{
|
|
#define RESET_BAUD (1 << 7)
|
|
#define AUTO_BAUD (0 << 7)
|
|
uint32_t reg_value = 0;
|
|
uint32_t temp_baudrate = 0;
|
|
|
|
_ASSERT(IS_UART(UARTx));
|
|
_ASSERT(IS_MODE(UART_InitStruct->Mode));
|
|
_ASSERT(IS_BAUDRATE(UART_InitStruct->BaudRate));
|
|
_ASSERT(IS_PARITY(UART_InitStruct->Parity));
|
|
_ASSERT(IS_FlowCtrl(UART_InitStruct->FlowCtrl));
|
|
_ASSERT(IS_USART_STOPBITS(UART_InitStruct->StopBits));
|
|
|
|
temp_baudrate = ((48000000 / UART_InitStruct->BaudRate) << 16);
|
|
|
|
reg_value = RX_ENABLE |
|
|
UART_InitStruct->Parity |
|
|
UART_InitStruct->DataBits |
|
|
UART_InitStruct->StopBits |
|
|
UART_InitStruct->FlowCtrl |
|
|
UART_InitStruct->Mode |
|
|
RESET_BAUD |
|
|
temp_baudrate;
|
|
|
|
if (UARTx == UART0)
|
|
{
|
|
UART0_CTRL = 0;
|
|
DMA_DEST_ADDR(DMACH_UART0) = (int)uart0_DMA_buf;
|
|
DMA_LEN(DMACH_UART0) = uart_DMA_buf_len;
|
|
DMA_CONFIG(DMACH_UART0) = 1;
|
|
DMA_START(DMACH_UART0) |= (1 << (DMA_RESET_BIT));
|
|
DMA_START(DMACH_UART0) &= ~(1 << (DMA_RESET_BIT));
|
|
UART0_CTRL = 0;
|
|
UART0_CTRL = reg_value;
|
|
}
|
|
else
|
|
{
|
|
UART1_CTRL = 0;
|
|
DMA_DEST_ADDR(DMACH_UART1) = (int)uart1_DMA_buf;
|
|
DMA_LEN(DMACH_UART1) = uart_DMA_buf_len;
|
|
DMA_CONFIG(DMACH_UART1) = 1;
|
|
DMA_START(DMACH_UART1) |= (1 << (DMA_RESET_BIT));
|
|
DMA_START(DMACH_UART1) &= ~(1 << (DMA_RESET_BIT));
|
|
UART1_CTRL = 0;
|
|
UART1_CTRL = reg_value;
|
|
}
|
|
return;
|
|
}
|
|
|
|
Boolean UART_IsRXFIFOFull(UART_TypeDef UARTx)
|
|
{
|
|
#define BITRXFULL 1
|
|
_ASSERT(IS_UART(UARTx));
|
|
|
|
if (UART0 == UARTx)
|
|
{
|
|
return (Boolean)(UART0_STATUS & (1 << BITRXFULL));
|
|
}
|
|
else
|
|
{
|
|
return (Boolean)(UART1_STATUS & (1 << BITRXFULL));
|
|
}
|
|
}
|
|
|
|
Boolean UART_IsRXFIFONotEmpty(UART_TypeDef UARTx)
|
|
{
|
|
#define BITRXEMPTY 0
|
|
_ASSERT(IS_UART(UARTx));
|
|
|
|
if (UART0 == UARTx)
|
|
{
|
|
return (Boolean)((UART0_STATUS >> 16) ? 1 : 0);
|
|
}
|
|
else
|
|
{
|
|
return (Boolean)((UART1_STATUS >> 16) ? 1 : 0);
|
|
}
|
|
}
|
|
|
|
Boolean UART_IsUARTBusy(UART_TypeDef UARTx)
|
|
{
|
|
_ASSERT(IS_UART(UARTx));
|
|
|
|
if (UART0 == UARTx)
|
|
{
|
|
return (Boolean)(!(DMA_STATUS(DMACH_UART0) & 1));
|
|
}
|
|
else
|
|
{
|
|
return (Boolean)(!(DMA_STATUS(DMACH_UART1) & 1));
|
|
}
|
|
}
|
|
|
|
void UART_ITConfig(UART_TypeDef UARTx, uint32_t UART_IT, FunctionalState NewState)
|
|
{
|
|
_ASSERT(IS_UART(UARTx));
|
|
_ASSERT(IS_UART_IT(UART_IT));
|
|
|
|
switch (UARTx)
|
|
{
|
|
case UART0:
|
|
{
|
|
if (UART_IT == UART_IT_RX)
|
|
{
|
|
if (NewState)
|
|
{
|
|
UART0_CTRL |= ((ENABLE << 8));
|
|
}
|
|
else
|
|
{
|
|
UART0_CTRL &= ~Set_RxITNum_Mask;
|
|
}
|
|
}
|
|
else if (UART_IT == UART_IT_TX)
|
|
{
|
|
UART0_CTRL &= (~TX_INTR_ENABLE);
|
|
UART0_CTRL |= (NewState << TX_INTR_ENABLE_BIT);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case UART1:
|
|
{
|
|
if (UART_IT == UART_IT_RX)
|
|
{
|
|
if (NewState)
|
|
{
|
|
UART1_CTRL |= ((ENABLE << 8));
|
|
}
|
|
else
|
|
{
|
|
UART1_CTRL &= ~Set_RxITNum_Mask;
|
|
}
|
|
}
|
|
else if (UART_IT == UART_IT_TX)
|
|
{
|
|
UART1_CTRL &= (uint32_t)~TX_INTR_ENABLE;
|
|
UART1_CTRL |= (NewState << TX_INTR_ENABLE_BIT);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
uint8_t UART_ReceiveData(UART_TypeDef UARTx)
|
|
{
|
|
_ASSERT(IS_UART(UARTx));
|
|
|
|
if (UART0 == UARTx)
|
|
{
|
|
return UART0_RDATA;
|
|
}
|
|
else
|
|
{
|
|
return UART1_RDATA;
|
|
}
|
|
}
|
|
|
|
int UART_RecvBuf(UART_TypeDef UARTx, uint8_t *buf, int len)
|
|
{
|
|
uint32_t length = 0;
|
|
volatile int *pstatus = NULL;
|
|
volatile unsigned char *pdata = NULL;
|
|
_ASSERT(IS_UART(UARTx));
|
|
_ASSERT(NULL != buf);
|
|
|
|
if (UART0 == UARTx)
|
|
{
|
|
pstatus = &UART0_STATUS;
|
|
pdata = &UART0_RDATA;
|
|
}
|
|
else
|
|
{
|
|
pstatus = &UART1_STATUS;
|
|
pdata = &UART1_RDATA;
|
|
}
|
|
|
|
while ((*pstatus >> 16) > 0)
|
|
{
|
|
if (length < len)
|
|
{
|
|
buf[length++] = *pdata;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return length;
|
|
}
|
|
|
|
void UART_SendBuf(UART_TypeDef UARTx, uint8_t *buf, int len)
|
|
{
|
|
_ASSERT(IS_UART(UARTx));
|
|
_ASSERT(NULL != buf);
|
|
_ASSERT((len < 0xffff));
|
|
|
|
if (UARTx == UART0)
|
|
{
|
|
DMA_SRC_ADDR(DMACH_UART0) = (int)buf;
|
|
DMA_LEN(DMACH_UART0) = (DMA_LEN(DMACH_UART0) & 0xffff) | len << 16;
|
|
DMA_START(DMACH_UART0) = (1 << DMA_START_BIT);
|
|
while ((!(DMA_STATUS(DMACH_UART0) & 1)));
|
|
}
|
|
else
|
|
{
|
|
DMA_SRC_ADDR(DMACH_UART1) = (int)buf;
|
|
DMA_LEN(DMACH_UART1) = (DMA_LEN(DMACH_UART1) & 0xffff) | len << 16;
|
|
DMA_START(DMACH_UART1) = (1 << DMA_START_BIT);
|
|
while ((!(DMA_STATUS(DMACH_UART1) & 1)));
|
|
}
|
|
}
|
|
|
|
void UART_SendData(UART_TypeDef UARTx, uint8_t Data)
|
|
{
|
|
uint8_t buf[1] = {Data};
|
|
|
|
if (UARTx == UART0)
|
|
{
|
|
DMA_SRC_ADDR(DMACH_UART0) = (int)buf;
|
|
DMA_LEN(DMACH_UART0) = (DMA_LEN(DMACH_UART0) & 0xffff) | 1 << 16;
|
|
DMA_START(DMACH_UART0) = (1 << DMA_START_BIT);
|
|
while (!(DMA_STATUS(DMACH_UART0) & 1));
|
|
}
|
|
else
|
|
{
|
|
DMA_SRC_ADDR(DMACH_UART1) = (int)buf;
|
|
DMA_LEN(DMACH_UART1) = (DMA_LEN(DMACH_UART1) & 0xffff) | 1 << 16;
|
|
DMA_START(DMACH_UART1) = (1 << DMA_START_BIT);
|
|
while (!(DMA_STATUS(DMACH_UART1) & 1));
|
|
}
|
|
}
|
|
|
|
void UART_SetITTimeout(UART_TypeDef UARTx, uint16_t timeout)
|
|
{
|
|
if (UART0 == UARTx)
|
|
{
|
|
UART0_INTR = timeout;
|
|
}
|
|
else
|
|
{
|
|
UART1_INTR = timeout;
|
|
}
|
|
}
|
|
|
|
void UART_SetRxITNum(UART_TypeDef UARTx, uint8_t Bcnt)
|
|
{
|
|
_ASSERT(IS_UART(UARTx));
|
|
|
|
if (UART0 == UARTx)
|
|
{
|
|
UART0_CTRL = (UART0_CTRL & 0xffff00ff) | ((Bcnt & 0xff) << 8);
|
|
}
|
|
else
|
|
{
|
|
UART1_CTRL = (UART1_CTRL & 0xffff00ff) | ((Bcnt & 0xff) << 8);
|
|
}
|
|
}
|
|
|
|
void UART_StructInit(UART_InitTypeDef *UART_InitStruct)
|
|
{
|
|
UART_InitStruct->BaudRate = 9600;
|
|
UART_InitStruct->DataBits = Databits_8b;
|
|
UART_InitStruct->FlowCtrl = FlowCtrl_None;
|
|
UART_InitStruct->Mode = Mode_duplex;
|
|
UART_InitStruct->StopBits = StopBits_1;
|
|
UART_InitStruct->Parity = 0;
|
|
}
|
|
|
|
uint16_t UART_ReceiveDataLen(UART_TypeDef UARTx)
|
|
{
|
|
_ASSERT(IS_UART(UARTx));
|
|
|
|
if (UART0 == UARTx)
|
|
{
|
|
return (uint16_t)(UART0_STATUS >> 16);
|
|
}
|
|
else
|
|
{
|
|
return (uint16_t)(UART1_STATUS >> 16);
|
|
}
|
|
}
|