1 /*
2  * Copyright 2017-2019, 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"
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 Programming the sensor translation table.
27  *
28  * @param base TMU peripheral base address.
29  */
30 static void TMU_SetTranslationTable(TMU_Type *base);
31 
32 /*******************************************************************************
33  * Variables
34  ******************************************************************************/
35 /*! @brief Pointers to TMU bases for each instance. */
36 static TMU_Type *const s_tmuBases[] = TMU_BASE_PTRS;
37 
38 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
39 /*! @brief Pointers to TMU clocks for each instance. */
40 static const clock_ip_name_t s_tmuClocks[] = TMU_CLOCKS;
41 #endif
42 /*******************************************************************************
43  * Code
44  ******************************************************************************/
TMU_GetInstance(TMU_Type * base)45 static uint32_t TMU_GetInstance(TMU_Type *base)
46 {
47     uint32_t instance;
48 
49     /* Find the instance index from base address mappings. */
50     for (instance = 0; instance < ARRAY_SIZE(s_tmuBases); instance++)
51     {
52         if (s_tmuBases[instance] == base)
53         {
54             break;
55         }
56     }
57 
58     assert(instance < ARRAY_SIZE(s_tmuBases));
59 
60     return instance;
61 }
62 
TMU_SetTranslationTable(TMU_Type * base)63 static void TMU_SetTranslationTable(TMU_Type *base)
64 {
65     /*  programming the sensor translation table. */
66     base->TTRCR[0] = TMU_TTRCR_TEMP(0U) | TMU_TTRCR_CAL_PTS(11U);  /* Range0. */
67     base->TTRCR[1] = TMU_TTRCR_TEMP(44U) | TMU_TTRCR_CAL_PTS(9U);  /* Range1. */
68     base->TTRCR[2] = TMU_TTRCR_TEMP(78U) | TMU_TTRCR_CAL_PTS(6U);  /* Range2. */
69     base->TTRCR[3] = TMU_TTRCR_TEMP(102U) | TMU_TTRCR_CAL_PTS(3U); /* Range3. */
70     /* For range0. */
71     base->TTCFGR = 0x00000000U;
72     base->TSCFGR = 0x00000020U;
73     base->TTCFGR = 0x00000001U;
74     base->TSCFGR = 0x00000024U;
75     base->TTCFGR = 0x00000002U;
76     base->TSCFGR = 0x0000002AU;
77     base->TTCFGR = 0x00000003U;
78     base->TSCFGR = 0x00000032U;
79     base->TTCFGR = 0x00000004U;
80     base->TSCFGR = 0x00000038U;
81     base->TTCFGR = 0x00000005U;
82     base->TSCFGR = 0x0000003EU;
83     base->TTCFGR = 0x00000006U;
84     base->TSCFGR = 0x00000043U;
85     base->TTCFGR = 0x00000007U;
86     base->TSCFGR = 0x0000004AU;
87     base->TTCFGR = 0x00000008U;
88     base->TSCFGR = 0x00000050U;
89     base->TTCFGR = 0x00000009U;
90     base->TSCFGR = 0x00000059U;
91     base->TTCFGR = 0x0000000AU;
92     base->TSCFGR = 0x0000005FU;
93     base->TTCFGR = 0x0000000BU;
94     base->TSCFGR = 0x00000066U;
95     /* For range1. */
96     base->TTCFGR = 0x00010000U;
97     base->TSCFGR = 0x00000023U;
98     base->TTCFGR = 0x00010001U;
99     base->TSCFGR = 0x0000002BU;
100     base->TTCFGR = 0x00010002U;
101     base->TSCFGR = 0x00000033U;
102     base->TTCFGR = 0x00010003U;
103     base->TSCFGR = 0x0000003AU;
104     base->TTCFGR = 0x00010004U;
105     base->TSCFGR = 0x00000042U;
106     base->TTCFGR = 0x00010005U;
107     base->TSCFGR = 0x0000004AU;
108     base->TTCFGR = 0x00010006U;
109     base->TSCFGR = 0x00000054U;
110     base->TTCFGR = 0x00010007U;
111     base->TSCFGR = 0x0000005CU;
112     base->TTCFGR = 0x00010008U;
113     base->TSCFGR = 0x00000065U;
114     base->TTCFGR = 0x00010009U;
115     base->TSCFGR = 0x0000006FU;
116     /* For range2. */
117     base->TTCFGR = 0x00020000U;
118     base->TSCFGR = 0x00000029U;
119     base->TTCFGR = 0x00020001U;
120     base->TSCFGR = 0x00000033U;
121     base->TTCFGR = 0x00020002U;
122     base->TSCFGR = 0x0000003DU;
123     base->TTCFGR = 0x00020003U;
124     base->TSCFGR = 0x00000048U;
125     base->TTCFGR = 0x00020004U;
126     base->TSCFGR = 0x00000054U;
127     base->TTCFGR = 0x00020005U;
128     base->TSCFGR = 0x00000060U;
129     base->TTCFGR = 0x00020006U;
130     base->TSCFGR = 0x0000006CU;
131     /* For range3. */
132     base->TTCFGR = 0x00030000U;
133     base->TSCFGR = 0x00000025U;
134     base->TTCFGR = 0x00030001U;
135     base->TSCFGR = 0x00000033U;
136     base->TTCFGR = 0x00030002U;
137     base->TSCFGR = 0x00000043U;
138     base->TTCFGR = 0x00030003U;
139     base->TSCFGR = 0x00000055U;
140 }
141 /*!
142  * brief Enable the access to TMU registers and Initialize TMU module.
143  *
144  * param base TMU peripheral base address.
145  * param config Pointer to configuration structure. Refer to "tmu_config_t" structure.
146  */
TMU_Init(TMU_Type * base,const tmu_config_t * config)147 void TMU_Init(TMU_Type *base, const tmu_config_t *config)
148 {
149     assert(NULL != base);
150     assert(NULL != config);
151 
152 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
153     /* Enable TMU clock. */
154     CLOCK_EnableClock(s_tmuClocks[TMU_GetInstance(base)]);
155 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL. */
156 
157     /* Disable TMU monitor mode. */
158     TMU_Enable(base, false);
159 
160     /* Set the sensor translation table. */
161     TMU_SetTranslationTable(base);
162 
163     /* Clear interrupt relevant register. */
164     TMU_ClearInterruptStatusFlags(base, (uint32_t)kTMU_ImmediateTemperatureStatusFlags |
165                                             (uint32_t)kTMU_AverageTemperatureStatusFlags |
166                                             (uint32_t)kTMU_AverageTemperatureCriticalStatusFlags);
167 
168     /* Configure TMR register. */
169     base->TMR = TMU_TMR_ALPF(config->averageLPF) | TMU_TMR_MSITE(config->monitorSiteSelection);
170 
171     /* Configure the time interval. */
172     base->TMTMIR = TMU_TMTMIR_TMI(config->monitorInterval);
173 }
174 
175 /*!
176  * brief De-initialize TMU module and Disable the access to DCDC registers.
177  *
178  * param base TMU peripheral base address.
179  */
TMU_Deinit(TMU_Type * base)180 void TMU_Deinit(TMU_Type *base)
181 {
182     /* Disable TMU monitor mode.. */
183     TMU_Enable(base, false);
184 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
185     /* Disable TMU clock. */
186     CLOCK_DisableClock(s_tmuClocks[TMU_GetInstance(base)]);
187 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL. */
188 }
189 
190 /*!
191  * brief Gets the default configuration for TMU.
192  *
193  * This function initializes the user configuration structure to default value. The default value are:
194  *
195  * Example:
196    code
197    config->monitorInterval = 0U;
198    config->monitorSiteSelection = 0U;
199    config->averageLPF = kTMU_AverageLowPassFilter1_0;
200    endcode
201  *
202  * param config Pointer to TMU configuration structure.
203  */
TMU_GetDefaultConfig(tmu_config_t * config)204 void TMU_GetDefaultConfig(tmu_config_t *config)
205 {
206     assert(NULL != config);
207 
208     /* Initializes the configure structure to zero. */
209     (void)memset(config, 0, sizeof(*config));
210 
211     config->monitorInterval      = 0U;
212     config->monitorSiteSelection = 0U; /* If no site is selected, site 0 is monitored by default. */
213     config->averageLPF           = kTMU_AverageLowPassFilter1_0;
214 }
215 
216 /*!
217  * brief Get interrupt status flags.
218  *
219  * param base TMU peripheral base address.
220  * param status The pointer to interrupt status structure. Record the current interrupt status.
221  *        Please refer to "tmu_interrupt_status_t" structure.
222  */
TMU_GetInterruptStatusFlags(TMU_Type * base,tmu_interrupt_status_t * status)223 void TMU_GetInterruptStatusFlags(TMU_Type *base, tmu_interrupt_status_t *status)
224 {
225     assert(NULL != status);
226 
227     status->interruptDetectMask         = base->TIDR;
228     status->immediateInterruptsSiteMask = (uint16_t)((TMU_TISCR_ISITE_MASK & base->TISCR) >> TMU_TISCR_ISITE_SHIFT);
229     status->AverageInterruptsSiteMask   = (uint16_t)((TMU_TISCR_ASITE_MASK & base->TISCR) >> TMU_TISCR_ASITE_SHIFT);
230     status->AverageCriticalInterruptsSiteMask =
231         (uint16_t)((TMU_TICSCR_CASITE_MASK & base->TICSCR) >> TMU_TICSCR_CASITE_SHIFT);
232 }
233 
234 /*!
235  * brief Clear interrupt status flags and corresponding interrupt critical site capture register.
236  *
237  * param base TMU peripheral base address.
238  * param The mask of interrupt status flags. Refer to "_tmu_interrupt_status_flags" enumeration.
239  */
TMU_ClearInterruptStatusFlags(TMU_Type * base,uint32_t mask)240 void TMU_ClearInterruptStatusFlags(TMU_Type *base, uint32_t mask)
241 {
242     /* For immediate temperature threshold interrupt. */
243     if (0U != ((uint32_t)kTMU_ImmediateTemperatureStatusFlags & mask))
244     {
245         base->TIDR = TMU_TIDR_ITTE_MASK;      /* Clear interrupt detect register. */
246         base->TISCR &= ~TMU_TISCR_ISITE_MASK; /* Clear interrupt site capture register. */
247     }
248     /* For average temperature threshold interrupt. */
249     if (0U != ((uint32_t)kTMU_AverageTemperatureStatusFlags & mask))
250     {
251         base->TIDR = TMU_TIDR_ATTE_MASK;      /* Clear interrupt detect register. */
252         base->TISCR &= ~TMU_TISCR_ASITE_MASK; /* Clear interrupt site capture register. */
253     }
254     /* For Average temperature critical threshold interrupt. */
255     if (0U != ((uint32_t)kTMU_AverageTemperatureCriticalStatusFlags & mask))
256     {
257         base->TIDR = TMU_TIDR_ATCTE_MASK;        /* Clear interrupt detect register. */
258         base->TICSCR &= ~TMU_TICSCR_CASITE_MASK; /* Clear interrupt critical site capture register. */
259     }
260 }
261 
262 /*!
263  * brief Get the highest temperature reached for any enabled monitored site within the temperature
264  *        sensor range.
265  *
266  * param base TMU peripheral base address.
267  * param temperature Highest temperature recorded in degrees Celsius by any enabled monitored site.
268  *
269  * return Execution status.
270  * retval kStatus_Success Temperature reading is valid.
271  * retval kStatus_Fail    Temperature reading is not valid due to no measured temperature within the
272  *                         sensor range of 0-125 °C for an enabled monitored site.
273  */
TMU_GetHighestTemperature(TMU_Type * base,uint32_t * temperature)274 status_t TMU_GetHighestTemperature(TMU_Type *base, uint32_t *temperature)
275 {
276     assert(NULL != temperature);
277 
278     status_t ret = kStatus_Success;
279 
280     if (0U == (TMU_TMHTCRH_V_MASK & base->TMHTCRH))
281     {
282         ret = kStatus_Fail;
283     }
284     else
285     {
286         *temperature = (TMU_TMHTCRH_TEMP_MASK & base->TMHTCRH) >> TMU_TMHTCRH_TEMP_SHIFT;
287     }
288 
289     return ret;
290 }
291 
292 /*!
293  * brief Get the lowest temperature reached for any enabled monitored site within the temperature
294  *        sensor range.
295  *
296  * param base TMU peripheral base address.
297  * param temperature Lowest temperature recorded in degrees Celsius by any enabled monitored site.
298  *
299  * return Execution status.
300  * retval kStatus_Success Temperature reading is valid.
301  * retval kStatus_Fail    Temperature reading is not valid due to no measured temperature within the
302  *                         sensor range of 0-125 °C for an enabled monitored site.
303  */
TMU_GetLowestTemperature(TMU_Type * base,uint32_t * temperature)304 status_t TMU_GetLowestTemperature(TMU_Type *base, uint32_t *temperature)
305 {
306     assert(NULL != temperature);
307 
308     status_t ret = kStatus_Success;
309 
310     if (0U == (TMU_TMHTCRL_V_MASK & base->TMHTCRL))
311     {
312         ret = kStatus_Fail;
313     }
314     else
315     {
316         *temperature = (TMU_TMHTCRL_TEMP_MASK & base->TMHTCRL) >> TMU_TMHTCRL_TEMP_SHIFT;
317     }
318 
319     return ret;
320 }
321 
322 /*!
323  * brief Get the last immediate temperature at site n. The site must be part of the list of enabled
324  *        monitored sites as defined by monitorSiteSelection in "tmu_config_t" structure.
325  *
326  * param base TMU peripheral base address.
327  * param siteIndex The index of the site user want to read. 0U: site0 ~ 15U: site15.
328  * param temperature Last immediate temperature reading at site n .
329  *
330  * return Execution status.
331  * retval kStatus_Success Temperature reading is valid.
332  * retval kStatus_Fail    Temperature reading is not valid because temperature out of sensor range or
333  *                         first measurement still pending.
334  */
TMU_GetImmediateTemperature(TMU_Type * base,uint32_t siteIndex,uint32_t * temperature)335 status_t TMU_GetImmediateTemperature(TMU_Type *base, uint32_t siteIndex, uint32_t *temperature)
336 {
337     assert(NULL != temperature);
338     assert(siteIndex < TMU_TRITSR_COUNT);
339 
340     status_t ret = kStatus_Success;
341 
342     if (0U == (TMU_TRITSR_V_MASK & base->TRTSR[siteIndex].TRITSR))
343     {
344         ret = kStatus_Fail;
345     }
346     else
347     {
348         *temperature = (TMU_TRITSR_TEMP_MASK & base->TRTSR[siteIndex].TRITSR) >> TMU_TRITSR_TEMP_SHIFT;
349     }
350 
351     return ret;
352 }
353 
354 /*!
355  * brief Get the last average temperature at site n. The site must be part of the list of enabled
356  *        monitored sites as defined by monitorSiteSelection in "tmu_config_t" structure.
357  *
358  * param base TMU peripheral base address.
359  * param siteIndex The index of the site user want to read. 0U: site0 ~ 15U: site15.
360  * param temperature Last average temperature reading at site n .
361  *
362  * return Execution status.
363  * retval kStatus_Success Temperature reading is valid.
364  * retval kStatus_Fail    Temperature reading is not valid because temperature out of sensor range or
365  *                         first measurement still pending.
366  */
TMU_GetAverageTemperature(TMU_Type * base,uint32_t siteIndex,uint32_t * temperature)367 status_t TMU_GetAverageTemperature(TMU_Type *base, uint32_t siteIndex, uint32_t *temperature)
368 {
369     assert(NULL != temperature);
370     assert(siteIndex < TMU_TRATSR_COUNT);
371 
372     status_t ret = kStatus_Success;
373 
374     if (0U == (TMU_TRATSR_V_MASK & base->TRTSR[siteIndex].TRATSR))
375     {
376         ret = kStatus_Fail;
377     }
378     else
379     {
380         *temperature = (TMU_TRATSR_TEMP_MASK & base->TRTSR[siteIndex].TRATSR) >> TMU_TRATSR_TEMP_SHIFT;
381     }
382 
383     return ret;
384 }
385 
386 /*!
387  * brief Configure the high temperature thresold value and enable/disable relevant thresold.
388  *
389  * param base TMU peripheral base address.
390  * param config Pointer to configuration structure. Refer to "tmu_thresold_config_t" structure.
391  */
TMU_SetHighTemperatureThresold(TMU_Type * base,const tmu_thresold_config_t * config)392 void TMU_SetHighTemperatureThresold(TMU_Type *base, const tmu_thresold_config_t *config)
393 {
394     assert(NULL != config);
395 
396     /* Configure the high temperature immediate threshold. */
397     if (config->immediateThresoldEnable)
398     {
399         base->TMHTITR = TMU_TMHTITR_EN_MASK | TMU_TMHTITR_TEMP(config->immediateThresoldValue);
400     }
401     else
402     {
403         base->TMHTITR = 0U;
404     }
405     /* Configure the high temperature average threshold. */
406     if (config->AverageThresoldEnable)
407     {
408         base->TMHTATR = TMU_TMHTATR_EN_MASK | TMU_TMHTATR_TEMP(config->averageThresoldValue);
409     }
410     else
411     {
412         base->TMHTATR = 0U;
413     }
414     /* Configure the high temperature average critical thresold. */
415     if (config->AverageCriticalThresoldEnable)
416     {
417         base->TMHTACTR = TMU_TMHTACTR_EN_MASK | TMU_TMHTACTR_TEMP(config->averageCriticalThresoldValue);
418     }
419     else
420     {
421         base->TMHTACTR = 0U;
422     }
423 }
424