⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 Cirrus Logic EP7312处理器部分控制程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
//****************************************************************************
//
// 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 + -