Пример #1
0
/*********************************************************************//**
* @brief       Set specified PHY mode in EMAC peripheral
* @param[in]   ulPHYMode   Specified PHY mode, should be:
*                          - EMAC_MODE_AUTO
*                          - EMAC_MODE_10M_FULL
*                          - EMAC_MODE_10M_HALF
*                          - EMAC_MODE_100M_FULL
*                          - EMAC_MODE_100M_HALF
* @return      Return (0) if no error, otherwise return (-1)
**********************************************************************/
int32_t emac_SetPHYMode(uint32_t ulPHYMode)
{
    int32_t id1, id2, tout, regv;

    id1 = read_PHY (EMAC_PHY_REG_IDR1);
    id2 = read_PHY (EMAC_PHY_REG_IDR2);

    if (((id1 << 16) | (id2 & 0xFFF0)) == EMAC_SMSC_8720A) {
        switch(ulPHYMode){
            case EMAC_MODE_AUTO:
                write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
                /* Wait to complete Auto_Negotiation */
                for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
                    regv = read_PHY (EMAC_PHY_REG_BMSR);
                    if (regv & EMAC_PHY_BMSR_AUTO_DONE) {
                        /* Auto-negotiation Complete. */
                        break;
                    }
                    if (tout == 0){
                        // Time out, return error
                        return (-1);
                    }
                }
                break;
            case EMAC_MODE_10M_FULL:
                /* Connect at 10MBit full-duplex */
                write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_10M);
                break;
            case EMAC_MODE_10M_HALF:
                /* Connect at 10MBit half-duplex */
                write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_10M);
                break;
            case EMAC_MODE_100M_FULL:
                /* Connect at 100MBit full-duplex */
                write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_100M);
                break;
            case EMAC_MODE_100M_HALF:
                /* Connect at 100MBit half-duplex */
                write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_100M);
                break;
            default:
                // un-supported
                return (-1);
        }
    }
    // It's not correct module ID
    else {
        printf("PHY reports id %04lX %04lX - not an SMSC 8720A\n", id1, id2);
        return (-1);
    }

    // Update EMAC configuration with current PHY status
    if (EMAC_UpdatePHYStatus() < 0){
        return (-1);
    }

    // Complete
    return (0);
}
Пример #2
0
portBASE_TYPE Init_EMAC(void)
{
portBASE_TYPE xReturn = pdPASS;
static portBASE_TYPE xAttempt = 0;
// Keil: function modified to access the EMAC
// Initializes the EMAC ethernet controller
  volatile unsigned int regv,tout,id1,id2;

  /* Enable P1 Ethernet Pins. */
  PINSEL2 = configPINSEL2_VALUE;
  PINSEL3 = (PINSEL3 & ~0x0000000F) | 0x00000005;

  /* Power Up the EMAC controller. */
  PCONP |= 0x40000000;
  vTaskDelay( 1 );

  /* Reset all EMAC internal modules. */
  MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX |
             MAC1_SIM_RES | MAC1_SOFT_RES;
  Command = CR_REG_RES | CR_TX_RES | CR_RX_RES;

  /* A short delay after reset. */
  vTaskDelay( 1 );

  /* Initialize MAC control registers. */
  MAC1 = MAC1_PASS_ALL;
  MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
  MAXF = ETH_MAX_FLEN;
  CLRT = CLRT_DEF;
  IPGR = IPGR_DEF;

  /* Enable Reduced MII interface. */
  Command = CR_RMII | CR_PASS_RUNT_FRM;

  /* Reset Reduced MII Logic. */
  SUPP = SUPP_RES_RMII;
  SUPP = 0;

  /* Put the DP83848C in reset mode */
  write_PHY (PHY_REG_BMCR, 0x8000);
  write_PHY (PHY_REG_BMCR, 0x8000);

  /* Wait for hardware reset to end. */
  for (tout = 0; tout < 100; tout++) {
    vTaskDelay( 10 );
    regv = read_PHY (PHY_REG_BMCR);
    if (!(regv & 0x8000)) {
      /* 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) {
    /* Configure the PHY device */

    /* Use autonegotiation about the link speed. */
    write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
    /* Wait to complete Auto_Negotiation. */
    for (tout = 0; tout < 10; tout++) {
      vTaskDelay( 100 );
      regv = read_PHY (PHY_REG_BMSR);
      if (regv & 0x0020) {
        /* Autonegotiation Complete. */
        break;
      }
    }
  }
  else
  {
    xReturn = pdFAIL;
  }

  /* Check the link status. */
  if( xReturn == pdPASS )
  {
    xReturn = pdFAIL;
    for (tout = 0; tout < 10; tout++) {
      vTaskDelay( 100 );
      regv = read_PHY (PHY_REG_STS);
      if (regv & 0x0001) {
        /* Link is on. */
        xReturn = pdPASS;
        break;
      }
    }
  }

  if( xReturn == pdPASS )
  {
    /* Configure Full/Half Duplex mode. */
    if (regv & 0x0004) {
      /* Full duplex is enabled. */
      MAC2    |= MAC2_FULL_DUP;
      Command |= CR_FULL_DUP;
      IPGT     = IPGT_FULL_DUP;
    }
    else {
      /* Half duplex mode. */
      IPGT = IPGT_HALF_DUP;
    }

    /* Configure 100MBit/10MBit mode. */
    if (regv & 0x0002) {
      /* 10MBit mode. */
      SUPP = 0;
    }
    else {
      /* 100MBit mode. */
      SUPP = SUPP_SPEED;
    }

    /* Set the Ethernet MAC Address registers */
    SA0 = (emacETHADDR0 << 8) | emacETHADDR1;
    SA1 = (emacETHADDR2 << 8) | emacETHADDR3;
    SA2 = (emacETHADDR4 << 8) | emacETHADDR5;

    /* Initialize Tx and Rx DMA Descriptors */
    rx_descr_init ();
    tx_descr_init ();

    /* Receive Broadcast and Perfect Match Packets */
    RxFilterCtrl = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;

    /* Create the semaphore used ot wake the uIP task. */
    vSemaphoreCreateBinary( xEMACSemaphore );

    /* Reset all interrupts */
    IntClear  = 0xFFFF;

    /* Enable receive and transmit mode of MAC Ethernet core */
    Command  |= (CR_RX_EN | CR_TX_EN);
    MAC1     |= MAC1_REC_EN;
  }

  return xReturn;
}
Пример #3
0
void init_ethernet (void) {
   /* Initialize the EMAC ethernet controller. */
   U32 tout,regv;

   /* Enable and Reset the Ethernet Controller */
   SysCtlPeripheralEnable (SYSCTL_PERIPH_ETH);
   SysCtlPeripheralReset (SYSCTL_PERIPH_ETH);

   /* Enable Port F for Ethernet LEDs */
   //SysCtlPeripheralEnable (SYSCTL_PERIPH_GPIOF);
   //GPIODirModeSet  (GPIO_PORTF_BASE, (GPIO_PIN_2 | GPIO_PIN_3),GPIO_DIR_MODE_HW);
   //GPIOPadConfigSet(GPIO_PORTF_BASE, (GPIO_PIN_2 | GPIO_PIN_3),GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);

   /* Disable all Ethernet Interrupts */
   pEMAC->IEN = 0;
   pEMAC->ISR = INT_ALL;

   /* Set MII interface clock (max. 2.5MHz) */
   pEMAC->MCDIV = 10;

   /* Put the PHY in reset mode */
   write_PHY (PHY_REG_CTRL, 0x8000);

   /* Wait for hardware reset to end. */
   for (tout = 0; tout < 0x20000; tout++) {
      regv = read_PHY (PHY_REG_CTRL);
      if (!(regv & 0x8000)) {
         /* Reset complete. */
         break;
      }
   }

#if defined (_10MBIT_)
   /* Connect at 10MBit */
   write_PHY (PHY_REG_CTRL, PHY_FULLD_10M);
#elif defined (_100MBIT_)
   /* Connect at 100MBit */
   write_PHY (PHY_REG_CTRL, PHY_FULLD_100M);
#else
   /* Use autonegotiation about the link speed. */
   write_PHY (PHY_REG_CTRL, PHY_AUTO_NEG);
   /* Wait to complete Auto_Negotiation. */
   for (tout = 0; tout < 0x20000; tout++) {
      regv = read_PHY (PHY_REG_STAT);
      if (regv & 0x0020) {
         /* Autonegotiation Complete. */
         break;
      }
   }
#endif

   /* Check the link status. */
   for (tout = 0; tout < 0x10000; tout++) {
      regv = read_PHY (PHY_REG_STAT);
      if (regv & 0x0004) {
         /* Link is on. */
         break;
      }
   }

   /* Configure TX/RX Control Registers, enable Multicast. */
   pEMAC->RXCTL = RXCTL_BAD_CRC | RXCTL_RST_FIFO | RXCTL_MCAST_EN;
   pEMAC->TXCTL = TXCTL_PAD_EN  | TXCTL_CRC_EN;

   /* Configure Full/Half Duplex mode. */
   if (regv & 0x0800) {
      /* Full duplex is enabled. */
      pEMAC->TXCTL |= TXCTL_DUP_EN;
   }

   /* Set the Ethernet MAC Address registers */
   pEMAC->IAR0 = ((U32)own_hw_adr[3] << 24) | ((U32)own_hw_adr[2] << 16) |
                 ((U32)own_hw_adr[1] << 8)  |  (U32)own_hw_adr[0];

   pEMAC->IAR1 = ((U32)own_hw_adr[5] << 8)  |  (U32)own_hw_adr[4];

   /* Enable the Ethernet Controller */
   pEMAC->RXCTL |= RXCTL_RX_EN;
   pEMAC->TXCTL |= TXCTL_TX_EN;

   /* Enable Interrupts */
   pEMAC->IEN = INT_RX;
   IntEnable(INT_ETH);
}
Пример #4
0
void Init_EMAC(void)
{
  int id1, id2, tout, regv;

 /* Ethernet pins configuration		*/
    scu_pinmux(0xC,  1, MD_PLN_FAST, FUNC3);    // ENET_MDC: PC_1 -> FUNC3
    scu_pinmux(0x1, 17, MD_PLN_FAST, FUNC3);    // ENET_MDIO: P1_17 -> FUNC3
    scu_pinmux(0x1, 18, MD_PLN_FAST, FUNC3);    // ENET_TXD0: P1_18 -> FUNC3
    scu_pinmux(0x1, 20, MD_PLN_FAST, FUNC3);    // ENET_TXD1: P1_20 -> FUNC3
    scu_pinmux(0x1, 19, MD_PLN_FAST, FUNC0);    // ENET_REF: P1_19 -> FUNC0
    scu_pinmux(0x0,  1, MD_PLN_FAST, FUNC6);    // ENET_TX_EN: P0_1 -> FUNC6
    scu_pinmux(0x1, 15, MD_PLN_FAST, FUNC3);    // ENET_RXD0: P1_15 -> FUNC3
    scu_pinmux(0x0,  0, MD_PLN_FAST, FUNC2);    // ENET_RXD1: P0_0 -> FUNC2
    scu_pinmux(0x1, 16, MD_PLN_FAST, FUNC3);    // ENET_CRS: P1_16 -> FUNC3
    scu_pinmux(0xC,  9, MD_PLN_FAST, FUNC3);    // ENET_RX_ER: PC_9 -> FUNC3
    scu_pinmux(0xC,  8, MD_PLN_FAST, FUNC3);    // ENET_RXDV: PC_8 -> FUNC3

    /*   Select MII interface       */
    scu_pinmux(0x9,  3, MD_PLN_FAST, FUNC5);    // ENET_RXD2: P9_3 -> FUNC5
    scu_pinmux(0x9,  2, MD_PLN_FAST, FUNC5);    // ENET_RXD3: P9_2 -> FUNC5
    scu_pinmux(0xC,  0, MD_PLN_FAST, FUNC3);    // ENET_RXCLK: PC_0 -> FUNC3
    scu_pinmux(0xC,  2, MD_PLN_FAST, FUNC3);    // ENET_TXD2: PC_2 -> FUNC3
    scu_pinmux(0xC,  3, MD_PLN_FAST, FUNC3);    // ENET_TXD3: PC_3 -> FUNC3
    scu_pinmux(0xC,  5, MD_PLN_FAST, FUNC3);    // ENET_TX_ER:  PC_5 -> FUNC3
    scu_pinmux(0x9,  6, MD_PLN_FAST, FUNC5);    // ENET_COL: P9_6 -> FUNC5

  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) {

	/* Configure the PHY device */

    /* 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 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;
  }
 
  /* 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 );		 

}
Пример #5
0
/*
TX_EN     P1_4
TXD0      P1_0
TXD1      P1_1

RXD0      P1_9
RXD1      P1_10
RX_ER     P1_14
CRS_DV    P1_8

MDC       P1_16
MDIO      P1_17

REF_CLK   P1_15
*/
static rt_err_t lpc_emac_init(rt_device_t dev)
{
    /* Initialize the EMAC ethernet controller. */
    rt_uint32_t regv, tout;

    /* Power Up the EMAC controller. */
    LPC_SC->PCONP |= (1UL << 30);

    /* Enable P1 Ethernet Pins. */
    PINSEL_ConfigPin(1, 0, 1);  /**< P1_0  ENET_TXD0 */
    PINSEL_ConfigPin(1, 1, 1);  /**< P1_1  ENET_TXD1 */
    PINSEL_ConfigPin(1, 4, 1);  /**< P1_4  ENET_TX_EN */
    PINSEL_ConfigPin(1, 8, 1);  /**< P1_8  ENET_CRS_DV */
    PINSEL_ConfigPin(1, 9, 1);  /**< P1_9  ENET_RXD0 */
    PINSEL_ConfigPin(1, 10, 1); /**< P1_10 ENET_RXD1 */
    PINSEL_ConfigPin(1, 14, 1); /**< P1_14 ENET_RX_ER */
    PINSEL_ConfigPin(1, 15, 1); /**< P1_15 ENET_REF_CLK */
    PINSEL_ConfigPin(1, 16, 1); /**< P1_16 ENET_MDC */
    PINSEL_ConfigPin(1, 17, 1); /**< P1_17 ENET_MDIO */

    /* Reset all EMAC internal modules. */
    LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX |
                     MAC1_SIM_RES | MAC1_SOFT_RES;
    LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES;

    /* A short delay after reset. */
    for (tout = 100; tout; tout--);

    /* Initialize MAC control registers. */
    LPC_EMAC->MAC1 = MAC1_PASS_ALL;
    LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
    LPC_EMAC->MAXF = ETH_MAX_FLEN;
    LPC_EMAC->CLRT = CLRT_DEF;
    LPC_EMAC->IPGR = IPGR_DEF;

    /* PCLK=18MHz, clock select=6, MDC=18/6=3MHz */
    /* Enable Reduced MII interface. */
    LPC_EMAC->MCFG = MCFG_CLK_DIV20 | MCFG_RES_MII;
    for (tout = 100; tout; tout--);
    LPC_EMAC->MCFG = MCFG_CLK_DIV20;

    /* Enable Reduced MII interface. */
    LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM | CR_PASS_RX_FILT;

    /* Reset Reduced MII Logic. */
    LPC_EMAC->SUPP = SUPP_RES_RMII | SUPP_SPEED;
    for (tout = 100; tout; tout--);
    LPC_EMAC->SUPP = SUPP_SPEED;

    /* Put the PHY in reset mode */
    write_PHY(PHY_REG_BMCR, 0x8000);
    for (tout = 1000; tout; tout--);

    /* Configure the PHY device */
    /* Configure the PHY device */
    switch (lpc_emac_device.phy_mode)
    {
    case EMAC_PHY_AUTO:
        /* Use autonegotiation about the link speed. */
        write_PHY(PHY_REG_BMCR, PHY_AUTO_NEG);
        break;
    case EMAC_PHY_10MBIT:
        /* Connect at 10MBit */
        write_PHY(PHY_REG_BMCR, PHY_FULLD_10M);
        break;
    case EMAC_PHY_100MBIT:
        /* Connect at 100MBit */
        write_PHY(PHY_REG_BMCR, PHY_FULLD_100M);
        break;
    }
    if (tout >= 0x100000) return -RT_ERROR; // auto_neg failed

    regv = 0x0004;
    /* Configure Full/Half Duplex mode. */
    if (regv & 0x0004)
    {
        /* Full duplex is enabled. */
        LPC_EMAC->MAC2    |= MAC2_FULL_DUP;
        LPC_EMAC->Command |= CR_FULL_DUP;
        LPC_EMAC->IPGT     = IPGT_FULL_DUP;
    }
    else
    {
        /* Half duplex mode. */
        LPC_EMAC->IPGT = IPGT_HALF_DUP;
    }

    /* Configure 100MBit/10MBit mode. */
    if (regv & 0x0002)
    {
        /* 10MBit mode. */
        LPC_EMAC->SUPP = 0;
    }
    else
    {
        /* 100MBit mode. */
        LPC_EMAC->SUPP = SUPP_SPEED;
    }

    /* Set the Ethernet MAC Address registers */
    LPC_EMAC->SA0 = (lpc_emac_device.dev_addr[1] << 8) | lpc_emac_device.dev_addr[0];
    LPC_EMAC->SA1 = (lpc_emac_device.dev_addr[3] << 8) | lpc_emac_device.dev_addr[2];
    LPC_EMAC->SA2 = (lpc_emac_device.dev_addr[5] << 8) | lpc_emac_device.dev_addr[4];

    /* Initialize Tx and Rx DMA Descriptors */
    rx_descr_init();
    tx_descr_init();

    /* Receive Broadcast and Perfect Match Packets */
    LPC_EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN;

    /* Reset all interrupts */
    LPC_EMAC->IntClear  = 0xFFFF;

    /* Enable EMAC interrupts. */
    LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE;

    /* Enable receive and transmit mode of MAC Ethernet core */
    LPC_EMAC->Command  |= (CR_RX_EN | CR_TX_EN);
    LPC_EMAC->MAC1     |= MAC1_REC_EN;

    /* Enable the ENET Interrupt */
    NVIC_EnableIRQ(ENET_IRQn);

    return RT_EOK;
}
Пример #6
0
void init_ethernet (void) {
  /* Initialize the EMAC ethernet controller. */
  U32 regv,tout,id1,id2;

  /* Enable Peripheral Clock for EMAC Peripherals */
  pPMC->PMC_PCER  = (1 << AT91C_ID_PIOA) | (1 << AT91C_ID_EMAC);

  /* Select PHY address 0 */
  pPIOA->PIO_IDR   =
  pPIOA->PIO_PPUDR =
  pPIOA->PIO_MDDR  =
  pPIOA->PIO_OER   =
  pPIOA->PIO_PER   =
  pPIOA->PIO_CODR  = AT91C_PA14_ERX0 | AT91C_PA15_ERX1 | AT91C_PA25_ERX2 |
                     AT91C_PA26_ERX3 | AT91C_PA28_ECRS | AT91C_PA17_ERXDV;

  /* After PHY power up, hardware reset the PHY */
  pRSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST;

  /* Wait for hardware reset to end. */
  while (!(pRSTC->RSTC_RSR & AT91C_RSTC_NRSTL));

  /* EMAC IO init for EMAC-PHY communication in RMII. */
  pPIOA->PIO_IDR   =
  pPIOA->PIO_PPUDR =
  pPIOA->PIO_PDR   =
  pPIOA->PIO_ASR   = AT91C_PA12_ETX0  | AT91C_PA13_ETX1  | AT91C_PA14_ERX0  |
                     AT91C_PA15_ERX1  | AT91C_PA16_ETXEN | AT91C_PA17_ERXDV |
                     AT91C_PA18_ERXER | AT91C_PA20_EMDC  | AT91C_PA21_EMDIO;

  /* Enable communication between EMAC-PHY. */
  enable_MDI ();
  /* Put the DM9161 in reset mode */
  write_PHY (PHY_REG_BMCR, BMCR_RESET);

  /* Wait for hardware reset to end. */
  for (tout = 0; tout < 0x200000; tout++) {
    regv = read_PHY (PHY_REG_BMCR);
    if (!(regv & BMCR_RESET)) {
      /* Reset complete */
      break;
    }
  }

  /* Check if this is a DM9161 PHY. */
  id1 = read_PHY (PHY_REG_PHYID1);
  id2 = read_PHY (PHY_REG_PHYID2);

  if (((id1 << 16) | (id2 & 0xfff0)) == MII_DM9161_ID) {
    /* Configure the PHY device */
#if defined (_10MBIT_)
    /* Connect at 10MBit */
    write_PHY (PHY_REG_BMCR, PHY_FULLD_10M);
    write_PHY (PHY_REG_DSCR, 0x0000);
#elif defined (_100MBIT_)
    /* Connect at 100MBit */
    write_PHY (PHY_REG_BMCR, PHY_FULLD_100M);
    write_PHY (PHY_REG_DSCR, 0x0400);
#else
    /* Use autonegotiation about the link speed. */
    write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
    /* Wait to complete Auto_Negotiation. */
    for (tout = 0; tout < 0x200000; tout++) {
      regv = read_PHY (PHY_REG_BMSR);
      if (regv & BMSR_ANEGCOMPLETE) {
        /* ANEG_ACK set, autonegotiation finished. */
        break;
      }
    }
    /* Check the link status. */
    for (tout = 0; tout < 0x20000; tout++) {
      regv = read_PHY (PHY_REG_BMSR);
      if (regv & BMSR_LINKST) {
        /* Link is on. */
        break;
      }
    }
#endif
  }

  /* Update the MAC register NCFGR. */
  pEMAC->EMAC_NCFGR = 0;
  regv = read_PHY (PHY_REG_BMCR);

  if (regv & BMCR_SPEED100) {
    /* Speed 100Mbit is enabled. */
    pEMAC->EMAC_NCFGR |= AT91C_EMAC_SPD;
  }
  if (regv & BMCR_FULLDPLX) {
    /* Full duplex is enabled. */
    pEMAC->EMAC_NCFGR |= AT91C_EMAC_FD;
  }

  disable_MDI ();

  /* Enable EMAC in RMII mode. */
  pEMAC->EMAC_USRIO= AT91C_EMAC_CLKEN | AT91C_EMAC_RMII;

  /* Transmit and Receive disable. */
  pEMAC->EMAC_NCR &= ~(AT91C_EMAC_RE | AT91C_EMAC_TE);

  /* Initialize Tx and Rx DMA Descriptors */
  rx_descr_init ();
  tx_descr_init ();

  /* The sequence write EMAC_SA1L and write EMAC_SA1H must be respected. */
  pEMAC->EMAC_SA1L = ((U32)own_hw_adr[3] << 24) | ((U32)own_hw_adr[2] << 16) |
                     ((U32)own_hw_adr[1] << 8)  |  (U32)own_hw_adr[0];
  pEMAC->EMAC_SA1H = ((U32)own_hw_adr[5] << 8)  |  (U32)own_hw_adr[4];

  /* Enable receiving of all Multicast packets. */
  pEMAC->EMAC_HRB  = 0xFFFFFFFF;
  pEMAC->EMAC_HRT  = 0xFFFFFFFF;

  /* Clear receive and transmit status registers. */
  pEMAC->EMAC_RSR  = (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
  pEMAC->EMAC_TSR  = (AT91C_EMAC_UND | AT91C_EMAC_COMP| AT91C_EMAC_BEX |
                      AT91C_EMAC_RLES| AT91C_EMAC_COL | AT91C_EMAC_UBR);

  /* Configure EMAC operation mode, enable Multicast. */
  pEMAC->EMAC_NCFGR |= (AT91C_EMAC_BIG | AT91C_EMAC_DRFCS | AT91C_EMAC_MTI);
  pEMAC->EMAC_NCR   |= (AT91C_EMAC_TE  | AT91C_EMAC_RE | AT91C_EMAC_WESTAT);

  /* Configure the EMAC Interrupts. */
  pEMAC->EMAC_IDR  = 0x3fff;
  /* Allow RCOMP, RXUBR and ROVR interrupts. */
  pEMAC->EMAC_IER  = AT91C_EMAC_RCOMP | AT91C_EMAC_ROVR | AT91C_EMAC_RXUBR;

  /* Enable EMAC interrupts. */
  pAIC->AIC_IDCR   = (1 << AT91C_ID_EMAC);
  pAIC->AIC_SVR[AT91C_ID_EMAC] = (U32)interrupt_ethernet;
  pAIC->AIC_SMR[AT91C_ID_EMAC] = AT91C_AIC_PRIOR_HIGHEST;
  pAIC->AIC_ICCR   = (1 << AT91C_ID_EMAC);
  pAIC->AIC_SPU    = (U32)def_interrupt;
}
		void Init_EMAC(void)
		{
		// Keil: function modified to access the EMAC
		// Initializes the EMAC ethernet controller
		  unsigned int regv,tout,id1,id2;
		
		   /* Power Up the EMAC controller. */
		   PCONP |= 0x40000000;
		
		  /* Enable P1 Ethernet Pins. */
		  if (MAC_MODULEID == OLD_EMAC_MODULE_ID) { 
		    /* For the first silicon rev.'-' ID P1.6 should be set. */
		    PINSEL2 = 0x50151105;
		  }
		  else {
		    /* on rev. 'A' and later, P1.6 should NOT be set. */
		    PINSEL2 = 0x50150105;
		  }
		  PINSEL3 = (PINSEL3 & ~0x0000000F) | 0x00000005;
		
		  /* Reset all EMAC internal modules. */
		  MAC_MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX |
		             MAC1_SIM_RES | MAC1_SOFT_RES;
		  MAC_COMMAND = CR_REG_RES | CR_TX_RES | CR_RX_RES;
		
		  /* A short delay after reset. */
		  for (tout = 100; tout; tout--);
		
		  /* Initialize MAC control registers. */
		  MAC_MAC1 = MAC1_PASS_ALL;
		  MAC_MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
		  MAC_MAXF = ETH_MAX_FLEN;
		  MAC_CLRT = CLRT_DEF;
		  MAC_IPGR = IPGR_DEF;
		
		  /* Enable Reduced MII interface. */
		  MAC_COMMAND = CR_RMII | CR_PASS_RUNT_FRM;
		
		  /* Reset Reduced MII Logic. */
		  MAC_SUPP = SUPP_RES_RMII;
		  for (tout = 100; tout; tout--);
		  MAC_SUPP = 0;
		
		  /* Put the DP83848C in reset mode */
		  write_PHY (PHY_REG_BMCR, 0x8000);
        
        //Allow NIC to power up. (Could get bullshit otherwise)
        //Parameter T2.1.1 http://www.national.com/ds/DP/DP83848C.pdf
        sleep(200);
		
		  /* Wait for hardware reset to end. */
		  for (tout = 0; tout < 0x100000; tout++) {
		    regv = read_PHY (PHY_REG_BMCR);
		    if (!(regv & 0x8000)) {
		      /* 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) {
		    /* Configure the PHY device */
		
		    /* Use autonegotiation about the link speed. */
		    write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
		    /* Wait to complete Auto_Negotiation. */
		    for (tout = 0; tout < 0x100000; tout++) {
		      regv = read_PHY (PHY_REG_BMSR);
		      if (regv & 0x0020) {
		        /* Autonegotiation Complete. */
		        break;
		      }
		    }
		  }
		
		  /* Check the link status. */
		  for (tout = 0; tout < 0x10000; tout++) {
		    regv = read_PHY (PHY_REG_STS);
		    if (regv & 0x0001) {
		      /* Link is on. */
		      break;
		    }
		  }
		
		  /* Configure Full/Half Duplex mode. */
		  if (regv & 0x0004) {
		    /* Full duplex is enabled. */
		    MAC_MAC2    |= MAC2_FULL_DUP;
		    MAC_COMMAND |= CR_FULL_DUP;
		    MAC_IPGT     = IPGT_FULL_DUP;
		  }
		  else {
		    /* Half duplex mode. */
		    MAC_IPGT = IPGT_HALF_DUP;
		  }
		
		  /* Configure 100MBit/10MBit mode. */
		  if (regv & 0x0002) {
		    /* 10MBit mode. */
		    MAC_SUPP = 0;
		  }
		  else {
		    /* 100MBit mode. */
		    MAC_SUPP = SUPP_SPEED;
		  }
		
		  /* Set the Ethernet MAC Address registers */
        uint8_t * addr = myAddress.getRaw();
		  MAC_SA0 = (addr[5] << 8) | addr[4];
		  MAC_SA1 = (addr[3] << 8) | addr[2];
		  MAC_SA2 = (addr[1] << 8) | addr[0];
		
		  /* Initialize Tx and Rx DMA Descriptors */
		  rx_descr_init ();
		  tx_descr_init ();
		
		  /* Receive Broadcast and Perfect Match Packets */
		  MAC_RXFILTERCTRL = RFC_BCAST_EN | RFC_MCAST_EN | RFC_PERFECT_EN;
		
		  /* Enable EMAC interrupts. */
		  MAC_INTENABLE = 0xFF;//INT_RX_DONE | INT_TX_DONE | INT_RX_OVERRUN;
		
		  /* Reset all interrupts */
		  MAC_INTCLEAR  = 0xFFFF;
		
		  /* Enable receive and transmit mode of MAC Ethernet core */
		  MAC_COMMAND  |= (CR_RX_EN | CR_TX_EN);
		  MAC_MAC1     |= MAC1_REC_EN;
		}
Пример #8
0
static rt_err_t lpc17xx_emac_init(rt_device_t dev)
{
	/* Initialize the EMAC ethernet controller. */
	rt_uint32_t regv, tout, id1, id2;

	/* Power Up the EMAC controller. */
	LPC_SC->PCONP |= 0x40000000;

	/* Enable P1 Ethernet Pins. */
	LPC_PINCON->PINSEL2 = 0x50150105;
	LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000005;

	/* Reset all EMAC internal modules. */
	LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX |
				 MAC1_SIM_RES | MAC1_SOFT_RES;
	LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES;

	/* A short delay after reset. */
	for (tout = 100; tout; tout--);

	/* Initialize MAC control registers. */
	LPC_EMAC->MAC1 = MAC1_PASS_ALL;
	LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
	LPC_EMAC->MAXF = ETH_MAX_FLEN;
	LPC_EMAC->CLRT = CLRT_DEF;
	LPC_EMAC->IPGR = IPGR_DEF;

	/* PCLK=18MHz, clock select=6, MDC=18/6=3MHz */
	/* Enable Reduced MII interface. */
	LPC_EMAC->MCFG = MCFG_CLK_DIV20 | MCFG_RES_MII;
	for (tout = 100; tout; tout--);
	LPC_EMAC->MCFG = MCFG_CLK_DIV20;

	/* Enable Reduced MII interface. */
	LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM | CR_PASS_RX_FILT;

	/* Reset Reduced MII Logic. */
	LPC_EMAC->SUPP = SUPP_RES_RMII | SUPP_SPEED;
	for (tout = 100; tout; tout--);
	LPC_EMAC->SUPP = SUPP_SPEED;

	/* Put the PHY in reset mode */
	write_PHY (PHY_REG_BMCR, 0x8000);
	for (tout = 1000; tout; tout--);

	/* Wait for hardware reset to end. */
	for (tout = 0; tout < 0x100000; tout++)
	{
		regv = read_PHY (PHY_REG_BMCR);
		if (!(regv & 0x8000))
		{
			/* Reset complete */
			break;
		}
	}
	if (tout >= 0x100000) return -RT_ERROR; /* reset failed */

	/* 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)
		return -RT_ERROR;

	/* Configure the PHY device */
	/* Configure the PHY device */
	switch (lpc17xx_emac_device.phy_mode)
	{
	case EMAC_PHY_AUTO:
		/* Use auto negotiation about the link speed. */
		write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
		/* Wait to complete Auto_Negotiation. */
		for (tout = 0; tout < 0x100000; tout++)
		{
			regv = read_PHY (PHY_REG_BMSR);
			if (regv & 0x0020)
			{
				/* Auto negotiation Complete. */
				break;
			}
		}
		break;
	case EMAC_PHY_10MBIT:
		/* Connect at 10MBit */
		write_PHY (PHY_REG_BMCR, PHY_FULLD_10M);
		break;
	case EMAC_PHY_100MBIT:
		/* Connect at 100MBit */
		write_PHY (PHY_REG_BMCR, PHY_FULLD_100M);
		break;
	}
	if (tout >= 0x100000) return -RT_ERROR; // auto_neg failed

	/* Check the link status. */
	for (tout = 0; tout < 0x10000; tout++)
	{
		regv = read_PHY (PHY_REG_STS);
		if (regv & 0x0001)
		{
			/* Link is on. */
			break;
		}
	}
	if (tout >= 0x10000) return -RT_ERROR;

	/* Configure Full/Half Duplex mode. */
	if (regv & 0x0004)
	{
		/* Full duplex is enabled. */
		LPC_EMAC->MAC2    |= MAC2_FULL_DUP;
		LPC_EMAC->Command |= CR_FULL_DUP;
		LPC_EMAC->IPGT     = IPGT_FULL_DUP;
	}
	else
	{
		/* Half duplex mode. */
		LPC_EMAC->IPGT = IPGT_HALF_DUP;
	}

	/* Configure 100MBit/10MBit mode. */
	if (regv & 0x0002)
	{
		/* 10MBit mode. */
		LPC_EMAC->SUPP = 0;
	}
	else
	{
		/* 100MBit mode. */
		LPC_EMAC->SUPP = SUPP_SPEED;
	}

	/* Set the Ethernet MAC Address registers */
	LPC_EMAC->SA0 = (lpc17xx_emac_device.dev_addr[1]<<8) | lpc17xx_emac_device.dev_addr[0];
	LPC_EMAC->SA1 = (lpc17xx_emac_device.dev_addr[3]<<8) | lpc17xx_emac_device.dev_addr[2];
	LPC_EMAC->SA2 = (lpc17xx_emac_device.dev_addr[5]<<8) | lpc17xx_emac_device.dev_addr[4];

	/* Initialize Tx and Rx DMA Descriptors */
	rx_descr_init ();
	tx_descr_init ();

	/* Receive Broadcast and Perfect Match Packets */
	LPC_EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN;

	/* Reset all interrupts */
	LPC_EMAC->IntClear  = 0xFFFF;

	/* Enable EMAC interrupts. */
	LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE;

	/* Enable receive and transmit mode of MAC Ethernet core */
	LPC_EMAC->Command  |= (CR_RX_EN | CR_TX_EN);
	LPC_EMAC->MAC1     |= MAC1_REC_EN;

	/* Enable the ENET Interrupt */
	NVIC_EnableIRQ(ENET_IRQn);

	return RT_EOK;
}
Пример #9
0
/*
TX_EN     P1_4
TXD0      P1_0
TXD1      P1_1

RXD0      P1_9
RXD1      P1_10
RX_ER     P1_14
CRS_DV    P1_8

MDC       P1_16
MDIO      P1_17

PHY_RESET P3_19
REF_CLK   P1_15
*/
static rt_err_t lpc17xx_emac_init(rt_device_t dev)
{
	/* Initialize the EMAC ethernet controller. */
	rt_uint32_t regv, tout;

	/* Power Up the EMAC controller. */
	LPC_SC->PCONP |= (1UL<<30);

	/* config RESET */
	PINSEL_ConfigPin(3, 19, 0);
	PINSEL_SetPinMode(3, 19, IOCON_MODE_PLAIN);
	LPC_GPIO3->DIR |= 1<<19;
	LPC_GPIO3->CLR = 1<<19;

	/* Enable P1 Ethernet Pins. */
	PINSEL_ConfigPin(1, 0, 1);  /**< P1_0  ENET_TXD0 */
	PINSEL_ConfigPin(1, 1, 1);  /**< P1_1  ENET_TXD1 */
	PINSEL_ConfigPin(1, 4, 1);  /**< P1_4  ENET_TX_EN */
	PINSEL_ConfigPin(1, 8, 1);  /**< P1_8  ENET_CRS_DV */
	PINSEL_ConfigPin(1, 9, 1);  /**< P1_9  ENET_RXD0 */
	PINSEL_ConfigPin(1, 10, 1); /**< P1_10 ENET_RXD1 */
	PINSEL_ConfigPin(1, 14, 1); /**< P1_14 ENET_RX_ER */
	PINSEL_ConfigPin(1, 15, 1); /**< P1_15 ENET_REF_CLK */
	PINSEL_ConfigPin(1, 16, 1); /**< P1_16 ENET_MDC */
	PINSEL_ConfigPin(1, 17, 1); /**< P1_17 ENET_MDIO */

	LPC_GPIO3->SET = 1<<19;

	/* Reset all EMAC internal modules. */
	LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX |
				 MAC1_SIM_RES | MAC1_SOFT_RES;
	LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES;

	/* A short delay after reset. */
	for (tout = 100; tout; tout--);

	/* Initialize MAC control registers. */
	LPC_EMAC->MAC1 = MAC1_PASS_ALL;
	LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
	LPC_EMAC->MAXF = ETH_MAX_FLEN;
	LPC_EMAC->CLRT = CLRT_DEF;
	LPC_EMAC->IPGR = IPGR_DEF;

	/* PCLK=18MHz, clock select=6, MDC=18/6=3MHz */
	/* Enable Reduced MII interface. */
	LPC_EMAC->MCFG = MCFG_CLK_DIV20 | MCFG_RES_MII;
	for (tout = 100; tout; tout--);
	LPC_EMAC->MCFG = MCFG_CLK_DIV20;

	/* Enable Reduced MII interface. */
	LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM | CR_PASS_RX_FILT;

	/* Reset Reduced MII Logic. */
	LPC_EMAC->SUPP = SUPP_RES_RMII | SUPP_SPEED;
	for (tout = 100; tout; tout--);
	LPC_EMAC->SUPP = SUPP_SPEED;

	/* Put the PHY in reset mode */
	write_PHY (PHY_REG_BMCR, 0x8000);
	for (tout = 1000; tout; tout--);

//	/* Wait for hardware reset to end. */
//	for (tout = 0; tout < 0x100000; tout++)
//	{
//		regv = read_PHY (PHY_REG_BMCR);
//		if (!(regv & 0x8000))
//		{
//			/* Reset complete */
//			break;
//		}
//	}
//	if (tout >= 0x100000)
//    {
//        rt_kprintf("reset failed\r\n");
//        return -RT_ERROR; /* reset failed */
//    }

//	/* 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)
//		return -RT_ERROR;

	/* Configure the PHY device */
	/* Configure the PHY device */
	switch (lpc17xx_emac_device.phy_mode)
	{
	case EMAC_PHY_AUTO:
		/* Use autonegotiation about the link speed. */
		write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
		/* Wait to complete Auto_Negotiation. */
//		for (tout = 0; tout < 0x100000; tout++)
//		{
//			regv = read_PHY (PHY_REG_BMSR);
//			if (regv & 0x0020)
//			{
//				/* Autonegotiation Complete. */
//				break;
//			}
//		}
		break;
	case EMAC_PHY_10MBIT:
		/* Connect at 10MBit */
		write_PHY (PHY_REG_BMCR, PHY_FULLD_10M);
		break;
	case EMAC_PHY_100MBIT:
		/* Connect at 100MBit */
		write_PHY (PHY_REG_BMCR, PHY_FULLD_100M);
		break;
	}
	if (tout >= 0x100000) return -RT_ERROR; // auto_neg failed

//	/* Check the link status. */
//	for (tout = 0; tout < 0x10000; tout++)
//	{
//		regv = read_PHY (PHY_REG_STS);
//		if (regv & 0x0001)
//		{
//			/* Link is on. */
//			break;
//		}
//	}
//	if (tout >= 0x10000) return -RT_ERROR;

	regv = 0x0004;
	/* Configure Full/Half Duplex mode. */
	if (regv & 0x0004)
	{
		/* Full duplex is enabled. */
		LPC_EMAC->MAC2    |= MAC2_FULL_DUP;
		LPC_EMAC->Command |= CR_FULL_DUP;
		LPC_EMAC->IPGT     = IPGT_FULL_DUP;
	}
	else
	{
		/* Half duplex mode. */
		LPC_EMAC->IPGT = IPGT_HALF_DUP;
	}

	/* Configure 100MBit/10MBit mode. */
	if (regv & 0x0002)
	{
		/* 10MBit mode. */
		LPC_EMAC->SUPP = 0;
	}
	else
	{
		/* 100MBit mode. */
		LPC_EMAC->SUPP = SUPP_SPEED;
	}

	/* Set the Ethernet MAC Address registers */
	LPC_EMAC->SA0 = (lpc17xx_emac_device.dev_addr[1]<<8) | lpc17xx_emac_device.dev_addr[0];
	LPC_EMAC->SA1 = (lpc17xx_emac_device.dev_addr[3]<<8) | lpc17xx_emac_device.dev_addr[2];
	LPC_EMAC->SA2 = (lpc17xx_emac_device.dev_addr[5]<<8) | lpc17xx_emac_device.dev_addr[4];

	/* Initialize Tx and Rx DMA Descriptors */
	rx_descr_init ();
	tx_descr_init ();

	/* Receive Broadcast and Perfect Match Packets */
	LPC_EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN;

	/* Reset all interrupts */
	LPC_EMAC->IntClear  = 0xFFFF;

	/* Enable EMAC interrupts. */
	LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE | INT_WAKEUP | INT_SOFT_INT | INT_RX_OVERRUN | INT_TX_UNDERRUN;

	/* Enable receive and transmit mode of MAC Ethernet core */
	LPC_EMAC->Command  |= (CR_RX_EN | CR_TX_EN);
	LPC_EMAC->MAC1     |= MAC1_REC_EN;

	/* Enable the ENET Interrupt */
	NVIC_EnableIRQ(ENET_IRQn);

	return RT_EOK;
}
BOOL_32 EMAC_Init(void)
{
   /* Initialize the EMAC ethernet controller. */
  UNS_32 regv, id1,id2;
  volatile unsigned int tout;
  unsigned phy_id;
  unsigned phy_linkstatus_reg;
  unsigned phy_linkstatus_mask;

   /* Power Up the EMAC controller. */
   LPC_SC->PCONP |= 0x40000000;

   /* Enable P1 Ethernet Pins. */
   LPC_PINCON->PINSEL2 = 0x50150105;
   LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000005;

  /* Reset all EMAC internal modules. */
   LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;
   LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM;

  /* A short delay after reset. */
  for (tout = 100; tout; tout--);

  /* Initialize MAC control registers. */
  LPC_EMAC->MAC1 = MAC1_PASS_ALL;
  LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
  LPC_EMAC->MAXF = ETH_MAX_FLEN;
  LPC_EMAC->CLRT = CLRT_DEF;
  LPC_EMAC->IPGR = IPGR_DEF;

  /* Enable Reduced MII interface. */
  LPC_EMAC->MCFG = MCFG_CLK_DIV64 | MCFG_RES_MII;
  for (tout = 100; tout; tout--);
  LPC_EMAC->MCFG = MCFG_CLK_DIV64;

  /* Enable Reduced MII interface. */
  LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM | CR_PASS_RX_FILT;

  /* Reset Reduced MII Logic. */
  LPC_EMAC->SUPP = SUPP_RES_RMII | SUPP_SPEED;
  for (tout = 100; tout; tout--);
  LPC_EMAC->SUPP = SUPP_SPEED;

  /* Put the PHY in reset mode */
  write_PHY (PHY_REG_BMCR, 0x8000);
  for (tout = 1000; tout; tout--);

  /* Wait for hardware reset to end. */
  for (tout = 0; tout < 0x100000; tout++)
  {
  	regv = read_PHY (PHY_REG_BMCR);
#if	defined (KEIL_BOARD_MCB17XX) || defined (CODERED_BOARD_RDB1768)
    if (!(regv & 0x8000)) 
#else
	#error "No board!"
#endif
	{
      /* Reset complete */
      break;
    }
  }
  if (tout >= 0x100000)
  	return FALSE; /* reset failed */

  /* Check if this is a DP83848C PHY. */
  id1 = read_PHY (PHY_REG_IDR1);
  id2 = read_PHY (PHY_REG_IDR2);
  phy_id = ((id1 << 16) | (id2 & 0xFFF0));
  
#if	defined (KEIL_BOARD_MCB17XX) || defined (CODERED_BOARD_RDB1768)
	  if ((phy_id != DP83848C_ID) && (phy_id != LAN8720_ID))
#else
	#error "No board"
#endif		  
  	return FALSE;
  	
	/* Configure the PHY device */
      /* Configure the PHY device */
#if defined (_10MBIT_)
      /* Connect at 10MBit */
      write_PHY (PHY_REG_BMCR, PHY_FULLD_10M);
#elif defined (_100MBIT_)
      /* Connect at 100MBit */
      write_PHY (PHY_REG_BMCR, PHY_FULLD_100M);
#else
      /* Use autonegotiation about the link speed. */
      write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
      /* Wait to complete Auto_Negotiation. */
      for (tout = 0; tout < 0x100000; tout++)
      {
         regv = read_PHY (PHY_REG_BMSR);
         if (regv & 0x0020)
         {
            /* Autonegotiation Complete. */
            break;
         }
      }

	if (tout >= 0x100000)
		return FALSE; // auto_neg failed
#endif
	  phy_linkstatus_reg = PHY_REG_STS;		// Default to DP83848C
	  phy_linkstatus_mask = 0x0001;

	  if (phy_id == LAN8720_ID)
	  {
		  phy_linkstatus_reg = PHY_REG_BMSR;
		  phy_linkstatus_mask = 0x0004;
	  }

  /* Check the link status. */
  for (tout = 0; tout < 0x100000; tout++) {
#if	defined (KEIL_BOARD_MCB17XX) || defined (CODERED_BOARD_RDB1768)
    regv = read_PHY (phy_linkstatus_reg);
    if (regv & phy_linkstatus_mask)
#else
	#error "No board"
#endif 
	{   	
      /* Link is on. */
      break;
    }
  }

  if (tout >= 0x100000)
  	return FALSE;

  /* Configure Full/Half Duplex mode. */
#if	defined (KEIL_BOARD_MCB17XX) || defined (CODERED_BOARD_RDB1768)
  if (regv & 0x0004) 
#else
	#error "No board"
#endif
	{  	
    /* Full duplex is enabled. */
	  LPC_EMAC->MAC2    |= MAC2_FULL_DUP;
	  LPC_EMAC->Command |= CR_FULL_DUP;
	  LPC_EMAC->IPGT     = IPGT_FULL_DUP;
  }
  else {
    /* Half duplex mode. */
	  LPC_EMAC->IPGT = IPGT_HALF_DUP;
  }

  /* Configure 100MBit/10MBit mode. */
#if	defined (KEIL_BOARD_MCB17XX) || defined (CODERED_BOARD_RDB1768)
  if (regv & 0x0002) {
#else
	#error "No baord"
#endif   	  	
    /* 10MBit mode. */
	  LPC_EMAC->SUPP = 0;
  }
  else {
    /* 100MBit mode. */
	  LPC_EMAC->SUPP = SUPP_SPEED;
  }

  /* Set the Ethernet MAC Address registers */
//  MAC_SA0 = (MYMAC_6 << 8) | MYMAC_5;
//  MAC_SA1 = (MYMAC_4 << 8) | MYMAC_3;
//  MAC_SA2 = (MYMAC_2 << 8) | MYMAC_1;
  LPC_EMAC->SA0 = (UIP_ETHADDR1<<8) | UIP_ETHADDR0;
  LPC_EMAC->SA1 = (UIP_ETHADDR3<<8) | UIP_ETHADDR2;
  LPC_EMAC->SA2 = (UIP_ETHADDR5<<8) | UIP_ETHADDR4;

  /* Initialize Tx and Rx DMA Descriptors */
  rx_descr_init ();
  tx_descr_init ();

  /* Receive Broadcast and Perfect Match Packets */
  LPC_EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN;

  /* Enable EMAC interrupts. */
  LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE;

  /* Reset all interrupts */
  LPC_EMAC->IntClear  = 0xFFFF;

  /* Enable receive and transmit mode of MAC Ethernet core */
  LPC_EMAC->Command  |= (CR_RX_EN | CR_TX_EN);
  LPC_EMAC->MAC1     |= MAC1_REC_EN;

   /* Configure VIC for EMAC interrupt. */
   //VICVectAddrxx = (UNS_32)xx;
   
  return TRUE;
}