📄 uart.c
字号:
// Init receive and transmit FIFOs
pUart1RxFifo->PopIndx = pUart1RxFifo->PushIndx = \
pUart1TxFifo->PopIndx = pUart1TxFifo->PushIndx = 0;
// Enable UART1
PCONP_bit.PCUART1 = 1;
// TX
PINSEL0_bit.P0_15 = 1;
// RX
PINSEL1_bit.P0_16 = 1;
U1LCR = 0x03; // Word Length =8, no parity , 1 stop
U1MCR = 0; // Word Length =8, no parity , 1 stop
U1FCR = 0x7; // Enable and Clear the UART1 FIFO, Set RX FIFO interrupt level - 1 char
// Transmit enable
U1TER_bit.TXEN = 1;
Tmp = U1IER; // Clear pending interrupts
// enable RBR Interrupt, THRE Interrupt, RX Line Status Interrupt
// Modem Status Interrupt, CTS Interrupt Enable
U1IER = 0x07 | (UART1_MODEM_STAT_ENA?0x88:0);
VIC_SetVectoredIRQ(Uart1Isr,IrqSlot,VIC_UART1);
VICINTENABLE |= 1<<VIC_UART1;
break;
case UART_2:
pUart2RxFifo = (pUartFifo_t)malloc(sizeof(UartFifo_t));
if(pUart2RxFifo == NULL)
{
return(FALSE);
}
pUart2TxFifo = (pUartFifo_t)malloc(sizeof(UartFifo_t));
if(pUart2TxFifo == NULL)
{
free(pUart2RxFifo);
return(FALSE);
}
// Init receive and transmit FIFOs
pUart2RxFifo->PopIndx = pUart2RxFifo->PushIndx = \
pUart2TxFifo->PopIndx = pUart2TxFifo->PushIndx = 0;
// Enable UART2
PCONP_bit.PCUART2 = 1;
// TX
PINSEL0_bit.P0_10 = 1;
// RX
PINSEL0_bit.P0_11 = 1;
U2LCR = 0x03; // Word Length =8, no parity , 1 stop
U2FCR = 0x7; // Enable and Clear the UART2 FIFO, Set RX FIFO interrupt level - 1 char
// Transmit enable
U2TER_bit.TXEN = 1;
Tmp = U2IER; // Clear pending interrupts
// enable RBR Interrupt, THRE Interrupt, RX Line Status Interrupt
U2IER = 0x07;
VIC_SetVectoredIRQ(Uart2Isr,IrqSlot,VIC_UART2);
VICINTENABLE |= 1<<VIC_UART2;
break;
case UART_3:
pUart3RxFifo = (pUartFifo_t)malloc(sizeof(UartFifo_t));
if(pUart3RxFifo == NULL)
{
return(FALSE);
}
pUart3TxFifo = (pUartFifo_t)malloc(sizeof(UartFifo_t));
if(pUart3TxFifo == NULL)
{
free(pUart3RxFifo);
return(FALSE);
}
// Init receive and transmit FIFOs
pUart3RxFifo->PopIndx = pUart3RxFifo->PushIndx = \
pUart3TxFifo->PopIndx = pUart3TxFifo->PushIndx = 0;
// Enable UART3
PCONP_bit.PCUART3 = 1;
// TX
PINSEL9_bit.P4_28 = 3;
// RX
PINSEL9_bit.P4_29 = 3;
U3LCR = 0x03; // Word Length =8, no parity , 1 stop
U3FCR = 0x7; // Enable and Clear the UART3 FIFO, Set RX FIFO interrupt level - 1 char
// Enable/Disable IrDA mode
if(UartMode == IRDA)
{
U3ICR_bit.FIXPULSEEN = 0;
U3ICR_bit.IRDAINV = 1;
U3ICR_bit.IRDAEN = 1;
}
else
{
U3ICR_bit.IRDAEN = 0;
}
// Transmit enable
U3TER_bit.TXEN = 1;
Tmp = U3IER; // Clear pending interrupts
// enable RBR Interrupt, THRE Interrupt, RX Line Status Interrupt
U3IER = 0x07;
VIC_SetVectoredIRQ(Uart3Isr,IrqSlot,VIC_UART3);
VICINTENABLE |= 1<<VIC_UART3;
break;
}
return(TRUE);
}
/*************************************************************************
* Function Name: UartCalcDivider
* Parameters: Int32U Freq, Int32U Baud
* pInt32U pDiv, pInt32U pAddDiv, pInt32U pMul
*
* Return: None
*
* Description: Calculate the coefficients of the UART baudrate generator
*
*************************************************************************/
static
void UartCalcDivider(Int32U Freq, Int32U Baud,
pInt32U pDiv, pInt32U pAddDiv, pInt32U pMul)
{
Int32U Temp, Error = (Int32U)-1;
Int32U K1, K2, K3, Baudrate;
Int32U DivTemp, MulTemp, AddDivTemp;
//
for(MulTemp = 1; MulTemp < 16; ++MulTemp)
{
K1 = Freq*MulTemp;
for(AddDivTemp = 1; AddDivTemp < 16; ++AddDivTemp)
{
K3 = (MulTemp + AddDivTemp)<<4;
K2 = K3 * Baud;
DivTemp = K1/K2;
// if DIVADDVAL>0, UnDL must be UnDL >= 0x0002 or the UART will
// not operate at the desired baud-rate!
if(DivTemp < 2)
{
continue;
}
Baudrate = DivTemp * K3;
Baudrate = K1/Baudrate;
Temp = (Baudrate > Baud)? \
(Baudrate - Baud): \
(Baud - Baudrate);
if (Temp < Error)
{
Error = Temp;
*pDiv = DivTemp;
*pMul = MulTemp;
*pAddDiv = AddDivTemp;
if(Error == 0)
{
return;
}
}
}
}
}
/*************************************************************************
* Function Name: UartSetLineCoding
* Parameters: UartNum_t Uart,UartLineCoding_t pUartCoding
*
* Return: None
*
* Description: Init UART Baud rate, Word width, Stop bits, Parity type
*
*************************************************************************/
void UartSetLineCoding(UartNum_t Uart,UartLineCoding_t UartCoding)
{
Int32U Mul, Div, AddDiv, Freq;
// Check parameters
if ((UartCoding.dwDTERate == 0) || (UartCoding.dwDTERate > UART_MAX_BAUD_RATE))
{
return;
}
switch (Uart)
{
case UART_0:
Freq = SYS_GetFpclk(UART0_PCLK_OFFSET);
UartCalcDivider(Freq,UartCoding.dwDTERate,&Div,&AddDiv,&Mul);
U0LCR_bit.WLS = UartCoding.bDataBits;
U0LCR_bit.SBS = UartCoding.bStopBitsFormat;
U0LCR_bit.PE =(UartCoding.bParityType == UART_NO_PARITY)?0:1;
U0LCR_bit.PS = UartCoding.bParityType;
U0LCR_bit.DLAB = 1;
U0DLL = Div & 0xFF;
U0DLM = (Div >> 8) & 0xFF;
U0FDR = AddDiv + (Mul << 4);
U0LCR_bit.DLAB = 0;
break;
case UART_1:
Freq = SYS_GetFpclk(UART1_PCLK_OFFSET);
UartCalcDivider(Freq,UartCoding.dwDTERate,&Div,&AddDiv,&Mul);
U1LCR_bit.WLS = UartCoding.bDataBits;
U1LCR_bit.SBS = UartCoding.bStopBitsFormat;
U1LCR_bit.PE =(UartCoding.bParityType == UART_NO_PARITY)?0:1;
U1LCR_bit.PS = UartCoding.bParityType;
U1LCR_bit.DLAB = 1;
U1DLL = Div & 0xFF;
U1DLM = (Div >> 8) & 0xFF;
U1FDR = AddDiv + (Mul << 4);
U1LCR_bit.DLAB = 0;
break;
case UART_2:
Freq = SYS_GetFpclk(UART2_PCLK_OFFSET);
UartCalcDivider(Freq,UartCoding.dwDTERate,&Div,&AddDiv,&Mul);
U2LCR_bit.WLS = UartCoding.bDataBits;
U2LCR_bit.SBS = UartCoding.bStopBitsFormat;
U2LCR_bit.PE =(UartCoding.bParityType == UART_NO_PARITY)?0:1;
U2LCR_bit.PS = UartCoding.bParityType;
U2LCR_bit.DLAB = 1;
U2DLL = Div & 0xFF;
U2DLM = (Div >> 8) & 0xFF;
U2FDR = AddDiv + (Mul << 4);
U2LCR_bit.DLAB = 0;
break;
case UART_3:
Freq = SYS_GetFpclk(UART3_PCLK_OFFSET);
UartCalcDivider(Freq,UartCoding.dwDTERate,&Div,&AddDiv,&Mul);
U3LCR_bit.WLS = UartCoding.bDataBits;
U3LCR_bit.SBS = UartCoding.bStopBitsFormat;
U3LCR_bit.PE =(UartCoding.bParityType == UART_NO_PARITY)?0:1;
U3LCR_bit.PS = UartCoding.bParityType;
U3LCR_bit.DLAB = 1;
U3DLL = Div & 0xFF;
U3DLM = (Div >> 8) & 0xFF;
U3FDR = AddDiv + (Mul << 4);
U3LCR_bit.DLAB = 0;
break;
}
}
/*************************************************************************
* Function Name: UartRead
* Parameters: UartNum_t Uart, pInt8U pBuffer, Int32U BufferSize
*
* Return: Int32U
*
* Description: Read received data from UART.
* Return number of readied characters
*
*************************************************************************/
Int32U UartRead(UartNum_t Uart, pInt8U pBuffer, Int32U BufferSize)
{
Int32U Count;
pUartFifo_t pUartFifo;
switch (Uart)
{
case UART_0:
pUartFifo= pUart0RxFifo;
break;
case UART_1:
pUartFifo= pUart1RxFifo;
break;
case UART_2:
pUartFifo= pUart2RxFifo;
break;
case UART_3:
pUartFifo= pUart3RxFifo;
break;
default:
return(0);
}
for (Count = 0; Count < BufferSize; ++Count)
{
if(!FifoPop(pUartFifo,pBuffer+Count))
{
break;
}
}
return(Count);
}
/*************************************************************************
* Function Name: UartWrite
* Parameters: UartNum_t Uart, pInt8U pBuffer, Int32U BufferSize
*
* Return: Int32U
*
* Description: Write a data to UART. Return number of successful
* transmitted bytes
*
*************************************************************************/
Int32U UartWrite(UartNum_t Uart, pInt8U pBuffer, Int32U BufferSize)
{
Int32U Count = 0;
pUartFifo_t pUartFifo;
Int32U save;
switch (Uart)
{
case UART_0:
pUartFifo= pUart0TxFifo;
break;
case UART_1:
pUartFifo= pUart1TxFifo;
break;
case UART_2:
pUartFifo= pUart2TxFifo;
break;
case UART_3:
pUartFifo= pUart3TxFifo;
break;
default:
return(0);
}
if(BufferSize != 0)
{
volatile pInt8U pUartTxReg;
save = __get_interrupt_state();
__disable_interrupt();
if((pUartFifo->PushIndx == pUartFifo->PopIndx))
{
// The Tx FIFO is empty
switch (Uart)
{
case UART_0:
pUartTxReg = (pInt8U)&U0THR;
if(U0LSR_bit.THRE)
{
*pUartTxReg = *pBuffer;
++Count;
}
break;
case UART_1:
pUartTxReg = (pInt8U)&U1THR;
if(U1LSR_bit.THRE)
{
*pUartTxReg = *pBuffer;
++Count;
}
break;
case UART_2:
pUartTxReg = (pInt8U)&U2THR;
if(U2LSR_bit.THRE)
{
*pUartTxReg = *pBuffer;
++Count;
}
break;
case UART_3:
pUartTxReg = (pInt8U)&U3THR;
if(U3LSR_bit.THRE)
{
*pUartTxReg = *pBuffer;
++Count;
}
break;
}
}
for ( ; Count < BufferSize; ++Count)
{
if(!FifoPush(pUartFifo,*(pBuffer+Count)))
{
break;
}
}
__set_interrupt_state(save);
}
return(Count);
}
/*************************************************************************
* Function Name: UartGetUartEvents
* Parameters: UartNum_t Uart
*
* Return: UartLineEvents_t
*
* Description: Get Uart Line events (PE,OE, FE, BI)
*
*************************************************************************/
UartLineEvents_t UartGetUartLineEvents (UartNum_t Uart)
{
UartLineEvents_t LineEvents;
LineEvents.Data = 0;
switch (Uart)
{
case UART_0:
AtomicExchange(LineEvents.Data,&Uart0LineEvents.Data);
break;
case UART_1:
AtomicExchange(LineEvents.Data,&Uart1LineEvents.Data);
break;
case UART_2:
AtomicExchange(LineEvents.Data,&Uart2LineEvents.Data);
break;
case UART_3:
AtomicExchange(LineEvents.Data,&Uart3LineEvents.Data);
break;
default:
LineEvents.Data = 0;
}
return(LineEvents);
}
/*************************************************************************
* Function Name: UartSetUartLineState
* Parameters: UartNum_t Uart UartNum_t Uart, Boolean Break
*
* Return: none
*
* Description: Set Uart Break Event
*
*************************************************************************/
void UartSetUartLineState (UartNum_t Uart, Boolean Break)
{
switch (Uart)
{
case UART_0:
U0LCR_bit.BC = Break;
break;
case UART_1:
U1LCR_bit.BC = Break;
break;
case UART_2:
U2LCR_bit.BC = Break;
break;
case UART_3:
U3LCR_bit.BC = Break;
}
}
#if UART1_MODEM_STAT_ENA > 0
/*************************************************************************
* Function Name: Uart1SetModemLineState
* Parameters: UartModemLineState_t UartModemLineState
*
* Return: none
*
* Description: Init UART1 Modem lines state (RTS, DTR)
*
*************************************************************************/
void Uart1SetModemLineState(UartModemLineState_t UartModemLineState)
{
U1MCR_bit.DTR = UartModemLineState.bDTR;
U1MCR_bit.RTS = UartModemLineState.bRTS;
}
/*************************************************************************
* Function Name: Uart1GetUartModemEvents
* Parameters: none
*
* Return: UartModemEvents_t
*
* Description: Get Uart1 Modem lines events (DCD,DSR,CTS,RI)
*
*************************************************************************/
UartModemEvents_t Uart1GetUartModemEvents (void)
{
UartModemEvents_t ModemEvents;
ModemEvents.Data = 0;
ModemEvents.Data = AtomicExchange(ModemEvents.Data,(pInt32U)&Uart1ModemEvents);
return(ModemEvents);
}
#endif // UART1_MODEM_STAT_ENA > 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -