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

📄 ethernet.c

📁 uCOS-II V2.84 LM3S6965 TCPIP Demo
💻 C
📖 第 1 页 / 共 3 页
字号:
    //
    // Check the arguments.
    //
    ASSERT(ulBase == ETH_BASE);

    //
    // Read the unmasked status.
    //
    ulStatus = HWREG(ulBase + MAC_O_IS);

    //
    // 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.
//!
//! \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.
//!
//! \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);
}

//*****************************************************************************
//
//! \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 If the packet is too large for \e pucBuf, the function will return
//! the negated length \b -n.  Otherwise, the function will return the length
//! \b n of the received 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, 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++] = pucTemp[2];
    pucBuf[i++] = pucTemp[3];

    //
    // Read all but the last WORD into the receive 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 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);
}

//*****************************************************************************
//
//! \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 If the packet is too large for FIFO, the function will return the
//! negated length \b -lBufLen.  Otherwise, the function will return the length
//! \b lBufLen of the transmitted packet.
//
//*****************************************************************************
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 transmit 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 transmit 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 transmit 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);
}

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

⌨️ 快捷键说明

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