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