dev_misc.c 6.0 KB
Newer Older
O
onelife.real@gmail.com 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 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

/******************************************************************//**
 * @}
*********************************************************************/