dev_misc.c 6.8 KB

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