uart.c
字号:
/*************************************************************************
*
* Used with ICCARM and AARM.
*
* (c) Copyright IAR Systems 2006
*
* File name : uart.c
* Description : UARTs module
*
* History :
* 1. Date : August 11, 2006
* Author : Stanimir Bonev
* Description : Create
*
* $Revision: 15135 $
**************************************************************************/
#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;
IndxTmp = IndxTmp % UART_FIFO_SIZE;
// 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;
IndxTmp = IndxTmp % UART_FIFO_SIZE;
// 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;
// Recognize the interrupt event
UartInt = UART0->MIS;
if(UartInt & 0x07D0)
{
UART_ClearITPendingBit(UART0,(UartInt & 0x07D0));
// Read the line state of the UART
LineStatus = UART0->RSR;
if(LineStatus & RLS_OverrunError)
{
// Overrun Error
Uart0LineEvents.bOE = TRUE;
}
Data = UART0->DR;
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;
}
// Read the line state of the UART
LineStatus = UART0->RSR;
}
if(UartInt & 0x0020)
{
UART_ClearITPendingBit(UART0,0x0020);
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;
}
}
}
/*************************************************************************
* Function Name: Uart1Isr
* Parameters: none
*
* Return: none
*
* Description: UART 1 interrupt routine
*
*************************************************************************/
void Uart1Isr(void)
{
Int32U UartInt, LineStatus, Counter;
Int8U Data;
// Recognize the interrupt event
UartInt = UART1->MIS;
if(UartInt & 0x07D0)
{
UART_ClearITPendingBit(UART1,(UartInt & 0x07D0));
// Read the line state of the UART
LineStatus = UART1->RSR;
if(LineStatus & RLS_OverrunError)
{
// Overrun Error
Uart1LineEvents.bOE = TRUE;
}
Data = UART1->DR;
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;
}
// Read the line state of the UART
LineStatus = UART1->RSR;
}
if(UartInt & 0x0020)
{
UART_ClearITPendingBit(UART1,0x0020);
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;
}
}
}
/*************************************************************************
* Function Name: Uart2Isr
* Parameters: none
*
* Return: none
*
* Description: UART 2 interrupt routine
*
*************************************************************************/
void Uart2Isr(void)
{
Int32U UartInt, LineStatus, Counter;
Int8U Data;
// Recognize the interrupt event
UartInt = UART2->MIS;
if(UartInt & 0x07D0)
{
UART_ClearITPendingBit(UART2,(UartInt & 0x07D0));
// Read the line state of the UART
LineStatus = UART2->RSR;
if(LineStatus & RLS_OverrunError)
{
// Overrun Error
Uart2LineEvents.bOE = TRUE;
}
Data = UART2->DR;
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;
}
// Read the line state of the UART
LineStatus = UART2->RSR;
}
if(UartInt & 0x0020)
{
UART_ClearITPendingBit(UART2,0x0020);
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;
}
}
}
/*************************************************************************
* Function Name: UartInit
* Parameters: Int32U IrqSlot
*
* Return: Boolean
*
* Description: Init UART
*
*************************************************************************/
Boolean UartInit(UartNum_t Uart,Int32U IrqSlot)
{
GPIO_InitTypeDef GPIO_InitStructure;
UART_InitTypeDef UART_InitStructure;
EIC_IRQInitTypeDef EIC_IRQInitStructure;
volatile Int8U Tmp;
// Enable GPIO clocks
MRCC_PeripheralClockConfig(MRCC_Peripheral_GPIO, ENABLE);
// Release GPIO reset
MRCC_PeripheralSWResetConfig(MRCC_Peripheral_GPIO,DISABLE);
UART_StructInit(&UART_InitStructure);
UART_InitStructure.UART_Parity = UART_Parity_No;
switch(Uart)
{
case UART_0:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -