📄 ethernet.c
字号:
//
//*****************************************************************************
long
EthernetPacketPutNonBlocking(unsigned long ulBase, unsigned char *pucBuf,
long lBufLen)
{
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
ASSERT(pucBuf != 0);
ASSERT(lBufLen > 0);
//
// Check if the transmit FIFO is in use and return the appropriate code.
//
if(HWREG(ulBase + MAC_O_TR) & MAC_TR_NEWTX)
{
return(0);
}
//
// Send the packet and return.
//
return(EthernetPacketPutInternal(ulBase, pucBuf, lBufLen));
}
//*****************************************************************************
//
//! Waits to send 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 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. This function will wait until the transmit FIFO is empty.
//! Once 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.
//!
//! \note This function blocks and will wait until space is available for the
//! transmit packet before returning.
//!
//! \return Returns the negated packet length \b -lBufLen if the packet is too
//! large for FIFO, and the packet length \b lBufLen otherwise.
//
//*****************************************************************************
long
EthernetPacketPut(unsigned long ulBase, unsigned char *pucBuf,
long lBufLen)
{
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
ASSERT(pucBuf != 0);
ASSERT(lBufLen > 0);
//
// Wait for current packet (if any) to complete.
//
while(HWREG(ulBase + MAC_O_TR) & MAC_TR_NEWTX)
{
}
//
// Send the packet and return.
//
return(EthernetPacketPutInternal(ulBase, pucBuf, lBufLen));
}
//*****************************************************************************
//
//! Registers an interrupt handler for an Ethernet interrupt.
//!
//! \param ulBase is the base address of the controller.
//! \param pfnHandler is a pointer to the function to be called when the
//! enabled Ethernet interrupts occur.
//!
//! This function sets the handler to be called when the Ethernet interrupt
//! occurs. This will enable the global interrupt in the interrupt controller;
//! specific Ethernet interrupts must be enabled via EthernetIntEnable(). It
//! is the interrupt handler's responsibility to clear the interrupt source.
//!
//! \sa IntRegister() for important information about registering interrupt
//! handlers.
//!
//! \return None.
//
//*****************************************************************************
void
EthernetIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
{
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
ASSERT(pfnHandler != 0);
//
// Register the interrupt handler.
//
IntRegister(INT_ETH, pfnHandler);
//
// Enable the Ethernet interrupt.
//
IntEnable(INT_ETH);
}
//*****************************************************************************
//
//! Unregisters an interrupt handler for an Ethernet interrupt.
//!
//! \param ulBase is the base address of the controller.
//!
//! This function unregisters the interrupt handler. This will disable the
//! global interrupt in the interrupt controller so that the interrupt handler
//! no longer is called.
//!
//! \sa IntRegister() for important information about registering interrupt
//! handlers.
//!
//! \return None.
//
//*****************************************************************************
void
EthernetIntUnregister(unsigned long ulBase)
{
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
//
// Disable the interrupt.
//
IntDisable(INT_ETH);
//
// Unregister the interrupt handler.
//
IntUnregister(INT_ETH);
}
//*****************************************************************************
//
//! Enables individual Ethernet interrupt sources.
//!
//! \param ulBase is the base address of the controller.
//! \param ulIntFlags is the bit mask of the interrupt sources to be enabled.
//!
//! Enables the indicated Ethernet interrupt sources. Only the sources that
//! are enabled can be reflected to the processor interrupt; disabled sources
//! have no effect on the processor.
//!
//! The \e ulIntFlags parameter is the logical OR of any of the following:
//!
//! - \b ETH_INT_PHY - An interrupt from the PHY has occurred. The integrated
//! PHY supports a number of interrupt conditions. The PHY register, PHY_MR17,
//! must be read to determine which PHY interrupt has occurred. This register
//! can be read using the EthernetPHYRead() API function.
//! - \b ETH_INT_MDIO - This interrupt indicates that a transaction on the
//! management interface has completed successfully.
//! - \b ETH_INT_RXER - This interrupt indicates that an error has occurred
//! during reception of a frame. This error can indicate a length mismatch, a
//! CRC failure, or an error indication from the PHY.
//! - \b ETH_INT_RXOF - This interrupt indicates that a frame has been received
//! that exceeds the available space in the RX FIFO.
//! - \b ETH_INT_TX - This interrupt indicates that the packet stored in the TX
//! FIFO has been successfully transmitted.
//! - \b ETH_INT_TXER - This interrupt indicates that an error has occurred
//! during the transmission of a packet. This error can be either a retry
//! failure during the back-off process, or an invalid length stored in the TX
//! FIFO.
//! - \b ETH_INT_RX - This interrupt indicates that one (or more) packets are
//! available in the RX FIFO for processing.
//!
//! \return None.
//
//*****************************************************************************
void
EthernetIntEnable(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)));
//
// Enable the specified interrupts.
//
HWREG(ulBase + MAC_O_IM) |= ulIntFlags;
}
//*****************************************************************************
//
//! Disables individual Ethernet interrupt sources.
//!
//! \param ulBase is the base address of the controller.
//! \param ulIntFlags is the bit mask of the interrupt sources to be disabled.
//!
//! Disables the indicated Ethernet interrupt sources. Only the sources that
//! are enabled can be reflected to the processor interrupt; disabled sources
//! have no effect on the processor.
//!
//! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
//! parameter to EthernetIntEnable().
//!
//! \return None.
//
//*****************************************************************************
void
EthernetIntDisable(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)));
//
// Disable the specified interrupts.
//
HWREG(ulBase + MAC_O_IM) &= ~ulIntFlags;
}
//*****************************************************************************
//
//! Gets the current Ethernet interrupt status.
//!
//! \param ulBase is the base address of the controller.
//! \param bMasked is false if the raw interrupt status is required and true
//! if the masked interrupt status is required.
//!
//! This returns the interrupt status for the Ethernet controller. Either the
//! raw interrupt status or the status of interrupts that are allowed to
//! reflect to the processor can be returned.
//!
//! \return Returns the current interrupt status, enumerated as a bit field of
//! values described in EthernetIntEnable().
//
//*****************************************************************************
unsigned long
EthernetIntStatus(unsigned long ulBase, tBoolean bMasked)
{
unsigned long ulStatus;
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
//
// Read the unmasked status.
//
ulStatus = HWREG(ulBase + MAC_O_RIS);
//
// 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 \e ulIntFlags parameter has the same definition as the \e ulIntFlags
//! parameter to EthernetIntEnable().
//!
//! \note Since there is a write buffer in the Cortex-M3 processor, it may take
//! several clock cycles before the interrupt source is actually cleared.
//! Therefore, it is recommended that the interrupt source be cleared early in
//! the interrupt handler (as opposed to the very last action) to avoid
//! returning from the interrupt handler before the interrupt source is
//! actually cleared. Failure to do so may result in the interrupt handler
//! being immediately reentered (since NVIC still sees the interrupt source
//! asserted).
//!
//! \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;
}
//*****************************************************************************
//
//! Writes 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_M;
//
// Program the PHY register address and initiate the transaction.
//
HWREG(ulBase + MAC_O_MCTL) = (((ucRegAddr << 3) & MAC_MCTL_REGADR_M) |
MAC_MCTL_WRITE | MAC_MCTL_START);
//
// Wait for the write transaction to complete.
//
while(HWREG(ulBase + MAC_O_MCTL) & MAC_MCTL_START)
{
}
}
//*****************************************************************************
//
//! Reads 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 return the contents of the PHY register specified by
//! \e ucRegAddr.
//!
//! \return Returns 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_M) |
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_M);
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -