Jelajahi Sumber

[BSP] Add EMAC driver in lpc4088

Bernard Xiong 9 tahun lalu
induk
melakukan
8f607deff3

+ 2 - 2
bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/system_LPC407x_8x_177x_8x.c

@@ -221,12 +221,12 @@
 #define SCS_Val               0x00000020
 #define CLKSRCSEL_Val         0x00000001
 #define PLL0_SETUP            1
-#define PLL0CFG_Val           0x0000000a
+#define PLL0CFG_Val           0x00000009
 #define PLL1_SETUP            1
 #define PLL1CFG_Val           0x00000023
 #define CCLKSEL_Val           0x00000101
 #define USBCLKSEL_Val         0x00000201
-#define EMCCLKSEL_Val         0x00000001
+#define EMCCLKSEL_Val         0x00000000
 #define PCLKSEL_Val           0x00000002
 #define SPIFICLKSEL_Val       0x00000002
 #define PCONP_Val             0x042887DE

+ 1 - 1
bsp/lpc408x/Libraries/Device/SConscript

@@ -18,6 +18,6 @@ elif rtconfig.CROSS_TOOL == 'keil':
 elif rtconfig.CROSS_TOOL == 'iar':
 	src += ['NXP/LPC407x_8x_177x_8x/Source/Templates/IAR/startup_LPC407x_8x_177x_8x.s']
 
-group = DefineGroup('CMSIS', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
+group = DefineGroup('Libraries', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
 
 Return('group')

+ 3 - 2
bsp/lpc408x/applications/board.c

@@ -52,9 +52,10 @@ void rt_hw_board_init()
 #endif
 
     /* init systick */
-    SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
+    SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND - 1);
     /* set pend exception priority */
     NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
+
     /*init uart device*/
     rt_hw_uart_init();
     rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
@@ -64,5 +65,5 @@ void rt_hw_board_init()
     lpc_sdram_hw_init();
     rt_kprintf("done!\n");
 #endif
-    rt_components_board_init();
+    // rt_components_board_init();
 }

+ 15 - 3
bsp/lpc408x/applications/board.h

@@ -11,6 +11,7 @@
  * Date           Author       Notes
  * 2009-09-22     Bernard      add board.h to this bsp
  * 2010-02-04     Magicoe      add board.h to LPC176x bsp
+ * 2013-12-18     Bernard      porting to LPC4088 bsp
  */
 
 #ifndef __BOARD_H__
@@ -19,10 +20,21 @@
 #include "LPC407x_8x_177x_8x.h"
 #include <rtthread.h>
 
+/* SRAM allocation for Peripherals */
+#define USB_RAM_BASE        0x20000000
+#define MCI_RAM_BASE        0x20002000
+#define ETH_RAM_BASE        0x20004000
+
+/* use SDRAM in default */
+#define LPC_EXT_SDRAM   1
+
+/* disable SDRAM in default */
+#ifndef LPC_EXT_SDRAM
+#define LPC_EXT_SDRAM       0
+#endif
+
 // <RDTConfigurator URL="http://www.rt-thread.com/eclipse">
 
-// <integer name="LPC_EXT_SDRAM" description="Enable External SDRAM memory" default="0" />
-//#define LPC_EXT_SDRAM    0
 // <integer name="LPC_EXT_SDRAM" description="Begin Address of External SDRAM" default="0xA0000000" />
 #define LPC_EXT_SDRAM_BEGIN    0xA0000000
 // <integer name="LPC_EXT_SDRAM_END" description="End Address of External SDRAM" default="0xA2000000" />
@@ -47,7 +59,7 @@ extern int Image$$RW_IRAM1$$ZI$$Limit;
 extern int __bss_end;
 #define HEAP_BEGIN  ((void *)&__bss_end)
 #endif
-#define HEAP_END    (0x10000000 + 0x10000)
+#define HEAP_END    (void*)(0x10000000 + 0x10000)
 
 #define FINSH_DEVICE_NAME   RT_CONSOLE_DEVICE_NAME
 void rt_hw_board_init(void);

+ 512 - 0
bsp/lpc408x/drivers/drv_emac.c

@@ -0,0 +1,512 @@
+/*
+ * File      : drv_emac.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009-2013 RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-05-19     Bernard      porting from LPC17xx drivers.
+ */
+
+#include <rtthread.h>
+#include "lwipopts.h"
+#include <netif/ethernetif.h>
+#include <board.h>
+
+#include "lpc_pinsel.h"
+#include "drv_emac.h"
+
+#define EMAC_PHY_AUTO       0
+#define EMAC_PHY_10MBIT     1
+#define EMAC_PHY_100MBIT    2
+
+#define MAX_ADDR_LEN 6
+
+/* EMAC_RAM_BASE is defined in board.h and the size is 16KB */
+#define RX_DESC_BASE        ETH_RAM_BASE
+#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_FRAG_SIZE)
+
+/* 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_FRAG_SIZE*i)
+#define TX_BUF(i)           (TX_BUF_BASE + ETH_FRAG_SIZE*i)
+
+struct lpc_emac
+{
+    /* inherit from ethernet device */
+    struct eth_device parent;
+
+    rt_uint8_t phy_mode;
+
+    /* interface address info. */
+    rt_uint8_t  dev_addr[MAX_ADDR_LEN];     /* hw address   */
+};
+static struct lpc_emac lpc_emac_device;
+static struct rt_semaphore sem_lock;
+static struct rt_event tx_event;
+
+/* Local Function Prototypes */
+static void write_PHY(rt_uint32_t PhyReg, rt_uint32_t Value);
+static rt_uint16_t read_PHY(rt_uint8_t PhyReg) ;
+
+void ENET_IRQHandler(void)
+{
+    rt_uint32_t status;
+
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    status = LPC_EMAC->IntStatus;
+
+    if (status & INT_RX_DONE)
+    {
+        /* Disable EMAC RxDone interrupts. */
+        LPC_EMAC->IntEnable = INT_TX_DONE;
+
+        /* a frame has been received */
+        eth_device_ready(&(lpc_emac_device.parent));
+    }
+    else if (status & INT_TX_DONE)
+    {
+        /* set event */
+        rt_event_send(&tx_event, 0x01);
+    }
+
+    if (status & INT_RX_OVERRUN)
+    {
+        rt_kprintf("rx overrun\n");
+    }
+
+    if (status & INT_TX_UNDERRUN)
+    {
+        rt_kprintf("tx underrun\n");
+    }
+
+    /* Clear the interrupt. */
+    LPC_EMAC->IntClear = status;
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+/* phy write */
+static void write_PHY(rt_uint32_t PhyReg, rt_uint32_t Value)
+{
+    unsigned int tout;
+
+    LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
+    LPC_EMAC->MWTD = Value;
+
+    /* Wait utill operation completed */
+    tout = 0;
+    for (tout = 0; tout < MII_WR_TOUT; tout++)
+    {
+        if ((LPC_EMAC->MIND & MIND_BUSY) == 0)
+        {
+            break;
+        }
+    }
+}
+
+/* phy read */
+static rt_uint16_t read_PHY(rt_uint8_t PhyReg)
+{
+    rt_uint32_t tout;
+
+    LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
+    LPC_EMAC->MCMD = MCMD_READ;
+
+    /* Wait until operation completed */
+    tout = 0;
+    for (tout = 0; tout < MII_RD_TOUT; tout++)
+    {
+        if ((LPC_EMAC->MIND & MIND_BUSY) == 0)
+        {
+            break;
+        }
+    }
+    LPC_EMAC->MCMD = 0;
+    return (LPC_EMAC->MRDD);
+}
+
+/* init rx descriptor */
+rt_inline void rx_descr_init(void)
+{
+    rt_uint32_t i;
+
+    for (i = 0; i < NUM_RX_FRAG; i++)
+    {
+        RX_DESC_PACKET(i)  = RX_BUF(i);
+        RX_DESC_CTRL(i)    = RCTRL_INT | (ETH_FRAG_SIZE - 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;
+}
+
+/* init tx descriptor */
+rt_inline void tx_descr_init(void)
+{
+    rt_uint32_t i;
+
+    for (i = 0; i < NUM_TX_FRAG; i++)
+    {
+        TX_DESC_PACKET(i) = TX_BUF(i);
+        TX_DESC_CTRL(i)   = (1ul << 31) | (1ul << 30) | (1ul << 29) | (1ul << 28) | (1ul << 26) | (ETH_FRAG_SIZE - 1);
+        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;
+}
+
+/*
+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;
+}
+
+static rt_err_t lpc_emac_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+static rt_err_t lpc_emac_close(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_size_t lpc_emac_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    rt_set_errno(-RT_ENOSYS);
+    return 0;
+}
+
+static rt_size_t lpc_emac_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+    rt_set_errno(-RT_ENOSYS);
+    return 0;
+}
+
+static rt_err_t lpc_emac_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+    switch (cmd)
+    {
+    case NIOCTL_GADDR:
+        /* get mac address */
+        if (args) rt_memcpy(args, lpc_emac_device.dev_addr, 6);
+        else return -RT_ERROR;
+        break;
+
+    default :
+        break;
+    }
+
+    return RT_EOK;
+}
+
+/* EtherNet Device Interface */
+/* transmit packet. */
+rt_err_t lpc_emac_tx(rt_device_t dev, struct pbuf *p)
+{
+    rt_uint32_t Index, IndexNext;
+    rt_uint8_t *ptr;
+
+    /* calculate next index */
+    IndexNext = LPC_EMAC->TxProduceIndex + 1;
+    if (IndexNext > LPC_EMAC->TxDescriptorNumber) IndexNext = 0;
+
+    /* check whether block is full */
+    while (IndexNext == LPC_EMAC->TxConsumeIndex)
+    {
+        rt_err_t result;
+        rt_uint32_t recved;
+
+        /* there is no block yet, wait a flag */
+        result = rt_event_recv(&tx_event, 0x01,
+                               RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recved);
+
+        RT_ASSERT(result == RT_EOK);
+    }
+
+    /* lock EMAC device */
+    rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+
+    /* get produce index */
+    Index = LPC_EMAC->TxProduceIndex;
+
+    /* calculate next index */
+    IndexNext = LPC_EMAC->TxProduceIndex + 1;
+    if (IndexNext > LPC_EMAC->TxDescriptorNumber)
+        IndexNext = 0;
+
+    /* copy data to tx buffer */
+    ptr = (rt_uint8_t *)TX_BUF(Index);
+    pbuf_copy_partial(p, ptr, p->tot_len, 0);
+
+    TX_DESC_CTRL(Index) &= ~0x7ff;
+    TX_DESC_CTRL(Index) |= (p->tot_len - 1) & 0x7ff;
+
+    /* change index to the next */
+    LPC_EMAC->TxProduceIndex = IndexNext;
+
+    /* unlock EMAC device */
+    rt_sem_release(&sem_lock);
+
+    return RT_EOK;
+}
+
+/* reception packet. */
+struct pbuf *lpc_emac_rx(rt_device_t dev)
+{
+    struct pbuf *p;
+    rt_uint32_t size;
+    rt_uint32_t Index;
+
+    /* init p pointer */
+    p = RT_NULL;
+
+    /* lock EMAC device */
+    rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+
+    Index = LPC_EMAC->RxConsumeIndex;
+    if (Index != LPC_EMAC->RxProduceIndex)
+    {
+        size = (RX_STAT_INFO(Index) & 0x7ff) + 1;
+        if (size > ETH_FRAG_SIZE) size = ETH_FRAG_SIZE;
+
+        /* allocate buffer */
+        p = pbuf_alloc(PBUF_LINK, size, PBUF_RAM);
+        if (p != RT_NULL)
+        {
+            pbuf_take(p, (rt_uint8_t *)RX_BUF(Index), size);
+        }
+
+        /* move Index to the next */
+        if (++Index > LPC_EMAC->RxDescriptorNumber)
+            Index = 0;
+
+        /* set consume index */
+        LPC_EMAC->RxConsumeIndex = Index;
+    }
+    else
+    {
+        /* Enable RxDone interrupt */
+        LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE;
+    }
+
+    /* unlock EMAC device */
+    rt_sem_release(&sem_lock);
+
+    return p;
+}
+
+int lpc_emac_hw_init(void)
+{
+    rt_event_init(&tx_event, "tx_event", RT_IPC_FLAG_FIFO);
+    rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
+
+    /* set autonegotiation mode */
+    lpc_emac_device.phy_mode = EMAC_PHY_AUTO;
+
+    // OUI 00-60-37 NXP Semiconductors
+    lpc_emac_device.dev_addr[0] = 0x00;
+    lpc_emac_device.dev_addr[1] = 0x60;
+    lpc_emac_device.dev_addr[2] = 0x37;
+    /* set mac address: (only for test) */
+    lpc_emac_device.dev_addr[3] = 0x12;
+    lpc_emac_device.dev_addr[4] = 0x34;
+    lpc_emac_device.dev_addr[5] = 0x56;
+
+    lpc_emac_device.parent.parent.init      = lpc_emac_init;
+    lpc_emac_device.parent.parent.open      = lpc_emac_open;
+    lpc_emac_device.parent.parent.close     = lpc_emac_close;
+    lpc_emac_device.parent.parent.read      = lpc_emac_read;
+    lpc_emac_device.parent.parent.write     = lpc_emac_write;
+    lpc_emac_device.parent.parent.control   = lpc_emac_control;
+    lpc_emac_device.parent.parent.user_data = RT_NULL;
+
+    lpc_emac_device.parent.eth_rx           = lpc_emac_rx;
+    lpc_emac_device.parent.eth_tx           = lpc_emac_tx;
+
+    eth_device_init(&(lpc_emac_device.parent), "e0");
+    return 0;
+}
+INIT_DEVICE_EXPORT(lpc_emac_hw_init);
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+void emac_dump()
+{
+    rt_kprintf("Command  : %08x\n", LPC_EMAC->Command);
+    rt_kprintf("Status   : %08x\n", LPC_EMAC->Status);
+    rt_kprintf("RxStatus : %08x\n", LPC_EMAC->RxStatus);
+    rt_kprintf("TxStatus : %08x\n", LPC_EMAC->TxStatus);
+    rt_kprintf("IntEnable: %08x\n", LPC_EMAC->IntEnable);
+    rt_kprintf("IntStatus: %08x\n", LPC_EMAC->IntStatus);
+}
+FINSH_FUNCTION_EXPORT(emac_dump, dump emac register);
+#endif
+

+ 291 - 0
bsp/lpc408x/drivers/drv_emac.h

@@ -0,0 +1,291 @@
+/*
+ * File      : drv_emac.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009-2013 RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-05-19     Bernard      porting from LPC17xx drivers.
+ */
+
+#ifndef __DRV_EMAC_H__
+#define __DRV_EMAC_H__
+
+#include "board.h"
+
+/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */
+#define NUM_RX_FRAG         4           /* Num.of RX Fragments 4*1536= 6.0kB */
+#define NUM_TX_FRAG         3           /* Num.of TX Fragments 3*1536= 4.6kB */
+#define ETH_FRAG_SIZE       1536        /* Packet Fragment size 1536 Bytes   */
+
+#define ETH_MAX_FLEN        1536        /* Max. Ethernet Frame Size          */
+
+
+/* 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       0x00000800  /* 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     */
+
+#define MCFG_CLK_DIV4       0x00000000  /* MDC = hclk / 4                    */
+#define MCFG_CLK_DIV6       0x00000008  /* MDC = hclk / 6                    */
+#define MCFG_CLK_DIV8       0x0000000C  /* MDC = hclk / 8                    */
+#define MCFG_CLK_DIV10      0x00000010  /* MDC = hclk / 10                   */
+#define MCFG_CLK_DIV14      0x00000014  /* MDC = hclk / 14                   */
+#define MCFG_CLK_DIV20      0x00000018  /* MDC = hclk / 20                   */
+#define MCFG_CLK_DIV28      0x0000001C  /* MDC = hclk / 28                   */
+
+
+/* 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    0x0F00      /* Default PHY device address        */
+#define DP83848C_ID         0x20005C90  /* PHY Identifier                    */
+
+int lpc_emac_hw_init(void);
+
+#endif

+ 17 - 16
bsp/lpc408x/drivers/drv_led.c

@@ -1,7 +1,7 @@
 #include <rtthread.h>
 #include "board.h"
 
-#define RT_DEVICE_CTRL_RTC_GET_COUNT     0x81        /**< get count                                   */
+#define LED_DEVICE_CTRL     0x81        /*LED control command*/
 
 #define LED_NUM    4
 struct led_ctrl
@@ -22,24 +22,24 @@ static struct lpc_led led;
 
 static rt_err_t rt_led_init(rt_device_t dev)
 {
-    /* led0 : P4.14,led1:P4.15 ,led2:P4.16 ,led3:P4.17*/
+    /* led0 : P4.27,led1:P4.15 ,led2:P4.16 ,led3:P4.17*/
     /* set P4.14,P4.15,P4.16,P4.17 as GPIO. */
-    LPC_IOCON->P4_14 = 0x00;
+    LPC_IOCON->P4_27 = 0x00;
     LPC_IOCON->P4_15 = 0x00;
     LPC_IOCON->P4_16 = 0x00;
     LPC_IOCON->P4_17 = 0x00;
-    /* set P4.14,P4.15,P4.16,P4.17  output. */
-    LPC_GPIO4->DIR |= (0x0f << 14);
+    /* set P4.27,P4.15,P4.16,P4.17  output. */
+    LPC_GPIO4->DIR |= (0x07 << 15) | (0x01 << 27);
     /* turn off all the led */
-    LPC_GPIO4->SET = (0x0f << 14);
-    led.ctrl[0].num = 14;
-    led.ctrl[0].port = LPC_GPIO4;
-    led.ctrl[1].num = 15;
-    led.ctrl[1].port = LPC_GPIO4;
-    led.ctrl[2].num = 16;
-    led.ctrl[2].port = LPC_GPIO4;
-    led.ctrl[3].num = 17;
+    LPC_GPIO4->SET = (0x07 << 15) | (0x01 << 27);
+    led.ctrl[3].num = 27;
     led.ctrl[3].port = LPC_GPIO4;
+    led.ctrl[2].num = 15;
+    led.ctrl[2].port = LPC_GPIO4;
+    led.ctrl[1].num = 16;
+    led.ctrl[1].port = LPC_GPIO4;
+    led.ctrl[0].num = 17;
+    led.ctrl[0].port = LPC_GPIO4;
     return RT_EOK;
 }
 
@@ -106,7 +106,7 @@ static rt_err_t rt_led_control(rt_device_t dev, rt_uint8_t cmd, void *args)
 {
     RT_ASSERT(dev == &led.parent);
 
-    if (cmd == RT_DEVICE_CTRL_RTC_GET_COUNT)
+    if (cmd == LED_DEVICE_CTRL)
     {
         rt_uint32_t *led_num = args;
         *led_num = LED_NUM;
@@ -114,7 +114,7 @@ static rt_err_t rt_led_control(rt_device_t dev, rt_uint8_t cmd, void *args)
     return RT_EOK;
 }
 
-void rt_led_hw_init(void)
+int rt_led_hw_init(void)
 {
     led.parent.type         = RT_Device_Class_Char;
     led.parent.rx_indicate  = RT_NULL;
@@ -131,8 +131,9 @@ void rt_led_hw_init(void)
     rt_device_register(&led.parent, "led", RT_DEVICE_FLAG_RDWR);
     /* init led device */
     rt_led_init(&led.parent);
+    return 0;
 }
-
+INIT_DEVICE_EXPORT(rt_led_hw_init);
 #ifdef RT_USING_FINSH
 #include <finsh.h>
 void led_test(rt_uint32_t led_num, rt_uint32_t value)

+ 153 - 0
bsp/lpc408x/drivers/drv_sdram.c

@@ -0,0 +1,153 @@
+/*
+ * File      : drv_sdram.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009-2013 RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-05-19     Bernard      The first version for LPC40xx
+ */
+
+#include "drv_sdram.h"
+
+#include <lpc_emc.h>
+#include <lpc_timer.h>
+
+#define SDRAM_BASE_ADDR     0xA0000000
+#define SDRAM_SIZE          0x2000000
+
+/*******************************************************************************************
+* @函数名:sdram_gpio_config()
+* @参数  :void
+* @返回值:void
+* @描述  :SDRAM管脚配置函数,内部调用
+*********************************************************************************************/
+static void  sdram_gpio_config(void)
+{
+    LPC_IOCON->P3_0 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D0 @ P3.0 */
+    LPC_IOCON->P3_1 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D1 @ P3.1 */
+    LPC_IOCON->P3_2 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D2 @ P3.2 */
+    LPC_IOCON->P3_3 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D3 @ P3.3 */
+
+    LPC_IOCON->P3_4 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D4 @ P3.4 */
+    LPC_IOCON->P3_5 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D5 @ P3.5 */
+    LPC_IOCON->P3_6 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D6 @ P3.6 */
+    LPC_IOCON->P3_7 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D7 @ P3.7 */
+
+    LPC_IOCON->P3_8 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D8 @ P3.8 */
+    LPC_IOCON->P3_9 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D9 @ P3.9 */
+    LPC_IOCON->P3_10 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D10 @ P3.10 */
+    LPC_IOCON->P3_11 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D11 @ P3.11 */
+
+    LPC_IOCON->P3_12 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D12 @ P3.12 */
+    LPC_IOCON->P3_13 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D13 @ P3.13 */
+    LPC_IOCON->P3_14 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D14 @ P3.14 */
+    LPC_IOCON->P3_15 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D15 @ P3.15 */
+
+
+    LPC_IOCON->P4_0 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A0 @ P4.0 */
+    LPC_IOCON->P4_1 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A1 @ P4.1 */
+    LPC_IOCON->P4_2 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A2 @ P4.2 */
+    LPC_IOCON->P4_3 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A3 @ P4.3 */
+
+    LPC_IOCON->P4_4 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A4 @ P4.4 */
+    LPC_IOCON->P4_5 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A5 @ P4.5 */
+    LPC_IOCON->P4_6 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A6 @ P4.6 */
+    LPC_IOCON->P4_7 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A7 @ P4.7 */
+
+    LPC_IOCON->P4_8 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A8 @ P4.8 */
+    LPC_IOCON->P4_9 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A9 @ P4.9 */
+    LPC_IOCON->P4_10 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A10 @ P4.10 */
+    LPC_IOCON->P4_11 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A11 @ P4.11 */
+
+    LPC_IOCON->P4_12 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A12 @ P4.12 */
+    LPC_IOCON->P4_13 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A13 @ P4.13 */
+    LPC_IOCON->P4_14 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A14 @ P4.14 */
+
+    LPC_IOCON->P4_25 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* WEN @ P4.25 */
+
+    LPC_IOCON->P2_16 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CASN @ P2.16 */
+    LPC_IOCON->P2_17 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* RASN @ P2.17 */
+    LPC_IOCON->P2_18 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CLK[0] @ P2.18 */
+    LPC_IOCON->P2_19 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CLK[1] @ P2.19 */
+
+    LPC_IOCON->P2_20 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* DYCSN[0] @ P2.20 */
+    LPC_IOCON->P2_24 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CKE[0] @ P2.24 */
+
+    LPC_IOCON->P2_28 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* DQM[0] @ P2.28 */
+    LPC_IOCON->P2_29 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* DQM[1] @ P2.29 */
+}
+
+void lpc_sdram_hw_init(void)
+{
+    volatile uint32_t i;
+    volatile uint32_t dwtemp;
+    uint16_t wtemp = wtemp;
+    TIM_TIMERCFG_Type TIM_ConfigStruct;
+
+    TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
+    TIM_ConfigStruct.PrescaleValue  = 1;
+
+    // Set configuration for Tim_config and Tim_MatchConfig
+    TIM_Init(LPC_TIM0, TIM_TIMER_MODE, &TIM_ConfigStruct);
+
+    LPC_SC->PCONP      |= 0x00000800;
+    LPC_SC->EMCDLYCTL   = 0x00001010;
+    LPC_EMC->Control = 0x00000001;
+    LPC_EMC->Config  = 0x00000000;
+
+    sdram_gpio_config();
+    //LPC_SC->EMCCLKSEL = 1;           //跑主频的一般频率,60Mhz
+    LPC_EMC->DynamicRP         = EMC_NS2CLK(20); /* 20ns,  */
+    LPC_EMC->DynamicRAS        = /*EMC_NS2CLK(42, nsPerClk);*/ 15; /* 42ns to 100K ns,  */
+    LPC_EMC->DynamicSREX       = 1 - 1; /* tSRE, 1clk, */
+    LPC_EMC->DynamicAPR        = 2 - 1; /* Not found!!! Estimated as 2clk, */
+    LPC_EMC->DynamicDAL        = EMC_NS2CLK(20) + 2; /* tDAL = tRP + tDPL = 20ns + 2clk  */
+    LPC_EMC->DynamicWR         = 2 - 1; /* 2CLK,  */
+    LPC_EMC->DynamicRC         = EMC_NS2CLK(63); /* H57V2562GTR-75C tRC=63ns(min)*/
+    LPC_EMC->DynamicRFC        = EMC_NS2CLK(63); /* H57V2562GTR-75C tRFC=tRC */
+    LPC_EMC->DynamicXSR        = 0x0000000F; /* exit self-refresh to active, 不知道,设为最久  */
+    LPC_EMC->DynamicRRD        = EMC_NS2CLK(63); /* 3clk, tRRD=15ns(min) */
+    LPC_EMC->DynamicMRD        = 2 - 1; /* 2clk, tMRD=2clk(min) */
+
+    LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */
+    /* H57V2562GTR-75C: tCL=3CLK, tRCD=20ns(min), 3 CLK=24ns */
+    LPC_EMC->DynamicRasCas0    = 0x303;
+
+    /* For Manley lpc1778 SDRAM: H57V2562GTR-75C, 256Mb, 16Mx16, 4 banks, row=13, column=9 */
+#ifdef SDRAM_CONFIG_16BIT
+    LPC_EMC->DynamicConfig0    = 0x680; /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
+#elif defined SDRAM_CONFIG_32BIT
+    LPC_EMC->DynamicConfig0 = 0x4680; /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
+#endif
+    TIM_Waitms(100);
+
+    LPC_EMC->DynamicControl    = 0x00000183; /* Issue NOP command */
+    TIM_Waitms(200);                            /* wait 200ms */
+
+    LPC_EMC->DynamicControl    = 0x00000103; /* Issue PALL command */
+
+    LPC_EMC->DynamicRefresh    = 0x00000002; /* ( n * 16 ) -> 32 clock cycles */
+    for (i = 0; i < 0x80; i++);               /* wait 128 AHB clock cycles */
+
+    LPC_EMC->DynamicRefresh    = EMC_SDRAM_REFRESH(64);
+
+    LPC_EMC->DynamicControl    = 0x00000083; /* Issue MODE command */
+
+#ifdef SDRAM_CONFIG_16BIT
+    wtemp = *((volatile uint16_t *)(SDRAM_BASE | (0x33 << 12))); /* 8 burst, 3 CAS latency */
+#elif defined SDRAM_CONFIG_32BIT
+    dwtemp = *((volatile uint32_t *)(SDRAM_BASE | (0x32 << 13))); /* 4 burst, 3 CAS latency */
+#endif
+
+    LPC_EMC->DynamicControl    = 0x00000000; /* Issue NORMAL command */
+
+    LPC_EMC->DynamicConfig0 |= 0x80000; /* enable buffer */
+    TIM_Waitms(1);
+
+    TIM_DeInit(LPC_TIM0);
+}

+ 35 - 0
bsp/lpc408x/drivers/drv_sdram.h

@@ -0,0 +1,35 @@
+/*
+ * File      : drv_sdram.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009-2013 RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-05-19     Bernard      The first version for LPC40xx
+ */
+
+#ifndef __DRV_SDRAM_H__
+#define __DRV_SDRAM_H__
+
+#include <board.h>
+
+#define SDRAM_CONFIG_16BIT     //use the 16 bitSDRAM
+//#define SDRAM_CONFIG_32BIT    //use the 32 bitSDRAM
+
+#ifdef SDRAM_CONFIG_16BIT
+#define SDRAM_SIZE               0x2000000  // 256Mbit
+#elif defined SDRAM_CONFIG_32BIT     //
+#define SDRAM_SIZE               0x4000000  // 512Mbit
+#else
+error Wrong SDRAM config, check ex_sdram.h
+#endif
+
+#define SDRAM_BASE               0xA0000000    /* CS0 */
+
+void lpc_sdram_hw_init(void);
+
+#endif

+ 172 - 104
bsp/lpc408x/drivers/drv_uart.c

@@ -17,20 +17,17 @@
 #include <rtdevice.h>
 
 #include "board.h"
-#include "lpc_uart.h"
-#include "lpc_pinsel.h"
 
 struct lpc_uart
 {
-    UART_ID_Type UART;
+    LPC_UART_TypeDef *UART;
     IRQn_Type UART_IRQn;
 };
 
 static rt_err_t lpc_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
 {
     struct lpc_uart *uart;
-    UART_CFG_Type UARTConfigStruct;
-    UART_FIFO_CFG_Type UARTFIFOConfigStruct;
+    uint32_t Fdiv = 0;
 
     RT_ASSERT(serial != RT_NULL);
     uart = (struct lpc_uart *)serial->parent.user_data;
@@ -41,25 +38,20 @@ static rt_err_t lpc_configure(struct rt_serial_device *serial, struct serial_con
      * 1 Stop bit
      * None parity
      */
-    UART_ConfigStructInit(&UARTConfigStruct);
-    UARTConfigStruct.Baud_rate = 115200;
-
-    // Initialize UART0 peripheral with given to corresponding parameter
-    UART_Init(uart->UART, &UARTConfigStruct);
-
-    /* Initialize FIFOConfigStruct to default state:
-     *              - FIFO_DMAMode = DISABLE
-     *              - FIFO_Level = UART_FIFO_TRGLEV0
-     *              - FIFO_ResetRxBuf = ENABLE
-     *              - FIFO_ResetTxBuf = ENABLE
-     *              - FIFO_State = ENABLE
-     */
-    UART_FIFOConfigStructInit(&UARTFIFOConfigStruct);
+    /* set DLAB=1 */
+    uart->UART->LCR |= 0x80;
+    /* config uart baudrate */
+    Fdiv = (PeripheralClock / 16) / cfg->baud_rate;
+    uart->UART->DLM = Fdiv / 256;
+    uart->UART->DLL = Fdiv % 256;
+    /* set DLAB=0 */
+    uart->UART->LCR &= ~0x80;
+    /* config to 8 data bit,1 Stop bit,None parity */
+    uart->UART->LCR |= 0x03;
 
-    // Initialize FIFO for UART0 peripheral
-    UART_FIFOConfig(uart->UART, &UARTFIFOConfigStruct);
+    /*enable and reset FIFO*/
+    uart->UART->FCR = 0x07;
 
-    UART_TxCmd(uart->UART, ENABLE);
 
     return RT_EOK;
 }
@@ -75,11 +67,11 @@ static rt_err_t lpc_control(struct rt_serial_device *serial, int cmd, void *arg)
     {
     case RT_DEVICE_CTRL_CLR_INT:
         /* disable rx irq */
-        UART_IntConfig(uart->UART, UART_INTCFG_RBR, DISABLE);
+        uart->UART->IER &= ~0x01;
         break;
     case RT_DEVICE_CTRL_SET_INT:
         /* enable rx irq */
-        UART_IntConfig(uart->UART, UART_INTCFG_RBR, ENABLE);
+        uart->UART->IER |= 0x01;
         break;
     }
 
@@ -91,21 +83,21 @@ static int lpc_putc(struct rt_serial_device *serial, char c)
     struct lpc_uart *uart;
 
     uart = (struct lpc_uart *)serial->parent.user_data;
-    UART_Send(uart->UART, (uint8_t *)&c, 1, BLOCKING);
+    while (!(uart->UART->LSR & 0x20));
+    uart->UART->THR = c;
 
     return 1;
 }
 
 static int lpc_getc(struct rt_serial_device *serial)
 {
-    uint8_t ch;
     struct lpc_uart *uart;
 
     uart = (struct lpc_uart *)serial->parent.user_data;
-    if (UART_Receive(uart->UART, &ch, 1, NONE_BLOCKING) == 1)
-        return (int) ch;
-
-    return -1;
+    if (uart->UART->LSR & 0x01)
+        return (uart->UART->RBR);
+    else
+        return -1;
 }
 
 static const struct rt_uart_ops lpc_uart_ops =
@@ -116,127 +108,167 @@ static const struct rt_uart_ops lpc_uart_ops =
     lpc_getc,
 };
 
-#if defined(RT_USING_UART0)
+#ifdef RT_USING_UART0
 /* UART0 device driver structure */
+#if RTTHREAD_VERSION < 20000 /* RT-Thread 1.x */
+struct serial_ringbuffer uart0_int_rx;
+#endif
+
 struct lpc_uart uart0 =
 {
-    UART_0,
+    LPC_UART0,
     UART0_IRQn,
 };
 struct rt_serial_device serial0;
 
 void UART0_IRQHandler(void)
 {
-    struct lpc_uart *uart;
-    uint32_t intsrc, tmp, tmp1;
-
-    uart = &uart0;
+    volatile  uint32_t IIR, tmp;
 
     /* enter interrupt */
     rt_interrupt_enter();
 
-    /* Determine the interrupt source */
-    intsrc = UART_GetIntId(uart->UART);
-    tmp = intsrc & UART_IIR_INTID_MASK;
-
-    // Receive Line Status
-    if (tmp == UART_IIR_INTID_RLS)
+    IIR = LPC_UART0->IIR;
+    IIR &= 0x0e;
+    switch (IIR)
     {
-        // Check line status
-        tmp1 = UART_GetLineStatus(uart->UART);
-        // Mask out the Receive Ready and Transmit Holding empty status
-        tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \
-                 | UART_LSR_BI | UART_LSR_RXFE);
-        // If any error exist
-        if (tmp1)
-        {
-            //
-        }
-    }
 
-    // Receive Data Available or Character time-out
-    if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI))
-    {
+    case 0x04:
+    case 0x0C:
+    #if RTTHREAD_VERSION < 20000
+        rt_hw_serial_isr(&serial0);
+    #else
         rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND);
+    #endif
+        break;
+    case 0x06:
+        tmp = LPC_UART0->LSR;
+        break;
+    default :
+        tmp = LPC_UART0->LSR;
+        break;
     }
-
     /* leave interrupt */
     rt_interrupt_leave();
 }
 #endif
-#if defined(RT_USING_UART2)
+#ifdef RT_USING_UART2
 /* UART2 device driver structure */
+#if RTTHREAD_VERSION < 20000 /* RT-Thread 1.x */
+struct serial_ringbuffer uart2_int_rx;
+#endif
+
 struct lpc_uart uart2 =
 {
-    UART_2,
+    LPC_UART2,
     UART2_IRQn,
 };
 struct rt_serial_device serial2;
 
 void UART2_IRQHandler(void)
 {
-    struct lpc_uart *uart;
-    uint32_t intsrc, tmp, tmp1;
-
-    uart = &uart2;
+    volatile  uint32_t IIR, tmp;
 
     /* enter interrupt */
     rt_interrupt_enter();
 
-    /* Determine the interrupt source */
-    intsrc = UART_GetIntId(uart->UART);
-    tmp = intsrc & UART_IIR_INTID_MASK;
-
-    // Receive Line Status
-    if (tmp == UART_IIR_INTID_RLS)
+    IIR = LPC_UART2->IIR;
+    IIR &= 0x0e;
+    switch (IIR)
     {
-        // Check line status
-        tmp1 = UART_GetLineStatus(uart->UART);
-        // Mask out the Receive Ready and Transmit Holding empty status
-        tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \
-                 | UART_LSR_BI | UART_LSR_RXFE);
-        // If any error exist
-        if (tmp1)
-        {
-            //
-        }
+    case 0x04:
+    case 0x0C:
+    #if RTTHREAD_VERSION < 20000
+        rt_hw_serial_isr(&serial2);
+    #else
+        rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND);
+    #endif
+        break;
+    case 0x06:
+        tmp = LPC_UART2->LSR;
+        break;
+    default :
+        tmp = LPC_UART2->LSR;
+        break;
     }
 
-    // Receive Data Available or Character time-out
-    if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI))
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+#endif
+
+#ifdef RT_USING_UART4
+/* UART4 device driver structure */
+#if RTTHREAD_VERSION < 20000 /* RT-Thread 1.x */
+struct serial_ringbuffer uart4_int_rx;
+#endif
+
+struct lpc_uart uart4 =
+{
+    LPC_UART4,
+    UART4_IRQn,
+};
+struct rt_serial_device serial4;
+
+void UART4_IRQHandler(void)
+{
+    volatile  uint32_t IIR, tmp;
+
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    IIR = LPC_UART4->IIR;
+    IIR &= 0x0e;
+    switch (IIR)
     {
-        rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND);
+    case 0x04:
+    case 0x0C:
+    #if RTTHREAD_VERSION < 20000
+        rt_hw_serial_isr(&serial4);
+    #else
+        rt_hw_serial_isr(&serial4, RT_SERIAL_EVENT_RX_IND);
+    #endif
+        break;
+    case 0x06:
+        tmp = LPC_UART4->LSR;
+        break;
+    default :
+        tmp = LPC_UART4->LSR;
+        break;
     }
 
     /* leave interrupt */
     rt_interrupt_leave();
 }
 #endif
+
 void rt_hw_uart_init(void)
 {
     struct lpc_uart *uart;
-    struct serial_configure config;
+    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
 
 #ifdef RT_USING_UART0
     uart = &uart0;
-    config.baud_rate = BAUD_RATE_115200;
-    config.bit_order = BIT_ORDER_LSB;
-    config.data_bits = DATA_BITS_8;
-    config.parity    = PARITY_NONE;
-    config.stop_bits = STOP_BITS_1;
-    config.invert    = NRZ_NORMAL;
-	config.bufsz     = RT_SERIAL_RB_BUFSZ;
 
     serial0.ops    = &lpc_uart_ops;
     serial0.config = config;
-
+    #if RTTHREAD_VERSION < 20000
+    serial0.int_rx = &uart0_int_rx;
+    #endif
+    serial0.parent.user_data = uart;
+    
     /*
      * Initialize UART0 pin connect
      * P0.2: U0_TXD
      * P0.3: U0_RXD
      */
-    PINSEL_ConfigPin(0, 2, 1);
-    PINSEL_ConfigPin(0, 3, 1);
+    LPC_IOCON->P0_2 &= ~0x07;
+    LPC_IOCON->P0_2 |= 0x01;
+    LPC_IOCON->P0_3 &= ~0x07;
+    LPC_IOCON->P0_3 |= 0x01;
+
+    /* enable the uart0 power and clock */
+    LPC_SC->PCONP |= 0x01 << 3;
 
     /* preemption = 1, sub-priority = 1 */
     NVIC_SetPriority(uart->UART_IRQn, ((0x01 << 3) | 0x01));
@@ -244,41 +276,77 @@ void rt_hw_uart_init(void)
     /* Enable Interrupt for UART channel */
     NVIC_EnableIRQ(uart->UART_IRQn);
 
-    /* register UART1 device */
+    /* register UART0 device */
     rt_hw_serial_register(&serial0, "uart0",
                           RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
                           uart);
 #endif
+
 #ifdef RT_USING_UART2
     uart = &uart2;
-    config.baud_rate = BAUD_RATE_115200;
-    config.bit_order = BIT_ORDER_LSB;
-    config.data_bits = DATA_BITS_8;
-    config.parity    = PARITY_NONE;
-    config.stop_bits = STOP_BITS_1;
-    config.invert    = NRZ_NORMAL;
-	config.bufsz     = RT_SERIAL_RB_BUFSZ;
 
     serial2.ops    = &lpc_uart_ops;
     serial2.config = config;
+    #if RTTHREAD_VERSION < 20000
+    serial2.int_rx = &uart2_int_rx;
+    #endif
+    serial2.parent.user_data = uart;
 
     /*
      * Initialize UART2 pin connect
      * P2.8: U2_TXD
      * P0.11: U2_RXD
      */
-    PINSEL_ConfigPin(2, 8, 2);
-    PINSEL_ConfigPin(0, 11, 1);
+    LPC_IOCON->P2_8 &= ~0x07;
+    LPC_IOCON->P0_11 &= ~0x07;
+    LPC_IOCON->P2_8 |= 0x02;
+    LPC_IOCON->P0_11 |= 0x01;
 
+    /* enable the uart2 power and clock */
+    LPC_SC->PCONP |= 0x01 << 24;
     /* preemption = 1, sub-priority = 1 */
     NVIC_SetPriority(uart->UART_IRQn, ((0x01 << 3) | 0x01));
 
     /* Enable Interrupt for UART channel */
     NVIC_EnableIRQ(uart->UART_IRQn);
 
-    /* register UART1 device */
+    /* register UART2 device */
     rt_hw_serial_register(&serial2, "uart2",
                           RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
                           uart);
 #endif
+
+#ifdef RT_USING_UART4
+    uart = &uart4;
+
+    serial4.ops    = &lpc_uart_ops;
+    serial4.config = config;
+    #if RTTHREAD_VERSION < 20000
+    serial4.int_rx = &uart4_int_rx;
+    #endif
+    serial4.parent.user_data = uart;
+    
+    /*
+     * Initialize UART2 pin connect
+     * P5.4: U2_TXD
+     * P5.3: U2_RXD
+     */
+    LPC_IOCON->P5_4 &= ~0x07;
+    LPC_IOCON->P5_3 &= ~0x07;
+    LPC_IOCON->P5_4 |= 0x04;
+    LPC_IOCON->P5_3 |= 0x04;
+
+    /* enable the uart4 power and clock */
+    LPC_SC->PCONP |= 0x01 << 8;
+    /* preemption = 1, sub-priority = 1 */
+    NVIC_SetPriority(uart->UART_IRQn, ((0x01 << 3) | 0x01));
+
+    /* Enable Interrupt for UART channel */
+    NVIC_EnableIRQ(uart->UART_IRQn);
+
+    /* register UART2 device */
+    rt_hw_serial_register(&serial4, "uart4",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
+                          uart);
+#endif
 }

+ 14 - 0
bsp/lpc408x/drivers/drv_uart.h

@@ -1,3 +1,17 @@
+/*
+ * File      : drv_uart.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009-2014 RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2014-01-05     NongXiaoming      The first version for LPC40xx
+ */
+
 #ifndef __UART_H__
 #define __UART_H__
 

+ 1 - 1
bsp/lpc408x/rtconfig.h

@@ -165,7 +165,7 @@
 // <bool name="RT_LWIP_SNMP" description="Enable SNMP protocol" default="false" />
 // #define RT_LWIP_SNMP
 // <bool name="RT_LWIP_DHCP" description="Enable DHCP client to get IP address" default="false" />
-// #define RT_LWIP_DHCP
+#define RT_LWIP_DHCP
 // <integer name="RT_LWIP_TCPTHREAD_PRIORITY" description="the thread priority of TCP thread" default="128" />
 #define RT_LWIP_TCPTHREAD_PRIORITY	12
 // <integer name="RT_LWIP_TCPTHREAD_MBOX_SIZE" description="the mail box size of TCP thread to wait for" default="32" />

+ 164 - 0
bsp/lpc408x/template.uvopt

@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_opt.xsd">
+
+  <SchemaVersion>1.0</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Extensions>
+    <cExt>*.c</cExt>
+    <aExt>*.s*; *.src; *.a*</aExt>
+    <oExt>*.obj</oExt>
+    <lExt>*.lib</lExt>
+    <tExt>*.txt; *.h; *.inc</tExt>
+    <pExt>*.plm</pExt>
+    <CppX>*.cpp</CppX>
+  </Extensions>
+
+  <DaveTm>
+    <dwLowDateTime>0</dwLowDateTime>
+    <dwHighDateTime>0</dwHighDateTime>
+  </DaveTm>
+
+  <Target>
+    <TargetName>RT-Thread LPC408x</TargetName>
+    <ToolsetNumber>0x4</ToolsetNumber>
+    <ToolsetName>ARM-ADS</ToolsetName>
+    <TargetOption>
+      <CLKADS>12000000</CLKADS>
+      <OPTTT>
+        <gFlags>1</gFlags>
+        <BeepAtEnd>1</BeepAtEnd>
+        <RunSim>1</RunSim>
+        <RunTarget>0</RunTarget>
+      </OPTTT>
+      <OPTHX>
+        <HexSelection>1</HexSelection>
+        <FlashByte>65535</FlashByte>
+        <HexRangeLowAddress>0</HexRangeLowAddress>
+        <HexRangeHighAddress>0</HexRangeHighAddress>
+        <HexOffset>0</HexOffset>
+      </OPTHX>
+      <OPTLEX>
+        <PageWidth>79</PageWidth>
+        <PageLength>66</PageLength>
+        <TabStop>8</TabStop>
+        <ListingPath>.\build\</ListingPath>
+      </OPTLEX>
+      <ListingPage>
+        <CreateCListing>1</CreateCListing>
+        <CreateAListing>1</CreateAListing>
+        <CreateLListing>1</CreateLListing>
+        <CreateIListing>0</CreateIListing>
+        <AsmCond>1</AsmCond>
+        <AsmSymb>1</AsmSymb>
+        <AsmXref>0</AsmXref>
+        <CCond>1</CCond>
+        <CCode>0</CCode>
+        <CListInc>0</CListInc>
+        <CSymb>0</CSymb>
+        <LinkerCodeListing>0</LinkerCodeListing>
+      </ListingPage>
+      <OPTXL>
+        <LMap>1</LMap>
+        <LComments>1</LComments>
+        <LGenerateSymbols>1</LGenerateSymbols>
+        <LLibSym>1</LLibSym>
+        <LLines>1</LLines>
+        <LLocSym>1</LLocSym>
+        <LPubSym>1</LPubSym>
+        <LXref>0</LXref>
+        <LExpSel>0</LExpSel>
+      </OPTXL>
+      <OPTFL>
+        <tvExp>0</tvExp>
+        <tvExpOptDlg>0</tvExpOptDlg>
+        <IsCurrentTarget>1</IsCurrentTarget>
+      </OPTFL>
+      <CpuCode>0</CpuCode>
+      <DllOpt>
+        <SimDllName>SARMCM3.DLL</SimDllName>
+        <SimDllArguments>-MPU</SimDllArguments>
+        <SimDlgDllName>DCM.DLL</SimDlgDllName>
+        <SimDlgDllArguments>-pCM4</SimDlgDllArguments>
+        <TargetDllName>SARMCM3.DLL</TargetDllName>
+        <TargetDllArguments>-MPU</TargetDllArguments>
+        <TargetDlgDllName>TCM.DLL</TargetDlgDllName>
+        <TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
+      </DllOpt>
+      <DebugOpt>
+        <uSim>0</uSim>
+        <uTrg>1</uTrg>
+        <sLdApp>1</sLdApp>
+        <sGomain>1</sGomain>
+        <sRbreak>1</sRbreak>
+        <sRwatch>1</sRwatch>
+        <sRmem>1</sRmem>
+        <sRfunc>1</sRfunc>
+        <sRbox>1</sRbox>
+        <tLdApp>1</tLdApp>
+        <tGomain>0</tGomain>
+        <tRbreak>1</tRbreak>
+        <tRwatch>1</tRwatch>
+        <tRmem>1</tRmem>
+        <tRfunc>0</tRfunc>
+        <tRbox>1</tRbox>
+        <tRtrace>0</tRtrace>
+        <sRunDeb>0</sRunDeb>
+        <sLrtime>0</sLrtime>
+        <nTsel>7</nTsel>
+        <sDll></sDll>
+        <sDllPa></sDllPa>
+        <sDlgDll></sDlgDll>
+        <sDlgPa></sDlgPa>
+        <sIfile></sIfile>
+        <tDll></tDll>
+        <tDllPa></tDllPa>
+        <tDlgDll></tDlgDll>
+        <tDlgPa></tDlgPa>
+        <tIfile></tIfile>
+        <pMon>Segger\JL2CM3.dll</pMon>
+      </DebugOpt>
+      <TargetDriverDllRegistry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>JL2CM3</Key>
+          <Name>-U4294967295 -O78 -S0 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO11 -FD10000000 -FC800 -FN1 -FF0LPC_IAP_512 -FS00 -FL080000</Name>
+        </SetRegEntry>
+      </TargetDriverDllRegistry>
+      <Breakpoint/>
+      <Tracepoint>
+        <THDelay>0</THDelay>
+      </Tracepoint>
+      <DebugFlag>
+        <trace>0</trace>
+        <periodic>0</periodic>
+        <aLwin>0</aLwin>
+        <aCover>0</aCover>
+        <aSer1>0</aSer1>
+        <aSer2>0</aSer2>
+        <aPa>0</aPa>
+        <viewmode>0</viewmode>
+        <vrSel>0</vrSel>
+        <aSym>0</aSym>
+        <aTbox>0</aTbox>
+        <AscS1>0</AscS1>
+        <AscS2>0</AscS2>
+        <AscS3>0</AscS3>
+        <aSer3>0</aSer3>
+        <eProf>0</eProf>
+        <aLa>0</aLa>
+        <aPa1>0</aPa1>
+        <AscS4>0</AscS4>
+        <aSer4>0</aSer4>
+        <StkLoc>0</StkLoc>
+        <TrcWin>0</TrcWin>
+        <newCpu>0</newCpu>
+        <uProt>0</uProt>
+      </DebugFlag>
+      <LintExecutable></LintExecutable>
+      <LintConfigFile></LintConfigFile>
+    </TargetOption>
+  </Target>
+
+</ProjectOpt>