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

📄 ethernet.c

📁 从Luminary官方网站下载的LM3S6000系列的UCos+Tcp/IP的源码, 经本人稍微修改后可直接在IAR6.2下编译通过,里面包括了LM3S6000系列的所有外设UART, PWn....
💻 C
📖 第 1 页 / 共 3 页
字号:
    // If masked status is requested, mask it off
    //
    if(bMasked)
    {
        ulStatus &= HWREG(ulBase + MAC_O_IM);
    }

    //
    // Return the interrupt status value
    //
    return(ulStatus);
}

//*****************************************************************************
//
//! Clears Ethernet interrupt sources.
//!
//! \param ulBase is the base address of the controller.
//! \param ulIntFlags is a bit mask of the interrupt sources to be cleared.
//!
//! The specified Ethernet interrupt sources are cleared, so that they no
//! longer assert.  This must be done in the interrupt handler to keep it from
//! being called again immediately upon exit.
//!
//! The parameter \e ulIntFlags has the same definition as the same parameter
//! to EthernetIntEnable().
//!
//! \return None.
//
//*****************************************************************************
void
EthernetIntClear(unsigned long ulBase, unsigned long ulIntFlags)
{
    //
    // Check the arguments.
    //
    ASSERT(ulBase == ETH_BASE);
    ASSERT(ulIntFlags & ~(ETH_INT_PHY | ETH_INT_MDIO | ETH_INT_RXER |
                ETH_INT_RXOF | ETH_INT_TX | ETH_INT_TXER | ETH_INT_RX));

    //
    // Clear the requested interrupt sources.
    //
    HWREG(ulBase + MAC_O_IACK) = ulIntFlags;
}

//*****************************************************************************
//
//! Write to the PHY register.
//!
//! \param ulBase is the base address of the controller.
//! \param ucRegAddr is the address of the PHY register to be accessed.
//! \param ulData is the data to be written to the PHY register.
//!
//! This function will write the \e ulData to the PHY register specified by
//! \e ucRegAddr.
//!
//! \note The register set for the PHY will be defined \e ethernet.h.  At this
//! time, the definitions have not yet been integrated into the hardware
//! specification, so no additional documentation is available.
//!
//! \return None.
//
//*****************************************************************************
void
EthernetPHYWrite(unsigned long ulBase, unsigned char ucRegAddr,
                 unsigned long ulData)
{
    //
    // Check the arguments.
    //
    ASSERT(ulBase == ETH_BASE);

    //
    // Wait for any pending transaction to complete
    //
    while(HWREG(ulBase + MAC_O_MCTL) & MAC_MCTL_START)
    {
    }

    //
    // Program the DATA to be written
    //
    HWREG(ulBase + MAC_O_MTXD) = ulData & MAC_MTXD_MDTX;

    //
    // Program the PHY register address and initiate the transaction
    //
    HWREG(ulBase + MAC_O_MCTL) = ((ucRegAddr << 3) & MAC_MCTL_REGADR) |
                                MAC_MCTL_WRITE | MAC_MCTL_START;
    //
    // Wait for the write transaction to complete
    //
    while(HWREG(ulBase + MAC_O_MCTL) & MAC_MCTL_START)
    {
    }
}

//*****************************************************************************
//
//! Read from a PHY register.
//!
//! \param ulBase is the base address of the controller.
//! \param ucRegAddr is the address of the PHY register to be accessed.
//!
//! This function will the contents of the PHY register specified by
//! \e ucRegAddr.
//!
//! \note The register set for the PHY will be defined \e ethernet.h.  At this
//! time, the definitions have not yet been integrated into the hardware
//! specification, so no additional documentation is available.
//!
//! \return The function will return the 16-bit value read from the PHY.
//
//*****************************************************************************
unsigned long
EthernetPHYRead(unsigned long ulBase, unsigned char ucRegAddr)
{
    //
    // Check the arguments.
    //
    ASSERT(ulBase == ETH_BASE);

    //
    // Wait for any pending transaction to complete
    //
    while(HWREG(ulBase + MAC_O_MCTL) & MAC_MCTL_START)
    {
    }

    //
    // Program the PHY register address and initiate the transaction
    //
    HWREG(ulBase + MAC_O_MCTL) = ((ucRegAddr << 3) & MAC_MCTL_REGADR) |
                                MAC_MCTL_START;

    //
    // Wait for the transaction to complete
    //
    while(HWREG(ulBase + MAC_O_MCTL) & MAC_MCTL_START)
    {
    }

    //
    // Return the PHY data that was read
    //
    return(HWREG(ulBase + MAC_O_MRXD) & MAC_MRXD_MDRX);
}

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

//*****************************************************************************
//
// 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 data to be read into the buffer
//
// Based on the following table of how the receive frame is stored in the
// RX FIFO, this function will extract a packet from the FIFO and store
// it in the packet structure that was passed in.
//
// Format of the data in the RX FIFO is as follows:
//
//         | 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    |
// --------+----------+----------+----------+----------+
//
// 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
//      -2  - Error in receive packet
//      -n  - Packet too large for buffer, truncated
//      +n  - Number of bytes in the Rx Packet
//
//*****************************************************************************
static long
EthernetInternalGetPacket(unsigned long ulBase, unsigned char *pucBuf,
                          long lBufLen)
{
    unsigned long ulTemp;
    long lFrameLen, lTempLen;
    short i = 0;
    unsigned char *pucTemp = (unsigned char *)&ulTemp;

    //
    // Read WORD 0 (see format above) from the FIFO, and set the RX
    // Frame Length, and store the first two bytes of the destination
    // address in the RX buffer
    //
    ulTemp = HWREG(ulBase + MAC_O_DATA);
    lFrameLen = (long)(ulTemp & 0xFFFF);
    pucBuf[i++] = pucTemp[2];
    pucBuf[i++] = pucTemp[3];

    //
    // Read all but the last WORD into the Buffer
    //
    lTempLen = (lBufLen < (lFrameLen - 6)) ? lBufLen : (lFrameLen - 6) ;
    while(i <= (lTempLen - 4))
    {
        ulTemp = HWREG(ulBase + MAC_O_DATA);
        pucBuf[i++] = pucTemp[0];
        pucBuf[i++] = pucTemp[1];
        pucBuf[i++] = pucTemp[2];
        pucBuf[i++] = pucTemp[3];
    }

    //
    // 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++] = pucTemp[0];
            pucBuf[i++] = pucTemp[1];
            pucBuf[i++] = pucTemp[2];
            i += 1;
        }
        else if(i == lTempLen - 2)
        {
            pucBuf[i++] = pucTemp[0];
            pucBuf[i++] = pucTemp[1];
            i += 2;
        }
        else if(i == lTempLen - 1)
        {
            pucBuf[i++] = pucTemp[0];
            i += 3;
        }
    }
    
    //
    // Read any remaining WORDS (that didn't 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);
}

//*****************************************************************************
//
// 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 the length of 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:
//
//         | 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     | DS 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 |
// --------+----------+----------+----------+----------+
//
// 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 None.
//
//*****************************************************************************
static long
EthernetInternalPutPacket(unsigned long ulBase, unsigned char *pucBuf,
                          long lBufLen)
{
    unsigned long ulTemp;
    short i = 0;
    unsigned char *pucTemp = (unsigned char *)&ulTemp;

    //
    // 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 FIFO
    //
    ulTemp  = (unsigned long)(lBufLen - 14);
    pucTemp[2] = pucBuf[i++];
    pucTemp[3] = pucBuf[i++];
    HWREG(ulBase + MAC_O_DATA) = ulTemp;

    //
    // Write each subsequent WORD n to the FIFO, except for the last
    // WORD, if the word does not contain 4 bytes
    //
    while(i <= (lBufLen - 4))
    {
        pucTemp[0] = pucBuf[i++];
        pucTemp[1] = pucBuf[i++];
        pucTemp[2] = pucBuf[i++];
        pucTemp[3] = pucBuf[i++];
        HWREG(ulBase + MAC_O_DATA) = ulTemp;
    }

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

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

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

⌨️ 快捷键说明

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