fsl_tempsensor.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * Copyright 2020-2021 NXP
  3. * All rights reserved.
  4. *
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_tempsensor.h"
  9. #include "math.h"
  10. /*******************************************************************************
  11. * Definitions
  12. ******************************************************************************/
  13. /* Component ID definition, used by tools. */
  14. #ifndef FSL_COMPONENT_ID
  15. #define FSL_COMPONENT_ID "platform.drivers.tempsensor"
  16. #endif
  17. /*******************************************************************************
  18. * Prototypes
  19. ******************************************************************************/
  20. static void TMPSNS_AIWriteAccess(uint32_t address, uint32_t data);
  21. static uint32_t TMPSNS_AIReadAccess(uint32_t address);
  22. /*******************************************************************************
  23. * Variables
  24. ******************************************************************************/
  25. const static float s_Ts20 = 133.6f;
  26. const static float s_Ts21 = -5.39f;
  27. const static float s_Ts21_2 = 29.0521f; /*!< It means (s_Ts21* s_Ts21) */
  28. const static float s_Ts22 = 0.002f;
  29. static float s_Ts25c;
  30. /*******************************************************************************
  31. * Code
  32. ******************************************************************************/
  33. /*!
  34. * brief Initializes the TMPSNS module.
  35. *
  36. * param base TMPSNS base pointer
  37. * param config Pointer to configuration structure.
  38. */
  39. void TMPSNS_Init(TMPSNS_Type *base, const tmpsns_config_t *config)
  40. {
  41. assert(NULL != config);
  42. uint32_t ControlVal;
  43. uint32_t temp;
  44. temp =
  45. (ANADIG_TEMPSENSOR_TEMPSNS_OTP_TRIM_VALUE_TEMPSNS_TEMP_VAL_MASK & ANADIG_TEMPSENSOR->TEMPSNS_OTP_TRIM_VALUE) >>
  46. 10;
  47. s_Ts25c = (float)temp;
  48. /* Power up the temperature sensor */
  49. ControlVal = TMPSNS_CTRL1_PWD(0x00U);
  50. if (config->measureMode == kTEMPSENSOR_SingleMode)
  51. {
  52. ControlVal |= TMPSNS_CTRL1_FREQ(0x00U);
  53. }
  54. else if (config->measureMode == kTEMPSENSOR_ContinuousMode)
  55. {
  56. ControlVal |= TMPSNS_CTRL1_FREQ(config->frequency);
  57. }
  58. else
  59. {
  60. ; /* Intentional empty for MISRA C-2012 rule 15.7*/
  61. }
  62. /* Enable finish interrupt status */
  63. ControlVal |= TMPSNS_CTRL1_FINISH_IE_MASK;
  64. TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), ControlVal);
  65. /* Set alarm temperature */
  66. TMPSNS_SetTempAlarm(base, config->highAlarmTemp, kTEMPMON_HighAlarmMode);
  67. TMPSNS_SetTempAlarm(base, config->panicAlarmTemp, kTEMPMON_PanicAlarmMode);
  68. TMPSNS_SetTempAlarm(base, config->lowAlarmTemp, kTEMPMON_LowAlarmMode);
  69. }
  70. /*!
  71. * brief Deinitializes the TMPSNS module.
  72. *
  73. * param base TMPSNS base pointer
  74. */
  75. void TMPSNS_Deinit(TMPSNS_Type *base)
  76. {
  77. TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), TMPSNS_CTRL1_PWD_MASK);
  78. }
  79. /*!
  80. * brief AI interface write access.
  81. *
  82. * param base TMPSNS base pointer
  83. */
  84. static void TMPSNS_AIWriteAccess(uint32_t address, uint32_t data)
  85. {
  86. /* AI bridge setting: AIRWB and ADDR
  87. Write: 0x00
  88. Address: offset from base address
  89. */
  90. ANADIG_MISC->VDDLPSR_AI_CTRL = (0x00UL << 16) | (address & 0xFFFFU);
  91. /* Write data into related register through AI bridge */
  92. ANADIG_MISC->VDDLPSR_AI_WDATA = data;
  93. /* AI toggle */
  94. ANADIG_TEMPSENSOR->TEMPSENSOR ^= ANADIG_TEMPSENSOR_TEMPSENSOR_TEMPSNS_AI_TOGGLE_MASK;
  95. }
  96. /*!
  97. * brief AI interface read access.
  98. *
  99. * param base TMPSNS base pointer
  100. */
  101. static uint32_t TMPSNS_AIReadAccess(uint32_t address)
  102. {
  103. uint32_t ret;
  104. /* AI bridge setting: AIRWB and ADDR
  105. Read: 0x01
  106. Address: offset from base address
  107. */
  108. ANADIG_MISC->VDDLPSR_AI_CTRL = (0x01UL << 16) | (address & 0xFFFFU);
  109. /* AI toggle */
  110. ANADIG_TEMPSENSOR->TEMPSENSOR ^= ANADIG_TEMPSENSOR_TEMPSENSOR_TEMPSNS_AI_TOGGLE_MASK;
  111. /* Read data from related register through AI bridge */
  112. ret = ANADIG_MISC->VDDLPSR_AI_RDATA_TMPSNS;
  113. return ret;
  114. }
  115. /*!
  116. * brief Gets the default configuration structure.
  117. *
  118. * This function initializes the TMPSNS configuration structure to a default value. The default
  119. * values are:
  120. * tempmonConfig->frequency = 0x00U;
  121. * tempmonConfig->highAlarmTemp = 25U;
  122. * tempmonConfig->panicAlarmTemp = 80U;
  123. * tempmonConfig->lowAlarmTemp = 20U;
  124. *
  125. * param config Pointer to a configuration structure.
  126. */
  127. void TMPSNS_GetDefaultConfig(tmpsns_config_t *config)
  128. {
  129. assert(config);
  130. /* Initializes the configure structure to zero. */
  131. (void)memset(config, 0, sizeof(*config));
  132. /* Default measurement mode */
  133. config->measureMode = kTEMPSENSOR_SingleMode;
  134. /* Default measure frequency */
  135. config->frequency = 0x00U;
  136. /* Default high alarm temperature */
  137. config->highAlarmTemp = 25;
  138. /* Default panic alarm temperature */
  139. config->panicAlarmTemp = 80;
  140. /* Default low alarm temperature */
  141. config->lowAlarmTemp = 20;
  142. }
  143. /*!
  144. * @brief start the temperature measurement process.
  145. *
  146. * @param base TMPSNS base pointer.
  147. */
  148. void TMPSNS_StartMeasure(TMPSNS_Type *base)
  149. {
  150. uint32_t controlVal;
  151. /* Read CTRL1 value*/
  152. controlVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
  153. /* Start measurement */
  154. TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), controlVal | TMPSNS_CTRL1_SET_START_MASK);
  155. }
  156. /*!
  157. * @brief stop the measurement process.
  158. *
  159. * @param base TMPSNS base pointer
  160. */
  161. void TMPSNS_StopMeasure(TMPSNS_Type *base)
  162. {
  163. uint32_t controlVal;
  164. /* Read CTRL1 value*/
  165. controlVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
  166. /* Start measurement */
  167. TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), controlVal & (~TMPSNS_CTRL1_SET_START_MASK));
  168. }
  169. /*!
  170. * brief Get current temperature with the fused temperature calibration data.
  171. *
  172. * param base TMPSNS base pointer
  173. * return current temperature with degrees Celsius.
  174. */
  175. float TMPSNS_GetCurrentTemperature(TMPSNS_Type *base)
  176. {
  177. uint32_t measureTempVal;
  178. uint32_t statusVal;
  179. float actualTempVal;
  180. /* Waiting for measurement finished */
  181. while (0U == (TMPSNS_AIReadAccess((uint32_t) & (base->STATUS0)) & TMPSNS_STATUS0_FINISH_MASK))
  182. {
  183. }
  184. /* Ready to read measured temperature value */
  185. measureTempVal = (TMPSNS_AIReadAccess((uint32_t) & (base->STATUS0)) & TMPSNS_STATUS0_TEMP_VAL_MASK) >>
  186. TMPSNS_STATUS0_TEMP_VAL_SHIFT;
  187. /* Calculate actual temperature */
  188. actualTempVal =
  189. (-s_Ts21 - sqrtf(s_Ts21_2 - 4.0f * s_Ts22 * (s_Ts20 + s_Ts25c - (float)measureTempVal))) / (2.0f * s_Ts22);
  190. /* Read STATUS0 value */
  191. statusVal = TMPSNS_AIReadAccess((uint32_t) & (base->STATUS0));
  192. /* Clear the FINISH flag */
  193. TMPSNS_AIWriteAccess((uint32_t) & (base->STATUS0), statusVal | TMPSNS_STATUS0_FINISH_MASK);
  194. return actualTempVal;
  195. }
  196. /*!
  197. * brief Set the temperature count (raw sensor output) that will generate an alarm interrupt.
  198. *
  199. * param base TMPSNS base pointer
  200. * param tempVal The alarm temperature with degrees Celsius
  201. * param alarmMode The alarm mode.
  202. */
  203. void TMPSNS_SetTempAlarm(TMPSNS_Type *base, int32_t tempVal, tmpsns_alarm_mode_t alarmMode)
  204. {
  205. float temp;
  206. int32_t tempCodeVal;
  207. uint32_t tempRegVal;
  208. /* Calculate alarm temperature code value */;
  209. temp = (-2.0f * s_Ts22 * (float)tempVal - s_Ts21) * (-2.0f * s_Ts22 * (float)tempVal - s_Ts21);
  210. temp = (temp - (s_Ts21_2 - 4.0f * s_Ts22 * (s_Ts20 + s_Ts25c))) / (4.0f * s_Ts22);
  211. tempCodeVal = (int32_t)temp;
  212. switch (alarmMode)
  213. {
  214. case kTEMPMON_HighAlarmMode:
  215. /* Clear alarm value and set a new high alarm temperature code value */
  216. tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->RANGE0));
  217. tempRegVal = (tempRegVal & ~TMPSNS_RANGE0_HIGH_TEMP_VAL_MASK) | TMPSNS_RANGE0_HIGH_TEMP_VAL(tempCodeVal);
  218. TMPSNS_AIWriteAccess((uint32_t) & (base->RANGE0), tempRegVal);
  219. /* Enable high temperature interrupt */
  220. TMPSNS_EnableInterrupt(base, kTEMPSENSOR_HighTempInterruptStatusEnable);
  221. break;
  222. case kTEMPMON_PanicAlarmMode:
  223. /* Clear panic alarm value and set a new panic alarm temperature code value */
  224. tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->RANGE1));
  225. tempRegVal = (tempRegVal & ~TMPSNS_RANGE1_PANIC_TEMP_VAL_MASK) | TMPSNS_RANGE1_PANIC_TEMP_VAL(tempCodeVal);
  226. TMPSNS_AIWriteAccess((uint32_t) & (base->RANGE1), tempRegVal);
  227. /* Enable panic temperature interrupt */
  228. TMPSNS_EnableInterrupt(base, kTEMPSENSOR_PanicTempInterruptStatusEnable);
  229. break;
  230. case kTEMPMON_LowAlarmMode:
  231. /* Clear low alarm value and set a new low alarm temperature code value */
  232. tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->RANGE0));
  233. tempRegVal = (tempRegVal & ~TMPSNS_RANGE0_LOW_TEMP_VAL_MASK) | TMPSNS_RANGE0_LOW_TEMP_VAL(tempCodeVal);
  234. TMPSNS_AIWriteAccess((uint32_t) & (base->RANGE0_SET), tempRegVal);
  235. /* Enable low temperature interrupt */
  236. TMPSNS_EnableInterrupt(base, kTEMPSENSOR_LowTempInterruptStatusEnable);
  237. break;
  238. default:
  239. assert(false);
  240. break;
  241. }
  242. }
  243. /*!
  244. * brief Enable interrupt status.
  245. *
  246. * param base TMPSNS base pointer
  247. * param mask The interrupts to enable from tmpsns_interrupt_status_enable_t.
  248. */
  249. void TMPSNS_EnableInterrupt(TMPSNS_Type *base, uint32_t mask)
  250. {
  251. uint32_t tempRegVal;
  252. tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
  253. TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), tempRegVal | mask);
  254. }
  255. /*!
  256. * brief Disable interrupt status.
  257. *
  258. * param base TMPSNS base pointer
  259. * param mask The interrupts to disable from tmpsns_interrupt_status_enable_t.
  260. */
  261. void TMPSNS_DisableInterrupt(TMPSNS_Type *base, uint32_t mask)
  262. {
  263. uint32_t tempRegVal;
  264. tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
  265. TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), tempRegVal & (~mask));
  266. }