dev_misc.c 6.0 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. /* Private constants -----------------------------------------------------------*/
  27. static rt_device_t adc0;
  28. static struct efm32_adc_control_t control = {ADC_MODE_SINGLE};
  29. /* Private variables ------------------------------------------------------------*/
  30. /* Private function prototypes ---------------------------------------------------*/
  31. rt_int32_t efm32_misc_getCelsius(rt_uint32_t adcSample);
  32. /* Private functions ------------------------------------------------------------*/
  33. /******************************************************************//**
  34. * @brief
  35. * Get current temperature value in degree celsius
  36. *
  37. * @details
  38. *
  39. * @note
  40. *
  41. * @return
  42. * Temperature value (signed integer) in degree celsius times 100
  43. *
  44. *********************************************************************/
  45. rt_int32_t rt_hw_get_temp(void)
  46. {
  47. ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
  48. rt_uint32_t temp;
  49. /* Set input to temperature sensor. Acquisition time must be 256 cycles. Reference must
  50. be 1.25V */
  51. singleInit.acqTime = adcAcqTime32;
  52. singleInit.reference = adcRef1V25;
  53. singleInit.input = adcSingleInpTemp;
  54. control.singleInit = &singleInit;
  55. adc0->control(adc0, RT_DEVICE_CTRL_ADC_MODE, &control);
  56. adc0->control(adc0, RT_DEVICE_CTRL_RESUME, EFM32_NO_POINTER);
  57. adc0->control(adc0, RT_DEVICE_CTRL_ADC_RESULT, &temp);
  58. return efm32_misc_getCelsius(temp);
  59. }
  60. /******************************************************************//**
  61. * @brief
  62. * Get current VDD value in volt
  63. *
  64. * @details
  65. *
  66. * @note
  67. *
  68. * @return
  69. * VDD value (unsigned integer) in volt times 100
  70. *
  71. *********************************************************************/
  72. rt_uint32_t rt_hw_get_vdd(void)
  73. {
  74. ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
  75. rt_uint32_t vdd;
  76. /* Set input to temperature sensor. Reference must be 1.25V */
  77. singleInit.acqTime = adcAcqTime32;
  78. singleInit.reference = adcRef1V25;
  79. singleInit.input = adcSingleInpVDDDiv3;
  80. control.singleInit = &singleInit;
  81. adc0->control(adc0, RT_DEVICE_CTRL_ADC_MODE, &control);
  82. adc0->control(adc0, RT_DEVICE_CTRL_RESUME, EFM32_NO_POINTER);
  83. adc0->control(adc0, RT_DEVICE_CTRL_ADC_RESULT, &vdd);
  84. return (vdd * 125 * 3) / 4096;
  85. }
  86. /******************************************************************//**
  87. * @brief
  88. * Initialize all the miscellaneous drivers
  89. *
  90. * @details
  91. *
  92. * @note
  93. *
  94. * @return
  95. * Error code
  96. *********************************************************************/
  97. rt_err_t rt_hw_misc_init(void)
  98. {
  99. adc0 = rt_device_find(RT_ADC0_NAME);
  100. if (adc0 == RT_NULL)
  101. {
  102. rt_kprintf("Batt error: Can't find device: %s!\n", RT_ADC0_NAME);
  103. goto MISC_INIT_ERROR;
  104. }
  105. return RT_EOK;
  106. MISC_INIT_ERROR:
  107. #ifdef RT_MISC_DEBUG
  108. rt_kprintf("Misc error: Init failed!\n");
  109. #endif
  110. return -RT_ERROR;
  111. }
  112. /**************************************************************************//**
  113. * @brief
  114. * Convert ADC result to degree celsius.
  115. *
  116. * @details
  117. *
  118. * @note
  119. * See section 2.3.4 in the reference manual for details on this calculatoin
  120. *
  121. * @param adcResult
  122. * Raw value from ADC to be converted to celsius
  123. *
  124. * @return
  125. * The temperature value (signed integer) in degrees celsius times 100
  126. *
  127. *****************************************************************************/
  128. rt_int32_t efm32_misc_getCelsius(rt_uint32_t adcResult)
  129. {
  130. /* Factory calibration temperature from device information page. */
  131. rt_int32_t cal_temp = ((DEVINFO->CAL & _DEVINFO_CAL_TEMP_MASK) \
  132. >> _DEVINFO_CAL_TEMP_SHIFT) * 100;
  133. /* Factory calibration value from device information page. */
  134. rt_int32_t cal_value = ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_TEMP1V25_MASK) \
  135. >> _DEVINFO_ADC0CAL2_TEMP1V25_SHIFT) * 10000;
  136. /* Temperature gradient (from datasheet) in (ADC unit / degree celsius * 100) */
  137. rt_int32_t t_grad = -385;
  138. return (cal_temp - (cal_value - (rt_int32_t)adcResult * 10000) / t_grad);
  139. }
  140. /*********************************************************************
  141. * Export to FINSH
  142. *********************************************************************/
  143. #ifdef RT_USING_FINSH
  144. #include <finsh.h>
  145. void list_temp(void)
  146. {
  147. rt_int32_t temp = rt_hw_get_temp();
  148. rt_kprintf("Temperature is %2d.%02d C\n", temp / 100, temp % 100);
  149. }
  150. FINSH_FUNCTION_EXPORT(list_temp, list current temperature value.)
  151. void list_vdd(void)
  152. {
  153. rt_uint32_t vdd = rt_hw_get_vdd();
  154. rt_kprintf("VDD is %1d.%02d V\n", vdd / 100, vdd % 100);
  155. }
  156. FINSH_FUNCTION_EXPORT(list_vdd, list current VDD value.)
  157. #endif
  158. /******************************************************************//**
  159. * @}
  160. *********************************************************************/