A PicoTCP driver for the lpc1768 mbed board

Dependents:   lpc1768-picotcp-demo TCPSocket_HelloWorld_PicoTCP Pico_TCP_UDP_Test TCPSocket_HelloWorld_PicoTCP ... more

Files at this revision

API Documentation at this revision

Comitter:
tass
Date:
Fri May 17 12:50:42 2013 +0000
Child:
1:5704aeb1157d
Commit message:
Initial commit of picotcp ethernet driver for lpc1768

Changed in this revision

pico_dev_mbed_emac.cpp Show annotated file Show diff for this revision Revisions of this file
pico_dev_mbed_emac.h Show annotated file Show diff for this revision Revisions of this file
pico_dev_mbed_emac_private.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pico_dev_mbed_emac.cpp	Fri May 17 12:50:42 2013 +0000
@@ -0,0 +1,695 @@
+/******************************************************************************
+PicoTCP. Copyright (c) 2012-2013 TASS Belgium NV. Some rights reserved.
+See LICENSE and COPYING for usage. https://github.com/tass-belgium/picotcp
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License Version 2
+as published by the Free Software Foundation;
+
+Some of the code contained in this file is based on mbed.org 
+mbed/libraries/mbed/vendor/NXP/capi/ethernet_api.c module, 
+licensed under the Apache License, Version 2.0
+and is Copyright (c) 2006-2013 ARM Limited
+
+Authors: Maxime Vincent, Andrei Carp
+
+******************************************************************************/
+
+#include "mbed.h"
+extern "C" {
+#include "pico_dev_mbed_emac.h"
+#include "pico_dev_mbed_emac_private.h"
+#include "pico_config.h"
+#include "pico_device.h"
+#include "pico_stack.h"
+#include "LPC17xx.h"
+#include <string.h>
+}
+
+/*******************************
+ * Local structs and typedefs  *
+ *******************************/
+__packed struct RX_DESC_TypeDef {                        /* RX Descriptor struct              */
+   unsigned int Packet;
+   unsigned int Ctrl;
+};
+typedef struct RX_DESC_TypeDef RX_DESC_TypeDef;
+
+__packed struct RX_STAT_TypeDef {                        /* RX Status struct                  */
+   unsigned int Info;
+   unsigned int HashCRC;
+};
+typedef struct RX_STAT_TypeDef RX_STAT_TypeDef;
+
+__packed struct TX_DESC_TypeDef {                        /* TX Descriptor struct              */
+   unsigned int Packet;
+   unsigned int Ctrl;
+};
+typedef struct TX_DESC_TypeDef TX_DESC_TypeDef;
+
+__packed struct TX_STAT_TypeDef {                        /* TX Status struct                  */
+   unsigned int Info;
+};
+typedef struct TX_STAT_TypeDef TX_STAT_TypeDef;
+
+// To be allocated in the ETH AHB RAM
+__packed typedef struct emac_dma_data {
+  RX_STAT_TypeDef   p_rx_stat[NUM_RX_FRAG];   /**< Pointer to RX statuses */
+  RX_DESC_TypeDef   p_rx_desc[NUM_RX_FRAG];   /**< Pointer to RX descriptor list */
+  TX_STAT_TypeDef   p_tx_stat[NUM_TX_FRAG];   /**< Pointer to TX statuses */
+  TX_DESC_TypeDef   p_tx_desc[NUM_TX_FRAG];   /**< Pointer to TX descriptor list */
+  uint8_t           rx_buf[NUM_RX_FRAG][ETH_MAX_MTU];      /**< RX pbuf pointer list, zero-copy mode */
+  uint8_t           tx_buf[NUM_TX_FRAG][ETH_MAX_MTU];      /**< TX pbuf pointer list, zero-copy mode */
+} EMAC_DMA_DATA_T;
+
+struct pico_device_mbed_emac {
+  struct pico_device dev;
+  uint16_t mtu;
+  uint8_t mac[PICO_SIZE_ETH];
+  EMAC_DMA_DATA_T * dma_data;
+};
+
+/********************
+ * Global variables *
+ ********************/
+uint16_t lBuffer[ETH_MAX_MTU>>1] __attribute__((section("AHBSRAM0")));
+
+/*******************
+ * Local variables *
+ *******************/
+static uint16_t *rptr;
+static uint16_t *tptr;
+static EMAC_DMA_DATA_T dma_data_ahbsram __attribute__((section("AHBSRAM1")));
+
+DigitalOut led_link(LED2);  /* Link */
+DigitalOut led_rx(LED3);    /* Rx */
+DigitalOut led_tx(LED4);    /* Tx */
+
+/**************************************
+ * Private helper function prototypes *
+ **************************************/
+static void _emac_init(struct pico_device_mbed_emac * mbdev);
+static void _emac_destroy(struct pico_device *dev);
+static int _emac_write_PHY (int PhyReg, int Value);
+static int _emac_read_PHY (unsigned char PhyReg);
+static void _emac_rx_descr_init (struct pico_device_mbed_emac * mbdev);
+static void _emac_tx_descr_init (struct pico_device_mbed_emac * mbdev);
+static int _emac_send_frame(struct pico_device * dev, void * buf, int len);
+static void _emac_phy_status(void const * dev);
+static inline unsigned int _emac_clockselect();
+static int _pico_emac_poll(struct pico_device *dev, int loop_score);
+
+/*****************
+ * CMSIS defines *
+ *****************/
+// Timer: For periodic PHY update
+osTimerDef(_emac_phy_status, _emac_phy_status);
+
+/******************************
+ * Public interface functions *
+ ******************************/
+uint32_t intStatus;
+
+void ENET_IRQHandler(void)
+{
+    // Get interrupt flag for enabled interrupts
+    intStatus = (LPC_EMAC->IntStatus & LPC_EMAC->IntEnable);
+    
+    if(intStatus & INT_TX_UNDERRUN)
+    {
+      // this case should be treated
+      //printf("TX_UNDERRUN\r\n");
+    }
+
+    if(intStatus & INT_RX_OVERRUN)
+    {
+      // this case should be treated
+      //printf("INT_RX_OVERRUN\r\n");
+    }
+ 
+    if(intStatus & INT_RX_DONE)
+    {
+    }
+    
+    // Clears _ALL_ EMAC interrupt flags
+    LPC_EMAC->IntClear = intStatus;
+}
+
+
+struct pico_device *pico_emac_create(char *name)
+{
+  struct pico_device_mbed_emac *mbdev = (struct pico_device_mbed_emac*) pico_zalloc(sizeof(struct pico_device_mbed_emac));
+
+  if (!mbdev)
+    return NULL;
+
+  // Set pointer to ETH AHB RAM
+  mbdev->dma_data = &dma_data_ahbsram;
+
+  // Read MAC address from HW
+  mbed_mac_address((char *)mbdev->mac);
+  
+  //printf("ETH> Set MAC address to: %x:%x:%x:%x:%x:%x\r\n", mbdev->mac[0], mbdev->mac[1], mbdev->mac[2], mbdev->mac[3], mbdev->mac[4], mbdev->mac[5]);
+
+  mbdev->mtu = ETH_MAX_MTU;
+
+  if(0 != pico_device_init((struct pico_device *)mbdev, name, mbdev->mac)) {
+    //printf ("ETH> Loop init failed.\n");
+    _emac_destroy(&mbdev->dev);
+    return NULL;
+  }
+
+  // Set function pointers
+  mbdev->dev.send = _emac_send_frame;
+  mbdev->dev.poll = _pico_emac_poll;
+  mbdev->dev.destroy = _emac_destroy;
+
+  // Init EMAC and PHY
+  _emac_init(mbdev);
+
+  // Create periodic PHY status update thread
+  osTimerId phy_timer = osTimerCreate(osTimer(_emac_phy_status), osTimerPeriodic, (void *)mbdev);
+  osTimerStart(phy_timer, 250);
+
+  //printf("ETH> Device %s created.\r\n", mbdev->dev.name);
+
+  return (struct pico_device *)mbdev;
+}
+
+/****************************
+ * Private helper functions *
+ ****************************/
+ 
+// Public interface: create/destroy.
+void _emac_destroy(struct pico_device *dev)
+{
+  pico_device_destroy(dev);
+}
+
+//extern unsigned int SystemFrequency;
+static inline unsigned int _emac_clockselect() {  
+  if(SystemCoreClock < 10000000) {
+    return 1;
+  } else if(SystemCoreClock <  15000000) {
+    return 2;
+  } else if(SystemCoreClock <  20000000) {
+    return 3;
+  } else if(SystemCoreClock <  25000000) {
+    return 4;
+  } else if(SystemCoreClock <  35000000) {
+    return 5;
+  } else if(SystemCoreClock <  50000000) {
+    return 6;
+  } else if(SystemCoreClock <  70000000) {
+    return 7;
+  } else if(SystemCoreClock <  80000000) {
+    return 8;
+  } else if(SystemCoreClock <  90000000) {
+    return 9;
+  } else if(SystemCoreClock < 100000000) {
+    return 10;
+  } else if(SystemCoreClock < 120000000) {
+    return 11;
+  } else if(SystemCoreClock < 130000000) {
+    return 12;
+  } else if(SystemCoreClock < 140000000) {
+    return 13;
+  } else if(SystemCoreClock < 150000000) {
+    return 15;
+  } else if(SystemCoreClock < 160000000) {
+    return 16;
+  } else {
+    return 0;
+  }
+}
+
+// configure port-pins for use with LAN-controller,
+// reset it and send the configuration-sequence
+void _emac_init(struct pico_device_mbed_emac * mbdev)
+{
+  unsigned int clock = _emac_clockselect();
+  // the DP83848C PHY clock can be up to 25 Mhz
+  // that means sysclock = 96 Mhz divided by 4 = 24 Mhz
+  // So we *could* set the clock divider to 4 (meaning "clock" = 0)
+  //clock = 0;
+  
+  // Initializes the EMAC ethernet controller
+  unsigned int regv,tout,id1,id2;
+
+  // Power Up the EMAC controller.
+  LPC_SC->PCONP |= 0x40000000;
+
+  // on rev. 'A' and later, P1.6 should NOT be set.
+  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--) __NOP();            // A short delay
+
+  // Initialize MAC control registers.
+  LPC_EMAC->MAC1 = MAC1_PASS_ALL;
+  LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
+  //  MAC2 = MAC2_CRC_EN | MAC2_PAD_EN | MAC2_VLAN_PAD_EN;
+
+  LPC_EMAC->MAXF = ETH_MAX_MTU; 
+  LPC_EMAC->CLRT = CLRT_DEF;
+  LPC_EMAC->IPGR = IPGR_DEF;
+
+  // Enable Reduced MII interface.
+  LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM;
+  
+  LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL;    // Set clock
+  LPC_EMAC->MCFG |= MCFG_RES_MII;                    // and reset
+
+  for(tout = 100; tout; tout--) __NOP();             // A short delay
+
+  LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL;
+  LPC_EMAC->MCMD = 0;
+
+  LPC_EMAC->SUPP = SUPP_RES_RMII;                    // Reset Reduced MII Logic.
+
+  for (tout = 100; tout; tout--) __NOP();            // A short delay
+
+  LPC_EMAC->SUPP = 0;
+
+  // Put the DP83848C in reset mode
+  _emac_write_PHY (PHY_REG_BMCR, 0x8000);
+
+  // Wait for hardware reset to end.
+  for (tout = 0; tout < 0x100000; tout++) {
+    regv = _emac_read_PHY (PHY_REG_BMCR);
+    if (!(regv & 0x8000)) {
+      // Reset complete
+      break;
+    }
+  }
+
+  // Check if this is a DP83848C PHY.
+  id1 = _emac_read_PHY (PHY_REG_IDR1);
+  id2 = _emac_read_PHY (PHY_REG_IDR2);
+  if (((id1 << 16) | (id2 & 0xFFF0)) == DP83848C_ID) {
+    // Configure the PHY device
+    //printf("PHY> DP83848C_ID PHY found!\r\n");
+    // Use autonegotiation about the link speed.
+    _emac_write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
+    // Wait to complete Auto_Negotiation.
+    for (tout = 0; tout < 0x100000; tout++) {
+      regv = _emac_read_PHY (PHY_REG_BMSR);
+      if (regv & 0x0020) {
+        // Autonegotiation Complete.
+        break;
+      }
+    }
+  }
+
+  /* Check the link status. */
+  for (tout = 0; tout < 0x10000; tout++) {
+    regv = _emac_read_PHY (PHY_REG_STS);
+    if (regv & 0x0001) {
+      // Link is on
+      //printf("PHY> Link active!\r\n");
+      break;
+    }
+  }
+
+  // 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 = (mbdev->mac[0] << 8) | mbdev->mac[1];
+  LPC_EMAC->SA1 = (mbdev->mac[2] << 8) | mbdev->mac[2];
+  LPC_EMAC->SA2 = (mbdev->mac[4] << 8) | mbdev->mac[5];
+
+  // Initialize Tx and Rx DMA Descriptors
+  _emac_rx_descr_init(mbdev);
+  _emac_tx_descr_init(mbdev);
+  
+  // Receive Unicast, Broadcast and Perfect Match Packets
+  LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;
+
+  // 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 EMAC interrupts.
+  LPC_EMAC->IntEnable = INT_RX_DONE | INT_RX_OVERRUN | INT_TX_DONE | INT_TX_FIN | INT_TX_ERR | INT_TX_UNDERRUN;
+
+  // Reset all interrupts
+  LPC_EMAC->IntClear  = 0xFFFF;
+
+  NVIC_SetPriority(ENET_IRQn, EMAC_INTERRUPT_PRIORITY);
+
+  // Enable the interrupt.
+  NVIC_EnableIRQ(ENET_IRQn);
+  
+}
+
+
+static int _emac_write_PHY (int PhyReg, int Value)
+{
+  unsigned int timeOut;
+
+  LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
+  LPC_EMAC->MWTD = Value;
+
+  // Wait until operation completed
+  for (timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) {
+    if ((LPC_EMAC->MIND & MIND_BUSY) == 0) {
+      return 0;
+    }
+  }
+  return -1;
+}
+
+static int _emac_read_PHY (unsigned char PhyReg)
+{
+  unsigned int timeOut;
+
+  LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
+  LPC_EMAC->MCMD = MCMD_READ;
+
+  for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) {   // Wait until operation completed
+    if((LPC_EMAC->MIND & MIND_BUSY) == 0) {
+      LPC_EMAC->MCMD = 0;
+      return LPC_EMAC->MRDD;                             // Return a 16-bit value.
+    }
+  }
+  
+  return -1;
+}
+
+
+void rx_descr_init (void)
+{
+  unsigned int i;
+
+  for (i = 0; i < NUM_RX_FRAG; i++) {
+    RX_DESC_PACKET(i)  = RX_BUF(i);
+    RX_DESC_CTRL(i)    = RCTRL_INT | (ETH_MAX_MTU-1);
+    RX_STAT_INFO(i)    = 0;
+    RX_STAT_HASHCRC(i) = 0;
+  }
+
+  // Set EMAC Receive Descriptor Registers.
+  LPC_EMAC->RxDescriptor    =   RX_DESC_BASE;
+  LPC_EMAC->RxStatus        =   RX_STAT_BASE;
+  LPC_EMAC->RxDescriptorNumber= NUM_RX_FRAG-1;
+
+  // Rx Descriptors Point to 0
+  LPC_EMAC->RxConsumeIndex  = 0;
+}
+
+
+void tx_descr_init (void) {
+  unsigned int i;
+
+  for (i = 0; i < NUM_TX_FRAG; i++) {
+    TX_DESC_PACKET(i) = TX_BUF(i);
+    TX_DESC_CTRL(i)   = 0;
+    TX_STAT_INFO(i)   = 0;
+  }
+
+  // Set EMAC Transmit Descriptor Registers.
+  LPC_EMAC->TxDescriptor    = TX_DESC_BASE;
+  LPC_EMAC->TxStatus        = TX_STAT_BASE;
+  LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1;
+
+  // Tx Descriptors Point to 0
+  LPC_EMAC->TxProduceIndex  = 0;
+}
+
+
+static void _emac_rx_descr_init (struct pico_device_mbed_emac * mbdev)
+{
+  unsigned int i;
+
+  for (i = 0; i < NUM_RX_FRAG; i++) {
+    // Fill in pointers to ETH DMA AHB RAM
+    mbdev->dma_data->p_rx_desc[i].Packet =  (uint32_t)&(mbdev->dma_data->rx_buf[i][0]);
+    mbdev->dma_data->p_rx_desc[i].Ctrl = RCTRL_INT | (ETH_MAX_MTU-1);
+    mbdev->dma_data->p_rx_stat[i].Info = 0;
+    mbdev->dma_data->p_rx_stat[i].HashCRC = 0;
+  }
+
+  // Set EMAC Receive Descriptor Registers.
+  LPC_EMAC->RxDescriptor        = (uint32_t)&(mbdev->dma_data->p_rx_desc[0]);
+  LPC_EMAC->RxStatus            = (uint32_t)&(mbdev->dma_data->p_rx_stat[0]);
+  LPC_EMAC->RxDescriptorNumber  = NUM_RX_FRAG-1;
+
+  // Rx Descriptors Point to 0
+  LPC_EMAC->RxConsumeIndex  = 0;
+}
+
+static void _emac_tx_descr_init (struct pico_device_mbed_emac * mbdev) {
+  unsigned int i;
+
+  for (i = 0; i < NUM_TX_FRAG; i++) {
+    mbdev->dma_data->p_tx_desc[i].Packet =  (uint32_t)&(mbdev->dma_data->tx_buf[i][0]);
+    mbdev->dma_data->p_tx_desc[i].Ctrl = 0;
+    mbdev->dma_data->p_tx_stat[i].Info = 0;
+  }
+  
+  // Set EMAC Transmit Descriptor Registers.
+  LPC_EMAC->TxDescriptor    = (uint32_t)&(mbdev->dma_data->p_tx_desc[0]);
+  LPC_EMAC->TxStatus        = (uint32_t)&(mbdev->dma_data->p_tx_stat[0]);
+  LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1;
+
+  // Tx Descriptors Point to index 0
+  LPC_EMAC->TxProduceIndex  = 0;
+}
+
+
+// async send, returning amount of data sent, and 0 if the buffers are busy
+static int _emac_send_frame(struct pico_device *dev, void * buf, int len)
+{
+  struct pico_device_mbed_emac *mbdev = (struct pico_device_mbed_emac *) dev;
+  uint16_t size = len;
+  uint32_t bufferIndex = LPC_EMAC->TxProduceIndex;
+  uint16_t pSize = (size+1u)>>1u;
+  uint16_t * data = (uint16_t *)buf;
+  int data_sent = 0;
+
+  // When TxProduceIndex == TxConsumeIndex, the transmit buffer is empty.
+  // When TxProduceIndex == TxConsumeIndex -1 (taking wraparound into account), the transmit buffer is full!
+  // We should check if there is still a tx_desc FREE!! Consume < Produce (wrapping!!)  
+  int cons = (int)LPC_EMAC->TxConsumeIndex;
+  int prod = (int)LPC_EMAC->TxProduceIndex;
+  int txfree = 0;
+  
+  if (prod == cons)
+    txfree = NUM_TX_FRAG;
+  else if (prod > cons)
+    txfree = NUM_TX_FRAG - prod + cons - 1;
+  else if (prod < cons)
+    txfree = cons - prod - 1; 
+  
+  if (txfree == 0)
+  {
+    //printf("p%i c%i stat:%d\r\n",prod,cons,LPC_EMAC->TxStatus);
+    return 0;
+  }
+  
+  // set tx descriptors for send
+  tptr = (uint16_t *)(mbdev->dma_data->p_tx_desc[bufferIndex].Packet);
+    
+  // copy data to AHB RAM (16-bit copies)
+  while(pSize)
+  {
+    *tptr++ = *data++;
+    pSize--;
+  }
+  
+  data_sent = size;
+
+  // send data, no interrupt needed I see, for now
+  mbdev->dma_data->p_tx_desc[bufferIndex].Ctrl &= ~0x7FF;
+  mbdev->dma_data->p_tx_desc[bufferIndex].Ctrl = (((uint32_t)size -1) & 0x7FF) | TCTRL_LAST | TCTRL_INT;
+  
+  //printf("ETH> sent %d bytes\r\n",data_sent);
+
+  // advance the TxProduceIndex
+  bufferIndex = (bufferIndex+1)%NUM_TX_FRAG;
+  LPC_EMAC->TxProduceIndex = bufferIndex;
+        
+  // Toggle TX LED
+  led_tx= !led_tx;
+
+  return data_sent;
+}
+
+/* polls for new data
+   returns amount of bytes received -- 0 when no new data arrived */
+static int _emac_poll(struct pico_device_mbed_emac * mbdev)
+{
+    uint32_t index = LPC_EMAC->RxConsumeIndex;
+    int retval = 0;
+
+    // Consume all packets available
+    while(index != LPC_EMAC->RxProduceIndex)
+    {
+      uint32_t info = mbdev->dma_data->p_rx_stat[index].Info;
+      uint32_t RxLen = (info & RINFO_SIZE) - 3u;
+      rptr = (uint16_t *)(mbdev->dma_data->p_rx_desc[index].Packet);
+
+      if(!( (RxLen >= ETH_MAX_MTU) || (info & RINFO_ERR_MASK) ) )
+      {
+        // copy uin16_t (that's per 2 bytes) data content
+        uint16_t lRxLen = RxLen>>1;
+        uint16_t * lptr = lBuffer;
+        while(lRxLen)
+        {
+            *lptr++ = *rptr++;
+            lRxLen--;
+        }
+        if(RxLen & 0x1)
+            *lptr = (*rptr) & 0xFF ;
+            
+        //printf("ETH> recv %d bytes: %x:%x\r\n", RxLen, lBuffer[0],lBuffer[1]);
+        
+        // call the stack and pass this packet to it
+        pico_stack_recv((struct pico_device *)mbdev,(uint8_t *)lBuffer,RxLen);
+      } else {
+        //printf("RxError?\r\n");
+      }
+      retval += RxLen;
+      
+      // Increment RxConsumeIndex
+      index = (index+1)%NUM_RX_FRAG;
+      LPC_EMAC->RxConsumeIndex = index;
+                
+      // Toggle RX LED
+      led_rx= !led_rx;
+    }
+    
+    return retval;
+}
+
+static int _pico_emac_poll(struct pico_device *dev, int loop_score)
+{
+  struct pico_device_mbed_emac *mb = (struct pico_device_mbed_emac *) dev;
+  
+  while(loop_score > 0)
+  {
+    // check for new frame(s) and send to pico stack
+    // return loop_score if no frame has arrived
+    if (!(_emac_poll(mb)))
+        return loop_score;
+    loop_score--;
+  }
+  return loop_score;
+}
+
+/* Read PHY status */
+static uint8_t _emac_update_phy_status(uint32_t linksts)
+{
+  uint8_t changed = 0;
+  static uint32_t oldlinksts = 0;
+    
+  if (oldlinksts != linksts)
+    changed = 1;
+        
+  if (changed)
+  {
+    oldlinksts = linksts;
+    
+    // Update link active status
+    if (linksts & DP8_VALID_LINK)
+    {
+      led_link = 1;
+      //printf("PHY> Link ACTIVE!     --");
+    }
+    else
+    {
+      led_link = 0;
+      //printf("PHY> Link inactive... --");
+    }
+
+    // Full or half duplex
+    /*
+    if (linksts & DP8_FULLDUPLEX)
+      printf(" Full duplex mode ! --");
+    else
+      printf(" No full duplex...! --");
+
+    // Configure 100MBit/10MBit mode.
+    if (linksts & DP8_SPEED10MBPS)
+      printf(" @  10 MBPS\r\n");
+    else
+      printf(" @ 100 MBPS\r\n");
+    */
+  }
+
+  return changed;
+}
+
+// Starts a read operation via the MII link (non-blocking)
+static void _emac_mii_read_noblock(uint32_t PhyReg) 
+{
+  // Read value at PHY address and register
+  LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
+  LPC_EMAC->MCMD = MCMD_READ;
+}
+
+/* Reads current MII link busy status */
+static uint32_t _emac_mii_is_busy(void)
+{
+  return (uint32_t) (LPC_EMAC->MIND & MIND_BUSY);
+}
+
+// Starts a read operation via the MII link (non-blocking)
+static uint32_t _emac_mii_read_data(void)
+{
+  uint32_t data = LPC_EMAC->MRDD;
+  LPC_EMAC->MCMD = 0;
+
+  return data;
+}
+
+// Phy status update state machine
+static void _emac_phy_status(void const * dev)
+{
+  static uint8_t phyustate = 0;
+  uint32_t changed = 0;
+
+  switch (phyustate) {
+    default:
+    case 0:
+      // Read BMSR to clear faults
+      _emac_mii_read_noblock(PHY_REG_STS);
+      phyustate = 1;
+      break;
+
+    case 1:
+      // Wait for read status state
+      if (!_emac_mii_is_busy()) {
+        // Update PHY status
+        changed = _emac_update_phy_status(_emac_mii_read_data());
+        phyustate = 0;
+      }
+      break;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pico_dev_mbed_emac.h	Fri May 17 12:50:42 2013 +0000
@@ -0,0 +1,33 @@
+/******************************************************************************
+PicoTCP. Copyright (c) 2012-2013 TASS Belgium NV. Some rights reserved.
+See LICENSE and COPYING for usage. https://github.com/tass-belgium/picotcp
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License Version 2
+as published by the Free Software Foundation;
+
+Some of the code contained in this file is based on mbed.org 
+mbed/libraries/mbed/vendor/NXP/capi/ethernet_api.c module, 
+licensed under the Apache License, Version 2.0
+and is Copyright (c) 2006-2013 ARM Limited
+
+Authors: Maxime Vincent, Andrei Carp
+
+******************************************************************************/
+
+#ifndef __PICO_DEV_MBED_EMAC_H
+#define __PICO_DEV_MBED_EMAC_H
+
+#include "cmsis_os.h"
+#include <stdint.h>
+
+/********************
+ * Public functions *
+ ********************/
+extern "C" {
+struct pico_device *pico_emac_create(char *name);
+extern void pico_emac_init(void);
+extern void ENET_IRQHandler(void);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pico_dev_mbed_emac_private.h	Fri May 17 12:50:42 2013 +0000
@@ -0,0 +1,313 @@
+/******************************************************************************
+PicoTCP. Copyright (c) 2012-2013 TASS Belgium NV. Some rights reserved.
+See LICENSE and COPYING for usage. https://github.com/tass-belgium/picotcp
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License Version 2
+as published by the Free Software Foundation;
+
+Some of the code contained in this file is based on mbed.org 
+mbed/libraries/mbed/vendor/NXP/capi/ethernet_api.c module, 
+licensed under the Apache License, Version 2.0
+and is Copyright (c) 2006-2013 ARM Limited
+
+Authors: Maxime Vincent, Andrei Carp
+
+******************************************************************************/
+
+#ifndef __PICO_DEV_MBED_EMAC_PRIVATE_H
+#define __PICO_DEV_MBED_EMAC_PRIVATE_H
+
+/***********
+ * DEFINES *
+ ***********/
+
+#define EMAC_INTERRUPT_PRIORITY       5 /* the lower the number, the higher the priority */
+
+/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */
+#define NUM_RX_FRAG         3           /* Num.of RX Fragments 4*1536= 6.0kB */
+#define NUM_TX_FRAG         4           /* Num.of TX Fragments 3*1536= 4.6kB */
+#define ETH_MAX_MTU         1536        /* Max. Ethernet Frame Size          */
+
+/* EMAC variables located in AHB SRAM bank 1*/
+#define ETH_AHB_RAM_BASE    0x20080000
+#define RX_DESC_BASE        0x20080000
+#define RX_STAT_BASE        (RX_DESC_BASE + NUM_RX_FRAG*8)
+#define TX_DESC_BASE        (RX_STAT_BASE + NUM_RX_FRAG*8)
+#define TX_STAT_BASE        (TX_DESC_BASE + NUM_TX_FRAG*8)
+#define RX_BUF_BASE         (TX_STAT_BASE + NUM_TX_FRAG*4)
+#define TX_BUF_BASE         (RX_BUF_BASE  + NUM_RX_FRAG*ETH_MAX_MTU)
+
+/* RX and TX descriptor and status definitions. */
+#define RX_DESC_PACKET(i)   (*(unsigned int *)(RX_DESC_BASE   + 8*i))
+#define RX_DESC_CTRL(i)     (*(unsigned int *)(RX_DESC_BASE+4 + 8*i))
+#define RX_STAT_INFO(i)     (*(unsigned int *)(RX_STAT_BASE   + 8*i))
+#define RX_STAT_HASHCRC(i)  (*(unsigned int *)(RX_STAT_BASE+4 + 8*i))
+#define TX_DESC_PACKET(i)   (*(unsigned int *)(TX_DESC_BASE   + 8*i))
+#define TX_DESC_CTRL(i)     (*(unsigned int *)(TX_DESC_BASE+4 + 8*i))
+#define TX_STAT_INFO(i)     (*(unsigned int *)(TX_STAT_BASE   + 4*i))
+#define RX_BUF(i)           (RX_BUF_BASE + ETH_MAX_MTU*i)
+#define TX_BUF(i)           (TX_BUF_BASE + ETH_MAX_MTU*i)
+
+/* MAC Configuration Register 1 */
+#define MAC1_REC_EN         0x00000001  /* Receive Enable                    */
+#define MAC1_PASS_ALL       0x00000002  /* Pass All Receive Frames           */
+#define MAC1_RX_FLOWC       0x00000004  /* RX Flow Control                   */
+#define MAC1_TX_FLOWC       0x00000008  /* TX Flow Control                   */
+#define MAC1_LOOPB          0x00000010  /* Loop Back Mode                    */
+#define MAC1_RES_TX         0x00000100  /* Reset TX Logic                    */
+#define MAC1_RES_MCS_TX     0x00000200  /* Reset MAC TX Control Sublayer     */
+#define MAC1_RES_RX         0x00000400  /* Reset RX Logic                    */
+#define MAC1_RES_MCS_RX     0x00000800  /* Reset MAC RX Control Sublayer     */
+#define MAC1_SIM_RES        0x00004000  /* Simulation Reset                  */
+#define MAC1_SOFT_RES       0x00008000  /* Soft Reset MAC                    */
+
+/* MAC Configuration Register 2 */
+#define MAC2_FULL_DUP       0x00000001  /* Full Duplex Mode                  */
+#define MAC2_FRM_LEN_CHK    0x00000002  /* Frame Length Checking             */
+#define MAC2_HUGE_FRM_EN    0x00000004  /* Huge Frame Enable                 */
+#define MAC2_DLY_CRC        0x00000008  /* Delayed CRC Mode                  */
+#define MAC2_CRC_EN         0x00000010  /* Append CRC to every Frame         */
+#define MAC2_PAD_EN         0x00000020  /* Pad all Short Frames              */
+#define MAC2_VLAN_PAD_EN    0x00000040  /* VLAN Pad Enable                   */
+#define MAC2_ADET_PAD_EN    0x00000080  /* Auto Detect Pad Enable            */
+#define MAC2_PPREAM_ENF     0x00000100  /* Pure Preamble Enforcement         */
+#define MAC2_LPREAM_ENF     0x00000200  /* Long Preamble Enforcement         */
+#define MAC2_NO_BACKOFF     0x00001000  /* No Backoff Algorithm              */
+#define MAC2_BACK_PRESSURE  0x00002000  /* Backoff Presurre / No Backoff     */
+#define MAC2_EXCESS_DEF     0x00004000  /* Excess Defer                      */
+
+/* Back-to-Back Inter-Packet-Gap Register */
+#define IPGT_FULL_DUP       0x00000015  /* Recommended value for Full Duplex */
+#define IPGT_HALF_DUP       0x00000012  /* Recommended value for Half Duplex */
+
+/* Non Back-to-Back Inter-Packet-Gap Register */
+#define IPGR_DEF            0x00000012  /* Recommended value                 */
+
+/* Collision Window/Retry Register */
+#define CLRT_DEF            0x0000370F  /* Default value                     */
+
+/* PHY Support Register */
+#define SUPP_SPEED          0x00000100  /* Reduced MII Logic Current Speed   */
+#define SUPP_RES_RMII       0x00000000  /* Reset Reduced MII Logic           */
+
+/* Test Register */
+#define TEST_SHCUT_PQUANTA  0x00000001  /* Shortcut Pause Quanta             */
+#define TEST_TST_PAUSE      0x00000002  /* Test Pause                        */
+#define TEST_TST_BACKP      0x00000004  /* Test Back Pressure                */
+
+/* MII Management Configuration Register */
+#define MCFG_SCAN_INC       0x00000001  /* Scan Increment PHY Address        */
+#define MCFG_SUPP_PREAM     0x00000002  /* Suppress Preamble                 */
+#define MCFG_CLK_SEL        0x0000001C  /* Clock Select Mask                 */
+#define MCFG_RES_MII        0x00008000  /* Reset MII Management Hardware     */
+
+/* MII Management Command Register */
+#define MCMD_READ           0x00000001  /* MII Read                          */
+#define MCMD_SCAN           0x00000002  /* MII Scan continuously             */
+
+#define MII_WR_TOUT         0x00050000  /* MII Write timeout count           */
+#define MII_RD_TOUT         0x00050000  /* MII Read timeout count            */
+
+/* MII Management Address Register */
+#define MADR_REG_ADR        0x0000001F  /* MII Register Address Mask         */
+#define MADR_PHY_ADR        0x00001F00  /* PHY Address Mask                  */
+
+/* MII Management Indicators Register */
+#define MIND_BUSY           0x00000001  /* MII is Busy                       */
+#define MIND_SCAN           0x00000002  /* MII Scanning in Progress          */
+#define MIND_NOT_VAL        0x00000004  /* MII Read Data not valid           */
+#define MIND_MII_LINK_FAIL  0x00000008  /* MII Link Failed                   */
+
+/* Command Register */
+#define CR_RX_EN            0x00000001  /* Enable Receive                    */
+#define CR_TX_EN            0x00000002  /* Enable Transmit                   */
+#define CR_REG_RES          0x00000008  /* Reset Host Registers              */
+#define CR_TX_RES           0x00000010  /* Reset Transmit Datapath           */
+#define CR_RX_RES           0x00000020  /* Reset Receive Datapath            */
+#define CR_PASS_RUNT_FRM    0x00000040  /* Pass Runt Frames                  */
+#define CR_PASS_RX_FILT     0x00000080  /* Pass RX Filter                    */
+#define CR_TX_FLOW_CTRL     0x00000100  /* TX Flow Control                   */
+#define CR_RMII             0x00000200  /* Reduced MII Interface             */
+#define CR_FULL_DUP         0x00000400  /* Full Duplex                       */
+
+/* Status Register */
+#define SR_RX_EN            0x00000001  /* Enable Receive                    */
+#define SR_TX_EN            0x00000002  /* Enable Transmit                   */
+
+/* Transmit Status Vector 0 Register */
+#define TSV0_CRC_ERR        0x00000001  /* CRC error                         */
+#define TSV0_LEN_CHKERR     0x00000002  /* Length Check Error                */
+#define TSV0_LEN_OUTRNG     0x00000004  /* Length Out of Range               */
+#define TSV0_DONE           0x00000008  /* Tramsmission Completed            */
+#define TSV0_MCAST          0x00000010  /* Multicast Destination             */
+#define TSV0_BCAST          0x00000020  /* Broadcast Destination             */
+#define TSV0_PKT_DEFER      0x00000040  /* Packet Deferred                   */
+#define TSV0_EXC_DEFER      0x00000080  /* Excessive Packet Deferral         */
+#define TSV0_EXC_COLL       0x00000100  /* Excessive Collision               */
+#define TSV0_LATE_COLL      0x00000200  /* Late Collision Occured            */
+#define TSV0_GIANT          0x00000400  /* Giant Frame                       */
+#define TSV0_UNDERRUN       0x00000800  /* Buffer Underrun                   */
+#define TSV0_BYTES          0x0FFFF000  /* Total Bytes Transferred           */
+#define TSV0_CTRL_FRAME     0x10000000  /* Control Frame                     */
+#define TSV0_PAUSE          0x20000000  /* Pause Frame                       */
+#define TSV0_BACK_PRESS     0x40000000  /* Backpressure Method Applied       */
+#define TSV0_VLAN           0x80000000  /* VLAN Frame                        */
+
+/* Transmit Status Vector 1 Register */
+#define TSV1_BYTE_CNT       0x0000FFFF  /* Transmit Byte Count               */
+#define TSV1_COLL_CNT       0x000F0000  /* Transmit Collision Count          */
+
+/* Receive Status Vector Register */
+#define RSV_BYTE_CNT        0x0000FFFF  /* Receive Byte Count                */
+#define RSV_PKT_IGNORED     0x00010000  /* Packet Previously Ignored         */
+#define RSV_RXDV_SEEN       0x00020000  /* RXDV Event Previously Seen        */
+#define RSV_CARR_SEEN       0x00040000  /* Carrier Event Previously Seen     */
+#define RSV_REC_CODEV       0x00080000  /* Receive Code Violation            */
+#define RSV_CRC_ERR         0x00100000  /* CRC Error                         */
+#define RSV_LEN_CHKERR      0x00200000  /* Length Check Error                */
+#define RSV_LEN_OUTRNG      0x00400000  /* Length Out of Range               */
+#define RSV_REC_OK          0x00800000  /* Frame Received OK                 */
+#define RSV_MCAST           0x01000000  /* Multicast Frame                   */
+#define RSV_BCAST           0x02000000  /* Broadcast Frame                   */
+#define RSV_DRIB_NIBB       0x04000000  /* Dribble Nibble                    */
+#define RSV_CTRL_FRAME      0x08000000  /* Control Frame                     */
+#define RSV_PAUSE           0x10000000  /* Pause Frame                       */
+#define RSV_UNSUPP_OPC      0x20000000  /* Unsupported Opcode                */
+#define RSV_VLAN            0x40000000  /* VLAN Frame                        */
+
+/* Flow Control Counter Register */
+#define FCC_MIRR_CNT        0x0000FFFF  /* Mirror Counter                    */
+#define FCC_PAUSE_TIM       0xFFFF0000  /* Pause Timer                       */
+
+/* Flow Control Status Register */
+#define FCS_MIRR_CNT        0x0000FFFF  /* Mirror Counter Current            */
+
+/* Receive Filter Control Register */
+#define RFC_UCAST_EN        0x00000001  /* Accept Unicast Frames Enable      */
+#define RFC_BCAST_EN        0x00000002  /* Accept Broadcast Frames Enable    */
+#define RFC_MCAST_EN        0x00000004  /* Accept Multicast Frames Enable    */
+#define RFC_UCAST_HASH_EN   0x00000008  /* Accept Unicast Hash Filter Frames */
+#define RFC_MCAST_HASH_EN   0x00000010  /* Accept Multicast Hash Filter Fram.*/
+#define RFC_PERFECT_EN      0x00000020  /* Accept Perfect Match Enable       */
+#define RFC_MAGP_WOL_EN     0x00001000  /* Magic Packet Filter WoL Enable    */
+#define RFC_PFILT_WOL_EN    0x00002000  /* Perfect Filter WoL Enable         */
+
+/* Receive Filter WoL Status/Clear Registers */
+#define WOL_UCAST           0x00000001  /* Unicast Frame caused WoL          */
+#define WOL_BCAST           0x00000002  /* Broadcast Frame caused WoL        */
+#define WOL_MCAST           0x00000004  /* Multicast Frame caused WoL        */
+#define WOL_UCAST_HASH      0x00000008  /* Unicast Hash Filter Frame WoL     */
+#define WOL_MCAST_HASH      0x00000010  /* Multicast Hash Filter Frame WoL   */
+#define WOL_PERFECT         0x00000020  /* Perfect Filter WoL                */
+#define WOL_RX_FILTER       0x00000080  /* RX Filter caused WoL              */
+#define WOL_MAG_PACKET      0x00000100  /* Magic Packet Filter caused WoL    */
+
+/* Interrupt Status/Enable/Clear/Set Registers */
+#define INT_RX_OVERRUN      0x00000001  /* Overrun Error in RX Queue         */
+#define INT_RX_ERR          0x00000002  /* Receive Error                     */
+#define INT_RX_FIN          0x00000004  /* RX Finished Process Descriptors   */
+#define INT_RX_DONE         0x00000008  /* Receive Done                      */
+#define INT_TX_UNDERRUN     0x00000010  /* Transmit Underrun                 */
+#define INT_TX_ERR          0x00000020  /* Transmit Error                    */
+#define INT_TX_FIN          0x00000040  /* TX Finished Process Descriptors   */
+#define INT_TX_DONE         0x00000080  /* Transmit Done                     */
+#define INT_SOFT_INT        0x00001000  /* Software Triggered Interrupt      */
+#define INT_WAKEUP          0x00002000  /* Wakeup Event Interrupt            */
+
+/* Power Down Register */
+#define PD_POWER_DOWN       0x80000000  /* Power Down MAC                    */
+
+/* RX Descriptor Control Word */
+#define RCTRL_SIZE          0x000007FF  /* Buffer size mask                  */
+#define RCTRL_INT           0x80000000  /* Generate RxDone Interrupt         */
+
+/* RX Status Hash CRC Word */
+#define RHASH_SA            0x000001FF  /* Hash CRC for Source Address       */
+#define RHASH_DA            0x001FF000  /* Hash CRC for Destination Address  */
+
+/* RX Status Information Word */
+#define RINFO_SIZE          0x000007FF  /* Data size in bytes                */
+#define RINFO_CTRL_FRAME    0x00040000  /* Control Frame                     */
+#define RINFO_VLAN          0x00080000  /* VLAN Frame                        */
+#define RINFO_FAIL_FILT     0x00100000  /* RX Filter Failed                  */
+#define RINFO_MCAST         0x00200000  /* Multicast Frame                   */
+#define RINFO_BCAST         0x00400000  /* Broadcast Frame                   */
+#define RINFO_CRC_ERR       0x00800000  /* CRC Error in Frame                */
+#define RINFO_SYM_ERR       0x01000000  /* Symbol Error from PHY             */
+#define RINFO_LEN_ERR       0x02000000  /* Length Error                      */
+#define RINFO_RANGE_ERR     0x04000000  /* Range Error (exceeded max. size)  */
+#define RINFO_ALIGN_ERR     0x08000000  /* Alignment Error                   */
+#define RINFO_OVERRUN       0x10000000  /* Receive overrun                   */
+#define RINFO_NO_DESCR      0x20000000  /* No new Descriptor available       */
+#define RINFO_LAST_FLAG     0x40000000  /* Last Fragment in Frame            */
+#define RINFO_ERR           0x80000000  /* Error Occured (OR of all errors)  */
+
+#define RINFO_ERR_MASK     (RINFO_FAIL_FILT | RINFO_CRC_ERR   | RINFO_SYM_ERR | \
+                            RINFO_LEN_ERR   | RINFO_ALIGN_ERR | RINFO_OVERRUN)
+
+/* TX Descriptor Control Word */
+#define TCTRL_SIZE          0x000007FF  /* Size of data buffer in bytes      */
+#define TCTRL_OVERRIDE      0x04000000  /* Override Default MAC Registers    */
+#define TCTRL_HUGE          0x08000000  /* Enable Huge Frame                 */
+#define TCTRL_PAD           0x10000000  /* Pad short Frames to 64 bytes      */
+#define TCTRL_CRC           0x20000000  /* Append a hardware CRC to Frame    */
+#define TCTRL_LAST          0x40000000  /* Last Descriptor for TX Frame      */
+#define TCTRL_INT           0x80000000  /* Generate TxDone Interrupt         */
+
+/* TX Status Information Word */
+#define TINFO_COL_CNT       0x01E00000  /* Collision Count                   */
+#define TINFO_DEFER         0x02000000  /* Packet Deferred (not an error)    */
+#define TINFO_EXCESS_DEF    0x04000000  /* Excessive Deferral                */
+#define TINFO_EXCESS_COL    0x08000000  /* Excessive Collision               */
+#define TINFO_LATE_COL      0x10000000  /* Late Collision Occured            */
+#define TINFO_UNDERRUN      0x20000000  /* Transmit Underrun                 */
+#define TINFO_NO_DESCR      0x40000000  /* No new Descriptor available       */
+#define TINFO_ERR           0x80000000  /* Error Occured (OR of all errors)  */
+
+/* ENET Device Revision ID */
+#define OLD_EMAC_MODULE_ID  0x39022000  /* Rev. ID for first rev '-'         */
+
+/* DP83848C PHY Registers */
+#define PHY_REG_BMCR        0x00        /* Basic Mode Control Register       */
+#define PHY_REG_BMSR        0x01        /* Basic Mode Status Register        */
+#define PHY_REG_IDR1        0x02        /* PHY Identifier 1                  */
+#define PHY_REG_IDR2        0x03        /* PHY Identifier 2                  */
+#define PHY_REG_ANAR        0x04        /* Auto-Negotiation Advertisement    */
+#define PHY_REG_ANLPAR      0x05        /* Auto-Neg. Link Partner Abitily    */
+#define PHY_REG_ANER        0x06        /* Auto-Neg. Expansion Register      */
+#define PHY_REG_ANNPTR      0x07        /* Auto-Neg. Next Page TX            */
+
+/* PHY Extended Registers */
+#define PHY_REG_STS         0x10        /* Status Register                   */
+#define PHY_REG_MICR        0x11        /* MII Interrupt Control Register    */
+#define PHY_REG_MISR        0x12        /* MII Interrupt Status Register     */
+#define PHY_REG_FCSCR       0x14        /* False Carrier Sense Counter       */
+#define PHY_REG_RECR        0x15        /* Receive Error Counter             */
+#define PHY_REG_PCSR        0x16        /* PCS Sublayer Config. and Status   */
+#define PHY_REG_RBR         0x17        /* RMII and Bypass Register          */
+#define PHY_REG_LEDCR       0x18        /* LED Direct Control Register       */
+#define PHY_REG_PHYCR       0x19        /* PHY Control Register              */
+#define PHY_REG_10BTSCR     0x1A        /* 10Base-T Status/Control Register  */
+#define PHY_REG_CDCTRL1     0x1B        /* CD Test Control and BIST Extens.  */
+#define PHY_REG_EDCR        0x1D        /* Energy Detect Control Register    */
+
+#define PHY_FULLD_100M      0x2100      /* Full Duplex 100Mbit               */
+#define PHY_HALFD_100M      0x2000      /* Half Duplex 100Mbit               */
+#define PHY_FULLD_10M       0x0100      /* Full Duplex 10Mbit                */
+#define PHY_HALFD_10M       0x0000      /* Half Duplex 10MBit                */
+#define PHY_AUTO_NEG        0x3000      /* Select Auto Negotiation           */
+
+#define DP83848C_DEF_ADR    0x0100      /* Default PHY device address        */
+#define DP83848C_ID         0x20005C90  /* PHY Identifier                    */
+
+/** \brief DP83848 PHY status definitions */
+#define DP8_REMOTEFAULT    (1 << 6)   /**< Remote fault */
+#define DP8_FULLDUPLEX     (1 << 2)   /**< 1=full duplex */
+#define DP8_SPEED10MBPS    (1 << 1)   /**< 1=10MBps speed */
+#define DP8_VALID_LINK     (1 << 0)   /**< 1=Link active */
+
+#define DISABLE_ETH_RX_INTERRUPT LPC_EMAC->IntEnable = LPC_EMAC->IntEnable & ~(INT_RX_DONE)
+#define ENABLE_ETH_RX_INTERRUPT  LPC_EMAC->IntEnable = LPC_EMAC->IntEnable |  (INT_RX_DONE)
+
+#endif
\ No newline at end of file