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

📄 ethernet.c

📁 基于TI公司Cortex-M3的uart超级通信开发
💻 C
📖 第 1 页 / 共 3 页
字号:
//
//*****************************************************************************
tBoolean
EthernetPacketAvail(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(ulBase == ETH_BASE);

    //
    // Return the availability of packets.
    //
    return((HWREG(ulBase + MAC_O_NP) & MAC_NP_NPR_M) ? true : false);
}

//*****************************************************************************
//
//! Checks for packet space available in the Ethernet controller.
//!
//! \param ulBase is the base address of the controller.
//!
//! The Ethernet controller's transmit FIFO is designed to support a single
//! packet at a time.  After the packet has been written into the FIFO, the
//! transmit request bit must be set to enable the transmission of the packet.
//! Only after the packet has been transmitted can a new packet be written
//! into the FIFO.  This function will simply check to see if a packet is
//! in progress.  If so, there is no space available in the transmit FIFO.
//!
//! \return Returns \b true if a space is available in the transmit FIFO, and
//! \b false otherwise.
//
//*****************************************************************************
tBoolean
EthernetSpaceAvail(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(ulBase == ETH_BASE);

    //
    // Return the availability of space.
    //
    return((HWREG(ulBase + MAC_O_TR) & MAC_TR_NEWTX) ? false : true);
}

//*****************************************************************************
//
//! \internal
//!
//! Internal function for reading a packet from the Ethernet controller.
//!
//! \param ulBase is the base address of the controller.
//! \param pucBuf is the pointer to the packet buffer.
//! \param lBufLen is the maximum number of bytes to be read into the buffer.
//!
//! Based on the following table of how the receive frame is stored in the
//! receive FIFO, this function will extract a packet from the FIFO and store
//! it in the packet buffer that was passed in.
//!
//! Format of the data in the RX FIFO is as follows:
//!
//! \verbatim
//! +---------+----------+----------+----------+----------+
//! |         | 31:24    | 23:16    | 15:8     | 7:0      |
//! +---------+----------+----------+----------+----------+
//! | Word 0  | DA 2     | DA 1     | FL MSB   | FL LSB   |
//! +---------+----------+----------+----------+----------+
//! | Word 1  | DA 6     | DA 5     | DA 4     | DA 3     |
//! +---------+----------+----------+----------+----------+
//! | Word 2  | SA 4     | SA 3     | SA 2     | SA 1     |
//! +---------+----------+----------+----------+----------+
//! | Word 3  | FT LSB   | FT MSB   | SA 6     | SA 5     |
//! +---------+----------+----------+----------+----------+
//! | Word 4  | DATA 4   | DATA 3   | DATA 2   | DATA 1   |
//! +---------+----------+----------+----------+----------+
//! | Word 5  | DATA 8   | DATA 7   | DATA 6   | DATA 5   |
//! +---------+----------+----------+----------+----------+
//! | Word 6  | DATA 12  | DATA 11  | DATA 10  | DATA 9   |
//! +---------+----------+----------+----------+----------+
//! | ...     |          |          |          |          |
//! +---------+----------+----------+----------+----------+
//! | Word X  | DATA n   | DATA n-1 | DATA n-2 | DATA n-3 |
//! +---------+----------+----------+----------+----------+
//! | Word Y  | FCS 4    | FCS 3    | FCS 2    | FCS 1    |
//! +---------+----------+----------+----------+----------+
//! \endverbatim
//!
//! Where FL is Frame Length, (FL + DA + SA + FT + DATA + FCS) Bytes.
//! Where DA is Destination (MAC) Address.
//! Where SA is Source (MAC) Address.
//! Where FT is Frame Type (or Frame Length for Ethernet).
//! Where DATA is Payload Data for the Ethernet Frame.
//! Where FCS is the Frame Check Sequence.
//!
//! \return Returns the negated packet length \b -n if the packet is too large
//! for \e pucBuf, and returns the packet length \b n otherwise.
//
//*****************************************************************************
static long
EthernetPacketGetInternal(unsigned long ulBase, unsigned char *pucBuf,
                          long lBufLen)
{
    unsigned long ulTemp;
    long lFrameLen, lTempLen;
    long i = 0;

    //
    // Read WORD 0 (see format above) from the FIFO, set the receive
    // Frame Length and store the first two bytes of the destination
    // address in the receive buffer.
    //
    ulTemp = HWREG(ulBase + MAC_O_DATA);
    lFrameLen = (long)(ulTemp & 0xFFFF);
    pucBuf[i++] = (unsigned char) ((ulTemp >> 16) & 0xff);
    pucBuf[i++] = (unsigned char) ((ulTemp >> 24) & 0xff);

    //
    // Read all but the last WORD into the receive buffer.
    //
    lTempLen = (lBufLen < (lFrameLen - 6)) ? lBufLen : (lFrameLen - 6);
    while(i <= (lTempLen - 4))
    {
        *(unsigned long *)&pucBuf[i] = HWREG(ulBase + MAC_O_DATA);
        i += 4;
    }

    //
    // Read the last 1, 2, or 3 BYTES into the buffer
    //
    if(i < lTempLen)
    {
        ulTemp = HWREG(ulBase + MAC_O_DATA);
        if(i == lTempLen - 3)
        {
            pucBuf[i++] = ((ulTemp >>  0) & 0xff);
            pucBuf[i++] = ((ulTemp >>  8) & 0xff);
            pucBuf[i++] = ((ulTemp >> 16) & 0xff);
            i += 1;
        }
        else if(i == lTempLen - 2)
        {
            pucBuf[i++] = ((ulTemp >>  0) & 0xff);
            pucBuf[i++] = ((ulTemp >>  8) & 0xff);
            i += 2;
        }
        else if(i == lTempLen - 1)
        {
            pucBuf[i++] = ((ulTemp >>  0) & 0xff);
            i += 3;
        }
    }

    //
    // Read any remaining WORDS (that did not fit into the buffer).
    //
    while(i < (lFrameLen - 2))
    {
        ulTemp = HWREG(ulBase + MAC_O_DATA);
        i += 4;
    }

    //
    // If frame was larger than the buffer, return the "negative" frame length
    //
    lFrameLen -= 6;
    if(lFrameLen > lBufLen)
    {
        return(-lFrameLen);
    }

    //
    // Return the Frame Length
    //
    return(lFrameLen);
}

//*****************************************************************************
//
//! Receives a packet from the Ethernet controller.
//!
//! \param ulBase is the base address of the controller.
//! \param pucBuf is the pointer to the packet buffer.
//! \param lBufLen is the maximum number of bytes to be read into the buffer.
//!
//! This function reads a packet from the receive FIFO of the controller and
//! places it into \e pucBuf.  If no packet is available the function will
//! return immediately.  Otherwise, the function will read the entire packet
//! from the receive FIFO.  If there are more bytes in the packet than will fit
//! into \e pucBuf (as specified by \e lBufLen), the function will return the
//! negated length of the packet and the buffer will contain \e lBufLen bytes
//! of the packet.  Otherwise, the function will return the length of the
//! packet that was read and \e pucBuf will contain the entire packet
//! (excluding the frame check sequence bytes).
//!
//! This function replaces the original EthernetPacketNonBlockingGet() API and
//! performs the same actions.  A macro is provided in <tt>ethernet.h</tt> to
//! map the original API to this API.
//!
//! \note This function will return immediately if no packet is available.
//!
//! \return Returns \b 0 if no packet is available, the negated packet length
//! \b -n if the packet is too large for \e pucBuf, and the packet length \b n
//! otherwise.
//
//*****************************************************************************
long
EthernetPacketGetNonBlocking(unsigned long ulBase, unsigned char *pucBuf,
                             long lBufLen)
{
    //
    // Check the arguments.
    //
    ASSERT(ulBase == ETH_BASE);
    ASSERT(pucBuf != 0);
    ASSERT(lBufLen > 0);

    //
    // Check to see if any packets are available.
    //
    if((HWREG(ulBase + MAC_O_NP) & MAC_NP_NPR_M) == 0)
    {
        return(0);
    }

    //
    // Read the packet, and return.
    //
    return(EthernetPacketGetInternal(ulBase, pucBuf, lBufLen));
}

//*****************************************************************************
//
//! Waits for a packet from the Ethernet controller.
//!
//! \param ulBase is the base address of the controller.
//! \param pucBuf is the pointer to the packet buffer.
//! \param lBufLen is the maximum number of bytes to be read into the buffer.
//!
//! This function reads a packet from the receive FIFO of the controller and
//! places it into \e pucBuf.  The function will wait until a packet is
//! available in the FIFO.  Then the function will read the entire packet
//! from the receive FIFO.  If there are more bytes in the packet than will
//! fit into \e pucBuf (as specified by \e lBufLen), the function will return
//! the negated length of the packet and the buffer will contain \e lBufLen
//! bytes of the packet.  Otherwise, the function will return the length of
//! the packet that was read and \e pucBuf will contain the entire packet
//! (excluding the frame check sequence bytes).
//!
//! \note This function is blocking and will not return until a packet arrives.
//!
//! \return Returns the negated packet length \b -n if the packet is too large
//! for \e pucBuf, and returns the packet length \b n otherwise.
//
//*****************************************************************************
long
EthernetPacketGet(unsigned long ulBase, unsigned char *pucBuf,
                  long lBufLen)
{
    //
    // Check the arguments.
    //
    ASSERT(ulBase == ETH_BASE);
    ASSERT(pucBuf != 0);
    ASSERT(lBufLen > 0);

    //
    // Wait for a packet to become available
    //
    while((HWREG(ulBase + MAC_O_NP) & MAC_NP_NPR_M) == 0)
    {
    }

    //
    // Read the packet
    //
    return(EthernetPacketGetInternal(ulBase, pucBuf, lBufLen));
}

//*****************************************************************************
//
//! \internal
//!
//! Internal function for sending a packet to the Ethernet controller.
//!
//! \param ulBase is the base address of the controller.
//! \param pucBuf is the pointer to the packet buffer.
//! \param lBufLen is number of bytes in the packet to be transmitted.
//!
//! Puts a packet into the transmit FIFO of the controller.
//!
//! Format of the data in the TX FIFO is as follows:
//!
//! \verbatim
//! +---------+----------+----------+----------+----------+
//! |         | 31:24    | 23:16    | 15:8     | 7:0      |
//! +---------+----------+----------+----------+----------+
//! | Word 0  | DA 2     | DA 1     | PL MSB   | PL LSB   |
//! +---------+----------+----------+----------+----------+
//! | Word 1  | DA 6     | DA 5     | DA 4     | DA 3     |
//! +---------+----------+----------+----------+----------+
//! | Word 2  | SA 4     | SA 3     | SA 2     | SA 1     |
//! +---------+----------+----------+----------+----------+
//! | Word 3  | FT LSB   | FT MSB   | SA 6     | SA 5     |
//! +---------+----------+----------+----------+----------+
//! | Word 4  | DATA 4   | DATA 3   | DATA 2   | DATA 1   |
//! +---------+----------+----------+----------+----------+
//! | Word 5  | DATA 8   | DATA 7   | DATA 6   | DATA 5   |
//! +---------+----------+----------+----------+----------+
//! | Word 6  | DATA 12  | DATA 11  | DATA 10  | DATA 9   |
//! +---------+----------+----------+----------+----------+
//! | ...     |          |          |          |          |
//! +---------+----------+----------+----------+----------+
//! | Word X  | DATA n   | DATA n-1 | DATA n-2 | DATA n-3 |
//! +---------+----------+----------+----------+----------+
//! \endverbatim
//!
//! Where PL is Payload Length, (DATA) only
//! Where DA is Destination (MAC) Address
//! Where SA is Source (MAC) Address
//! Where FT is Frame Type (or Frame Length for Ethernet)
//! Where DATA is Payload Data for the Ethernet Frame
//!
//! \return Returns the negated packet length \b -lBufLen if the packet is too
//! large for FIFO, and the packet length \b lBufLen otherwise.
//
//*****************************************************************************
static long
EthernetPacketPutInternal(unsigned long ulBase, unsigned char *pucBuf,
                          long lBufLen)
{
    unsigned long ulTemp;
    long i = 0;

    //
    // If the packet is too large, return the negative packet length as
    // an error code.
    //
    if(lBufLen > (2048 - 2))
    {
        return(-lBufLen);
    }

    //
    // Build and write WORD 0 (see format above) to the transmit FIFO.
    //
    ulTemp = (unsigned long)(lBufLen - 14);
    ulTemp |= (pucBuf[i++] << 16);
    ulTemp |= (pucBuf[i++] << 24);
    HWREG(ulBase + MAC_O_DATA) = ulTemp;

    //
    // Write each subsequent WORD n to the transmit FIFO, except for the last
    // WORD (if the word does not contain 4 bytes).
    //
    while(i <= (lBufLen - 4))
    {
        HWREG(ulBase + MAC_O_DATA) = *(unsigned long *)&pucBuf[i];
        i += 4;
    }

    //
    // Build the last word of the remaining 1, 2, or 3 bytes, and store
    // the WORD into the transmit FIFO.
    //
    if(i != lBufLen)
    {
        if(i == (lBufLen - 3))
        {
            ulTemp  = (pucBuf[i++] <<  0);
            ulTemp |= (pucBuf[i++] <<  8);
            ulTemp |= (pucBuf[i++] << 16);
            HWREG(ulBase + MAC_O_DATA) = ulTemp;
        }
        else if(i == (lBufLen - 2))
        {
            ulTemp  = (pucBuf[i++] <<  0);
            ulTemp |= (pucBuf[i++] <<  8);
            HWREG(ulBase + MAC_O_DATA) = ulTemp;
        }
        else if(i == (lBufLen - 1))
        {
            ulTemp  = (pucBuf[i++] <<  0);
            HWREG(ulBase + MAC_O_DATA) = ulTemp;
        }
    }

    //
    // Activate the transmitter
    //
    HWREG(ulBase + MAC_O_TR) = MAC_TR_NEWTX;

    //
    // Return the Buffer Length transmitted.
    //
    return(lBufLen);
}

//*****************************************************************************
//
//! Sends a packet to the Ethernet controller.
//!
//! \param ulBase is the base address of the controller.
//! \param pucBuf is the pointer to the packet buffer.
//! \param lBufLen is number of bytes in the packet to be transmitted.
//!
//! This function writes \e lBufLen bytes of the packet contained in \e pucBuf
//! into the transmit FIFO of the controller and then activates the
//! transmitter for this packet.  If no space is available in the FIFO, the
//! function will return immediately.  If space is available, the
//! function will return once \e lBufLen bytes of the packet have been placed
//! into the FIFO and the transmitter has been started.  The function will not
//! wait for the transmission to complete.  The function will return the
//! negated \e lBufLen if the length is larger than the space available in
//! the transmit FIFO.
//!
//! This function replaces the original EthernetPacketNonBlockingPut() API and
//! performs the same actions.  A macro is provided in <tt>ethernet.h</tt> to
//! map the original API to this API.
//!
//! \note This function does not block and will return immediately if no space
//! is available for the transmit packet.
//!
//! \return Returns \b 0 if no space is available in the transmit FIFO, the
//! negated packet length \b -lBufLen if the packet is too large for FIFO, and
//! the packet length \b lBufLen otherwise.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -