rt-thread-official/bsp/yichip/yc3121-pos/Libraries/sdk/yc_uart.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);
}
}