1 /*
2 * Copyright 2022-2024, NXP
3 *
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7 #include "fsl_tmu.h"
8
9 /* Component ID definition, used by tools. */
10 #ifndef FSL_COMPONENT_ID
11 #define FSL_COMPONENT_ID "platform.drivers.tmu_3"
12 #endif
13
14 /*******************************************************************************
15 * Prototypes
16 ******************************************************************************/
17 /*!
18 * @brief Get instance number for TMU module.
19 *
20 * @param base TMU peripheral base address
21 */
22 static uint32_t TMU_GetInstance(TMU_Type *base);
23
24 /*!
25 * @brief Programming the sensor translation table.
26 *
27 * @param base TMU peripheral base address.
28 */
29 static void TMU_SetTranslationTable(TMU_Type *base);
30
31 /*******************************************************************************
32 * Variables
33 ******************************************************************************/
34 /*! @brief Pointers to TMU bases for each instance. */
35 static TMU_Type *const s_tmuBases[] = TMU_BASE_PTRS;
36
37 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
38 /*! @brief Pointers to TMU clocks for each instance. */
39 static const clock_ip_name_t s_tmuClocks[] = TMU_CLOCKS;
40 #endif
41 /*******************************************************************************
42 * Code
43 ******************************************************************************/
TMU_GetInstance(TMU_Type * base)44 static uint32_t TMU_GetInstance(TMU_Type *base)
45 {
46 uint32_t instance;
47
48 /* Find the instance index from base address mappings. */
49 for (instance = 0; instance < ARRAY_SIZE(s_tmuBases); instance++)
50 {
51 if (s_tmuBases[instance] == base)
52 {
53 break;
54 }
55 }
56
57 assert(instance < ARRAY_SIZE(s_tmuBases));
58
59 return instance;
60 }
61
TMU_SetTranslationTable(TMU_Type * base)62 static void TMU_SetTranslationTable(TMU_Type *base)
63 {
64 /* programming the sensor translation table. */
65 base->TTRCR[0] = TMU_TTRCR_TEMP(218U) | TMU_TTRCR_V(1U); /* Range0. */
66 base->TTRCR[1] = TMU_TTRCR_TEMP(233U) | TMU_TTRCR_V(1U); /* Range1. */
67 base->TTRCR[2] = TMU_TTRCR_TEMP(258U) | TMU_TTRCR_V(1U); /* Range2. */
68 base->TTRCR[3] = TMU_TTRCR_TEMP(298U) | TMU_TTRCR_V(1U); /* Range3. */
69 base->TTRCR[4] = TMU_TTRCR_TEMP(358U) | TMU_TTRCR_V(1U); /* Range4. */
70 base->TTRCR[5] = TMU_TTRCR_TEMP(423U) | TMU_TTRCR_V(1U); /* Range5. */
71 base->TTRCR[6] = TMU_TTRCR_TEMP(438U) | TMU_TTRCR_V(1U); /* Range6. */
72 /* For range0. */
73 base->TTCFGR = 0x000U;
74 base->TSCFGR = 0x00EU;
75 /* For range1. */
76 base->TTCFGR = 0x001U;
77 base->TSCFGR = 0x029U;
78 /* For range2. */
79 base->TTCFGR = 0x002U;
80 base->TSCFGR = 0x056U;
81 /* For range3. */
82 base->TTCFGR = 0x003U;
83 base->TSCFGR = 0x0A2U;
84 /* For range4. */
85 base->TTCFGR = 0x004U;
86 base->TSCFGR = 0x116U;
87 /* For range5. */
88 base->TTCFGR = 0x005U;
89 base->TSCFGR = 0x195U;
90 /* For range6. */
91 base->TTCFGR = 0x006U;
92 base->TSCFGR = 0x1B2U;
93 }
94 /*!
95 * brief Enable the access to TMU registers and Initialize TMU module.
96 *
97 * param base TMU peripheral base address.
98 * param config Pointer to configuration structure. Refer to "tmu_config_t" structure.
99 */
TMU_Init(TMU_Type * base,const tmu_config_t * config)100 void TMU_Init(TMU_Type *base, const tmu_config_t *config)
101 {
102 assert(NULL != base);
103 assert(NULL != config);
104
105 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
106 /* Enable TMU clock. */
107 CLOCK_EnableClock(s_tmuClocks[TMU_GetInstance(base)]);
108 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL. */
109
110 /* Disable TMU monitor mode. */
111 TMU_Enable(base, false);
112
113 /* Set the sensor translation table. */
114 TMU_SetTranslationTable(base);
115
116 /* Clear interrupt relevant register. */
117 TMU_ClearInterruptStatusFlags(base, (uint32_t)kTMU_ImmediateTemperatureStatusFlags |
118 (uint32_t)kTMU_AverageTemperatureStatusFlags |
119 (uint32_t)kTMU_AverageTemperatureCriticalStatusFlags |
120 (uint32_t)kTMU_RisingTemperatureCriticalStatusFlags |
121 (uint32_t)kTMU_FallingTemperatureCriticalStatusFlags);
122 /* Configure TCMCFG register. */
123 base->TCMCFG |= (TMU_TCMCFG_OCM_MASK | TMU_TCMCFG_DEMA_MASK);
124 base->TCMCFG &= ~TMU_TCMCFG_CLK_DIV_MASK;
125 /* Configure TMR register. */
126 base->TMR = TMU_TMR_ALPF(config->averageLPF);
127 /* Configure TMSR register. */
128 base->TMSR |= TMU_TMSR_SITE_MASK;
129 /* Configure the time interval. */
130 base->TMTMIR = TMU_TMTMIR_TMI(config->monitorInterval);
131 }
132
133 /*!
134 * brief De-initialize TMU module and Disable the access to DCDC registers.
135 *
136 * param base TMU peripheral base address.
137 */
TMU_Deinit(TMU_Type * base)138 void TMU_Deinit(TMU_Type *base)
139 {
140 /* Disable TMU monitor mode.. */
141 TMU_Enable(base, false);
142 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
143 /* Disable TMU clock. */
144 CLOCK_DisableClock(s_tmuClocks[TMU_GetInstance(base)]);
145 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL. */
146 }
147
148 /*!
149 * brief Gets the default configuration for TMU.
150 *
151 * This function initializes the user configuration structure to default value. The default value are:
152 *
153 * Example:
154 code
155 config->monitorInterval = 0U;
156 config->monitorSiteSelection = 0U;
157 config->averageLPF = kTMU_AverageLowPassFilter1_0;
158 endcode
159 *
160 * param config Pointer to TMU configuration structure.
161 */
TMU_GetDefaultConfig(tmu_config_t * config)162 void TMU_GetDefaultConfig(tmu_config_t *config)
163 {
164 assert(NULL != config);
165
166 /* Initializes the configure structure to zero. */
167 (void)memset(config, 0, sizeof(*config));
168
169 config->monitorInterval = 0U;
170 config->monitorSiteSelection = 0U; /* If no site is selected, site 0 is monitored by default. */
171 config->averageLPF = kTMU_AverageLowPassFilter1_0;
172 }
173
174 /*!
175 * brief Get interrupt status flags.
176 *
177 * param base TMU peripheral base address.
178 * param status The pointer to interrupt status structure. Record the current interrupt status.
179 * Please refer to "tmu_interrupt_status_t" structure.
180 */
TMU_GetInterruptStatusFlags(TMU_Type * base,tmu_interrupt_status_t * status)181 void TMU_GetInterruptStatusFlags(TMU_Type *base, tmu_interrupt_status_t *status)
182 {
183 assert(NULL != status);
184
185 status->interruptDetectMask = base->TIDR;
186 status->immediateInterruptsSiteMask = (uint16_t)((TMU_TIISCR_SITE_MASK & base->TIISCR) >> TMU_TIISCR_SITE_SHIFT);
187 status->averageInterruptsSiteMask = (uint16_t)((TMU_TIASCR_SITE_MASK & base->TIASCR) >> TMU_TIASCR_SITE_SHIFT);
188 status->averageCriticalInterruptsSiteMask =
189 (uint16_t)((TMU_TICSCR_SITE_MASK & base->TICSCR) >> TMU_TICSCR_SITE_SHIFT);
190 status->risingCriticalInterruptsSiteMask =
191 (uint16_t)((TMU_TICSCR_SITE_MASK & base->TICSCR) >> TMU_TICSCR_SITE_SHIFT);
192 status->fallingCriticalInterruptsSiteMask =
193 (uint16_t)((TMU_TICSCR_SITE_MASK & base->TICSCR) >> TMU_TICSCR_SITE_SHIFT);
194 }
195
196 /*!
197 * brief Clear interrupt status flags and corresponding interrupt critical site capture register.
198 *
199 * param base TMU peripheral base address.
200 * param The mask of interrupt status flags. Refer to "_tmu_interrupt_status_flags" enumeration.
201 */
TMU_ClearInterruptStatusFlags(TMU_Type * base,uint32_t mask)202 void TMU_ClearInterruptStatusFlags(TMU_Type *base, uint32_t mask)
203 {
204 /* For immediate temperature threshold interrupt. */
205 if (0U != ((uint32_t)kTMU_ImmediateTemperatureStatusFlags & mask))
206 {
207 base->TIDR = TMU_TIDR_IHTT_MASK; /* Clear interrupt detect register. */
208 base->TIISCR &= ~TMU_TIISCR_SITE_MASK; /* Clear interrupt site capture register. */
209 }
210 /* For average temperature threshold interrupt. */
211 if (0U != ((uint32_t)kTMU_AverageTemperatureStatusFlags & mask))
212 {
213 base->TIDR = TMU_TIDR_AHTT_MASK; /* Clear interrupt detect register. */
214 base->TIASCR &= ~TMU_TIASCR_SITE_MASK; /* Clear interrupt site capture register. */
215 }
216 /* For Average temperature critical threshold interrupt. */
217 if (0U != ((uint32_t)kTMU_AverageTemperatureCriticalStatusFlags & mask))
218 {
219 base->TIDR = TMU_TIDR_AHTCT_MASK; /* Clear interrupt detect register. */
220 base->TICSCR &= ~TMU_TICSCR_SITE_MASK; /* Clear interrupt critical site capture register. */
221 }
222 /* For Rising temperature critical threshold interrupt. */
223 if (0U != ((uint32_t)kTMU_RisingTemperatureCriticalStatusFlags & mask))
224 {
225 base->TIDR = TMU_TIDR_RTRCT_MASK; /* Clear interrupt detect register. */
226 base->TICSCR &= ~TMU_TICSCR_SITE_MASK; /* Clear interrupt critical site capture register. */
227 }
228 /* For Falling temperature critical threshold interrupt. */
229 if (0U != ((uint32_t)kTMU_FallingTemperatureCriticalStatusFlags & mask))
230 {
231 base->TIDR = TMU_TIDR_FTRCT_MASK; /* Clear interrupt detect register. */
232 base->TICSCR &= ~TMU_TICSCR_SITE_MASK; /* Clear interrupt critical site capture register. */
233 }
234 }
235
236 /*!
237 * brief Get the highest temperature reached for any enabled monitored site within the temperature
238 * sensor range.
239 *
240 * param base TMU peripheral base address.
241 * param temperature Highest temperature recorded in degrees Celsius by any enabled monitored site.
242 *
243 * return Execution status.
244 * retval kStatus_Success Temperature reading is valid.
245 * retval kStatus_Fail Temperature reading is not valid due to no measured temperature within the
246 * sensor range of 0-160 °C for an enabled monitored site.
247 */
TMU_GetHighestTemperature(TMU_Type * base,uint32_t * temperature)248 status_t TMU_GetHighestTemperature(TMU_Type *base, uint32_t *temperature)
249 {
250 assert(NULL != temperature);
251
252 status_t ret = kStatus_Success;
253
254 if (0U == (TMU_TMHTCR_V_MASK & base->TMHTCR))
255 {
256 ret = kStatus_Fail;
257 }
258 else
259 {
260 *temperature = (TMU_TMHTCR_TEMP_MASK & base->TMHTCR) >> TMU_TMHTCR_TEMP_SHIFT;
261 }
262
263 return ret;
264 }
265
266 /*!
267 * brief Get the lowest temperature reached for any enabled monitored site within the temperature
268 * sensor range.
269 *
270 * param base TMU peripheral base address.
271 * param temperature Lowest temperature recorded in degrees Celsius by any enabled monitored site.
272 *
273 * return Execution status.
274 * retval kStatus_Success Temperature reading is valid.
275 * retval kStatus_Fail Temperature reading is not valid due to no measured temperature within the
276 * sensor range of 0-160 °C for an enabled monitored site.
277 */
TMU_GetLowestTemperature(TMU_Type * base,uint32_t * temperature)278 status_t TMU_GetLowestTemperature(TMU_Type *base, uint32_t *temperature)
279 {
280 assert(NULL != temperature);
281
282 status_t ret = kStatus_Success;
283
284 if (0U == (TMU_TMLTCR_V_MASK & base->TMLTCR))
285 {
286 ret = kStatus_Fail;
287 }
288 else
289 {
290 *temperature = (TMU_TMLTCR_TEMP_MASK & base->TMHTCR) >> TMU_TMLTCR_TEMP_SHIFT;
291 }
292
293 return ret;
294 }
295
296 /*!
297 * brief Get the last immediate temperature at site n. The site must be part of the list of enabled
298 * monitored sites as defined by monitorSiteSelection in "tmu_config_t" structure.
299 *
300 * param base TMU peripheral base address.
301 * param temperature Last immediate temperature reading at site 0.
302 *
303 * return Execution status.
304 * retval kStatus_Success Temperature reading is valid.
305 * retval kStatus_Fail Temperature reading is not valid because temperature out of sensor range or
306 * first measurement still pending.
307 */
TMU_GetImmediateTemperature(TMU_Type * base,float * temperature)308 status_t TMU_GetImmediateTemperature(TMU_Type *base, float *temperature)
309 {
310 assert(NULL != temperature);
311
312 status_t ret = kStatus_Success;
313
314 if (0U == (TMU_TRITSR_V_MASK & base->TRITRATSR[0].TRITSR))
315 {
316 ret = kStatus_Fail;
317 }
318 else
319 {
320 *temperature = (float)(uint32_t)((TMU_TRITSR_TEMP_MASK & base->TRITRATSR[0].TRITSR) >> TMU_TRITSR_TEMP_SHIFT);
321 if (TMU_TRITSR_TP5_MASK == (TMU_TRITSR_TP5_MASK & base->TRITRATSR[0].TRITSR))
322 {
323 *temperature += 0.50f;
324 }
325 /* To Celsius */
326 *temperature -= 273.15f;
327 }
328
329 return ret;
330 }
331
332 /*!
333 * brief Get the last average temperature at site n. The site must be part of the list of enabled
334 * monitored sites as defined by monitorSiteSelection in "tmu_config_t" structure.
335 *
336 * param base TMU peripheral base address.
337 * param temperature Last average temperature reading at site 0.
338 *
339 * return Execution status.
340 * retval kStatus_Success Temperature reading is valid.
341 * retval kStatus_Fail Temperature reading is not valid because temperature out of sensor range or
342 * first measurement still pending.
343 */
TMU_GetAverageTemperature(TMU_Type * base,uint32_t * temperature)344 status_t TMU_GetAverageTemperature(TMU_Type *base, uint32_t *temperature)
345 {
346 assert(NULL != temperature);
347
348 status_t ret = kStatus_Success;
349
350 if (0U == (TMU_TRATSR_V_MASK & base->TRITRATSR[0].TRATSR))
351 {
352 ret = kStatus_Fail;
353 }
354 else
355 {
356 *temperature = (TMU_TRATSR_TEMP_MASK & base->TRITRATSR[0].TRATSR) >> TMU_TRATSR_TEMP_SHIFT;
357 }
358
359 return ret;
360 }
361
362 /*!
363 * brief Configure the high temperature thresold value and enable/disable relevant thresold.
364 *
365 * param base TMU peripheral base address.
366 * param config Pointer to configuration structure. Refer to "tmu_thresold_config_t" structure.
367 */
TMU_SetHighTemperatureThresold(TMU_Type * base,const tmu_thresold_config_t * config)368 void TMU_SetHighTemperatureThresold(TMU_Type *base, const tmu_thresold_config_t *config)
369 {
370 assert(NULL != config);
371
372 /* Configure the high temperature immediate threshold. */
373 if (config->immediateThresoldEnable)
374 {
375 base->TMHTITR = TMU_TMHTITR_EN_MASK | TMU_TMHTITR_TEMP(config->immediateThresoldValue);
376 }
377 else
378 {
379 base->TMHTITR = 0U;
380 }
381 /* Configure the high temperature average threshold. */
382 if (config->averageThresoldEnable)
383 {
384 base->TMHTATR = TMU_TMHTATR_EN_MASK | TMU_TMHTATR_TEMP(config->averageThresoldValue);
385 }
386 else
387 {
388 base->TMHTATR = 0U;
389 }
390 /* Configure the high temperature average critical thresold. */
391 if (config->averageCriticalThresoldEnable)
392 {
393 base->TMHTACTR = TMU_TMHTACTR_EN_MASK | TMU_TMHTACTR_TEMP(config->averageCriticalThresoldValue);
394 }
395 else
396 {
397 base->TMHTACTR = 0U;
398 }
399 /* Configure the rising temperature rate critical thresold. */
400 if (config->risingCriticalThresoldEnable)
401 {
402 base->TMRTRCTR = TMU_TMRTRCTR_EN_MASK | TMU_TMRTRCTR_TEMP(config->risingfallingCriticalThresoldValue);
403 }
404 else
405 {
406 base->TMRTRCTR = 0U;
407 }
408 /* Configure the falling temperature rate critical thresold. */
409 if (config->fallingCriticalThresoldEnable)
410 {
411 base->TMFTRCTR = TMU_TMFTRCTR_EN_MASK | TMU_TMFTRCTR_TEMP(config->risingfallingCriticalThresoldValue);
412 }
413 else
414 {
415 base->TMFTRCTR = 0U;
416 }
417 }
418