rt-thread-official/bsp/yichip/yc3122-pos/Libraries/sdk/yc_uart.c

383 lines
12 KiB
C

/*
* Copyright (c) 2006-2020, YICHIP Development Team
* @file yc_uart.c
* @brief source file for setting uart
*
* Change Logs:
* Date Author Version Notes
* 2020-11-06 wushengyan V1.0.0 the first version
*/
#include "yc_uart.h"
#define uart_DMA_buf_len 1024
const UART_TypeDef * const UARTs[] = {MUART0, MUART1, MUART2, MUART3};
uint8_t uart0_DMA_buf[uart_DMA_buf_len] = {0};
uint8_t uart1_DMA_buf[uart_DMA_buf_len] = {0};
uint8_t uart2_DMA_buf[uart_DMA_buf_len] = {0};
uint8_t uart3_DMA_buf[uart_DMA_buf_len] = {0};
#define RX_ENABLE BIT0
#define UART_DMA_ENABLE BIT31
#define TX_INTR_ENABLE BIT31
#define Set_RxITNum_Mask 0xff00
#define Statu_RxNum_Mask (uint32_t)0xffff0000
/**
* @method UART_Buffer_Select
* @brief select UART buffer
* @param UARTx: Select the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @retval NULL
*/
static uint8_t *UART_Buffer_Select(UART_TypeDef *UARTx)
{
_ASSERT(IS_UART(UARTx));
uint8_t *buffers[] = {uart0_DMA_buf, uart1_DMA_buf, uart2_DMA_buf, uart3_DMA_buf};
for (int i = 0; i < sizeof(UARTs) / sizeof(UARTs[0]); i++)
{
if ((void *)UARTs[i] == (void *)UARTx)
{
return buffers[i];
}
}
return NULL;
}
/**
* @method UART_DeInit
* @brief DeInit UART
* @param UARTx: Select the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @retval None
*/
void UART_DeInit(UART_TypeDef *UARTx)
{
_ASSERT(IS_UART(UARTx));
UARTx->CTRL.reg = 0;
UARTx->RX_INT_LEN.reg = 0;
}
/**
* @method UART_Init
* @brief Initializes the UARTx peripheral according to
* the specified parameters.
* @param UARTx: Select the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @param UART_InitStruct: pointer to a UART_InitTypeDef structure that
* contains the configuration information.
*/
void UART_Init(UART_TypeDef *UARTx, UART_InitTypeDef *UART_InitStruct)
{
DMA_TypeDef *DMAx = NULL;
uint8_t *uartx_DMA_buf = NULL;
uint32_t temp_baudrate = 0;
_ASSERT(IS_UART(UARTx));
_ASSERT(IS_UART_RX_MODE(UART_InitStruct->RxMode));
_ASSERT(IS_UART_PARITY(UART_InitStruct->Parity));
_ASSERT(IS_UART_WORD_LENGTH(UART_InitStruct->DataBits));
_ASSERT(IS_UART_STOPBITS(UART_InitStruct->StopBits));
_ASSERT(IS_UART_FLOW_CTRL(UART_InitStruct->FlowCtrl));
_ASSERT(IS_UART_SMART_CARD(UART_InitStruct->SmartCard));
_ASSERT(IS_UART_COMM_MODE(UART_InitStruct->CommMode));
_ASSERT(IS_UART_BAUDRATE(UART_InitStruct->BaudRate));
DMAx = (DMA_TypeDef *)((uint32_t)UARTx - sizeof(DMA_TypeDef));
uartx_DMA_buf = UART_Buffer_Select(UARTx);
temp_baudrate = (48000000 / UART_InitStruct->BaudRate);
UART_DeInit(UARTx);
DMAx->DEST_ADDR.reg = (uint32_t)uartx_DMA_buf;
DMAx->LEN_LOW.bit.RX_LEN_L = uart_DMA_buf_len;
DMAx->CTRL.bit.LOOPBACK = 1;
DMAx->CTRL.bit.RESET = 1;
DMAx->CTRL.bit.RESET = 0;
UARTx->CTRL.bit.RX_EN = UART_InitStruct->RxMode;
UARTx->CTRL.bit.PARITY = UART_InitStruct->Parity;
UARTx->CTRL.bit.DATA_BITS = UART_InitStruct->DataBits;
UARTx->CTRL.bit.STOP_BITS = UART_InitStruct->StopBits;
UARTx->CTRL.bit.FLOW_CTRL = UART_InitStruct->FlowCtrl;
UARTx->CTRL.bit.SMART_CARD = UART_InitStruct->SmartCard;
UARTx->CTRL.bit.HDX_EN = UART_InitStruct->CommMode;
UARTx->CTRL.bit.RESET_BAUD = ENABLE;
UARTx->BAUD.bit.BAUD_RATE = temp_baudrate;
}
/**
* @method UART_StructInit
* @brief Fills each USART_InitStruct member with its default value.
* @param USART_InitStruct: pointer to a USART_InitTypeDef structure
* which will be initialized.
* @retval None
*/
void UART_StructInit(UART_InitTypeDef *UART_InitStruct)
{
UART_InitStruct->BaudRate = 9600;
UART_InitStruct->RxMode = MODE_RX_ENABLE;
UART_InitStruct->Parity = YC_PARITY_NONE;
UART_InitStruct->DataBits = DATABITS_8B;
UART_InitStruct->StopBits = STOPBITS_1;
UART_InitStruct->FlowCtrl = FLOWCTRL_NONE;
UART_InitStruct->SmartCard = SMARTCARD_DISABLE;
UART_InitStruct->CommMode = MODE_DUPLEX;
}
/**
* @method UART_ITConfig
* @brief Enable or disable the specified UART interrupt.
* @param UARTx: Select the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @param UART_IT: specifies the UART interrupt sources
* This parameter can be one of the following values:
* @arg UART_IT_TX:interrupt trigger after send data completed.
* @arg UART_IT_RX:interrupt trigger when received data.
* @param NewState: new state of the specified UART interrupt
* This parameter can be ENABLE or DISABLE
*/
void UART_ITConfig(UART_TypeDef *UARTx, uint32_t UART_IT, FunctionalState NewState)
{
_ASSERT(IS_UART(UARTx));
_ASSERT(IS_UART_IT(UART_IT));
if (UART_IT == UART_IT_TX)
{
UARTx->BAUD.bit.TX_INT_EN = NewState;
}
else if (UART_IT == UART_IT_RX)
{
UARTx->RX_INT_LEN.bit.VAL = NewState;
}
}
/**
* @method UART_SendData
* @brief UART Send One Data
* @param UARTx: Select the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @retval None
*/
void UART_SendData(UART_TypeDef *UARTx, uint8_t Data)
{
_ASSERT(IS_UART(UARTx));
volatile uint8_t buf[1];
buf[0] = Data;
DMA_TypeDef *DMAx = (DMA_TypeDef *)((uint32_t)UARTx - sizeof(DMA_TypeDef));
DMAx->SRC_ADDR.reg = (uint32_t)buf;
DMAx->LEN_LOW.bit.TX_LEN_L = 1;
DMAx->CTRL.bit.START = 1;
while (DMAx->STATUS.bit.DONE != 1);
}
/**
* @method UART_SendBuf
* @brief Transmits datas via UART DMA, the function will return after datas is sent.
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @param buf: pointer to a buf that contains the data you want transmit.
* @param len: the buf length
* @retval None
*/
void UART_SendBuf(UART_TypeDef *UARTx, uint8_t *buf, uint32_t len)
{
_ASSERT(IS_UART(UARTx));
_ASSERT(NULL != buf);
_ASSERT(len < 0xfffff);
DMA_TypeDef *DMAx = (DMA_TypeDef *)((uint32_t)UARTx - sizeof(DMA_TypeDef));
DMAx->SRC_ADDR.reg = (uint32_t)buf;
DMAx->LEN_LOW.bit.TX_LEN_L = len & 0xffff;
DMAx->CTRL.bit.TX_LEN_H = len >> 16;
DMAx->CTRL.bit.START = 1;
while (DMAx->STATUS.bit.DONE != 1);
}
/**
* @method UART_ReceiveData
* @brief Receive single data through the USARTx peripheral.
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @retval An one byte received data.
*/
uint8_t UART_ReceiveData(UART_TypeDef *UARTx)
{
_ASSERT(IS_UART(UARTx));
return UARTx->RX_DATA.bit.VAL;
}
/**
* @method UART_ReceiveBuf
* @brief Receives datas through the UART DMA.
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @param buf: pointer to a buf that contains the data you want receive.
* @param len: the buf length, which size should be less than 20 bit (len < 0xfffff)
* @retval The length of received data before return.
*/
uint32_t UART_ReceiveBuf(UART_TypeDef *UARTx, uint8_t *buf, uint32_t len)
{
_ASSERT(IS_UART(UARTx));
_ASSERT(NULL != buf);
_ASSERT(len < 0xfffff);
uint32_t rcv_len = 0;
while ((UART_ReceiveDataLen(UARTx) > 0) && (rcv_len < len))
{
buf[rcv_len++] = UARTx->RX_DATA.bit.VAL;
}
return rcv_len;
}
/**
* @method UART_AutoFlowCtrlCmd
* @brief ENABLE or DISABLE UARTx auto flow control
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @param NewState: ENABLE or DISABLE auto flow control
* @retval None
*/
void UART_AutoFlowCtrlCmd(UART_TypeDef *UARTx, FunctionalState NewState)
{
_ASSERT(IS_UART(UARTx));
UARTx->CTRL.bit.FLOW_CTRL = NewState;
}
/**
* @method UART_GetITIdentity
* @brief Get IT Identity
* @param UARTx: Select the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @retval IT Identity
*/
uint8_t UART_GetITIdentity(UART_TypeDef *UARTx)
{
_ASSERT(IS_UART(UARTx));
//return (0 || (UARTx->BAUD.bit.TX_INT_EN) || (UARTx->RX_INT_LEN.bit.VAL));
if((UARTx->RX_INT_LEN.reg > 0)&& (UARTx->STATUS.bit.RX_ITEMS_L >=UARTx->RX_INT_LEN.reg))
{
return UART_IT_RX;
}
else if(UARTx->BAUD.bit.TX_INT_EN)
{
return UART_IT_TX;
}
return 0;
}
/**
* @method UART_IsRXFIFOFull
* @brief Check if the Rx fifo is full or not.
* @param UARTx: Select the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @retval TRUE: Rx fifo is full.
* FALSE: Rx fifo is not full
*/
Boolean UART_IsRXFIFOFull(UART_TypeDef *UARTx)
{
_ASSERT(IS_UART(UARTx));
return (Boolean)(UARTx->STATUS.bit.RX_FULL);
}
/**
* @method UART_IsRXFIFONotEmpty
* @brief Check if the Rx fifo is empty or not.
* @param UARTx: Select the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @retval TRUE: Rx fifo is not empty.
* FALSE: Rx fifo is empty
*/
Boolean UART_IsRXFIFONotEmpty(UART_TypeDef *UARTx)
{
_ASSERT(IS_UART(UARTx));
return (Boolean)(!(UARTx->STATUS.bit.RX_EMPTY));
}
/**
* @method UART_IsBusy
* @brief Check if the UARTx is busy or not.
* @param UARTx: Select the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @retval TRUE: UARTx is busy.
* FALSE: UARTx is not busy.
*/
Boolean UART_IsBusy(UART_TypeDef *UARTx)
{
_ASSERT(IS_UART(UARTx));
return (Boolean)(!(UARTx->STATUS.bit.RX_EMPTY));
}
/**
* @method UART_SetITTimeout
* @brief Sets the interruption time for serial port timeout.
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @param timeout: 0x00~0xff
* @retval None
*/
void UART_SetITTimeout(UART_TypeDef *UARTx, uint16_t timeout)
{
_ASSERT(IS_UART(UARTx));
UARTx->TIMEOUT_INT.reg = timeout;
}
/**
* @method UART_SetRxITNum
* @brief Set the number of uart receive data intterupt trigger
* @param UARTx: Select the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @param Bcnt: if the number of receive datas greater than Bcnt,interrupt trigger
* @retval None
*/
void UART_SetRxITNum(UART_TypeDef *UARTx, uint8_t Bcnt)
{
_ASSERT(IS_UART(UARTx));
UARTx->RX_INT_LEN.reg = Bcnt;
}
/**
* @method UART_ReceiveDataLen
* @brief Return the length of received data
* @param UARTx: Select the UART peripheral.
* This parameter can be one of the following values:
* MUART0, MUART1, MUART2 or MUART3.
* @retval Data len
*/
uint32_t UART_ReceiveDataLen(UART_TypeDef *UARTx)
{
_ASSERT(IS_UART(UARTx));
return (UARTx->STATUS.bit.RX_ITEMS_H << 16) + UARTx->STATUS.bit.RX_ITEMS_L;
}
/************************ (C) COPYRIGHT Yichip Microelectronics *****END OF FILE****/