diff options
Diffstat (limited to 'hw/bsp/ea4357/emac.c')
| -rw-r--r-- | hw/bsp/ea4357/emac.c | 480 |
1 files changed, 0 insertions, 480 deletions
diff --git a/hw/bsp/ea4357/emac.c b/hw/bsp/ea4357/emac.c deleted file mode 100644 index fce042259..000000000 --- a/hw/bsp/ea4357/emac.c +++ /dev/null @@ -1,480 +0,0 @@ -/****************************************************************** - ***** ***** - ***** Name: cs8900.c ***** - ***** Ver.: 1.0 ***** - ***** Date: 07/05/2001 ***** - ***** Auth: Andreas Dannenberg ***** - ***** HTWK Leipzig ***** - ***** university of applied sciences ***** - ***** Germany ***** - ***** Func: ethernet packet-driver for use with LAN- ***** - ***** controller CS8900 from Crystal/Cirrus Logic ***** - ***** ***** - ***** NXP: Module modified for use with NXP ***** - ***** lpc43xx EMAC Ethernet controller ***** - ***** ***** - ******************************************************************/ - -#include "../board.h" - -#if BOARD == BOARD_EA4357 - -#include "emac.h" -//#include "tcpip.h" -#include "LPC43xx.h" -#include "lpc43xx_scu.h" -#include "lpc43xx_rgu.h" - -#define TIMEOUT 100000 - -static unsigned short *rptr; -static unsigned short *tptr; - -static unsigned int TxDescIndex = 0; -static unsigned int RxDescIndex = 0; - -// Keil: function added to write PHY -static void write_PHY (unsigned int PhyReg, unsigned short Value) { - - unsigned int tout; - - /* Write a data 'Value' to PHY register 'PhyReg'. */ - while(LPC_ETHERNET->MAC_MII_ADDR & GMII_BUSY); // Check GMII busy bit - LPC_ETHERNET->MAC_MII_ADDR = (DP83848C_DEF_ADR<<11) | (PhyReg<<6) | GMII_WRITE; - LPC_ETHERNET->MAC_MII_DATA = Value; - LPC_ETHERNET->MAC_MII_ADDR |= GMII_BUSY; // Start PHY Write Cycle - - /* Wait utill operation completed */ - for (tout = 0; tout < MII_WR_TOUT; tout++) { - if ((LPC_ETHERNET->MAC_MII_ADDR & GMII_BUSY) == 0) { - break; - } - } - if (tout == MII_WR_TOUT) // Trap the timeout - while(1); -} - - -// Keil: function added to read PHY -static unsigned short read_PHY (unsigned int PhyReg) { - - unsigned int tout, val; - - /* Read a PHY register 'PhyReg'. */ - while(LPC_ETHERNET->MAC_MII_ADDR & GMII_BUSY); // Check GMII busy bit - LPC_ETHERNET->MAC_MII_ADDR = (DP83848C_DEF_ADR<<11) | (PhyReg<<6) | GMII_READ; - LPC_ETHERNET->MAC_MII_ADDR |= GMII_BUSY; // Start PHY Read Cycle - - /* Wait until operation completed */ - for (tout = 0; tout < MII_RD_TOUT; tout++) { - if ((LPC_ETHERNET->MAC_MII_ADDR & GMII_BUSY) == 0) { - break; - } - } - if (tout == MII_RD_TOUT) // Trap the timeout - while(1); - val = LPC_ETHERNET->MAC_MII_DATA; - return (val); -} - - -// Keil: function added to initialize Rx Descriptors -void rx_descr_init (void) -{ - unsigned int i; - - for (i = 0; i < NUM_RX_DESC; i++) { - RX_DESC_STAT(i) = OWN_BIT; - RX_DESC_CTRL(i) = ETH_FRAG_SIZE; - RX_BUFADDR(i) = RX_BUF(i); - if (i == (NUM_RX_DESC-1)) // Last Descriptor? - RX_DESC_CTRL(i) |= RX_END_RING; - } - - /* Set Starting address of RX Descriptor list */ - LPC_ETHERNET->DMA_REC_DES_ADDR = RX_DESC_BASE; -} - - -// Keil: function added to initialize Tx Descriptors -void tx_descr_init (void) -{ - unsigned int i; - - for (i = 0; i < NUM_TX_DESC; i++) { // Take it out!!!! - TX_DESC_STAT(i) = 0; - TX_DESC_CTRL(i) = 0; - TX_BUFADDR(i) = 0; - } - - for (i = 0; i < NUM_TX_DESC; i++) { - TX_DESC_STAT(i) = TX_LAST_SEGM | TX_FIRST_SEGM; - TX_DESC_CTRL(i) = 0; - TX_BUFADDR(i) = TX_BUF(i); - if (i == (NUM_TX_DESC-1)) // Last Descriptor? - TX_DESC_STAT(i) |= TX_END_RING; - } - - /* Set Starting address of RX Descriptor list */ - LPC_ETHERNET->DMA_TRANS_DES_ADDR = TX_DESC_BASE; -} - - - -// configure port-pins for use with LAN-controller, -// reset it and send the configuration-sequence - -void Init_EMAC(void) -{ - int id1, id2, tout, regv; - unsigned phy_in_use = 0; - - /* Ethernet pins configuration */ -#if MII - scu_pinmux(0xC ,1 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_MDC: PC_1 -> FUNC3 - scu_pinmux(0x1 ,17 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_MDIO: P1_17 -> FUNC3 - scu_pinmux(0x1 ,18 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TXD0: P1_18 -> FUNC3 - scu_pinmux(0x1 ,20 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TXD1: P1_20 -> FUNC3 - scu_pinmux(0x1 ,19 , (MD_PLN | MD_EZI | MD_ZI), FUNC0); // ENET_REF: P1_19 -> FUNC0 (default) - -// scu_pinmux(0xC ,4 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TX_EN: PC_4 -> FUNC3 - scu_pinmux(0x0 ,1 , (MD_PLN | MD_EZI | MD_ZI), FUNC6); // ENET_TX_EN: P0_1 -> FUNC6 - - scu_pinmux(0x1 ,15 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RXD0: P1_15 -> FUNC3 - scu_pinmux(0x0 ,0 , (MD_PLN | MD_EZI | MD_ZI), FUNC2); // ENET_RXD1: P0_0 -> FUNC2 - -// scu_pinmux(0x1 ,16 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_CRS: P1_16 -> FUNC3 - scu_pinmux(0x9 ,0 , (MD_PLN | MD_EZI | MD_ZI), FUNC5); // ENET_CRS: P9_0 -> FUNC5 - -// scu_pinmux(0xC ,9 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RX_ER: PC_9 -> FUNC3 - scu_pinmux(0x9 ,1 , (MD_PLN | MD_EZI | MD_ZI), FUNC5); // ENET_RX_ER: P9_1 -> FUNC5 - -// scu_pinmux(0xC ,8 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RXDV: PC_8 -> FUNC3 - scu_pinmux(0x1 ,16 , (MD_PLN | MD_EZI | MD_ZI), FUNC7); // ENET_RXDV: P1_16 -> FUNC7 - -#else - scu_pinmux(0xC ,1 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_MDC: PC_1 -> FUNC3 - scu_pinmux(0x1 ,17 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_MDIO: P1_17 -> FUNC3 - scu_pinmux(0x1 ,18 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TXD0: P1_18 -> FUNC3 - scu_pinmux(0x1 ,20 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TXD1: P1_20 -> FUNC3 - scu_pinmux(0x1 ,19 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC0); // ENET_REF: P1_19 -> FUNC0 (default) -// scu_pinmux(0xC ,4 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TX_EN: PC_4 -> FUNC3 - scu_pinmux(0x0 ,1 , (MD_PLN | MD_EZI | MD_ZI), FUNC6); // ENET_TX_EN: P0_1 -> FUNC6 - scu_pinmux(0x1 ,15 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RXD0: P1_15 -> FUNC3 - scu_pinmux(0x0 ,0 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC2); // ENET_RXD1: P0_0 -> FUNC2 -// scu_pinmux(0x1 ,16 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_CRS: P1_16 -> FUNC3 -// scu_pinmux(0x9 ,0 , (MD_PLN | MD_EZI | MD_ZI), FUNC5); // ENET_CRS: P9_0 -> FUNC5 -// scu_pinmux(0xC ,9 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RX_ER: PC_9 -> FUNC3 -// scu_pinmux(0x9 ,1 , (MD_PLN | MD_EZI | MD_ZI), FUNC5); // ENET_RX_ER: P9_1 -> FUNC5 -// scu_pinmux(0xC ,8 , (MD_EHS | MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RXDV: PC_8 -> FUNC3 - scu_pinmux(0x1 ,16 , (MD_PLN | MD_EZI | MD_ZI), FUNC7); // ENET_RXDV: P1_16 -> FUNC7 -#endif - - -#if MII /* Select MII interface */ // check MUXING for new Eagle... -// scu_pinmux(0xC ,6 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RXD2: PC_6 -> FUNC3 - scu_pinmux(0x9 ,3 , (MD_PLN | MD_EZI | MD_ZI), FUNC5); // ENET_RXD2: P9_3 -> FUNC5 - -// scu_pinmux(0xC ,7 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RXD3: PC_7 -> FUNC3 - scu_pinmux(0x9 ,2 , (MD_PLN | MD_EZI | MD_ZI), FUNC5); // ENET_RXD3: P9_2 -> FUNC5 - - scu_pinmux(0xC ,0 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_RXLK: PC_0 -> FUNC3 - -// scu_pinmux(0xC ,2 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TXD2: PC_2 -> FUNC3 - scu_pinmux(0x9 ,4 , (MD_PLN | MD_EZI | MD_ZI), FUNC5); // ENET_TXD2: P9_4 -> FUNC5 - -// scu_pinmux(0xC ,3 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TXD3: PC_3 -> FUNC3 - scu_pinmux(0x9 ,5 , (MD_PLN | MD_EZI | MD_ZI), FUNC5); // ENET_TXD3: P9_5 -> FUNC5 - -// scu_pinmux(0xC ,5 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TX_ER: PC_5 -> FUNC3 - scu_pinmux(0xC ,5 , (MD_PLN | MD_EZI | MD_ZI), FUNC3); // ENET_TX_ER: PC_5 -> FUNC3 - -// scu_pinmux(0x0 ,1 , (MD_PLN | MD_EZI | MD_ZI), FUNC2); // ENET_COL: P0_1 -> FUNC2 - scu_pinmux(0x9 ,6 , (MD_PLN | MD_EZI | MD_ZI), FUNC5); // ENET_COL: P9_6 -> FUNC5 -#else /* Select RMII interface */ - LPC_CREG->CREG6 |= RMII_SELECT; -#endif - - - RGU_SoftReset(RGU_SIG_ETHERNET); - while(1){ // Confirm the reset happened - if (LPC_RGU->RESET_ACTIVE_STATUS0 & (1<<ETHERNET_RST)) - break; - } - - LPC_ETHERNET->DMA_BUS_MODE |= DMA_SOFT_RESET; // Reset all GMAC Subsystem internal registers and logic - while(LPC_ETHERNET->DMA_BUS_MODE & DMA_SOFT_RESET); // Wait for software reset completion - - /* Put the DP83848C in reset mode */ - write_PHY (PHY_REG_BMCR, PHY_BMCR_RESET); - - /* Wait for hardware reset to end. */ - for (tout = 0; tout < TIMEOUT; tout++) { - regv = read_PHY (PHY_REG_BMCR); - if (!(regv & PHY_BMCR_RESET)) { - /* Reset complete */ - break; - } - } - - /* Check if this is a DP83848C PHY. */ - id1 = read_PHY (PHY_REG_IDR1); - id2 = read_PHY (PHY_REG_IDR2); - if (((id1 << 16) | (id2 & 0xFFF0)) == DP83848C_ID) { - phy_in_use = DP83848C_ID; - } - else if (((id1 << 16) | (id2 & 0xFFF0)) == LAN8720_ID) { - phy_in_use = LAN8720_ID; - } - - if (phy_in_use != 0) { - /* Configure the PHY device */ -#if !MII - write_PHY (PHY_REG_RBR, 0x20); -#endif - - /* Use autonegotiation about the link speed. */ - write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG); - /* Wait to complete Auto_Negotiation. */ - for (tout = 0; tout < TIMEOUT; tout++) { - regv = read_PHY (PHY_REG_BMSR); - if (regv & PHY_AUTO_NEG_DONE) { - /* Autonegotiation Complete. */ - break; - } - } - } - - - - /* Check the link status. */ - for (tout = 0; tout < TIMEOUT; tout++) { - regv = read_PHY (PHY_REG_STS); - if (regv & LINK_VALID_STS) { - /* Link is on. */ - break; - } - } - - // Configure the EMAC with the established parameters - switch (phy_in_use) { - case DP83848C_ID: - - /* Configure Full/Half Duplex mode. */ - if (regv & FULL_DUP_STS) { - /* Full duplex is enabled. */ - LPC_ETHERNET->MAC_CONFIG |= MAC_DUPMODE; - } - - /* Configure 100MBit/10MBit mode. */ - if (~(regv & SPEED_10M_STS)) { - /* 100MBit mode. */ - LPC_ETHERNET->MAC_CONFIG |= MAC_100MPS; - } - -// value = ReadFromPHY (PHY_REG_STS); /* PHY Extended Status Register */ -// // Now configure for full/half duplex mode -// if (value & 0x0004) { -// // We are in full duplex is enabled mode -// LPC_ETHERNET->MAC2 |= MAC2_FULL_DUP; -// LPC_ETHERNET->Command |= CR_FULL_DUP; -// LPC_ETHERNET->IPGT = IPGT_FULL_DUP; -// } -// else { -// // Otherwise we are in half duplex mode -// LPC_ETHERNET->IPGT = IPGT_HALF_DUP; -// } - -// // Now configure 100MBit or 10MBit mode -// if (value & 0x0002) { -// // 10MBit mode -// LPC_ETHERNET->SUPP = 0; -// } -// else { -// // 100MBit mode -// LPC_ETHERNET->SUPP = SUPP_SPEED; -// } - break; - - case LAN8720_ID: - - regv = read_PHY (PHY_REG_SCSR); /* PHY Extended Status Register */ - // Now configure for full/half duplex mode - if (regv & (1<<4)) { /* bit 4: 1 = Full Duplex, 0 = Half Duplex */ - // We are in full duplex is enabled mode - LPC_ETHERNET->MAC_CONFIG |= MAC_DUPMODE; - } - - // Now configure 100MBit or 10MBit mode - if (regv & (1<<3)) { /* bit 3: 1 = 100Mbps, 0 = 10Mbps */ - // 100MBit mode - LPC_ETHERNET->MAC_CONFIG |= MAC_100MPS; - } - - - break; - - } - - /* Set the Ethernet MAC Address registers */ - LPC_ETHERNET->MAC_ADDR0_HIGH = (MYMAC_6 << 8) | MYMAC_5; - LPC_ETHERNET->MAC_ADDR0_LOW = (MYMAC_4 << 24) | (MYMAC_3 << 16) | (MYMAC_2 << 8) | MYMAC_1; - - /* Initialize Descriptor Lists */ - rx_descr_init(); - tx_descr_init(); - - /* Configure Filter */ - LPC_ETHERNET->MAC_FRAME_FILTER = MAC_PROMISCUOUS | MAC_RECEIVEALL; - - /* Enable Receiver and Transmitter */ - LPC_ETHERNET->MAC_CONFIG |= (MAC_TX_ENABLE | MAC_RX_ENABLE); - - /* Enable interrupts */ - //LPC_ETHERNET->DMA_INT_EN = DMA_INT_NOR_SUM | DMA_INT_RECEIVE | DMA_INT_TRANSMIT; - - /* Start Transmission & Receive processes */ - LPC_ETHERNET->DMA_OP_MODE |= (DMA_SS_TRANSMIT | DMA_SS_RECEIVE ); - -} - - -// reads a word in little-endian byte order from RX_BUFFER - -unsigned short ReadFrame_EMAC(void) -{ - return (*rptr++); -} - - -// easyWEB internal function -// help function to swap the byte order of a WORD - -unsigned short SwapBytes(unsigned short Data) -{ - return (Data >> 8) | (Data << 8); -} - -// reads a word in big-endian byte order from RX_FRAME_PORT -// (useful to avoid permanent byte-swapping while reading -// TCP/IP-data) - -unsigned short ReadFrameBE_EMAC(void) -{ - unsigned short ReturnValue; - - ReturnValue = SwapBytes (*rptr++); - return (ReturnValue); -} - - -// copies bytes from frame port to MCU-memory -// NOTES: * an odd number of byte may only be transfered -// if the frame is read to the end! -// * MCU-memory MUST start at word-boundary - -void CopyFromFrame_EMAC(void *Dest, unsigned short Size) -{ - unsigned short * piDest; // Keil: Pointer added to correct expression - - piDest = Dest; // Keil: Line added - while (Size > 1) { - *piDest++ = ReadFrame_EMAC(); - Size -= 2; - } - - if (Size) { // check for leftover byte... - *(unsigned char *)piDest = (char)ReadFrame_EMAC();// the LAN-Controller will return 0 - } // for the highbyte -} - -// does a dummy read on frame-I/O-port -// NOTE: only an even number of bytes is read! - -void DummyReadFrame_EMAC(unsigned short Size) // discards an EVEN number of bytes -{ // from RX-fifo - while (Size > 1) { - ReadFrame_EMAC(); - Size -= 2; - } -} - -// Reads the length of the received ethernet frame and checks if the -// destination address is a broadcast message or not -// returns the frame length -unsigned short StartReadFrame(void) { - unsigned short RxLen; - - if ((RX_DESC_STAT(RxDescIndex) & OWN_BIT) == 0) { - RxLen = (RX_DESC_STAT(RxDescIndex) >> 16) & 0x03FFF; - rptr = (unsigned short *)RX_BUFADDR(RxDescIndex); - return(RxLen); - } - return 0; - -} - -void EndReadFrame(void) { - - RX_DESC_STAT(RxDescIndex) = OWN_BIT; - RxDescIndex++; - if (RxDescIndex == NUM_RX_DESC) - RxDescIndex = 0; -} - -unsigned int CheckFrameReceived(void) { // Packet received ? - - if ((RX_DESC_STAT(RxDescIndex) & OWN_BIT) == 0) - return(1); - else - return(0); -} - -// requests space in EMAC memory for storing an outgoing frame - -void RequestSend(unsigned short FrameSize) -{ - tptr = (unsigned short *)TX_BUFADDR(TxDescIndex); - TX_DESC_CTRL(TxDescIndex) = FrameSize; -} - -// check if ethernet controller is ready to accept the -// frame we want to send - -unsigned int Rdy4Tx(void) -{ - return (1); // the ethernet controller transmits much faster -} // than the CPU can load its buffers - - -// writes a word in little-endian byte order to TX_BUFFER -void WriteFrame_EMAC(unsigned short Data) -{ - *tptr++ = Data; -} - -// copies bytes from MCU-memory to frame port -// NOTES: * an odd number of byte may only be transfered -// if the frame is written to the end! -// * MCU-memory MUST start at word-boundary - -void CopyToFrame_EMAC(void *Source, unsigned int Size) -{ - unsigned short * piSource; -// unsigned int idx; - - piSource = Source; - Size = (Size + 1) & 0xFFFE; // round Size up to next even number - while (Size > 0) { - WriteFrame_EMAC(*piSource++); - Size -= 2; - } - TX_DESC_STAT(TxDescIndex) |= OWN_BIT; - LPC_ETHERNET->DMA_TRANS_POLL_DEMAND = 1; // Wake Up the DMA if it's in Suspended Mode - TxDescIndex++; - if (TxDescIndex == NUM_TX_DESC) - TxDescIndex = 0; -} - -#endif - |
