📄 uart.c
字号:
//****************************************************************************
//
// UART.C - Routines for enabling the UARTs and sending/receiving data via
// them
//
// Copyright (c) 1998-1999 Cirrus Logic, Inc.
//
//****************************************************************************
#include "ep7312.h"
#include "lib7312.h"
//****************************************************************************
//
// The following variables indicate which of the UARTs are currently
// configured. This is used to prevent a configured UART from being
// reconfigured while it is being used.
//
//****************************************************************************
long lPort1Enabled = 0;
long lPort2Enabled = 1;
//****************************************************************************
//
// The following variables contain the send and receive buffers for UART1 and
// UART2. The buffers are serviced by the interrupt handler for the UART.
//
//****************************************************************************
#define SIZE 64
static char pcPort1TxData[SIZE], pcPort1RxData[SIZE];
static char pcPort2TxData[SIZE], pcPort2RxData[SIZE];
static int iPort1TxRead = 0, iPort1TxWrite = 0;
static int iPort1RxRead = 0, iPort1RxWrite = 0;
static int iPort2TxRead = 0, iPort2TxWrite = 0;
static int iPort2RxRead = 0, iPort2RxWrite = 0;
//****************************************************************************
//
// UART1ISR is the interrupt handler for UART1. It takes care of keeping the
// transmit FIFO full and the receive FIFO empty.
//
//****************************************************************************
void
UART1ISR(void)
{
unsigned long * volatile pulPtr = (unsigned long *)HwBaseAddress;
long lIntStatus;
//
// Determine which interrupt(s) the UART is currently asserting.
//
lIntStatus = pulPtr[HwIntStatus >> 2];
//
// Handle the Tx interrupt.
//
if(lIntStatus & HwIrqUartTx)
{
//
// Try to copy all the data out of the transmit buffer to the UART's
// FIFO.
//
while(iPort1TxRead != iPort1TxWrite)
{
//
// Stop if there is no more space in the transmit FIFO.
//
if(pulPtr[HwStatus >> 2] & HwStatusUartTxFifoFull)
{
break;
}
//
// Write the next character to the UART.
//
pulPtr[HwUartData >> 2] = pcPort1TxData[iPort1TxRead];
//
// Skip to the next character in the buffer.
//
iPort1TxRead = (iPort1TxRead + 1) & (SIZE - 1);
}
//
// If we've sent all the data from the transmit buffer, then disable
// the UART Tx interrupt.
//
if(iPort1TxRead == iPort1TxWrite)
{
pulPtr[HwIntMask >> 2] &= ~HwIrqUartTx;
}
}
//
// Handle the Rx interrupt.
//
if(lIntStatus & HwIrqUartRx)
{
//
// Copy all the data from the UART's receive FIFO.
//
while(!(pulPtr[HwStatus >> 2] & HwStatusUartRxFifoEmpty))
{
//
// Read the next character from the UART.
//
pcPort1RxData[iPort1RxWrite] = pulPtr[HwUartData >> 2] & 0xff;
//
// Skip to the next character in the buffer.
//
iPort1RxWrite = (iPort1RxWrite + 1) & (SIZE - 1);
}
}
}
//****************************************************************************
//
// UART2ISR is the interrupt handler for UART2. It takes care of keeping the
// transmit FIFO full and the receive FIFO empty.
//
//****************************************************************************
void
UART2ISR(void)
{
unsigned long * volatile pulPtr = (unsigned long *)HwBaseAddress;
long lIntStatus;
//
// Determine which interrupt(s) the UART is currently asserting.
//
lIntStatus = pulPtr[HwIntStatus2 >> 2];
//
// Handle the Tx interrupt.
//
if(lIntStatus & HwIrqUartTx)
{
//
// Try to copy all the data out of the transmit buffer to the UART's
// FIFO.
//
while(iPort2TxRead != iPort2TxWrite)
{
//
// Stop if there is no more space in the transmit FIFO.
//
if(pulPtr[HwStatus2 >> 2] & HwStatusUartTxFifoFull)
{
break;
}
//
// Write the next character to the UART.
//
pulPtr[HwUart2Data >> 2] = pcPort2TxData[iPort2TxRead];
//
// Skip to the next character in the buffer.
//
iPort2TxRead = (iPort2TxRead + 1) & (SIZE - 1);
}
//
// If we've sent all the data from the transmit buffer, then disable
// the UART Tx interrupt.
//
if(iPort2TxRead == iPort2TxWrite)
{
pulPtr[HwIntMask2 >> 2] &= ~HwIrqUartTx;
}
}
//
// Handle the Rx interrupt.
//
if(lIntStatus & HwIrqUartRx)
{
((unsigned char *)pulPtr)[HwPortB] |= 0x08;
//
// Copy all the data from the UART's receive FIFO.
//
while(!(pulPtr[HwStatus2 >> 2] & HwStatusUartRxFifoEmpty))
{
//
// Read the next character from the UART.
//
pcPort2RxData[iPort2RxWrite] = pulPtr[HwUart2Data >> 2] & 0xff;
//
// Skip to the next character in the buffer.
//
iPort2RxWrite = (iPort2RxWrite + 1) & (SIZE - 1);
}
((unsigned char *)pulPtr)[HwPortB] &= ~0x08;
}
}
//****************************************************************************
//
// UARTEnable will configure the specified UART and enable it for operation.
//
//****************************************************************************
long
UARTEnable(long lPort, long lDataRate, long lDataBits, long lStopBits,
long lParity, long lEvenParity)
{
unsigned long * volatile pulPtr = (unsigned long *)HwBaseAddress;
long lRates[12] = { 115200, 76800, 57600, 38400, 28800, 19200, 14400, 9600,
4800, 2400, 1200, 110 };
long lDivisors[12] = { 1, 2, 3, 5, 7, 11, 15, 23, 47, 95, 191, 2094 };
long lIdx, lConfig;
//
// Make sure that a valid UART port was specified.
//
if(lPort == 1)
{
//
// Do not configure UART1 if it is already enabled.
//
if(lPort1Enabled)
{
return(0);
}
}
else if(lPort == 2)
{
//
// Do not configure UART2 if it is already enabled.
//
if(lPort2Enabled)
{
return(0);
}
}
else
{
return(0);
}
//
// Check for a valid data rate.
//
for(lIdx = 0; lIdx < 12; lIdx++)
{
if(lRates[lIdx] == lDataRate)
{
break;
}
}
if(lIdx == 12)
{
return(0);
}
lConfig = lDivisors[lIdx];
//
// Check for a valid number of data bits.
//
switch(lDataBits)
{
case 5:
{
lConfig |= HwUartControlDataLength5;
break;
}
case 6:
{
lConfig |= HwUartControlDataLength6;
break;
}
case 7:
{
lConfig |= HwUartControlDataLength7;
break;
}
case 8:
{
lConfig |= HwUartControlDataLength8;
break;
}
default:
{
return(0);
}
}
//
// Check for a valid number of stop bits.
//
if(lStopBits == 2)
{
lConfig |= HwUartControlTwoStopBits;
}
else if(lStopBits != 1)
{
return(0);
}
//
// Set the parity as specified.
//
if(lParity)
{
//
// Parity was requested, so enable parity.
//
lConfig |= HwUartControlParityEnable;
//
// See if even parity was requested.
//
if(lEvenParity)
{
//
// Change the parity to even (the default is odd).
//
lConfig |= HwUartControlParityEven;
}
}
//
// Configure and enable the appropriate UART.
//
if(lPort == 1)
{
//
// Turn off RTS.
//
((unsigned char *)pulPtr)[HwPortB] &= ~HwPortBRTS;
//
// Turn on UART1.
//
pulPtr[HwControl >> 2] |= HwControlUartEnable;
//
// Configure UART1.
//
pulPtr[HwUartControl >> 2] = lConfig | HwUartControlFifoEnable;
//
// Clear the local FIFO buffers.
//
iPort1TxRead = iPort1TxWrite = 0;
iPort1RxRead = iPort1RxWrite = 0;
//
// Install the ISR so that we can process the UART interrupt.
//
InterruptInstallIRQ();
//
// Install the UART1 interrupt handler.
//
InterruptSetUART1Handler(UART1ISR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -