1 /*
2  * Copyright 2020 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #include "fsl_tmu.h"
9 
10 /* Component ID definition, used by tools. */
11 #ifndef FSL_COMPONENT_ID
12 #define FSL_COMPONENT_ID "platform.drivers.tmu_2"
13 #endif
14 
15 /*******************************************************************************
16  * Prototypes
17  ******************************************************************************/
18 /*!
19  * @brief Get instance number for TMU module.
20  *
21  * @param base TMU peripheral base address
22  */
23 static uint32_t TMU_GetInstance(TMU_Type *base);
24 
25 /*!
26  * @brief Set the high temperature threshold.
27  *
28  * @param base TMU peripheral base address.
29  * @param probe probe selection, if select both 2 probes, enable main probe path by default. Refer to
30  "tmu_probe_select_t" structure.
31  * @param thresholdConfig threshold configuration. Refer to "tmu_threshold_config_t" structure.
32  */
33 static void TMU_SetHighTemperatureThreshold(TMU_Type *base,
34                                             tmu_probe_select_t probe,
35                                             const tmu_threshold_config_t *thresholdConfig);
36 
37 /*!
38  * @brief Enable/disable the high temperature threshold.
39  *
40  * @param base TMU peripheral base address.
41  * @param probe probe selection, if select both 2 probes, enable main probe path by default. Refer to
42  "tmu_probe_select_t" structure.
43  * @param thresholdConfig threshold configuration. Refer to "tmu_threshold_config_t" structure.
44  */
45 static void TMU_EnableHighTemperatureThreshold(TMU_Type *base,
46                                                tmu_probe_select_t probe,
47                                                const tmu_threshold_config_t *thresholdConfig);
48 
49 /*******************************************************************************
50  * Variables
51  ******************************************************************************/
52 
53 /*! @brief Pointers to TMU bases for each instance. */
54 static TMU_Type *const s_tmuBases[] = TMU_BASE_PTRS;
55 
56 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
57 /*! @brief Pointers to TMU clocks for each instance. */
58 static const clock_ip_name_t s_tmuClocks[] = TMU_CLOCKS;
59 #endif
60 /*******************************************************************************
61  * Code
62  ******************************************************************************/
TMU_GetInstance(TMU_Type * base)63 static uint32_t TMU_GetInstance(TMU_Type *base)
64 {
65     uint32_t instance;
66 
67     /* Find the instance index from base address mappings. */
68     for (instance = 0; instance < ARRAY_SIZE(s_tmuBases); instance++)
69     {
70         if (s_tmuBases[instance] == base)
71         {
72             break;
73         }
74     }
75 
76     assert(instance < ARRAY_SIZE(s_tmuBases));
77 
78     return instance;
79 }
80 
TMU_Init(TMU_Type * base,const tmu_config_t * config)81 void TMU_Init(TMU_Type *base, const tmu_config_t *config)
82 {
83     assert(NULL != base);
84     assert(NULL != config);
85 
86     uint32_t ctrlReg;
87 
88 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
89     /* Enable TMU clock. */
90     CLOCK_EnableClock(s_tmuClocks[TMU_GetInstance(base)]);
91 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL. */
92 
93     /* Configure averageLPF register. */
94     ctrlReg = base->TER;
95     ctrlReg |= TMU_TER_ALPF(config->averageLPF);
96     base->TER = ctrlReg;
97 
98     /* Configure high temperature threshold. */
99     TMU_UpdateHighTemperatureThreshold(base, config->probeSelect,
100                                        (const tmu_threshold_config_t *)&config->thresholdConfig);
101 }
102 
TMU_Deinit(TMU_Type * base)103 void TMU_Deinit(TMU_Type *base)
104 {
105     /* Disable TMU monitor mode. */
106     base->TER &= ~TMU_TER_EN_MASK;
107     /* Power down. */
108     base->TER |= TMU_TER_ADC_PD_MASK;
109 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
110     /* Disable TMU clock. */
111     CLOCK_DisableClock(s_tmuClocks[TMU_GetInstance(base)]);
112 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL. */
113 }
114 
TMU_Enable(TMU_Type * base,bool enable)115 void TMU_Enable(TMU_Type *base, bool enable)
116 {
117     uint32_t ctrlReg;
118 
119     ctrlReg = base->TER;
120 
121     if (enable)
122     {
123         /* Power on. */
124         ctrlReg &= ~TMU_TER_ADC_PD_MASK;
125         /* Enable the temperature sensor. */
126         base->TER = ctrlReg | TMU_TER_EN_MASK;
127     }
128     else
129     {
130         /* Disable TMU monitor mode. */
131         ctrlReg &= ~TMU_TER_EN_MASK;
132         /* Power off. */
133         base->TER = ctrlReg | TMU_TER_ADC_PD_MASK;
134     }
135 }
136 
TMU_GetDefaultConfig(tmu_config_t * config)137 void TMU_GetDefaultConfig(tmu_config_t *config)
138 {
139     assert(NULL != config);
140 
141     config->probeSelect = kTMU_ProbeSelectMainProbe;
142     config->averageLPF  = kTMU_AverageLowPassFilter0_5;
143 
144     config->thresholdConfig.immediateThresholdEnable                   = false;
145     config->thresholdConfig.immediateThresholdValueOfMainProbe         = 0x00U;
146     config->thresholdConfig.immediateThresholdValueOfRemoteProbe       = 0x00U;
147     config->thresholdConfig.AverageThresholdEnable                     = false;
148     config->thresholdConfig.averageThresholdValueOfMainProbe           = 0x00U;
149     config->thresholdConfig.averageThresholdValueOfRemoteProbe         = 0x00U;
150     config->thresholdConfig.AverageCriticalThresholdEnable             = false;
151     config->thresholdConfig.averageCriticalThresholdValueOfMainProbe   = 0x00U;
152     config->thresholdConfig.averageCriticalThresholdValueOfRemoteProbe = 0x00U;
153 }
154 
TMU_GetImmediateTemperature(TMU_Type * base,tmu_probe_select_t probe,int8_t * temperature)155 status_t TMU_GetImmediateTemperature(TMU_Type *base, tmu_probe_select_t probe, int8_t *temperature)
156 {
157     assert(NULL != temperature);
158 
159     uint32_t temp   = 0x00U;
160     int8_t rawVal   = 0x00;
161     status_t status = kStatus_Success;
162 
163     /* If select both 2 probes, return main probe path by default. */
164     if ((kTMU_ProbeSelectMainProbe == probe) || (kTMU_ProbeSelectBothProbes == probe))
165     {
166         /* Check first measurement ready or not, this valid bit field(V0/V1) only shows temperature sensor
167            first captured actual temperature completely and relevant temperature registers can be read continuously. */
168         if (0U == (TMU_TRATSR_V0_MASK & base->TRITSR))
169         {
170             status = kStatus_Fail;
171         }
172         else
173         {
174             /* Get raw average temperature value. */
175             temp = (TMU_TRITSR_TEMP0_MASK & base->TRITSR) >> TMU_TRITSR_TEMP0_SHIFT;
176         }
177     }
178     else if (kTMU_ProbeSelectRemoteProbe == probe)
179     {
180         /* Check first measurement ready or not, this valid bit field(V0/V1) only shows temperature sensor
181            first captured actual temperature completely and relevant temperature registers can be read continuously. */
182         if (0U == (TMU_TRATSR_V1_MASK & base->TRITSR))
183         {
184             status = kStatus_Fail;
185         }
186         else
187         {
188             /* Get raw average temperature value. */
189             temp = (TMU_TRITSR_TEMP1_MASK & base->TRITSR) >> TMU_TRITSR_TEMP1_SHIFT;
190         }
191     }
192     else
193     {
194         ; /* For MISRA C-2012 rule 15.7. */
195     }
196 
197     rawVal       = (int8_t)temp;
198     *temperature = rawVal;
199     return status;
200 }
201 
TMU_GetAverageTemperature(TMU_Type * base,tmu_probe_select_t probe,int8_t * temperature)202 status_t TMU_GetAverageTemperature(TMU_Type *base, tmu_probe_select_t probe, int8_t *temperature)
203 {
204     assert(NULL != temperature);
205 
206     uint32_t temp   = 0x00U;
207     int8_t rawVal   = 0x00;
208     status_t status = kStatus_Success;
209 
210     /* If select both 2 probes, return main probe path by default. */
211     if ((kTMU_ProbeSelectMainProbe == probe) || (kTMU_ProbeSelectBothProbes == probe))
212     {
213         /* Check first measurement ready or not, this valid bit field(V0/V1) only shows temperature sensor
214            first captured actual temperature completely and relevant temperature registers can be read continuously. */
215         if (0U == (TMU_TRATSR_V0_MASK & base->TRATSR))
216         {
217             status = kStatus_Fail;
218         }
219         else
220         {
221             /* Get raw average temperature value. */
222             temp = (TMU_TRATSR_TEMP0_MASK & base->TRATSR) >> TMU_TRATSR_TEMP0_SHIFT;
223         }
224     }
225     else if (kTMU_ProbeSelectRemoteProbe == probe)
226     {
227         /* Check first measurement ready or not, this valid bit field(V0/V1) only shows temperature sensor
228            first captured actual temperature completely and relevant temperature registers can be read continuously. */
229         if (0U == (TMU_TRATSR_V1_MASK & base->TRATSR))
230         {
231             status = kStatus_Fail;
232         }
233         else
234         {
235             /* Get raw average temperature value. */
236             temp = (TMU_TRATSR_TEMP1_MASK & base->TRATSR) >> TMU_TRATSR_TEMP1_SHIFT;
237         }
238     }
239     else
240     {
241         ; /* For MISRA C-2012 rule 15.7. */
242     }
243 
244     rawVal       = (int8_t)temp;
245     *temperature = rawVal;
246     return status;
247 }
248 
TMU_SetHighTemperatureThreshold(TMU_Type * base,tmu_probe_select_t probe,const tmu_threshold_config_t * thresholdConfig)249 static void TMU_SetHighTemperatureThreshold(TMU_Type *base,
250                                             tmu_probe_select_t probe,
251                                             const tmu_threshold_config_t *thresholdConfig)
252 {
253     uint32_t tempITRegVal;
254     uint32_t tempATRegVal;
255     uint32_t tempACTRegVal;
256 
257     /* Configure the high temperature immediate threshold. */
258     if (thresholdConfig->immediateThresholdEnable)
259     {
260         if (((uint8_t)kTMU_ProbeSelectMainProbe & (uint8_t)probe) != 0U)
261         {
262             /* Disable immediate threshold.*/
263             base->TMHTITR &= ~TMU_TMHTITR_EN0_MASK;
264             /* Clear immediate threshold value and set a new immediate threshold value of probe0. */
265             tempITRegVal = base->TMHTITR;
266             tempITRegVal = (tempITRegVal & ~TMU_TMHTITR_TEMP0_MASK) |
267                            TMU_TMHTITR_TEMP0(thresholdConfig->immediateThresholdValueOfMainProbe);
268             base->TMHTITR = tempITRegVal;
269         }
270 
271         if (((uint8_t)kTMU_ProbeSelectRemoteProbe & (uint8_t)probe) != 0U)
272         {
273             /* Disable immediate threshold.*/
274             base->TMHTITR &= ~TMU_TMHTITR_EN1_MASK;
275             /* Clear immediate threshold value and set a new immediate threshold value of probe1. */
276             tempITRegVal = base->TMHTITR;
277             tempITRegVal = (tempITRegVal & ~TMU_TMHTITR_TEMP1_MASK) |
278                            TMU_TMHTITR_TEMP1(thresholdConfig->immediateThresholdValueOfRemoteProbe);
279             base->TMHTITR = tempITRegVal;
280         }
281     }
282 
283     /* Configure the high temperature average threshold. */
284     if (thresholdConfig->AverageThresholdEnable)
285     {
286         if (((uint8_t)kTMU_ProbeSelectMainProbe & (uint8_t)probe) != 0U)
287         {
288             /* Disable average threshold.*/
289             base->TMHTATR &= ~TMU_TMHTATR_EN0_MASK;
290             /* Clear average threshold value and set a new average threshold value of probe0. */
291             tempATRegVal = base->TMHTATR;
292             tempATRegVal = (tempATRegVal & ~TMU_TMHTATR_TEMP0_MASK) |
293                            TMU_TMHTATR_TEMP0(thresholdConfig->averageThresholdValueOfMainProbe);
294             base->TMHTATR = tempATRegVal;
295         }
296 
297         if (((uint8_t)kTMU_ProbeSelectRemoteProbe & (uint8_t)probe) != 0U)
298         {
299             /* Disable average threshold.*/
300             base->TMHTATR &= ~TMU_TMHTATR_EN1_MASK;
301             /* Clear average threshold value and set a new average threshold value of probe1. */
302             tempATRegVal = base->TMHTATR;
303             tempATRegVal = (tempATRegVal & ~TMU_TMHTATR_TEMP1_MASK) |
304                            TMU_TMHTATR_TEMP1(thresholdConfig->averageThresholdValueOfRemoteProbe);
305             base->TMHTATR = tempATRegVal;
306         }
307     }
308 
309     /* Configure the high temperature average critical threshold. */
310     if (thresholdConfig->AverageCriticalThresholdEnable)
311     {
312         if (((uint8_t)kTMU_ProbeSelectMainProbe & (uint8_t)probe) != 0U)
313         {
314             /* Disable average critical threshold.*/
315             base->TMHTACTR &= ~TMU_TMHTACTR_EN0_MASK;
316             /* Clear average critical threshold value and set a new average threshold value of probe0. */
317             tempACTRegVal = base->TMHTACTR;
318             tempACTRegVal = (tempACTRegVal & ~TMU_TMHTACTR_TEMP0_MASK) |
319                             TMU_TMHTACTR_TEMP0(thresholdConfig->averageCriticalThresholdValueOfMainProbe);
320             base->TMHTACTR = tempACTRegVal;
321         }
322 
323         if (((uint8_t)kTMU_ProbeSelectRemoteProbe & (uint8_t)probe) != 0U)
324         {
325             /* Disable average critical threshold.*/
326             base->TMHTACTR &= ~TMU_TMHTACTR_EN1_MASK;
327             /* Clear average critical threshold value and set a new average threshold value of probe1. */
328             tempACTRegVal = base->TMHTACTR;
329             tempACTRegVal = (tempACTRegVal & ~TMU_TMHTACTR_TEMP1_MASK) |
330                             TMU_TMHTACTR_TEMP1(thresholdConfig->averageCriticalThresholdValueOfRemoteProbe);
331             base->TMHTACTR = tempACTRegVal;
332         }
333     }
334 }
335 
TMU_EnableHighTemperatureThreshold(TMU_Type * base,tmu_probe_select_t probe,const tmu_threshold_config_t * thresholdConfig)336 static void TMU_EnableHighTemperatureThreshold(TMU_Type *base,
337                                                tmu_probe_select_t probe,
338                                                const tmu_threshold_config_t *thresholdConfig)
339 {
340     uint32_t tempITRegVal;
341     uint32_t tempATRegVal;
342     uint32_t tempACTRegVal;
343 
344     /* Configure the high temperature immediate threshold. */
345     if (thresholdConfig->immediateThresholdEnable)
346     {
347         if (((uint8_t)kTMU_ProbeSelectMainProbe & (uint8_t)probe) != 0U)
348         {
349             /* Enable threshold after configuring its value. Otherwise, TIDR interrupt status will be set immediately
350              * and dead loop into ISR. */
351             tempITRegVal = base->TMHTITR;
352             tempITRegVal |= TMU_TMHTITR_EN0_MASK;
353             base->TMHTITR = tempITRegVal;
354         }
355 
356         if (((uint8_t)kTMU_ProbeSelectRemoteProbe & (uint8_t)probe) != 0U)
357         {
358             /* Enable threshold after configuring its value. Otherwise, TIDR interrupt status will set immediately and
359              * dead loop into ISR. */
360             tempITRegVal = base->TMHTITR;
361             tempITRegVal |= TMU_TMHTITR_EN1_MASK;
362             base->TMHTITR = tempITRegVal;
363         }
364     }
365     else
366     {
367         if (((uint8_t)kTMU_ProbeSelectMainProbe & (uint8_t)probe) != 0U)
368         {
369             /* Disable immediate threshold.*/
370             base->TMHTITR &= ~TMU_TMHTITR_EN0_MASK;
371         }
372 
373         if (((uint8_t)kTMU_ProbeSelectRemoteProbe & (uint8_t)probe) != 0U)
374         {
375             /* Disable immediate threshold.*/
376             base->TMHTITR &= ~TMU_TMHTITR_EN1_MASK;
377         }
378     }
379 
380     /* Configure the high temperature average threshold. */
381     if (thresholdConfig->AverageThresholdEnable)
382     {
383         if (((uint8_t)kTMU_ProbeSelectMainProbe & (uint8_t)probe) != 0U)
384         {
385             /* Enable threshold after configuring its value. Otherwise, TIDR interrupt status will set immediately and
386              * dead loop into ISR. */
387             tempATRegVal = base->TMHTATR;
388             tempATRegVal |= TMU_TMHTATR_EN0_MASK;
389             base->TMHTATR = tempATRegVal;
390         }
391 
392         if (((uint8_t)kTMU_ProbeSelectRemoteProbe & (uint8_t)probe) != 0U)
393         {
394             /* Enable threshold after configuring its value. Otherwise, TIDR interrupt status will set immediately and
395              * dead loop into ISR. */
396             tempATRegVal = base->TMHTATR;
397             tempATRegVal |= TMU_TMHTATR_EN1_MASK;
398             base->TMHTATR = tempATRegVal;
399         }
400     }
401     else
402     {
403         if (((uint8_t)kTMU_ProbeSelectMainProbe & (uint8_t)probe) != 0U)
404         {
405             /* Disable average threshold.*/
406             base->TMHTATR &= ~TMU_TMHTATR_EN0_MASK;
407         }
408 
409         if (((uint8_t)kTMU_ProbeSelectRemoteProbe & (uint8_t)probe) != 0U)
410         {
411             /* Disable average threshold.*/
412             base->TMHTATR &= ~TMU_TMHTATR_EN1_MASK;
413         }
414     }
415 
416     /* Configure the high temperature average critical threshold. */
417     if (thresholdConfig->AverageCriticalThresholdEnable)
418     {
419         if (((uint8_t)kTMU_ProbeSelectMainProbe & (uint8_t)probe) != 0U)
420         {
421             /* Enable threshold after configuring its value. Otherwise, TIDR interrupt status will set immediately and
422              * dead loop into ISR. */
423             tempACTRegVal = base->TMHTACTR;
424             tempACTRegVal |= TMU_TMHTACTR_EN0_MASK;
425             base->TMHTACTR = tempACTRegVal;
426         }
427 
428         if (((uint8_t)kTMU_ProbeSelectRemoteProbe & (uint8_t)probe) != 0U)
429         {
430             /* Enable threshold after configuring its value. Otherwise, TIDR interrupt status will set immediately and
431              * dead loop into ISR. */
432             tempACTRegVal = base->TMHTACTR;
433             tempACTRegVal |= TMU_TMHTACTR_EN1_MASK;
434             base->TMHTACTR = tempACTRegVal;
435         }
436     }
437     else
438     {
439         if (((uint8_t)kTMU_ProbeSelectMainProbe & (uint8_t)probe) != 0U)
440         {
441             /* Disable average critical threshold.*/
442             base->TMHTACTR &= ~TMU_TMHTACTR_EN0_MASK;
443         }
444 
445         if (((uint8_t)kTMU_ProbeSelectRemoteProbe & (uint8_t)probe) != 0U)
446         {
447             /* Disable average critical threshold.*/
448             base->TMHTACTR &= ~TMU_TMHTACTR_EN1_MASK;
449         }
450     }
451 }
452 
TMU_UpdateHighTemperatureThreshold(TMU_Type * base,tmu_probe_select_t probe,const tmu_threshold_config_t * thresholdConfig)453 void TMU_UpdateHighTemperatureThreshold(TMU_Type *base,
454                                         tmu_probe_select_t probe,
455                                         const tmu_threshold_config_t *thresholdConfig)
456 {
457     /*a. disable the TMU.*/
458     TMU_Enable(base, false);
459     /* Set TMU probe select. */
460     base->TPS = TMU_TPS_PROBE_SEL((uint32_t)probe - 0x01U);
461     /*b. disable the threshold.*/
462     /*c. update the threshold value.*/
463     TMU_SetHighTemperatureThreshold(base, probe, thresholdConfig);
464     /*d. enable the TMU, waiting at least 5 us.*/
465     TMU_Enable(base, true);
466     /* Delay 5us to make sure that TMU registers' status reset completely. */
467     SDK_DelayAtLeastUs(5, SystemCoreClock);
468     /*e. enable the threshold*/
469     TMU_EnableHighTemperatureThreshold(base, probe, thresholdConfig);
470 
471     if (((uint8_t)kTMU_ProbeSelectMainProbe & (uint8_t)probe) != 0U)
472     {
473         while (((TMU_TRITSR_V0_MASK & base->TRITSR) == 0x00U) && ((TMU_TRATSR_V0_MASK & base->TRATSR) == 0x00U))
474         {
475         }
476     }
477     if (((uint8_t)kTMU_ProbeSelectRemoteProbe & (uint8_t)probe) != 0U)
478     {
479         while (((TMU_TRITSR_V1_MASK & base->TRITSR) == 0x00U) && ((TMU_TRATSR_V1_MASK & base->TRATSR) == 0x00U))
480         {
481         }
482     }
483 
484     /* Delay 1us to make sure that load captured temperature value into related registers. */
485     SDK_DelayAtLeastUs(1, SystemCoreClock);
486 }
487