rt-thread/bsp/efm32/dev_misc.c
onelife.real ea6d73f140 *** EFM32 branch ***
1. Upgrade Cortex driver library (CMSIS -> CMSIS & Device): version 2.3.2 -> 3.0.1 & 3.0.0
 - Remove "bsp/efm32/Libraries/CMSIS/Lib/ARM", "bsp/efm32/Libraries/CMSIS/Lib/G++" and "bsp/efm32/Libraries/CMSIS/SVD" to save space
2. Upgrade EFM32 driver libraries (efm32lib -> emlib): version 2.3.2 -> 3.0.0
 - Remove "bsp/efm32/Libraries/Device/EnergyMicro/EFM32LG" and "bsp/efm32/Libraries/Device/EnergyMicro/EFM32TG" to save space
3. Upgrade EFM32GG_DK3750 development kit driver library: version 1.2.2 -> 2.0.1
4. Upgrade EFM32_Gxxx_DK development kit driver library: version 1.7.3 -> 2.0.1
5. Add energy management unit driver and test code
6. Modify linker script and related code to compatible with new version of libraries
7. Change EFM32 branch version number to 1.0
8. Add photo frame demo application

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2122 bbd45198-f89e-11dd-88c7-29a3b14d5316
2012-05-18 04:40:40 +00:00

205 lines
7.0 KiB
C

/***************************************************************************//**
* @file dev_misc.c
* @brief Miscellaneous driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2012, RT-Thread Development Team
* @author onelife
* @version 1.0
*******************************************************************************
* @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
* 2011-07-27 onelife Modify according to ADC driver changes
******************************************************************************/
/***************************************************************************//**
* @addtogroup efm32
* @{
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "board.h"
#include "drv_adc.h"
#if defined(RT_USING_MISC)
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#ifdef RT_MISC_DEBUG
#define misc_debug(format,args...) rt_kprintf(format, ##args)
#else
#define misc_debug(format,args...)
#endif
/* Private constants ---------------------------------------------------------*/
static rt_device_t adc0;
static struct efm32_adc_control_t control = \
{ADC_MODE_SINGLE, {}, {0, (rt_uint8_t)EFM32_NO_DMA}};
/* 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;
struct efm32_adc_result_t result;
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.single.init = &singleInit;
adc0->control(adc0, RT_DEVICE_CTRL_ADC_MODE, &control);
result.mode = control.mode;
result.buffer = (void *)&temp;
adc0->control(adc0, RT_DEVICE_CTRL_RESUME, &result);
adc0->control(adc0, RT_DEVICE_CTRL_ADC_RESULT, &result);
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;
struct efm32_adc_result_t result;
rt_uint32_t vdd;
/* Set input to temperature sensor. Reference must be 1.25V */
singleInit.acqTime = adcAcqTime32;
singleInit.reference = adcRef1V25;
singleInit.input = adcSingleInpVDDDiv3;
control.single.init = &singleInit;
adc0->control(adc0, RT_DEVICE_CTRL_ADC_MODE, &control);
result.mode = control.mode;
result.buffer = (void *)&vdd;
adc0->control(adc0, RT_DEVICE_CTRL_RESUME, &result);
adc0->control(adc0, RT_DEVICE_CTRL_ADC_RESULT, &result);
return (vdd * 125 * 3) / 4096;
}
/***************************************************************************//**
* @brief
* Initialize all the miscellaneous drivers
*
* @details
*
* @note
*
* @return
* Error code
******************************************************************************/
rt_err_t rt_hw_misc_init(void)
{
do
{
/* Find ADC device */
adc0 = rt_device_find(RT_ADC0_NAME);
if (adc0 == RT_NULL)
{
misc_debug("Misc err: Can't find device: %s!\n", RT_ADC0_NAME);
break;
}
misc_debug("Misc: Find device %s\n", RT_ADC0_NAME);
return RT_EOK;
} while (0);
misc_debug("Misc err: Init failed!\n");
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 /* RT_USING_FINSH */
#endif /* defined(RT_USING_MISC) */
/***************************************************************************//**
* @}
******************************************************************************/