mbed library sources

Dependents:   Nucleo_blink_led

Fork of mbed-src by mbed official

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Mon Feb 09 08:45:07 2015 +0000
Parent:
466:12a9a5f8fea0
Child:
468:3f6bf90246bd
Commit message:
Synchronized with git revision aeeed2d0507dc81ed795d026940ad5234c03f314

Full URL: https://github.com/mbedmicro/mbed/commit/aeeed2d0507dc81ed795d026940ad5234c03f314/

Initial ethernet support for LPC433x

Changed in this revision

targets/cmsis/TARGET_Freescale/TARGET_K22F/cmsis_nvic.c Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_Freescale/TARGET_K22F/cmsis_nvic.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_NXP/TARGET_LPC43XX/ethernet_api.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/cmsis/TARGET_Freescale/TARGET_K22F/cmsis_nvic.c	Fri Feb 06 08:30:07 2015 +0000
+++ b/targets/cmsis/TARGET_Freescale/TARGET_K22F/cmsis_nvic.c	Mon Feb 09 08:45:07 2015 +0000
@@ -30,7 +30,7 @@
  */
 #include "cmsis_nvic.h"
 
-#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFE000)  // Vectors positioned at start of RAM
+#define NVIC_RAM_VECTOR_ADDRESS (0x1FFF0000)  // Vectors positioned at start of RAM
 #define NVIC_FLASH_VECTOR_ADDRESS (0x0)       // Initial vector position in flash
 
 void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
--- a/targets/cmsis/TARGET_Freescale/TARGET_K22F/cmsis_nvic.h	Fri Feb 06 08:30:07 2015 +0000
+++ b/targets/cmsis/TARGET_Freescale/TARGET_K22F/cmsis_nvic.h	Mon Feb 09 08:45:07 2015 +0000
@@ -32,7 +32,7 @@
 #ifndef MBED_CMSIS_NVIC_H
 #define MBED_CMSIS_NVIC_H
 
-#define NVIC_NUM_VECTORS      (16 + 46)   // CORE + MCU Peripherals
+#define NVIC_NUM_VECTORS      (16 + 86)   // CORE + MCU Peripherals
 #define NVIC_USER_IRQ_OFFSET  16
 
 #include "cmsis.h"
--- a/targets/hal/TARGET_NXP/TARGET_LPC43XX/ethernet_api.c	Fri Feb 06 08:30:07 2015 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC43XX/ethernet_api.c	Mon Feb 09 08:45:07 2015 +0000
@@ -1,5 +1,5 @@
 /* mbed Microcontroller Library
- * Copyright (c) 2006-2013 ARM Limited
+ * Copyright (c) 2006-2015 ARM Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * Ported to NXP LPC43XX by Micromint USA <support@micromint.com>
+ * Contribution by Nitin Bhaskar(nitin.bhaskar.27.09@gmail.com)
  */
 #include "ethernet_api.h"
 
@@ -22,6 +22,7 @@
 #include "mbed_interface.h"
 #include "toolchain.h"
 #include "mbed_error.h"
+#include "pinmap.h"
 
 #define NEW_LOGIC       0
 #define NEW_ETH_BUFFER  0
@@ -54,83 +55,76 @@
 
 #define ETHERNET_ADDR_SIZE 6
 
+/*  Descriptors Fields bits       */
+#define TRDES_OWN_BIT		(1U<<31)	/*  Own bit in RDES0 & TDES0              */
+#define RX_END_RING		(1<<15)		/*  Receive End of Ring bit in RDES1      */
+#define RX_NXTDESC_FLAG		(1<<14)		/*  Second Address Chained bit in RDES1   */
+#define TX_LAST_SEGM		(1<<29)		/*  Last Segment bit in TDES0             */
+#define TX_FIRST_SEGM		(1<<28)		/*  First Segment bit in TDES0            */
+#define TX_END_RING		(1<<21)		/*  Transmit End of Ring bit in TDES0     */
+#define TX_NXTDESC_FLAG		(1<<20)		/*  Second Address Chained bit in TDES0   */
+
 PACKED struct RX_DESC_TypeDef {                        /* RX Descriptor struct              */
-   unsigned int Packet;
-   unsigned int Ctrl;
+    unsigned int Status;
+    unsigned int Ctrl;
+    unsigned int BufAddr1;
+    unsigned int NextDescAddr;
 };
 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;
+    unsigned int Status;
+    unsigned int Ctrl;
+    unsigned int BufAddr1;
+    unsigned int NextDescAddr;
 };
 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;
+/* ETHMODE RMII SELECT */
+#define RMII_SELECT			0x04
+/* define to tell PHY about write operation */
+#define MII_WRITE		(1 << 1)
+/* define to tell PHY about read operation */
+#define MII_READ		(0 << 1)
+/* define to enable duplex mode */
+#define MAC_DUPLEX_MODE (1 << 11)
 
-/* 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_FRAME_FILTER register bit defines */
+#define MAC_FRAME_FILTER_PR      (1 << 0)		/* Promiscuous Mode */
+#define MAC_FRAME_FILTER_RA      (1UL << 31)	/* Receive all */
+
+/* MAC_CONFIG register bit defines */
+#define MAC_CONFIG_RE     (1 << 2)		/* Receiver enable */
+#define MAC_CONFIG_TE     (1 << 3)		/* Transmitter Enable */
 
-/* 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                      */
+/* DMA_OP_MODE register bit defines */
+#define DMA_OP_MODE_SSR      (1 << 1)		/* Start/stop receive */
+#define DMA_OP_MODE_SST      (1 << 13)	/* Start/Stop Transmission Command */
 
-/* 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 */
+/* DMA_INT_EN register bit defines */
+#define DMA_INT_EN_TIE     (1 << 0)		/* Transmit interrupt enable */
+#define DMA_INT_EN_TSE     (1 << 1)		/* Transmit stopped enable */
+#define DMA_INT_EN_TUE     (1 << 2)		/* Transmit buffer unavailable enable */
+#define DMA_INT_EN_TJE     (1 << 3)		/* Transmit jabber timeout enable */
+#define DMA_INT_EN_OVE     (1 << 4)		/* Overflow interrupt enable */
+#define DMA_INT_EN_UNE     (1 << 5)		/* Underflow interrupt enable */
+#define DMA_INT_EN_RIE     (1 << 6)		/* Receive interrupt enable */
+#define DMA_INT_EN_RUE     (1 << 7)		/* Receive buffer unavailable enable */
+#define DMA_INT_EN_RSE     (1 << 8)		/* Received stopped enable */
+#define DMA_INT_EN_RWE     (1 << 9)		/* Receive watchdog timeout enable */
+#define DMA_INT_EN_ETE     (1 << 10)	/* Early transmit interrupt enable */
+#define DMA_INT_EN_FBE     (1 << 13)	/* Fatal bus error enable */
+#define DMA_INT_EN_ERE     (1 << 14)	/* Early receive interrupt enable */
+#define DMA_INT_EN_AIE     (1 << 15)	/* Abnormal interrupt summary enable */
+#define DMA_INT_EN_NIE     (1 << 16)	/* Normal interrupt summary enable */
 
-/* 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_SPEED          0x00004000  /* Reduced MII Logic Current Speed   */
 //#define SUPP_RES_RMII       0x00000800  /* Reset Reduced MII Logic           */
 #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        0x0000003C  /* 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             */
@@ -148,157 +142,6 @@
 #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)
-#define RINFO_ERR_MASK     (RINFO_FAIL_FILT | 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        */
@@ -329,9 +172,9 @@
 #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 PHY_AUTO_NEG        0x1000      /* Select Auto Negotiation           */
 
-#define DP83848C_DEF_ADR    0x0100      /* Default PHY device address        */
+#define DP83848C_DEF_ADR    0x01      /* Default PHY device address        */
 #define DP83848C_ID         0x20005C90  /* PHY Identifier - DP83848C         */
 
 #define LAN8720_ID          0x0007C0F0  /* PHY Identifier - LAN8720          */
@@ -347,6 +190,12 @@
 #define PHY_SCSR_100MBIT    0x0008      /* Speed: 1=100 MBit, 0=10Mbit       */
 #define PHY_SCSR_DUPLEX     0x0010      /* PHY Duplex Mask                   */
 
+static int phy_read(unsigned int PhyReg);
+static int phy_write(unsigned int PhyReg, unsigned short Data);
+
+static void txdscr_init(void);
+static void rxdscr_init(void);
+
 #if defined (__ICCARM__)
 #   define AHBSRAM1
 #elif defined(TOOLCHAIN_GCC_CR)
@@ -358,78 +207,322 @@
 AHBSRAM1 volatile uint8_t rxbuf[NUM_RX_FRAG][ETH_FRAG_SIZE];
 AHBSRAM1 volatile uint8_t txbuf[NUM_TX_FRAG][ETH_FRAG_SIZE];
 AHBSRAM1 volatile RX_DESC_TypeDef rxdesc[NUM_RX_FRAG];
-AHBSRAM1 volatile RX_STAT_TypeDef rxstat[NUM_RX_FRAG];
 AHBSRAM1 volatile TX_DESC_TypeDef txdesc[NUM_TX_FRAG];
-AHBSRAM1 volatile TX_STAT_TypeDef txstat[NUM_TX_FRAG];
 
 #ifndef min
 #define min(x, y) (((x)<(y))?(x):(y))
 #endif
 
+static uint32_t phy_id = 0;
+static uint32_t TxDescIndex = 0;
+static uint32_t RxDescIndex = 0;
+static uint32_t RxOffset = 0;
+
 /*----------------------------------------------------------------------------
   Ethernet Device initialize
  *----------------------------------------------------------------------------*/
-int ethernet_init() {
-  return 0;
+int ethernet_init()
+{
+    int regv, tout;
+    char mac[ETHERNET_ADDR_SIZE];
+
+    pin_function(PC_0, (SCU_MODE_INACT | FUNC3)); 	/* Enable ENET RX CLK */
+    pin_function(P1_19, (SCU_MODE_INACT | FUNC0)); 	/* Enable ENET TX CLK */
+
+    /* Ethernet pinmuxing	*/
+    pin_function(P2_0, SCU_PINIO_FAST | FUNC7); 	/* ENET_MDC */
+    pin_function(P1_17, SCU_PINIO_FAST | FUNC3); 	/* ENET_MDIO */
+    pin_function(P1_18, SCU_PINIO_FAST | FUNC3); 	/* ENET_TXD0 */
+    pin_function(P1_20, SCU_PINIO_FAST | FUNC3); 	/* ENET_TXD1 */
+    pin_function(P1_19, SCU_PINIO_FAST | FUNC0); 	/* ENET_REF */
+    pin_function(P0_1, SCU_PINIO_FAST | FUNC6); 	/* ENET_TX_EN */
+    pin_function(P1_15, SCU_PINIO_FAST | FUNC3); 	/* ENET_RXD0 */
+    pin_function(P0_0, SCU_PINIO_FAST | FUNC2); 	/* ENET_RXD1 */
+    pin_function(P1_16, SCU_PINIO_FAST | FUNC3); 	/* ENET_CRS */
+    pin_function(PC_9, SCU_PINIO_FAST | FUNC3); 	/* ENET_RX_ER */
+    pin_function(P1_16, SCU_PINIO_FAST | FUNC7); 	/* ENET_RXDV */
+
+    LPC_CREG->CREG6 |= RMII_SELECT;
+
+    /* perform RGU soft reset */
+    LPC_RGU->RESET_CTRL0 = 1 << 22;
+    LPC_RGU->RESET_CTRL0 = 0;
+
+    /* Wait until reset is performed */
+    while(1) {
+        if (LPC_RGU->RESET_ACTIVE_STATUS0 & (1 << 22))
+            break;
+    }
+
+    /* Reset MAC DMA Controller */
+    LPC_ETHERNET->DMA_BUS_MODE |= 0x01;
+    while(LPC_ETHERNET->DMA_BUS_MODE & 0x01);
+
+    phy_write(PHY_REG_BMCR, PHY_BMCR_RESET);           /* perform PHY reset */
+
+    for(tout = 0x20000; ; tout--) {                    /* Wait for hardware reset to end. */
+        regv = phy_read(PHY_REG_BMCR);
+        if(regv < 0 || tout == 0) {
+            return -1;                                    /* Error */
+        }
+        if(!(regv & PHY_BMCR_RESET)) {
+            break;                                        /* Reset complete. */
+        }
+    }
+
+    phy_id =  (phy_read(PHY_REG_IDR1) << 16);
+    phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0);
+
+    if (phy_id != DP83848C_ID && phy_id != LAN8720_ID) {
+        error("Unknown Ethernet PHY (%x)", (unsigned int)phy_id);
+    }
+
+    ethernet_set_link(-1, 0);
+
+    /* Set the Ethernet MAC Address registers */
+    ethernet_address(mac);
+    LPC_ETHERNET->MAC_ADDR0_HIGH = (mac[5] << 8) | mac[4];
+    LPC_ETHERNET->MAC_ADDR0_LOW =	(mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
+
+    txdscr_init();                                      /* initialize DMA TX Descriptor */
+    rxdscr_init();                                      /* initialize DMA RX Descriptor */
+
+    /* Configure Filter */
+    LPC_ETHERNET->MAC_FRAME_FILTER = MAC_FRAME_FILTER_PR | MAC_FRAME_FILTER_RA;
+
+    /* Enable Receiver and Transmitter */
+    LPC_ETHERNET->MAC_CONFIG |= (MAC_CONFIG_RE | MAC_CONFIG_TE);
+
+    //LPC_ETHERNET->DMA_INT_EN =  DMA_INT_EN_NIE | DMA_INT_EN_RIE | DMA_INT_EN_TJE;	/* Enable EMAC interrupts. */
+
+    /* Start Transmission & Receive processes   */
+    LPC_ETHERNET->DMA_OP_MODE |= (DMA_OP_MODE_SST | DMA_OP_MODE_SSR);
+
+    return 0;
 }
 
 /*----------------------------------------------------------------------------
   Ethernet Device Uninitialize
  *----------------------------------------------------------------------------*/
-void ethernet_free() {
+void ethernet_free()
+{
+}
+
+/*----------------------------------------------------------------------------
+  Ethernet write
+ *----------------------------------------------------------------------------*/
+int ethernet_write(const char *data, int slen)
+{
+    if (slen > ETH_FRAG_SIZE)
+        return -1;
+
+    txdesc[TxDescIndex].Ctrl = slen;
+    memcpy((void *)txdesc[TxDescIndex].BufAddr1, data, slen);
+    return slen;
 }
 
-// if(TxProduceIndex == TxConsumeIndex) buffer array is empty
-// if(TxProduceIndex == TxConsumeIndex - 1) buffer is full, should not fill
-// TxProduceIndex - The buffer that will/is being fileld by driver, s/w increment
-// TxConsumeIndex - The buffer that will/is beign sent by hardware
+/*----------------------------------------------------------------------------
+  Ethernet Send
+ *----------------------------------------------------------------------------*/
+int ethernet_send()
+{
+    int s = txdesc[TxDescIndex].Ctrl;
+    txdesc[TxDescIndex].Status |= TRDES_OWN_BIT;
+    LPC_ETHERNET->DMA_TRANS_POLL_DEMAND = 1;   //  Wake Up the DMA if it's in Suspended Mode
+    TxDescIndex++;
+    if (TxDescIndex == NUM_TX_FRAG)
+        TxDescIndex = 0;
 
-int ethernet_write(const char *data, int slen) {
-  return -1;
+    return s;
 }
 
-int ethernet_send() {
-  return -1;
+/*----------------------------------------------------------------------------
+  Ethernet receive
+ *----------------------------------------------------------------------------*/
+int ethernet_receive()
+{
+    int i, slen = 0;
+    for (i = RxDescIndex;; i++) {
+        if (rxdesc[i].Status & TRDES_OWN_BIT)
+            return (slen - RxOffset);
+        else
+            slen += (rxdesc[i].Status >> 16) & 0x03FFF;
+    }
+    return 0;
 }
 
-// RxConsmeIndex - The index of buffer the driver will/is reading from. Driver should inc once read
-// RxProduceIndex - The index of buffer that will/is being filled by MAC. H/w will inc once rxd
-//
-// if(RxConsumeIndex == RxProduceIndex) buffer array is empty
-// if(RxConsumeIndex == RxProduceIndex + 1) buffer array is full
+
+/*----------------------------------------------------------------------------
+  Ethernet read
+ *----------------------------------------------------------------------------*/
+int ethernet_read(char *data, int dlen)
+{
+    int copylen;
+    uint32_t *pSrc = (uint32_t *)rxdesc[RxDescIndex].BufAddr1;
+    copylen = (rxdesc[RxDescIndex].Status >> 16) & 0x03FFF;
+    if (rxdesc[RxDescIndex].Status & TRDES_OWN_BIT || (dlen + RxOffset) > copylen)
+        return -1;
 
-// Recevies an arrived ethernet packet.
-// Receiving an ethernet packet will drop the last received ethernet packet
-// and make a new ethernet packet ready to read.
-// Returns size of packet, else 0 if nothing to receive
-
-// We read from RxConsumeIndex from position rx_consume_offset
-// if rx_consume_offset < 0, then we have not recieved the RxConsumeIndex packet for reading
-// rx_consume_offset = -1 // no frame
-// rx_consume_offset = 0  // start of frame
-// Assumption: A fragment should alway be a whole frame
-
-int ethernet_receive() {
-  return -1;
+    if ((dlen + RxOffset) == copylen) {
+        memcpy(&pSrc[RxOffset], data, copylen);
+        rxdesc[RxDescIndex].Status = TRDES_OWN_BIT;
+        RxDescIndex++;
+        RxOffset = 0;
+        if (RxDescIndex == NUM_RX_FRAG)
+            RxDescIndex = 0;
+    } else if ((dlen + RxOffset) < copylen) {
+        copylen = dlen;
+        memcpy(&pSrc[RxOffset], data, copylen);
+        RxOffset += dlen;
+    }
+    return copylen;
 }
 
-// Read from an recevied ethernet packet.
-// After receive returnd a number bigger than 0 it is
-// possible to read bytes from this packet.
-// Read will write up to size bytes into data.
-// It is possible to use read multible times.
-// Each time read will start reading after the last read byte before.
+int ethernet_link(void)
+{
+
+    if (phy_id == DP83848C_ID) {
+        return (phy_read(PHY_REG_STS) & PHY_STS_LINK);
+    } else { // LAN8720_ID
+        return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK);
+    }
+}
 
-int ethernet_read(char *data, int dlen) {
+static int phy_write(unsigned int PhyReg, unsigned short Data)
+{
+    unsigned int timeOut;
+
+    while(LPC_ETHERNET->MAC_MII_ADDR & MIND_BUSY);
+    LPC_ETHERNET->MAC_MII_ADDR = (DP83848C_DEF_ADR<<11) | (PhyReg<<6) | MII_WRITE;
+    LPC_ETHERNET->MAC_MII_DATA = Data;
+    LPC_ETHERNET->MAC_MII_ADDR |= MIND_BUSY;				// Start PHY Write Cycle
+
+    /* Wait utill operation completed */
+    for (timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) {
+        if ((LPC_ETHERNET->MAC_MII_ADDR & MIND_BUSY) == 0) {
+            break;
+        }
+    }
+
     return -1;
 }
 
-int ethernet_link(void) {
+static int phy_read(unsigned int PhyReg)
+{
+    unsigned int timeOut;
+
+    while(LPC_ETHERNET->MAC_MII_ADDR & MIND_BUSY);
+    LPC_ETHERNET->MAC_MII_ADDR = (DP83848C_DEF_ADR<<11) | (PhyReg<<6) | MII_READ;
+    LPC_ETHERNET->MAC_MII_ADDR |= MIND_BUSY;
+
+    for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) {     /* Wait until operation completed */
+        if((LPC_ETHERNET->MAC_MII_ADDR & MIND_BUSY) == 0) {
+            return LPC_ETHERNET->MAC_MII_DATA;               /* Return a 16-bit value. */
+        }
+    }
+
     return -1;
 }
 
-void ethernet_address(char *mac) {
+static void txdscr_init()
+{
+    int i;
+
+    for(i = 0; i < NUM_TX_FRAG; i++) {
+        txdesc[i].Status = TX_LAST_SEGM | TX_FIRST_SEGM;;
+        txdesc[i].Ctrl   = 0;
+        txdesc[i].BufAddr1   = (uint32_t)&txbuf[i];
+        if (i == (NUM_RX_FRAG - 1)) {
+            txdesc[i].Status |= TX_END_RING;
+        }
+    }
+
+    LPC_ETHERNET->DMA_TRANS_DES_ADDR = (uint32_t)txdesc;         /* Set EMAC Transmit Descriptor Registers. */
+}
+
+
+static void rxdscr_init()
+{
+    int i;
+
+    for(i = 0; i < NUM_RX_FRAG; i++) {
+        rxdesc[i].Status  = TRDES_OWN_BIT;
+        rxdesc[i].Ctrl    = ETH_FRAG_SIZE;
+        rxdesc[i].BufAddr1  = (uint32_t)&rxbuf[i];
+        if (i == (NUM_RX_FRAG - 1)) {
+            rxdesc[i].Ctrl |= RX_END_RING;
+        }
+    }
+
+    LPC_ETHERNET->DMA_REC_DES_ADDR = (uint32_t)rxdesc;        /* Set EMAC Receive Descriptor Registers. */
+}
+
+void ethernet_address(char *mac)
+{
+    mbed_mac_address(mac);
 }
 
-void ethernet_set_link(int speed, int duplex) {
+void ethernet_set_link(int speed, int duplex)
+{
+    volatile unsigned short phy_data;
+    int tout;
+
+    if((speed < 0) || (speed > 1)) {
+
+        phy_data = PHY_AUTO_NEG;
+
+    } else {
+
+        phy_data = (((unsigned short) speed << 13) |
+                    ((unsigned short) duplex << 8));
+    }
+
+    phy_write(PHY_REG_BMCR, phy_data);
+
+    for(tout = 100; tout; tout--) {
+        __NOP();    /* A short delay */
+    }
+
+    switch(phy_id) {
+        case DP83848C_ID:
+
+            phy_data = phy_read(PHY_REG_STS);
+
+            if(phy_data & PHY_STS_DUPLEX) {
+                /* Full duplex is enabled. */
+                LPC_ETHERNET->MAC_CONFIG |= MAC_DUPLEX_MODE;
+            } else {
+                LPC_ETHERNET->MAC_CONFIG &= ~MAC_DUPLEX_MODE;
+            }
+
+            if(phy_data & PHY_STS_SPEED) {
+                LPC_ETHERNET->MAC_CONFIG &= ~SUPP_SPEED;
+            } else {
+                LPC_ETHERNET->MAC_CONFIG |= SUPP_SPEED;
+            }
+            break;
+
+        case LAN8720_ID:
+
+            for(tout = 100; tout; tout--) {
+                phy_data = phy_read(PHY_REG_BMSR);
+                if (phy_data & PHY_STS_DUPLEX)
+                    break;
+            }
+
+            if (phy_data & PHY_STS_DUPLEX) {
+                /* Full duplex is enabled. */
+                LPC_ETHERNET->MAC_CONFIG |= MAC_DUPLEX_MODE;
+            } else {
+                LPC_ETHERNET->MAC_CONFIG &= ~MAC_DUPLEX_MODE;
+            }
+
+            if(phy_data & PHY_STS_SPEED) {
+                LPC_ETHERNET->MAC_CONFIG &= ~SUPP_SPEED;
+            } else {
+                LPC_ETHERNET->MAC_CONFIG |= SUPP_SPEED;
+            }
+            break;
+    }
 }
+