dev_misc.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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. #ifdef RT_MISC_DEBUG
  103. rt_kprintf("Batt err: Can't find device: %s!\n", RT_ADC0_NAME);
  104. #endif
  105. goto MISC_INIT_ERROR;
  106. }
  107. return RT_EOK;
  108. MISC_INIT_ERROR:
  109. #ifdef RT_MISC_DEBUG
  110. rt_kprintf("Misc err: Init failed!\n");
  111. #endif
  112. return -RT_ERROR;
  113. }
  114. /**************************************************************************//**
  115. * @brief
  116. * Convert ADC result to degree celsius.
  117. *
  118. * @details
  119. *
  120. * @note
  121. * See section 2.3.4 in the reference manual for details on this calculatoin
  122. *
  123. * @param adcResult
  124. * Raw value from ADC to be converted to celsius
  125. *
  126. * @return
  127. * The temperature value (signed integer) in degrees celsius times 100
  128. *
  129. *****************************************************************************/
  130. rt_int32_t efm32_misc_getCelsius(rt_uint32_t adcResult)
  131. {
  132. /* Factory calibration temperature from device information page. */
  133. rt_int32_t cal_temp = ((DEVINFO->CAL & _DEVINFO_CAL_TEMP_MASK) \
  134. >> _DEVINFO_CAL_TEMP_SHIFT) * 100;
  135. /* Factory calibration value from device information page. */
  136. rt_int32_t cal_value = ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_TEMP1V25_MASK) \
  137. >> _DEVINFO_ADC0CAL2_TEMP1V25_SHIFT) * 10000;
  138. /* Temperature gradient (from datasheet) in (ADC unit / degree celsius * 100) */
  139. rt_int32_t t_grad = -385;
  140. return (cal_temp - (cal_value - (rt_int32_t)adcResult * 10000) / t_grad);
  141. }
  142. /*********************************************************************
  143. * Export to FINSH
  144. *********************************************************************/
  145. #ifdef RT_USING_FINSH
  146. #include <finsh.h>
  147. void list_temp(void)
  148. {
  149. rt_int32_t temp = rt_hw_get_temp();
  150. rt_kprintf("Temperature is %2d.%02d C\n", temp / 100, temp % 100);
  151. }
  152. FINSH_FUNCTION_EXPORT(list_temp, list current temperature value.)
  153. void list_vdd(void)
  154. {
  155. rt_uint32_t vdd = rt_hw_get_vdd();
  156. rt_kprintf("VDD is %1d.%02d V\n", vdd / 100, vdd % 100);
  157. }
  158. FINSH_FUNCTION_EXPORT(list_vdd, list current VDD value.)
  159. #endif
  160. /******************************************************************//**
  161. * @}
  162. *********************************************************************/