From ef6bbc34fa2c49433e6b2fe6516ae288daf8d351 Mon Sep 17 00:00:00 2001 From: "onelife.real" Date: Fri, 8 Jul 2011 07:13:20 +0000 Subject: [PATCH] *** 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 --- bsp/efm32/Libraries/SConscript | 8 +- bsp/efm32/Readme.txt | 46 +- bsp/efm32/SConscript | 5 +- bsp/efm32/application.c | 119 ++- bsp/efm32/board.h | 11 +- bsp/efm32/copy_this_file_dfs_elm.c | 1 - bsp/efm32/dev_misc.c | 66 +- bsp/efm32/dev_misc.h | 22 +- bsp/efm32/dev_sflash.c | 5 +- bsp/efm32/dev_sflash.h | 3 +- bsp/efm32/drv_adc.c | 64 +- bsp/efm32/drv_adc.h | 26 +- bsp/efm32/drv_ethernet.c | 1083 ++++++++++++++++++++++++++++ bsp/efm32/drv_ethernet.h | 44 ++ bsp/efm32/drv_sdcard.c | 141 ++-- bsp/efm32/drv_sdcard.h | 32 +- bsp/efm32/drv_usart.c | 113 +-- bsp/efm32/drv_usart.h | 29 +- bsp/efm32/efm32_rom.ld | 60 +- bsp/efm32/enc28j60.h | 313 ++++++++ bsp/efm32/httpd.c | 237 ++++++ bsp/efm32/rtconfig.h | 179 +++-- bsp/efm32/rtconfig.py | 32 +- bsp/efm32/startup.c | 2 +- libcpu/arm/cortex-m3/start_gcc.S | 246 +------ 25 files changed, 2254 insertions(+), 633 deletions(-) create mode 100644 bsp/efm32/drv_ethernet.c create mode 100644 bsp/efm32/drv_ethernet.h create mode 100644 bsp/efm32/enc28j60.h create mode 100644 bsp/efm32/httpd.c diff --git a/bsp/efm32/Libraries/SConscript b/bsp/efm32/Libraries/SConscript index 1471edef0..1fcddb896 100644 --- a/bsp/efm32/Libraries/SConscript +++ b/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', diff --git a/bsp/efm32/Readme.txt b/bsp/efm32/Readme.txt index 571d10ed3..234360105 100644 --- a/bsp/efm32/Readme.txt +++ b/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 \ No newline at end of file + - 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 \ No newline at end of file diff --git a/bsp/efm32/SConscript b/bsp/efm32/SConscript index 5c006a435..c968b15df 100644 --- a/bsp/efm32/SConscript +++ b/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) diff --git a/bsp/efm32/application.c b/bsp/efm32/application.c index b092105fe..7e968790d 100644 --- a/bsp/efm32/application.c +++ b/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 -#ifdef RT_USING_DFS +#if defined(RT_USING_DFS) /* dfs init */ #include /* 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; } -/******************************************************************//** +/***************************************************************************//** * @} -*********************************************************************/ + ******************************************************************************/ diff --git a/bsp/efm32/board.h b/bsp/efm32/board.h index 39cbe832b..3ba7529cd 100644 --- a/bsp/efm32/board.h +++ b/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) diff --git a/bsp/efm32/copy_this_file_dfs_elm.c b/bsp/efm32/copy_this_file_dfs_elm.c index bbd5ab4dc..195022b30 100644 --- a/bsp/efm32/copy_this_file_dfs_elm.c +++ b/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; diff --git a/bsp/efm32/dev_misc.c b/bsp/efm32/dev_misc.c index 5345d06f1..f1031342a 100644 --- a/bsp/efm32/dev_misc.c +++ b/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 @@ -185,6 +185,6 @@ FINSH_FUNCTION_EXPORT(list_vdd, list current VDD value.) #endif -/******************************************************************//** +/***************************************************************************//** * @} -*********************************************************************/ + ******************************************************************************/ diff --git a/bsp/efm32/dev_misc.h b/bsp/efm32/dev_misc.h index cd16444b6..330f5026a 100644 --- a/bsp/efm32/dev_misc.h +++ b/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); diff --git a/bsp/efm32/dev_sflash.c b/bsp/efm32/dev_sflash.c index 55e0579ee..5a7e19225 100644 --- a/bsp/efm32/dev_sflash.c +++ b/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) { diff --git a/bsp/efm32/dev_sflash.h b/bsp/efm32/dev_sflash.h index 7eb8c1e16..3f4dc1043 100644 --- a/bsp/efm32/dev_sflash.h +++ b/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 diff --git a/bsp/efm32/drv_adc.c b/bsp/efm32/drv_adc.c index a7f8fbf31..d39cbd92e 100644 --- a/bsp/efm32/drv_adc.c +++ b/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 -/******************************************************************//** +/***************************************************************************//** * @} -*********************************************************************/ + ******************************************************************************/ diff --git a/bsp/efm32/drv_adc.h b/bsp/efm32/drv_adc.h index d9f2e10bc..c67d28b50 100644 --- a/bsp/efm32/drv_adc.h +++ b/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__ */ diff --git a/bsp/efm32/drv_ethernet.c b/bsp/efm32/drv_ethernet.c new file mode 100644 index 000000000..9fd85890b --- /dev/null +++ b/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 + +/* 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, ®_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(ð_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(ðLock, 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, ®_eie); + /* Unlock device */ + rt_sem_release(ðLock); + + 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(ðLock, 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(ðLock); + + 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(ðLock, "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(ð_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 + +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) */ +/******************************************************************//** + * @} + ******************************************************************************/ diff --git a/bsp/efm32/drv_ethernet.h b/bsp/efm32/drv_ethernet.h new file mode 100644 index 000000000..7c9718cdc --- /dev/null +++ b/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__ */ diff --git a/bsp/efm32/drv_sdcard.c b/bsp/efm32/drv_sdcard.c index ab3d74296..4831acf2c 100644 --- a/bsp/efm32/drv_sdcard.c +++ b/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 -/* 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 -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) */ -/******************************************************************//** +/***************************************************************************//** * @} -*********************************************************************/ + ******************************************************************************/ diff --git a/bsp/efm32/drv_sdcard.h b/bsp/efm32/drv_sdcard.h index b820ab6ad..c3fdc7293 100644 --- a/bsp/efm32/drv_sdcard.h +++ b/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__ */ diff --git a/bsp/efm32/drv_usart.c b/bsp/efm32/drv_usart.c index 16392dc72..1ab0c470e 100644 --- a/bsp/efm32/drv_usart.c +++ b/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 -/******************************************************************//** +/***************************************************************************//** * @} -*********************************************************************/ + ******************************************************************************/ diff --git a/bsp/efm32/drv_usart.h b/bsp/efm32/drv_usart.h index e0e844b52..765f3bbe4 100644 --- a/bsp/efm32/drv_usart.h +++ b/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__ */ diff --git a/bsp/efm32/efm32_rom.ld b/bsp/efm32/efm32_rom.ld index f6f4e984f..e1bb9dc8f 100644 --- a/bsp/efm32/efm32_rom.ld +++ b/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 = .; - - /* This is used by the startup in order to initialize the .data secion */ - _sidata = _etext; } > CODE = 0 - /* .data section which is used for initialized data */ + /* .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 = .; + } > 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 diff --git a/bsp/efm32/enc28j60.h b/bsp/efm32/enc28j60.h new file mode 100644 index 000000000..f6eaef79d --- /dev/null +++ b/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 + +// 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 diff --git a/bsp/efm32/httpd.c b/bsp/efm32/httpd.c new file mode 100644 index 000000000..607e9704f --- /dev/null +++ b/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 + * (C) Copyright 2009 Energy Micro AS, http://www.energymicro.com + ****************************************************************************** + * + * 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 + * + */ + +/***************************************************************************//** +* @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\ + \ + EFM32 HTTPD DEMO\ + \ +

This is a simple http server

\ +

Ethernet controller: ENC28J60\ +

Refreshing timers: "; + +static const char indexdata2[] = + "

Current Vdd: "; + +static const char indexdata3[] = + " V\ +

Current temperature: "; + +static const char indexdata4[] = + " C\ + \ + "; + +/* 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 + +/***************************************************************************//** + * @} + ******************************************************************************/ diff --git a/bsp/efm32/rtconfig.h b/bsp/efm32/rtconfig.h index 5a8990f95..f2080b91f 100644 --- a/bsp/efm32/rtconfig.h +++ b/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 -/* Exported functions --------------------------------------------------------- */ +/* 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 ------------------------------------------------------- */ #endif /* __RTTHREAD_CFG_H__ */ diff --git a/bsp/efm32/rtconfig.py b/bsp/efm32/rtconfig.py index 5adf18e20..9657f1cb8 100644 --- a/bsp/efm32/rtconfig.py +++ b/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 = '' diff --git a/bsp/efm32/startup.c b/bsp/efm32/startup.c index 9bcec6274..afcee2562 100644 --- a/bsp/efm32/startup.c +++ b/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 diff --git a/libcpu/arm/cortex-m3/start_gcc.S b/libcpu/arm/cortex-m3/start_gcc.S index 81ec65d2e..7d3ec26ae 100644 --- a/libcpu/arm/cortex-m3/start_gcc.S +++ b/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 + .size _start, .-_start -/** - * @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 - - .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 - -/******************************************************************//** +/***************************************************************************//** * @} -*********************************************************************/ +*******************************************************************************/