Browse Source

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1290 bbd45198-f89e-11dd-88c7-29a3b14d5316

dennis.zhang.os@gmail.com 14 years ago
parent
commit
9236274689

+ 127 - 0
bsp/mini4020/application.c

@@ -0,0 +1,127 @@
+/*
+ * File      : application.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development 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
+ * 2007-11-20     Yi.Qiu		add rtgui application
+ * 2008-6-28      Bernard		no rtgui init
+ */
+
+/**
+ * @addtogroup mini2440
+ */
+/*@{*/
+
+#include <board.h>
+#include <rtthread.h>
+
+#ifdef RT_USING_DFS
+#include <dfs_init.h>
+#include <dfs_elm.h>
+#include <dfs_fs.h>
+#include <dfs_posix.h>
+#endif
+#ifdef RT_USING_RTGUI
+#include <rtgui/rtgui.h>
+extern void radio_rtgui_init(void);
+#endif
+#define RT_INIT_THREAD_STACK_SIZE (2*1024)
+
+void rt_init_thread_entry(void* parameter)
+{
+	int fd;
+	rt_uint32_t sz;
+	char buffer[20];
+#ifdef RT_USING_DFS
+	dfs_init();
+#ifdef RT_USING_DFS_ELMFATFS
+	elm_init();
+	/* mount sd card fat partition 1 as root directory */
+	if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)
+	{
+		rt_kprintf("File System initialized!\n");
+
+		/*Open a file*/
+		fd = open("/fattest.txt", O_RDWR|O_CREAT, 0);
+		if (fd < 0)
+		{
+			rt_kprintf("open file for write failed\n");
+			return;
+		}
+
+		sz = write(fd,"Hello RT-Thread!",sizeof("Hello RT-Thread!"));
+
+		if(sz!=0)
+		{
+			rt_kprintf("written %d\n",sz);
+		}
+		else
+			rt_kprintf("haven't written\n");
+
+		lseek(fd,0,SEEK_SET);
+		
+		sz = read(fd,buffer,sizeof(buffer));
+
+		if(sz!=0)
+		{
+			rt_kprintf("READ %d:",sz);
+			while(sz--)
+				rt_kprintf("%c",buffer[sz]);//opposite
+			rt_kprintf("\n");
+		}
+		else
+			rt_kprintf("haven't read\n");
+
+		close(fd);
+	}
+	else
+		rt_kprintf("File System initialzation failed!\n");
+#endif	
+#endif
+}
+
+void rt_led_thread_entry(void* parameter)
+{
+ /*
+    while (1)
+    {
+        count++;
+        *(RP)GPIO_PORTE_DATA |= 0x1<<4;
+        rt_thread_delay(RT_TICK_PER_SECOND*2);
+
+        *(RP)GPIO_PORTE_DATA &= ~(0x1<<4);
+        rt_thread_delay(RT_TICK_PER_SECOND*2);
+
+    }
+*/
+}
+
+
+int rt_application_init()
+{
+	rt_thread_t init_thread;
+	rt_thread_t led_thread;
+
+
+	init_thread = rt_thread_create("init",
+								rt_init_thread_entry, RT_NULL,
+								RT_INIT_THREAD_STACK_SIZE, 8, 20);
+	led_thread = rt_thread_create("led",
+								rt_led_thread_entry, RT_NULL,
+								512, 200, 20);
+
+	if (init_thread != RT_NULL)
+		rt_thread_startup(init_thread);
+
+	if (led_thread != RT_NULL)
+		rt_thread_startup(led_thread);
+	return 0;
+}
+
+/*@}*/

+ 163 - 0
bsp/mini4020/board.c

@@ -0,0 +1,163 @@
+/*
+ * File      : board.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009 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://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-05-16     Bernard      first implementation
+ * 2010-10-5      Wangmeng     sep4020 implementation
+ */
+#include <rthw.h>
+#include <rtthread.h>
+
+#include <sep4020.h>
+#include <serial.h>
+
+void rt_hw_serial_putc(const char c);
+
+#define UART0	((struct uartport *)UART0_BASE)
+struct rt_device uart0_device;
+struct serial_int_rx uart0_int_rx;
+struct serial_device uart0 =
+{
+	UART0,
+	&uart0_int_rx,
+	RT_NULL
+};
+
+
+/**
+ * This function will handle rtos timer
+ */
+void rt_timer_handler(int vector)
+{
+	rt_uint32_t clear_int;
+	rt_tick_increase();
+
+	/*Clear timer interrupt*/
+	clear_int = *(RP)TIMER_T1ISCR; 
+    *(RP)TIMER_T1ISCR=clear_int;
+}
+
+/**
+ * This function will handle serial
+ */
+void rt_serial_handler(int vector)
+{
+	//rt_kprintf("in rt_serial_handler\n");
+    rt_int32_t stat = *(RP)UART0_IIR ;
+	UNUSED char c;
+
+	/*Received data*/
+	if(((stat & 0x0E) >> 1) == 0x02)
+	{
+	  
+	  rt_hw_serial_isr(&uart0_device);
+			
+	}
+	else
+	{
+		/*clear the timeout interrupt*/
+		while (uart0.uart_device->lsr & USTAT_RCV_READY)
+			c = uart0.uart_device->dlbl_fifo.rxfifo;	
+	}
+}
+/** 
+ * This function will init led on the board
+ */
+static void rt_hw_board_led_init(void)
+{
+  /* PE3 PE4 PE5 for led */
+  *(RP)GPIO_PORTE_SEL |=0x38; /* GPIO */
+  
+  *(RP)GPIO_PORTE_DIR &= ~0x38; /* output*/
+
+  *(RP)GPIO_PORTE_DATA &= ~0x38;  /* low */
+}
+/**
+ * This function will init timer4 for system ticks
+ */
+ void rt_hw_timer_init()
+ {
+ 	/*Set timer1*/
+ 	*(RP)TIMER_T1LCR = 880000;
+	*(RP)TIMER_T1CR = 0x06;
+
+	rt_hw_interrupt_install(INTSRC_TIMER1, rt_timer_handler, RT_NULL);
+	rt_hw_interrupt_umask(INTSRC_TIMER1);
+
+	/*Enable timer1*/
+	*(RP)TIMER_T1CR |= 0x01;
+ }
+
+/**
+ * This function will handle init uart
+ */
+void rt_hw_uart_init(void)
+{
+	const rt_int32_t sysclk = 72000000;
+	
+	/*Set data bit:8*/
+	*(RP)(UART0_LCR) = 0x83;
+	/*Set baud rate high*/
+	*(RP)(UART0_DLBH) = (sysclk/16/115200) >> 8;
+	/*Set baud rate low*/
+	*(RP)(UART0_DLBL) = (sysclk/16/115200) & 0xff;
+
+	*(RP)(UART0_LCR) = 0x83&(~(0x1 << 7));
+
+	/*Set trigger level*/
+	*(RP)(UART0_FCR) = 0x0;
+	*(RP)(UART0_IER) = 0x0;
+
+	/*Enable rx interrupt*/
+	*(RP)(UART0_IER) |= 0x01;
+	/*Disable tx interrupt*/
+	*(RP)(UART0_IER) &= ~(0x1<<1);
+	
+	rt_hw_interrupt_install(INTSRC_UART0, rt_serial_handler, RT_NULL);
+	rt_hw_interrupt_umask(INTSRC_UART0);
+	/* register uart0 */
+	rt_hw_serial_register(&uart0_device, "uart0",
+		RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
+		&uart0);
+}
+
+void rt_hw_board_init()
+{
+   	/* initialize uart */
+	rt_hw_uart_init();
+//	rt_hw_board_led_init();
+	rt_hw_timer_init();
+}
+
+/* write one character to serial, must not trigger interrupt */
+void rt_hw_serial_putc(const char c)
+{
+	/*
+		to be polite with serial console add a line feed
+		to the carriage return character
+	*/
+	if (c=='\n')rt_hw_serial_putc('\r');
+
+	while (!((*(RP)UART0_LSR) & 0x40));
+	*(RP)(UART0_BASE) = c;
+}
+
+/**
+ * This function is used by rt_kprintf to display a string on console.
+ *
+ * @param str the displayed string
+ */
+void rt_hw_console_output(const char* str)
+{
+	while (*str)
+	{
+		rt_hw_serial_putc(*str++);
+	}
+}

+ 24 - 0
bsp/mini4020/board.h

@@ -0,0 +1,24 @@
+/*
+ * File      : board.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, 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
+ * 2006-10-08     Bernard      add board.h to this bsp
+ * 2010-10-5      Wangmeng     sep4020 implemention
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include <sep4020.h>
+
+void rt_hw_board_init(void);
+void rt_hw_sdcard_init(void);
+
+#endif

+ 700 - 0
bsp/mini4020/dm9161.c

@@ -0,0 +1,700 @@
+#include <rtthread.h>
+#include <netif/ethernetif.h>
+
+#include "dm9161.h"
+#include <sep4020.h>
+#include "mii.h"
+
+#define SPEED_10    10
+#define SPEED_100   100
+#define SPEED_1000  1000
+/* Duplex, half or full. */
+#define DUPLEX_HALF		0x00
+#define DUPLEX_FULL		0x01
+
+/*
+ * Davicom dm9161EP driver
+ *
+ * IRQ_LAN connects to EINT7(GPF7)
+ * nLAN_CS connects to nGCS4
+ */
+
+/* #define dm9161_DEBUG		1 */
+#if DM9161_DEBUG
+#define DM9161_TRACE	rt_kprintf
+#else
+#define DM9161_TRACE(...)
+#endif
+
+/*
+ * dm9161 interrupt line is connected to PF7
+ */
+//--------------------------------------------------------
+
+#define DM9161_PHY          0x40    /* PHY address 0x01 */
+
+#define MAX_ADDR_LEN 6
+enum DM9161_PHY_mode
+{
+    DM9161_10MHD = 0, DM9161_100MHD = 1,
+    DM9161_10MFD = 4, DM9161_100MFD = 5,
+    DM9161_AUTO  = 8, DM9161_1M_HPNA = 0x10
+};
+
+enum DM9161_TYPE
+{
+    TYPE_DM9161,
+};
+
+struct rt_dm9161_eth
+{
+    /* inherit from ethernet device */
+    struct eth_device parent;
+
+    enum DM9161_TYPE type;
+	enum DM9161_PHY_mode mode;
+
+    rt_uint8_t imr_all;
+	rt_uint8_t phy_addr;
+
+	rt_uint32_t tx_index;
+
+    rt_uint8_t packet_cnt;                  /* packet I or II */
+    rt_uint16_t queue_packet_len;           /* queued packet (packet II) */
+
+    /* interface address info. */
+    rt_uint8_t  dev_addr[MAX_ADDR_LEN];		/* hw address	*/
+};
+static struct rt_dm9161_eth dm9161_device;
+static struct rt_semaphore sem_ack, sem_lock;
+
+void rt_dm9161_isr(int irqno);
+
+static void udelay(unsigned long ns)
+{
+	unsigned long i;
+	while(ns--)
+	{
+		i = 100;
+		while(i--);
+	}
+}
+
+static __inline unsigned long sep_emac_read(unsigned int reg)
+{
+	void __iomem *emac_base = (void __iomem *)reg; 
+	return read_reg(emac_base);
+}
+ 
+/*
+* Write to a EMAC register.
+*/
+static __inline void sep_emac_write(unsigned int reg, unsigned long value)
+{
+	void __iomem *emac_base = (void __iomem *)reg;
+ 
+	write_reg(emac_base,value);
+}
+
+  
+/* ........................... PHY INTERFACE ........................... */
+/*         CAN DO MAC CONFIGRATION
+* Enable the MDIO bit in MAC control register
+* When not called from an interrupt-handler, access to the PHY must be
+*  protected by a spinlock.
+*/
+static void enable_mdi(void)           //need think more
+{
+	unsigned long ctl;
+  
+	ctl = sep_emac_read(MAC_CTRL);
+	sep_emac_write(MAC_CTRL, ctl&(~0x3));    /* enable management port */
+	return;
+}
+
+/*          CANNOT DO MAC CONFIGRATION
+* Disable the MDIO bit in the MAC control register
+*/
+static void disable_mdi(void)
+{
+	unsigned long ctl;
+  
+	ctl = sep_emac_read(MAC_CTRL);
+	sep_emac_write(MAC_CTRL, ctl|(0x3));    /* disable management port */
+	return;
+}
+
+/*
+* Wait until the PHY operation is complete.
+*/
+static __inline void sep_phy_wait(void) 
+{
+	unsigned long timeout = 2;
+
+	while ((sep_emac_read(MAC_MII_STATUS) & 0x2)) 
+	{
+		timeout--;
+		if (!timeout) 
+		{
+			EOUT("sep_ether: MDIO timeout\n");
+			break;
+		}		
+	}
+	return;
+}
+ 
+/*
+* Write value to the a PHY register
+* Note: MDI interface is assumed to already have been enabled.
+*/
+static void write_phy(unsigned char phy_addr, unsigned char address, unsigned int value)
+{
+	unsigned short mii_txdata;
+	
+	mii_txdata = value;
+	sep_emac_write(MAC_MII_ADDRESS,(unsigned long)(address<<8) | phy_addr);
+	sep_emac_write(MAC_MII_TXDATA ,mii_txdata);
+	sep_emac_write(MAC_MII_CMD ,0x4);
+	udelay(40);
+
+	sep_phy_wait();
+	return;	
+}
+ 
+/*
+* Read value stored in a PHY register.
+* Note: MDI interface is assumed to already have been enabled.
+*/
+static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int *value)
+{
+	unsigned short mii_rxdata;
+//	unsigned long mii_status;
+	
+	sep_emac_write(MAC_MII_ADDRESS,(unsigned long)(address<<8) | phy_addr);
+	sep_emac_write(MAC_MII_CMD ,0x2);
+	udelay(40);
+	sep_phy_wait();
+		
+	mii_rxdata = sep_emac_read(MAC_MII_RXDATA);
+	*value =  mii_rxdata;
+	return;
+}  
+
+
+
+
+/* interrupt service routine */
+void rt_dm9161_isr(int irqno)
+{
+	  unsigned long intstatus;
+	  rt_uint32_t address;
+
+ 	  mask_irq(INTSRC_MAC);
+	  intstatus = sep_emac_read(MAC_INTSRC);
+
+	  sep_emac_write(MAC_INTSRC,intstatus);
+	  
+	  /*Receive complete*/
+	  if(intstatus & 0x04)
+	  {
+	  	eth_device_ready(&(dm9161_device.parent));
+	  }	
+	  /*Receive error*/
+	  else if(intstatus & 0x08)
+	  {
+	  	rt_kprintf("Receive error\n");
+	  }
+	  /*Transmit complete*/
+	  else if(intstatus & 0x03)
+	  {
+	  	  	if(dm9161_device.tx_index == 0)
+				address = (MAC_TX_BD +(MAX_TX_DESCR-2)*8);
+			else if(dm9161_device.tx_index == 1) 
+				address = (MAC_TX_BD +(MAX_TX_DESCR-1)*8);
+			else 
+				address = (MAC_TX_BD + dm9161_device.tx_index*8-16);
+			//printk("free tx skb 0x%x in inter!!\n",lp->txBuffIndex);	
+			sep_emac_write(address,0x0);
+	  }
+	  else if (intstatus & 0x10)
+	  {
+	  	rt_kprintf("ROVER ERROR\n");
+
+	  }
+
+	while(intstatus)
+	{
+		sep_emac_write(MAC_INTSRC,intstatus);
+		intstatus = sep_emac_read(MAC_INTSRC);
+	}
+
+	unmask_irq(INTSRC_MAC);
+
+}
+
+static rt_err_t update_mac_address()
+{
+	rt_uint32_t lo,hi;
+	hi = sep_emac_read(MAC_ADDR1);
+	lo = sep_emac_read(MAC_ADDR0);
+	DBOUT("Before MAC: hi=%x lo=%x\n",hi,lo);
+
+	sep_emac_write(MAC_ADDR0,(dm9161_device.dev_addr[2] << 24) | (dm9161_device.dev_addr[3] << 16) | (dm9161_device.dev_addr[4] << 8) | (dm9161_device.dev_addr[5]));
+	sep_emac_write(MAC_ADDR1,dm9161_device.dev_addr[1]|(dm9161_device.dev_addr[0]<<8));
+
+	hi = sep_emac_read(MAC_ADDR1);
+	lo = sep_emac_read(MAC_ADDR0);
+	DBOUT("After MAC: hi=%x lo=%x\n",hi,lo);
+
+	return RT_EOK;
+}
+
+static int mii_link_ok (unsigned long phy_id)
+{
+	/* first, a dummy read, needed to latch some MII phys */
+
+	unsigned int value;
+
+	read_phy(phy_id, MII_BMSR,&value);
+	if (value & BMSR_LSTATUS)
+		return 1;
+	return 0;
+}
+
+static void update_link_speed(unsigned short phy_addr)
+{
+	unsigned int bmsr, bmcr, lpa, mac_cfg;
+	unsigned int speed, duplex;
+
+	if(!mii_link_ok(phy_addr))
+	{
+		EOUT("Link Down\n");
+		//goto result;
+	}
+
+	read_phy(phy_addr,MII_BMSR,&bmsr);
+	read_phy(phy_addr,MII_BMCR,&bmcr);
+
+	if (bmcr & BMCR_ANENABLE)                /* AutoNegotiation is enabled */
+	{                         
+		if (!(bmsr & BMSR_ANEGCOMPLETE))              /* Do nothing - another interrupt generated when negotiation complete */
+			goto result;              
+
+		read_phy(phy_addr, MII_LPA, &lpa);
+		
+		if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) 
+			speed = SPEED_100;
+		else 
+			speed = SPEED_10;
+			
+		if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) 
+			duplex = DUPLEX_FULL;
+		else 
+			duplex = DUPLEX_HALF;
+	} 
+	else 
+	{
+		speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
+		duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
+	 }
+ 
+    /* Update the MAC */
+	mac_cfg = sep_emac_read(MAC_CTRL);
+	if (speed == SPEED_100) 
+	{
+		mac_cfg |= 0x800;			/* set speed 100 M */
+		//bmcr &=(~0x2000);
+		//write_phy(lp->phy_address, MII_BMCR, bmcr); //将dm9161的速度设为10M
+		if (duplex == DUPLEX_FULL)              /* 100 Full Duplex */
+			mac_cfg |= 0x400;
+		else                                    /* 100 Half Duplex */
+			mac_cfg &= (~0x400);
+	} 
+	else 
+	{
+		mac_cfg &= (~0x800);             /* set speed 10 M */
+		
+		if (duplex == DUPLEX_FULL)              /* 10 Full Duplex */
+			mac_cfg |= 0x400;
+		else                                /* 10 Half Duplex */
+			mac_cfg &= (~0x400);
+	}
+	
+	sep_emac_write(MAC_CTRL, mac_cfg);
+	rt_kprintf("Link now %i M-%s\n",  speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex");
+			
+result:
+	mac_cfg = sep_emac_read(MAC_CTRL);
+	DBOUT("After mac_cfg=%d\n",mac_cfg);
+	return;
+}
+
+static rt_err_t rt_dm9161_open(rt_device_t dev, rt_uint16_t oflag);
+/* RT-Thread Device Interface */
+/* initialize the interface */
+static rt_err_t rt_dm9161_init(rt_device_t dev)
+{
+	unsigned int phyid1, phyid2;
+	int detected = -1;
+	unsigned long phy_id;
+	unsigned short phy_address = 0;
+
+	while ((detected != 0) && (phy_address < 32)) 
+	{
+		/* Read the PHY ID registers */
+		enable_mdi();
+		read_phy(phy_address, MII_PHYSID1, &phyid1);
+		read_phy(phy_address, MII_PHYSID2, &phyid2);
+	
+		disable_mdi();
+
+		phy_id = (phyid1 << 16) | (phyid2 & 0xfff0);
+		switch (phy_id) 
+		{
+			case MII_DM9161_ID:		/* Davicom 9161: PHY_ID1 = 0x181, PHY_ID2 = B881 */
+			case MII_DM9161A_ID:		/* Davicom 9161A: PHY_ID1 = 0x181, PHY_ID2 = B8A0 */
+			case MII_RTL8201_ID:		/* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */
+			case MII_BCM5221_ID:		/* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */
+			case MII_DP83847_ID:		/* National Semiconductor DP83847:  */
+			case MII_AC101L_ID:		/* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */
+			case MII_KS8721_ID:		/* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */
+			{
+				enable_mdi();
+				#warning SHOULD SET MAC ADDR
+				//get_mac_address(dev);		/* Get ethernet address and store it in dev->dev_addr */
+				update_mac_address();	/* Program ethernet address into MAC */
+			
+				//用哈希寄存器比较当前群播地址,全双工,添加CRC校验,短数据帧进行填充
+				sep_emac_write(MAC_CTRL, 0xa413);
+				#warning SHOULD DETERMIN LINK SPEED
+				update_link_speed(phy_address);
+				dm9161_device.phy_addr = phy_address;
+				disable_mdi();
+				break;
+			}
+				
+		}
+
+		phy_address++;
+	}
+
+	rt_dm9161_open(dev,0);
+
+    return RT_EOK;
+}
+
+
+
+/* ................................ MAC ................................ */
+
+/*
+ * Initialize and start the Receiver and Transmit subsystems
+ */
+static void sepether_start()
+{
+	int i;
+	unsigned int tempaddr;
+		 
+    sep_emac_write(MAC_TXBD_NUM,MAX_TX_DESCR);
+   
+	 //初始化发送和接收描述符
+	for (i = 0; i < MAX_TX_DESCR; i++)
+	{
+		tempaddr=(MAC_TX_BD+i*8);
+        sep_emac_write(tempaddr,0);
+        tempaddr=(MAC_TX_BD+i*8+4);
+        sep_emac_write(tempaddr,0);
+	}
+	for (i = 0; i < MAX_RX_DESCR; i++)
+	{
+        tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8);
+        sep_emac_write(tempaddr,0);
+        tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8+4);
+        sep_emac_write(tempaddr,0);
+	}
+    
+	for (i = 0; i < MAX_RX_DESCR; i++) 
+	{
+		tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8);
+        sep_emac_write(tempaddr,0xc000);
+        tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8+4);
+		sep_emac_write(tempaddr,ESRAM_BASE+ MAX_TX_DESCR*0x600+i*0x600);
+	}
+
+	/* Set the Wrap bit on the last descriptor */
+	tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8-8);
+	sep_emac_write(tempaddr,0xe000);
+  
+
+	for (i = 0; i < MAX_TX_DESCR; i++) 
+	{
+        tempaddr=(MAC_TX_BD+i*8);
+        sep_emac_write(tempaddr,0x0);
+        tempaddr=(MAC_TX_BD+i*8+4);
+        sep_emac_write(tempaddr,ESRAM_BASE+i*0x600);
+	}
+	
+	return;
+}
+
+static rt_err_t rt_dm9161_open(rt_device_t dev, rt_uint16_t oflag)
+{
+	unsigned int dsintr;
+	enable_mdi();
+  	mask_irq(28);
+ 	
+  	sep_emac_write(MAC_INTMASK,0x0);  //首先屏蔽中断
+  
+
+ 	sepether_start();
+
+	/* Enable PHY interrupt */
+	*(volatile unsigned long*)GPIO_PORTA_DIR |= 0x0080 ;          //1 stands for in
+	*(volatile unsigned long*)GPIO_PORTA_SEL |= 0x0080 ;       //for common use
+	*(volatile unsigned long*)GPIO_PORTA_INCTL |= 0x0080;      //中断输入方式
+	*(volatile unsigned long*)GPIO_PORTA_INTRCTL |= (0x3UL<<14);    //中断类型为低电平解发
+	*(volatile unsigned long*)GPIO_PORTA_INTRCLR |= 0x0080;    //清除中断
+	*(volatile unsigned long*)GPIO_PORTA_INTRCLR = 0x0000;          //清除中断
+
+	rt_hw_interrupt_install(INTSRC_MAC, rt_dm9161_isr, RT_NULL);
+	enable_irq(INTSRC_EXINT7);
+
+
+	read_phy(dm9161_device.phy_addr, MII_DSINTR_REG, &dsintr);
+	dsintr = dsintr & ~0xf00;		/* clear bits 8..11 */
+	write_phy(dm9161_device.phy_addr, MII_DSINTR_REG, dsintr);
+
+	update_link_speed(dm9161_device.phy_addr);
+	
+	
+	/************************************************************************************/
+	/* Enable MAC interrupts */
+	sep_emac_write(MAC_INTMASK,0xff);  //open中断
+  	sep_emac_write(MAC_INTSRC,0xff);   //clear all mac irq
+	unmask_irq(28);
+	disable_mdi();
+	
+	rt_kprintf("SEP4020 ethernet interface open!\n\r");
+    return RT_EOK;
+}
+
+static rt_err_t rt_dm9161_close(rt_device_t dev)
+{
+	rt_kprintf("SEP4020 ethernet interface close!\n\r");
+	
+	/* Disable Receiver and Transmitter */
+	disable_mdi();
+	#warning disable ether;
+	
+//	INT_ENABLE(28);
+	/* Disable PHY interrupt */
+//	disable_phyirq(dev);
+	
+	/* Disable MAC interrupts */
+	sep_emac_write(MAC_INTMASK,0);  //屏蔽中断
+
+	
+//	INT_DISABLE(28);
+	
+    return RT_EOK;
+}
+
+static rt_size_t rt_dm9161_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 rt_dm9161_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 rt_dm9161_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+
+    return RT_EOK;
+}
+
+/* ethernet device interface */
+/* transmit packet. */
+rt_err_t rt_dm9161_tx( rt_device_t dev, struct pbuf* p)
+{
+	rt_uint8_t i;
+	rt_uint32_t length = 0;
+	struct pbuf *q;
+	unsigned long  address;
+	unsigned long tmp_tx_bd;
+
+    /* lock DM9000 device */
+//    rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+
+    /* disable dm9000a interrupt */
+    #warning SHOULD DISABLE INTEERUPT?
+
+	/*Search for available BD*/
+	for(i = 0;i<MAX_TX_DESCR;)
+	{
+		address	= MAC_TX_BD + i*8;
+		tmp_tx_bd = sep_emac_read(address);
+		if(!(tmp_tx_bd & 0x8000))
+		{
+			if(i == (MAX_TX_DESCR-1)) 
+				i = 0;
+			else 
+				i = i+1;
+			break;
+		}
+		if(i == MAX_TX_DESCR-1) 
+			i = 0;
+		else 
+			i++;
+	}
+	
+	q = p;
+	while (q)
+	{
+		rt_memcpy((u8_t*)(ESRAM_BASE + i*0x600 + length),(u8_t*)q->payload,q->len);
+		length += q->len;
+		q = q->next;
+	}
+
+	#warning SHOULD NOTICE IT'S LENGTH
+
+	length = length << 16;
+
+	if(i == MAX_TX_DESCR - 1)
+		length |= 0xb800;
+	else 
+		length |= 0x9800;
+
+	address = (MAC_TX_BD + i*8);
+	dm9161_device.tx_index = i;
+	sep_emac_write(address,length);
+
+	//wait for tranfer complete
+	while(!(sep_emac_read(address)&0x8000));
+
+	/* unlock DM9000 device */
+//    rt_sem_release(&sem_lock);
+
+    /* wait ack */
+//    rt_sem_take(&sem_ack, RT_WAITING_FOREVER);
+
+    return RT_EOK;
+}
+
+/* reception packet. */
+struct pbuf *rt_dm9161_rx(rt_device_t dev)
+{
+	unsigned int temp_rx_bd,address;
+	rt_uint32_t i = 0;
+	rt_uint32_t length;
+	unsigned char *p_recv;
+	struct pbuf* p = RT_NULL;
+
+	/* lock DM9000 device */
+    rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+
+	while(1)
+	{
+	
+		address = MAC_TX_BD +  (MAX_TX_DESCR + i) * 8;
+		temp_rx_bd = sep_emac_read(address);
+	
+		if(!(temp_rx_bd & 0x8000))
+		{
+			length = temp_rx_bd;
+			length = length >> 16;
+	
+			p_recv = (unsigned char*)(ESRAM_BASE + (MAX_TX_DESCR + i) * 0x600);
+			p = pbuf_alloc(PBUF_LINK,length,PBUF_RAM);
+			if(p != RT_NULL)
+			{
+				struct pbuf* q;
+				rt_int32_t len;
+	
+				for(q = p;q != RT_NULL;q = q->next)
+				{
+					rt_memcpy((rt_uint8_t*)(q->payload),p_recv,q->len);
+				}
+			}
+			else
+			{
+				 rt_kprintf("Droping %d packet \n",length);
+			}
+	
+			if(i == (MAX_RX_DESCR-1))
+			{
+				sep_emac_write(address,0xe000);
+				i = 0;
+			}
+			else
+			{
+				sep_emac_write(address,0xc000);
+				i++;
+			}
+		}
+		else
+			break;
+	}
+
+	 rt_sem_release(&sem_lock);
+
+	
+	return p;
+}
+
+
+void rt_hw_dm9161_init()
+{
+	rt_sem_init(&sem_ack, "tx_ack", 1, RT_IPC_FLAG_FIFO);
+    rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
+
+    dm9161_device.type  = TYPE_DM9161;
+	dm9161_device.mode	= DM9161_AUTO;
+	dm9161_device.packet_cnt = 0;
+	dm9161_device.queue_packet_len = 0;
+
+    /*
+     * SRAM Tx/Rx pointer automatically return to start address,
+     * Packet Transmitted, Packet Received
+     */
+	#warning NOTICE:
+    //dm9161_device.imr_all = IMR_PAR | IMR_PTM | IMR_PRM;
+
+    dm9161_device.dev_addr[0] = 0x01;
+    dm9161_device.dev_addr[1] = 0x60;
+    dm9161_device.dev_addr[2] = 0x6E;
+    dm9161_device.dev_addr[3] = 0x11;
+    dm9161_device.dev_addr[4] = 0x02;
+    dm9161_device.dev_addr[5] = 0x0F;
+
+    dm9161_device.parent.parent.init       = rt_dm9161_init;
+    dm9161_device.parent.parent.open       = rt_dm9161_open;
+    dm9161_device.parent.parent.close      = rt_dm9161_close;
+    dm9161_device.parent.parent.read       = rt_dm9161_read;
+    dm9161_device.parent.parent.write      = rt_dm9161_write;
+    dm9161_device.parent.parent.control    = rt_dm9161_control;
+    dm9161_device.parent.parent.user_data  = RT_NULL;
+
+    dm9161_device.parent.eth_rx     = rt_dm9161_rx;
+    dm9161_device.parent.eth_tx     = rt_dm9161_tx;
+
+    eth_device_init(&(dm9161_device.parent), "e0");
+
+    /* instal interrupt */
+	#warning TODO
+	//rt_hw_interrupt_install(INTEINT4_7, rt_dm9161_isr, RT_NULL);
+	//rt_hw_interrupt_umask(INTEINT4_7);
+}
+
+void dm9161a(void)
+{
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT(dm9161a, dm9161a register dump);
+#endif

+ 65 - 0
bsp/mini4020/dm9161.h

@@ -0,0 +1,65 @@
+#ifndef __DM9000_H__
+#define __DM9000_H__
+
+/*MACRO DEFINATIONS*/
+
+
+ #define SEP4020_ID_EMAC   ((unsigned int) 28) // Ethernet Mac
+ /* Davicom 9161 PHY */
+ #define MII_DM9161_ID   0x0181b880
+ #define MII_DM9161A_ID  0x0181b8a0
+  
+ /* Davicom specific registers */
+ #define MII_DSCR_REG    16
+ #define MII_DSCSR_REG   17
+ #define MII_DSINTR_REG  21
+  
+  /* Intel LXT971A PHY */
+ #define MII_LXT971A_ID  0x001378E0
+  
+  /* Intel specific registers */
+ #define MII_ISINTE_REG  18
+ #define MII_ISINTS_REG  19
+ #define MII_LEDCTRL_REG 20
+
+ /* Realtek RTL8201 PHY */
+ #define MII_RTL8201_ID  0x00008200
+  
+ /* Broadcom BCM5221 PHY */
+ #define MII_BCM5221_ID  0x004061e0
+  
+ /* Broadcom specific registers */
+ #define MII_BCMINTR_REG 26
+  
+  /* National Semiconductor DP83847 */
+ #define MII_DP83847_ID  0x20005c30
+ 
+  /* Altima AC101L PHY */
+ #define MII_AC101L_ID   0x00225520
+  
+ /* Micrel KS8721 PHY */
+ #define MII_KS8721_ID   0x00221610
+ 
+ /* ........................................................................ */
+  
+ #define MAX_RBUFF_SZ    0x600           /* 1518 rounded up */
+ #define MAX_RX_DESCR    20           /* max number of receive buffers */
+  
+ #define MAX_TBUFF_SZ    0x600           /* 1518 rounded up */
+ #define MAX_TX_DESCR    20               /* max number of receive buffers */
+  
+ #define EMAC_DESC_DONE  0x00000001      /* bit for if DMA is done */
+ #define EMAC_DESC_WRAP  0x00000002      /* bit for wrap */
+  
+ #define EMAC_BROADCAST  0x80000000      /* broadcast address */
+ #define EMAC_MULTICAST  0x40000000      /* multicast address */
+ #define EMAC_UNICAST    0x20000000      /* unicast address */
+ 
+#define DM9161_inb(r) 		(*(volatile rt_uint8_t  *)r)
+#define DM9161_outb(r, d) 	(*(volatile rt_uint8_t  *)r = d)
+#define DM9161_inw(r) 		(*(volatile rt_uint16_t *)r)
+#define DM9161_outw(r, d) 	(*(volatile rt_uint16_t *)r = d)
+
+void rt_hw_dm9616_init(void);
+
+#endif

+ 9 - 0
bsp/mini4020/export.c

@@ -0,0 +1,9 @@
+#include <rtthread.h>
+#include <finsh.h>
+
+void testkkkk(void)
+{
+	rt_kprintf("Hello wangmengmeng!\n");	
+	return;
+}
+FINSH_FUNCTION_EXPORT(testkkkk,a test);

+ 130 - 0
bsp/mini4020/mii.h

@@ -0,0 +1,130 @@
+
+#ifndef __MII_H__
+#define __MII_H__
+
+/* Generic MII registers. */
+
+#define MII_BMCR            0x00        /* Basic mode control register */
+#define MII_BMSR            0x01        /* Basic mode status register  */
+#define MII_PHYSID1         0x02        /* PHYS ID 1                   */
+#define MII_PHYSID2         0x03        /* PHYS ID 2                   */
+#define MII_ADVERTISE       0x04        /* Advertisement control reg   */
+#define MII_LPA             0x05        /* Link partner ability reg    */
+#define MII_EXPANSION       0x06        /* Expansion register          */
+#define MII_CTRL1000        0x09        /* 1000BASE-T control          */
+#define MII_STAT1000        0x0a        /* 1000BASE-T status           */
+#define MII_ESTATUS	    0x0f	/* Extended Status */
+#define MII_DCOUNTER        0x12        /* Disconnect counter          */
+#define MII_FCSCOUNTER      0x13        /* False carrier counter       */
+#define MII_NWAYTEST        0x14        /* N-way auto-neg test reg     */
+#define MII_RERRCOUNTER     0x15        /* Receive error counter       */
+#define MII_SREVISION       0x16        /* Silicon revision            */
+#define MII_RESV1           0x17        /* Reserved...                 */
+#define MII_LBRERROR        0x18        /* Lpback, rx, bypass error    */
+#define MII_PHYADDR         0x19        /* PHY address                 */
+#define MII_RESV2           0x1a        /* Reserved...                 */
+#define MII_TPISTATUS       0x1b        /* TPI status for 10mbps       */
+#define MII_NCONFIG         0x1c        /* Network interface config    */
+
+/* Basic mode control register. */
+#define BMCR_RESV               0x003f  /* Unused...                   */
+#define BMCR_SPEED1000		0x0040  /* MSB of Speed (1000)         */
+#define BMCR_CTST               0x0080  /* Collision test              */
+#define BMCR_FULLDPLX           0x0100  /* Full duplex                 */
+#define BMCR_ANRESTART          0x0200  /* Auto negotiation restart    */
+#define BMCR_ISOLATE            0x0400  /* Disconnect DP83840 from MII */
+#define BMCR_PDOWN              0x0800  /* Powerdown the DP83840       */
+#define BMCR_ANENABLE           0x1000  /* Enable auto negotiation     */
+#define BMCR_SPEED100           0x2000  /* Select 100Mbps              */
+#define BMCR_LOOPBACK           0x4000  /* TXD loopback bits           */
+#define BMCR_RESET              0x8000  /* Reset the DP83840           */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP              0x0001  /* Ext-reg capability          */
+#define BMSR_JCD                0x0002  /* Jabber detected             */
+#define BMSR_LSTATUS            0x0004  /* Link status                 */
+#define BMSR_ANEGCAPABLE        0x0008  /* Able to do auto-negotiation */
+#define BMSR_RFAULT             0x0010  /* Remote fault detected       */
+#define BMSR_ANEGCOMPLETE       0x0020  /* Auto-negotiation complete   */
+#define BMSR_RESV               0x00c0  /* Unused...                   */
+#define BMSR_ESTATEN		0x0100	/* Extended Status in R15 */
+#define BMSR_100FULL2		0x0200	/* Can do 100BASE-T2 HDX */
+#define BMSR_100HALF2		0x0400	/* Can do 100BASE-T2 FDX */
+#define BMSR_10HALF             0x0800  /* Can do 10mbps, half-duplex  */
+#define BMSR_10FULL             0x1000  /* Can do 10mbps, full-duplex  */
+#define BMSR_100HALF            0x2000  /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL            0x4000  /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4           0x8000  /* Can do 100mbps, 4k packets  */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT          0x001f  /* Selector bits               */
+#define ADVERTISE_CSMA          0x0001  /* Only selector supported     */
+#define ADVERTISE_10HALF        0x0020  /* Try for 10mbps half-duplex  */
+#define ADVERTISE_1000XFULL     0x0020  /* Try for 1000BASE-X full-duplex */
+#define ADVERTISE_10FULL        0x0040  /* Try for 10mbps full-duplex  */
+#define ADVERTISE_1000XHALF     0x0040  /* Try for 1000BASE-X half-duplex */
+#define ADVERTISE_100HALF       0x0080  /* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE    0x0080  /* Try for 1000BASE-X pause    */
+#define ADVERTISE_100FULL       0x0100  /* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100  /* Try for 1000BASE-X asym pause */
+#define ADVERTISE_100BASE4      0x0200  /* Try for 100mbps 4k packets  */
+#define ADVERTISE_PAUSE_CAP     0x0400  /* Try for pause               */
+#define ADVERTISE_PAUSE_ASYM    0x0800  /* Try for asymetric pause     */
+#define ADVERTISE_RESV          0x1000  /* Unused...                   */
+#define ADVERTISE_RFAULT        0x2000  /* Say we can detect faults    */
+#define ADVERTISE_LPACK         0x4000  /* Ack link partners response  */
+#define ADVERTISE_NPAGE         0x8000  /* Next page bit               */
+
+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+			ADVERTISE_CSMA)
+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+                       ADVERTISE_100HALF | ADVERTISE_100FULL)
+
+/* Link partner ability register. */
+#define LPA_SLCT                0x001f  /* Same as advertise selector  */
+#define LPA_10HALF              0x0020  /* Can do 10mbps half-duplex   */
+#define LPA_1000XFULL           0x0020  /* Can do 1000BASE-X full-duplex */
+#define LPA_10FULL              0x0040  /* Can do 10mbps full-duplex   */
+#define LPA_1000XHALF           0x0040  /* Can do 1000BASE-X half-duplex */
+#define LPA_100HALF             0x0080  /* Can do 100mbps half-duplex  */
+#define LPA_1000XPAUSE          0x0080  /* Can do 1000BASE-X pause     */
+#define LPA_100FULL             0x0100  /* Can do 100mbps full-duplex  */
+#define LPA_1000XPAUSE_ASYM     0x0100  /* Can do 1000BASE-X pause asym*/
+#define LPA_100BASE4            0x0200  /* Can do 100mbps 4k packets   */
+#define LPA_PAUSE_CAP           0x0400  /* Can pause                   */
+#define LPA_PAUSE_ASYM          0x0800  /* Can pause asymetrically     */
+#define LPA_RESV                0x1000  /* Unused...                   */
+#define LPA_RFAULT              0x2000  /* Link partner faulted        */
+#define LPA_LPACK               0x4000  /* Link partner acked us       */
+#define LPA_NPAGE               0x8000  /* Next page bit               */
+
+#define LPA_DUPLEX		(LPA_10FULL | LPA_100FULL)
+#define LPA_100			(LPA_100FULL | LPA_100HALF | LPA_100BASE4)
+
+/* Expansion register for auto-negotiation. */
+#define EXPANSION_NWAY          0x0001  /* Can do N-way auto-nego      */
+#define EXPANSION_LCWP          0x0002  /* Got new RX page code word   */
+#define EXPANSION_ENABLENPAGE   0x0004  /* This enables npage words    */
+#define EXPANSION_NPCAPABLE     0x0008  /* Link partner supports npage */
+#define EXPANSION_MFAULTS       0x0010  /* Multiple faults detected    */
+#define EXPANSION_RESV          0xffe0  /* Unused...                   */
+
+#define ESTATUS_1000_TFULL	0x2000	/* Can do 1000BT Full */
+#define ESTATUS_1000_THALF	0x1000	/* Can do 1000BT Half */
+
+/* N-way test register. */
+#define NWAYTEST_RESV1          0x00ff  /* Unused...                   */
+#define NWAYTEST_LOOPBACK       0x0100  /* Enable loopback for N-way   */
+#define NWAYTEST_RESV2          0xfe00  /* Unused...                   */
+
+/* 1000BASE-T Control register */
+#define ADVERTISE_1000FULL      0x0200  /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF      0x0100  /* Advertise 1000BASE-T half duplex */
+
+/* 1000BASE-T Status register */
+#define LPA_1000LOCALRXOK       0x2000  /* Link partner local receiver status */
+#define LPA_1000REMRXOK         0x1000  /* Link partner remote receiver status */
+#define LPA_1000FULL            0x0800  /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF            0x0400  /* Link partner 1000BASE-T half duplex */
+
+#endif

+ 25 - 0
bsp/mini4020/mini4020.sct

@@ -0,0 +1,25 @@
+; *************************************************************
+; *** Scatter-Loading Description File generated by uVision ***
+; *************************************************************
+
+; *************************************************************
+; *** Scatter-Loadig Description File generated by uVision ***n
+; *************************************************************
+
+
+LR_ROM1 0x30000000 0x0FFD00 ; load region size_region 
+  {    
+  	ER_ROM1 0x30000000 0x0FFD00  ; load address = execution address
+	{  
+   		*.o (RESET, +First)
+		*(InRoot$$Sections)
+		.ANY (+RO)
+  	}
+  	RW_RAM1 0x30100000 0x100000 ; RW data 
+  	{  
+   		.ANY (+RW +ZI)
+  	}
+
+
+}
+

+ 200 - 0
bsp/mini4020/rtconfig.h

@@ -0,0 +1,200 @@
+/* RT-Thread config file */
+#ifndef __RTTHREAD_CFG_H__
+#define __RTTHREAD_CFG_H__
+
+/* RT_NAME_MAX*/
+#define RT_NAME_MAX	8
+
+/* RT_ALIGN_SIZE*/
+#define RT_ALIGN_SIZE	4
+
+/* PRIORITY_MAX */
+#define RT_THREAD_PRIORITY_MAX	256
+
+/* Tick per Second */
+#define RT_TICK_PER_SECOND	100
+
+/* SECTION: RT_DEBUG */
+/* Thread Debug */
+#define RT_DEBUG
+/* #define RT_THREAD_DEBUG */
+
+#define RT_USING_OVERFLOW_CHECK
+
+/* Using Hook */
+#define RT_USING_HOOK
+
+/* Using Software Timer */
+#define RT_USING_TIMER_SOFT
+#define RT_TIMER_THREAD_PRIO		8
+#define RT_TIMER_THREAD_STACK_SIZE	512
+#define RT_TIMER_TICK_PER_SECOND	10
+
+/* SECTION: IPC */
+/* Using Semaphore */
+#define RT_USING_SEMAPHORE
+
+/* Using Mutex */
+#define RT_USING_MUTEX
+
+/* Using Event */
+#define RT_USING_EVENT
+
+/* Using MailBox */
+#define RT_USING_MAILBOX
+
+/* Using Message Queue */
+#define RT_USING_MESSAGEQUEUE
+
+/* SECTION: Memory Management */
+/* Using Memory Pool Management*/
+#define RT_USING_MEMPOOL
+
+/* Using Dynamic Heap Management */
+#define RT_USING_HEAP
+
+/* Using Small MM */
+/* #define RT_USING_SMALL_MEM */
+
+/* Using SLAB Allocator */
+#define RT_USING_SLAB
+
+/* SECTION: Device System */
+/* Using Device System */
+#define RT_USING_DEVICE
+
+/* SECTION: Console options */
+/* the buffer size of console */
+#define RT_CONSOLEBUF_SIZE	128
+
+/* SECTION: finsh, a C-Express shell */
+/* Using FinSH as Shell*/
+#define RT_USING_FINSH
+#define FINSH_USING_SYMTAB
+#define FINSH USING DESCRIPTION
+
+/* SECTION: a runtime libc library */
+/* a runtime libc library */
+/* #define RT_USING_NEWLIB */
+
+/* SECTION: a mini libc */
+
+/* SECTION: C++ support */
+/* Using C++ support */
+/* #define RT_USING_CPLUSPLUS */
+
+/* SECTION: Device filesystem support */
+/* using DFS support */
+#define RT_USING_DFS
+#define RT_USING_DFS_ELMFATFS
+/* #define RT_USING_DFS_YAFFS2 */
+
+/* #define DFS_USING_WORKDIR */
+
+/* the max number of mounted filesystem */
+#define DFS_FILESYSTEMS_MAX		2
+/* the max number of opened files 		*/
+#define DFS_FD_MAX					16
+/* the max number of cached sector 		*/
+#define DFS_CACHE_MAX_NUM   		4
+
+/* SECTION: lwip, a lighwight TCP/IP protocol stack */
+/* Using lighweight TCP/IP protocol stack */
+//#define RT_USING_LWIP
+#define RT_LWIP_DNS
+
+/* Trace LwIP protocol */
+/* #define RT_LWIP_DEBUG */
+
+/* Enable ICMP protocol */
+#define RT_LWIP_ICMP
+
+/* Enable IGMP protocol */
+#define RT_LWIP_IGMP
+
+/* Enable UDP protocol */
+#define RT_LWIP_UDP
+
+/* Enable TCP protocol */
+#define RT_LWIP_TCP
+
+/* the number of simulatenously active TCP connections*/
+#define RT_LWIP_TCP_PCB_NUM	5
+
+/* TCP sender buffer space */
+#define RT_LWIP_TCP_SND_BUF	1024*10
+
+/* TCP receive window. */
+#define RT_LWIP_TCP_WND	1024
+
+/* Enable SNMP protocol */
+/* #define RT_LWIP_SNMP */
+
+/* Using DHCP */
+/* #define RT_LWIP_DHCP */
+
+#define RT_LWIP_DNS
+
+/* ip address of target */
+#define RT_LWIP_IPADDR0	192
+#define RT_LWIP_IPADDR1	168
+#define RT_LWIP_IPADDR2	1
+#define RT_LWIP_IPADDR3	30
+
+/* gateway address of target */
+#define RT_LWIP_GWADDR0	192
+#define RT_LWIP_GWADDR1	168
+#define RT_LWIP_GWADDR2	1
+#define RT_LWIP_GWADDR3	1
+
+/* mask address of target */
+#define RT_LWIP_MSKADDR0	255
+#define RT_LWIP_MSKADDR1	255
+#define RT_LWIP_MSKADDR2	255
+#define RT_LWIP_MSKADDR3	0
+
+/* the number of blocks for pbuf */
+#define RT_LWIP_PBUF_NUM	16
+
+/* thread priority of tcpip thread */
+#define RT_LWIP_TCPTHREAD_PRIORITY	128
+
+/* mail box size of tcpip thread to wait for */
+#define RT_LWIP_TCPTHREAD_MBOX_SIZE	8
+
+/* thread stack size of tcpip thread */
+#define RT_LWIP_TCPTHREAD_STACKSIZE	4096
+
+/* thread priority of ethnetif thread */
+#define RT_LWIP_ETHTHREAD_PRIORITY	144
+
+/* mail box size of ethnetif thread to wait for */
+#define RT_LWIP_ETHTHREAD_MBOX_SIZE	32
+
+/* thread stack size of ethnetif thread */
+#define RT_LWIP_ETHTHREAD_STACKSIZE	1024
+
+/* SECTION: RTGUI support */
+/* using RTGUI support */
+#define RT_USING_RTGUI
+
+/* name length of RTGUI object */
+#define RTGUI_NAME_MAX		16
+/* support 16 weight font */
+#define RTGUI_USING_FONT16
+/* support 16 weight font */
+#define RTGUI_USING_FONT12
+/* support Chinese font */
+#define RTGUI_USING_FONTHZ
+/* use DFS as file interface */
+#define RTGUI_USING_DFS_FILERW
+/* use font file as Chinese font */
+/* #define RTGUI_USING_HZ_FILE */
+/* use Chinese bitmap font */
+#define RTGUI_USING_HZ_BMP
+/* use small size in RTGUI */
+/* #define RTGUI_USING_SMALL_SIZE */
+/* use mouse cursor */
+/* #define RTGUI_USING_MOUSE_CURSOR */
+
+#endif

+ 790 - 0
bsp/mini4020/sdcard.c

@@ -0,0 +1,790 @@
+/*
+ * File      : sdcard.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, 2007, 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
+ * 2007-12-02     Yi.Qiu      the first version
+ * 2010-01-01     Bernard     Modify for mini2440
+ * 2010-10-13     Wangmeng    Added sep4020 support
+ */
+
+#include "sdcard.h"
+#include <dfs_config.h>
+
+volatile rt_int32_t RCA;
+
+#ifdef RT_USING_DFS
+
+/* RT-Thread Device Driver Interface */
+#include <rtthread.h>						  
+#include <dfs_fs.h>
+
+/*GLOBAL SD DEVICE PONITER*/
+static struct sd_device *ptr_sddev;
+static rt_uint8_t gsec_buf[SECTOR_SIZE];
+
+#define USE_TIMEOUT
+
+/*This file is to power on/off the SEP4020 SDC*/
+/**
+ * This function will power on/off the SEP4020 SDC
+ *
+ * @param sd_ctl: 0/power on; 1/power off
+ * @return none
+ *
+ */
+static void sd_pwr(int sd_ctl)
+{
+	if (sd_ctl)
+	{
+	    *(RP)GPIO_PORTA_SEL  |= 0x0200;
+	    *(RP)GPIO_PORTA_DIR  &= (~0x0200);
+	    *(RP)GPIO_PORTA_DATA |= 0x0200;
+	}
+	else
+	{
+	     
+	   *(RP)GPIO_PORTA_SEL |= 0x0200;
+	   *(RP)GPIO_PORTA_DIR &= (~0x0200);
+	   *(RP)GPIO_PORTA_DATA &= (~0x0200);     
+	}
+}
+
+/*a nop operation to delay*/
+static void delay (U32 j)
+{ 
+  U32 i;
+  
+  for (i=0;i<j;i++)
+  {};
+
+}
+/*
+* Send the command to set the data transfer mode
+* @param cmd:the command to sent
+* @param arg:the argument of the command
+* @param mode:SDC transfer mode
+* @param blk_len:the block size of each data
+* @param num:number of blocks
+* @param mask:sdc interrupt mask
+*/
+static rt_err_t cmd_data(U16 cmd,U32 arg,U16 mode,U16 blk_len,U16 num,U16 mask)
+{
+    U32 i;
+	#ifdef USE_TIMEOUT
+	U32 to = 10000;
+	#endif
+    
+    *(RP)SDC_CLOCK_CONTROL = 0Xff00;                  //配置SD时钟,512分频,关闭SD 时钟
+    *(RP)SDC_CLOCK_CONTROL = 0Xff04;                  //打开SD时钟,512分频,开启SD 时钟
+    *(RP)SDC_INTERRUPT_STATUS_MASK = mask;         //中断状态屏蔽寄存器赋值
+    
+    *(RP)SDC_TRANSFER_MODE = mode;               //传输模式选择寄存器赋值
+    
+    *(RP)SDC_BLOCK_SIZE = blk_len;                     //数据块长度寄存器赋值
+    *(RP)SDC_BLOCK_COUNT = num;                       //数据块数目寄存器赋值
+    *(RP)SDC_ARGUMENT = arg;                          //命令参数寄存器赋值
+    *(RP)SDC_COMMAND = cmd;                           //命令控制寄存器赋值
+    
+    delay(10);                                  
+   
+    i = *(RP)SDC_INTERRUPT_STATUS & 0x1000;
+	
+    while(i != 0x1000)                             //判断:是否命令发送完毕,并且收到响应
+    {
+	   i = *(RP)SDC_INTERRUPT_STATUS & 0x1000;
+	   #ifdef USE_TIMEOUT
+	   to --;
+	   if(!to)
+	   {
+	   		EOUT("%s TIMEOUT\n",__FUNCTION__);
+			return RT_ETIMEOUT;
+	   }
+	   #endif
+    }
+    delay(160);
+
+	#ifdef USE_TIMEOUT
+	//DBOUT("cmd_data TO is %d\n",to);
+	#endif
+
+    return *(RP)SDC_RESPONSE0;                     //返回命令反馈信息
+}
+
+static rt_err_t cmd_response(U16 Cmd,U32 Arg,U16 TransMode,U16 BlkLen,U16 Nob,U16 IntMask)
+{
+   U32 i;
+   #ifdef USE_TIMEOUT
+   U32 to = 50000;
+   #endif
+    
+   *(RP)SDC_CLOCK_CONTROL=0Xff00;               //配置SD时钟
+   
+   *(RP)SDC_CLOCK_CONTROL=0Xff04;               //打开SD时钟		
+    
+    
+    *(RP)SDC_INTERRUPT_STATUS_MASK=IntMask;     //中断状态屏蔽寄存器赋值
+    *(RP)SDC_TRANSFER_MODE=TransMode;           //传输模式选择寄存器赋值
+    *(RP)SDC_BLOCK_SIZE=BlkLen;                 //数据块长度寄存器赋值
+    *(RP)SDC_BLOCK_COUNT=Nob;                   //数据块数目寄存器赋值
+    *(RP)SDC_ARGUMENT=Arg;                      //命令参数寄存器赋值
+    *(RP)SDC_COMMAND=Cmd;                       //命令控制寄存器赋值
+    
+    delay(10);    
+        
+    i = *(RP)SDC_INTERRUPT_STATUS & 0x1040;
+	
+    while(i != 0x1040)                         //判断:命令发送完毕,并且收到响应,数据传输完毕。这三项是否已经都完成。
+    {
+		i = *(RP)SDC_INTERRUPT_STATUS & 0x1040;
+		#ifdef USE_TIMEOUT
+		to--;
+		if(!to)
+		{
+			EOUT("%s Timeout\n",__FUNCTION__);
+			return RT_ETIMEOUT;
+		}
+		#endif
+    }
+    
+	//DBOUT("cmd_response TO is %d\n",to);
+    delay(100);
+    
+    return RT_EOK;                  //返回命令反馈信息
+}
+static rt_err_t cmd_wait(U16 Cmd,U32 Arg,U16 IntMask )
+{
+    int i;
+	#ifdef USE_TIMEOUT
+	U32 to=200000;
+	#endif
+
+    *(RP)SDC_CLOCK_CONTROL=0Xff00;                       //配置SD时钟
+    
+    *(RP)SDC_CLOCK_CONTROL=0Xff04;                       //打开SD时钟
+       
+    *(RP)SDC_COMMAND=Cmd;                                //命令控制寄存器赋值    
+                    
+    *(RP)SDC_INTERRUPT_STATUS_MASK=IntMask;              //中断状态屏蔽寄存器赋值
+    
+    *(RP)SDC_ARGUMENT=Arg;                               //命令参数寄存器赋值
+	
+    i = *(RP)SDC_INTERRUPT_STATUS & 0x1000;
+	
+    while(i != 0x1000)                                  //判断:是否命令发送完毕,并且收到响应
+    {
+		i = *(RP)SDC_INTERRUPT_STATUS & 0x1000;
+		#ifdef USE_TIMEOUT
+		to--;
+		if(!to)
+		{
+			EOUT("%s Timeout\n",__FUNCTION__);
+			return RT_ETIMEOUT;
+		}
+		#endif
+
+    }
+
+	//DBOUT("cmd_wait TO is %d\n",to);    
+
+    delay(10);
+        	                	             
+    return RT_EOK;                           //返回命令反馈信息以及数值1
+}
+/**
+ * This function will set a hook function, which will be invoked when a memory
+ * block is allocated from heap memory.
+ *
+ * @param hook the hook function
+ */
+static rt_err_t sd_init(void)
+{
+	rt_err_t err;
+	#ifdef USE_TIMEOUT
+	rt_uint32_t to=1000;
+	#endif
+	sd_pwr(1);
+    
+    *(RP)SDC_SOFTWARE_RESET=0x0;                   //触发软复位,对其写0是进行reset    
+    delay(200);
+    *(RP)SDC_SOFTWARE_RESET=0x1;                   //不触发软复位    
+    delay(200);
+ 
+    cmd_wait(0x08,0x0,0xfff);               //CMD0,命令发送使能
+       
+	do
+    {
+    	err = cmd_wait(0x6ea,0x0,0xfff);          //CMD55,以切换到ACMD命令
+
+		#ifdef USE_TIMEOUT
+		if(err != RT_EOK)
+		{	
+			EOUT("cmd_wait err in %s\n",__FUNCTION__);
+			return RT_ETIMEOUT;
+		}
+		#endif
+    	
+    	delay(3);  
+    	err = cmd_wait(0x52a,0x80ff8000,0xfff);   //ACMD41,向SD控制器发送命令,等待SD控制器确认收到命令
+		if(err != RT_EOK)
+		{	
+			EOUT("cmd_wait err in %s\n",__FUNCTION__);
+			return RT_ETIMEOUT;
+		}
+		#ifdef USE_TIMEOUT
+		to--;
+		if(!to)
+		{
+			EOUT("%s timeout\n",__FUNCTION__);
+			return RT_ETIMEOUT;
+		}
+		#endif
+       
+    }while(*(RP)SDC_RESPONSE0<0X80008000);
+
+	#ifdef USE_TIMEOUT
+    //DBOUT("%s TO is %d\n",__FUNCTION__,to);
+	#endif
+
+    cmd_data(0x49,0X0,0X0,0x0,0x0,0Xfff);//CMD2,发送CID    
+    cmd_data(0x6a,0X0,0X0,0x0,0x0,0Xfff);//CMD3,询问卡片发出新的相关地址    
+    RCA = *(RP)SDC_RESPONSE0;    
+    cmd_data(0xea,RCA,0X0,0x0,0x0,0Xfff);//CMD7,设置选择性的相关参数
+
+	return RT_EOK;
+}
+
+/**
+ * This function will set a hook function, which will be invoked when a memory
+ * block is allocated from heap memory.
+ *
+ * @param hook the hook function
+ */
+static rt_err_t sd_readblock(rt_uint32_t address, rt_uint8_t* buf)
+{
+	U32 complete,i;
+	rt_uint8_t temp;
+	rt_err_t err;
+	UNUSED rt_uint32_t discard;
+	#ifdef USE_TIMEOUT
+	rt_uint32_t to = 10;
+	#endif
+
+
+	//rt_kprintf("in readblock:%x\n",address);
+	//Clear all the errors & interrups
+	*(RP)DMAC_INTINTERRCLR  |= 0x1;
+	*(RP)DMAC_INTINTERRCLR	&= ~0x1;
+	*(RP)DMAC_INTTCCLEAR	|= 0x1;
+	*(RP)DMAC_INTTCCLEAR	&= ~0x1; 
+
+	/*Clear read fifo*/
+	*(RP)(SDC_INTERRUPT_STATUS_MASK) = ~(0x1<<9); //don't mask fifo empty
+	while((*(RP)SDC_INTERRUPT_STATUS)&0x200 != 0x200)
+		discard = *(RP)SDC_READ_BUFER_ACCESS;
+
+	/*DMAC2,word,size=0x80*/
+    *(RP)DMAC_C2SRCADDR  = SDC_READ_BUFER_ACCESS;           
+    *(RP)DMAC_C2DESTADDR = (rt_uint32_t)buf;                
+    *(RP)DMAC_C2CONTROL  =0x20249b;                        
+    *(RP)DMAC_C2CONFIGURATION = 0x38d;                      	
+
+    err = cmd_wait(0x6ea,RCA,0xfff);                       
+	if(err != RT_EOK)
+	{
+		rt_set_errno(err);
+		return err;
+	}
+
+    err = cmd_wait(0xca,0x2,0xfff);
+	if(err != RT_EOK)
+	{
+		rt_set_errno(err);
+		return err;
+	}                       
+   						
+    err = cmd_response(0x22e,address,0X1,0x0200,0x1,0Xfff); //CMD17 4bit mode
+	if(err != RT_EOK)
+	{
+		rt_set_errno(err);
+		return err;
+	}
+    
+    complete = *(RP)SDC_INTERRUPT_STATUS;
+    
+	/*CRC*/
+    if((complete |0xfffffffd) !=0xfffffffd)              
+    {
+     	rt_kprintf("CRC ERROR!!!\n");
+      	complete = *(RP)SDC_INTERRUPT_STATUS;
+    }
+	while(((*(RP)( DMAC_INTTCSTATUS)) & 0x4) != 0x4 )
+	{
+		delay(10);
+		#ifdef USE_TIMEOUT
+		to--;
+		if(!to)
+		{
+			EOUT("%s TIMEOUT\n",__FUNCTION__);
+			return RT_ETIMEOUT;
+		}
+		#endif
+	}
+	#ifdef USE_TIMEOUT
+	//DBOUT("%s timeout is %d\n",__FUNCTION__,to);
+	#endif
+	/*for the buf is big-endian we must reverse it*/
+	for(i = 0;i<0x80;i++)
+	{
+		temp = buf[0];
+		buf[0] = buf[3];
+		buf[3] = temp;
+
+		temp = buf[1];
+		buf[1] = buf[2];
+		buf[2] = temp;
+
+		buf += 4;
+	}  
+
+	return RT_EOK;
+}
+
+static rt_uint8_t sd_readmultiblock(rt_uint32_t address, rt_uint8_t* buf,rt_uint32_t size)
+{
+	rt_int32_t index;
+	rt_uint8_t status=RT_EOK;
+	
+	for(index = 0;index < size;index++)
+	{
+		status = sd_readblock(address+index*SECTOR_SIZE,buf+index*SECTOR_SIZE);
+		if(status!=RT_EOK)
+			break;	
+	}
+	return status;
+}
+
+/**
+ * This function will set a hook function, which will be invoked when a memory
+ * block is allocated from heap memory.
+ *
+ * @param hook the hook function
+ */
+static rt_uint8_t sd_writeblock(rt_uint32_t address, rt_uint8_t* buf)
+{
+	U32 complete;
+	rt_uint8_t temp;
+	rt_uint8_t *ptr = buf;
+	rt_err_t err;
+	#ifdef USE_TIMEOUT
+	rt_uint32_t to = 10;
+	#endif
+
+	int i;
+
+	rt_kprintf("in writeblock:%x\n",address);
+
+	/*for the buf is big-endian we must reverse it*/
+	for(i = 0;i<0x80;i++)
+	{
+		temp = ptr[0];
+		ptr[0] = ptr[3];
+		ptr[3] = temp;
+
+		temp = ptr[1];
+		ptr[1] = ptr[2];
+		ptr[2] = temp;
+
+		ptr += 4;
+	} 
+	//Clear all the errors & interrups
+	*(RP)DMAC_INTINTERRCLR  |= 0x1;
+	*(RP)DMAC_INTINTERRCLR	&= ~0x1;
+	*(RP)DMAC_INTTCCLEAR	|= 0x1;
+	*(RP)DMAC_INTTCCLEAR	&= ~0x1; 
+
+    //***********************配置DMA2进行四位写*************************
+    *(RP)DMAC_C2SRCADDR  = (U32)buf;                  //DMAC道2源地址赋为0x30200000
+    *(RP)DMAC_C2DESTADDR = SDC_WRITE_BUFER_ACCESS;           //DMAC道2目的地址赋为发送FIFO的地址
+    *(RP)DMAC_C2CONTROL  = 0x20149b;                         //传输尺寸0x080,源地址增加目的地址不增加,传输宽度32bit,传输的数目4                                                  				
+    *(RP)DMAC_C2CONFIGURATION = 0x380b;	                     //不屏蔽传输中断,屏蔽错误中断,通道使能,传输类型:存储器到外设							       				 	    
+    
+    
+    err = cmd_wait(0x6ea,RCA,0xfff);                        //CMD55,以切换到ACMD命令
+	if(err != RT_EOK)
+	{
+		rt_set_errno(err);
+		return err;
+	}
+
+    err = cmd_wait(0xca,0x2,0xfff);                         //ACMD6,定义数据线宽度,48 位短反馈,无数据传输
+    if(err != RT_EOK)
+	{
+		rt_set_errno(err);
+		return err;
+	}
+  
+    err = cmd_response(0x30e,address,0X3,0x0200,0x1,0Xfff);  //CMD24  1bit mode
+    if(err != RT_EOK)
+	{
+		rt_set_errno(err);
+		return err;
+	}
+ 
+    complete = *(RP)SDC_INTERRUPT_STATUS;
+    
+    if((complete |0xfffffffe) !=0xfffffffe)               //响应超时错误
+    {
+      //printf("CRC ERROR");
+      complete = *(RP)SDC_INTERRUPT_STATUS;
+    } 
+	
+	while(((*(RP)( DMAC_INTTCSTATUS)) & 0x4) != 0x4 )
+	{
+		delay(10);
+		#ifdef USE_TIMEOUT
+		to--;
+		if(!to)
+		{
+			EOUT("%s TIMEOUT\n",__FUNCTION__);
+		}
+		#endif
+	}
+	#ifdef USE_TIMEOUT
+	//DBOUT("%s timeout is %d\n",__FUNCTION__,to);
+	#endif
+
+	return RT_EOK;
+}
+
+
+/**
+ * This function will set a hook function, which will be invoked when a memory
+ * block is allocated from heap memory.
+ *
+ * @param hook the hook function
+ */
+static rt_err_t rt_sdcard_init(rt_device_t dev)
+{
+	return 0;
+}
+
+/**
+ * This function will set a hook function, which will be invoked when a memory
+ * block is allocated from heap memory.
+ *
+ * @param hook the hook function
+ */
+static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
+{
+	return 0;
+}
+
+/**
+ * This function will set a hook function, which will be invoked when a memory
+ * block is allocated from heap memory.
+ *
+ * @param hook the hook function
+ */
+static rt_err_t rt_sdcard_close(rt_device_t dev)
+{
+	return 0;
+}
+
+/**
+ * This function will set a hook function, which will be invoked when a memory
+ * block is allocated from heap memory.
+ *
+ * @param hook the hook function
+ */
+static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+	rt_kprintf("cmd = %d\n",cmd);
+	    RT_ASSERT(dev != RT_NULL);
+
+    if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
+    {
+        struct rt_device_blk_geometry *geometry;
+
+        geometry = (struct rt_device_blk_geometry *)args;
+        if (geometry == RT_NULL) return -RT_ERROR;
+
+        geometry->bytes_per_sector = 512;
+        geometry->block_size = 0x200000;
+		//if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
+		//	geometry->sector_count = (SDCardInfo.SD_csd.DeviceSize + 1)  * 1024;
+		//else
+        	geometry->sector_count = 0x200000;//SDCardInfo.CardCapacity/SDCardInfo.CardBlockSize;
+    }
+
+    return RT_EOK;
+}
+
+/**
+ * This function will set a hook function, which will be invoked when a memory
+ * block is allocated from heap memory.
+ *
+ * @param hook the hook function
+ */
+static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+	rt_uint32_t retry = 3;
+	rt_uint8_t	status;
+	rt_uint32_t index;
+
+	///*take the semaphore
+	struct dfs_partition *part = (struct dfs_partition *)dev->user_data;
+	rt_sem_take(part->lock, RT_WAITING_FOREVER);
+    while(retry--)
+    {
+		if (((rt_uint32_t)buffer % 4 != 0) ||
+        ((rt_uint32_t)buffer > 0x20080000))
+		{
+			for(index = 0;index < size;index++)
+			{
+				status = sd_readblock((part->offset + pos) * SECTOR_SIZE,ptr_sddev->sec_buf);
+				if(status != RT_EOK)
+					break;
+	
+				rt_memcpy((rt_uint8_t *)buffer + (index * SECTOR_SIZE),ptr_sddev->sec_buf,SECTOR_SIZE);
+			}
+		}
+		else
+		{
+			 for(index = 0;index<size;index++)
+			 {
+			 	status = sd_readblock((pos) * SECTOR_SIZE,(rt_uint8_t*)buffer + index * SECTOR_SIZE);
+				if(status != RT_EOK)
+					break;
+			 }
+		}
+
+    } 
+	rt_sem_release(part->lock);
+
+	if (status == RT_EOK) 
+		return size;
+
+	rt_kprintf("read failed: %d, buffer 0x%08x\n", status, buffer);
+	return 0;  
+
+}
+
+/**
+ * This function will set a hook function, which will be invoked when a memory
+ * block is allocated from heap memory.
+ *
+ * @param hook the hook function
+ */
+static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+	int i;
+	rt_uint8_t status;
+
+	struct dfs_partition *part = (struct dfs_partition *)dev->user_data;
+
+	if ( dev == RT_NULL )
+	{
+		rt_set_errno(-DFS_STATUS_EINVAL);
+		return 0;
+	}
+
+	rt_sem_take(part->lock, RT_WAITING_FOREVER);
+
+    if (((rt_uint32_t)buffer % 4 != 0) ||
+        ((rt_uint32_t)buffer > 0x20080000))
+	{
+		rt_uint32_t index;
+
+		for(index=0;index<size;index++)
+		{
+			 rt_memcpy(ptr_sddev->sec_buf, ((rt_uint8_t*)buffer + index * SECTOR_SIZE), SECTOR_SIZE);
+			 status = sd_writeblock((part->offset + index + pos)*SECTOR_SIZE,ptr_sddev->sec_buf);
+		}
+	}
+	else
+	{  
+
+		for(i=0;i<size;i++)
+		{
+			status = sd_writeblock((part->offset + i + pos)*SECTOR_SIZE,
+				(rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE));	
+			if (status != RT_EOK) break;
+		}
+	}
+
+	rt_sem_release(part->lock);
+
+	if (status == RT_EOK) 
+		return size;
+
+	rt_kprintf("read failed: %d, buffer 0x%08x\n", status, buffer);
+	return 0;
+}
+
+
+rt_err_t rt_hw_sdcard_exit()
+{
+	if(ptr_sddev->device != RT_NULL)
+		rt_free(ptr_sddev->device);
+	if(ptr_sddev->part != RT_NULL)
+		rt_free(ptr_sddev->part);
+	if(ptr_sddev != RT_NULL)
+		rt_free(ptr_sddev);
+
+	return RT_EOK;
+}
+
+/**
+ * This function will init sd card
+ *
+ * @param void
+ */
+rt_err_t rt_hw_sdcard_init()
+{
+	/*For test*/
+	rt_err_t err;
+	rt_int32_t i;
+
+	char dname[4];
+	char sname[8];
+
+	/*Initialize structure*/
+
+	ptr_sddev = (struct sd_device*)rt_malloc(sizeof(struct sd_device));
+	if(ptr_sddev == RT_NULL)
+	{
+		EOUT("Failed to allocate sdcard device structure\n");
+		return RT_ENOMEM;		 	
+	}
+
+	/*sdcard intialize*/
+	err = sd_init();
+	if(err != RT_EOK)
+	 	goto FAIL2;
+
+	/*set sector buffer*/
+	ptr_sddev->sec_buf = gsec_buf;
+	ptr_sddev->buf_size = SECTOR_SIZE;
+	ptr_sddev->sdc = (struct sd_c*)SD_BASE;
+
+	//DBOUT("allocate partition sector buffer OK!");
+
+	err = sd_readblock(0,ptr_sddev->sec_buf);
+	if(err != RT_EOK)
+	{
+		EOUT("read first block error\n");
+		goto FAIL2;
+	}
+
+	/*sdcard driver initialize*/
+	ptr_sddev->part = (struct dfs_partition*)rt_malloc(4 * sizeof(struct dfs_partition));
+	if(ptr_sddev->part == RT_NULL)
+	{
+		 EOUT("allocate partition failed\n");
+		 err = 	RT_ENOMEM;
+		 goto FAIL2;
+	}
+
+	/*alloc device buffer*/
+	ptr_sddev->device = (struct rt_device*)rt_malloc(4 * sizeof(struct rt_device));
+	if(ptr_sddev->device == RT_NULL)
+	{
+		 EOUT("allocate device failed\n");
+		 err = RT_ENOMEM;
+		 goto FAIL1;
+	}
+
+	ptr_sddev->part_num = 0;
+
+	err = sd_readblock(0,ptr_sddev->sec_buf);
+
+	if(err != RT_EOK)
+	{
+		EOUT("Read block 0 to initialize ERROR\n");
+		goto FAIL1;
+	}
+
+	for(i=0; i<4; i++)
+	{
+		/* get the first partition */
+		err = dfs_filesystem_get_partition(&(ptr_sddev->part[i]), ptr_sddev->sec_buf, i);
+		if (err == RT_EOK)
+		{
+			rt_snprintf(dname, 4, "sd%d",  i);
+			rt_snprintf(sname, 8, "sem_sd%d",  i);
+			ptr_sddev->part[i].lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
+
+			/* register sdcard device */
+			ptr_sddev->device[i].init = rt_sdcard_init;
+			ptr_sddev->device[i].open = rt_sdcard_open;
+			ptr_sddev->device[i].close = rt_sdcard_close;
+			ptr_sddev->device[i].read = rt_sdcard_read;
+			ptr_sddev->device[i].write = rt_sdcard_write;
+			ptr_sddev->device[i].control = rt_sdcard_control;
+			ptr_sddev->device[i].user_data= &ptr_sddev->part[i];
+
+			err = rt_device_register(&ptr_sddev->device[i], dname,
+				RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+			if(err == RT_EOK)
+				ptr_sddev->part_num++;
+		}
+		else
+		{
+			if(i == 0)
+			{
+				/* there is no partition table */
+				ptr_sddev->part[0].offset = 0;
+				ptr_sddev->part[0].size   = 0;
+				ptr_sddev->part[0].lock = rt_sem_create("sem_sd0", 1, RT_IPC_FLAG_FIFO);
+
+				/* register sdcard device */
+				ptr_sddev->device[0].init = rt_sdcard_init;
+				ptr_sddev->device[0].open = rt_sdcard_open;
+				ptr_sddev->device[0].close = rt_sdcard_close;
+				ptr_sddev->device[0].read = rt_sdcard_read;
+				ptr_sddev->device[0].write = rt_sdcard_write;
+				ptr_sddev->device[0].control = rt_sdcard_control;
+				ptr_sddev->device[0].user_data= &ptr_sddev->part[0];
+
+				err = rt_device_register(&ptr_sddev->device[0], "sd0",
+					RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+				if(err == RT_EOK)
+					ptr_sddev->part_num++;
+
+				break;
+			}
+		}
+	}
+
+	if(ptr_sddev->part_num == 0)
+		goto FAIL0;
+	
+	return err;
+
+	FAIL0:
+	rt_free(ptr_sddev->device);
+	ptr_sddev->device = RT_NULL;
+
+	FAIL1:
+	rt_free(ptr_sddev->part);
+	ptr_sddev->part = RT_NULL;
+
+	FAIL2:
+	rt_free(ptr_sddev);
+	ptr_sddev = RT_NULL;
+
+	return err;
+
+
+}
+
+#endif

+ 51 - 0
bsp/mini4020/sdcard.h

@@ -0,0 +1,51 @@
+
+#ifndef __SDCARD_H
+#define __SDCARD_H
+
+#include <rtthread.h>
+
+#ifdef RT_USING_DFS
+ 
+#include  <sep4020.h>
+
+#define INICLK	300000
+#define SDCLK	24000000	//PCLK=49.392MHz
+#define MMCCLK	15000000	//PCLK=49.392MHz
+
+/*struct of the SDC*/
+struct 	sd_c
+{
+ 	__IO rt_uint32_t	clk_ctl;  		 
+ 	__IO rt_uint32_t	soft_rst;
+	__IO rt_uint32_t	arg;
+	__IO rt_uint32_t	cmd;
+	__IO rt_uint32_t	blk_sz;
+	__IO rt_uint32_t	blk_cnt;
+	__IO rt_uint32_t	trans_mode;
+	__O  rt_uint32_t	response0;
+	__O  rt_uint32_t	response1;
+	__O  rt_uint32_t	response2;
+	__O  rt_uint32_t	response3;
+	__IO rt_uint32_t	rd_to_ctl;
+	__IO rt_uint32_t	int_stat;
+	__IO rt_uint32_t	int_stat_mask;
+	__O  rt_uint32_t	rx_fifo;
+	__I  rt_uint32_t	tx_fifo;                
+};
+
+/*sdcard driver structure*/
+struct	sd_device
+{
+	struct rt_device		*device; 	/*rt_device*/
+	struct sd_c			*sdc;	 	/*SDCARD register*/
+	struct dfs_partition	*part;		/*dfs partitions*/
+	rt_uint8_t		*sec_buf;	/*sdcard buffer*/
+	rt_uint32_t		part_num;	/*partiont numbers*/
+	rt_uint32_t		buf_size;	/*buffer size*/
+};
+
+
+
+#endif
+#endif
+

+ 867 - 0
bsp/mini4020/sep4020.h

@@ -0,0 +1,867 @@
+#ifndef __SEP4020_H
+#define __SEP4020_H
+
+#include <rtthread.h>
+
+/*Core definations*/
+#define SVCMODE
+#define	Mode_USR	0x10
+#define	Mode_FIQ	0x11
+#define	Mode_IRQ	0x12
+#define	Mode_SVC	0x13
+#define	Mode_ABT	0x17
+#define	Mode_UND	0x1B
+#define	Mode_SYS	0x1F
+
+
+
+/*
+ *  各模块寄存器基值
+ */
+
+#define   ESRAM_BASE    0x04000000
+#define   INTC_BASE     0x10000000
+#define   PMU_BASE      0x10001000
+#define   RTC_BASE      0x10002000
+#define   WD_BASE       0x10002000
+#define   TIMER_BASE    0x10003000
+#define   PWM_BASE      0x10004000
+#define   UART0_BASE    0X10005000
+#define   UART1_BASE    0X10006000
+#define   UART2_BASE    0X10007000
+#define   UART3_BASE    0X10008000
+#define   SSI_BASE      0X10009000
+#define   I2S_BASE      0x1000A000
+#define   MMC_BASE      0x1000B000
+#define   SD_BASE       0x1000B000
+#define   SMC0_BASE     0x1000C000
+#define   SMC1_BASE     0x1000D000
+#define   USBD_BASE     0x1000E000
+#define   GPIO_BASE     0x1000F000
+#define   EMI_BASE      0x11000000
+#define   DMAC_BASE     0x11001000
+#define   LCDC_BASE     0x11002000
+#define   MAC_BASE      0x11003000
+#define   AMBA_BASE     0x11005000
+
+
+/*
+ *  INTC模块
+ *  基址: 0x10000000
+ */
+
+#define INTC_IER                  (INTC_BASE+0X000)       /* IRQ中断允许寄存器 */
+#define INTC_IMR                  (INTC_BASE+0X008)       /* IRQ中断屏蔽寄存器 */
+#define INTC_IFR                  (INTC_BASE+0X010)       /* IRQ软件强制中断寄存器 */
+#define INTC_IRSR                 (INTC_BASE+0X018)       /* IRQ未处理中断状态寄存器 */
+#define INTC_ISR                  (INTC_BASE+0X020)       /* IRQ中断状态寄存器 */
+#define INTC_IMSR                 (INTC_BASE+0X028)       /* IRQ屏蔽中断状态寄存器 */
+#define INTC_IFSR                 (INTC_BASE+0X030)       /* IRQ中断最终状态寄存器 */
+#define INTC_FIER                 (INTC_BASE+0X0C0)       /* FIQ中断允许寄存器 */
+#define INTC_FIMR                 (INTC_BASE+0X0C4)       /* FIQ中断屏蔽寄存器 */
+#define INTC_FIFR                 (INTC_BASE+0X0C8)       /* FIQ软件强制中断寄存器 */
+#define INTC_FIRSR                (INTC_BASE+0X0CC)       /* FIQ未处理中断状态寄存器 */
+#define INTC_FISR                 (INTC_BASE+0X0D0)       /* FIQ中断状态寄存器 */
+#define INTC_FIFSR                (INTC_BASE+0X0D4)       /* FIQ中断最终状态寄存器 */
+#define INTC_IPLR                 (INTC_BASE+0X0D8)       /* IRQ中断优先级寄存器 */
+#define INTC_ICR1                 (INTC_BASE+0X0DC)       /* IRQ内部中断优先级控制寄存器1 */
+#define INTC_ICR2                 (INTC_BASE+0X0E0)       /* IRQ内部中断优先级控制寄存器2 */
+#define INTC_EXICR1               (INTC_BASE+0X0E4)       /* IRQ外部中断优先级控制寄存器1 */
+#define INTC_EXICR2               (INTC_BASE+0X0E8)       /* IRQ外部中断优先级控制寄存器2 */
+
+
+/*
+ *  PMU模块
+ *  基址: 0x10001000
+ */
+
+#define PMU_PLTR                  (PMU_BASE+0X000)        /* PLL的稳定过渡时间 */
+#define PMU_PMCR                  (PMU_BASE+0X004)        /* 系统主时钟PLL的控制寄存器 */
+#define PMU_PUCR                  (PMU_BASE+0X008)        /* USB时钟PLL的控制寄存器 */
+#define PMU_PCSR                  (PMU_BASE+0X00C)        /* 内部模块时钟源供给的控制寄存器 */
+#define PMU_PDSLOW                (PMU_BASE+0X010)        /* SLOW状态下时钟的分频因子 */
+#define PMU_PMDR                  (PMU_BASE+0X014)        /* 芯片工作模式寄存器 */
+#define PMU_RCTR                  (PMU_BASE+0X018)        /* Reset控制寄存器 */
+#define PMU_CLRWAKUP              (PMU_BASE+0X01C)        /* WakeUp清除寄存器 */
+
+
+/*
+ *  RTC模块
+ *  基址: 0x10002000
+ */
+
+#define RTC_STA_YMD               (RTC_BASE+0X000)        /* 年, 月, 日计数寄存器 */
+#define RTC_STA_HMS               (RTC_BASE+0X004)        /* 小时, 分钟, 秒寄存器 */
+#define RTC_ALARM_ALL             (RTC_BASE+0X008)        /* 定时月, 日, 时, 分寄存器 */
+#define RTC_CTR                   (RTC_BASE+0X00C)        /* 控制寄存器 */
+#define RTC_INT_EN                (RTC_BASE+0X010)        /* 中断使能寄存器 */
+#define RTC_INT_STS               (RTC_BASE+0X014)        /* 中断状态寄存器 */
+#define RTC_SAMP                  (RTC_BASE+0X018)        /* 采样周期寄存器 */
+#define RTC_WD_CNT                (RTC_BASE+0X01C)        /* Watch-Dog计数值寄存器 */
+#define RTC_WD_SEV                (RTC_BASE+0X020)        /* Watch-Dog服务寄存器 */ 
+#define RTC_CONFIG_CHECK          (RTC_BASE+0X024)        /* 配置时间确认寄存器 (在配置时间之前先写0xaaaaaaaa) */
+#define RTC_KEY0                  (RTC_BASE+0X02C)        /* 密钥寄存器 */
+
+/*
+ *  TIMER模块
+ *  基址: 0x10003000
+ */
+
+#define TIMER_T1LCR               (TIMER_BASE+0X000)      /* 通道1加载计数寄存器 */
+#define TIMER_T1CCR               (TIMER_BASE+0X004)      /* 通道1当前计数值寄存器 */
+#define TIMER_T1CR                (TIMER_BASE+0X008)      /* 通道1控制寄存器 */
+#define TIMER_T1ISCR              (TIMER_BASE+0X00C)      /* 通道1中断状态清除寄存器 */
+#define TIMER_T1IMSR              (TIMER_BASE+0X010)      /* 通道1中断屏蔽状态寄存器 */
+#define TIMER_T2LCR               (TIMER_BASE+0X020)      /* 通道2加载计数寄存器 */
+#define TIMER_T2CCR               (TIMER_BASE+0X024)      /* 通道2当前计数值寄存器 */
+#define TIMER_T2CR                (TIMER_BASE+0X028)      /* 通道2控制寄存器 */
+#define TIMER_T2ISCR              (TIMER_BASE+0X02C)      /* 通道2中断状态清除寄存器 */
+#define TIMER_T2IMSR              (TIMER_BASE+0X030)      /* 通道2中断屏蔽状态寄存器 */
+#define TIMER_T3LCR               (TIMER_BASE+0X040)      /* 通道3加载计数寄存器 */
+#define TIMER_T3CCR               (TIMER_BASE+0X044)      /* 通道3当前计数值寄存器 */
+#define TIMER_T3CR                (TIMER_BASE+0X048)      /* 通道3控制寄存器 */
+#define TIMER_T3ISCR              (TIMER_BASE+0X04C)      /* 通道3中断状态清除寄存器 */
+#define TIMER_T3IMSR              (TIMER_BASE+0X050)      /* 通道3中断屏蔽状态寄存器 */
+#define TIMER_T3CAPR              (TIMER_BASE+0X054)      /* 通道3捕获寄存器 */
+#define TIMER_T4LCR               (TIMER_BASE+0X060)      /* 通道4加载计数寄存器 */
+#define TIMER_T4CCR               (TIMER_BASE+0X064)      /* 通道4当前计数值寄存器 */
+#define TIMER_T4CR                (TIMER_BASE+0X068)      /* 通道4控制寄存器 */
+#define TIMER_T4ISCR              (TIMER_BASE+0X06C)      /* 通道4中断状态清除寄存器 */
+#define TIMER_T4IMSR              (TIMER_BASE+0X070)      /* 通道4中断屏蔽状态寄存器 */
+#define TIMER_T4CAPR              (TIMER_BASE+0X074)      /* 通道4捕获寄存器 */
+#define TIMER_T5LCR               (TIMER_BASE+0X080)      /* 通道5加载计数寄存器 */
+#define TIMER_T5CCR               (TIMER_BASE+0X084)      /* 通道5当前计数值寄存器 */
+#define TIMER_T5CR                (TIMER_BASE+0X088)      /* 通道5控制寄存器 */
+#define TIMER_T5ISCR              (TIMER_BASE+0X08C)      /* 通道5中断状态清除寄存器 */
+#define TIMER_T5IMSR              (TIMER_BASE+0X090)      /* 通道5中断屏蔽状态寄存器 */
+#define TIMER_T5CAPR              (TIMER_BASE+0X094)      /* 通道5捕获寄存器 */
+#define TIMER_T6LCR               (TIMER_BASE+0X0A0)      /* 通道6加载计数寄存器 */
+#define TIMER_T6CCR               (TIMER_BASE+0X0A4)      /* 通道6当前计数值寄存器 */
+#define TIMER_T6CR                (TIMER_BASE+0X0A8)      /* 通道6控制寄存器 */
+#define TIMER_T6ISCR              (TIMER_BASE+0X0AC)      /* 通道6中断状态清除寄存器 */
+#define TIMER_T6IMSR              (TIMER_BASE+0X0B0)      /* 通道6中断屏蔽状态寄存器 */
+#define TIMER_T6CAPR              (TIMER_BASE+0X0B4)      /* 通道6捕获寄存器 */
+#define TIMER_T7LCR               (TIMER_BASE+0X0C0)      /* 通道7加载计数寄存器 */
+#define TIMER_T7CCR               (TIMER_BASE+0X0C4)      /* 通道7当前计数值寄存器 */
+#define TIMER_T7CR                (TIMER_BASE+0X0C8)      /* 通道7控制寄存器 */
+#define TIMER_T7ISCR              (TIMER_BASE+0X0CC)      /* 通道7中断状态清除寄存器 */
+#define TIMER_T7IMSR              (TIMER_BASE+0X0D0)      /* 通道7中断屏蔽状态寄存器 */
+#define TIMER_T8LCR               (TIMER_BASE+0X0E0)      /* 通道8加载计数寄存器 */
+#define TIMER_T8CCR               (TIMER_BASE+0X0E4)      /* 通道8当前计数值寄存器 */
+#define TIMER_T8CR                (TIMER_BASE+0X0E8)      /* 通道8控制寄存器 */
+#define TIMER_T8ISCR              (TIMER_BASE+0X0EC)      /* 通道8中断状态清除寄存器 */
+#define TIMER_T8IMSR              (TIMER_BASE+0X0F0)      /* 通道8中断屏蔽状态寄存器 */
+#define TIMER_T9LCR               (TIMER_BASE+0X100)      /* 通道9加载计数寄存器 */
+#define TIMER_T9CCR               (TIMER_BASE+0X104)      /* 通道9当前计数值寄存器 */
+#define TIMER_T9CR                (TIMER_BASE+0X108)      /* 通道9控制寄存器 */
+#define TIMER_T9ISCR              (TIMER_BASE+0X10C)      /* 通道9中断状态清除寄存器 */
+#define TIMER_T9IMSR              (TIMER_BASE+0X110)      /* 通道9中断屏蔽状态寄存器 */
+#define TIMER_T10LCR              (TIMER_BASE+0X120)      /* 通道10加载计数寄存器 */
+#define TIMER_T10CCR              (TIMER_BASE+0X124)      /* 通道10当前计数值寄存器 */
+#define TIMER_T10CR               (TIMER_BASE+0X128)      /* 通道10控制寄存器 */
+#define TIMER_T10ISCR             (TIMER_BASE+0X12C)      /* 通道10中断状态清除寄存器 */
+#define TIMER_T10IMSR             (TIMER_BASE+0X130)      /* 通道10中断屏蔽状态寄存器 */
+#define TIMER_TIMSR               (TIMER_BASE+0X140)      /* TIMER中断屏蔽状态寄存器 */
+#define TIMER_TISCR               (TIMER_BASE+0X144)      /* TIMER中断状态清除寄存器 */
+#define TIMER_TISR                (TIMER_BASE+0X148)      /* TIMER中断状态寄存器 */
+
+
+
+/*
+ *  PWM模块
+ *  基址: 0x10004000
+ */
+
+#define PWM0_CTRL                 (PWM_BASE+0X000)        /* PWM0控制寄存器 */
+#define PWM0_DIV                  (PWM_BASE+0X004)        /* PWM0分频寄存器 */
+#define PWM0_PERIOD               (PWM_BASE+0X008)        /* PWM0周期寄存器 */
+#define PWM0_DATA                 (PWM_BASE+0X00C)        /* PWM0数据寄存器 */
+#define PWM0_CNT                  (PWM_BASE+0X010)        /* PWM0计数寄存器 */
+#define PWM0_STATUS               (PWM_BASE+0X014)        /* PWM0状态寄存器 */
+#define PWM1_CTRL                 (PWM_BASE+0X020)        /* PWM1控制寄存器 */
+#define PWM1_DIV                  (PWM_BASE+0X024)        /* PWM1分频寄存器 */
+#define PWM1_PERIOD               (PWM_BASE+0X028)        /* PWM1周期寄存器 */
+#define PWM1_DATA                 (PWM_BASE+0X02C)        /* PWM1数据寄存器 */
+#define PWM1_CNT                  (PWM_BASE+0X030)        /* PWM1计数寄存器 */
+#define PWM1_STATUS               (PWM_BASE+0X034)        /* PWM1状态寄存器 */
+#define PWM2_CTRL                 (PWM_BASE+0X040)        /* PWM2控制寄存器 */
+#define PWM2_DIV                  (PWM_BASE+0X044)        /* PWM2分频寄存器 */
+#define PWM2_PERIOD               (PWM_BASE+0X048)        /* PWM2周期寄存器 */
+#define PWM2_DATA                 (PWM_BASE+0X04C)        /* PWM2数据寄存器 */
+#define PWM2_CNT                  (PWM_BASE+0X050)        /* PWM2计数寄存器 */
+#define PWM2_STATUS               (PWM_BASE+0X054)        /* PWM2状态寄存器 */
+#define PWM3_CTRL                 (PWM_BASE+0X060)        /* PWM3控制寄存器 */
+#define PWM3_DIV                  (PWM_BASE+0X064)        /* PWM3分频寄存器 */
+#define PWM3_PERIOD               (PWM_BASE+0X068)        /* PWM3周期寄存器 */
+#define PWM3_DATA                 (PWM_BASE+0X06C)        /* PWM3数据寄存器 */
+#define PWM3_CNT                  (PWM_BASE+0X070)        /* PWM3计数寄存器 */
+#define PWM3_STATUS               (PWM_BASE+0X074)        /* PWM3状态寄存器 */
+#define PWM_INTMASK               (PWM_BASE+0X080)        /* PWM中断屏蔽寄存器 */
+#define PWM_INT                   (PWM_BASE+0X084)        /* PWM中断寄存器 */
+#define PWM_ENABLE                (PWM_BASE+0X088)        /* PWM使能寄存器 */
+
+
+/*
+ *  UART0模块
+ *  基址: 0x10005000
+ */
+
+#define UART0_DLBL                (UART0_BASE+0X000)      /* 波特率设置低八位寄存器 */
+#define UART0_RXFIFO              (UART0_BASE+0X000)      /* 接收FIFO */
+#define UART0_TXFIFO              (UART0_BASE+0X000)      /* 发送FIFO */
+#define UART0_DLBH                (UART0_BASE+0X004)      /* 波特率设置高八位寄存器 */
+#define UART0_IER                 (UART0_BASE+0X004)      /* 中断使能寄存器 */
+#define UART0_IIR                 (UART0_BASE+0X008)      /* 中断识别寄存器 */
+#define UART0_FCR                 (UART0_BASE+0X008)      /* FIFO控制寄存器 */
+#define UART0_LCR                 (UART0_BASE+0X00C)      /* 行控制寄存器 */
+#define UART0_MCR                 (UART0_BASE+0X010)      /* Modem控制寄存器 */
+#define UART0_LSR                 (UART0_BASE+0X014)      /* 行状态寄存器 */
+#define UART0_MSR                 (UART0_BASE+0X018)      /* Modem状态寄存器 */
+
+
+/*
+ *  UART1模块
+ *  基址: 0x10006000
+ */
+
+#define UART1_DLBL                (UART1_BASE+0X000)      /* 波特率设置低八位寄存器 */
+#define UART1_RXFIFO              (UART1_BASE+0X000)      /* 接收FIFO */
+#define UART1_TXFIFO              (UART1_BASE+0X000)      /* 发送FIFO */
+#define UART1_DLBH                (UART1_BASE+0X004)      /* 波特率设置高八位寄存器 */
+#define UART1_IER                 (UART1_BASE+0X004)      /* 中断使能寄存器 */
+#define UART1_IIR                 (UART1_BASE+0X008)      /* 中断识别寄存器 */
+#define UART1_FCR                 (UART1_BASE+0X008)      /* FIFO控制寄存器 */
+#define UART1_LCR                 (UART1_BASE+0X00C)      /* 行控制寄存器 */
+#define UART1_MCR                 (UART1_BASE+0X010)      /* Modem控制寄存器 */
+#define UART1_LSR                 (UART1_BASE+0X014)      /* 行状态寄存器 */
+#define UART1_MSR                 (UART1_BASE+0X018)      /* Modem状态寄存器 */
+
+
+/*
+ *  UART2模块
+ *  基址: 0x10007000
+ */
+
+#define UART2_DLBL                (UART2_BASE+0X000)      /* 波特率设置低八位寄存器 */
+#define UART2_RXFIFO              (UART2_BASE+0X000)      /* 接收FIFO */
+#define UART2_TXFIFO              (UART2_BASE+0X000)      /* 发送FIFO */
+#define UART2_DLBH                (UART2_BASE+0X004)      /* 波特率设置高八位寄存器 */
+#define UART2_IER                 (UART2_BASE+0X004)      /* 中断使能寄存器 */
+#define UART2_IIR                 (UART2_BASE+0X008)      /* 中断识别寄存器 */
+#define UART2_FCR                 (UART2_BASE+0X008)      /* FIFO控制寄存器 */
+#define UART2_LCR                 (UART2_BASE+0X00C)      /* 行控制寄存器 */
+#define UART2_MCR                 (UART2_BASE+0X010)      /* Modem控制寄存器 */
+#define UART2_LSR                 (UART2_BASE+0X014)      /* 行状态寄存器 */
+#define UART2_MSR                 (UART2_BASE+0X018)      /* Modem状态寄存器 */
+
+
+/*
+ *  UART3模块
+ *  基址: 0x10008000
+ */
+
+#define UART3_DLBL                (UART3_BASE+0X000)      /* 波特率设置低八位寄存器 */
+#define UART3_RXFIFO              (UART3_BASE+0X000)      /* 接收FIFO */
+#define UART3_TXFIFO              (UART3_BASE+0X000)      /* 发送FIFO */
+#define UART3_DLBH                (UART3_BASE+0X004)      /* 波特率设置高八位寄存器 */
+#define UART3_IER                 (UART3_BASE+0X004)      /* 中断使能寄存器 */
+#define UART3_IIR                 (UART3_BASE+0X008)      /* 中断识别寄存器 */
+#define UART3_FCR                 (UART3_BASE+0X008)      /* FIFO控制寄存器 */
+#define UART3_LCR                 (UART3_BASE+0X00C)      /* 行控制寄存器 */
+#define UART3_MCR                 (UART3_BASE+0X010)      /* Modem控制寄存器 */
+#define UART3_LSR                 (UART3_BASE+0X014)      /* 行状态寄存器 */
+#define UART3_MSR                 (UART3_BASE+0X018)      /* Modem状态寄存器 */
+
+
+/*
+ *  SSI模块
+ *  基址: 0x10009000
+ */
+
+#define SSI_CONTROL0              (SSI_BASE+0X000)        /* 控制寄存器0 */
+#define SSI_CONTROL1              (SSI_BASE+0X004)        /* 控制寄存器1 */
+#define SSI_SSIENR                (SSI_BASE+0X008)        /* SSI使能寄存器 */
+#define SSI_MWCR                  (SSI_BASE+0X00C)        /* Microwire控制寄存器 */
+#define SSI_SER                   (SSI_BASE+0X010)        /* 从设备使能寄存器 */
+#define SSI_BAUDR                 (SSI_BASE+0X014)        /* 波特率设置寄存器 */
+#define SSI_TXFTLR                (SSI_BASE+0X018)        /* 发送FIFO阈值寄存器 */
+#define SSI_RXFTLR                (SSI_BASE+0X01C)        /* 接收FIFO阈值寄存器 */
+#define SSI_TXFLR                 (SSI_BASE+0X020)        /* 发送FIFO状态寄存器 */
+#define SSI_RXFLR                 (SSI_BASE+0X024)        /* 接收FIFO状态寄存器 */
+#define SSI_SR                    (SSI_BASE+0X028)        /* 状态寄存器 */
+#define SSI_IMR                   (SSI_BASE+0X02C)        /* 中断屏蔽寄存器 */
+#define SSI_ISR                   (SSI_BASE+0X030)        /* 中断最终状态寄存器 */
+#define SSI_RISR                  (SSI_BASE+0X034)        /* 中断原始状态寄存器 */
+#define SSI_TXOICR                (SSI_BASE+0X038)        /* 发送FIFO上溢中断清除寄存器 */
+#define SSI_RXOICR                (SSI_BASE+0X03C)        /* 接收FIFO上溢中断清除寄存器 */
+#define SSI_RXUICR                (SSI_BASE+0X040)        /* 接收FIFO下溢中断清除寄存器 */
+#define SSI_ICR                   (SSI_BASE+0X02C)        /* 中断清除寄存器 */
+#define SSI_DMACR                 (SSI_BASE+0X04C)        /* DMA控制寄存器 */
+#define SSI_DMATDLR               (SSI_BASE+0X050)        /* DMA发送状态寄存器 */
+#define SSI_DMARDLR               (SSI_BASE+0X054)        /* DMA接收状态寄存器 */
+#define SSI_DR                    (SSI_BASE+0X060)        /* 数据寄存器 */
+
+
+/*
+ *  I2S模块
+ *  基址: 0x1000A000
+ */
+
+#define I2S_CTRL                  (I2S_BASE+0X000)        /* I2S控制寄存器 */
+#define I2S_DATA                  (I2S_BASE+0X004)        /* I2S数据寄存器 */
+#define I2S_INT                   (I2S_BASE+0X008)        /* I2S中断寄存器 */
+#define I2S_STATUS                (I2S_BASE+0X00C)        /* I2S状态寄存器 */
+
+
+/*
+ *  SD模块
+ *  基址: 0x1000B000
+ */
+ 
+#define SDC_CLOCK_CONTROL  		  (SD_BASE+0x00)          /* SDIO时钟控制寄存器 */
+#define SDC_SOFTWARE_RESET 		  (SD_BASE+0X04)          /* SDIO软件复位寄存器 */
+#define SDC_ARGUMENT     		  (SD_BASE+0X08)          /* SDIO命令参数寄存器 */
+#define SDC_COMMAND       	      (SD_BASE+0X0C)          /* SDIO命令控制寄存器 */
+#define SDC_BLOCK_SIZE            (SD_BASE+0X10)          /* SDIO数据块长度寄存器 */
+#define SDC_BLOCK_COUNT    		  (SD_BASE+0X14)          /* SDIO数据块数目寄存器 */
+#define SDC_TRANSFER_MODE  		  (SD_BASE+0X18)          /* SDIO传输模式选择寄存器 */
+#define SDC_RESPONSE0    		  (SD_BASE+0X1c)          /* SDIO响应寄存器0 */
+#define SDC_RESPONSE1    		  (SD_BASE+0X20)          /* SDIO响应寄存器1 */
+#define SDC_RESPONSE2    		  (SD_BASE+0X24)          /* SDIO响应寄存器2 */
+#define SDC_RESPONSE3    		  (SD_BASE+0X28)          /* SDIO响应寄存器3 */
+#define SDC_READ_TIMEOUT_CONTROL  (SD_BASE+0X2c)          /* SDIO读超时控制寄存器 */
+#define SDC_INTERRUPT_STATUS      (SD_BASE+0X30)          /* SDIO中断状态寄存器 */
+#define SDC_INTERRUPT_STATUS_MASK (SD_BASE+0X34)          /* SDIO中断状态屏蔽寄存器 */
+#define SDC_READ_BUFER_ACCESS     (SD_BASE+0X38)          /* SDIO接收FIFO */
+#define SDC_WRITE_BUFER_ACCESS    (SD_BASE+0X3c)          /* SDIO发送FIFO */
+
+
+
+/*
+ *  SMC0模块
+ *  基址: 0x1000C000
+ */
+
+#define SMC0_CTRL                 (SMC0_BASE+0X000)       /* SMC0控制寄存器 */
+#define SMC0_INT                  (SMC0_BASE+0X004)       /* SMC0中断寄存器 */
+#define SMC0_FD                   (SMC0_BASE+0X008)       /* SMC0基本单元时间寄存器 */
+#define SMC0_CT                   (SMC0_BASE+0X00C)       /* SMC0字符传输时间寄存器 */
+#define SMC0_BT                   (SMC0_BASE+0X010)       /* SMC0块传输时间寄存器 */
+
+
+
+/*
+ *  SMC1模块
+ *  基址: 0x1000D000
+ */
+
+#define SMC1_CTRL                 (SMC1_BASE+0X000)       /* SMC1控制寄存器 */
+#define SMC1_INT                  (SMC1_BASE+0X004)       /* SMC1中断寄存器 */
+#define SMC1_FD                   (SMC1_BASE+0X008)       /* SMC1基本单元时间寄存器 */
+#define SMC1_CT                   (SMC1_BASE+0X00C)       /* SMC1字符传输时间寄存器 */
+#define SMC1_BT                   (SMC1_BASE+0X010)       /* SMC1块传输时间寄存器 */
+
+
+
+/*
+ *  USBD模块
+ *  基址: 0x1000E000
+ */
+
+#define USBD_PROTOCOLINTR         (USBD_BASE+0X000)       /* USB协议中断寄存器 */
+#define USBD_INTRMASK             (USBD_BASE+0X004)       /* USB中断屏蔽寄存器 */
+#define USBD_INTRCTRL             (USBD_BASE+0X008)       /* USB中断类型控制寄存器 */
+#define USBD_EPINFO               (USBD_BASE+0X00C)       /* USB活动端点状态寄存器 */
+#define USBD_BCONFIGURATIONVALUE  (USBD_BASE+0X010)       /* SET_CCONFIGURATION记录 */
+#define USBD_BMATTRIBUTES         (USBD_BASE+0X014)       /* 当前配置属性寄存器 */
+#define USBD_DEVSPEED             (USBD_BASE+0X018)       /* 当前设备工作速度寄存器 */
+#define USBD_FRAMENUMBER          (USBD_BASE+0X01C)       /* 记录当前SOF包内的帧号 */
+#define USBD_EPTRANSACTIONS0      (USBD_BASE+0X020)       /* 记录下次要求的传输次数 */
+#define USBD_EPTRANSACTIONS1      (USBD_BASE+0X024)       /* 记录下次要求的传输次数 */
+#define USBD_APPIFUPDATE          (USBD_BASE+0X028)       /* 接口号快速更新寄存器 */
+#define USBD_CFGINTERFACE0        (USBD_BASE+0X02C)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE1        (USBD_BASE+0X030)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE2        (USBD_BASE+0X034)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE3        (USBD_BASE+0X038)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE4        (USBD_BASE+0X03C)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE5        (USBD_BASE+0X040)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE6        (USBD_BASE+0X044)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE7        (USBD_BASE+0X048)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE8        (USBD_BASE+0X04C)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE9        (USBD_BASE+0X050)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE10       (USBD_BASE+0X054)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE11       (USBD_BASE+0X058)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE12       (USBD_BASE+0X05C)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE13       (USBD_BASE+0X060)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE14       (USBD_BASE+0X064)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE15       (USBD_BASE+0X068)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE16       (USBD_BASE+0X06C)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE17       (USBD_BASE+0X070)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE18       (USBD_BASE+0X074)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE19       (USBD_BASE+0X078)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE20       (USBD_BASE+0X07C)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE21       (USBD_BASE+0X080)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE22       (USBD_BASE+0X084)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE23       (USBD_BASE+0X088)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE24       (USBD_BASE+0X08C)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE25       (USBD_BASE+0X090)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE26       (USBD_BASE+0X094)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE27       (USBD_BASE+0X098)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE28       (USBD_BASE+0X09C)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE29       (USBD_BASE+0X0A0)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE30       (USBD_BASE+0X0A4)       /* 记录接口的值 */
+#define USBD_CFGINTERFACE31       (USBD_BASE+0X0A8)       /* 记录接口的值 */
+#define USBD_PKTPASSEDCTRL        (USBD_BASE+0X0AC)       /* 记录成功接收的包数 */
+#define USBD_PKTDROPPEDCTRL       (USBD_BASE+0X0B0)       /* 记录丢失的包数 */
+#define USBD_CRCERRCTRL           (USBD_BASE+0X0B4)       /* 记录CRC错误的包数 */
+#define USBD_BITSTUFFERRCTRL      (USBD_BASE+0X0B8)       /* 记录位填充错误的包数 */
+#define USBD_PIDERRCTRL           (USBD_BASE+0X0BC)       /* 记录PID错误的包数 */
+#define USBD_FRAMINGERRCTL        (USBD_BASE+0X0C0)       /* 记录有SYNC和EOP的包数 */
+#define USBD_TXPKTCTRL            (USBD_BASE+0X0C4)       /* 记录发送包的数量 */
+#define USBD_STATCTRLOV           (USBD_BASE+0X0C8)       /* 记录统计寄存器溢出情况 */
+#define USBD_TXLENGTH             (USBD_BASE+0X0CC)       /* 记录每次IN传输事务包长度 */
+#define USBD_RXLENGTH             (USBD_BASE+0X0D0)       /* 记录OUT传输事务包长度 */
+#define USBD_RESUME               (USBD_BASE+0X0D4)       /* USB唤醒寄存器 */
+#define USBD_READFLAG             (USBD_BASE+0X0D8)       /* 读异步状态寄存器标志 */
+#define USBD_RECEIVETYPE          (USBD_BASE+0X0DC)       /* 传输状态寄存器 */
+#define USBD_APPLOCK              (USBD_BASE+0X0E0)       /* 锁信号寄存器 */
+#define USBD_EP0OUTADDR           (USBD_BASE+0X100)       /* 端点0端点号和方向 */
+#define USBD_EP0OUTBMATTR         (USBD_BASE+0X104)       /* 端点0类型寄存器 */
+#define USBD_EP0OUTMAXPKTSIZE     (USBD_BASE+0X108)       /* 端点0最大包尺寸寄存器 */
+#define USBD_EP0OUTIFNUM          (USBD_BASE+0X10C)       /* 端点0接口号寄存器 */
+#define USBD_EP0OUTSTAT           (USBD_BASE+0X110)       /* 端点0状态寄存器 */
+#define USBD_EP0OUTBMREQTYPE      (USBD_BASE+0X114)       /* 端点0 SETUP事务请求类 */
+#define USBD_EP0OUTBREQUEST       (USBD_BASE+0X118)       /* 端点0 SETUP事务请求内容 */
+#define USBD_EP0OUTWVALUE         (USBD_BASE+0X11C)       /* 端点0 SETUP事务请求值 */
+#define USBD_EP0OUTWINDEX         (USBD_BASE+0X120)       /* 端点0 SETUP事务请求索引 */
+#define USBD_EP0OUTWLENGTH        (USBD_BASE+0X120)       /* 端点0 SETUP事务请求长度 */
+#define USBD_EP0OUTSYNCHFRAME     (USBD_BASE+0X128)       /* 端点0同步包帧号 */
+#define USBD_EP1OUTADDR           (USBD_BASE+0X12C)       /* 端点1输出端点号和方向 */
+#define USBD_EP1OUTBMATTR         (USBD_BASE+0X130)       /* 端点1输出类型寄存器 */
+#define USBD_EP1OUTMAXPKTSIZE     (USBD_BASE+0X134)       /* 端点1输出最大包尺寸寄存器 */
+#define USBD_EP1OUTIFNUM          (USBD_BASE+0X138)       /* 端点1输出接口号寄存器 */
+#define USBD_EP1OUTSTAT           (USBD_BASE+0X13C)       /* 端点1输出状态寄存器 */
+#define USBD_EP1OUTBMREQTYPE      (USBD_BASE+0X140)       /* 端点1输出SETUP事务请求类型 */
+#define USBD_EP1OUTBREQUEST       (USBD_BASE+0X144)       /* 端点1输出SETUP事务请求内容 */
+#define USBD_EP1OUTWVALUE         (USBD_BASE+0X148)       /* 端点1输出SETUP事务请求值 */
+#define USBD_EP1OUTWINDX          (USBD_BASE+0X14C)       /* 端点1输出SETUP事务请求索引 */
+#define USBD_EP1OUTWLENGH         (USBD_BASE+0X150)       /* 端点1输出SETUP事务请求域长度 */
+#define USBD_EP1OUTSYNCHFRAME     (USBD_BASE+0X154)       /* 端点1输出同步包帧号 */
+#define USBD_EP1INADDR            (USBD_BASE+0X158)       /* 端点1输入端点号和方向 */
+#define USBD_EP1INBMATTR          (USBD_BASE+0X15C)       /* 端点1输入类型寄存器 */
+#define USBD_EP1INMAXPKTSIZE      (USBD_BASE+0X160)       /* 端点1输入最大包尺寸寄存器 */
+#define USBD_EP1INIFNUM           (USBD_BASE+0X164)       /* 端点1输入接口号寄存器 */
+#define USBD_EP1INSTAT            (USBD_BASE+0X168)       /* 端点1输入状态寄存器 */
+#define USBD_EP1INBMREQTYPE       (USBD_BASE+0X16C)       /* 端点1输入SETUP事务请求类型 */
+#define USBD_EP1INBREQUEST        (USBD_BASE+0X170)       /* 端点1输入SETUP事务请求内容 */
+#define USBD_EP1INWVALUE          (USBD_BASE+0X174)       /* 端点1输入SETUP事务请求值 */
+#define USBD_EP1INWINDEX          (USBD_BASE+0X178)       /* 端点1输入SETUP事务请求索引 */
+#define USBD_EP1INWLENGTH         (USBD_BASE+0X17C)       /* 端点1输入SETUP事务请求域长度 */
+#define USBD_EP1INSYNCHFRAME      (USBD_BASE+0X180)       /* 端点1输入同步包帧号 */
+#define USBD_EP2OUTADDR           (USBD_BASE+0X184)       /* 端点2输出端点号和方向 */
+#define USBD_EP2OUTBMATTR         (USBD_BASE+0X188)       /* 端点2输出类型寄存器 */
+#define USBD_EP2OUTMAXPKTSIZE     (USBD_BASE+0X18C)       /* 端点2输出最大包尺寸寄存器 */
+#define USBD_EP2OUTIFNUM          (USBD_BASE+0X190)       /* 端点2输出接口号寄存器 */
+#define USBD_EP2OUTSTAT           (USBD_BASE+0X194)       /* 端点2输出状态寄存器 */
+#define USBD_EP2OUTBMREQTYPE      (USBD_BASE+0X198)       /* 端点2输出SETUP事务请求类型 */
+#define USBD_EP2OUTBREQUEST       (USBD_BASE+0X19C)       /* 端点2输出SETUP事务请求内容 */
+#define USBD_EP2OUTWVALUE         (USBD_BASE+0X1A0)       /* 端点2输出SETUP事务请求值 */
+#define USBD_EP2OUTWINDEX         (USBD_BASE+0X1A4)       /* 端点2输出SETUP事务请求索引 */
+#define USBD_EP2OUTWLENGTH        (USBD_BASE+0X1A8)       /* 端点2输出SETUP事务请求域长度 */
+#define USBD_EP2OUTSYNCHFRAME     (USBD_BASE+0X1AC)       /* 端点2输出同步包帧号 */
+#define USBD_EP2INADDR            (USBD_BASE+0X1B0)       /* 端点2输入端点号和方向 */
+#define USBD_EP2INBMATTR          (USBD_BASE+0X1B4)       /* 端点2输入类型寄存器 */
+#define USBD_EP2INMAXPKTSIZE      (USBD_BASE+0X1B8)       /* 端点2输入最大包尺寸寄存器 */
+#define USBD_EP2INIFNUM           (USBD_BASE+0X1BC)       /* 端点2输入接口号寄存器 */
+#define USBD_EP2INSTAT            (USBD_BASE+0X1C0)       /* 端点2输入状态寄存器 */
+#define USBD_EP2INBMREQTYPE       (USBD_BASE+0X1C4)       /* 端点2输入SETUP事务请求类型 */
+#define USBD_EP2INBREQUEST        (USBD_BASE+0X1C8)       /* 端点2输入SETUP事务请求内容 */
+#define USBD_EP2INWVALUE          (USBD_BASE+0X1CC)       /* 端点2输入SETUP事务请求值 */
+#define USBD_EP2INWINDEX          (USBD_BASE+0X1D0)       /* 端点2输入SETUP事务请求索引 */
+#define USBD_EP2INWLENGTH         (USBD_BASE+0X1D4)       /* 端点2输入SETUP事务请求域长度 */
+#define USBD_EP2INSYNCHFRAME      (USBD_BASE+0X1D8)       /* 端点2输入同步包帧号 */
+#define USBD_RXFIFO               (USBD_BASE+0X200)       /* 接受FIFO */
+#define USBD_TXFIFO               (USBD_BASE+0X300)       /* 发送FIFO */
+
+
+/*
+ *  GPIO模块
+ *  基址: 0x1000F000
+ */
+
+#define GPIO_DBCLK_DIV            (GPIO_BASE+0X000)       /* 去毛刺采用时钟分频比配置寄存器 */
+#define GPIO_PORTA_DIR            (GPIO_BASE+0X004)       /* A组端口输入输出方向配置寄存器 */
+#define GPIO_PORTA_SEL            (GPIO_BASE+0X008)       /* A组端口通用用途选择配置寄存器 */
+#define GPIO_PORTA_INCTL          (GPIO_BASE+0X00C)       /* A组端口通用用途输入时类型配置寄存器 */
+#define GPIO_PORTA_INTRCTL        (GPIO_BASE+0X010)       /* A组端口中断触发类型配置寄存器 */
+#define GPIO_PORTA_INTRCLR        (GPIO_BASE+0X014)       /* A组端口通用用途中断清除配置寄存器 */
+#define GPIO_PORTA_DATA           (GPIO_BASE+0X018)       /* A组端口通用用途数据配置寄存器 */
+#define GPIO_PORTB_DIR            (GPIO_BASE+0X01C)       /* B组端口输入输出方向配置寄存器 */
+#define GPIO_PORTB_SEL            (GPIO_BASE+0X020)       /* B组端口通用用途选择配置寄存器 */
+#define GPIO_PORTB_DATA           (GPIO_BASE+0X024)       /* B组端口通用用途数据配置寄存器 */
+#define GPIO_PORTC_DIR            (GPIO_BASE+0X028)       /* C组端口输入输出方向配置寄存器 */
+#define GPIO_PORTC_SEL            (GPIO_BASE+0X02C)       /* C组端口通用用途选择配置寄存器 */
+#define GPIO_PORTC_DATA           (GPIO_BASE+0X030)       /* C组端口通用用途数据配置寄存器 */
+#define GPIO_PORTD_DIR            (GPIO_BASE+0X034)       /* D组端口输入输出方向配置寄存器 */
+#define GPIO_PORTD_SEL            (GPIO_BASE+0X038)       /* D组端口通用用途选择配置寄存器 */
+#define GPIO_PORTD_SPECII         (GPIO_BASE+0X03C)       /* D组端口专用用途2选择配置寄存器 */
+#define GPIO_PORTD_DATA           (GPIO_BASE+0X040)       /* D组端口通用用途数据配置寄存器 */
+#define GPIO_PORTE_DIR            (GPIO_BASE+0X044)       /* E组端口输入输出方向配置寄存器 */
+#define GPIO_PORTE_SEL            (GPIO_BASE+0X048)       /* E组端口通用用途选择配置寄存器 */
+#define GPIO_PORTE_DATA           (GPIO_BASE+0X04C)       /* E组端口通用用途数据配置寄存器 */
+#define GPIO_PORTF_DIR            (GPIO_BASE+0X050)       /* F组端口输入输出方向配置寄存器 */
+#define GPIO_PORTF_SEL            (GPIO_BASE+0X054)       /* F组端口通用用途选择配置寄存器 */
+#define GPIO_PORTF_INCTL          (GPIO_BASE+0X058)       /* F组端口通用用途输入时类型配置寄存器 */
+#define GPIO_PORTF_INTRCTL        (GPIO_BASE+0X05C)       /* F组端口中断触发类型配置寄存器 */
+#define GPIO_PORTF_INTRCLR        (GPIO_BASE+0X060)       /* F组端口通用用途中断清除配置寄存器 */
+#define GPIO_PORTF_DATA           (GPIO_BASE+0X064)       /* F组端口通用用途数据配置寄存器 */
+#define GPIO_PORTG_DIR            (GPIO_BASE+0X068)       /* G组端口输入输出方向配置寄存器 */
+#define GPIO_PORTG_SEL            (GPIO_BASE+0X06C)       /* G组端口通用用途选择配置寄存器 */
+#define GPIO_PORTG_DATA           (GPIO_BASE+0X070)       /* G组端口通用用途数据配置寄存器 */
+#define GPIO_PORTH_DIR            (GPIO_BASE+0X07C)       /* H组端口输入输出方向配置寄存器 */
+#define GPIO_PORTH_SEL            (GPIO_BASE+0X078)       /* H组端口通用用途选择配置寄存器 */
+#define GPIO_PORTH_DATA           (GPIO_BASE+0X07C)       /* H组端口通用用途数据配置寄存器 */
+#define GPIO_PORTI_DIR            (GPIO_BASE+0X080)       /* I组端口输入输出方向配置寄存器 */
+#define GPIO_PORTI_SEL            (GPIO_BASE+0X084)       /* I组端口通用用途选择配置寄存器 */
+#define GPIO_PORTI_DATA           (GPIO_BASE+0X088)       /* I组端口通用用途数据配置寄存器 */
+
+
+
+/*
+ *  EMI模块
+ *  基址: 0x11000000
+ */
+
+#define EMI_CSACONF               (EMI_BASE+0X000)        /* CSA参数配置寄存器 */
+#define EMI_CSBCONF               (EMI_BASE+0X004)        /* CSB参数配置寄存器 */
+#define EMI_CSCCONF               (EMI_BASE+0X008)        /* CSC参数配置寄存器 */
+#define EMI_CSDCONF               (EMI_BASE+0X00C)        /* CSD参数配置寄存器 */
+#define EMI_CSECONF               (EMI_BASE+0X010)        /* CSE参数配置寄存器 */
+#define EMI_CSFCONF               (EMI_BASE+0X014)        /* CSF参数配置寄存器 */
+#define EMI_SDCONF1               (EMI_BASE+0X018)        /* SDRAM时序配置寄存器1 */
+#define EMI_SDCONF2               (EMI_BASE+0X01C)        /* SDRAM时序配置寄存器2, SDRAM初始化用到的配置信息 */
+#define EMI_REMAPCONF             (EMI_BASE+0X020)        /* 片选空间及地址映射REMAP配置寄存器 */
+#define EMI_NAND_ADDR1            (EMI_BASE+0X100)        /* NAND FLASH的地址寄存器1 */
+#define EMI_NAND_COM              (EMI_BASE+0X104)        /* NAND FLASH的控制字寄存器 */
+#define EMI_NAND_STA              (EMI_BASE+0X10C)        /* NAND FLASH的状态寄存器 */
+#define EMI_ERR_ADDR1             (EMI_BASE+0X110)        /* 读操作出错的地址寄存器1 */
+#define EMI_ERR_ADDR2             (EMI_BASE+0X114)        /* 读操作出错的地址寄存器2 */
+#define EMI_NAND_CONF1            (EMI_BASE+0X118)        /* NAND FLASH的配置器存器1 */
+#define EMI_NAND_INTR             (EMI_BASE+0X11C)        /* NAND FLASH中断寄存器 */
+#define EMI_NAND_ECC              (EMI_BASE+0X120)        /* ECC校验完成寄存器 */
+#define EMI_NAND_IDLE             (EMI_BASE+0X124)        /* NAND FLASH空闲寄存器 */
+#define EMI_NAND_CONF2            (EMI_BASE+0X128)        /* NAND FLASH的配置器存器2 */
+#define EMI_NAND_ADDR2            (EMI_BASE+0X12C)        /* NAND FLASH的地址寄存器2 */
+#define EMI_NAND_DATA             (EMI_BASE+0X200)        /* NAND FLASH的数据寄存器 */
+
+
+/*
+ *  DMAC模块
+ *  基址: 0x11001000
+ */
+
+#define DMAC_INTSTATUS            (DMAC_BASE+0X020)       /* DAMC中断状态寄存器。 */
+#define DMAC_INTTCSTATUS          (DMAC_BASE+0X050)       /* DMAC传输完成中断状态寄存器 */
+#define DMAC_INTTCCLEAR           (DMAC_BASE+0X060)       /* DMAC传输完成中断状态清除寄存器 */
+#define DMAC_INTERRORSTATUS       (DMAC_BASE+0X080)       /* DMAC传输错误中断状态寄存器 */
+#define DMAC_INTINTERRCLR         (DMAC_BASE+0X090)       /* DMAC传输错误中断状态清除寄存器 */
+#define DMAC_ENBLDCHNS            (DMAC_BASE+0X0B0)       /* DMAC通道使能状态寄存器 */
+#define DMAC_C0SRCADDR            (DMAC_BASE+0X000)       /* DMAC道0源地址寄存器 */
+#define DMAC_C0DESTADD            (DMAC_BASE+0X004)       /* DMAC道0目的地址寄存器 */
+#define DMAC_C0CONTROL            (DMAC_BASE+0X00C)       /* DMAC道0控制寄存器 */
+#define DMAC_C0CONFIGURATION      (DMAC_BASE+0X010)       /* DMAC道0配置寄存器 */
+#define DMAC_C0DESCRIPTOR         (DMAC_BASE+0X01C)       /* DMAC道0链表地址寄存器 */
+#define DMAC_C1SRCADDR            (DMAC_BASE+0X100)       /* DMAC道1源地址寄存器 */
+#define DMAC_C1DESTADDR           (DMAC_BASE+0X104)       /* DMAC道1目的地址寄存器 */
+#define DMAC_C1CONTROL            (DMAC_BASE+0X10C)       /* DMAC道1控制寄存器 */
+#define DMAC_C1CONFIGURATION      (DMAC_BASE+0X110)       /* DMAC道1配置寄存器 */
+#define DMAC_C1DESCRIPTOR         (DMAC_BASE+0X114)       /* DMAC道1链表地址寄存器 */
+#define DMAC_C2SRCADDR            (DMAC_BASE+0X200)       /* DMAC道2源地址寄存器 */
+#define DMAC_C2DESTADDR           (DMAC_BASE+0X204)       /* DMAC道2目的地址寄存器 */
+#define DMAC_C2CONTROL            (DMAC_BASE+0X20C)       /* DMAC道2控制寄存器 */
+#define DMAC_C2CONFIGURATION      (DMAC_BASE+0X210)       /* DMAC道2配置寄存器 */
+#define DMAC_C2DESCRIPTOR         (DMAC_BASE+0X214)       /* DMAC道2链表地址寄存器 */
+#define DMAC_C3SRCADDR            (DMAC_BASE+0X300)       /* DMAC道3源地址寄存器 */
+#define DMAC_C3DESTADDR           (DMAC_BASE+0X304)       /* DMAC道3目的地址寄存器 */
+#define DMAC_C3CONTROL            (DMAC_BASE+0X30C)       /* DMAC道3控制寄存器 */
+#define DMAC_C3CONFIGURATION      (DMAC_BASE+0X310)       /* DMAC道3配置寄存器 */
+#define DMAC_C3DESCRIPTOR         (DMAC_BASE+0X314)       /* DMAC道3链表地址寄存器 */
+#define DMAC_C4SRCADDR            (DMAC_BASE+0X400)       /* DMAC道4源地址寄存器 */
+#define DMAC_C4DESTADDR           (DMAC_BASE+0X404)       /* DMAC道4目的地址寄存器 */
+#define DMAC_C4CONTROL            (DMAC_BASE+0X40C)       /* DMAC道4控制寄存器 */
+#define DMAC_C4CONFIGURATION      (DMAC_BASE+0X410)       /* DMAC道4配置寄存器 */
+#define DMAC_C4DESCRIPTOR         (DMAC_BASE+0X414)       /* DMAC道4链表地址寄存器 */
+#define DMAC_C5SRCADDR            (DMAC_BASE+0X500)       /* DMAC道5源地址寄存器 */
+#define DMAC_C5DESTADDR           (DMAC_BASE+0X504)       /* DMAC道5目的地址寄存器 */
+#define DMAC_C5CONTROL            (DMAC_BASE+0X50C)       /* DMAC道5控制寄存器 */
+#define DMAC_C5CONFIGURATION      (DMAC_BASE+0X510)       /* DMAC道5配置寄存器 */
+#define DMAC_C5DESCRIPTOR         (DMAC_BASE+0X514)       /* DMAC道5链表地址寄存器 */
+
+
+/*
+ *  LCDC模块
+ *  基址: 0x11002000
+ */
+
+#define LCDC_SSA                  (LCDC_BASE+0X000)       /* 屏幕起始地址寄存器 */
+#define LCDC_SIZE                 (LCDC_BASE+0X004)       /* 屏幕尺寸寄存器 */
+#define LCDC_PCR                  (LCDC_BASE+0X008)       /* 面板配置寄存器 */
+#define LCDC_HCR                  (LCDC_BASE+0X00C)       /* 水平配置寄存器 */
+#define LCDC_VCR                  (LCDC_BASE+0X010)       /* 垂直配置寄存器 */
+#define LCDC_PWMR                 (LCDC_BASE+0X014)       /* PWM对比度控制寄存器 */
+#define LCDC_LECR                 (LCDC_BASE+0X018)       /* 使能控制寄存器 */
+#define LCDC_DMACR                (LCDC_BASE+0X01C)       /* DMA控制寄存器 */
+#define LCDC_LCDISREN             (LCDC_BASE+0X020)       /* 中断使能寄存器 */
+#define LCDC_LCDISR               (LCDC_BASE+0X024)       /* 中断状态寄存器 */
+#define LCDC_LGPMR                (LCDC_BASE+0X040)       /* 灰度调色映射寄存器组 (16个32bit寄存器) */
+
+
+/*
+ *  MAC模块
+ *  基址: 0x11003000
+ */
+
+#define MAC_CTRL                  (MAC_BASE+0X000)        /* MAC控制寄存器 */
+#define MAC_INTSRC                (MAC_BASE+0X004)        /* MAC中断源寄存器 */
+#define MAC_INTMASK               (MAC_BASE+0X008)        /* MAC中断屏蔽寄存器 */
+#define MAC_IPGT                  (MAC_BASE+0X00C)        /* 连续帧间隔寄存器 */
+#define MAC_IPGR1                 (MAC_BASE+0X010)        /* 等待窗口寄存器 */
+#define MAC_IPGR2                 (MAC_BASE+0X014)        /* 等待窗口寄存器 */
+#define MAC_PACKETLEN             (MAC_BASE+0X018)        /* 帧长度寄存器 */
+#define MAC_COLLCONF              (MAC_BASE+0X01C)        /* 碰撞重发寄存器 */
+#define MAC_TXBD_NUM              (MAC_BASE+0X020)        /* 发送描述符寄存器 */
+#define MAC_FLOWCTRL              (MAC_BASE+0X024)        /* 流控寄存器 */
+#define MAC_MII_CTRL              (MAC_BASE+0X028)        /* PHY控制寄存器 */
+#define MAC_MII_CMD               (MAC_BASE+0X02C)        /* PHY命令寄存器 */
+#define MAC_MII_ADDRESS           (MAC_BASE+0X030)        /* PHY地址寄存器 */
+#define MAC_MII_TXDATA            (MAC_BASE+0X034)        /* PHY写数据寄存器 */
+#define MAC_MII_RXDATA            (MAC_BASE+0X038)        /* PHY读数据寄存器 */
+#define MAC_MII_STATUS            (MAC_BASE+0X03C)        /* PHY状态寄存器 */
+#define MAC_ADDR0                 (MAC_BASE+0X040)        /* MAC地址寄存器 */
+#define MAC_ADDR1                 (MAC_BASE+0X044)        /* MAC地址寄存器 */
+#define MAC_HASH0                 (MAC_BASE+0X048)        /* MAC HASH寄存器 */
+#define MAC_HASH1                 (MAC_BASE+0X04C)        /* MAC HASH寄存器 */
+#define MAC_TXPAUSE               (MAC_BASE+0X050)        /* MAC控制帧寄存器 */
+#define MAC_TX_BD                 (MAC_BASE+0X400)      
+#define MAC_RX_BD                 (MAC_BASE+0X600)      
+
+
+/*
+ **************************************
+ * Error Codes:
+ *    IF SUCCESS RETURN 0, ELSE RETURN OTHER ERROR CODE,
+ *    parameter error return (-33)/E_PAR, 
+ *    hardware error reture (-99)/E_HA
+ **************************************
+ */
+
+#define    E_OK          0        /* Normal completion */
+#define    E_SYS         (-5)     /* System error */
+#define    E_NOMEM       (-10)    /* Insufficient memory */
+#define    E_NOSPT       (-17)    /* Feature not supported */
+#define    E_INOSPT      (-18)    /* Feature not supported by ITRON/FILE specification */
+#define    E_RSFN        (-20)    /* Reserved function code number */
+#define    E_RSATR       (-24)    /* Reserved attribute */
+#define    E_PAR         (-33)    /* Parameter error */
+#define    E_ID          (-35)    /* Invalid ID number */
+#define    E_NOEXS       (-52)    /* Object does not exist */
+#define    E_OBJ         (-63)    /* Invalid object state */
+#define    E_MACV        (-65)    /* Memory access disabled or memory access violation */
+#define    E_OACV        (-66)    /* Object access violation */
+#define    E_CTX         (-69)    /* Context error */
+#define    E_QOVR        (-73)    /* Queuing or nesting overflow */
+#define    E_DLT         (-81)    /* Object being waited for was deleted */
+#define    E_TMOUT       (-85)    /* Polling failure or timeout exceeded */
+#define    E_RLWAI       (-86)    /* WAIT state was forcibly released */ 
+
+#define    E_HA          (-99)    /* HARD WARE ERROR */
+
+
+/*
+ **************************************
+ * PMU 模块时钟
+ **************************************
+ */
+
+#define    CLK_SGPT      (1 << 16)
+#define    CLK_SI2S      (1 << 15) 
+#define    CLK_SSMC      (1 << 14)
+#define    CLK_SMAC      (1 << 13)
+#define    CLK_SUSB      (1 << 12)
+#define    CLK_SUART3    (1 << 11)
+#define    CLK_SUART2    (1 << 10)
+#define    CLK_SUART1    (1 << 9)
+#define    CLK_SUART0    (1 << 8)
+#define    CLK_SSSI      (1 << 7)
+#define    CLK_SAC97     (1 << 6)
+#define    CLK_SMMCSD    (1 << 5)
+#define    CLK_SEMI      (1 << 4)
+#define    CLK_SDMAC     (1 << 3)
+#define    CLK_SPWM      (1 << 2)
+#define    CLK_SLCDC     (1 << 1)
+#define    CLK_SESRAM    (1)
+
+
+/*Interrupt Sources*/
+
+
+#define  INTSRC_RTC        31		        
+#define  INTSRC_DMAC       30	                
+#define  INTSRC_EMI        29
+#define  INTSRC_MAC        28
+#define  INTSRC_TIMER1     27
+#define  INTSRC_TIMER2     26
+#define  INTSRC_TIMER3     25
+#define  INTSRC_UART0      24
+#define  INTSRC_UART1      23
+#define  INTSRC_UART2      22
+#define  INTSRC_UART3      21
+#define  INTSRC_PWM        20
+#define  INTSRC_LCDC       19
+#define  INTSRC_I2S        18
+#define  INTSRC_SSI        17
+
+#define  INTSRC_USB        15
+#define  INTSRC_SMC0       14
+#define  INTSRC_SMC1       13
+#define  INTSRC_SDIO       12  
+#define  INTSRC_EXINT10    11              
+#define  INTSRC_EXINT9     10              
+#define  INTSRC_EXINT8     9               
+#define  INTSRC_EXINT7     8               
+#define  INTSRC_EXINT6     7               
+#define  INTSRC_EXINT5     6               
+#define  INTSRC_EXINT4     5               
+#define  INTSRC_EXINT3     4               
+#define  INTSRC_EXINT2     3               
+#define  INTSRC_EXINT1     2               
+#define  INTSRC_EXINT0     1
+#define  INTSRC_NULL       0
+
+
+/*Sereral useful macros*/
+#define set_plevel(plevel)          *(RP)INTC_IPLR = plevel                      //设置普通中断的优先级门限,只有优先级大于此值的中断才能通过
+#define set_int_force(intnum)       *(RP)INTC_IFR = (1 << intnum)                //置1后,软件强制该位对应的中断源发出中断信号
+#define enable_irq(intnum)          *(RP)INTC_IER |= (1 << intnum)               //置1后,允许中断源的IRQ 中断信号
+#define disable_irq( intnum)        *(RP)INTC_IER &= ~(1<< intnum)               //置0后,不允许中断源的IRQ 中断信号
+#define mask_irq(intnum)            *(RP)INTC_IMR |= (1 << intnum)               //置1后,屏蔽对应的IRQ 中断信号               
+#define unmask_irq(intnum)          *(RP)INTC_IMR &= ~(1 << intnum)              //置0后,通过对应的IRQ 中断信号
+#define mask_all_irq()              *(RP)INTC_IMR = 0xFFFFFFFF                   //屏蔽对应的IRQ 中断信号
+#define unmask_all_irq()            *(RP)INTC_IMR = 0x00000000                   //通过对应的IRQ 中断信号
+#define enable_all_irq()            *(RP)INTC_IER = 0XFFFFFFFF                   //允许中断源的IRQ 中断信号
+#define disable_all_irq()           *(RP)INTC_IER = 0X00000000                   //不允许中断源的IRQ 中断信号
+#define InitInt()                  do{mask_all_irq(); enable_all_irq();}while(0)
+
+/*
+ **************************************
+ * 所有程序中用到的Typedef
+ **************************************
+ */
+ 
+typedef    char                 S8;        /* signed 8-bit integer */
+typedef    short                S16;       /* signed 16-bit integer */
+typedef    long                 S32;       /* signed 32-bit integer */
+typedef    unsigned char        U8;        /* unsigned 8-bit integer */
+typedef    unsigned short       U16;       /* unsigned 16-bit integer */
+typedef    unsigned long        U32;       /* unsigned 32-bit integer */
+
+typedef    volatile U32 *       RP;
+typedef    volatile U16 *       RP16;
+typedef    volatile U8  *       RP8;
+
+typedef    void                 *VP;       /* pointer to an unpredictable data type */
+typedef    void                 (*FP)();   /* program start address */
+
+#ifndef    _BOOL_TYPE_
+#define    _BOOL_TYPE_
+typedef    int                  BOOL;	     /* Boolean value.  TRUE (1) or FALSE (0). */
+#endif  
+
+typedef    int                  ER;         /* Error code.  A signed integer. */
+
+/**
+ * IO definitions
+ *
+ * define access restrictions to peripheral registers
+ */
+
+#define     __I     volatile const            /*!< defines 'read only' permissions      */
+#define     __O     volatile                  /*!< defines 'write only' permissions     */
+#define     __IO    volatile                  /*!< defines 'read / write' permissions   */
+#define     __iomem volatile
+
+
+/*Macros for debug*/
+
+#define EOUT(fmt,...) \
+	do \
+	{ 	\
+		rt_kprintf("EOUT:(%s:%i)  ",__FILE__,__LINE__); \
+		rt_kprintf(fmt,##__VA_ARGS__); \
+	}while(0)
+
+#define RT_DEBUG
+#ifdef RT_DEBUG
+	#define DBOUT(fmt,...) \
+	do \
+	{ 	\
+		rt_kprintf("DBOUT:(%s:%i)  ",__FILE__,__LINE__); \
+		rt_kprintf(fmt,##__VA_ARGS__); \
+	}while(0)
+#else
+	#define DBOUT(fmt,...) \
+	do{}while(0)
+#endif
+
+#ifdef	RT_DEBUG
+	#define ASSERT(arg) \
+	if((arg) == 0) \
+	{		\
+		while(1) \
+		{		  \
+			rt_kprintf("have a assert failure\n"); \
+		}										 \
+	}
+#else
+	#define ASSERT(arg) \
+	do		\
+	{		 \
+	}while(0)
+#endif
+
+
+#define write_reg(reg,value) \
+	do \
+	{ \
+		*(RP)(reg) = value; \
+	}while(0)
+
+#define read_reg(reg) (*(RP)reg)
+
+
+struct rt_hw_register
+{
+	rt_uint32_t r0;
+	rt_uint32_t r1;
+	rt_uint32_t r2;
+	rt_uint32_t r3;
+	rt_uint32_t r4;
+	rt_uint32_t r5;
+	rt_uint32_t r6;
+	rt_uint32_t r7;
+	rt_uint32_t r8;
+	rt_uint32_t r9;
+	rt_uint32_t r10;
+	rt_uint32_t fp;
+	rt_uint32_t ip;
+	rt_uint32_t sp;
+	rt_uint32_t lr;
+	rt_uint32_t pc;
+	rt_uint32_t cpsr;
+	rt_uint32_t ORIG_r0;
+};
+
+
+/*@}*/
+
+#endif

+ 282 - 0
bsp/mini4020/serial.c

@@ -0,0 +1,282 @@
+/*
+ * File      : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-03-13     Bernard      first version
+ * 2009-04-20     yi.qiu      modified according bernard's stm32 version
+ * 2010-10-6      wangmeng    added sep4020 surpport     	  	
+ */
+#include <rtthread.h>
+#include <rthw.h>
+#include "serial.h"
+
+/**
+ * @addtogroup SEP4020
+ */
+/*@{*/
+
+/* RT-Thread Device Interface */
+/**
+ * This function initializes serial
+ */
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+	struct serial_device* uart = (struct serial_device*) dev->user_data;
+
+	if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
+	{
+
+		if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+		{
+			rt_memset(uart->int_rx->rx_buffer, 0, 
+				sizeof(uart->int_rx->rx_buffer));
+			uart->int_rx->read_index = uart->int_rx->save_index = 0;
+		}
+		
+		if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+		{
+			rt_memset(uart->int_tx->tx_buffer, 0, 
+				sizeof(uart->int_tx->tx_buffer));
+			uart->int_tx->write_index = uart->int_tx->save_index = 0;
+		}
+
+		dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
+	}
+
+	return RT_EOK;
+}
+
+/* save a char to serial buffer */
+static void rt_serial_savechar(struct serial_device* uart, char ch)
+{
+	rt_base_t level;
+	
+	/* disable interrupt */
+	level = rt_hw_interrupt_disable();
+
+	uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch;
+	uart->int_rx->save_index ++;
+	if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE)
+		uart->int_rx->save_index = 0;
+	
+	/* if the next position is read index, discard this 'read char' */
+	if (uart->int_rx->save_index == uart->int_rx->read_index)
+	{
+		uart->int_rx->read_index ++;
+		if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
+			uart->int_rx->read_index = 0;
+	}
+
+	/* enable interrupt */
+	rt_hw_interrupt_enable(level);
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+	RT_ASSERT(dev != RT_NULL);	
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+	RT_ASSERT(dev != RT_NULL);	
+	return RT_EOK;
+}
+
+static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+	rt_uint8_t* ptr;
+	rt_err_t err_code;
+	struct serial_device* uart;
+	
+	ptr = buffer;
+	err_code = RT_EOK;
+	uart = (struct serial_device*)dev->user_data;
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		rt_base_t level;
+
+		/* interrupt mode Rx */
+		while (size)
+		{
+			if (uart->int_rx->read_index != uart->int_rx->save_index)
+			{
+				*ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
+				size --;
+
+				/* disable interrupt */
+				level = rt_hw_interrupt_disable();
+
+				uart->int_rx->read_index ++;
+				if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
+					uart->int_rx->read_index = 0;
+
+				/* enable interrupt */
+				rt_hw_interrupt_enable(level);
+			}
+			else
+			{
+				/* set error code */
+				err_code = -RT_EEMPTY;
+				break;
+			}
+		}
+	}
+	else
+	{
+		/* polling mode */
+		while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
+		{
+			while (uart->uart_device->lsr & USTAT_RCV_READY)
+			{
+				*ptr = uart->uart_device->dlbl_fifo.txfifo & 0xff;
+				ptr ++;
+			}
+		}
+	}
+
+	/* set error code */
+	rt_set_errno(err_code);
+	return (rt_uint32_t)ptr - (rt_uint32_t)buffer;	
+}
+
+static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{	
+	rt_uint8_t* ptr;
+	rt_err_t err_code;
+	struct serial_device* uart;
+	
+	err_code = RT_EOK;
+	ptr = (rt_uint8_t*)buffer;
+	uart = (struct serial_device*)dev->user_data;
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+	{
+		/* interrupt mode Tx */
+		while (uart->int_tx->save_index != uart->int_tx->write_index)
+		{
+			/* save on tx buffer */
+			uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++;
+			
+			-- size;
+
+			/* move to next position */
+			uart->int_tx->save_index ++;
+			
+			/* wrap save index */
+			if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE)
+				uart->int_tx->save_index = 0;
+		}
+		
+		/* set error code */
+		if (size > 0)
+			err_code = -RT_EFULL;
+	}
+	else
+	{
+		/* polling mode */
+		while (size)
+		{
+			/*
+			 * to be polite with serial console add a line feed
+			 * to the carriage return character
+			 */
+			if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM))
+			{
+				while (!(uart->uart_device->lsr & USTAT_TXB_EMPTY));
+				uart->uart_device->dlbl_fifo.txfifo = '\r';
+			}
+
+			while (!(uart->uart_device->lsr & USTAT_TXB_EMPTY));
+			uart->uart_device->dlbl_fifo.txfifo = (*ptr & 0x1FF);
+
+			++ptr; --size;
+		}
+	}	
+
+	/* set error code */
+	rt_set_errno(err_code);
+	
+	return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+}
+
+static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+	RT_ASSERT(dev != RT_NULL);
+
+	switch (cmd)
+	{
+	case RT_DEVICE_CTRL_SUSPEND:
+		/* suspend device */
+		dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
+		break;
+	
+	case RT_DEVICE_CTRL_RESUME:
+		/* resume device */
+		dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
+		break;
+	}
+	
+	return RT_EOK;
+}
+
+/*
+ * serial register
+ */
+rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial)
+{
+	RT_ASSERT(device != RT_NULL);
+
+	device->type 		= RT_Device_Class_Char;
+	device->rx_indicate = RT_NULL;
+	device->tx_complete = RT_NULL;
+	device->init 		= rt_serial_init;
+	device->open		= rt_serial_open;
+	device->close		= rt_serial_close;
+	device->read 		= rt_serial_read;
+	device->write 		= rt_serial_write;
+	device->control 	= rt_serial_control;
+	device->user_data   = serial;
+
+	/* register a character device */
+	return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
+}
+	
+/* ISR for serial interrupt */
+void rt_hw_serial_isr(rt_device_t device)
+{
+	struct serial_device* uart = (struct serial_device*) device->user_data;
+	
+	/* interrupt mode receive */	
+	RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
+
+	/* save on rx buffer */
+	while (uart->uart_device->lsr & USTAT_RCV_READY)
+	{
+		rt_serial_savechar(uart, uart->uart_device->dlbl_fifo.rxfifo & 0xff);
+	}
+
+	/* invoke callback */
+	if (device->rx_indicate != RT_NULL)
+	{
+		rt_size_t rx_length;
+		
+		/* get rx length */
+		rx_length = uart->int_rx->read_index > uart->int_rx->save_index ?
+			UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index :
+			uart->int_rx->save_index - uart->int_rx->read_index;
+
+		device->rx_indicate(device, rx_length);
+	}
+}
+
+/*@}*/
+

+ 90 - 0
bsp/mini4020/serial.h

@@ -0,0 +1,90 @@
+/*
+ * File      : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-03-13     Bernard      first version
+ * 2009-04-20     yi.qiu      modified according bernard's stm32 version
+ * 2010-10-6      wangmeng    added sep4020 surpport     	  	
+ */
+
+#ifndef __SERIAL_H__
+#define __SERIAL_H__
+
+#include <sep4020.h>
+
+#define	USTAT_RCV_READY		0x01   	/* receive data ready */ 
+#define	USTAT_TXB_EMPTY		0x40   	/* tx buffer empty */
+#define BPS					115200	/* serial baudrate */
+
+#define UART_RX_BUFFER_SIZE		64
+#define UART_TX_BUFFER_SIZE		64
+
+/*For sep4020's uart have several secondary function*/
+/*we use union to decribe it*/
+
+union dlbl_fifo
+{
+	rt_uint32_t dlbl;
+	rt_uint32_t rxfifo;
+	rt_uint32_t txfifo;	
+};
+
+union dlbh_ier
+{
+	rt_uint32_t dlbh;
+	rt_uint32_t ier;
+};
+
+union iir_fcr
+{
+	rt_uint32_t iir;
+	rt_uint32_t fcr;
+};
+
+struct serial_int_rx
+{
+	rt_uint8_t  rx_buffer[UART_RX_BUFFER_SIZE];
+	rt_uint32_t read_index, save_index;
+};
+
+struct serial_int_tx
+{
+	rt_uint8_t  tx_buffer[UART_TX_BUFFER_SIZE];
+	rt_uint32_t write_index, save_index;
+};
+
+typedef struct uartport
+{
+	union dlbl_fifo dlbl_fifo;
+	union dlbh_ier	dlbh_ier;
+	union iir_fcr	iir_fcr;
+	rt_uint32_t lcr;
+	rt_uint32_t mcr;
+	rt_uint32_t lsr;
+	rt_uint32_t msr;
+}uartport;
+
+struct serial_device
+{
+	uartport* uart_device;
+	
+	/* rx structure */
+	struct serial_int_rx* int_rx;
+
+	/* tx structure */
+	struct serial_int_tx* int_tx;
+};
+
+rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial);
+
+void rt_hw_serial_isr(rt_device_t device);
+
+
+#endif

+ 107 - 0
bsp/mini4020/startup.c

@@ -0,0 +1,107 @@
+#include <rthw.h>
+#include <rtthread.h>
+
+#include <sep4020.h>
+#include <board.h>
+#include <serial.h>
+#include <finsh.h>
+
+#ifdef RT_USING_LWIP
+#include <lwip/sys.h>
+#include <netif/ethernetif.h>
+#endif
+
+#define SDRAM_BASE	0x30000000
+
+
+#ifdef __CC_ARM
+extern int Image$$RW_RAM1$$ZI$$Limit;
+#endif
+
+extern void rt_application_init(void);
+extern void finsh_system_init(void);
+extern void sd_init(void);
+
+void rtthread_startup()
+{
+	/* init hardware interrupt */
+	rt_hw_interrupt_init();
+
+	/* init board */
+	rt_hw_board_init();
+
+	/* show version */
+	rt_show_version();
+		
+	/* init tick */
+	rt_system_tick_init();
+
+	/* init kernel object */
+	rt_system_object_init();
+
+	/* init timer system */
+	rt_system_timer_init();
+
+	/* init heap memory system */
+#ifdef __CC_ARM
+	rt_system_heap_init((void*)&Image$$RW_RAM1$$ZI$$Limit, (void*)(SDRAM_BASE + 0x200000));
+#else
+	rt_system_heap_init(&__bss_end, (void*)0x34000000);
+#endif
+
+
+	/* init scheduler system */
+	rt_system_scheduler_init();
+
+#ifdef RT_USING_DEVICE
+
+#ifdef RT_USING_DFS
+	rt_hw_sdcard_init();
+#endif
+
+#ifdef RT_USING_LWIP
+	eth_system_device_init();
+	rt_hw_dm9161_init();
+#endif
+	
+	/*init all registed devices */
+	rt_device_init_all();
+#endif
+
+	/* init application */
+	rt_application_init();
+
+#ifdef RT_USING_FINSH
+	/* init finsh */
+	finsh_system_init();
+#ifdef RT_USING_DEVICE
+	finsh_set_device("uart0");
+#endif
+#endif
+
+	/* init idle thread */
+	rt_thread_idle_init();
+
+	/* start scheduler */
+	rt_system_scheduler_start();
+
+	/* never reach here */
+	return ;
+	
+}
+
+int main()
+{
+	rt_uint32_t UNUSED level;
+
+	/* disable interrupt first */
+	level = rt_hw_interrupt_disable();
+
+	/* startup RT-Thread RTOS */
+	rtthread_startup();
+
+	return 0;
+}
+
+
+