📄 bsp_lpc32xx_eth.c
字号:
// Try 100MBase/full duplex
goodacc = btemp = FALSE;
if ((tmp1 & PHY_BMSR_TX_FULL) != 0)
{
// Setup for full duplex and 100MBase
goodacc = btemp = TRUE;
}
else if ((tmp1 & PHY_BMSR_TX_HALF) != 0)
{
// Setup for half duplex and 100MBase
goodacc = TRUE;
}
else if ((tmp1 & PHY_BMSR_TX_HALF) != 0)
{
// Setup for full duplex and 10MBase
btemp = TRUE;
}
// Configure Full/Half Duplex mode
if (btemp == TRUE)
{
// 10MBase full duplex is supported
pEregs->mac2 |= MAC2_FULL_DUPLEX;
pEregs->command |= COMMAND_FULLDUPLEX;
pEregs->ipgt = IPGT_LOAD(0x15);
OALMSGS((OAL_ETHER && OAL_FUNC), (L"ENET:FULL DUPLEX\r\n"));
}
else
{
pEregs->ipgt = IPGT_LOAD(0x12);
OALMSGS((OAL_ETHER && OAL_FUNC), (L"ENET:HALF DUPLEX\r\n"));
}
// Configure 100MBit/10MBit mode
if (goodacc == TRUE)
{
// 100MBase mode
pEregs->supp = SUPP_SPEED;
OALMSGS((OAL_ETHER && OAL_FUNC), (L"ENET:100MBase\r\n"));
}
else
{
// 10MBase mode
pEregs->supp = 0;
OALMSGS((OAL_ETHER && OAL_FUNC), (L"ENET:10MBase\r\n"));
}
// Save station address
pEregs->sa [2] = smac [0];
pEregs->sa [1] = smac [1];
pEregs->sa [0] = smac [2];
// Setup TX and RX descriptors
txrx_setup();
// Enable broadcast and matching address packets
pEregs->rxfliterctrl = (RXFLTRW_ACCEPTUBROADCAST |
RXFLTRW_ACCEPTPERFECT);
// pEregs->txproduceindex = 0;
// pEregs->rxconsumeindex = 0;
// Clear and enable interrupts
pEregs->intclear = 0xFFFF;
pEregs->intenable = 0;
// Enable receive and transmit mode of MAC ethernet core
pEregs->command |= (COMMAND_RXENABLE | COMMAND_TXENABLE);
pEregs->mac1 |= MAC1_RECV_ENABLE;
// Perform a 'dummy' send of the first ethernet frame with a size of 0
// to 'prime' the MAC. The first packet after a reset seems to wait
// until at least 2 packets are ready to go.
// goodacc = 0;
// LPC32XX_Eth_SendFrame((UINT8 *) &goodacc, 4);
return TRUE;
}
//------------------------------------------------------------------------------
//
// HWDeInit
//
// De-initialize ethernet and PHY hardware
//
BOOL HWDeInit(VOID)
{
if (init == TRUE)
{
init = FALSE;
// Reset PHY
(void) HYPHYReset();
// Reset all MAC logic
pEregs->mac1 = (MAC1_SOFT_RESET | MAC1_SIMULATION_RESET |
MAC1_RESET_MCS_TX | MAC1_RESET_TX | MAC1_RESET_MCS_RX |
MAC1_RESET_RX);
pEregs->command = (COMMAND_REG_RESET | COMMAND_TXRESET |
COMMAND_RXRESET);
msDelay(2);
// Disable MAC clocks, but keep MAC interface active
#ifdef USE_PHY_RMII
pClkpwr->clkpwr_macclk_ctrl = CLKPWR_MACCTRL_USE_RMII_PINS;
#else
pClkpwr->clkpwr_macclk_ctrl = CLKPWR_MACCTRL_USE_MII_PINS;
#endif
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// LPC32XX_Eth_Init
//
// Initialize ethernet interface for KITL/download support
//
BOOL LPC32XX_Eth_Init(UINT8 *pAddress, UINT32 offset, UINT16 mac[3])
{
BOOL rc = FALSE;
pClkpwr = (CLKPWR_REGS_T *) OALPAtoVA((UINT32) CLKPWR, FALSE);
pEregs = (ETHERNET_REGS_T *) OALPAtoVA((UINT32) pAddress, FALSE);
// Set MAC address from hardware
mac [0] = (phyhwdesc.mac[0] | (phyhwdesc.mac[1] << 8));
mac [1] = (phyhwdesc.mac[2] | (phyhwdesc.mac[3] << 8));
mac [2] = (phyhwdesc.mac[4] | (phyhwdesc.mac[5] << 8));
// Save MAC address
smac [0] = (UINT32) (mac[0]);
smac [1] = (UINT32) (mac[1]);
smac [2] = (UINT32) (mac[2]);
OALMSGS((OAL_ETHER && OAL_FUNC), (
L"+LPC32XX_Eth_Init(0x%08x, 0x%08x, %02x:%02x:%02x:%02x:%02x:%02x)\r\n",
pAddress, offset, mac[0]&0xFF, mac[0]>>8, mac[1]&0xFF, mac[1]>>8,
mac[2]&0xFF, mac[2]>>8
));
rc = HWInit();
// De-init if an error occurred
init = FALSE;
if (rc == FALSE)
{
HWDeInit();
}
return rc;
}
#if 0
//------------------------------------------------------------------------------
//
// LPC32xx_Eth_InitDMABuffer
//
// Initialize DMA buffers
//
BOOL LPC32xx_Eth_InitDMABuffer(UINT32 address, UINT32 size)
{
UINT32 tmp;
// Align on 16 byte boundary and save base address and size for DMA location
g_dmabase = address & ~0xF;
g_dmabase += 0x10;
gdma_size = size - (g_dmabase - address);
OALMSGS((OAL_ETHER && OAL_FUNC), (
L"+LPC32xx_Eth_InitDMABuffer 0x%x 0x%x\r\n", address, size));
// Verify that enough space is allocated for the DMA buffers to store
// 4 TX buffers, 4 RX buffers, and descriptors and statuses for the
// buffers. 256 bytes are used for descriptors/statuses.
tmp = 512 + (ENET_MAXF_SIZE * (ENET_MAX_TX_PACKETS + ENET_MAX_RX_PACKETS));
if (tmp > gdma_size)
{
// Not enough space
OALMSGS((OAL_ETHER && OAL_FUNC), (
L"+LPC32xx_Eth_InitDMABuffer-not enough space for DMA buffers\r\n"));
return FALSE;
}
return TRUE;
}
#endif
//------------------------------------------------------------------------------
//
// LPC32XX_Eth_Deinit
//
// De-initialize ethernet
//
BOOL LPC32XX_Eth_Deinit(VOID)
{
OALMSGS((OAL_ETHER && OAL_FUNC), (L"+LPC32XX_Eth_Deinit\r\n"));
return HWDeInit();
}
//------------------------------------------------------------------------------
//
// LPC32XX_Eth_SendFrame
//
// Send an ethernet frame
//
UINT16 LPC32XX_Eth_SendFrame(UINT8 *pbData, UINT32 length)
{
UINT32 idx, cidx, fb;
// Determine number of free buffers and wait for a buffer if needed
fb = 0;
while (fb == 0)
{
idx = pEregs->txproduceindex;
cidx = pEregs->txconsumeindex;
if (idx == cidx)
{
// Producer and consumer are the same, all buffers are free
fb = ENET_MAX_TX_PACKETS;
}
else if (cidx > idx)
{
fb = (ENET_MAX_TX_PACKETS - 1) -
((idx + ENET_MAX_TX_PACKETS) - cidx);
}
else
{
fb = (ENET_MAX_TX_PACKETS - 1) - (cidx - idx);
}
}
// Update descriptor with new frame size
pTXDesc[idx].control = ((length - 1) | 0x40000000);
// Move data to buffer
memcpy((void *) pTXVBuffs [idx], pbData, length);
// Get next index for transmit data DMA buffer and descriptor
idx++;
if (idx >= ENET_MAX_TX_PACKETS)
{
idx = 0;
}
pEregs->txproduceindex = idx;
return 0;
}
//------------------------------------------------------------------------------
//
// LPC32XX_Eth_GetFrame
//
// Get ethernet frame
//
UINT16 LPC32XX_Eth_GetFrame(UINT8 *pbData, UINT16 *pLength)
{
UINT32 idx, length;
// Determine if a frame has been received
length = 0;
idx = pEregs->rxconsumeindex;
if (pEregs->rxproduceindex != idx)
{
// Clear interrupt
pEregs->intclear = MACINT_RXDONEINTEN;
// Frame received, get size of RX packet
length = (pRXStatus[idx].statusinfo & 0x7FF) - 1;
// Copy data to passed buffer
memcpy(pbData, (void *) pRXVBuffs [idx], length);
// Return DMA buffer
idx++;
if (idx >= ENET_MAX_TX_PACKETS)
{
idx = 0;
}
pEregs->rxconsumeindex = (UNS_32) idx;
}
// Return size
*pLength = (UINT16) length;
return (UINT16) length;
}
//------------------------------------------------------------------------------
//
// LPC32XX_Eth_EnableInts
//
// Enable ethernet interrupts
//
VOID LPC32XX_Eth_EnableInts()
{
// Enable EMAC interrupts
OALMSGS((OAL_ETHER && OAL_FUNC), (L"+LPC32XX_Eth_EnableInts\r\n"));
pEregs->intclear = 0xFFFF;
pEregs->intenable = MACINT_RXDONEINTEN;
}
//------------------------------------------------------------------------------
//
// LPC32XX_Eth_DisableInts
//
// Disable ethernet interrupts
//
VOID LPC32XX_Eth_DisableInts()
{
// Disable EMAC interrupts
OALMSGS((OAL_ETHER && OAL_FUNC), (L"+LPC32XX_Eth_DisableInts\r\n"));
pEregs->intenable = 0;
pEregs->intclear = 0xFFFF;
}
//------------------------------------------------------------------------------
//
// LPC32XX_Eth_PowerOff
//
// Power down ethernet interface
//
VOID LPC32XX_Eth_PowerOff()
{
OALMSGS((OAL_ETHER && OAL_FUNC), (L"+LPC32XX_Eth_PowerOff)\r\n"));
HWDeInit();
}
//------------------------------------------------------------------------------
//
// LPC32XX_Eth_PowerOn
//
// Power up ethernet interface
//
VOID LPC32XX_Eth_PowerOn()
{
OALMSGS((OAL_ETHER && OAL_FUNC), (L"+LPC32XX_Eth_PowerOn)\r\n"));
HWInit();
}
//------------------------------------------------------------------------------
//
// LPC32XX_Eth_CurrentPacketFilter
//
// Setup ethernet packet filtering
//
VOID LPC32XX_Eth_CurrentPacketFilter(UINT32 filter)
{
UINT32 rxfilt;
OALMSGS((OAL_ETHER && OAL_FUNC), (L"+LPC32XX_Eth_CurrentPacketFilter)\r\n"));
// Read current filter
rxfilt = pEregs->rxfliterctrl;
// All multicast packets
if ((filter & PACKET_TYPE_ALL_MULTICAST) != 0) {
pEregs->hashfilterL = 0xFFFFFFFF;
pEregs->hashfilterh = 0xFFFFFFFF;
rxfilt |= RXFLTRW_ACCEPTUMULTICAST;
}
else
{
rxfilt &= ~RXFLTRW_ACCEPTUMULTICAST;
}
// Broadcast packets
if ((filter & PACKET_TYPE_BROADCAST) != 0) {
rxfilt |= RXFLTRW_ACCEPTUBROADCAST;
}
else
{
rxfilt &= ~RXFLTRW_ACCEPTUBROADCAST;
}
// Promiscous mode
if ((filter & PACKET_TYPE_PROMISCUOUS) != 0) {
rxfilt |= (RXFLTRW_ACCEPTUMULTICAST |
RXFLTRW_ACCEPTUBROADCAST | RXFLTRW_ACCEPTUNICAST);
}
else
{
rxfilt &= ~RXFLTRW_ACCEPTUNICAST;
}
// Enable broadcast and matching address packets
pEregs->rxfliterctrl = rxfilt;
}
//------------------------------------------------------------------------------
//
// LPC32XX_Eth_MulticastList
//
// Setup ethernet multi-casst addressing
//
BOOL LPC32XX_Eth_MulticastList(UINT8 *pAddresses, UINT32 count)
{
OALMSGS((OAL_ETHER && OAL_FUNC), (L"+LPC32XX_Eth_MulticastList)\r\n"));
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -