*** 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:
parent
338155eddc
commit
cabc797a2d
|
@ -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')
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
/******************************************************************//**
|
||||
* @}
|
||||
*********************************************************************/
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
* @}
|
||||
*********************************************************************/
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
* @}
|
||||
*********************************************************************/
|
|
@ -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__ */
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
|
|
|
@ -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__ */
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
|
@ -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
|
||||
**********************************************************************
|
||||
|
|
Loading…
Reference in New Issue