*** EFM32 branch ***

1. Update the copyright information
 - 2009 => 2011
2. Add external oscillator configuration routine in "rt_hw_board_init()"
 - Before, it is set by default frequency, 32MHz
 - Now it can be set by user specified frequency
3. Add ADC and ACMP (analog comparator) drivers
4. Clarify the MCU and target board define in "rtconfig.py"

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1296 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
onelife.real@gmail.com 2011-02-28 04:47:50 +00:00
parent 338155eddc
commit cabc797a2d
35 changed files with 1411 additions and 134 deletions

View File

@ -3,13 +3,13 @@ Import('RTT_ROOT')
from building import *
src_bsp = ['application.c', 'startup.c', 'board.c']
src_drv = ['drv_dma.c', 'drv_rtc.c', 'drv_usart.c', 'drv_iic.c', 'drv_timer.c']
src_dev = ['dev_led.c']
src_drv = ['drv_dma.c', 'drv_rtc.c', 'drv_adc.c', 'drv_acmp.c', 'drv_usart.c', 'drv_iic.c', 'drv_timer.c']
src_dev = ['dev_misc.c', 'dev_led.c']
src_hdl = ['hdl_interrupt.c']
src = src_bsp + src_drv + src_dev + src_hdl
CPPPATH = [RTT_ROOT + '/bsp/efm32']
CPPDEFINES = ['USE_STDPERIPH_DRIVER', rtconfig.EFM32_TYPE]
CPPDEFINES = ['USE_STDPERIPH_DRIVER', rtconfig.EFM32_BOARD, rtconfig.EFM32_TYPE]
group = DefineGroup('Startup', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
Return('group')

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file application.c
* @brief application tasks
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************
@ -42,7 +42,7 @@
/* Private define --------------------------------------------------------------*/
/* Private macro --------------------------------------------------------------*/
/* Private variables ------------------------------------------------------------*/
rt_uint32_t rt_system_status = 0;
rt_uint32_t rt_system_status = 0;
/* Private function prototypes ---------------------------------------------------*/
/* Private functions ------------------------------------------------------------*/
@ -68,7 +68,18 @@ void rt_led_thread_entry(void* parameter)
int rt_application_init()
{
rt_thread_t led_thread;
rt_thread_t test_thread;
/* Initialize all device drivers (dev_?.c) */
if (rt_hw_led_init() != RT_EOK)
{
rt_kprintf("*** Failed to initialize LED driver!");
while(1); //Or do something?
}
if (rt_hw_misc_init() != RT_EOK)
{
rt_kprintf("*** Failed to miscellaneous driver!");
while(1); //Or do something?
}
#if (RT_THREAD_PRIORITY_MAX == 32)
led_thread = rt_thread_create(

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file board.c
* @brief USART driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************
@ -192,6 +192,9 @@ void rt_hw_board_init(void)
/* NVIC Configuration */
NVIC_Configuration();
/* Configure external oscillator */
SystemHFXOClockSet(EFM32_HFXO_FREQUENCY);
/* Configure the SysTick */
SysTick_Configuration();
}
@ -215,23 +218,24 @@ void rt_hw_driver_init(void)
/* Enabling clock to the interface of the low energy modules */
CMU_ClockEnable(cmuClock_CORELE, true);
/* Initialize TIMER */
//rt_hw_timer_init();
/* Initialize DMA */
rt_hw_dma_init();
/* Initialize Timer */
rt_hw_timer_init();
/* Initialize USART */
rt_hw_usart_init();
/* Initialize Timer */
rt_hw_timer_init();
/* Initialize ADC */
rt_hw_adc_init();
/* Initialize ACMP */
rt_hw_acmp_init();
/* Initialize IIC */
rt_hw_iic_init();
rt_hw_led_init();
rt_console_set_device(CONSOLE_DEVICE);
}

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file drv_dma.h
* @brief USART driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************
@ -17,9 +17,8 @@
#define __BOARD_H__
#if defined(EFM32G890F128)
#define EFM32_G890_STK
#elif defined(EFM32G290F128)
#define EFM32_G290_DK
#elif defined(EFM32G230F128)
#else
#error Unknown MCU type
#endif
@ -30,9 +29,11 @@
#include <efm32_cmu.h>
#include <efm32_rmu.h>
#include <efm32_dma.h>
#include <efm32_rtc.h>
#include <efm32_timer.h>
#include <efm32_gpio.h>
#include <efm32_rtc.h>
#include <efm32_acmp.h>
#include <efm32_adc.h>
#include <efm32_usart.h>
#include <efm32_i2c.h>
@ -51,21 +52,26 @@ extern rt_uint32_t rt_system_status;
#define EFM32_NO_OFFSET (-1)
#define EFM32_NO_POINTER (RT_NULL)
#define HFXO_FREQUENCY (32000000)
#define UART_PERCLK_FREQUENCY HFXO_FREQUENCY
#define UART_BAUDRATE (115200)
#define SERIAL_RX_BUFFER_SIZE (64)
#define IIC_RX_BUFFER_SIZE (32)
#define EFM32_SRAM_END (RAM_MEM_BASE + SRAM_SIZE)
#define EFM32_BASE_PRI_DEFAULT (0x0UL << 5)
#define EFM32_IRQ_PRI_DEFAULT (0x4UL << 5)
#if (defined(EFM32_G890_STK) || defined(EFM32_G290_DK))
#define EFM32_HFXO_FREQUENCY (32000000)
#else
#define EFM32_HFXO_FREQUENCY (00000000)
#endif
#define UART_BAUDRATE (115200)
#define SERIAL_RX_BUFFER_SIZE (64)
#define IIC_RX_BUFFER_SIZE (32)
#define ADC_INIT_REF adcRef2V5
#define ADC_INIT_CH adcSingleInpCh5
#define ADC_CONVERT_FREQUENCY (7000000)
#if (RT_CONSOLE_DEVICE == 0x0UL)
#define CONSOLE_DEVICE RT_USART0_NAME
@ -77,9 +83,14 @@ extern rt_uint32_t rt_system_status;
#define CONSOLE_DEVICE "no"
#endif
#define RT_DEVICE_CTRL_USART (0x04) /*!< USART control */
#define RT_DEVICE_CTRL_IIC (0x08) /*!< IIC control */
#define RT_DEVICE_CTRL_TIMER (0x10) /*!< Timer control */
/*! fixme: move the following define to Rtdef.h */
#define RT_DEVICE_CTRL_USART_RBUFFER (0xF1) /*!< set USART rx buffer */
#define RT_DEVICE_CTRL_IIC_SETTING (0xF2) /*!< change IIC setting */
#define RT_DEVICE_CTRL_TIMER_PERIOD (0xF3) /*!< set Timer timeout period */
#define RT_DEVICE_CTRL_ADC_MODE (0xF4) /*!< change ADC mode */
#define RT_DEVICE_CTRL_ADC_RESULT (0xF5) /*!< get ADC result */
#define RT_DEVICE_CTRL_ACMP_INIT (0xF6) /*!< Initialize ACMP */
#define RT_DEVICE_CTRL_ACMP_OUTPUT (0xF7) /*!< get ACMP output */
/* Exported functions --------------------------------------------------------- */
void rt_hw_board_init(void);

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file dev_led.c
* @brief LED driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************
@ -111,8 +111,10 @@ rt_uint8_t rt_hw_led_state(rt_uint8_t num)
*
* @note
*
* @return
* Error code
*********************************************************************/
void rt_hw_led_init(void)
rt_err_t rt_hw_led_init(void)
{
rt_uint8_t i;
@ -125,6 +127,8 @@ void rt_hw_led_init(void)
gpioModePushPull,
0);
}
return RT_EOK;
}
/*********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file dev_led.h
* @brief LED driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************
@ -38,7 +38,7 @@
#endif
/* Exported functions --------------------------------------------------------- */
void rt_hw_led_init(void);
rt_err_t rt_hw_led_init(void);
void rt_hw_led_on(rt_uint8_t num);
void rt_hw_led_off(rt_uint8_t num);
void rt_hw_led_toggle(rt_uint8_t num);

190
bsp/efm32/dev_misc.c Normal file
View File

@ -0,0 +1,190 @@
/******************************************************************//**
* @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
**********************************************************************
* @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-02-22 onelife Initial creation for EFM32
*********************************************************************/
/******************************************************************//**
* @addtogroup efm32
* @{
*********************************************************************/
/* Includes -------------------------------------------------------------------*/
#include "board.h"
#include "drv_adc.h"
/* Private typedef -------------------------------------------------------------*/
/* Private define --------------------------------------------------------------*/
/* Private macro --------------------------------------------------------------*/
/* Private constants -----------------------------------------------------------*/
static rt_device_t adc0;
static struct efm32_adc_control_t control = {ADC_MODE_SINGLE};
/* Private variables ------------------------------------------------------------*/
/* Private function prototypes ---------------------------------------------------*/
rt_int32_t efm32_misc_getCelsius(rt_uint32_t adcSample);
/* Private functions ------------------------------------------------------------*/
/******************************************************************//**
* @brief
* Get current temperature value in degree celsius
*
* @details
*
* @note
*
* @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 */
singleInit.acqTime = adcAcqTime32;
singleInit.reference = adcRef1V25;
singleInit.input = adcSingleInpTemp;
control.singleInit = &singleInit;
adc0->control(adc0, RT_DEVICE_CTRL_ADC_MODE, &control);
adc0->control(adc0, RT_DEVICE_CTRL_RESUME, EFM32_NO_POINTER);
adc0->control(adc0, RT_DEVICE_CTRL_ADC_RESULT, &temp);
return efm32_misc_getCelsius(temp);
}
/******************************************************************//**
* @brief
* Get current VDD value in volt
*
* @details
*
* @note
*
* @return
* VDD value (unsigned integer) in volt times 100
*
*********************************************************************/
rt_uint32_t rt_hw_get_vdd(void)
{
ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
rt_uint32_t vdd;
/* Set input to temperature sensor. Reference must be 1.25V */
singleInit.acqTime = adcAcqTime32;
singleInit.reference = adcRef1V25;
singleInit.input = adcSingleInpVDDDiv3;
control.singleInit = &singleInit;
adc0->control(adc0, RT_DEVICE_CTRL_ADC_MODE, &control);
adc0->control(adc0, RT_DEVICE_CTRL_RESUME, EFM32_NO_POINTER);
adc0->control(adc0, RT_DEVICE_CTRL_ADC_RESULT, &vdd);
return (vdd * 125 * 3) / 4096;
}
/******************************************************************//**
* @brief
* Initialize all the miscellaneous drivers
*
* @details
*
* @note
*
* @return
* Error code
*********************************************************************/
rt_err_t rt_hw_misc_init(void)
{
adc0 = rt_device_find(RT_ADC0_NAME);
if (adc0 == RT_NULL)
{
rt_kprintf("Batt error: Can't find device: %s!\n", RT_ADC0_NAME);
goto MISC_INIT_ERROR;
}
return RT_EOK;
MISC_INIT_ERROR:
#ifdef RT_MISC_DEBUG
rt_kprintf("Misc error: Init failed!\n");
#endif
return -RT_ERROR;
}
/**************************************************************************//**
* @brief
* Convert ADC result to degree celsius.
*
* @details
*
* @note
* See section 2.3.4 in the reference manual for details on this calculatoin
*
* @param adcResult
* Raw value from ADC to be converted to celsius
*
* @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. */
rt_int32_t cal_temp = ((DEVINFO->CAL & _DEVINFO_CAL_TEMP_MASK) \
>> _DEVINFO_CAL_TEMP_SHIFT) * 100;
/* Factory calibration value from device information page. */
rt_int32_t cal_value = ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_TEMP1V25_MASK) \
>> _DEVINFO_ADC0CAL2_TEMP1V25_SHIFT) * 10000;
/* Temperature gradient (from datasheet) in (ADC unit / degree celsius * 100) */
rt_int32_t t_grad = -385;
return (cal_temp - (cal_value - (rt_int32_t)adcResult * 10000) / t_grad);
}
/*********************************************************************
* Export to FINSH
*********************************************************************/
#ifdef RT_USING_FINSH
#include <finsh.h>
void list_temp(void)
{
rt_int32_t temp = rt_hw_get_temp();
rt_kprintf("Temperature is %2d.%02d C\n", temp / 100, temp % 100);
}
FINSH_FUNCTION_EXPORT(list_temp, list current temperature value.)
void list_vdd(void)
{
rt_uint32_t vdd = rt_hw_get_vdd();
rt_kprintf("VDD is %1d.%02d V\n", vdd / 100, vdd % 100);
}
FINSH_FUNCTION_EXPORT(list_vdd, list current VDD value.)
#endif
/******************************************************************//**
* @}
*********************************************************************/

28
bsp/efm32/dev_misc.h Normal file
View File

@ -0,0 +1,28 @@
/******************************************************************//**
* @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
**********************************************************************
* @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 --------------------------------------------------------- */
rt_err_t rt_hw_misc_init(void);
rt_int32_t rt_hw_get_temp(void);
rt_uint32_t rt_hw_get_vdd(void);
#endif /* __DEV_MISC_H__ */

367
bsp/efm32/drv_acmp.c Normal file
View File

@ -0,0 +1,367 @@
/******************************************************************//**
* @file drv_acmp.c
* @brief ACMP (analog comparator) driver 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
**********************************************************************
* @section Change Logs
* Date Author Notes
* 2011-02-21 onelife Initial creation for EFM32
*********************************************************************/
/******************************************************************//**
* @addtogroup efm32
* @{
*********************************************************************/
/* Includes -------------------------------------------------------------------*/
#include "board.h"
#include "drv_acmp.h"
/* Private typedef -------------------------------------------------------------*/
/* Private define --------------------------------------------------------------*/
/* Private macro --------------------------------------------------------------*/
/* Private variables ------------------------------------------------------------*/
#ifdef RT_USING_ACMP0
static struct rt_device acmp0_device;
#endif
#ifdef RT_USING_ACMP1
static struct rt_device acmp1_device;
#endif
/* Private function prototypes ---------------------------------------------------*/
ACMP_WarmTime_TypeDef efm32_acmp_WarmTimeCalc(rt_uint32_t hfperFreq);
/* Private functions ------------------------------------------------------------*/
/******************************************************************//**
* @brief
* Initialize ACMP device
*
* @details
*
* @note
*
* @param[in] dev
* Pointer to device descriptor
*
* @return
* Error code
*********************************************************************/
static rt_err_t rt_acmp_init(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
struct efm32_acmp_device_t *acmp;
acmp = (struct efm32_acmp_device_t *)(dev->user_data);
acmp->hook.cbFunc = RT_NULL;
acmp->hook.userPtr = RT_NULL;
return RT_EOK;
}
/******************************************************************//**
* @brief
* Configure ACMP device
*
* @details
*
* @note
*
* @param[in] dev
* Pointer to device descriptor
*
* @param[in] cmd
* ACMP control command
*
* @param[in] args
* Arguments
*
* @return
* Error code
*********************************************************************/
static rt_err_t rt_acmp_control(
rt_device_t dev,
rt_uint8_t cmd,
void *args)
{
RT_ASSERT(dev != RT_NULL);
struct efm32_acmp_device_t *acmp;
acmp = (struct efm32_acmp_device_t *)(dev->user_data);
switch (cmd)
{
case RT_DEVICE_CTRL_SUSPEND:
/* Suspend device */
dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
ACMP_DisableNoReset(acmp->acmp_device);
break;
case RT_DEVICE_CTRL_RESUME:
/* Resume device */
dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
ACMP_Enable(acmp->acmp_device);
break;
case RT_DEVICE_CTRL_ACMP_INIT:
{
rt_bool_t int_en = false;
rt_kprintf("ACMP: control -> init start\n");
/* change device setting */
struct efm32_acmp_control_t *control;
control = (struct efm32_acmp_control_t *)args;
/* Configure ACMPn */
if (control->init == RT_NULL)
{
return -RT_ERROR;
}
ACMP_Init(acmp->acmp_device, control->init);
ACMP_ChannelSet(acmp->acmp_device, control->negInput, control->posInput);
if (control->output != RT_NULL)
{
ACMP_GPIOSetup(
acmp->acmp_device,
control->output->location,
control->output->enable,
control->output->invert);
int_en = true;
}
if (control->hook.cbFunc != RT_NULL)
{
acmp->hook.cbFunc = control->hook.cbFunc;
acmp->hook.userPtr = control->hook.userPtr;
int_en = true;
}
if (int_en)
{
/* Enable edge interrupt */
ACMP_IntEnable(acmp->acmp_device, ACMP_IEN_EDGE);
ACMP_IntClear(acmp->acmp_device, ACMP_IFC_EDGE);
/* Enable ACMP0/1 interrupt vector in NVIC */
NVIC_ClearPendingIRQ(ACMP0_IRQn);
NVIC_SetPriority(ACMP0_IRQn, EFM32_IRQ_PRI_DEFAULT);
NVIC_EnableIRQ(ACMP0_IRQn);
}
}
break;
case RT_DEVICE_CTRL_ACMP_OUTPUT:
*((rt_bool_t *)args) = \
(acmp->acmp_device->STATUS & ACMP_STATUS_ACMPOUT) ? true : false;
break;
default:
return -RT_ERROR;
}
return RT_EOK;
}
/******************************************************************//**
* @brief
* Register ACMP device
*
* @details
*
* @note
*
* @param[in] device
* Pointer to device descriptor
*
* @param[in] name
* Device name
*
* @param[in] flag
* Configuration flags
*
* @param[in] acmp
* Pointer to ACMP device descriptor
*
* @return
* Error code
*********************************************************************/
rt_err_t rt_hw_acmp_register(
rt_device_t device,
const char *name,
rt_uint32_t flag,
struct efm32_acmp_device_t *acmp)
{
RT_ASSERT(device != RT_NULL);
device->type = RT_Device_Class_Char; /* fixme: should be acmp type */
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
device->init = rt_acmp_init;
device->open = RT_NULL;
device->close = RT_NULL;
device->read = RT_NULL;
device->write = RT_NULL;
device->control = rt_acmp_control;
device->user_data = acmp;
/* register a character device */
return rt_device_register(device, name, flag);
}
/******************************************************************//**
* @brief
* ACMP edge trigger interrupt handler
*
* @details
*
* @note
*********************************************************************/
void rt_hw_acmp_isr(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
struct efm32_acmp_device_t *acmp;
acmp = (struct efm32_acmp_device_t *)(dev->user_data);
if (acmp->hook.cbFunc != RT_NULL)
{
(acmp->hook.cbFunc)(acmp->hook.userPtr);
}
}
/******************************************************************//**
* @brief
* Initialize all ACMP module related hardware and register ACMP device to kernel
*
* @details
*
* @note
*
*********************************************************************/
void rt_hw_acmp_init(void)
{
struct efm32_acmp_device_t *acmp;
efm32_irq_hook_init_t hook;
#ifdef RT_USING_ACMP0
acmp = rt_malloc(sizeof(struct efm32_acmp_device_t));
if (acmp == RT_NULL)
{
rt_kprintf("no memory for ACMP0 driver\n");
return;
}
acmp->acmp_device = ACMP0;
/* Enable clock for ACMP0 module */
CMU_ClockEnable(cmuClock_ACMP0, true);
/* Reset */
ACMP_Reset(ACMP0);
hook.type = efm32_irq_type_acmp;
hook.unit = 0;
hook.cbFunc = rt_hw_acmp_isr;
hook.userPtr = &acmp0_device;
efm32_irq_hook_register(&hook);
rt_hw_acmp_register(&acmp0_device, RT_ACMP0_NAME, EFM32_NO_DATA, acmp);
#endif
#ifdef RT_USING_ACMP1
acmp = rt_malloc(sizeof(struct efm32_acmp_device_t));
if (acmp == RT_NULL)
{
rt_kprintf("no memory for ACMP1 driver\n");
return;
}
acmp->acmp_device = ACMP1;
/* Enable clock for ACMP1 module */
CMU_ClockEnable(cmuClock_ACMP1, true);
/* Reset */
ACMP_Reset(ACMP1);
hook.type = efm32_irq_type_acmp;
hook.unit = 0;
hook.cbFunc = rt_hw_acmp_isr;
hook.userPtr = &acmp0_device;
efm32_irq_hook_register(&hook);
rt_hw_acmp_register(&acmp1_device, RT_ACMP1_NAME, EFM32_NO_DATA, acmp);
#endif
}
/******************************************************************//**
* @brief
* Calculate the warm-up time value providing at least 10us
*
* @param[in] hfperFreq
* Frequency in Hz of reference HFPER clock. Set to 0 to use currently defined HFPER clock
* setting
*
* @return
* Warm-up time value to use for ACMP in order to achieve at least 10us
*********************************************************************/
ACMP_WarmTime_TypeDef efm32_acmp_WarmTimeCalc(rt_uint32_t hfperFreq)
{
if (!hfperFreq)
{
hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
/* Just in case, make sure we get non-zero freq for below calculation */
if (!hfperFreq)
{
hfperFreq = 1;
}
}
/* Determine number of HFPERCLK cycle >= 10us */
if (4 * 1000000 / hfperFreq > 10)
{
return acmpWarmTime4;
}
else if (8 * 1000000 / hfperFreq > 10)
{
return acmpWarmTime8;
}
else if (16 * 1000000 / hfperFreq > 10)
{
return acmpWarmTime16;
}
else if (32 * 1000000 / hfperFreq > 10)
{
return acmpWarmTime32;
}
else if (64 * 1000000 / hfperFreq > 10)
{
return acmpWarmTime64;
}
else if (128 * 1000000 / hfperFreq > 10)
{
return acmpWarmTime128;
}
else if (256 * 1000000 / hfperFreq > 10)
{
return acmpWarmTime256;
}
else if (512 * 1000000 / hfperFreq > 10)
{
return acmpWarmTime512;
}
}
/******************************************************************//**
* @}
*********************************************************************/

65
bsp/efm32/drv_acmp.h Normal file
View File

@ -0,0 +1,65 @@
/******************************************************************//**
* @file drv_acmp.h
* @brief ACMP (analog comparator) driver 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
**********************************************************************
* @section Change Logs
* Date Author Notes
* 2011-02-23 onelife Initial creation for EFM32
*********************************************************************/
#ifndef __DRV_ACMP_H__
#define __DRV_ACMP_H__
/* Includes -------------------------------------------------------------------*/
#include "hdl_interrupt.h"
/* Exported types -------------------------------------------------------------*/
struct efm32_acmp_device_t
{
ACMP_TypeDef *acmp_device;
efm32_irq_hook_t hook;
};
struct efm32_acmp_output_t
{
rt_uint32_t location;
rt_bool_t enable;
rt_bool_t invert;
};
struct efm32_acmp_control_t
{
ACMP_Init_TypeDef *init;
ACMP_Channel_TypeDef posInput;
ACMP_Channel_TypeDef negInput;
struct efm32_acmp_output_t *output;
efm32_irq_hook_t hook;
};
/* Exported constants ---------------------------------------------------------*/
/* Exported macro -------------------------------------------------------------*/
/** Default config for ACMP init structure. */
#define ACMP_INIT_DEFAULT \
{ \
false, /* Full bias current*/ \
true, /* Half bias current */ \
0, /* Biasprog current configuration */ \
false, /* Enable interrupt for falling edge */ \
false, /* Enable interrupt for rising edge */ \
acmpWarmTime512, /* Warm-up time must be >10us */ \
acmpHysteresisLevel0, /* Hysteresis configuration */ \
0, /* Inactive comparator output value */ \
false, /* Enable low power mode */ \
0 /* Vdd reference scaling */ \
}
/* Exported functions --------------------------------------------------------- */
void rt_hw_acmp_init(void);
#endif /*__DRV_ACMP_H__ */

452
bsp/efm32/drv_adc.c Normal file
View File

@ -0,0 +1,452 @@
/******************************************************************//**
* @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
**********************************************************************
* @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-02-21 onelife Initial creation for EFM32
*********************************************************************/
/******************************************************************//**
* @addtogroup efm32
* @{
*********************************************************************/
/* Includes -------------------------------------------------------------------*/
#include "board.h"
#include "drv_adc.h"
/* Private typedef -------------------------------------------------------------*/
/* Private define --------------------------------------------------------------*/
/* Private macro --------------------------------------------------------------*/
/* Private variables ------------------------------------------------------------*/
#ifdef RT_USING_ADC0
static struct rt_device adc0_device;
#endif
/* Private function prototypes ---------------------------------------------------*/
rt_uint32_t efm32_adc_calibration(
ADC_TypeDef *adc,
ADC_Ref_TypeDef ref,
ADC_SingleInput_TypeDef input);
/* Private functions ------------------------------------------------------------*/
/******************************************************************//**
* @brief
* Initialize ADC device
*
* @details
*
* @note
*
* @param[in] dev
* Pointer to device descriptor
*
* @return
* Error code
*********************************************************************/
static rt_err_t rt_adc_init(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
rt_uint32_t temp;
struct efm32_adc_device_t *adc;
adc = (struct efm32_adc_device_t *)(dev->user_data);
temp = efm32_adc_calibration(adc->adc_device, ADC_INIT_REF, ADC_INIT_CH);
#ifdef RT_ADC_DEBUG
rt_kprintf("adc->CAL = %x\n", temp);
#endif
return RT_EOK;
}
/******************************************************************//**
* @brief
* Configure ADC device
*
* @details
*
* @note
*
* @param[in] dev
* Pointer to device descriptor
*
* @param[in] cmd
* ADC control command
*
* @param[in] args
* Arguments
*
* @return
* Error code
*********************************************************************/
static rt_err_t rt_adc_control(
rt_device_t dev,
rt_uint8_t cmd,
void *args)
{
RT_ASSERT(dev != RT_NULL);
struct efm32_adc_device_t *adc;
adc = (struct efm32_adc_device_t *)(dev->user_data);
switch (cmd)
{
case RT_DEVICE_CTRL_SUSPEND:
/* Suspend device */
dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
adc->adc_device->CMD = ADC_CMD_SINGLESTOP | ADC_CMD_SCANSTOP;
break;
case RT_DEVICE_CTRL_RESUME:
/* Resume device */
dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
switch (adc->mode)
{
case ADC_MODE_SINGLE:
ADC_Start(adc->adc_device, adcStartSingle);
break;
case ADC_MODE_SCAN:
ADC_Start(adc->adc_device, adcStartScan);
break;
case ADC_MODE_TAILGATE:
ADC_Start(adc->adc_device, adcStartScanAndSingle);
break;
default:
return -RT_ERROR;
}
break;
case RT_DEVICE_CTRL_ADC_MODE:
{
/* change device setting */
struct efm32_adc_control_t *control;
control = (struct efm32_adc_control_t *)args;
switch (control->mode)
{
case ADC_MODE_SINGLE:
ADC_InitSingle(adc->adc_device, control->singleInit);
break;
case ADC_MODE_SCAN:
ADC_InitScan(adc->adc_device, control->scanInit);
break;
case ADC_MODE_TAILGATE:
ADC_InitSingle(adc->adc_device, control->singleInit);
ADC_InitScan(adc->adc_device, control->scanInit);
break;
default:
return -RT_ERROR;
}
adc->mode = control->mode;
}
break;
case RT_DEVICE_CTRL_ADC_RESULT:
switch (adc->mode)
{
case ADC_MODE_SINGLE:
while (adc->adc_device->STATUS & ADC_STATUS_SINGLEACT);
*((rt_uint32_t *)args) = ADC_DataSingleGet(adc->adc_device);
break;
case ADC_MODE_SCAN:
while (adc->adc_device->STATUS & ADC_STATUS_SCANACT);
*((rt_uint32_t *)args) = ADC_DataScanGet(adc->adc_device);
break;
case ADC_MODE_TAILGATE:
while (adc->adc_device->STATUS & ADC_STATUS_SCANACT);
*((rt_uint32_t *)args) = ADC_DataScanGet(adc->adc_device);
while (adc->adc_device->STATUS & ADC_STATUS_SINGLEACT);
*((rt_uint32_t *)args + 1) = ADC_DataSingleGet(adc->adc_device);
break;
default:
return -RT_ERROR;
}
break;
}
return RT_EOK;
}
/******************************************************************//**
* @brief
* Register ADC device
*
* @details
*
* @note
*
* @param[in] device
* Pointer to device descriptor
*
* @param[in] name
* Device name
*
* @param[in] flag
* Configuration flags
*
* @param[in] adc
* Pointer to ADC device descriptor
*
* @return
* Error code
*********************************************************************/
rt_err_t rt_hw_adc_register(
rt_device_t device,
const char *name,
rt_uint32_t flag,
struct efm32_adc_device_t *adc)
{
RT_ASSERT(device != RT_NULL);
device->type = RT_Device_Class_Char; /* fixme: should be adc type */
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
device->init = rt_adc_init;
device->open = RT_NULL;
device->close = RT_NULL;
device->read = RT_NULL;
device->write = RT_NULL;
device->control = rt_adc_control;
device->user_data = adc;
/* register a character device */
return rt_device_register(device, name, flag);
}
/******************************************************************//**
* @brief
* Initialize all ADC module related hardware and register ADC device to kernel
*
* @details
*
* @note
*
*********************************************************************/
void rt_hw_adc_init(void)
{
struct efm32_adc_device_t *adc;
ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
init.ovsRateSel = adcOvsRateSel4096; //TODO
init.timebase = ADC_TimebaseCalc(0);
init.prescale = ADC_PrescaleCalc(ADC_CONVERT_FREQUENCY, 0);
#ifdef RT_USING_ADC0
adc = rt_malloc(sizeof(struct efm32_adc_device_t));
if (adc == RT_NULL)
{
rt_kprintf("no memory for ADC driver\n");
return;
}
adc->adc_device = ADC0;
adc->mode = ADC_MODE_SINGLE;
/* Enable clock for ADCn module */
CMU_ClockEnable(cmuClock_ADC0, true);
/* Reset */
ADC_Reset(ADC0);
/* Configure ADC */
ADC_Init(adc->adc_device, &init);
rt_hw_adc_register(&adc0_device, RT_ADC0_NAME, EFM32_NO_DATA, adc);
#endif
}
/***************************************************************************//**
* @brief
* Calibrate offset and gain for the specified reference.
* Supports currently only single ended gain calibration.
* Could easily be expanded to support differential gain calibration.
*
* @details
* The offset calibration routine measures 0 V with the ADC, and adjust
* the calibration register until the converted value equals 0.
* The gain calibration routine needs an external reference voltage equal
* to the top value for the selected reference. For example if the 2.5 V
* reference is to be calibrated, the external supply must also equal 2.5V.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @param[in] ref
* Reference used during calibration. Can be both external and internal
* references.
*
* @param[in] input
* Input channel used during calibration.
*
* @return
* The final value of the calibration register, note that the calibration
* register gets updated with this value during the calibration.
* No need to load the calibration values after the function returns.
******************************************************************************/
rt_uint32_t efm32_adc_calibration(
ADC_TypeDef *adc,
ADC_Ref_TypeDef ref,
ADC_SingleInput_TypeDef input)
{
rt_uint32_t cal;
rt_int32_t sample;
rt_int8_t high, mid, low, tmp;
ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
/* Init for single conversion use, measure diff 0 with selected reference. */
singleInit.reference = ref;
singleInit.input = adcSingleInpDiff0;
singleInit.acqTime = adcAcqTime32;
singleInit.diff = true;
/* Enable oversampling rate */
singleInit.resolution = adcResOVS;
ADC_InitSingle(adc, &singleInit);
/* ADC is now set up for offset calibration */
/* Offset calibration register is a 7 bit signed 2's complement value. */
/* Use unsigned indexes for binary search, and convert when calibration */
/* register is written to. */
high = 63;
low = -64;
/* Do binary search for offset calibration*/
while (low < high)
{
/* Calculate midpoint */
mid = low + (high - low) / 2;
/* Midpoint is converted to 2's complement and written to both scan and */
/* single calibration registers */
cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SCANOFFSET_MASK);
tmp = mid < 0 ? (mid & 0x3F ^ 0x3F | 0x40) + 1 : mid;
cal |= tmp << _ADC_CAL_SINGLEOFFSET_SHIFT;
cal |= tmp << _ADC_CAL_SCANOFFSET_SHIFT;
#ifdef RT_ADC_DEBUG
rt_kprintf("adc->CAL = %x, cal = %x, tmp = %x\n", adc->CAL, cal, tmp);
#endif
adc->CAL = cal;
/* Do a conversion */
ADC_Start(adc, adcStartSingle);
/* Wait while conversion is active */
while (adc->STATUS & ADC_STATUS_SINGLEACT) ;
/* Get ADC result */
sample = ADC_DataSingleGet(adc);
/* Check result and decide in which part of to repeat search */
/* Calibration register has negative effect on result */
if (sample < 0)
{
/* Repeat search in bottom half. */
high = mid;
}
else if (sample > 0)
{
/* Repeat search in top half. */
low = mid + 1;
}
else
{
/* Found it, exit while loop */
break;
}
}
#ifdef RT_ADC_DEBUG
rt_kprintf("adc->CAL = %x\n", adc->CAL);
#endif
/* Now do gain calibration, only input and diff settings needs to be changed */
adc->SINGLECTRL &= ~(_ADC_SINGLECTRL_INPUTSEL_MASK | _ADC_SINGLECTRL_DIFF_MASK);
adc->SINGLECTRL |= (input << _ADC_SINGLECTRL_INPUTSEL_SHIFT);
adc->SINGLECTRL |= (false << _ADC_SINGLECTRL_DIFF_SHIFT);
/* ADC is now set up for gain calibration */
/* Gain calibration register is a 7 bit unsigned value. */
high = 127;
low = 0;
/* Do binary search for gain calibration */
while (low < high)
{
/* Calculate midpoint and write to calibration register */
mid = low + (high - low) / 2;
/* Midpoint is converted to 2's complement */
cal = adc->CAL & ~(_ADC_CAL_SINGLEGAIN_MASK | _ADC_CAL_SCANGAIN_MASK);
cal |= mid << _ADC_CAL_SINGLEGAIN_SHIFT;
cal |= mid << _ADC_CAL_SCANGAIN_SHIFT;
#ifdef RT_ADC_DEBUG
rt_kprintf("adc->CAL = %x, cal = %x, mid = %x\n", adc->CAL, cal, mid);
#endif
adc->CAL = cal;
/* Do a conversion */
ADC_Start(adc, adcStartSingle);
/* Wait while conversion is active */
while (adc->STATUS & ADC_STATUS_SINGLEACT) ;
/* Get ADC result */
sample = ADC_DataSingleGet(adc);
/* Check result and decide in which part to repeat search */
/* Compare with a value atleast one LSB's less than top to avoid overshooting */
/* Since oversampling is used, the result is 16 bits, but a couple of lsb's */
/* applies to the 12 bit result value, if 0xffe is the top value in 12 bit, this */
/* is in turn 0xffe0 in the 16 bit result. */
/* Calibration register has positive effect on result */
if (sample > 0xffd0)
{
/* Repeat search in bottom half. */
high = mid;
}
else if (sample < 0xffd0)
{
/* Repeat search in top half. */
low = mid + 1;
}
else
{
/* Found it, exit while loop */
break;
}
}
#ifdef RT_ADC_DEBUG
rt_kprintf("adc->CAL = %x\n", adc->CAL);
#endif
return adc->CAL;
}
/******************************************************************//**
* @}
*********************************************************************/

43
bsp/efm32/drv_adc.h Normal file
View File

@ -0,0 +1,43 @@
/******************************************************************//**
* @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
**********************************************************************
* @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-02-21 onelife Initial creation for EFM32
*********************************************************************/
#ifndef __DRV_ADC_H__
#define __DRV_ADC_H__
/* Includes -------------------------------------------------------------------*/
/* Exported types -------------------------------------------------------------*/
struct efm32_adc_device_t
{
ADC_TypeDef *adc_device;
rt_uint32_t mode;
};
struct efm32_adc_control_t
{
rt_uint32_t mode;
ADC_InitSingle_TypeDef *singleInit;
ADC_InitScan_TypeDef *scanInit;
};
/* Exported constants ---------------------------------------------------------*/
/* Exported macro -------------------------------------------------------------*/
#define ADC_MODE_SINGLE 0x00UL
#define ADC_MODE_SCAN 0x01UL
#define ADC_MODE_TAILGATE 0x02UL
/* Exported functions --------------------------------------------------------- */
void rt_hw_adc_init(void);
#endif /*__DRV_ADC_H__ */

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file drv_dma.c
* @brief USART driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file drv_dma.h
* @brief USART driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file drv_iic.c
* @brief Serial API of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************
@ -74,16 +74,6 @@ static rt_err_t rt_iic_init (rt_device_t dev)
return RT_EOK;
}
static rt_err_t rt_iic_open(rt_device_t dev, rt_uint16_t oflag)
{
return RT_EOK;
}
static rt_err_t rt_iic_close(rt_device_t dev)
{
return RT_EOK;
}
/******************************************************************//**
* @brief
* Read from IIC device
@ -296,9 +286,10 @@ static rt_err_t rt_iic_control (
rt_uint8_t cmd,
void *args)
{
RT_ASSERT(dev != RT_NULL);
struct efm32_iic_device_t *iic;
RT_ASSERT(dev != RT_NULL);
iic = (struct efm32_iic_device_t*)dev->user_data;
switch (cmd)
{
@ -314,7 +305,7 @@ static rt_err_t rt_iic_control (
I2C_Enable(iic->iic_device, true);
break;
case RT_DEVICE_CTRL_IIC:
case RT_DEVICE_CTRL_IIC_SETTING:
{
/* change device setting */
struct efm32_iic_control_t *control;
@ -371,8 +362,8 @@ rt_err_t rt_hw_iic_register(
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
device->init = rt_iic_init;
device->open = rt_iic_open;
device->close = rt_iic_close;
device->open = RT_NULL;
device->close = RT_NULL;
device->read = rt_iic_read;
device->write = rt_iic_write;
device->control = rt_iic_control;
@ -486,7 +477,7 @@ void rt_hw_iic_init(void)
rt_hw_iic_register(&iic0_device, RT_IIC0_NAME, flag, iic);
#endif
/* register iic1 */
/* register iic1 */
#ifdef RT_USING_IIC1
iic = rt_malloc(sizeof(struct efm32_iic_device_t));
if (iic == RT_NULL)

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file drv_iic.h
* @brief IIC driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file drv_rtc.c
* @brief RTC driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************
@ -29,8 +29,8 @@
/* Private define --------------------------------------------------------------*/
/* Private macro --------------------------------------------------------------*/
/* Private variables ------------------------------------------------------------*/
static rt_uint32_t rtc_time;
static struct rt_device rtc;
static rt_uint32_t rtc_time;
/* Private function prototypes ---------------------------------------------------*/
static void startLfxoForRtc(void);
@ -117,6 +117,49 @@ void rt_hw_rtc_isr(rt_device_t device)
RTC->IFC = _RTC_IFC_MASK;
}
/******************************************************************//**
* @brief
* Register RTC device
*
* @details
*
* @note
*
* @param[in] device
* Pointer to device descriptor
*
* @param[in] name
* Device name
*
* @param[in] flag
* Configuration flags
*
* @return
* Error code
*********************************************************************/
rt_err_t rt_hw_rtc_register(
rt_device_t device,
const char *name,
rt_uint32_t flag)
{
RT_ASSERT(device != RT_NULL);
device->type = RT_Device_Class_RTC;
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
device->init = RT_NULL;
device->open = rt_rtc_open;
device->close = RT_NULL;
device->read = rt_rtc_read;
device->write = RT_NULL;
device->control = rt_rtc_control;
device->user_data = RT_NULL; /* no private */
/* register a character device */
return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
}
/******************************************************************//**
* @brief
* Initialize all RTC module related hardware and register RTC device to kernel
@ -129,7 +172,6 @@ void rt_hw_rtc_init(void)
{
rt_uint32_t reset;
rtc.type = RT_Device_Class_RTC;
reset = RMU_ResetCauseGet();
if (reset & RMU_RSTCAUSE_PORST || reset & RMU_RSTCAUSE_EXTRST) //TODO
@ -168,14 +210,7 @@ void rt_hw_rtc_init(void)
}
/* register rtc device */
rtc.init = RT_NULL;
rtc.open = rt_rtc_open;
rtc.close = RT_NULL;
rtc.read = rt_rtc_read;
rtc.write = RT_NULL;
rtc.control = rt_rtc_control;
rtc.user_data = RT_NULL; /* no private */
rt_device_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
rt_hw_rtc_register(&rtc, RT_RTC_NAME, EFM32_NO_DATA);
}
/******************************************************************//**

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file drv_rtc.h
* @brief RTC driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************
@ -24,4 +24,4 @@
/* Exported functions --------------------------------------------------------- */
void rt_hw_rtc_init(void);
#endif
#endif /* __DRV_RTC_H__ */

View File

@ -27,7 +27,7 @@
/* Private define --------------------------------------------------------------*/
/* Private macro --------------------------------------------------------------*/
#define TIMER_TopCalculate(p) \
(p * (HFXO_FREQUENCY / (1 << TMR_CFG_PRESCALER) / 1000))
(p * (EFM32_HFXO_FREQUENCY / (1 << TMR_CFG_PRESCALER) / 1000))
/* Private variables ------------------------------------------------------------*/
#ifdef RT_USING_TIMER2
@ -56,7 +56,6 @@
struct efm32_timer_device_t *timer;
RT_ASSERT(dev != RT_NULL);
timer = (struct efm32_timer_device_t *)(dev->user_data);
timer->hook.cbFunc = RT_NULL;
@ -90,9 +89,10 @@ static rt_err_t rt_hs_timer_control (
rt_uint8_t cmd,
void *args)
{
RT_ASSERT(dev != RT_NULL);
struct efm32_timer_device_t *timer;
RT_ASSERT(dev != RT_NULL);
timer = (struct efm32_timer_device_t *)(dev->user_data);
switch (cmd)
@ -109,7 +109,7 @@ static rt_err_t rt_hs_timer_control (
TIMER_Enable(timer->timer_device, true);
break;
case RT_DEVICE_CTRL_TIMER:
case RT_DEVICE_CTRL_TIMER_PERIOD:
{
/* change device setting */
struct efm32_timer_control_t *control;
@ -185,9 +185,10 @@ rt_err_t rt_hw_timer_register(
*********************************************************************/
void rt_hw_timer_isr(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
struct efm32_timer_device_t *timer;
RT_ASSERT(dev != RT_NULL);
timer = (struct efm32_timer_device_t *)(dev->user_data);
if (timer->hook.cbFunc != RT_NULL)

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file drv_timer.h
* @brief USART driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************
@ -22,7 +22,7 @@
/* Exported types -------------------------------------------------------------*/
struct efm32_timer_device_t
{
TIMER_TypeDef* timer_device;
TIMER_TypeDef *timer_device;
efm32_irq_hook_t hook;
};

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file drv_usart.c
* @brief USART driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************
@ -125,10 +125,11 @@ static rt_err_t rt_usart_init (rt_device_t dev)
*********************************************************************/
static rt_err_t rt_usart_open(rt_device_t dev, rt_uint16_t oflag)
{
RT_ASSERT(dev != RT_NULL);
struct efm32_usart_device_t *usart;
IRQn_Type rxIrq;
RT_ASSERT(dev != RT_NULL);
usart = (struct efm32_usart_device_t *)(dev->user_data);
//if (usart->state & USART_STATE_CONSOLE)
@ -454,9 +455,10 @@ static rt_err_t rt_usart_control (
rt_uint8_t cmd,
void *args)
{
RT_ASSERT(dev != RT_NULL);
struct efm32_usart_device_t *usart;
RT_ASSERT(dev != RT_NULL);
usart = (struct efm32_usart_device_t *)(dev->user_data);
switch (cmd)
@ -473,7 +475,7 @@ static rt_err_t rt_usart_control (
USART_Enable(usart->usart_device, usartEnable);
break;
case RT_DEVICE_CTRL_USART:
case RT_DEVICE_CTRL_USART_RBUFFER:
/* Set RX buffer */
{
struct efm32_usart_int_mode_t *int_rx;

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file drv_usart.h
* @brief USART driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file efm32_rom.ld
* @brief Linker script for EFM32 with GNU ld
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file hdl_interrupt.c
* @brief USART driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************
@ -29,9 +29,10 @@
/* Private variables ---------------------------------------------------------*/
efm32_irq_hook_t dmaCbTable[DMA_CHAN_COUNT * 2] = {RT_NULL};
efm32_irq_hook_t timerCbTable[TIMER_COUNT] = {RT_NULL};
efm32_irq_hook_t gpioCbTable[16] = {RT_NULL};
efm32_irq_hook_t usartCbTable[USART_COUNT * 2] = {RT_NULL};
efm32_irq_hook_t rtcCbTable[RTC_COUNT] = {RT_NULL};
efm32_irq_hook_t gpioCbTable[16] = {RT_NULL};
efm32_irq_hook_t acmpCbTable[ACMP_COUNT] = {RT_NULL};
efm32_irq_hook_t usartCbTable[USART_COUNT * 2] = {RT_NULL};
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
@ -205,6 +206,34 @@ void TIMER2_IRQHandler(void)
}
}
/******************************************************************//**
* @brief
* Common RTC interrupt handler
*
* @details
* This function handles RTC counter overflow interrupt request
*
* @note
*
*********************************************************************/
void RTC_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
if (RTC->IF & RTC_IF_OF)
{
/* invoke callback function */
if (rtcCbTable[0].cbFunc != RT_NULL)
{
(rtcCbTable[0].cbFunc)(rtcCbTable[0].userPtr);
}
}
/* leave interrupt */
rt_interrupt_leave();
}
/******************************************************************//**
* @brief
* Common even number GPIO interrupt handler
@ -271,6 +300,49 @@ void GPIO_ODD_IRQHandler(void)
rt_interrupt_leave();
}
/******************************************************************//**
* @brief
* Common ACMP interrupt handler
*
* @details
* This function handles ACMP edge trigger interrupt request
*
* @note
*
*********************************************************************/
void ACMP0_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
if (ACMP0->IF & ACMP_IF_EDGE)
{
/* invoke callback function */
if (acmpCbTable[0].cbFunc != RT_NULL)
{
(acmpCbTable[0].cbFunc)(acmpCbTable[0].userPtr);
}
/* clear interrupt */
BITBAND_Peripheral(&(ACMP0->IFC), _ACMP_IF_EDGE_SHIFT, 0x1UL);
}
if (ACMP1->IF & ACMP_IF_EDGE)
{
/* invoke callback function */
if (acmpCbTable[1].cbFunc != RT_NULL)
{
(acmpCbTable[1].cbFunc)(acmpCbTable[1].userPtr);
}
/* clear interrupt */
BITBAND_Peripheral(&(ACMP1->IFC), _ACMP_IF_EDGE_SHIFT, 0x1UL);
}
/* leave interrupt */
rt_interrupt_leave();
}
/******************************************************************//**
* @brief
* Common USART0 TX interrupt handler
@ -430,34 +502,6 @@ void USART2_RX_IRQHandler(void)
}
}
/******************************************************************//**
* @brief
* Common RTC interrupt handler
*
* @details
* This function handles RTC counter overflow interrupt request
*
* @note
*
*********************************************************************/
void RTC_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
if (RTC->IF & RTC_IF_OF)
{
/* invoke callback function */
if (rtcCbTable[0].cbFunc != RT_NULL)
{
(rtcCbTable[0].cbFunc)(rtcCbTable[0].userPtr);
}
}
/* leave interrupt */
rt_interrupt_leave();
}
/******************************************************************//**
* @brief
* EFM32 common interrupt handlers register function
@ -475,7 +519,12 @@ rt_err_t efm32_irq_hook_register(efm32_irq_hook_init_t *hook)
dmaCbTable[hook->unit].cbFunc = hook->cbFunc;
dmaCbTable[hook->unit].userPtr = hook->userPtr;
break;
case efm32_irq_type_rtc:
rtcCbTable[hook->unit].cbFunc = hook->cbFunc;
rtcCbTable[hook->unit].userPtr = hook->userPtr;
break;
case efm32_irq_type_timer:
timerCbTable[hook->unit].cbFunc = hook->cbFunc;
timerCbTable[hook->unit].userPtr = hook->userPtr;
@ -485,17 +534,17 @@ rt_err_t efm32_irq_hook_register(efm32_irq_hook_init_t *hook)
gpioCbTable[hook->unit].cbFunc = hook->cbFunc;
gpioCbTable[hook->unit].userPtr = hook->userPtr;
break;
case efm32_irq_type_acmp:
acmpCbTable[hook->unit].cbFunc = hook->cbFunc;
acmpCbTable[hook->unit].userPtr = hook->userPtr;
break;
case efm32_irq_type_usart:
usartCbTable[hook->unit].cbFunc = hook->cbFunc;
usartCbTable[hook->unit].userPtr = hook->userPtr;
break;
case efm32_irq_type_rtc:
rtcCbTable[hook->unit].cbFunc = hook->cbFunc;
rtcCbTable[hook->unit].userPtr = hook->userPtr;
break;
default:
break;
}

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file hdl_interrupt.h
* @brief USART driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************
@ -21,10 +21,11 @@
enum efm32_irq_hook_type_t
{
efm32_irq_type_dma = 0,
efm32_irq_type_rtc,
efm32_irq_type_timer,
efm32_irq_type_gpio,
efm32_irq_type_usart,
efm32_irq_type_rtc
efm32_irq_type_acmp,
efm32_irq_type_usart
};
typedef void (*efm32_irq_callback_t)(rt_device_t device);

View File

@ -34,6 +34,7 @@
//#define THREAD_DEBUG
//#define IRQ_DEBUG
//#define RT_IRQHDL_DEBUG
//#define RT_ADC_DEBUG
#define RT_USING_OVERFLOW_CHECK
#define RT_USART_DEBUG
@ -87,6 +88,20 @@
#define RT_USART1_USING_DMA 0x0UL
#endif
/* SECTION: RTC options */
#if (defined(EFM32_G290_DK) || defined(EFM32_G890_STK))
#define RT_USING_RTC
#endif
#define RT_RTC_NAME "rtc"
/* SECTION: ADC options */
#define RT_USING_ACMP0
#define RT_ACMP0_NAME "acmp0"
/* SECTION: ADC options */
#define RT_USING_ADC0
#define RT_ADC0_NAME "adc"
/* SECTION: Serial options */
#if defined(EFM32_G290_DK)
#define RT_CONSOLE_DEVICE 0x0UL

View File

@ -3,12 +3,18 @@ ARCH = 'arm'
CPU = 'cortex-m3'
CROSS_TOOL = 'gcc'
if CROSS_TOOL == 'gcc':
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = 'C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin'
BUILD = 'debug'
EFM32_TYPE = 'EFM32G890F128'
EFM32_BOARD = 'EFM32_G890_STK'
# EFM32_BOARD = 'EFM32_G290_DK'
if EFM32_BOARD == 'EFM32_G890_STK':
EFM32_TYPE = 'EFM32G890F128'
elif EFM32_BOARD == 'EFM32_G290_DK':
EFM32_TYPE = 'EFM32G290F128'
if PLATFORM == 'gcc':
# toolchains

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file interrupt.c
* @brief This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************
@ -118,9 +118,11 @@ void rtthread_startup(void)
/* init scheduler system */
rt_system_scheduler_init();
#ifdef RT_USING_RTC
/* init RTC */
rt_hw_rtc_init();
#endif
/* init all device */
rt_device_init_all();

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file context_gcc.S
* @brief Context switch functions
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file cpu.c
* @brief This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file fault.c
* @brief This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file fault_gcc.S
* @brief Faults handling functions
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file interrupt.c
* @brief This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file stack.c
* @brief This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife
* @version 0.4 beta
**********************************************************************

View File

@ -1,7 +1,7 @@
/******************************************************************//**
* @file start_gcc.S
* @brief Context switch functions
* COPYRIGHT (C) 2009, RT-Thread Development Team
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
**********************************************************************