Browse Source

*** EFM32 branch ***
1. Add ENC28J60 Ethernet controller driver
2. Add lwIP support (Please read "Readme.txt")
3. Add simple Http server demo application
4. Modify USART device write function to avoid sleep in ISR
5. Fix a bug in USART driver when using compiler optimization
6. Modify to make use the start-up code in libraries
7. Change the default build option for squeezing the executable file size
8. Modify source code alignment

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

onelife.real 14 years ago
parent
commit
ef6bbc34fa

+ 4 - 4
bsp/efm32/Libraries/SConscript

@@ -35,9 +35,9 @@ efm32lib/src/efm32_wdog.c
 """)
 
 # starupt scripts for each EFM32 family
-#startup_scripts = {}
-#startup_scripts['Gecko'] = 'startup_efm32.s'
-#startup_scripts['TinyGecko'] = 'startup_efm32tg.s'
+startup_scripts = {}
+startup_scripts['Gecko'] = 'startup_efm32.s'
+startup_scripts['TinyGecko'] = 'startup_efm32tg.s'
 
 # linker scripts for each EFM32 family
 #linker_scripts = {}
@@ -45,7 +45,7 @@ efm32lib/src/efm32_wdog.c
 #linker_scripts['TinyGecko'] = 'efm32tg.ld'
 
 # add startup script 
-#src = src + ['CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/startup/cs3/' + startup_scripts[rtconfig.EFM32_FAMILY]]
+src = src + ['CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/startup/cs3/' + startup_scripts[rtconfig.EFM32_FAMILY]]
     
 path = [RTT_ROOT + '/bsp/efm32/Libraries/efm32lib/inc', 
     RTT_ROOT + '/bsp/efm32/Libraries/CMSIS/CM3/CoreSupport',

+ 16 - 30
bsp/efm32/Readme.txt

@@ -1,31 +1,17 @@
-To test the ELM FatFs:
-1. Please copy "bsp/efm32/copy_this_file_dfs_elm.c" to "components/dfs/filesystems/elmfat/"
-2. rename it to "dfs_elm.c" replacing the original file
-3. and then compile
+ - To test the ELM FatFs:
+1. Please turn on the following defines in "rtconfig.h":
+      #define EFM32_USING_SPISD
+      #define RT_USING_DFS
+      #define RT_USING_DFS_ELMFAT
+      #define DFS_*
+2. copy "bsp/efm32/copy_this_file_dfs_elm.c" to "components/dfs/filesystems/elmfat/"
+3. rename it to "dfs_elm.c" replacing the original file
+4. and then compile
 
-Warning:
-FatFs is really FAT! (35KB)
-You may remove the following defines in "rtconfig.h" to save space:
-//#define RT_MEM_DEBUG
-//#define THREAD_DEBUG
-//#define IRQ_DEBUG
-
-//#define RT_IRQHDL_DEBUG
-//#define RT_IIC_DEBUG
-//#define RT_MISC_DEBUG
-//#define RT_ADC_DEBUG
-//#define RT_ACMP_DEBUG
-//#define RT_TIMER_DEBUG
-//#define RT_RTC_DEBUG
-
-//#define RT_USING_EVENT
-//#define RT_USING_MAILBOX
-//#define RT_USING_MESSAGEQUEUE
-//#define RT_USING_MEMPOOL
-
-//#define RT_USING_IIC0			0x1UL
-//#define RT_USING_ACMP0
-//#define RT_USING_ADC0
-//#define RT_USING_TIMER2			(0x00) 		/* Continuous mode */
-//#define RT_USING_RTC
-//#define EFM32_USING_SFLASH
+ - To test the lwIP:
+1. You should have a ENC28J60 Ethernet controller and connect it with your board properly
+2. Please turn on the following defines in "rtconfig.h":
+      #define EFM32_USING_ETHERNET
+      #define RT_USING_LWIP
+      #RT_LWIP_*
+3. and then compile

+ 3 - 2
bsp/efm32/SConscript

@@ -11,11 +11,12 @@ else:
 
 src_bsp = ['application.c', 'startup.c', 'board.c']
 src_drv1 = ['drv_dma.c', 'drv_rtc.c', 'drv_adc.c', 'drv_acmp.c', 'drv_usart.c', 'drv_iic.c', 'drv_timer.c']
-src_drv2 = ['drv_sdcard.c']
+src_drv2 = ['drv_sdcard.c', 'drv_ethernet.c']
 src_dev = ['dev_misc.c', 'dev_led.c', 'dev_sflash.c']
 src_hdl = ['hdl_interrupt.c']
+src_app = ['httpd.c']
 
-src = src_kit + src_bsp + src_drv1 + src_drv2 + src_dev + src_hdl
+src = src_kit + src_bsp + src_drv1 + src_drv2 + src_dev + src_hdl + src_app
 CPPPATH.append(RTT_ROOT + '/bsp/efm32')
 CPPDEFINES = ['USE_STDPERIPH_DRIVER', rtconfig.EFM32_BOARD, rtconfig.EFM32_TYPE]
 group = DefineGroup('Startup', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)

+ 84 - 35
bsp/efm32/application.c

@@ -1,30 +1,30 @@
-/******************************************************************//**
- * @file 		application.c
+/***************************************************************************//**
+ * @file 	application.c
  * @brief 	application tasks
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	Bernard, onelife
- * @version 	0.4 beta
- **********************************************************************
+ * @version 0.4 beta
+ *******************************************************************************
  * @section License
- * 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
- **********************************************************************
+ * 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
+ *******************************************************************************
  * @section Change Logs
  * Date			Author		Notes
- * 2009-01-05 	Bernard 		first version
+ * 2009-01-05 	Bernard 	first version
  * 2010-12-29	onelife		Modify for EFM32
  * 2011-05-06	onelife		Add SPI Flash DEMO
- *********************************************************************/
+ ******************************************************************************/
  
-/******************************************************************//**
-* @addtogroup cortex-m3
-* @{
-*********************************************************************/
+/***************************************************************************//**
+ * @addtogroup efm32
+ * @{
+ ******************************************************************************/
 
-/* Includes -------------------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
 #include <board.h>
 
-#ifdef RT_USING_DFS
+#if defined(RT_USING_DFS)
 /* dfs init */
 #include <dfs_init.h>
 /* dfs filesystem:ELM filesystem init */
@@ -34,33 +34,35 @@
 #endif
 
 #include "dev_led.h"
-#ifdef EFM32_USING_SFLASH
+#if defined(EFM32_USING_SFLASH)
 #include "dev_sflash.h"
 #endif
-#ifdef EFM32_USING_SPISD
+#if defined(EFM32_USING_SPISD)
 #include "drv_sdcard.h"
 #endif
+#if defined(EFM32_USING_ETHERNET)
+#include "drv_ethernet.h"
+#endif
 
-
-/* Private typedef -------------------------------------------------------------*/
-/* Private define --------------------------------------------------------------*/
-/* Private macro --------------------------------------------------------------*/
-/* Private variables ------------------------------------------------------------*/
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
 rt_uint32_t	rt_system_status = 0;
 
-/* Private function prototypes ---------------------------------------------------*/
-/* Private functions ------------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
 void rt_demo_thread_entry(void* parameter)
 {
 #if defined(RT_USING_DFS)
 	/* Filesystem Initialization */
 	dfs_init();
 
-#if defined(RT_USING_DFS_ELMFAT)
+ #if defined(RT_USING_DFS_ELMFAT)
 	/* init the elm chan FatFs filesystam*/
 	elm_init();
 
-#if defined(EFM32_USING_SPISD)
+  #if defined(EFM32_USING_SPISD)
 	/* mount sd card fat partition 1 as root directory */
 	if (dfs_mount(SPISD_DEVICE_NAME, "/", "elm", 0, 0) == 0)
 	{
@@ -70,8 +72,8 @@ void rt_demo_thread_entry(void* parameter)
 	{
 		rt_kprintf("FatFs init failed!\n");
 	}
-#endif
-#endif
+  #endif
+ #endif
 #endif
 
 #ifdef EFM32_USING_SFLASH
@@ -109,6 +111,20 @@ void rt_demo_thread_entry(void* parameter)
 
 	//efm_spiFlash_deinit();
 }
+#endif
+
+#if defined(EFM32_USING_ETHERNET)
+	rt_device_t eth = RT_NULL;
+
+	eth = rt_device_find(ETH_DEVICE_NAME);
+	if (eth != RT_NULL)
+	{
+		eth->init(eth);
+	}
+	else
+	{
+		rt_kprintf("%s is not found\n"), ETH_DEVICE_NAME;
+	}
 #endif
 	rt_kprintf("Demo End\n");
 }
@@ -139,33 +155,66 @@ int rt_application_init()
 	rt_thread_t demo_thread, led_thread;
 
 #if defined(EFM32_USING_SFLASH)
-	efm_spiFlash_init();
+	if (efm_spiFlash_init() != RT_EOK)
+	{
+		rt_kprintf("*** Init SPI Flash driver failed!");
+		while(1); //Or do something?
+	}
 #endif
 
 #if defined(EFM32_USING_SPISD)
-	efm_spiSd_init();
+	if (efm_spiSd_init() != RT_EOK)
+	{
+		rt_kprintf("*** Init SD card driver failed!");
+		while(1); //Or do something?
+	}
 #endif
 
 	/* Initialize all device drivers (dev_?.c) */
 	if (rt_hw_led_init() != RT_EOK)
 	{
-		rt_kprintf("*** Failed to initialize LED driver!");
+		rt_kprintf("*** Init LED driver failed!");
 		while(1); //Or do something?
 	}
 #if defined(RT_USING_ADC0)
 	if (rt_hw_misc_init() != RT_EOK)
 	{
-		rt_kprintf("*** Failed to miscellaneous driver!");
+		rt_kprintf("*** Init miscellaneous driver failed!");
 		while(1); //Or do something?
 	}
 #endif
 
+#if defined(RT_USING_LWIP)
+	{
+		extern void lwip_sys_init(void);
+		extern void httpd_init(void);
+
+		/* Create Ethernet Threads */
+		if (eth_system_device_init() != RT_EOK)
+		{
+			rt_kprintf("*** Create Ethernet threads failed!");
+			while(1); //Or do something?
+		}
+ #if defined(EFM32_USING_ETHERNET)
+		if (efm_hw_eth_init() != RT_EOK)
+		{
+			rt_kprintf("*** Init Ethernet driver failed!");
+			while(1); //Or do something?
+		}
+ #endif
+		/* init lwip system */
+		lwip_sys_init();
+		httpd_init();
+		rt_kprintf("TCP/IP stack init OK!\n");
+	}
+#endif
+
 #if (RT_THREAD_PRIORITY_MAX == 32)
 	demo_thread = rt_thread_create(
 		"demo",
 		rt_demo_thread_entry, 
 		RT_NULL,
-		2048, 
+		512, 
 		3, 
 		20);
 
@@ -193,6 +242,6 @@ int rt_application_init()
 	return 0;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @}
-*********************************************************************/
+ ******************************************************************************/

+ 9 - 2
bsp/efm32/board.h

@@ -71,6 +71,13 @@ extern rt_uint32_t rt_system_status;
 #define SD_CS_PIN 					(8)
 #endif
 
+/* SECTION: Ethernet */
+#if defined(EFM32_USING_ETHERNET)
+#define USART_2_AUTOCS 				(0)
+#define ETH_CS_PORT 				(gpioPortB)
+#define ETH_CS_PIN 					(6)
+#endif
+
 /* SECTION: SYSTEM */
 #define EFM32_SRAM_END 				(RAM_MEM_BASE + SRAM_SIZE)
 #define EFM32_BASE_PRI_DEFAULT 		(0x0UL << 5)
@@ -107,8 +114,8 @@ extern rt_uint32_t rt_system_status;
 
 /* SECTION: ADC */
 
-#define ADC_INIT_REF				adcRef2V5
-#define ADC_INIT_CH 				adcSingleInpCh5
+#define ADC_CALI_REF				adcRef2V5
+#define ADC_CALI_CH 				adcSingleInpCh5
 #define ADC_CONVERT_FREQUENCY 		(7000000)
 
 #if (RT_CONSOLE_DEVICE == 0x0UL)

+ 0 - 1
bsp/efm32/copy_this_file_dfs_elm.c

@@ -780,7 +780,6 @@ DRESULT disk_ioctl (
 {
 	rt_device_t device = disk[drv];
 
-	/* Supports only single drive */
 	if (!device)
 	{
 		return RES_ERROR;

+ 33 - 33
bsp/efm32/dev_misc.c

@@ -1,47 +1,47 @@
-/******************************************************************//**
- * @file 		dev_misc.c
+/***************************************************************************//**
+ * @file 	dev_misc.c
  * @brief 	Miscellaneous drivers of RT-Thread RTOS for EFM32
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	onelife
- * @version 	0.4 beta
- **********************************************************************
+ * @version 0.4 beta
+ *******************************************************************************
  * @section License
- * 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
- **********************************************************************
+ * 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
+ *******************************************************************************
  * @section Change Logs
  * Date			Author		Notes
  * 2011-02-22	onelife		Initial creation for EFM32
- *********************************************************************/
+ ******************************************************************************/
 
-/******************************************************************//**
+/***************************************************************************//**
  * @addtogroup efm32
  * @{
-*********************************************************************/
+ ******************************************************************************/
 
-/* Includes -------------------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
 #include "board.h"
 #include "drv_adc.h"
 
-/* Private typedef -------------------------------------------------------------*/
-/* Private define --------------------------------------------------------------*/
-/* Private macro --------------------------------------------------------------*/
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
 #ifdef RT_MISC_DEBUG
 #define misc_debug(format,args...) 			rt_kprintf(format, ##args)
 #else
 #define misc_debug(format,args...)
 #endif
 
-/* Private constants -----------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
 static rt_device_t adc0;
 static struct efm32_adc_control_t control = {ADC_MODE_SINGLE};
 
-/* Private variables ------------------------------------------------------------*/
-/* Private function prototypes ---------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
 rt_int32_t efm32_misc_getCelsius(rt_uint32_t adcSample);
 
-/* Private functions ------------------------------------------------------------*/
-/******************************************************************//**
+/* Private functions ---------------------------------------------------------*/
+/***************************************************************************//**
  * @brief
  *   Get current temperature value in degree celsius
  *
@@ -52,14 +52,14 @@ rt_int32_t efm32_misc_getCelsius(rt_uint32_t adcSample);
  * @return
  *   Temperature value (signed integer) in degree celsius times 100
  *
- *********************************************************************/
+ ******************************************************************************/
 rt_int32_t rt_hw_get_temp(void)
 {
 	ADC_InitSingle_TypeDef 	singleInit = ADC_INITSINGLE_DEFAULT;
 	rt_uint32_t 			temp;
 
-	/* Set input to temperature sensor. Acquisition time must be 256 cycles. Reference must 
-	    be 1.25V */
+	/* Set input to temperature sensor. Acquisition time must be 256 cycles. 
+	   Reference must be 1.25V */
 	singleInit.acqTime 		= adcAcqTime32;
 	singleInit.reference 	= adcRef1V25;
 	singleInit.input 		= adcSingleInpTemp;
@@ -72,7 +72,7 @@ rt_int32_t rt_hw_get_temp(void)
 	return efm32_misc_getCelsius(temp);
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Get current VDD value in volt
  *
@@ -83,7 +83,7 @@ rt_int32_t rt_hw_get_temp(void)
  * @return
  *   VDD value (unsigned integer) in volt times 100
  *
- *********************************************************************/
+ ******************************************************************************/
 rt_uint32_t rt_hw_get_vdd(void)
 {
 	ADC_InitSingle_TypeDef 	singleInit = ADC_INITSINGLE_DEFAULT;
@@ -102,7 +102,7 @@ rt_uint32_t rt_hw_get_vdd(void)
 	return (vdd * 125 * 3) / 4096;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Initialize all the miscellaneous drivers
  *
@@ -112,7 +112,7 @@ rt_uint32_t rt_hw_get_vdd(void)
  *
  * @return
  *	 Error code
- *********************************************************************/
+ ******************************************************************************/
 rt_err_t rt_hw_misc_init(void)
 {
 	adc0 = rt_device_find(RT_ADC0_NAME);
@@ -129,7 +129,7 @@ MISC_INIT_ERROR:
 
 }
 
-/**************************************************************************//**
+/***************************************************************************//**
  * @brief 
  *   Convert ADC result to degree celsius.
  *
@@ -144,7 +144,7 @@ MISC_INIT_ERROR:
  * @return 
  *   The temperature value (signed integer) in degrees celsius times 100
  *
- *****************************************************************************/
+ ******************************************************************************/
 rt_int32_t efm32_misc_getCelsius(rt_uint32_t adcResult)
 {
 	/* Factory calibration temperature from device information page. */
@@ -161,9 +161,9 @@ rt_int32_t efm32_misc_getCelsius(rt_uint32_t adcResult)
 	return (cal_temp - (cal_value - (rt_int32_t)adcResult * 10000) / t_grad);
 }
 
-/*********************************************************************
-* 	Export to FINSH
-*********************************************************************/
+/***************************************************************************//**
+ * 	Export to FINSH
+ ******************************************************************************/
 #ifdef RT_USING_FINSH
 #include <finsh.h>
 
@@ -185,6 +185,6 @@ FINSH_FUNCTION_EXPORT(list_vdd, list current VDD value.)
 
 #endif
 
-/******************************************************************//**
+/***************************************************************************//**
  * @}
-*********************************************************************/
+ ******************************************************************************/

+ 11 - 11
bsp/efm32/dev_misc.h

@@ -1,26 +1,26 @@
-/******************************************************************//**
+/***************************************************************************//**
  * @file 		dev_misc.h
  * @brief 	Miscellaneous drivers of RT-Thread RTOS for EFM32
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	onelife
  * @version 	0.4 beta
- **********************************************************************
+ *******************************************************************************
  * @section License
- * 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
- **********************************************************************
+ * 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
+ *******************************************************************************
  * @section Change Logs
  * Date			Author		Notes
  * 2011-02-22	onelife		Initial creation for EFM32
- *********************************************************************/
+ ******************************************************************************/
 #ifndef __DEV_MISC_H__
 #define __DEV_MISC_H__
 
-/* Includes -------------------------------------------------------------------*/
-/* Exported types -------------------------------------------------------------*/
-/* Exported constants ---------------------------------------------------------*/
-/* Exported macro -------------------------------------------------------------*/
-/* Exported functions --------------------------------------------------------- */
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
 rt_err_t rt_hw_misc_init(void);
 rt_int32_t rt_hw_get_temp(void);
 rt_uint32_t rt_hw_get_vdd(void);

+ 3 - 2
bsp/efm32/dev_sflash.c

@@ -1,7 +1,8 @@
 /******************************************************************//**
  * @file 		dev_sflash.c
  * @brief 	SPI Flash driver of RT-Thread RTOS for using EFM32 USART module.
- * 	This driver is tested by using the M25PX16 device on the EFM32 development kit.
+ * 	 This driver is tested by using the M25PX16 device on the EFM32 development 
+ *  kit.
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	onelife
  * @version 	0.4 beta
@@ -227,7 +228,7 @@ rt_err_t efm_spiFlash_deinit(void)
  * @note
  *
  * @param[in] enable
- *  Chip select pin status
+ *  Chip select pin setting
  *********************************************************************/
 static void efm_spiFlash_cs(rt_uint8_t enable)
 {

+ 2 - 1
bsp/efm32/dev_sflash.h

@@ -1,7 +1,8 @@
 /******************************************************************//**
  * @file 		dev_sflash.h
  * @brief 	SPI Flash driver of RT-Thread RTOS for using EFM32 USART module
- * 	This driver is tested by using the M25PX16 device on the EFM32 development kit.
+ * 	 This driver is tested by using the M25PX16 device on the EFM32 development 
+ *  kit.
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	onelife
  * @version 	0.4 beta

+ 32 - 32
bsp/efm32/drv_adc.c

@@ -1,51 +1,51 @@
-/******************************************************************//**
- * @file 		drv_adc.c
+/***************************************************************************//**
+ * @file 	drv_adc.c
  * @brief 	ADC driver of RT-Thread RTOS for EFM32
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	onelife
- * @version 	0.4 beta
- **********************************************************************
+ * @version 0.4 beta
+ *******************************************************************************
  * @section License
- * 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
- **********************************************************************
+ * 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
+ *******************************************************************************
  * @section Change Logs
  * Date			Author		Notes
  * 2011-02-21	onelife		Initial creation for EFM32
- *********************************************************************/
+ ******************************************************************************/
  
-/******************************************************************//**
-* @addtogroup efm32
-* @{
-*********************************************************************/
+/***************************************************************************//**
+ * @addtogroup efm32
+ * @{
+ ******************************************************************************/
 
-/* Includes -------------------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
 #include "board.h"
 #include "drv_adc.h"
 
 #if defined(RT_USING_ADC0)
-/* Private typedef -------------------------------------------------------------*/
-/* Private define --------------------------------------------------------------*/
-/* Private macro --------------------------------------------------------------*/
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
 #ifdef RT_ADC_DEBUG
 #define adc_debug(format,args...) 			rt_kprintf(format, ##args)
 #else
 #define adc_debug(format,args...)
 #endif
 
-/* Private variables ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
 #ifdef RT_USING_ADC0
 	static struct rt_device adc0_device;
 #endif
 
-/* Private function prototypes ---------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
 rt_uint32_t efm32_adc_calibration(
 	ADC_TypeDef 			*adc, 
 	ADC_Ref_TypeDef			ref,
 	ADC_SingleInput_TypeDef	input);
 
-/* Private functions ------------------------------------------------------------*/
-/******************************************************************//**
+/* Private functions ---------------------------------------------------------*/
+/***************************************************************************//**
  * @brief
  *   Initialize ADC device
  *
@@ -58,7 +58,7 @@ rt_uint32_t efm32_adc_calibration(
  *
  * @return
  *   Error code
- *********************************************************************/
+ ******************************************************************************/
  static rt_err_t rt_adc_init(rt_device_t dev)
 {
 	RT_ASSERT(dev != RT_NULL);
@@ -69,13 +69,13 @@ rt_uint32_t efm32_adc_calibration(
 
 	adc = (struct efm32_adc_device_t *)(dev->user_data);
 
-	temp = efm32_adc_calibration(adc->adc_device, ADC_INIT_REF, ADC_INIT_CH);
+	temp = efm32_adc_calibration(adc->adc_device, ADC_CALI_REF, ADC_CALI_CH);
 
 	adc_debug("adc->CAL = %x\n", temp);
 	return RT_EOK;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
 * @brief
 *	Configure ADC device
 *
@@ -94,7 +94,7 @@ rt_uint32_t efm32_adc_calibration(
 *
 * @return
 *	Error code
-*********************************************************************/
+******************************************************************************/
 static rt_err_t rt_adc_control(
 	rt_device_t 	dev, 
 	rt_uint8_t 		cmd, 
@@ -197,7 +197,7 @@ static rt_err_t rt_adc_control(
 	return RT_EOK;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
 * @brief
 *	Register ADC device
 *
@@ -219,7 +219,7 @@ static rt_err_t rt_adc_control(
 *
 * @return
 *	Error code
-*********************************************************************/
+******************************************************************************/
 rt_err_t rt_hw_adc_register(
 	rt_device_t		device, 
 	const char		*name, 
@@ -243,7 +243,7 @@ rt_err_t rt_hw_adc_register(
 	return rt_device_register(device, name, flag);
 }
 
-/******************************************************************//**
+/***************************************************************************//**
 * @brief
 *	Initialize the specified ADC unit 
 *
@@ -259,7 +259,7 @@ rt_err_t rt_hw_adc_register(
 *
 * @return
 *	Pointer to ADC device  
-*********************************************************************/
+******************************************************************************/
 static struct efm32_adc_device_t *rt_hw_adc_unit_init(
 	rt_device_t device,
 	rt_uint8_t 	unitNumber)
@@ -319,7 +319,7 @@ static struct efm32_adc_device_t *rt_hw_adc_unit_init(
 	return RT_NULL;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
 * @brief
 *	Initialize all ADC module related hardware and register ADC device to kernel
 *
@@ -327,7 +327,7 @@ static struct efm32_adc_device_t *rt_hw_adc_unit_init(
 *
 * @note
 *
-*********************************************************************/
+******************************************************************************/
 void rt_hw_adc_init(void)
 {
 	struct efm32_adc_device_t 	*adc;
@@ -499,6 +499,6 @@ rt_uint32_t efm32_adc_calibration(
 }
 
 #endif
-/******************************************************************//**
+/***************************************************************************//**
  * @}
-*********************************************************************/
+ ******************************************************************************/ 

+ 13 - 13
bsp/efm32/drv_adc.h

@@ -1,23 +1,23 @@
-/******************************************************************//**
- * @file 		drv_adc.h
+/***************************************************************************//**
+ * @file 	drv_adc.h
  * @brief 	ADC driver of RT-Thread RTOS for EFM32
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	onelife
- * @version 	0.4 beta
- **********************************************************************
+ * @version 0.4 beta
+ *******************************************************************************
  * @section License
- * 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
- **********************************************************************
+ * 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
+ *******************************************************************************
  * @section Change Logs
  * Date			Author		Notes
  * 2011-02-21	onelife		Initial creation for EFM32
- *********************************************************************/
+ ******************************************************************************/
 #ifndef __DRV_ADC_H__
 #define __DRV_ADC_H__
 
-/* Includes -------------------------------------------------------------------*/
-/* Exported types -------------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
 struct efm32_adc_device_t
 {
 	ADC_TypeDef 			*adc_device;
@@ -31,13 +31,13 @@ struct efm32_adc_control_t
 	ADC_InitScan_TypeDef 	*scanInit;
 };
 
-/* Exported constants ---------------------------------------------------------*/
-/* Exported macro -------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
 #define ADC_MODE_SINGLE 	0x00UL
 #define ADC_MODE_SCAN 		0x01UL
 #define ADC_MODE_TAILGATE	0x02UL
 
-/* Exported functions --------------------------------------------------------- */
+/* Exported functions ------------------------------------------------------- */
 void rt_hw_adc_init(void);
 
 #endif /*__DRV_ADC_H__ */

+ 1083 - 0
bsp/efm32/drv_ethernet.c

@@ -0,0 +1,1083 @@
+/***************************************************************************//**
+ * @file 	drv_ethernet.c
+ * @brief 	Ethernet driver (SPI mode) of RT-Thread RTOS for using EFM32 USART 
+ *  module
+ * 	 This driver is tested by using the Microchip ENC28J60 stand-alone Ethernet 
+ *  controller with SPI interface.
+ * 	COPYRIGHT (C) 2011, RT-Thread Development Team
+ * @author 	onelife
+ * @version 0.4 beta
+ *******************************************************************************
+ * @section License
+ * 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
+ *******************************************************************************
+ * @section Change Logs
+ * Date			Author		Notes
+ * 2011-06-22	onelife		Initial creation for using EFM32 USART module
+ ******************************************************************************/
+
+/***************************************************************************//**
+ * @addtogroup efm32_eth
+ * @{
+******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "board.h"
+#include "drv_usart.h"
+#include "hdl_interrupt.h"
+#include "drv_ethernet.h"
+
+#if defined(EFM32_USING_ETHERNET)
+#include <netif/ethernetif.h>
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+#ifdef EFM32_ETHERNET_DEBUG
+#define eth_debug(format,args...) 			rt_kprintf(format, ##args)
+#else
+#define eth_debug(format,args...)
+#endif
+
+/* Private constants ---------------------------------------------------------*/
+static const rt_uint8_t 	eth_addr[ETH_ADDR_LEN] = ETH_ADDR_DEFAULT;
+
+/* Private variables ---------------------------------------------------------*/
+static struct eth_device 	eth_dev;
+static struct rt_semaphore 	ethLock;
+static rt_uint8_t 			ethBank;
+static rt_uint16_t 			ethNxtPkt;
+static rt_device_t 			spi 			= RT_NULL;
+static rt_bool_t 			ethAutoCs 		= true;
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/***************************************************************************//**
+ * @brief
+ *   Set/Clear chip select
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] enable
+ *  Chip select pin setting
+ ******************************************************************************/
+static void efm_eth_cs(rt_uint8_t enable)
+{
+	if (!ethAutoCs)
+	{
+		if (enable)
+		{
+			GPIO_PinOutClear(ETH_CS_PORT, ETH_CS_PIN);
+		}
+		else
+		{
+			GPIO_PinOutSet(ETH_CS_PORT, ETH_CS_PIN);
+		}
+	}
+}
+
+/***************************************************************************//**
+ * @brief
+ *  Send command to Ethernet device
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] cmd
+ *   Command index
+ *
+ * @param[in] addr
+ *   Register address
+ *
+ * @param[in/out] data
+ *   Pointer to the buffer of register value
+ *
+ * @return
+ *   Error code
+ ******************************************************************************/
+static rt_err_t efm_eth_cmd(
+	rt_uint8_t cmd, 
+	rt_uint8_t addr,
+	rt_uint8_t *data)
+{
+	RT_ASSERT(spi != RT_NULL);
+
+	rt_uint8_t buf_ins[6], buf_res[2];
+	rt_uint8_t len_ins, len_res;
+
+	len_ins = 0;
+	do
+	{
+		/* Build instruction buffer */
+		/* Check if need to read back */
+		if (cmd == ENC28J60_READ_CTRL_REG)
+		{
+			buf_ins[len_ins++] = 1; 						/* Instruction length */
+		}
+		/* Byte 0: Check if no address section */
+		if (cmd == ENC28J60_READ_BUF_MEM || cmd == ENC28J60_WRITE_BUF_MEM || \
+			cmd == ENC28J60_SOFT_RESET)
+		{
+			buf_ins[len_ins++] = cmd;
+		}
+		else
+		{
+			buf_ins[len_ins++] = cmd | (addr & ADDR_MASK);
+		}
+		/* Byte 1: Check if data section is present */
+		if (cmd == ENC28J60_WRITE_CTRL_REG || cmd == ENC28J60_BIT_FIELD_SET || \
+			cmd == ENC28J60_BIT_FIELD_CLR || cmd == ENC28J60_WRITE_BUF_MEM)
+		{
+			buf_ins[len_ins++] = *data;
+		}
+
+		/* Check if reading */
+		if (cmd == ENC28J60_READ_CTRL_REG)
+		{
+			*(rt_uint8_t **)(&buf_ins[len_ins]) = buf_res; 	/* Pointer to RX buffer */
+			len_ins += 4;
+
+			/* Check if MAC or MII register */
+			if (addr & SPRD_MASK)
+			{
+				len_res = 2;
+			}
+			else
+			{
+				len_res = 1;
+			}
+
+			/* Send command and get response */
+			efm_eth_cs(1);
+			if (spi->read(spi, ETH_SPI_RX_SKIP, buf_ins, len_res) == 0)
+			{
+				break;
+			}
+			*data = buf_res[len_res - 1];
+//			eth_debug("ETH: read RX %x %x (%d)\n", buf_res[0], buf_res[1], len_res);
+//			eth_debug("ETH: ** read RX %x %x (%d)\n", 
+//				buf_res[0], buf_res[1], buf_res[2], buf_res[3], buf_res[4], 
+//				buf_res[5], buf_res[6], buf_res[7], buf_res[8], buf_res[9], 
+//				len_res);
+		}
+		else
+		{
+//			eth_debug("ETH: ** write TX %x %x %x %x %x %x (%d) \n", buf_ins[0],
+//				buf_ins[1], buf_ins[2], buf_ins[3], buf_ins[4], buf_ins[5], 
+//				len_ins);
+			/* Send command and get response */
+			efm_eth_cs(1);
+			if (spi->write(spi, EFM32_NO_DATA, buf_ins, len_ins) == 0)
+			{
+				break;
+			}
+		}
+
+		if (!(cmd == ENC28J60_READ_BUF_MEM || cmd == ENC28J60_WRITE_BUF_MEM))
+		{
+			efm_eth_cs(0);
+		}
+		return RT_EOK;
+	} while(0);
+
+	eth_debug("ETH: Send command failed!\n");
+	efm_eth_cs(0);
+	return -RT_ERROR;
+}
+
+/***************************************************************************//**
+ * @brief
+ *  Wrapper function of send command to Ethernet device
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] cmd
+ *   Command index
+ *
+ * @param[in] addr
+ *   Register address
+ *
+ * @param[in/out] data
+ *   Pointer to the buffer of register value
+ *
+ * @return
+ *   Error code
+ ******************************************************************************/
+static rt_err_t efm_eth_sendCmd(
+	rt_uint8_t cmd, 
+	rt_uint8_t addr,
+	rt_uint8_t *data)
+{
+	rt_err_t ret;
+
+	eth_debug("ETH: Send command %x (%x %x)\n", cmd, addr, *data);
+	do
+	{
+		/* Change bank */
+		if(((addr & BANK_MASK) != ethBank) && ((addr < EIE) || (addr > ECON1)))
+		{
+			rt_uint8_t temp;
+
+			if ((ret = efm_eth_cmd(ENC28J60_READ_CTRL_REG, ECON1, &temp)) != RT_EOK)
+			{
+				break;
+			}
+			temp &= 0xFC;
+			ethBank = (addr & BANK_MASK);
+			temp |= ethBank >> BANK_SHIFT;
+			if ((ret = efm_eth_cmd(ENC28J60_WRITE_CTRL_REG, ECON1, &temp)) != RT_EOK)
+			{
+				break;
+			}
+		}
+		/* Send command */
+		ret = efm_eth_cmd(cmd, addr, data);
+	} while(0);
+
+	return ret;
+}
+
+/***************************************************************************//**
+ * @brief
+ *  Read register of Ethernet device
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] addr
+ *   Register address
+ *
+ * @return
+ *   Register value
+ ******************************************************************************/
+static rt_uint8_t efm_eth_readReg(rt_uint8_t addr)
+{
+	rt_uint8_t data;
+
+	efm_eth_sendCmd(ENC28J60_READ_CTRL_REG, addr, &data);
+
+	return data;
+}
+
+/***************************************************************************//**
+ * @brief
+ *  Write register of Ethernet device
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] addr
+ *   Register address
+ *
+ * @param[in] data
+ *   Register value
+ ******************************************************************************/
+static void efm_eth_writeReg(rt_uint8_t addr, rt_uint8_t data)
+{
+	efm_eth_sendCmd(ENC28J60_WRITE_CTRL_REG, addr, &data);
+}
+
+/***************************************************************************//**
+ * @brief
+ *  Read PHY register of Ethernet device
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] addr
+ *   Register address
+ *
+ * @return
+ *   Register value
+ ******************************************************************************/
+static rt_uint16_t efm_eth_readPhy(rt_uint8_t addr)
+{
+	rt_uint16_t ret;
+
+	eth_debug("ETH: *** read PHY %x\n", addr);
+
+	/* Set PHY register address */
+	efm_eth_writeReg(MIREGADR, addr);
+
+	/* Start read operation */
+	efm_eth_writeReg(MICMD, MICMD_MIIRD);
+	/* Waiting for at least 10.24 uS */
+	while(efm_eth_readReg(MISTAT) & MISTAT_BUSY);
+
+	/* Stop read operation */
+	efm_eth_writeReg(MICMD, 0x00);
+
+	/* Get the result */
+	ret = (rt_uint16_t)efm_eth_readReg(MIRDL);
+	ret |= (rt_uint16_t)efm_eth_readReg(MIRDH) << 8;
+	return ret;
+}
+
+/***************************************************************************//**
+ * @brief
+ *  Write PHY register of Ethernet device
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] addr
+ *   Register address
+ *
+ * @param[in] data
+ *   Register value
+ ******************************************************************************/
+static void efm_eth_writePhy(rt_uint8_t addr, rt_uint16_t data)
+{
+	eth_debug("ETH: *** write PHY %x (%x)\n", addr, data);
+
+	/* Set PHY register address */
+	efm_eth_writeReg(MIREGADR, addr);
+
+	/* Set data */
+	efm_eth_writeReg(MIWRL, data);
+	efm_eth_writeReg(MIWRH, data >> 8);
+	/* Waiting for at least 10.24 uS */
+	while(efm_eth_readReg(MISTAT) & MISTAT_BUSY);
+}
+
+/***************************************************************************//**
+ * @brief
+ *	Interrupt handler of Ethernet device
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] dev
+ *	Pointer to device descriptor
+ ******************************************************************************/
+void efm_eth_isr(rt_device_t dev)
+{
+	rt_uint8_t reg_eir, data;
+	volatile rt_uint8_t cnt;
+
+	/* Disable RX interrutp */
+	data = EIE_PKTIE;
+	efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIE, &data);
+
+	/* Get interrupt flag */
+	efm_eth_sendCmd(ENC28J60_READ_CTRL_REG, EIR, &reg_eir);
+
+	data = 0;
+	/* DMA completed */
+	if (reg_eir & EIR_DMAIF)
+	{
+		data |= (rt_uint8_t)EIR_DMAIF;
+	}
+	/* Link Changed */
+	if (reg_eir & EIR_LINKIF)
+	{
+		/* Read PHIR to clear the flag */
+		efm_eth_readPhy(PHIR);
+	}
+	/* TX done */
+	if (reg_eir & EIR_TXIF)
+	{
+		data |= (rt_uint8_t)EIR_TXIF;
+	}
+	/* TX error */
+	if (reg_eir & EIR_TXERIF)
+	{
+		data |= (rt_uint8_t)EIR_TXERIF;
+	}
+	/* RX error */
+	if (reg_eir & EIR_RXERIF)
+	{
+		data |= (rt_uint8_t)EIR_RXERIF;
+	}
+	/* Clear flags */
+	efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIR, &data);
+
+	/* Get packet counter (Errata 6) */
+	efm_eth_sendCmd(ENC28J60_READ_CTRL_REG, EPKTCNT, (rt_uint8_t *)&cnt);
+	if (cnt)
+	{
+	    /* Inform Ethernet thread */
+		eth_device_ready(&eth_dev);
+	}
+}
+
+/***************************************************************************//**
+ * @brief
+ *   Initialize Ethernet device
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] dev
+ *   Pointer to device descriptor
+ *
+ * @return
+ *   Error code
+ ******************************************************************************/
+static rt_err_t efm_eth_init(rt_device_t dev)
+{
+	rt_uint16_t reg_phy;
+	rt_uint8_t data;
+
+	/* Reset chip select */
+	efm_eth_cs(0);
+	/* Software reset */
+	efm_eth_sendCmd(ENC28J60_SOFT_RESET, EFM32_NO_DATA, EFM32_NO_POINTER);
+	/* Waiting for at least 1 ms (Errata 2) */
+	rt_thread_delay(ETH_PERIOD_WAIT_INIT);
+	ethNxtPkt = RXSTART_INIT;
+	ethBank = 0;
+
+	/* Init RX buffer */
+	efm_eth_writeReg(ERXSTL, RXSTART_INIT & 0xFF);
+	efm_eth_writeReg(ERXSTH, RXSTART_INIT >> 8);
+	efm_eth_writeReg(ERXNDL, RXSTOP_INIT & 0xFF);
+	efm_eth_writeReg(ERXNDH, RXSTOP_INIT >> 8);
+	efm_eth_writeReg(ERXRDPTL, RXSTOP_INIT & 0xFF);
+	efm_eth_writeReg(ERXRDPTH, RXSTOP_INIT >> 8);
+
+	/* Init TX buffer */
+	efm_eth_writeReg(ETXSTL, TXSTART_INIT & 0xFF);
+	efm_eth_writeReg(ETXSTH, TXSTART_INIT >> 8);
+	efm_eth_writeReg(ETXNDL, TXSTOP_INIT & 0xFF);
+	efm_eth_writeReg(ETXNDH, TXSTOP_INIT >> 8);
+	efm_eth_writeReg(EWRPTL, TXSTART_INIT & 0xFF);
+	efm_eth_writeReg(EWRPTH, TXSTART_INIT >> 8);
+
+	/* Init RX filters */
+	/* For broadcast packets we allow only ARP packtets
+	   All other packets should be unicast only for our mac (MAADR)
+
+	   The pattern to match on is therefore
+	   Type                    ETH.DST
+	   ARP                     BROADCAST
+	   06 08 -- -- -- -- -- -- ff ff ff ff ff ff
+	   These poitions are: 11 0000 0011 1111 in binary and 30 3f in hex
+	   Checksum for theses bytes is: f7 f9 */
+	efm_eth_writeReg(EPMM0, 0x3f);
+	efm_eth_writeReg(EPMM1, 0x30);
+	efm_eth_writeReg(EPMCSL, 0xf9);
+	efm_eth_writeReg(EPMCSH, 0xf7); 
+	efm_eth_writeReg(ERXFCON, 
+		ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN);
+	//efm_eth_writeReg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN);
+	/* Waiting For OST: The OST does not expire until 7500 OSC1 clock cycles (300 uS) 
+	    pass after Power-on Reset or wake-up from Power-Down mode occurs */
+
+	/* Init MAC */
+	/* Enable RX, IEEE defined flow control */
+	efm_eth_writeReg(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
+	/* Enable padding to 60 bytes, CRC and frame length status reporting */
+#if defined(ETH_HALF_DUPLEX)
+	efm_eth_writeReg(MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN);
+	efm_eth_writeReg(MACON4, MACON4_DEFER);
+#else
+	efm_eth_writeReg(MACON3, \
+		MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX);
+#endif
+	/* Set the maximum packet length */
+	efm_eth_writeReg(MAMXFLL, MAX_FRAMELEN & 0xFF);
+	efm_eth_writeReg(MAMXFLH, MAX_FRAMELEN >> 8);
+	/* Set inter-packet gap (back-to-back). Full-Duplex: 0x15, Half-Duplex: 0x12 */
+#if defined(ETH_HALF_DUPLEX)
+	efm_eth_writeReg(MABBIPG, 0x12);
+#else
+	efm_eth_writeReg(MABBIPG, 0x15);
+#endif
+	/* Set inter-packet gap (non-back-to-back). 
+	    Full-Duplex: 0x0012, Half-Duplex: 0x0C12 */
+	efm_eth_writeReg(MAIPGL, 0x12);
+#if defined(ETH_HALF_DUPLEX)
+	efm_eth_writeReg(MAIPGH, 0x0C);
+	/* Set retransmission and collision window */
+	efm_eth_writeReg(MACLCON1, 0x0F);
+	efm_eth_writeReg(MACLCON2, 0x37);
+#endif
+	/* Set MAC address
+	    NOTE: MAC address in ENC28J60 is byte-backward */
+	efm_eth_writeReg(MAADR1, eth_addr[0]);
+	efm_eth_writeReg(MAADR2, eth_addr[1]);
+	efm_eth_writeReg(MAADR3, eth_addr[2]);
+	efm_eth_writeReg(MAADR4, eth_addr[3]);
+	efm_eth_writeReg(MAADR5, eth_addr[4]);
+	efm_eth_writeReg(MAADR6, eth_addr[5]);
+
+	/* Init PHY */
+#if defined(ETH_HALF_DUPLEX)
+	reg_phy = efm_eth_readPhy(PHCON2);
+	efm_eth_writePhy(PHCON2, reg_phy | PHCON2_HDLDIS);
+#else
+	reg_phy = efm_eth_readPhy(PHCON1);
+	efm_eth_writePhy(PHCON1, reg_phy | PHCON1_PDPXMD);
+#endif
+	/* LEDA: Display link status; 
+	   LEDB: Display transmit and receive activity */
+	reg_phy = efm_eth_readPhy(PHLCON);
+	efm_eth_writePhy(PHLCON, (reg_phy & 0xF00F) | 0x0470);
+
+	/* Disable clock output */
+	efm_eth_writeReg(ECOCON, 0x00);
+
+	/* Clear interrutp flags */
+	data = EIR_DMAIF | EIR_TXIF | EIR_TXERIF | EIR_RXERIF;
+	efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIR, &data);
+	/* Enable interrutps */
+	data = EIE_INTIE | EIE_PKTIE | EIE_TXIE;
+	efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, EIE, &data);
+	/* Enable RX */
+	data = ECON1_RXEN;
+	efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, ECON1, &data);
+
+	eth_debug("ETH: Init OK\n");
+	return RT_EOK;
+}
+
+/***************************************************************************//**
+ * @brief
+ *   Open Ethernet device
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] dev
+ *   Pointer to device descriptor
+ *
+ * @param[in] oflag
+ *   Device open flag
+ *
+ * @return
+ *   Error code
+ ******************************************************************************/
+static rt_err_t efm_eth_open(rt_device_t dev, rt_uint16_t oflag)
+{
+	eth_debug("ETH: Open, flag %x\n", eth_dev.parent.flag);
+	return RT_EOK;
+}
+
+/***************************************************************************//**
+ * @brief
+ *   Close Ethernet device
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] dev
+ *   Pointer to device descriptor
+ *
+ * @return
+ *   Error code
+ ******************************************************************************/
+static rt_err_t efm_eth_close(rt_device_t dev)
+{
+	eth_debug("ETH: Close, flag %x\n", eth_dev.parent.flag);
+	return RT_EOK;
+}
+
+/***************************************************************************//**
+ * @brief
+ *   Read from Ethernet device (Dummy function)
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] dev
+ *   Pointer to device descriptor
+ *
+ * @param[in] pos
+ *   Offset
+ *
+ * @param[in] buffer
+ *   Poniter to the buffer
+ *
+ * @param[in] size
+ *   Buffer size in byte
+ *
+ * @return
+ *   Number of read bytes
+ ******************************************************************************/
+static rt_size_t efm_eth_read(
+	rt_device_t 	dev, 
+	rt_off_t 		pos,
+	void 			*buffer,
+	rt_size_t 		size)
+{
+    rt_set_errno(-RT_ENOSYS);
+    return 0;
+}
+
+/***************************************************************************//**
+ * @brief
+ *   Write to Ethernet device (Dummy function)
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] dev
+ *   Pointer to device descriptor
+ *
+ * @param[in] pos
+ *   Offset
+ *
+ * @param[in] buffer
+ *   Poniter to the buffer
+ *
+ * @param[in] size
+ *   Buffer size in byte
+ *
+ * @return
+ *   Number of written bytes
+ ******************************************************************************/
+static rt_size_t efm_eth_write (
+	rt_device_t 	dev, 
+	rt_off_t 		pos,
+	const void 		*buffer,
+	rt_size_t 		size)
+{
+    rt_set_errno(-RT_ENOSYS);
+    return 0;
+}
+
+/***************************************************************************//**
+* @brief
+*   Configure Ethernet device
+*
+* @details
+*
+* @note
+*
+* @param[in] dev
+*   Pointer to device descriptor
+*
+* @param[in] cmd
+*   Ethernet control command
+*
+* @param[in] args
+*	Arguments
+*
+* @return
+*   Error code
+******************************************************************************/
+static rt_err_t efm_eth_control (
+	rt_device_t 	dev, 
+	rt_uint8_t 		cmd, 
+	void 			*args)
+{
+	rt_err_t ret;
+	
+	ret = -RT_ERROR;
+	switch(cmd)
+	{
+	case NIOCTL_GADDR:
+		/* Get MAC address */
+		if(args) 
+		{
+			rt_memcpy(args, eth_addr, sizeof(eth_addr));
+			ret = RT_EOK;
+		}
+		break;
+
+	default :
+		break;
+	}
+
+	return RT_EOK;
+}
+
+/***************************************************************************//**
+* @brief
+*   Packet receiving function
+*
+* @details
+*
+* @note
+*
+* @param[in] dev
+*   Pointer to device descriptor
+*
+* @return
+*   Pointer to packet buffer
+******************************************************************************/
+struct pbuf *efm_eth_rx(rt_device_t dev)
+{
+	rt_uint8_t buf_ins[5], buf_read[6];
+	rt_uint8_t data, reg_eie;
+	rt_uint16_t len_rx, sta_rx;
+	struct pbuf* p;
+
+    p = RT_NULL;
+
+    /* Lock device */
+    rt_sem_take(&ethLock, RT_WAITING_FOREVER);
+    /* Disable interrupts */
+	data = EIE_INTIE;
+	efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIE, &data);
+
+	reg_eie = 0;
+    if (efm_eth_readReg(EPKTCNT))
+    {
+        /* Set read pointer to the start of RX packet */
+        efm_eth_writeReg(ERDPTL, ethNxtPkt & 0xFF);
+        efm_eth_writeReg(ERDPTH, ethNxtPkt >> 8);
+
+		/* Send read buffer command */
+		efm_eth_sendCmd(ENC28J60_READ_BUF_MEM, EFM32_NO_DATA, EFM32_NO_POINTER);
+		/* Build instruction buffer */
+		buf_ins[0] = 0x00;
+		*(rt_uint8_t **)(&buf_ins[1]) = buf_read;
+		/* Read packet header */
+		if (spi->read(spi, EFM32_NO_DATA, buf_ins, sizeof(buf_read)) == 0)
+		{
+			eth_debug("ETH: RX header failed!\n");
+		}
+
+		ethNxtPkt = buf_read[0] | (buf_read[1] << 8);
+		len_rx = buf_read[2] | (buf_read[3] << 8);
+		sta_rx = buf_read[4] | (buf_read[5] << 8);
+		eth_debug("ETH: RX header ethNxtPkt %x, len_rx %x, sta_rx %x\n", 
+			ethNxtPkt, len_rx, sta_rx);
+		/* Check if OK */
+        if (sta_rx & 0x80)
+        {
+            /* Allocate pbuf */
+            p = pbuf_alloc(PBUF_LINK, len_rx - 4, PBUF_RAM);
+            if (p != RT_NULL)
+            {
+                struct pbuf* q;
+
+                for (q = p; q != RT_NULL; q= q->next)
+                {
+					/* Build instruction buffer */
+					buf_ins[0] = 0x00;
+					*(rt_uint8_t **)(&buf_ins[1]) = q->payload;
+					/* Read packet header */
+					if (spi->read(spi, EFM32_NO_DATA, buf_ins, q->len) == 0)
+					{
+						eth_debug("ETH: RX payload failed!\n");
+					}
+#ifdef EFM32_ETHERNET_DEBUG
+					{
+						rt_uint8_t *temp = (rt_uint8_t *)q->payload;
+						rt_uint32_t i;
+
+						eth_debug("ETH: ***** read RX (q->len %x) *****\n", q->len);
+						for (i = 0; i < q->len; i += 8)
+						{
+							eth_debug("%02x %02x %02x %02x %02x %02x %02x %02x (%d %d)\n",
+								temp[i], temp[i + 1], temp[i + 2], temp[i + 3], 
+								temp[i + 4], temp[i + 5], temp[i + 6], temp[i + 7], 
+								i, q->len);
+						}
+					}
+#endif
+                }
+            }
+			else
+			{
+				eth_debug("ETH: No memory for pbuf!!!\n");
+			}
+        }
+		else
+		{
+            eth_debug("ETH: Invalid CRC or symbol error occurred!\n");
+        }
+		efm_eth_cs(0);
+
+        /* Free buffer */
+        efm_eth_writeReg(ERXRDPTL, ethNxtPkt & 0xFF);
+        efm_eth_writeReg(ERXRDPTH, ethNxtPkt >> 8);
+
+        /* Decrease counter */
+		data = ECON2_PKTDEC;
+        efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, ECON2, &data);
+    }
+	else
+	{
+		/* Enable RX */
+		data = ECON1_RXEN;
+		efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, ECON1, &data);
+
+	    reg_eie |= EIE_PKTIE;
+		eth_debug("ETH: Enable RX interrupt\n");
+	}
+	eth_debug("ETH: RX counter %x\n", efm_eth_readReg(EPKTCNT));
+
+    /* Enable interrupts */
+	reg_eie |= EIE_INTIE;
+	efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, EIE, &reg_eie);
+	/* Unlock device */
+    rt_sem_release(&ethLock);
+
+    return p;
+}
+
+/***************************************************************************//**
+* @brief
+*   Packet transmission function
+*
+* @details
+*
+* @note
+*
+* @param[in] dev
+*   Pointer to device descriptor
+*
+* @param[in] p
+*   Pointer to packet buffer
+*
+* @return
+*	Error code
+******************************************************************************/
+rt_err_t efm_eth_tx(rt_device_t dev, struct pbuf* p)
+{
+	rt_uint8_t data;
+	struct pbuf* q;
+
+    /* Lock device */
+    rt_sem_take(&ethLock, RT_WAITING_FOREVER);
+    /* Disable interrupts */
+	data = EIE_INTIE;
+	efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIE, &data);
+
+	/* Set write pointer to the start of TX buffer */
+	efm_eth_writeReg(EWRPTL, TXSTART_INIT & 0xFF);
+	efm_eth_writeReg(EWRPTH, TXSTART_INIT >> 8);
+	/* Set buffer end pointer according to the packet size */
+	efm_eth_writeReg(ETXNDL, (TXSTART_INIT + p->tot_len + 1) & 0xFF);
+	efm_eth_writeReg(ETXNDH, (TXSTART_INIT + p->tot_len + 1) >> 8);
+
+	/* Send write buffer command */
+	data = 0x00; 	/* Control byte */
+	efm_eth_sendCmd(ENC28J60_WRITE_BUF_MEM, EFM32_NO_DATA, &data);
+	/* Send data */
+	for (q = p; q != NULL; q = q->next)
+	{
+		if (spi->write(spi, EFM32_NO_DATA, q->payload, q->len) == 0)
+		{
+			eth_debug("ETH: TX failed!\n");
+			return -RT_ERROR;
+		}
+#ifdef EFM32_ETHERNET_DEBUG
+		{
+			rt_uint8_t *temp = (rt_uint8_t *)q->payload;
+			rt_uint32_t i;
+
+			eth_debug("ETH: ***** write TX (len %d) *****\n", p->len);
+			for (i = 0; i < q->len; i += 8)
+			{
+				eth_debug("%02x %02x %02x %02x %02x %02x %02x %02x (%d %d)\n",
+					temp[i], temp[i + 1], temp[i + 2], temp[i + 3], 
+					temp[i + 4], temp[i + 5], temp[i + 6], temp[i + 7],
+					i, q->len);
+			}
+		}
+#endif
+	}
+	efm_eth_cs(0);
+	/* Start TX */
+	data = ECON1_TXRTS;
+	efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, ECON1, &data);
+	/* Errata 12 */
+	if (efm_eth_readReg(EIR) & EIR_TXERIF)
+	{
+		efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, ECON1, &data);
+		data = EIR_TXERIF;
+		efm_eth_sendCmd(ENC28J60_BIT_FIELD_CLR, EIR, &data);
+		data = ECON1_TXRTS;
+		efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, ECON1, &data);
+	}
+
+    /* Enable interrupts */
+	data = EIE_INTIE;
+	efm_eth_sendCmd(ENC28J60_BIT_FIELD_SET, EIE, &data);
+	/* Unlock device */
+    rt_sem_release(&ethLock);
+
+    return RT_EOK;
+}
+
+/***************************************************************************//**
+* @brief
+*	Initialize all Ethernet related hardware and register the device to kernel
+*
+* @details
+*
+* @note
+*
+* @return
+*	Error code
+******************************************************************************/
+rt_err_t efm_hw_eth_init(void)
+{
+	struct efm32_usart_device_t *usart;
+	efm32_irq_hook_init_t 		hook;
+
+	do
+	{
+		/* Find SPI device */
+		spi = rt_device_find(ETH_USING_DEVICE_NAME);
+		if (spi == RT_NULL)
+		{
+			eth_debug("ETH: Can't find device %s!\n", 
+				ETH_USING_DEVICE_NAME);
+			break;
+		}
+		eth_debug("ETH: Find device %s\n", ETH_USING_DEVICE_NAME);
+
+		/* Config chip slect pin */
+		usart = (struct efm32_usart_device_t *)(spi->user_data);
+		if (!(usart->state & USART_STATE_AUTOCS))
+		{
+			GPIO_PinModeSet(ETH_CS_PORT, ETH_CS_PIN, gpioModePushPull, 1);
+			ethAutoCs = false;
+		}
+		/* Config reset pin */
+		GPIO_PinModeSet(ETH_RESET_PORT, ETH_RESET_PIN, gpioModePushPull, 0);
+		/* Config interrupt pin */
+		GPIO_PinModeSet(ETH_INT_PORT, ETH_INT_PIN, gpioModeInput, 1);
+
+		/* Config interrupt */
+		hook.type		= efm32_irq_type_gpio;
+		hook.unit		= ETH_INT_PIN;
+		hook.cbFunc 	= efm_eth_isr;
+		hook.userPtr	= RT_NULL;
+		efm32_irq_hook_register(&hook);
+		/* Clear pending interrupt */
+		BITBAND_Peripheral(&(GPIO->IFC), ETH_INT_PIN, 0x1UL);
+		/* Set falling edge interrupt and clear/enable it */
+		GPIO_IntConfig(
+			ETH_INT_PORT, 
+			ETH_INT_PIN, 
+			false, 
+			true, 
+			true);
+		if ((rt_uint8_t)ETH_INT_PIN % 2)
+		{
+			NVIC_ClearPendingIRQ(GPIO_ODD_IRQn);
+			NVIC_SetPriority(GPIO_ODD_IRQn, EFM32_IRQ_PRI_DEFAULT);
+			NVIC_EnableIRQ(GPIO_ODD_IRQn);
+		}
+		else
+		{
+			NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn);
+			NVIC_SetPriority(GPIO_EVEN_IRQn, EFM32_IRQ_PRI_DEFAULT);
+			NVIC_EnableIRQ(GPIO_EVEN_IRQn);
+		}
+
+		/* Set SPI speed */
+		USART_BaudrateSyncSet(usart->usart_device, 0, ETH_CLK_MAX);
+
+		/* Initialize semaphore */
+		rt_sem_init(&ethLock, "lck_eth", 1, RT_IPC_FLAG_FIFO);
+
+		/* Register Ethernet device */
+		eth_dev.parent.init 	= efm_eth_init;
+		eth_dev.parent.open 	= efm_eth_open;
+		eth_dev.parent.close 	= efm_eth_close;
+		eth_dev.parent.read 	= efm_eth_read;
+		eth_dev.parent.write 	= efm_eth_write;
+		eth_dev.parent.control 	= efm_eth_control;
+		eth_dev.eth_rx 			= efm_eth_rx;
+		eth_dev.eth_tx 			= efm_eth_tx;
+		eth_device_init(&eth_dev, ETH_DEVICE_NAME);
+
+		/* Start device */
+		GPIO_PinOutSet(ETH_RESET_PORT, ETH_RESET_PIN);
+
+		eth_debug("ETH: HW init OK\n");
+		return RT_EOK;
+	} while (0);
+
+	/* Release buffer */
+	rt_kprintf("ETH: HW init failed!\n");
+	return -RT_ERROR;
+}
+
+/***************************************************************************//**
+* 	Export to FINSH
+******************************************************************************/
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+
+void list_eth(void)
+{
+	rt_uint16_t reg_phy;
+	rt_uint8_t data;
+
+	rt_kprintf("    ENC28J60 on %s\n", ETH_USING_DEVICE_NAME);
+	rt_kprintf(" ------------------------------\n");
+	rt_kprintf(" MAC address is %02x %02x %02x %02x %02x %02x\n", 
+		eth_addr[0], eth_addr[1], eth_addr[2], eth_addr[3], eth_addr[4],
+		eth_addr[5], eth_addr[6]);
+	reg_phy = efm_eth_readPhy(PHSTAT2);
+	if (reg_phy & PHSTAT2_PLRITY)
+	{
+		rt_kprintf(" Cable polarity is reversed\n");
+	}
+	else
+	{
+		rt_kprintf(" Cable polarity is correct\n");
+	}
+	if (reg_phy & PHSTAT2_DPXSTAT)
+	{
+		rt_kprintf(" Full-duplex mode\n");
+	}
+	else
+	{
+		rt_kprintf(" Half-duplex mode\n");
+	}
+	if (reg_phy & PHSTAT2_LSTAT)
+	{
+		rt_kprintf(" Link is up\n");
+	}
+	else
+	{
+		rt_kprintf(" Link is down\n");
+	}
+	if (reg_phy & PHSTAT2_COLSTAT)
+	{
+		rt_kprintf(" Collision is occuring\n");
+	}
+	else
+	{
+		rt_kprintf(" No collision\n");
+	}
+	if (reg_phy & PHSTAT2_RXSTAT)
+	{
+		rt_kprintf(" RX is busy\n");
+	}
+	else
+	{
+		rt_kprintf(" RX is idle\n");
+	}
+	if (reg_phy & PHSTAT2_TXSTAT)
+	{
+		rt_kprintf(" TX is busy\n");
+	}
+	else
+	{
+		rt_kprintf(" TX is idle\n");
+	}
+}
+FINSH_FUNCTION_EXPORT(list_eth, list the Ethernet device status.)
+#endif
+
+#endif /* defined(EFM32_USING_ETHERNET) */
+/******************************************************************//**
+ * @}
+ ******************************************************************************/

+ 44 - 0
bsp/efm32/drv_ethernet.h

@@ -0,0 +1,44 @@
+/***************************************************************************//**
+ * @file 	drv_ethernet.h
+ * @brief 	Ethernet driver (SPI mode) of RT-Thread RTOS for using EFM32 USART 
+ *  module
+ * 	 This driver is tested by using the Microchip ENC28J60 stand-alone Ethernet 
+ *  controller with SPI interface.
+ * 	COPYRIGHT (C) 2011, RT-Thread Development Team
+ * @author 	onelife
+ * @version 0.4 beta
+ *******************************************************************************
+ * @section License
+ * 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
+ *******************************************************************************
+ * @section Change Logs
+ * Date			Author		Notes
+ * 2011-06-22	onelife		Initial creation for using EFM32 USART module
+ ******************************************************************************/
+#ifndef __DEV_ETHERNET_H__
+#define __DEV_ETHERNET_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "enc28j60.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+#define ETH_ADDR_LEN 			(6)
+#define ETH_CLK_MAX 			(10000000) 	/* Should be more than 8 Mz (Errata 1) */
+//#define ETH_HALF_DUPLEX
+
+#define ETH_PERIOD_WAIT_INIT 	(RT_TICK_PER_SECOND/100)
+#define ETH_SPI_RX_SKIP 		(1)
+
+
+#define ETH_RESET_PORT 			(gpioPortB)
+#define ETH_RESET_PIN 			(9)
+#define ETH_INT_PORT 			(gpioPortB)
+#define ETH_INT_PIN 			(10)
+
+/* Exported functions ------------------------------------------------------- */
+rt_err_t efm_hw_eth_init(void);
+
+#endif /* __DEV_ETHERNET_H__ */

+ 74 - 67
bsp/efm32/drv_sdcard.c

@@ -1,25 +1,27 @@
-/******************************************************************//**
- * @file 		drv_sdcard.c
- * @brief 	Memory card driver (SPI mode) of RT-Thread RTOS for using EFM32 USART module
+/***************************************************************************//**
+ * @file 	drv_sdcard.c
+ * @brief 	Memory card driver (SPI mode) of RT-Thread RTOS for using EFM32 
+ *  USART module
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	onelife
- * @version 	0.4 beta
- **********************************************************************
+ * @version 0.4 beta
+ *******************************************************************************
  * @section License
- * 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
- **********************************************************************
+ * 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
+ *******************************************************************************
  * @section Change Logs
  * Date			Author		Notes
  * 2011-05-13	onelife		Initial creation for using EFM32 USART module
- *********************************************************************/
+ * 2011-07-07	onelife		Modify initialization function to return error code
+ ******************************************************************************/
 
-/******************************************************************//**
+/***************************************************************************//**
  * @addtogroup efm32_dk
  * @{
-*********************************************************************/
+ ******************************************************************************/
 
-/* Includes -------------------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
 #include "board.h"
 #include "drv_usart.h"
 #include "drv_sdcard.h"
@@ -27,17 +29,17 @@
 #if defined(EFM32_USING_SPISD)
 #include <dfs_fs.h>
 
-/* Private typedef -------------------------------------------------------------*/
-/* Private define --------------------------------------------------------------*/
-/* Private macro --------------------------------------------------------------*/
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
 #ifdef EFM32_SDCARD_DEBUG
 #define sdcard_debug(format,args...) 		rt_kprintf(format, ##args)
 #else
 #define sdcard_debug(format,args...)
 #endif
 
-/* Private constants -----------------------------------------------------------*/
-/* Private variables ------------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
 static struct rt_device 	sd_device;
 static struct dfs_partition	sdPart;
 static rt_device_t 			spi 			= RT_NULL;
@@ -46,9 +48,9 @@ static rt_bool_t 			sdAutoCs 		= true;
 static rt_timer_t 			sdTimer 		= RT_NULL;
 static rt_bool_t 			sdInTime 		= true;
 
-/* Private function prototypes ---------------------------------------------------*/
-/* Private functions ------------------------------------------------------------*/
-/******************************************************************//**
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/***************************************************************************//**
  * @brief
  *   Memory device timeout interrupt handler
  *
@@ -58,13 +60,13 @@ static rt_bool_t 			sdInTime 		= true;
  *
  * @param[in] parameter
  *	Parameter
- *********************************************************************/
+ ******************************************************************************/
 static void efm_spiSd_timer(void* parameter)
 {
 	sdInTime = false;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Set/Clear chip select
  *
@@ -73,8 +75,8 @@ static void efm_spiSd_timer(void* parameter)
  * @note
  *
  * @param[in] enable
- *  Chip select pin status
- *********************************************************************/
+ *  Chip select pin setting
+ ******************************************************************************/
 static void efm_spiSd_cs(rt_uint8_t enable)
 {
 	if (!sdAutoCs)
@@ -90,7 +92,7 @@ static void efm_spiSd_cs(rt_uint8_t enable)
 	}
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Set operation speed level 
  *
@@ -100,7 +102,7 @@ static void efm_spiSd_cs(rt_uint8_t enable)
  *
  * @param[in] level
  *  Set SD speed level 
- *********************************************************************/
+ ******************************************************************************/
 static void efm_spiSd_speed(rt_uint8_t level)
 {
 	RT_ASSERT(spi != RT_NULL);
@@ -120,7 +122,7 @@ static void efm_spiSd_speed(rt_uint8_t level)
 	USART_BaudrateSyncSet(usart->usart_device, 0, baudrate);
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Read raw data from memory device
  *
@@ -136,7 +138,7 @@ static void efm_spiSd_speed(rt_uint8_t level)
  *
  * @return
  *   Number of read bytes
- *********************************************************************/
+ ******************************************************************************/
 static rt_size_t efm_spiSd_read(void *buffer, rt_size_t size)
 {
 	RT_ASSERT(spi != RT_NULL);
@@ -157,7 +159,7 @@ static rt_size_t efm_spiSd_read(void *buffer, rt_size_t size)
 	return ret;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Send command to memory device
  *
@@ -176,7 +178,7 @@ static rt_size_t efm_spiSd_read(void *buffer, rt_size_t size)
  *
  * @return
  *   Command response
- *********************************************************************/
+ ******************************************************************************/
 static rt_uint16_t efm_spiSd_cmd(
 	rt_uint8_t cmd, 
 	rt_uint32_t arg, 
@@ -320,10 +322,10 @@ static rt_uint16_t efm_spiSd_cmd(
 	return ret;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
- *   Read a block of data from memory device. This function is used to handle the responses of 
- *  specified commands (e.g. ACMD13, CMD17 and CMD18)
+ *   Read a block of data from memory device. This function is used to handle 
+ *  the responses of specified commands (e.g. ACMD13, CMD17 and CMD18)
  *
  * @details
  *
@@ -337,7 +339,7 @@ static rt_uint16_t efm_spiSd_cmd(
  *
  * @return
  *   Error code
- *********************************************************************/
+ ******************************************************************************/
 static rt_err_t efm_spiSd_readBlock(void *buffer, rt_size_t size)
 {
 	RT_ASSERT(spi != RT_NULL);
@@ -419,10 +421,10 @@ static rt_err_t efm_spiSd_readBlock(void *buffer, rt_size_t size)
 	return -RT_ERROR;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
- *   Write a block of data to memory device. This function is used to send data and control 
- *  tokens for block write commands (e.g. CMD24 and CMD25) 
+ *   Write a block of data to memory device. This function is used to send data 
+ *  and control tokens for block write commands (e.g. CMD24 and CMD25) 
  *
  * @details
  *
@@ -436,7 +438,7 @@ static rt_err_t efm_spiSd_readBlock(void *buffer, rt_size_t size)
  *
  * @return
  *   Error code
- *********************************************************************/
+ ******************************************************************************/
 static rt_err_t efm_spiSd_writeBlock(void *buffer, rt_uint8_t token)
 {
 	RT_ASSERT(spi != RT_NULL);
@@ -539,7 +541,7 @@ static rt_err_t efm_spiSd_writeBlock(void *buffer, rt_uint8_t token)
 	return ret;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Wrapper function of send command to memory device
  *
@@ -558,7 +560,7 @@ static rt_err_t efm_spiSd_writeBlock(void *buffer, rt_uint8_t token)
  *
  * @return
  *   Command response
- *********************************************************************/
+ ******************************************************************************/
 rt_uint16_t efm_spiSd_sendCmd(
 	rt_uint8_t cmd, 
 	rt_uint32_t arg, 
@@ -580,7 +582,7 @@ rt_uint16_t efm_spiSd_sendCmd(
 	return efm_spiSd_cmd(cmd, arg, trail);
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Initialize memory card device
  *
@@ -593,7 +595,7 @@ rt_uint16_t efm_spiSd_sendCmd(
  *
  * @return
  *   Error code
- *********************************************************************/
+ ******************************************************************************/
 static rt_err_t rt_spiSd_init(rt_device_t dev)
 {
 	RT_ASSERT(spi != RT_NULL);
@@ -606,7 +608,7 @@ static rt_err_t rt_spiSd_init(rt_device_t dev)
 
 	do
 	{
-		/* Setup timer */
+		/* Create and setup timer */
 		if ((sdTimer = rt_timer_create(
 			"sdTimer",
 			efm_spiSd_timer,
@@ -614,7 +616,7 @@ static rt_err_t rt_spiSd_init(rt_device_t dev)
 			SD_WAIT_PERIOD, 
 			RT_TIMER_FLAG_ONE_SHOT)) == RT_NULL)
 		{
-			sdcard_debug("SPISD: Creat timer failed!\n");
+			sdcard_debug("SPISD: Create timer failed!\n");
 			break;
 		}
 
@@ -732,7 +734,7 @@ static rt_err_t rt_spiSd_init(rt_device_t dev)
 	return -RT_ERROR;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Open memory card device
  *
@@ -748,14 +750,14 @@ static rt_err_t rt_spiSd_init(rt_device_t dev)
  *
  * @return
  *   Error code
- *********************************************************************/
+ ******************************************************************************/
 static rt_err_t rt_spiSd_open(rt_device_t dev, rt_uint16_t oflag)
 {
 	sdcard_debug("SPISD: Open, flag %x\n", sd_device.flag);
 	return RT_EOK;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Close memory card device
  *
@@ -768,14 +770,14 @@ static rt_err_t rt_spiSd_open(rt_device_t dev, rt_uint16_t oflag)
  *
  * @return
  *   Error code
- *********************************************************************/
+ ******************************************************************************/
 static rt_err_t rt_spiSd_close(rt_device_t dev)
 {
 	sdcard_debug("SPISD: Close, flag %x\n", sd_device.flag);
 	return RT_EOK;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Read from memory card device
  *
@@ -797,7 +799,7 @@ static rt_err_t rt_spiSd_close(rt_device_t dev)
  *
  * @return
  *   Number of read sectors
- *********************************************************************/
+ ******************************************************************************/
 static rt_size_t rt_spiSd_read(
 	rt_device_t 	dev, 
 	rt_off_t 		sector,
@@ -865,7 +867,7 @@ static rt_size_t rt_spiSd_read(
 	return (0);
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Write to memory card device
  *
@@ -887,7 +889,7 @@ static rt_size_t rt_spiSd_read(
  *
  * @return
  *   Number of written sectors
- *********************************************************************/
+ ******************************************************************************/
 static rt_size_t rt_spiSd_write (
 	rt_device_t 	dev, 
 	rt_off_t 		sector,
@@ -961,7 +963,7 @@ static rt_size_t rt_spiSd_write (
 	return (0);
 }
 
-/******************************************************************//**
+/***************************************************************************//**
 * @brief
 *   Configure memory card device
 *
@@ -980,7 +982,7 @@ static rt_size_t rt_spiSd_write (
 *
 * @return
 *   Error code
-*********************************************************************/
+******************************************************************************/
 static rt_err_t rt_spiSd_control (
 	rt_device_t 	dev, 
 	rt_uint8_t 		ctrl, 
@@ -1171,15 +1173,19 @@ static rt_err_t rt_spiSd_control (
 	return ret;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
 * @brief
-*	Initialize all memory card related hardware and register the device to kernel
+*	Initialize all memory card related hardware and register the device to 
+*  kernel
 *
 * @details
 *
 * @note
-*********************************************************************/
-void efm_spiSd_init(void)
+*
+* @return
+*	Error code
+******************************************************************************/
+rt_err_t efm_spiSd_init(void)
 {
 	struct efm32_usart_device_t *usart;
 
@@ -1222,21 +1228,22 @@ void efm_spiSd_init(void)
 			RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
 
 		sdcard_debug("SPISD: HW init OK, card type %x\n", sdType);
-		return;
+		return RT_EOK;
 	} while (0);
 
 	/* Release buffer */
 	rt_kprintf("SPISD: HW init failed!\n");
+	return -RT_ERROR;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   De-initialize memory card device
  *
  * @details
  *
  * @note
- *********************************************************************/
+ ******************************************************************************/
 void efm_spiSd_deinit(void)
 {
 	/* Close SPI device */
@@ -1257,13 +1264,13 @@ void efm_spiSd_deinit(void)
 	sdcard_debug("SPISD: Deinit OK\n");
 }
 
-/*********************************************************************
+/***************************************************************************//**
 * 	Export to FINSH
-*********************************************************************/
+******************************************************************************/
 #ifdef RT_USING_FINSH
 #include <finsh.h>
 
-void list_sdcard(void)
+void list_sd(void)
 {
 	rt_uint8_t buf_res[16];
 	rt_uint32_t capacity, temp32;
@@ -1307,10 +1314,10 @@ void list_sdcard(void)
 	capacity >>= 4;
 	rt_kprintf(" Card capacity:\t\t%dMB\n", capacity);
 }
-FINSH_FUNCTION_EXPORT(list_sdcard, list the SD card.)
+FINSH_FUNCTION_EXPORT(list_sd, list the SD card.)
 #endif
 
 #endif /* defined(EFM32_USING_SPISD) */
-/******************************************************************//**
+/***************************************************************************//**
  * @}
-*********************************************************************/
+ ******************************************************************************/

+ 17 - 15
bsp/efm32/drv_sdcard.h

@@ -1,25 +1,27 @@
-/******************************************************************//**
- * @file 		drv_sdcard.h
- * @brief 	Memory card driver (SPI mode) of RT-Thread RTOS for using EFM32 USART module
+/***************************************************************************//**
+ * @file 	drv_sdcard.h
+ * @brief 	Memory card driver (SPI mode) of RT-Thread RTOS for using EFM32 
+ *  USART module
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	onelife
- * @version 	0.4 beta
- **********************************************************************
+ * @version 0.4 beta
+ *******************************************************************************
  * @section License
- * 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
- **********************************************************************
+ * 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
+ *******************************************************************************
  * @section Change Logs
  * Date			Author		Notes
  * 2011-05-13	onelife		Initial creation for using EFM32 USART module
- *********************************************************************/
+ * 2011-07-07	onelife		Modify initialization function to return error code
+ ******************************************************************************/
 #ifndef __DEV_SDCARD_H__
 #define __DEV_SDCARD_H__
 
-/* Includes -------------------------------------------------------------------*/
-/* Exported types -------------------------------------------------------------*/
-/* Exported constants ---------------------------------------------------------*/
-/* Exported macro -------------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
 #define EFM32_SDCLK_LOW 		(100000)
 #define EFM32_SDCLK_HIGH		(EFM32_HFXO_FREQUENCY/2)
 
@@ -61,8 +63,8 @@
 #define CMD55 					(55) 		/* APP_CMD */
 #define CMD58 					(58) 		/* READ_OCR */
 
-/* Exported functions --------------------------------------------------------- */
-void efm_spiSd_init(void);
+/* Exported functions ------------------------------------------------------- */
+rt_err_t efm_spiSd_init(void);
 void efm_spiSd_deinit(void);
 
 #endif /* __DEV_SDCARD_H__ */

+ 58 - 55
bsp/efm32/drv_usart.c

@@ -1,14 +1,14 @@
-/******************************************************************//**
- * @file 		drv_usart.c
+/***************************************************************************//**
+ * @file 	drv_usart.c
  * @brief 	USART driver of RT-Thread RTOS for EFM32
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	onelife
- * @version 	0.4 beta
- **********************************************************************
+ * @version 0.4 beta
+ *******************************************************************************
  * @section License
- * 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
- **********************************************************************
+ * 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
+ *******************************************************************************
  * @section Change Logs
  * Date			Author		Notes
  * 2010-12-22	onelife		Initial creation for EFM32
@@ -16,40 +16,42 @@
  * 2011-05-06	onelife		Add sync mode (SPI) support
  * 2011-06-14	onelife		Fix a bug of TX by DMA
  * 2011-06-16	onelife		Modify init function for efm32lib v2 upgrading
+ * 2011-07-07	onelife		Modify write function to avoid sleep in ISR
  *
  * @section Change Logs of serial.c
  * 2009-02-05	Bernard		first version
- * 2009-10-25	Bernard		fix rt_serial_read bug when there is no data in the buffer.
+ * 2009-10-25	Bernard		fix rt_serial_read bug when there is no data in the 
+ *  buffer.
  * 2010-03-29	Bernard		cleanup code.
- *********************************************************************/
+ ******************************************************************************/
 
-/******************************************************************//**
+/***************************************************************************//**
  * @addtogroup efm32
  * @{
-*********************************************************************/
+ ******************************************************************************/
 
-/* Includes -------------------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
 #include "board.h"
 #include "hdl_interrupt.h"
 #include "drv_usart.h"
 
 #if (defined(RT_USING_USART0) || defined(RT_USING_USART1) || defined(RT_USING_USART2))
-/* Private typedef -------------------------------------------------------------*/
+/* Private typedef -----------------------------------------------------------*/
 union efm32_usart_init_t
 {
 	USART_InitAsync_TypeDef 	async;
 	USART_InitSync_TypeDef		sync;
 };
 
-/* Private define --------------------------------------------------------------*/
-/* Private macro --------------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
 #ifdef RT_USART_DEBUG
 #define usart_debug(format,args...) 		rt_kprintf(format, ##args)
 #else
 #define usart_debug(format,args...)
 #endif
 
-/* Private variables ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
 #ifdef RT_USING_USART0
 #if (RT_USING_USART0 > 3)
 	#error "The location number range of usart is 0~3"
@@ -71,9 +73,9 @@ union efm32_usart_init_t
 	struct rt_device usart2_device;
 #endif
 
-/* Private function prototypes ---------------------------------------------------*/
-/* Private functions ------------------------------------------------------------*/
-/******************************************************************//**
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/***************************************************************************//**
  * @brief
  *   Initialize USART device
  *
@@ -86,7 +88,7 @@ union efm32_usart_init_t
  *
  * @return
  *   Error code
- *********************************************************************/
+ ******************************************************************************/
 static rt_err_t rt_usart_init (rt_device_t dev)
 {
 	struct efm32_usart_device_t *usart;
@@ -122,7 +124,7 @@ static rt_err_t rt_usart_init (rt_device_t dev)
 	return RT_EOK;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Open USART device
  *
@@ -138,7 +140,7 @@ static rt_err_t rt_usart_init (rt_device_t dev)
  *
  * @return
  *   Error code
- *********************************************************************/
+ ******************************************************************************/
 static rt_err_t rt_usart_open(rt_device_t dev, rt_uint16_t oflag)
 {
 	RT_ASSERT(dev != RT_NULL);
@@ -205,7 +207,7 @@ static rt_err_t rt_usart_open(rt_device_t dev, rt_uint16_t oflag)
 	return RT_EOK;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Close USART device
  *
@@ -218,7 +220,7 @@ static rt_err_t rt_usart_open(rt_device_t dev, rt_uint16_t oflag)
  *
  * @return
  *   Error code
- *********************************************************************/
+ ******************************************************************************/
 static rt_err_t rt_usart_close(rt_device_t dev)
 {
 	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
@@ -234,7 +236,7 @@ static rt_err_t rt_usart_close(rt_device_t dev)
 	return RT_EOK;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Read from USART device
  *
@@ -256,7 +258,7 @@ static rt_err_t rt_usart_close(rt_device_t dev)
  *
  * @return
  *   Number of read bytes
- *********************************************************************/
+ ******************************************************************************/
 static rt_size_t rt_usart_read (
 	rt_device_t 	dev, 
 	rt_off_t 		pos, 
@@ -387,7 +389,7 @@ static rt_size_t rt_usart_read (
 	return read_len;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *   Write to USART device
  *
@@ -409,7 +411,7 @@ static rt_size_t rt_usart_read (
  *
  * @return
  *   Number of written bytes
- *********************************************************************/
+ ******************************************************************************/
 static rt_size_t rt_usart_write (
 	rt_device_t 	dev, 
 	rt_off_t 		pos, 
@@ -424,7 +426,7 @@ static rt_size_t rt_usart_write (
 	write_size = 0;
 	usart = (struct efm32_usart_device_t*)(dev->user_data);
 
-	if ((dev->flag & RT_DEVICE_FLAG_DMA_TX) && (size > 1))
+	if ((dev->flag & RT_DEVICE_FLAG_DMA_TX) && (size > 2))
 	{	/* DMA mode Tx */
 		struct efm32_usart_dma_mode_t *dma_tx;
 	
@@ -453,18 +455,18 @@ static rt_size_t rt_usart_write (
 			(rt_uint32_t)(size - 1));
 
 		/* Wait, otherwise the TX buffer is overwrite */
-		if (usart->state & USART_STATE_CONSOLE)
-		{
+//		if (usart->state & USART_STATE_CONSOLE)
+//		{
 			while(usart->state & USART_STATE_TX_BUSY);
-		}
-		else
-		{
-			while(usart->state & USART_STATE_TX_BUSY)
-			{
-				rt_thread_sleep(USART_WAIT_TIME_TX);
-			}
-		}
-		
+//		}
+//		else
+//		{
+//			while(usart->state & USART_STATE_TX_BUSY)
+//			{
+//				rt_thread_sleep(USART_WAIT_TIME_TX);
+//			}
+//		}
+// TODO: This function blocks the process		
 		write_size = size;
 	}
 	else
@@ -506,7 +508,7 @@ static rt_size_t rt_usart_write (
 	return write_size;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
 * @brief
 *	Configure USART device
 *
@@ -525,7 +527,7 @@ static rt_size_t rt_usart_write (
 *
 * @return
 *	Error code
-*********************************************************************/
+******************************************************************************/
 static rt_err_t rt_usart_control (
 	rt_device_t 	dev, 
 	rt_uint8_t 		cmd, 
@@ -601,7 +603,7 @@ static rt_err_t rt_usart_control (
 	return RT_EOK;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *	USART RX data valid interrupt handler
  *
@@ -611,7 +613,7 @@ static rt_err_t rt_usart_control (
  *
  * @param[in] dev
  *	Pointer to device descriptor
- *********************************************************************/
+ ******************************************************************************/
 void rt_hw_usart_rx_isr(rt_device_t dev)
 {
 	struct efm32_usart_device_t 	*usart;
@@ -671,7 +673,7 @@ void rt_hw_usart_rx_isr(rt_device_t dev)
 	}
 }
 
-/******************************************************************//**
+/***************************************************************************//**
  * @brief
  *	DMA for USART TX interrupt handler
  *
@@ -681,7 +683,7 @@ void rt_hw_usart_rx_isr(rt_device_t dev)
  *
  * @param[in] dev
  *	Pointer to device descriptor
- *********************************************************************/
+ ******************************************************************************/
 void rt_hw_usart_dma_tx_isr(rt_device_t dev)
 {
 	/* DMA mode receive */
@@ -703,7 +705,7 @@ void rt_hw_usart_dma_tx_isr(rt_device_t dev)
 	usart->state &= ~(rt_uint32_t)USART_STATE_TX_BUSY;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
 * @brief
 *	Register USART device
 *
@@ -725,7 +727,7 @@ void rt_hw_usart_dma_tx_isr(rt_device_t dev)
 *
 * @return
 *	Error code
-*********************************************************************/
+******************************************************************************/
 rt_err_t rt_hw_usart_register(
 	rt_device_t		device, 
 	const char		*name, 
@@ -755,7 +757,7 @@ rt_err_t rt_hw_usart_register(
 	return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
 }
 
-/******************************************************************//**
+/***************************************************************************//**
 * @brief
 *	Initialize the specified USART unit 
 *
@@ -783,7 +785,7 @@ rt_err_t rt_hw_usart_register(
 *
 * @return
 *	Pointer to USART device  
-*********************************************************************/
+******************************************************************************/
 static struct efm32_usart_device_t *rt_hw_usart_unit_init(
 	rt_device_t device,
 	rt_uint8_t 	unitNumber, 
@@ -1018,14 +1020,15 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init(
 	return RT_NULL;
 }
 
-/******************************************************************//**
+/***************************************************************************//**
 * @brief
-*	Initialize all USART module related hardware and register USART device to kernel
+*   Initialize all USART module related hardware and register USART device to 
+* kernel
 *
 * @details
 *
 * @note
-*********************************************************************/
+******************************************************************************/
 void rt_hw_usart_init(void)
 {
 	struct efm32_usart_device_t	*usart;
@@ -1169,6 +1172,6 @@ void rt_hw_usart_init(void)
 }
 
 #endif
-/******************************************************************//**
+/***************************************************************************//**
  * @}
-*********************************************************************/
+ ******************************************************************************/

+ 15 - 14
bsp/efm32/drv_usart.h

@@ -1,23 +1,24 @@
-/******************************************************************//**
- * @file 		drv_usart.h
+/***************************************************************************//**
+ * @file 	drv_usart.h
  * @brief 	USART driver of RT-Thread RTOS for EFM32
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	onelife
- * @version 	0.4 beta
- **********************************************************************
+ * @version 0.4 beta
+ *******************************************************************************
  * @section License
- * 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
- **********************************************************************
+ * 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
+ *******************************************************************************
  * @section Change Logs
  * Date			Author		Notes
  * 2010-12-22	onelife		Initial creation for EFM32
- *********************************************************************/
+ * 2011-06-27	onelife		Fix a bug when using compiler optimization
+ ******************************************************************************/
 #ifndef __DRV_USART_H__
 #define __DRV_USART_H__
 
-/* Includes -------------------------------------------------------------------*/
-/* Exported types -------------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
 struct efm32_usart_int_mode_t
 {
 	rt_uint8_t  *data_ptr;
@@ -40,7 +41,7 @@ struct efm32_usart_device_t
 	/* Unit number */
 	rt_uint8_t unit;
 	/* State */
-	rt_uint8_t state;
+	volatile rt_uint8_t state;
 	/*  Pointer to USART device structure */
 	USART_TypeDef* usart_device;
 	/* Pointer to RX structure */
@@ -49,8 +50,8 @@ struct efm32_usart_device_t
 	void *tx_mode;
 };
 
-/* Exported constants ---------------------------------------------------------*/
-/* Exported macro -------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
 #define USART_WAIT_TIME_TX		(RT_TICK_PER_SECOND / 100 * 3)
 
 #define USART_STATE_CONSOLE 	(1 << 0)
@@ -61,7 +62,7 @@ struct efm32_usart_device_t
 #define USART_STATE_RX_BUSY 	(1 << 5)
 
 
-/* Exported functions --------------------------------------------------------- */
+/* Exported functions ------------------------------------------------------- */
 void rt_hw_usart_init(void);
 
 #endif /* __DRV_USART_H__ */

+ 45 - 13
bsp/efm32/efm32_rom.ld

@@ -1,21 +1,22 @@
-/******************************************************************//**
+/***************************************************************************//**
  * @file 		efm32_rom.ld
  * @brief 	Linker script for EFM32 with GNU ld
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	Bernard, onelife
  * @version 	0.4 beta
- **********************************************************************
+ *******************************************************************************
  * @section License
- * 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
- **********************************************************************
+ * 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
+ *******************************************************************************
  * @section Change Logs
  * Date			Author		Notes
- * 2009-10-14 	Bernard 		first version
+ * 2009-10-14 	Bernard 	first version
  * 2010-12-22	onelife		Modify for EFM32
- *********************************************************************/
+ * 2011-07-06 	onelife 	Modify to make use the start code in libraries
+ ******************************************************************************/
 OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(Reset_Handler)
+ENTRY(__cs3_reset)
 SEARCH_DIR(.)
 GROUP(-lgcc -lc -lcs3 -lcs3unhosted) 
 
@@ -24,20 +25,36 @@ MEMORY
 	CODE (rx) : ORIGIN = 0x00000000, LENGTH = 128K
 	DATA (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
 }
+_system_stack_size = 0x200;
+
+/* These force the linker to search for particular symbols from
+ * the start of the link process and thus ensure the user's
+ * overrides are picked up
+ */
+
+EXTERN(__cs3_reset __cs3_reset_efm32)
+EXTERN(__cs3_start_asm _start)
+
+PROVIDE(__cs3_reset = __cs3_reset_efm32);
+PROVIDE(__cs3_start_asm = _start);
 
 SECTIONS
 {
 	.text :
 	{
 		. = ALIGN(4);
-		KEEP(*(.isr_vector))            /* Startup code */
+		KEEP(*(.cs3.interrupt_vector))  /* Startup code */
 		. = ALIGN(4);
+
+		*(.cs3.reset)
+		*(.cs3.init)
 		*(.text)						/* remaining code */
 		*(.text.*)						/* remaining code */
 		*(.rodata)						/* read-only data (constants) */
 		*(.rodata*)
 		*(.glue_7)
 		*(.glue_7t)
+		*(.gnu.linkonce.t*)
 
 		/* section information for finsh shell */
 		. = ALIGN(4);
@@ -52,13 +69,20 @@ SECTIONS
 
 		. = ALIGN(4);
 		_etext = .;
+	} > CODE = 0
+
+	/* .ARM.exidx is sorted, so has to go in its own output section.  */
+	__exidx_start = .;
+	.ARM.exidx :
+	{
+		*(.ARM.exidx* .gnu.linkonce.armexidx.*)
 
 		/* This is used by the startup in order to initialize the .data secion */
-		_sidata = _etext;
-	} > CODE = 0
+		_sidata = .;
+	} > CODE
+	__exidx_end = .;
 
 	/* .data section which is used for initialized data */
-
 	.data : AT (_sidata)
 	{
 		. = ALIGN(4);
@@ -67,12 +91,20 @@ SECTIONS
 
 		*(.data)
 		*(.data.*)
+		*(.gnu.linkonce.d*)
 
 		. = ALIGN(4);
 		/* This is used by the startup in order to initialize the .data secion */
 		_edata = . ;
 	} >DATA
 
+	.stack : 
+	{
+		. = . + _system_stack_size;
+		. = ALIGN(4);
+		__cs3_stack = .;
+	} >DATA
+
 	__bss_start = .;
 	.bss :
 	{
@@ -81,12 +113,12 @@ SECTIONS
 		_sbss = .;
 
 		*(.bss)
+		*(.bss.*)
 		*(COMMON)
 
 		. = ALIGN(4);
 		/* This is used by the startup in order to initialize the .bss secion */
 		_ebss = . ;
-		_estack = .;
 		
 		*(.bss.init)
 	} > DATA

+ 313 - 0
bsp/efm32/enc28j60.h

@@ -0,0 +1,313 @@
+/*
+ * File      : enc28j60.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, 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
+ * 2009-01-05     Bernard      the first version
+ */
+
+#ifndef __ENC28J60_H__
+#define __ENC28J60_H__
+
+#include <rtthread.h>
+
+// ENC28J60 Control Registers
+// Control register definitions are a combination of address,
+// bank number, and Ethernet/MAC/PHY indicator bits.
+// - Register address        (bits 0-4)
+// - Bank number        (bits 5-6)
+// - MAC/PHY indicator        (bit 7)
+#define ADDR_MASK        0x1F
+#define BANK_MASK        0x60
+#define SPRD_MASK        0x80
+#define ADDR_SHIFT       (0)
+#define BANK_SHIFT       (5)
+#define SPRD_SHIFT       (7)
+// All-bank registers
+#define EIE              0x1B
+#define EIR              0x1C
+#define ESTAT            0x1D
+#define ECON2            0x1E
+#define ECON1            0x1F
+// Bank 0 registers
+#define ERDPTL           (0x00|0x00)
+#define ERDPTH           (0x01|0x00)
+#define EWRPTL           (0x02|0x00)
+#define EWRPTH           (0x03|0x00)
+#define ETXSTL           (0x04|0x00)
+#define ETXSTH           (0x05|0x00)
+#define ETXNDL           (0x06|0x00)
+#define ETXNDH           (0x07|0x00)
+#define ERXSTL           (0x08|0x00)
+#define ERXSTH           (0x09|0x00)
+#define ERXNDL           (0x0A|0x00)
+#define ERXNDH           (0x0B|0x00)
+#define ERXRDPTL         (0x0C|0x00)
+#define ERXRDPTH         (0x0D|0x00)
+#define ERXWRPTL         (0x0E|0x00)
+#define ERXWRPTH         (0x0F|0x00)
+#define EDMASTL          (0x10|0x00)
+#define EDMASTH          (0x11|0x00)
+#define EDMANDL          (0x12|0x00)
+#define EDMANDH          (0x13|0x00)
+#define EDMADSTL         (0x14|0x00)
+#define EDMADSTH         (0x15|0x00)
+#define EDMACSL          (0x16|0x00)
+#define EDMACSH          (0x17|0x00)
+// Bank 1 registers
+#define EHT0             (0x00|0x20)
+#define EHT1             (0x01|0x20)
+#define EHT2             (0x02|0x20)
+#define EHT3             (0x03|0x20)
+#define EHT4             (0x04|0x20)
+#define EHT5             (0x05|0x20)
+#define EHT6             (0x06|0x20)
+#define EHT7             (0x07|0x20)
+#define EPMM0            (0x08|0x20)
+#define EPMM1            (0x09|0x20)
+#define EPMM2            (0x0A|0x20)
+#define EPMM3            (0x0B|0x20)
+#define EPMM4            (0x0C|0x20)
+#define EPMM5            (0x0D|0x20)
+#define EPMM6            (0x0E|0x20)
+#define EPMM7            (0x0F|0x20)
+#define EPMCSL           (0x10|0x20)
+#define EPMCSH           (0x11|0x20)
+#define EPMOL            (0x14|0x20)
+#define EPMOH            (0x15|0x20)
+#define ERXFCON          (0x18|0x20)
+#define EPKTCNT          (0x19|0x20)
+// Bank 2 registers
+#define MACON1           (0x00|0x40|0x80)
+#define MACON3           (0x02|0x40|0x80)
+#define MACON4           (0x03|0x40|0x80)
+#define MABBIPG          (0x04|0x40|0x80)
+#define MAIPGL           (0x06|0x40|0x80)
+#define MAIPGH           (0x07|0x40|0x80)
+#define MACLCON1         (0x08|0x40|0x80)
+#define MACLCON2         (0x09|0x40|0x80)
+#define MAMXFLL          (0x0A|0x40|0x80)
+#define MAMXFLH          (0x0B|0x40|0x80)
+#define MICMD            (0x12|0x40|0x80)
+#define MIREGADR         (0x14|0x40|0x80)
+#define MIWRL            (0x16|0x40|0x80)
+#define MIWRH            (0x17|0x40|0x80)
+#define MIRDL            (0x18|0x40|0x80)
+#define MIRDH            (0x19|0x40|0x80)
+// Bank 3 registers
+#define MAADR5           (0x00|0x60|0x80)
+#define MAADR6           (0x01|0x60|0x80)
+#define MAADR3           (0x02|0x60|0x80)
+#define MAADR4           (0x03|0x60|0x80)
+#define MAADR1           (0x04|0x60|0x80)
+#define MAADR2           (0x05|0x60|0x80)
+#define EBSTSD           (0x06|0x60)
+#define EBSTCON          (0x07|0x60)
+#define EBSTCSL          (0x08|0x60)
+#define EBSTCSH          (0x09|0x60)
+#define MISTAT           (0x0A|0x60|0x80)
+#define EREVID           (0x12|0x60)
+#define ECOCON           (0x15|0x60)
+#define EFLOCON          (0x17|0x60)
+#define EPAUSL           (0x18|0x60)
+#define EPAUSH           (0x19|0x60)
+// PHY registers
+#define PHCON1           0x00
+#define PHSTAT1          0x01
+#define PHHID1           0x02
+#define PHHID2           0x03
+#define PHCON2           0x10
+#define PHSTAT2          0x11
+#define PHIE             0x12
+#define PHIR             0x13
+#define PHLCON           0x14
+
+// ENC28J60 ERXFCON Register Bit Definitions
+#define ERXFCON_UCEN     0x80
+#define ERXFCON_ANDOR    0x40
+#define ERXFCON_CRCEN    0x20
+#define ERXFCON_PMEN     0x10
+#define ERXFCON_MPEN     0x08
+#define ERXFCON_HTEN     0x04
+#define ERXFCON_MCEN     0x02
+#define ERXFCON_BCEN     0x01
+// ENC28J60 EIE Register Bit Definitions
+#define EIE_INTIE        0x80
+#define EIE_PKTIE        0x40
+#define EIE_DMAIE        0x20
+#define EIE_LINKIE       0x10
+#define EIE_TXIE         0x08
+#define EIE_WOLIE        0x04
+#define EIE_TXERIE       0x02
+#define EIE_RXERIE       0x01
+// ENC28J60 EIR Register Bit Definitions
+#define EIR_PKTIF        0x40
+#define EIR_DMAIF        0x20
+#define EIR_LINKIF       0x10
+#define EIR_TXIF         0x08
+#define EIR_WOLIF        0x04
+#define EIR_TXERIF       0x02
+#define EIR_RXERIF       0x01
+// ENC28J60 ESTAT Register Bit Definitions
+#define ESTAT_INT        0x80
+#define ESTAT_LATECOL    0x10
+#define ESTAT_RXBUSY     0x04
+#define ESTAT_TXABRT     0x02
+#define ESTAT_CLKRDY     0x01
+// ENC28J60 ECON2 Register Bit Definitions
+#define ECON2_AUTOINC    0x80
+#define ECON2_PKTDEC     0x40
+#define ECON2_PWRSV      0x20
+#define ECON2_VRPS       0x08
+// ENC28J60 ECON1 Register Bit Definitions
+#define ECON1_TXRST      0x80
+#define ECON1_RXRST      0x40
+#define ECON1_DMAST      0x20
+#define ECON1_CSUMEN     0x10
+#define ECON1_TXRTS      0x08
+#define ECON1_RXEN       0x04
+#define ECON1_BSEL1      0x02
+#define ECON1_BSEL0      0x01
+// ENC28J60 MACON1 Register Bit Definitions
+#define MACON1_LOOPBK    0x10
+#define MACON1_TXPAUS    0x08
+#define MACON1_RXPAUS    0x04
+#define MACON1_PASSALL   0x02
+#define MACON1_MARXEN    0x01
+// ENC28J60 MACON2 Register Bit Definitions
+#define MACON2_MARST     0x80
+#define MACON2_RNDRST    0x40
+#define MACON2_MARXRST   0x08
+#define MACON2_RFUNRST   0x04
+#define MACON2_MATXRST   0x02
+#define MACON2_TFUNRST   0x01
+// ENC28J60 MACON3 Register Bit Definitions
+#define MACON3_PADCFG2   0x80
+#define MACON3_PADCFG1   0x40
+#define MACON3_PADCFG0   0x20
+#define MACON3_TXCRCEN   0x10
+#define MACON3_PHDRLEN   0x08
+#define MACON3_HFRMLEN   0x04
+#define MACON3_FRMLNEN   0x02
+#define MACON3_FULDPX    0x01
+// ENC28J60 MACON4 Register Bit Definitions
+#define	MACON4_DEFER	(1<<6)
+#define	MACON4_BPEN		(1<<5)
+#define	MACON4_NOBKOFF	(1<<4)
+// ENC28J60 MICMD Register Bit Definitions
+#define MICMD_MIISCAN    0x02
+#define MICMD_MIIRD      0x01
+// ENC28J60 MISTAT Register Bit Definitions
+#define MISTAT_NVALID    0x04
+#define MISTAT_SCAN      0x02
+#define MISTAT_BUSY      0x01
+// ENC28J60 PHY PHCON1 Register Bit Definitions
+#define PHCON1_PRST      0x8000
+#define PHCON1_PLOOPBK   0x4000
+#define PHCON1_PPWRSV    0x0800
+#define PHCON1_PDPXMD    0x0100
+// ENC28J60 PHY PHSTAT1 Register Bit Definitions
+#define PHSTAT1_PFDPX    0x1000
+#define PHSTAT1_PHDPX    0x0800
+#define PHSTAT1_LLSTAT   0x0004
+#define PHSTAT1_JBSTAT   0x0002
+/* ENC28J60 PHY PHSTAT2 Register Bit Definitions */
+#define PHSTAT2_TXSTAT	(1 << 13)
+#define PHSTAT2_RXSTAT	(1 << 12)
+#define PHSTAT2_COLSTAT	(1 << 11)
+#define PHSTAT2_LSTAT	(1 << 10)
+#define PHSTAT2_DPXSTAT	(1 << 9)
+#define PHSTAT2_PLRITY	(1 << 5)
+// ENC28J60 PHY PHCON2 Register Bit Definitions
+#define PHCON2_FRCLINK   0x4000
+#define PHCON2_TXDIS     0x2000
+#define PHCON2_JABBER    0x0400
+#define PHCON2_HDLDIS    0x0100
+
+// ENC28J60 Packet Control Byte Bit Definitions
+#define PKTCTRL_PHUGEEN  0x08
+#define PKTCTRL_PPADEN   0x04
+#define PKTCTRL_PCRCEN   0x02
+#define PKTCTRL_POVERRIDE 0x01
+
+/* ENC28J60 Transmit Status Vector */
+#define TSV_TXBYTECNT           0
+#define TSV_TXCOLLISIONCNT      16
+#define TSV_TXCRCERROR          20
+#define TSV_TXLENCHKERROR       21
+#define TSV_TXLENOUTOFRANGE     22
+#define TSV_TXDONE              23
+#define TSV_TXMULTICAST         24
+#define TSV_TXBROADCAST         25
+#define TSV_TXPACKETDEFER       26
+#define TSV_TXEXDEFER           27
+#define TSV_TXEXCOLLISION       28
+#define TSV_TXLATECOLLISION     29
+#define TSV_TXGIANT             30
+#define TSV_TXUNDERRUN          31
+#define TSV_TOTBYTETXONWIRE     32
+#define TSV_TXCONTROLFRAME      48
+#define TSV_TXPAUSEFRAME        49
+#define TSV_BACKPRESSUREAPP     50
+#define TSV_TXVLANTAGFRAME      51
+
+#define TSV_SIZE                7
+#define TSV_BYTEOF(x)           ((x) / 8)
+#define TSV_BITMASK(x)          (1 << ((x) % 8))
+#define TSV_GETBIT(x, y)        (((x)[TSV_BYTEOF(y)] & TSV_BITMASK(y)) ? 1 : 0)
+
+/* ENC28J60 Receive Status Vector */
+#define RSV_RXLONGEVDROPEV      16
+#define RSV_CARRIEREV           18
+#define RSV_CRCERROR            20
+#define RSV_LENCHECKERR         21
+#define RSV_LENOUTOFRANGE       22
+#define RSV_RXOK                23
+#define RSV_RXMULTICAST         24
+#define RSV_RXBROADCAST         25
+#define RSV_DRIBBLENIBBLE       26
+#define RSV_RXCONTROLFRAME      27
+#define RSV_RXPAUSEFRAME        28
+#define RSV_RXUNKNOWNOPCODE     29
+#define RSV_RXTYPEVLAN          30
+
+#define RSV_SIZE                6
+#define RSV_BITMASK(x)          (1 << ((x) - 16))
+#define RSV_GETBIT(x, y)        (((x) & RSV_BITMASK(y)) ? 1 : 0)
+
+// SPI operation codes
+#define ENC28J60_READ_CTRL_REG 		(0x00)
+#define ENC28J60_READ_BUF_MEM 		(0x20 | 0x1A)
+#define ENC28J60_WRITE_CTRL_REG 	(0x40)
+#define ENC28J60_WRITE_BUF_MEM 		(0x60 | 0x1A)
+#define ENC28J60_BIT_FIELD_SET 		(0x80)
+#define ENC28J60_BIT_FIELD_CLR 		(0xA0)
+#define ENC28J60_SOFT_RESET 		(0xE0 | 0x1F)
+
+// The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata
+// buffer boundaries applied to internal 8K ram
+// the entire available packet buffer space is allocated
+//
+
+// start with recbuf at 0/
+#define RXSTART_INIT	0x0
+// receive buffer end
+#define RXSTOP_INIT		(0x1FFF - 0x0600 - 1)
+// start TX buffer at 0x1FFF-0x0600, pace for one full ethernet frame (~1500 bytes)
+
+#define TXSTART_INIT	(0x1FFF - 0x0600)
+// stp TX buffer at end of mem
+#define TXSTOP_INIT		0x1FFF
+
+// max frame length which the conroller will accept:
+#define MAX_FRAMELEN	1518
+
+void rt_hw_enc28j60_init(void);
+
+#endif

+ 237 - 0
bsp/efm32/httpd.c

@@ -0,0 +1,237 @@
+/***************************************************************************//**
+ * @file 	httpd.c
+ * @brief 	Simple http server demo application
+ * 	COPYRIGHT (C) 2011, RT-Thread Development Team
+ * @author 	onelife
+ * @version 0.4 beta
+ *******************************************************************************
+ * @section License
+ * 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
+ *******************************************************************************
+ * @section Change Logs
+ * Date			Author		Notes
+ * 2011-07-04	onelife		Derive from Energy Micro demo application
+ ******************************************************************************/
+ 
+/**************************************************************************//**
+ * @file
+ * @brief This file is dervied from the ``httpd.c'' skeleton.
+ * @author Energy Micro AS
+ * @@version 0.0.4
+ ******************************************************************************
+ * @section License
+ * <b>(C) Copyright 2009 Energy Micro AS, http://www.energymicro.com</b>
+ ******************************************************************************
+ *
+ * This source code is the property of Energy Micro AS. The source and compiled
+ * code may only be used on Energy Micro "EFM32" microcontrollers.
+ *
+ * This copyright notice may not be removed from the source code nor changed.
+ *
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
+ * obligation to support this Software. Energy Micro AS is providing the
+ * Software "AS IS", with no express or implied warranties of any kind,
+ * including, but not limited to, any implied warranties of merchantability
+ * or fitness for any particular purpose or warranties against infringement
+ * of any proprietary rights of a third party.
+ *
+ * Energy Micro AS will not be liable for any consequential, incidental, or
+ * special damages, or any other relief, or for any claim by any third party,
+ * arising from your use of this Software.
+ *
+ *****************************************************************************/
+/**
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/***************************************************************************//**
+* @addtogroup efm32_eth
+* @{
+******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "rtthread.h"
+#include "dev_misc.h"
+
+#if defined(RT_USING_LWIP)
+#include "lwip\tcp.h"
+#include "lwip\ip_addr.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* This is the data for the actual web page. */
+static int temp, vdd;
+static char indexdata[700];
+static const char indexdata1[] =
+	"HTTP/1.0 200 OK\r\n\
+	Content-type: text/html\r\n\
+	Pragma: no-cache\r\n\
+	Refresh: 5\r\n\
+	\r\n\
+	<html>\
+	<head><title>EFM32 HTTPD DEMO</title><head>\
+	<body>\
+	<h1>This is a simple http server</h1>\
+	<br><br><B>Ethernet controller: ENC28J60</B>\
+	<br><br><B>Refreshing timers: ";
+
+static const char indexdata2[] =
+	"<br><br><B>Current Vdd: ";
+
+static const char indexdata3[] =
+	" V</B>\
+	<br><br><B>Current temperature: ";
+
+static const char indexdata4[] =
+	" C</B>\
+	</body>\
+	</html>";
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/* This is the callback function that is called
+ * when a TCP segment has arrived in the connection. */
+static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+  static unsigned char temp_var = 0;
+  unsigned short       counter, i;
+  char                 *rq;
+  /* If we got a NULL pbuf in p, the remote end has closed
+   * the connection. */
+  if (p != NULL)
+  {
+    /* The payload pointer in the pbuf contains the data
+     * in the TCP segment. */
+    rq = p->payload;
+    /* Check if the request was an HTTP "GET / HTTP/1.1". */
+    if (rq[0] == 'G' && rq[1] == 'E' && rq[2] == 'T')
+    {
+      /* Send the web page to the remote host. A zero
+       * in the last argument means that the data should
+       * not be copied into internal buffers. */
+
+      counter = 0;
+
+      for (i = 0; i < sizeof(indexdata1) - 1; i++)
+      {
+        indexdata[counter] = indexdata1[i];
+        counter++;
+      }
+
+      indexdata[counter] = ' ';
+      counter++;
+
+      /*Copy page counter MSB*/
+      indexdata[counter] = temp_var / 10 + 0x30;
+      counter++;
+
+      /*Copy page counter LSB*/
+      indexdata[counter] = temp_var % 10 + 0x30;
+      counter++;
+
+      temp_var++;
+      if (temp_var > 100) temp_var = 1;
+
+      for (i = 0; i < sizeof(indexdata2) - 1; i++)
+      {
+        indexdata[counter] = indexdata2[i];
+        counter++;
+      }
+
+	  vdd = rt_hw_get_vdd();
+	  rt_sprintf(&indexdata[counter], "%1d.%02d", vdd / 100, vdd % 100);
+	  counter += 4;
+
+      for (i = 0; i < sizeof(indexdata3) - 1; i++)
+      {
+        indexdata[counter] = indexdata3[i];
+        counter++;
+      }
+
+	  temp = rt_hw_get_temp();
+      /*Set temperature sign*/
+      if (temp < 0)
+      {
+        indexdata[counter] = '-';
+        counter++;
+      }
+	  rt_sprintf(&indexdata[counter], "%02d.%02d\n", temp / 100, temp % 100);
+	  counter += 5;
+
+      for (i = 0; i < sizeof(indexdata4); i++)
+      {
+        indexdata[counter] = indexdata4[i];
+        counter++;
+      }
+
+      tcp_write(pcb, indexdata, counter, 1);
+    }
+    /* Free the pbuf. */
+    pbuf_free(p);
+  }
+  /* Close the connection. */
+  tcp_close(pcb);
+  return ERR_OK;
+}
+
+/* This is the callback function that is called when
+ * a connection has been accepted. */
+static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
+{
+  /* Set up the function http_recv() to be called when data
+   * arrives. */
+  tcp_recv(pcb, http_recv);
+  return ERR_OK;
+}
+
+/* The initialization function. */
+void httpd_init(void)
+{
+  struct tcp_pcb *pcb;
+  /* Create a new TCP PCB. */
+  pcb = tcp_new();
+  /* Bind the PCB to TCP port 80. */
+  tcp_bind(pcb, NULL, 80);
+  /* Change TCP state to LISTEN. */
+  pcb = tcp_listen(pcb);
+  /* Set up http_accet() function to be called
+   * when a new connection arrives. */
+  tcp_accept(pcb, http_accept);
+}
+
+#endif
+
+/***************************************************************************//**
+ * @}
+ ******************************************************************************/

+ 119 - 60
bsp/efm32/rtconfig.h

@@ -1,42 +1,45 @@
-/******************************************************************//**
- * @file 		rtconfig.h
+/***************************************************************************//**
+ * @file 	rtconfig.h
  * @brief 	RT-Thread config file
  * 	COPYRIGHT (C) 2009, RT-Thread Development Team
  * @author 	
- * @version 	0.4 beta
- **********************************************************************
+ * @version 0.4 beta
+ *******************************************************************************
  * @section License
- * 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
- *********************************************************************/
+ * 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
+ ******************************************************************************/
 #ifndef __RTTHREAD_CFG_H__
 #define __RTTHREAD_CFG_H__
 
-/* Includes -------------------------------------------------------------------*/
-/* Exported types -------------------------------------------------------------*/
-/* Exported constants ---------------------------------------------------------*/
-/* Exported macro -------------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
 /* RT_NAME_MAX*/
-#define RT_NAME_MAX				8
+#define RT_NAME_MAX					(8)
 
 /* RT_ALIGN_SIZE*/
-#define RT_ALIGN_SIZE			4
+#define RT_ALIGN_SIZE				(4)
 
 /* PRIORITY_MAX */
-#define RT_THREAD_PRIORITY_MAX	32
+#define RT_THREAD_PRIORITY_MAX		(32)
 
 /* Tick per Second */
-#define RT_TICK_PER_SECOND		100
+#define RT_TICK_PER_SECOND			(100)
 
 /* SECTION: RT_DEBUG */
 #define RT_DEBUG
-//#define RT_MEM_DEBUG
+//#define RT_MEM_DEBUG 				(1)
+//#define RT_DEBUG_SCHEDULER 			(1)
 //#define THREAD_DEBUG
 //#define IRQ_DEBUG
 #define RT_USING_OVERFLOW_CHECK
+//#define DFS_DEBUG
+#define RT_LWIP_DEBUG
 
 //#define RT_IRQHDL_DEBUG
-#define RT_USART_DEBUG
+//#define RT_USART_DEBUG
 //#define RT_IIC_DEBUG
 //#define RT_MISC_DEBUG
 //#define RT_ADC_DEBUG
@@ -46,33 +49,29 @@
 
 #define EFM32_SFLASH_DEBUG
 //#define EFM32_SDCARD_DEBUG
-//#define DFS_DEBUG
+#define EFM32_ETHERNET_DEBUG
+
 
 /* Using Hook */
 //#define RT_USING_HOOK
 
 /* Using Software Timer */
 /* #define RT_USING_TIMER_SOFT */
-#define RT_TIMER_THREAD_PRIO		4
-#define RT_TIMER_THREAD_STACK_SIZE	512
-#define RT_TIMER_TICK_PER_SECOND	10
+#define RT_TIMER_THREAD_PRIO		(4)
+#define RT_TIMER_THREAD_STACK_SIZE	(512)
+#define RT_TIMER_TICK_PER_SECOND	(10)
 
 /* SECTION: IPC */
 /* Using Semaphore*/
-#define RT_USING_SEMAPHORE
-
+#define RT_USING_SEMAPHORE 					/* Using by DFS and lwIP */
 /* Using Mutex */
-#define RT_USING_MUTEX
-
+//#define RT_USING_MUTEX 						/* Using by DFS */
 /* Using Event */
 //#define RT_USING_EVENT
-
 /* Using MailBox */
-//#define RT_USING_MAILBOX
-
+#define RT_USING_MAILBOX 					/* Using by lwIP */
 /* Using Message Queue */
 //#define RT_USING_MESSAGEQUEUE
-
 /* SECTION: Memory Management */
 /* Using Memory Pool Management*/
 //#define RT_USING_MEMPOOL
@@ -89,62 +88,66 @@
 
 /* USART Device for Console */
 #if defined(EFM32_G290_DK)
-#define RT_USING_USART1			(0x0UL)
-#define RT_USART1_NAME			"debug"
-#define RT_USART1_USING_DMA		(0x0UL)
+#define RT_USING_USART1				(0x0UL)
+#define RT_USART1_NAME				"debug"
+//#define RT_USART1_USING_DMA			(0x0UL)
 #elif defined(EFM32_G890_STK)
-#define RT_USING_USART1			(0x1UL)
-#define RT_USART1_NAME			"debug"
-#define RT_USART1_USING_DMA		(0x0UL)
+#define RT_USING_USART1				(0x1UL)
+#define RT_USART1_NAME				"debug"
+#define RT_USART1_USING_DMA			(0x0UL)
 #endif
 
 /* SECTION: SPI options */
 #if defined(EFM32_G290_DK)
-#define RT_USING_USART0			(0x2UL)
-#define RT_USART0_SYNC_MODE		(0x1UL) 	/* Master */
-#define RT_USART0_NAME			"spi0"
-#define RT_USART0_USING_DMA		(0x1UL)
+#define RT_USING_USART0				(0x2UL)
+#define RT_USART0_SYNC_MODE			(0x1UL) 	/* Master */
+#define RT_USART0_NAME				"spi0"
+#define RT_USART0_USING_DMA			(0x1UL)
+
+#define RT_USING_USART2				(0x1UL)
+#define RT_USART2_SYNC_MODE			(0x1UL) 	/* Master */
+#define RT_USART2_NAME				"spi2"
+#define RT_USART2_USING_DMA			(0x2UL)
 #elif defined(EFM32_G890_STK)
-//#define RT_USING_USART0			(0x0UL)
-//#define RT_USART0_SYNC_MODE		(0x1UL) 		/* Master */
-//#define RT_USART0_NAME			"spi0"
-//#define RT_USART0_USING_DMA		(0x1UL)
+//#define RT_USING_USART0				(0x0UL)
+//#define RT_USART0_SYNC_MODE			(0x1UL) 		/* Master */
+//#define RT_USART0_NAME				"spi0"
+//#define RT_USART0_USING_DMA			(0x1UL)
 #endif
 
 /* SECTION: IIC options */
-//#define RT_USING_IIC0			0x1UL
-#define RT_IIC0_NAME			"iic0"
+//#define RT_USING_IIC0				0x1UL
+#define RT_IIC0_NAME				"iic0"
 
 /* SECTION: ACMP options */
 //#define RT_USING_ACMP0
-#define RT_ACMP0_NAME 			"acmp0"
+#define RT_ACMP0_NAME 				"acmp0"
 
 /* SECTION: ADC options */
-//#define RT_USING_ADC0
-#define RT_ADC0_NAME 			"adc"
+#define RT_USING_ADC0
+#define RT_ADC0_NAME 				"adc"
 
 /* SECTION: TIMER options */
-//#define RT_USING_TIMER2			(0x00) 		/* Continuous mode */
-#define RT_TIMER2_NAME			"tmr2"
+//#define RT_USING_TIMER2				(0x00) 		/* Continuous mode */
+#define RT_TIMER2_NAME				"tmr2"
 
 /* SECTION: RTC options */
 #if (defined(EFM32_G290_DK) || defined(EFM32_G890_STK))
 //#define RT_USING_RTC
+#define RT_RTC_NAME 				"rtc"
 #endif
-#define RT_RTC_NAME 			"rtc"
-
 
 /* SECTION: Serial options */
 #if defined(EFM32_G290_DK)
-#define RT_CONSOLE_DEVICE		0x1UL
+#define RT_CONSOLE_DEVICE			(0x1UL)
 #elif defined(EFM32_G890_STK)
-#define RT_CONSOLE_DEVICE		0x1UL
+#define RT_CONSOLE_DEVICE			(0x1UL)
 #endif
 
 /* SECTION: Console options */
 #define RT_USING_CONSOLE
 /* the buffer size of console*/
-#define RT_CONSOLEBUF_SIZE		128
+#define RT_CONSOLEBUF_SIZE			(128)
 
 /* SECTION: finsh, a C-Express shell */
 #define RT_USING_FINSH
@@ -152,10 +155,11 @@
 #define FINSH_USING_SYMTAB
 #define FINSH_USING_DESCRIPTION
 
-/* SECTION: SPI Flash and MicroSD card */
+/* SECTION: SPI Flash, MicroSD card and Ethernet */
 #if defined(EFM32_G290_DK)
 //#define EFM32_USING_SFLASH
-#define EFM32_USING_SPISD
+//#define EFM32_USING_SPISD
+#define EFM32_USING_ETHERNET
 #endif
 #if defined(EFM32_USING_SFLASH)
 #define SFLASH_USING_DEVICE_NAME 	RT_USART0_NAME
@@ -164,10 +168,16 @@
 #define SPISD_USING_DEVICE_NAME 	RT_USART0_NAME
 #define SPISD_DEVICE_NAME 			"spiSd"
 #endif
+#if defined(EFM32_USING_ETHERNET)
+#define ETH_USING_DEVICE_NAME 		RT_USART2_NAME
+#define ETH_DEVICE_NAME 			"spiEth"
+#define ETH_ADDR_DEFAULT 			{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}
+#endif
 
 /* SECTION: device filesystem */
-#define RT_USING_DFS
-#define RT_USING_DFS_ELMFAT
+#if defined(EFM32_USING_SPISD)
+//#define RT_USING_DFS
+//#define RT_USING_DFS_ELMFAT
 #define DFS_ELMFAT_INTERFACE_EFM
 /* the max number of mounted filesystem */
 #define DFS_FILESYSTEMS_MAX			(2)
@@ -175,7 +185,56 @@
 #define DFS_FD_MAX					(4)
 /* the max number of cached sector 		*/
 #define DFS_CACHE_MAX_NUM   		(4)
+#endif
+
+/* SECTION: lwip, a lighwight TCP/IP protocol stack */
+#if defined(EFM32_USING_ETHERNET)
+#define RT_USING_LWIP
+#define RT_USING_NETUTILS
+//#define RT_LWIP_DHCP
+/* LwIP uses RT-Thread Memory Management */
+#define RT_LWIP_USING_RT_MEM
+/* Enable ICMP protocol*/
+#define RT_LWIP_ICMP
+/* Enable UDP protocol*/
+#define RT_LWIP_UDP
+/* Enable TCP protocol*/
+#define RT_LWIP_TCP
+/* Enable DNS */
+//#define RT_LWIP_DNS
+
+/* the number of simulatenously active TCP connections*/
+#define RT_LWIP_TCP_PCB_NUM			(2)
+
+/* ip address of target*/
+#define RT_LWIP_IPADDR0				(192)
+#define RT_LWIP_IPADDR1				(168)
+#define RT_LWIP_IPADDR2				(1)
+#define RT_LWIP_IPADDR3				(118)
+
+/* 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)
+
+/* tcp thread options */
+#define RT_LWIP_TCPTHREAD_PRIORITY	(12)
+#define RT_LWIP_TCPTHREAD_MBOX_SIZE	(4)
+#define RT_LWIP_TCPTHREAD_STACKSIZE	(512)
+
+/* ethernet if thread options */
+#define RT_LWIP_ETHTHREAD_PRIORITY 	(15)
+#define RT_LWIP_ETHTHREAD_MBOX_SIZE	(4)
+#define RT_LWIP_ETHTHREAD_STACKSIZE	(512)
+#endif
 
-/* Exported functions --------------------------------------------------------- */
+/* Exported functions ------------------------------------------------------- */
 
 #endif /* __RTTHREAD_CFG_H__ */

+ 17 - 15
bsp/efm32/rtconfig.py

@@ -1,22 +1,23 @@
 # toolchains options
-ARCH     = 'arm'
-CPU      = 'cortex-m3'
-CROSS_TOOL 	= 'gcc'
+ARCH        = 'arm'
+CPU         = 'cortex-m3'
+CROSS_TOOL  = 'gcc'
 
 if CROSS_TOOL == 'gcc':
-	PLATFORM 	= 'gcc'
-	EXEC_PATH 	= 'C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin'
+    PLATFORM    = 'gcc'
+    EXEC_PATH   = 'C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin'
+    #EXEC_PATH  = 'C:\Program Files (x86)\yagarto\bin'
 
-BUILD = 'debug'
-# EFM32_BOARD 	=  'EFM32_G890_STK'
-EFM32_BOARD 	=  'EFM32_G290_DK'
+BUILD = 'run'
+# EFM32_BOARD   =  'EFM32_G890_STK'
+EFM32_BOARD     =  'EFM32_G290_DK'
 
 if EFM32_BOARD == 'EFM32_G890_STK':
-#	EFM32_FAMILY = 'Gecko'
-	EFM32_TYPE = 'EFM32G890F128'
+    EFM32_FAMILY = 'Gecko'
+    EFM32_TYPE = 'EFM32G890F128'
 elif EFM32_BOARD == 'EFM32_G290_DK':
-#	EFM32_FAMILY = 'Gecko'
-	EFM32_TYPE = 'EFM32G290F128'
+    EFM32_FAMILY = 'Gecko'
+    EFM32_TYPE = 'EFM32G290F128'
 
 if PLATFORM == 'gcc':
     # toolchains
@@ -30,10 +31,11 @@ if PLATFORM == 'gcc':
     OBJDUMP = PREFIX + 'objdump'
     OBJCPY = PREFIX + 'objcopy'
 
-    DEVICE = ' -mcpu=cortex-m3 -mthumb'
-    CFLAGS = DEVICE + ' -DRT_USING_MINILIBC'
+    DEVICE = ' -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections'
+    #CFLAGS = DEVICE + ' -DRT_USING_MINILIBC'
+    CFLAGS = DEVICE
     AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
-    LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-efm32.map,-cref,-u,Reset_Handler -T efm32_rom.ld'
+    LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-efm32.map,-cref,-u,__cs3_reset -T efm32_rom.ld'
 
     CPATH = ''
     LPATH = ''

+ 1 - 1
bsp/efm32/startup.c

@@ -118,7 +118,7 @@ void rtthread_startup(void)
 	/* init scheduler system */
 	rt_system_scheduler_init();
 
-	/* init all device */
+	/* init all devices */
 	rt_device_init_all();
 
 #ifdef RT_USING_FINSH

+ 20 - 226
libcpu/arm/cortex-m3/start_gcc.S

@@ -1,24 +1,24 @@
-/******************************************************************//**
+/***************************************************************************//**
  * @file 		start_gcc.S
  * @brief 	Context switch functions
  * 	COPYRIGHT (C) 2011, RT-Thread Development Team
  * @author 	onelife
  * @version 	0.4 beta
- **********************************************************************
+ *******************************************************************************
  * @section License
- * 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
- **********************************************************************
+ * 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
+ *******************************************************************************
  * @section Change Logs
  * Date			Author		Notes
- * 2010-12-21 	onelife 		Initial creation for EFM32
- *********************************************************************/
+ * 2010-12-21 	onelife 	Initial creation for EFM32
+ * 2011-07-06 	onelife 	Modify to make use the start code in libraries
+ ******************************************************************************/
  
-/******************************************************************//**
+/***************************************************************************//**
 * @addtogroup cortex-m3
 * @{
-*********************************************************************/
-
+*******************************************************************************/
 	.syntax unified
 	.cpu 	cortex-m3
 	.fpu 	softvfp
@@ -36,93 +36,20 @@ defined in linker script */
 /* end address for the .bss section. defined in linker script */
 	.word _ebss
 
-
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3.  Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/    
-  .section .isr_vector, "a", %progbits
-  .global g_pfnVectors
-  .type g_pfnVectors, %object
-g_pfnVectors:
-  .word  Initial_spTop
-  .word  Reset_Handler
-  .word  NMI_Handler
-  .word  HardFault_Handler
-  .word  MemManage_Handler
-  .word  BusFault_Handler
-  .word  UsageFault_Handler
-  .word  0
-  .word  0
-  .word  0
-  .word  0
-  .word  SVC_Handler
-  .word  DebugMon_Handler
-  .word  0
-  .word  PendSV_Handler
-  .word  SysTick_Handler
-  /* External Interrupts */
-  .word  DMA_IRQHandler				/* 0: DMA Interrupt (efm32_dma.c) */
-  .word  GPIO_EVEN_IRQHandler		/* 1: GPIO_EVEN Interrupt */
-  .word  TIMER0_IRQHandler			/* 2: TIMER0 Interrupt */
-  .word  USART0_RX_IRQHandler		/* 3: USART0_RX Interrupt */
-  .word  USART0_TX_IRQHandler		/* 4: USART0_TX Interrupt */
-  .word  ACMP0_IRQHandler			/* 5: ACMP0 Interrupt */
-  .word  ADC0_IRQHandler			/* 6: ADC0 Interrupt */
-  .word  DAC0_IRQHandler			/* 7: DAC0 Interrupt */
-  .word  I2C0_IRQHandler			/* 8: I2C0 Interrupt */
-  .word  GPIO_ODD_IRQHandler		/* 9: GPIO_ODD Interrupt */
-  .word  TIMER1_IRQHandler			/* 10: TIMER1 Interrupt */
-  .word  TIMER2_IRQHandler			/* 11: TIMER2 Interrupt */
-  .word  USART1_RX_IRQHandler		/* 12: USART1_RX Interrupt */
-  .word  USART1_TX_IRQHandler		/* 13: USART1_TX Interrupt */
-  .word  USART2_RX_IRQHandler		/* 14: USART2_RX Interrupt */
-  .word  USART2_TX_IRQHandler		/* 15: USART2_TX Interrupt */
-  .word  UART0_RX_IRQHandler		/* 16: UART0_RX Interrupt */
-  .word  UART0_TX_IRQHandler		/* 17: UART0_TX Interrupt */
-  .word  LEUART0_IRQHandler			/* 18: LEUART0 Interrupt */
-  .word  LEUART1_IRQHandler			/* 19: LEUART1 Interrupt */
-  .word  LETIMER0_IRQHandler		/* 20: LETIMER0 Interrupt */
-  .word  PCNT0_IRQHandler			/* 21: PCNT0 Interrupt */
-  .word  PCNT1_IRQHandler			/* 22: PCNT1 Interrupt */
-  .word  PCNT2_IRQHandler			/* 23: PCNT2 Interrupt */
-  .word  RTC_IRQHandler				/* 24: RTC Interrupt */
-  .word  CMU_IRQHandler				/* 25: CMU Interrupt */
-  .word  VCMP_IRQHandler			/* 26: VCMP Interrupt */
-  .word  LCD_IRQHandler				/* 27: LCD Interrupt */
-  .word  MSC_IRQHandler				/* 28: MSC Interrupt */
-  .word  AES_IRQHandler				/* 29: AES Interrupt */
-  .size	g_pfnVectors, .-g_pfnVectors
-
-/**
- * @brief  Top of stack pointer
-*/
-	.section .bss.init
-	.equ Stack_Size, 0x00000200
-	.space Stack_Size
-Initial_spTop:
-
-/**
+/***************************************************************************//**
  * @brief  This is the code that gets called when the processor first
  *          starts execution following a reset event. Only the absolutely
  *          necessary set is performed, after which the application
  *          supplied main() routine is called. 
  * @param  None
- * @retval  None
-*/
+ * @retval None
+*******************************************************************************/
 	.thumb
 	.thumb_func
-	.section .text.Reset_Handler, "ax", %progbits
-	.weak Reset_Handler
-	.global Reset_Handler
-	.type Reset_Handler, %function
-Reset_Handler:  
-	/* restore original stack pointer */  
-	ldr  r0, =Initial_spTop
-	msr  msp, r0
+	.section	.cs3.init,"ax", %progbits
+	.globl		_start
+	.type		_start, %function
+_start:  
 	/* Copy the data segment initializers from flash to SRAM */  
 	movs  r1, #0
 	b  LoopCopyDataInit
@@ -154,141 +81,8 @@ LoopFillZerobss:
 	/* Call the application's entry point.*/
 	bl  main
 	bx  lr    
-	.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief  This is the code that gets called when the processor receives an 
- *         unexpected interrupt.  This simply enters an infinite loop, preserving
- *         the system state for examination by a debugger.
- *
- * @param None     
- * @retval None       
-*/
-	.thumb
-	.thumb_func
-	.section .text.Default_Handler, "ax", %progbits
-	.global Default_Handler
-	.type Default_Handler, %function
-Default_Handler:
-Infinite_Loop:
-	b  Infinite_Loop
-	.size Default_Handler, .-Default_Handler
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler. 
-* As they are weak aliases, any function with the same name will override 
-* this definition.
-*
-*******************************************************************************/
-  .weak			NMI_Handler
-  .thumb_set	NMI_Handler, Default_Handler
-  
-  .weak			MemManage_Handler
-  .thumb_set	MemManage_Handler, Default_Handler
-  
-  .weak			BusFault_Handler
-  .thumb_set	BusFault_Handler, Default_Handler
-
-  .weak			UsageFault_Handler
-  .thumb_set	UsageFault_Handler, Default_Handler
-
-  .weak			SVC_Handler
-  .thumb_set	SVC_Handler, Default_Handler
-
-  .weak			DebugMon_Handler
-  .thumb_set	DebugMon_Handler ,Default_Handler
-  
-  .weak  		DMA_IRQHandler
-  .thumb_set 	DMA_IRQHandler, Default_Handler
-  
-  .weak  		GPIO_EVEN_IRQHandler
-  .thumb_set 	GPIO_EVEN_IRQHandler, Default_Handler
-  
-  .weak  		TIMER0_IRQHandler
-  .thumb_set 	TIMER0_IRQHandler, Default_Handler
-
-  .weak  		USART0_RX_IRQHandler
-  .thumb_set 	USART0_RX_IRQHandler, Default_Handler
-
-  .weak  		USART0_TX_IRQHandler
-  .thumb_set 	USART0_TX_IRQHandler, Default_Handler
-
-  .weak  		ACMP0_IRQHandler
-  .thumb_set 	ACMP0_IRQHandler, Default_Handler
-
-  .weak  		ADC0_IRQHandler
-  .thumb_set 	ADC0_IRQHandler, Default_Handler
-
-  .weak  		DAC0_IRQHandler
-  .thumb_set 	DAC0_IRQHandler, Default_Handler
-
-  .weak  		I2C0_IRQHandler
-  .thumb_set 	I2C0_IRQHandler, Default_Handler
-
-  .weak  		GPIO_ODD_IRQHandler
-  .thumb_set 	GPIO_ODD_IRQHandler, Default_Handler
+	.size _start, .-_start
 
-  .weak  		TIMER1_IRQHandler
-  .thumb_set 	TIMER1_IRQHandler, Default_Handler
-
-  .weak  		TIMER2_IRQHandler
-  .thumb_set 	TIMER2_IRQHandler, Default_Handler
-
-  .weak  		USART1_RX_IRQHandler
-  .thumb_set 	USART1_RX_IRQHandler, Default_Handler
-
-  .weak  		USART1_TX_IRQHandler
-  .thumb_set 	USART1_TX_IRQHandler, Default_Handler
-
-  .weak  		USART2_RX_IRQHandler
-  .thumb_set 	USART2_RX_IRQHandler, Default_Handler
-
-  .weak  		USART2_TX_IRQHandler
-  .thumb_set 	USART2_TX_IRQHandler, Default_Handler
-
-  .weak  		UART0_RX_IRQHandler
-  .thumb_set 	UART0_RX_IRQHandler, Default_Handler
-  
-  .weak  		UART0_TX_IRQHandler
-  .thumb_set 	UART0_TX_IRQHandler, Default_Handler
-
-  .weak  		LEUART0_IRQHandler
-  .thumb_set 	LEUART0_IRQHandler, Default_Handler
-
-  .weak  		LEUART1_IRQHandler
-  .thumb_set 	LEUART1_IRQHandler, Default_Handler
-
-  .weak  		LETIMER0_IRQHandler
-  .thumb_set 	LETIMER0_IRQHandler, Default_Handler
-
-  .weak  		PCNT0_IRQHandler
-  .thumb_set 	PCNT0_IRQHandler, Default_Handler
-
-  .weak  		PCNT1_IRQHandler
-  .thumb_set 	PCNT1_IRQHandler, Default_Handler
-
-  .weak  		PCNT2_IRQHandler
-  .thumb_set 	PCNT2_IRQHandler, Default_Handler
-
-  .weak  		RTC_IRQHandler
-  .thumb_set 	RTC_IRQHandler, Default_Handler
-
-  .weak  		CMU_IRQHandler
-  .thumb_set 	CMU_IRQHandler, Default_Handler
-
-  .weak  		VCMP_IRQHandler
-  .thumb_set 	VCMP_IRQHandler, Default_Handler
-
-  .weak  		LCD_IRQHandler
-  .thumb_set 	LCD_IRQHandler, Default_Handler
-
-  .weak  		MSC_IRQHandler
-  .thumb_set 	MSC_IRQHandler, Default_Handler
-
-  .weak  		AES_IRQHandler
-  .thumb_set 	AES_IRQHandler, Default_Handler
-
-/******************************************************************//**
+/***************************************************************************//**
  * @}
-*********************************************************************/
+*******************************************************************************/