📄 ethisr.c
字号:
// Release mutex
xSemaphoreGive(ETHRxAccessMutex[ulPort]);
}
if (flCmd & ETH_FLUSH_TX)
{
// Access to shared variable
xSemaphoreTake( ETHTxAccessMutex[ulPort], ( portTickType ) portMAX_DELAY);
// See if Ethernet is currently transmitting a frame,
while (MAC_TR_NEWTX == HWREG(ETH_BASE + MAC_O_TR))
{
/*
* vTaskDelay() does not provide a good method of controlling the frequency
* of a cyclical task as the path taken through the code, as well as other task and
* interrupt activity, will effect the frequency at which vTaskDelay() gets called
* and therefore the time at which the task next executes.
*/
// The shortest time to wait with respect to other tasks. If you need
// immediate reaction, remove this function.
vTaskDelay(1);
}
// Reset write FIFO pointer, MACRIS/MACIACK register.
// BitBand region: TXER - Setting this bit clears the TXER interrupt in the MACRIS register and
// resets the TX FIFO write pointer, bit 1
HWREGBITW(ETHBase[ulPort] + MAC_O_IACK, 1) = 1;
// Release mutex
xSemaphoreGive(ETHTxAccessMutex[ulPort]);
}
//return ok
return 0;
}
HWREGBITW(ÐDevice[ulPort], ETH_ERROR) = 1;
HWREGBITW(ÐDevice[ulPort], ETH_EBADF) = 1;
return (-1);
}
//!*****************************************************************************
//!
//! Enables transmitting and receiving.
//! This function is called from low_level_init in ETHIsr.c
//!
//! \param ulPort is the ETH port number to be accessed.
//!
//! \return 0 or -1 if error.
//
//*****************************************************************************
int ETHServiceTaskEnable(unsigned long ulPort)
{
unsigned long temp;
unsigned long phyStatus;
if (ulPort < MAX_ETH_PORTS)
{
// Do whatever else is needed to initialize interface.
// Disable and clear all Ethernet Interrupts.
EthernetIntDisable(ETHBase[ulPort], (ETH_INT_PHY | ETH_INT_MDIO | ETH_INT_RXER
| ETH_INT_RXOF | ETH_INT_TX | ETH_INT_TXER | ETH_INT_RX));
temp = EthernetIntStatus(ETHBase[ulPort], false);
EthernetIntClear(ETHBase[ulPort], temp);
// Initialize the Ethernet Controller.
EthernetInitExpClk(ETHBase[ulPort], SysCtlClockGet());
/*
* Configure the Ethernet Controller for normal operation.
* - Enable TX Duplex Mode
* - Enable TX Padding
* - Enable TX CRC Generation
* - Enable RX Multicast Reception
*/
EthernetConfigSet(ETHBase[ulPort], (ETH_CFG_TX_DPLXEN |ETH_CFG_TX_CRCEN
| ETH_CFG_TX_PADEN | ETH_CFG_RX_AMULEN));
// Enable the Ethernet Controller transmitter and receiver.
EthernetEnable(ETHBase[ulPort]);
// Determine if link is up
// no need to worry about while loop in EthernetPHYRead
// Ethernet PHY Management Register 1 - Status
phyStatus = EthernetPHYRead(ETH_BASE, PHY_MR1);
if (phyStatus & ETH_PHY_LINK_UP)
{
// set link up flag
HWREGBITW(ÐDevice[ulPort], ETH_LINK_OK) = 1;
}
else
{
HWREGBITW(ÐDevice[ulPort], ETH_LINK_OK) = 0;
}
// Configure the Ethernet PHY interrupt management register.
EthernetPHYWrite(ETHBase[ulPort], PHY_MR17, ETH_PHY_INT_MASK);
// Enable the Ethernet Interrupt handler.
IntEnable(ETHInterrupt[ulPort]);
// Set interrupt priority to number higher than configMAX_SYSCALL_INTERRUPT_PRIORITY
// defined in FreeRTOSConfig.h, see www.freertos.org
IntPrioritySet(ETHInterrupt[ulPort], SET_SYSCALL_INTERRUPT_PRIORITY(6));
// Enable Ethernet RX, PHY and RXOF Packet Interrupts.
EthernetIntEnable(ETHBase[ulPort], ETH_INT_RX | ETH_INT_PHY | ETH_INT_RXOF | ETH_INT_TXER);
HWREGBITW(ÐDevice[ulPort], ETH_ENABLED) = 1;
return 0;
}
return (-1);
}
//!*****************************************************************************
//!
//!
//! This function is called from low_level_init function in LWIPStack.c
//!
//!
int ETHServiceTaskWaitReady(const unsigned long ulPort)
{
if ((ulPort < MAX_ETH_PORTS) && (HWREGBITW(ÐDevice[ulPort], ETH_ENABLED)))
{
// See if Ethernet completed autonegation,
while (!(PHY_MR1_ANEGC & EthernetPHYRead(ETHBase[0], PHY_MR1)))
{
/*
* vTaskDelay() does not provide a good method of controlling the frequency
* of a cyclical task as the path taken through the code, as well as other task and
* interrupt activity, will effect the frequency at which vTaskDelay() gets called
* and therefore the time at which the task next executes.
*/
// The shortest time to wait with respect to other tasks. If you need
// immediate reaction, remove this function.
vTaskDelay(1);
}
return (0);
}
HWREGBITW(ÐDevice[ulPort], ETH_ERROR) = 1;
HWREGBITW(ÐDevice[ulPort], ETH_EBADF) = 1;
return (-1);
}
//*****************************************************************************
//
//! Disables transmitting and receiving.
//! This function is called from low_level_init function in LWIPStack.c
//!
//! \param ulPort is the Ethernet port number to be accessed.
//!
//! Disables Ethernet peripheral
//!
//!
//! \return 0 or -1 if error.
//
//*****************************************************************************
int ETHServiceTaskDisable(const unsigned long ulPort)
{
if ((ulPort < MAX_ETH_PORTS) && (HWREGBITW(ÐDevice[ulPort], ETH_ENABLED)))
{
// Disable the ETH transmit and receive interrupts.
IntDisable(ETHInterrupt[ulPort]);
// Disable the ETH transmit and receive interrupts.
EthernetIntDisable(ETHBase[ulPort], (ETH_INT_RX | ETH_INT_PHY | ETH_INT_RXOF));
// Disable the ETH.
EthernetDisable(ETHBase[ulPort]);
// Clear all flags
ETHDevice[ulPort] = 0;
return (0);
}
return (-1);
}
//*****************************************************************************
//
//! Return error status.
//! This function is called from low_level_input function in LWIPStack.c
//!
//! \param ulPort is the Ethernet port number to be accessed.
//!
//! This function returns last error and clears error flags
//!
//! \return int or -1 if error.
//
//*****************************************************************************
int ETHServiceTaskLastError(const unsigned long ulPort)
{
if ((ulPort < MAX_ETH_PORTS) && (HWREGBITW(ÐDevice[ulPort], ETH_ENABLED)))
{
unsigned long err = ETHDevice[ulPort];
// Clear all flags except linkup flag and enabled device
ETHDevice[ulPort] &= (0x01 << ETH_LINK_OK) | (0x01 << ETH_ENABLED);
return (int)err;
}
HWREGBITW(ÐDevice[ulPort], ETH_ERROR) = 1;
HWREGBITW(ÐDevice[ulPort], ETH_EBADF) = 1;
return (-1);
}
//*****************************************************************************
//
//! Return link status.
//! This function is called from low_level_transmit function in LWIPStack.c
//!
//! \param ulPort is the Ethernet port number to be accessed.
//!
//! This function returns status of link. If is up or down.
//!
//! \return int or -1 if error.
//
//*****************************************************************************
int ETHServiceTaskLinkStatus(const unsigned long ulPort)
{
if ((ulPort < MAX_ETH_PORTS) && (HWREGBITW(ÐDevice[ulPort], ETH_ENABLED)))
{
return (int)HWREGBITW(ÐDevice[ulPort], ETH_LINK_OK);
}
HWREGBITW(ÐDevice[ulPort], ETH_ERROR) = 1;
HWREGBITW(ÐDevice[ulPort], ETH_EBADF) = 1;
return (-1);
}
//*****************************************************************************
//
//! Return MAC adress.
//! This function is called from low_level_init function in LWIPStack.c
//!
//! \param ulPort is the Ethernet port number to be accessed.
//!
//! This function returns status of link. If is up or down.
//!
//! \return int or -1 if error.
//
//*****************************************************************************
int ETHServiceTaskMACAddress(const unsigned long ulPort, unsigned char *pucMACAddr)
{
if ((ulPort < MAX_ETH_PORTS))
{
EthernetMACAddrGet(ETHBase[ulPort], pucMACAddr);
return (int)(0);
}
HWREGBITW(ÐDevice[ulPort], ETH_ERROR) = 1;
HWREGBITW(ÐDevice[ulPort], ETH_EBADF) = 1;
return (-1);
}
//!*****************************************************************************
//!
//! Check for packet available from the Ethernet controller.
//! This function is called from ethernetif_input function in LWIPStack.c
//!
//!
//! \param ulBase is the base address of the controller.
//!
//! The Ethernet controller provides a register that contains the number of
//! packets available in the receive FIFO. When the last bytes of a packet are
//! successfully received (that is, the frame check sequence bytes), the packet
//! count is incremented. Once the packet has been fully read (including the
//! frame check sequence bytes) from the FIFO, the packet count will be
//! decremented.
//!
//! \return 0,1 or -1 if error.
//
//*****************************************************************************
int ETHServiceTaskPacketAvail(const unsigned long ulPort)
{
if (ulPort < MAX_ETH_PORTS)
{
// Return the availability of packets.
return ((HWREG(ETHBase[ulPort] + MAC_O_NP) & MAC_NP_NPR_M) ? 1 : 0);
}
HWREGBITW(ÐDevice[ulPort], ETH_ERROR) = 1;
HWREGBITW(ÐDevice[ulPort], ETH_EBADF) = 1;
return (-1);
}
//!*****************************************************************************
//!
//!
//! This function is called from ethernetif_input function in LWIPStack.c
//!
//!
int ETHServiceTaskEnableReceive(const unsigned long ulPort)
{
if (ulPort < MAX_ETH_PORTS)
{
EthernetIntEnable(ETHBase[ulPort], ETH_INT_RX);
return 0;
}
HWREGBITW(ÐDevice[ulPort], ETH_ERROR) = 1;
HWREGBITW(ÐDevice[ulPort], ETH_EBADF) = 1;
return (-1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -