📄 uart.c
字号:
/*************************************************************************
*
* Used with ICCARM and AARM.
*
* (c) Copyright IAR Systems 2006
*
* File name : uart.c
* Description : UARTs module
*
* History :
* 1. Date : October 2, 2006
* Author : Stanimir Bonev
* Description : Create
*
* $Revision: 16170 $
**************************************************************************/
#define UART_GLOBAL
#include "uart.h"
pUartFifo_t pUart0RxFifo; // Pointer to a FIFO Buffer of the UART0 Receive
pUartFifo_t pUart0TxFifo; // Pointer to a FIFO Buffer of the UART0 Transmit
pUartFifo_t pUart1RxFifo; // Pointer to a FIFO Buffer of the UART1 Receive
pUartFifo_t pUart1TxFifo; // Pointer to a FIFO Buffer of the UART1 Transmit
pUartFifo_t pUart2RxFifo; // Pointer to a FIFO Buffer of the UART2 Receive
pUartFifo_t pUart2TxFifo; // Pointer to a FIFO Buffer of the UART2 Transmit
// Hold UART0 Evens (PE, BI, FE, OE)
UartLineEvents_t Uart0LineEvents;
// Hold UART1 Evens (PE, BI, FE, OE)
UartLineEvents_t Uart1LineEvents;
// Hold UART2 Evens (PE, BI, FE, OE)
UartLineEvents_t Uart2LineEvents;
/*************************************************************************
* Function Name: FifoPush
* Parameters: pUartFifo_t Fifo, Int8U Data
*
* Return: Boolean
*
* Description: Push a char in a FIFO. Return TRUE when push is successful
* or FALSE when the FIFO is full.
*
*************************************************************************/
static Boolean FifoPush(pUartFifo_t Fifo, Int8U Data)
{
Int32U IndxTmp;
// calculate next push index
IndxTmp = Fifo->PushIndx + 1;
if(IndxTmp >= UART_FIFO_SIZE)
{
IndxTmp = 0;
}
// Check FIFO state
if (IndxTmp == Fifo->PopIndx)
{
// The FIFO is full
return(FALSE);
}
// Push the data
Fifo->Buffer[Fifo->PushIndx] = Data;
// Updating the push's index
Fifo->PushIndx = IndxTmp;
return(TRUE);
}
/*************************************************************************
* Function Name: FifoPop
* Parameters: pUartFifo_t Fifo, Int8U Data
*
* Return: Boolean
*
* Description: Pop a char from a FIFO. Return TRUE when pop is successful
* or FALSE when the FIFO is empty.
*
*************************************************************************/
static Boolean FifoPop(pUartFifo_t Fifo, pInt8U pData)
{
Int32U IndxTmp;
// Check FIFO state
if (Fifo->PushIndx == Fifo->PopIndx)
{
// The FIFO is empty
return(FALSE);
}
// Calculate the next pop index
IndxTmp = Fifo->PopIndx + 1;
if(IndxTmp >= UART_FIFO_SIZE)
{
IndxTmp = 0;
}
// Pop the data
*pData = Fifo->Buffer[Fifo->PopIndx];
// Updating of the pop's index
Fifo->PopIndx = IndxTmp;
return(TRUE);
}
/*************************************************************************
* Function Name: Uart0Isr
* Parameters: none
*
* Return: none
*
* Description: UART 0 interrupt routine
*
*************************************************************************/
void Uart0Isr(void)
{
Int32U UartInt, LineStatus, Counter;
Int8U Data;
Int32U Save;
Save = __get_interrupt_state();
__disable_interrupt();
// Recognize the interrupt event
UartInt = UART0->MIS;
if(UartInt & (UART_IT_ReceiveTimeOut | UART_IT_Receive |
UART_IT_OverrunError | UART_IT_BreakError |
UART_IT_ParityError | UART_IT_FrameError))
{
do
{
UART_ClearITPendingBit(UART0,UART_IT_ReceiveTimeOut | UART_IT_Receive |
UART_IT_OverrunError | UART_IT_BreakError |
UART_IT_ParityError | UART_IT_FrameError);
// Read the line state of the UART
LineStatus = UART0->RSECR;
if(LineStatus & RLS_OverrunError)
{
// Overrun Error
Uart0LineEvents.bOE = TRUE;
}
Data = UART0->DR;
// Read the line state of the UART
LineStatus = UART0->RSECR;
if (LineStatus & RLS_BreakInterruptr)
{
// Break Indicator
Uart0LineEvents.bBI = TRUE;
}
else if (LineStatus & RLS_FramingError)
{
// Framing Error
Uart0LineEvents.bFE = TRUE;
}
else if (LineStatus & RLS_ParityError)
{
// Parity Error
Uart0LineEvents.bPE = TRUE;
}
// Push a new data into the receiver buffer
if(!FifoPush(pUart0RxFifo,Data))
{
// the FIFO is full
Uart0LineEvents.bOE = TRUE;
break;
}
}
while(UART_GetFlagStatus(UART0, UART_FLAG_RxFIFOEmpty) == RESET);
}
if(UartInt & UART_IT_Transmit)
{
UART_ClearITPendingBit(UART0,UART_IT_Transmit);
Counter = 1;
if(UART0->LCR & 1UL << 4)
{
switch (UART0->IFLS & 0x7)
{
case 0:
Counter = 7;
break;
case 1:
Counter = 5;
break;
case 2:
Counter = 3;
break;
}
}
for( ;Counter; --Counter)
{
// Pop a data from the transmit buffer
if(!FifoPop(pUart0TxFifo,&Data))
{
// The tx software FIFO is empty
break;
}
UART0->DR = Data;
}
}
__set_interrupt_state(Save);
}
/*************************************************************************
* Function Name: Uart1Isr
* Parameters: none
*
* Return: none
*
* Description: UART 1 interrupt routine
*
*************************************************************************/
void Uart1Isr(void)
{
Int32U UartInt, LineStatus, Counter;
Int8U Data;
Int32U Save;
Save = __get_interrupt_state();
__disable_interrupt();
// Recognize the interrupt event
UartInt = UART1->MIS;
if(UartInt & (UART_IT_ReceiveTimeOut | UART_IT_Receive |
UART_IT_OverrunError | UART_IT_BreakError |
UART_IT_ParityError | UART_IT_FrameError))
{
do
{
UART_ClearITPendingBit(UART1,UART_IT_ReceiveTimeOut | UART_IT_Receive |
UART_IT_OverrunError | UART_IT_BreakError |
UART_IT_ParityError | UART_IT_FrameError);
// Read the line state of the UART
LineStatus = UART1->RSECR;
if(LineStatus & RLS_OverrunError)
{
// Overrun Error
Uart1LineEvents.bOE = TRUE;
}
Data = UART1->DR;
// Read the line state of the UART
LineStatus = UART1->RSECR;
if (LineStatus & RLS_BreakInterruptr)
{
// Break Indicator
Uart1LineEvents.bBI = TRUE;
}
else if (LineStatus & RLS_FramingError)
{
// Framing Error
Uart1LineEvents.bFE = TRUE;
}
else if (LineStatus & RLS_ParityError)
{
// Parity Error
Uart1LineEvents.bPE = TRUE;
}
// Push a new data into the receiver buffer
if(!FifoPush(pUart1RxFifo,Data))
{
// the FIFO is full
Uart1LineEvents.bOE = TRUE;
break;
}
}
while(UART_GetFlagStatus(UART1, UART_FLAG_RxFIFOEmpty) == RESET);
}
if(UartInt & UART_IT_Transmit)
{
UART_ClearITPendingBit(UART1,UART_IT_Transmit);
Counter = 1;
if(UART1->LCR & 1UL << 4)
{
switch (UART1->IFLS & 0x7)
{
case 0:
Counter = 7;
break;
case 1:
Counter = 5;
break;
case 2:
Counter = 3;
break;
}
}
for( ;Counter; --Counter)
{
// Pop a data from the transmit buffer
if(!FifoPop(pUart1TxFifo,&Data))
{
// The tx software FIFO is empty
break;
}
UART1->DR = Data;
}
}
__set_interrupt_state(Save);
}
/*************************************************************************
* Function Name: Uart2Isr
* Parameters: none
*
* Return: none
*
* Description: UART 2 interrupt routine
*
*************************************************************************/
void Uart2Isr(void)
{
Int32U UartInt, LineStatus, Counter;
Int8U Data;
Int32U Save;
Save = __get_interrupt_state();
__disable_interrupt();
// Recognize the interrupt event
UartInt = UART2->MIS;
if(UartInt & (UART_IT_ReceiveTimeOut | UART_IT_Receive |
UART_IT_OverrunError | UART_IT_BreakError |
UART_IT_ParityError | UART_IT_FrameError))
{
do
{
UART_ClearITPendingBit(UART2,UART_IT_ReceiveTimeOut | UART_IT_Receive |
UART_IT_OverrunError | UART_IT_BreakError |
UART_IT_ParityError | UART_IT_FrameError);
// Read the line state of the UART
LineStatus = UART2->RSECR;
if(LineStatus & RLS_OverrunError)
{
// Overrun Error
Uart2LineEvents.bOE = TRUE;
}
Data = UART2->DR;
// Read the line state of the UART
LineStatus = UART2->RSECR;
if (LineStatus & RLS_BreakInterruptr)
{
// Break Indicator
Uart2LineEvents.bBI = TRUE;
}
else if (LineStatus & RLS_FramingError)
{
// Framing Error
Uart2LineEvents.bFE = TRUE;
}
else if (LineStatus & RLS_ParityError)
{
// Parity Error
Uart2LineEvents.bPE = TRUE;
}
// Push a new data into the receiver buffer
if(!FifoPush(pUart2RxFifo,Data))
{
// the FIFO is full
Uart2LineEvents.bOE = TRUE;
break;
}
}
while(UART_GetFlagStatus(UART2, UART_FLAG_RxFIFOEmpty) == RESET);
}
if(UartInt & UART_IT_Transmit)
{
UART_ClearITPendingBit(UART2,UART_IT_Transmit);
Counter = 1;
if(UART2->LCR & 1UL << 4)
{
switch (UART2->IFLS & 0x7)
{
case 0:
Counter = 7;
break;
case 1:
Counter = 5;
break;
case 2:
Counter = 3;
break;
}
}
for( ;Counter; --Counter)
{
// Pop a data from the transmit buffer
if(!FifoPop(pUart2TxFifo,&Data))
{
// The tx software FIFO is empty
break;
}
UART2->DR = Data;
}
}
__set_interrupt_state(Save);
}
/*************************************************************************
* Function Name: UartInit
* Parameters: Int32U IntrPriority
*
* Return: Boolean
*
* Description: Init UART
*
*************************************************************************/
Boolean UartInit(UartNum_t Uart,Int32U IntrPriority)
{
GPIO_InitTypeDef GPIO_InitStructure;
UART_InitTypeDef UART_InitStructure;
volatile Int8U Tmp;
UART_StructInit(&UART_InitStructure);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -