dev_misc.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /******************************************************************//**
  2. * @file dev_misc.c
  3. * @brief Miscellaneous drivers of RT-Thread RTOS for EFM32
  4. * COPYRIGHT (C) 2011, RT-Thread Development Team
  5. * @author onelife
  6. * @version 0.4 beta
  7. **********************************************************************
  8. * @section License
  9. * The license and distribution terms for this file may be found in the file LICENSE in this
  10. * distribution or at http://www.rt-thread.org/license/LICENSE
  11. **********************************************************************
  12. * @section Change Logs
  13. * Date Author Notes
  14. * 2011-02-22 onelife Initial creation for EFM32
  15. *********************************************************************/
  16. /******************************************************************//**
  17. * @addtogroup efm32
  18. * @{
  19. *********************************************************************/
  20. /* Includes -------------------------------------------------------------------*/
  21. #include "board.h"
  22. #include "drv_adc.h"
  23. /* Private typedef -------------------------------------------------------------*/
  24. /* Private define --------------------------------------------------------------*/
  25. /* Private macro --------------------------------------------------------------*/
  26. #ifdef RT_MISC_DEBUG
  27. #define misc_debug(format,args...) rt_kprintf(format, ##args)
  28. #else
  29. #define misc_debug(format,args...)
  30. #endif
  31. /* Private constants -----------------------------------------------------------*/
  32. static rt_device_t adc0;
  33. static struct efm32_adc_control_t control = {ADC_MODE_SINGLE};
  34. /* Private variables ------------------------------------------------------------*/
  35. /* Private function prototypes ---------------------------------------------------*/
  36. rt_int32_t efm32_misc_getCelsius(rt_uint32_t adcSample);
  37. /* Private functions ------------------------------------------------------------*/
  38. /******************************************************************//**
  39. * @brief
  40. * Get current temperature value in degree celsius
  41. *
  42. * @details
  43. *
  44. * @note
  45. *
  46. * @return
  47. * Temperature value (signed integer) in degree celsius times 100
  48. *
  49. *********************************************************************/
  50. rt_int32_t rt_hw_get_temp(void)
  51. {
  52. ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
  53. rt_uint32_t temp;
  54. /* Set input to temperature sensor. Acquisition time must be 256 cycles. Reference must
  55. be 1.25V */
  56. singleInit.acqTime = adcAcqTime32;
  57. singleInit.reference = adcRef1V25;
  58. singleInit.input = adcSingleInpTemp;
  59. control.singleInit = &singleInit;
  60. adc0->control(adc0, RT_DEVICE_CTRL_ADC_MODE, &control);
  61. adc0->control(adc0, RT_DEVICE_CTRL_RESUME, EFM32_NO_POINTER);
  62. adc0->control(adc0, RT_DEVICE_CTRL_ADC_RESULT, &temp);
  63. return efm32_misc_getCelsius(temp);
  64. }
  65. /******************************************************************//**
  66. * @brief
  67. * Get current VDD value in volt
  68. *
  69. * @details
  70. *
  71. * @note
  72. *
  73. * @return
  74. * VDD value (unsigned integer) in volt times 100
  75. *
  76. *********************************************************************/
  77. rt_uint32_t rt_hw_get_vdd(void)
  78. {
  79. ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
  80. rt_uint32_t vdd;
  81. /* Set input to temperature sensor. Reference must be 1.25V */
  82. singleInit.acqTime = adcAcqTime32;
  83. singleInit.reference = adcRef1V25;
  84. singleInit.input = adcSingleInpVDDDiv3;
  85. control.singleInit = &singleInit;
  86. adc0->control(adc0, RT_DEVICE_CTRL_ADC_MODE, &control);
  87. adc0->control(adc0, RT_DEVICE_CTRL_RESUME, EFM32_NO_POINTER);
  88. adc0->control(adc0, RT_DEVICE_CTRL_ADC_RESULT, &vdd);
  89. return (vdd * 125 * 3) / 4096;
  90. }
  91. /******************************************************************//**
  92. * @brief
  93. * Initialize all the miscellaneous drivers
  94. *
  95. * @details
  96. *
  97. * @note
  98. *
  99. * @return
  100. * Error code
  101. *********************************************************************/
  102. rt_err_t rt_hw_misc_init(void)
  103. {
  104. adc0 = rt_device_find(RT_ADC0_NAME);
  105. if (adc0 == RT_NULL)
  106. {
  107. misc_debug("Batt err: Can't find device: %s!\n", RT_ADC0_NAME);
  108. goto MISC_INIT_ERROR;
  109. }
  110. return RT_EOK;
  111. MISC_INIT_ERROR:
  112. misc_debug("Misc err: Init failed!\n");
  113. return -RT_ERROR;
  114. }
  115. /**************************************************************************//**
  116. * @brief
  117. * Convert ADC result to degree celsius.
  118. *
  119. * @details
  120. *
  121. * @note
  122. * See section 2.3.4 in the reference manual for details on this calculatoin
  123. *
  124. * @param adcResult
  125. * Raw value from ADC to be converted to celsius
  126. *
  127. * @return
  128. * The temperature value (signed integer) in degrees celsius times 100
  129. *
  130. *****************************************************************************/
  131. rt_int32_t efm32_misc_getCelsius(rt_uint32_t adcResult)
  132. {
  133. /* Factory calibration temperature from device information page. */
  134. rt_int32_t cal_temp = ((DEVINFO->CAL & _DEVINFO_CAL_TEMP_MASK) \
  135. >> _DEVINFO_CAL_TEMP_SHIFT) * 100;
  136. /* Factory calibration value from device information page. */
  137. rt_int32_t cal_value = ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_TEMP1V25_MASK) \
  138. >> _DEVINFO_ADC0CAL2_TEMP1V25_SHIFT) * 10000;
  139. /* Temperature gradient (from datasheet) in (ADC unit / degree celsius * 100) */
  140. rt_int32_t t_grad = -385;
  141. return (cal_temp - (cal_value - (rt_int32_t)adcResult * 10000) / t_grad);
  142. }
  143. /*********************************************************************
  144. * Export to FINSH
  145. *********************************************************************/
  146. #ifdef RT_USING_FINSH
  147. #include <finsh.h>
  148. void list_temp(void)
  149. {
  150. rt_int32_t temp = rt_hw_get_temp();
  151. rt_kprintf("Temperature is %2d.%02d C\n", temp / 100, temp % 100);
  152. }
  153. FINSH_FUNCTION_EXPORT(list_temp, list current temperature value.)
  154. void list_vdd(void)
  155. {
  156. rt_uint32_t vdd = rt_hw_get_vdd();
  157. rt_kprintf("VDD is %1d.%02d V\n", vdd / 100, vdd % 100);
  158. }
  159. FINSH_FUNCTION_EXPORT(list_vdd, list current VDD value.)
  160. #endif
  161. /******************************************************************//**
  162. * @}
  163. *********************************************************************/