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

📄 bsp_lpc32xx_eth.c

📁 NXP LPC3000系列 wince BSP包
💻 C
📖 第 1 页 / 共 2 页
字号:

	// 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 + -