Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:02

0001 /*
0002  * Copyright 2020-2022 NXP
0003  * All rights reserved.
0004  *
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_tempsensor.h"
0010 #include "math.h"
0011 
0012 /*******************************************************************************
0013  * Definitions
0014  ******************************************************************************/
0015 
0016 /* Component ID definition, used by tools. */
0017 #ifndef FSL_COMPONENT_ID
0018 #define FSL_COMPONENT_ID "platform.drivers.tempsensor"
0019 #endif
0020 
0021 /*******************************************************************************
0022  * Prototypes
0023  ******************************************************************************/
0024 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0025 static void TMPSNS_AIWriteAccess(uint32_t address, uint32_t data);
0026 static uint32_t TMPSNS_AIReadAccess(uint32_t address);
0027 #endif
0028 
0029 /*******************************************************************************
0030  * Variables
0031  ******************************************************************************/
0032 const static float s_Ts20   = 133.6f;
0033 const static float s_Ts21   = -5.39f;
0034 const static float s_Ts21_2 = 29.0521f; /*!< It means (s_Ts21* s_Ts21) */
0035 const static float s_Ts22   = 0.002f;
0036 static float s_Ts25c;
0037 
0038 /*******************************************************************************
0039  * Code
0040  ******************************************************************************/
0041 /*!
0042  * brief Initializes the TMPSNS module.
0043  *
0044  * param base TMPSNS base pointer
0045  * param config Pointer to configuration structure.
0046  */
0047 
0048 void TMPSNS_Init(TMPSNS_Type *base, const tmpsns_config_t *config)
0049 {
0050     assert(NULL != config);
0051     uint32_t controlVal = 0x00U;
0052     uint32_t temp;
0053 
0054     temp =
0055         (ANADIG_TEMPSENSOR_TEMPSNS_OTP_TRIM_VALUE_TEMPSNS_TEMP_VAL_MASK & ANADIG_TEMPSENSOR->TEMPSNS_OTP_TRIM_VALUE) >>
0056         10;
0057     s_Ts25c = (float)temp;
0058 
0059     /* Select normal temperature measuring mode */
0060 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0061     controlVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL0));
0062     TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL0), controlVal & (~TMPSNS_CTRL0_V_SEL_MASK));
0063 #else
0064     base->CTRL0 &= ~TMPSNS_CTRL0_V_SEL_MASK;
0065 #endif
0066 
0067     if (config->measureMode == kTEMPSENSOR_SingleMode)
0068     {
0069         controlVal = TMPSNS_CTRL1_FREQ(0x00U);
0070     }
0071     else if (config->measureMode == kTEMPSENSOR_ContinuousMode)
0072     {
0073         controlVal = TMPSNS_CTRL1_FREQ(config->frequency);
0074     }
0075     else
0076     {
0077         ; /* Intentional empty for MISRA C-2012 rule 15.7*/
0078     }
0079 
0080     /* Enable finish interrupt status */
0081     controlVal |= TMPSNS_CTRL1_FINISH_IE_MASK;
0082 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0083     /* Power up the temperature sensor */
0084     controlVal &= ~TMPSNS_CTRL1_PWD_MASK;
0085     TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), controlVal);
0086 #else
0087     base->CTRL1 |= controlVal;
0088     /* Power up the temperature sensor */
0089     base->CTRL1 &= ~TMPSNS_CTRL1_PWD_MASK;
0090 #endif
0091 
0092     /* Set alarm temperature */
0093     TMPSNS_SetTempAlarm(base, config->highAlarmTemp, kTEMPMON_HighAlarmMode);
0094     TMPSNS_SetTempAlarm(base, config->panicAlarmTemp, kTEMPMON_PanicAlarmMode);
0095     TMPSNS_SetTempAlarm(base, config->lowAlarmTemp, kTEMPMON_LowAlarmMode);
0096 }
0097 
0098 /*!
0099  * brief Deinitializes the TMPSNS module.
0100  *
0101  * param base TMPSNS base pointer
0102  */
0103 void TMPSNS_Deinit(TMPSNS_Type *base)
0104 {
0105 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0106     TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), TMPSNS_CTRL1_PWD_MASK);
0107 #else
0108     base->CTRL1 |= TMPSNS_CTRL1_PWD_MASK;
0109 #endif
0110 }
0111 
0112 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0113 /*!
0114  * brief AI interface write access.
0115  *
0116  * param base TMPSNS base pointer
0117  */
0118 static void TMPSNS_AIWriteAccess(uint32_t address, uint32_t data)
0119 {
0120     /* AI bridge setting: AIRWB and ADDR
0121        Write: 0x00
0122        Address: offset from base address
0123      */
0124     ANADIG_MISC->VDDLPSR_AI_CTRL = (0x00UL << 16) | (address & 0xFFFFU);
0125     /* Write data into related register through AI bridge */
0126     ANADIG_MISC->VDDLPSR_AI_WDATA = data;
0127     /* AI toggle */
0128     ANADIG_TEMPSENSOR->TEMPSENSOR ^= ANADIG_TEMPSENSOR_TEMPSENSOR_TEMPSNS_AI_TOGGLE_MASK;
0129 }
0130 
0131 /*!
0132  * brief AI interface read access.
0133  *
0134  * param base TMPSNS base pointer
0135  */
0136 static uint32_t TMPSNS_AIReadAccess(uint32_t address)
0137 {
0138     uint32_t ret;
0139 
0140     /* AI bridge setting: AIRWB and ADDR
0141        Read: 0x01
0142        Address: offset from base address
0143      */
0144     ANADIG_MISC->VDDLPSR_AI_CTRL = (0x01UL << 16) | (address & 0xFFFFU);
0145     /* AI toggle */
0146     ANADIG_TEMPSENSOR->TEMPSENSOR ^= ANADIG_TEMPSENSOR_TEMPSENSOR_TEMPSNS_AI_TOGGLE_MASK;
0147     /* Read data from related register through AI bridge */
0148     ret = ANADIG_MISC->VDDLPSR_AI_RDATA_TMPSNS;
0149 
0150     return ret;
0151 }
0152 #endif /* FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE */
0153 
0154 /*!
0155  * brief Gets the default configuration structure.
0156  *
0157  * This function initializes the TMPSNS configuration structure to a default value. The default
0158  * values are:
0159  *   tempmonConfig->frequency = 0x00U;
0160  *   tempmonConfig->highAlarmTemp = 25U;
0161  *   tempmonConfig->panicAlarmTemp = 80U;
0162  *   tempmonConfig->lowAlarmTemp = 20U;
0163  *
0164  * param config Pointer to a configuration structure.
0165  */
0166 void TMPSNS_GetDefaultConfig(tmpsns_config_t *config)
0167 {
0168     assert(config);
0169 
0170     /* Initializes the configure structure to zero. */
0171     (void)memset(config, 0, sizeof(*config));
0172 
0173     /* Default measurement mode */
0174     config->measureMode = kTEMPSENSOR_SingleMode;
0175     /* Default measure frequency */
0176     config->frequency = 0x00U;
0177     /* Default high alarm temperature */
0178     config->highAlarmTemp = 25;
0179     /* Default panic alarm temperature */
0180     config->panicAlarmTemp = 80;
0181     /* Default low alarm temperature */
0182     config->lowAlarmTemp = 5;
0183 }
0184 
0185 /*!
0186  * @brief start the temperature measurement process.
0187  *
0188  * @param base TMPSNS base pointer.
0189  */
0190 void TMPSNS_StartMeasure(TMPSNS_Type *base)
0191 {
0192 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0193     uint32_t controlVal;
0194     /* Read CTRL1 value*/
0195     controlVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
0196     /* Start measurement */
0197     TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), controlVal | TMPSNS_CTRL1_SET_START_MASK);
0198 #else
0199     base->CTRL1 |= TMPSNS_CTRL1_SET_START_MASK;
0200 #endif
0201 }
0202 
0203 /*!
0204  * @brief stop the measurement process.
0205  *
0206  * @param base TMPSNS base pointer
0207  */
0208 void TMPSNS_StopMeasure(TMPSNS_Type *base)
0209 {
0210 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0211     uint32_t controlVal;
0212     /* Read CTRL1 value*/
0213     controlVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
0214     /* Start measurement */
0215     TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), controlVal & (~TMPSNS_CTRL1_SET_START_MASK));
0216 #else
0217     base->CTRL1 &= ~TMPSNS_CTRL1_SET_START_MASK;
0218 #endif
0219 }
0220 
0221 /*!
0222  * brief Get current temperature with the fused temperature calibration data.
0223  *
0224  * param base TMPSNS base pointer
0225  * return current temperature with degrees Celsius.
0226  */
0227 float TMPSNS_GetCurrentTemperature(TMPSNS_Type *base)
0228 {
0229     uint32_t measureTempVal;
0230     float actualTempVal;
0231 
0232 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0233     /* Waiting for measurement finished */
0234     while (0U == (TMPSNS_AIReadAccess((uint32_t) & (base->STATUS0)) & TMPSNS_STATUS0_FINISH_MASK))
0235     {
0236     }
0237     /* Ready to read measured temperature value */
0238     measureTempVal = (TMPSNS_AIReadAccess((uint32_t) & (base->STATUS0)) & TMPSNS_STATUS0_TEMP_VAL_MASK) >>
0239                      TMPSNS_STATUS0_TEMP_VAL_SHIFT;
0240 #else
0241     /* Waiting for measurement finished */
0242     while (0U == (base->STATUS0 & TMPSNS_STATUS0_FINISH_MASK))
0243     {
0244     }
0245     /* Ready to read measured temperature value */
0246     measureTempVal = (base->STATUS0 & TMPSNS_STATUS0_TEMP_VAL_MASK) >> TMPSNS_STATUS0_TEMP_VAL_SHIFT;
0247 #endif
0248 
0249     /* Calculate actual temperature */
0250     actualTempVal =
0251         (-s_Ts21 - sqrtf(s_Ts21_2 - 4.0f * s_Ts22 * (s_Ts20 + s_Ts25c - (float)measureTempVal))) / (2.0f * s_Ts22);
0252 
0253 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0254     uint32_t statusVal;
0255     /* Read STATUS0 value */
0256     statusVal = TMPSNS_AIReadAccess((uint32_t) & (base->STATUS0));
0257     /* Clear the FINISH flag */
0258     TMPSNS_AIWriteAccess((uint32_t) & (base->STATUS0), statusVal | TMPSNS_STATUS0_FINISH_MASK);
0259 #else
0260     /* Clear the FINISH flag */
0261     base->STATUS0 |= TMPSNS_STATUS0_FINISH_MASK;
0262 #endif
0263 
0264     return actualTempVal;
0265 }
0266 
0267 /*!
0268  * brief Set the temperature count (raw sensor output) that will generate an alarm interrupt.
0269  *
0270  * param base TMPSNS base pointer
0271  * param tempVal The alarm temperature with degrees Celsius
0272  * param alarmMode The alarm mode.
0273  */
0274 void TMPSNS_SetTempAlarm(TMPSNS_Type *base, int32_t tempVal, tmpsns_alarm_mode_t alarmMode)
0275 {
0276     float temp;
0277     int32_t tempCodeVal;
0278     uint32_t tempRegVal;
0279 
0280     /* Calculate alarm temperature code value */;
0281     temp        = (-2.0f * s_Ts22 * (float)tempVal - s_Ts21) * (-2.0f * s_Ts22 * (float)tempVal - s_Ts21);
0282     temp        = (temp - (s_Ts21_2 - 4.0f * s_Ts22 * (s_Ts20 + s_Ts25c))) / (4.0f * s_Ts22);
0283     tempCodeVal = (int32_t)temp;
0284 
0285     switch (alarmMode)
0286     {
0287         case kTEMPMON_HighAlarmMode:
0288             /* Clear alarm value and set a new high alarm temperature code value */
0289 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0290             tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->RANGE0));
0291             tempRegVal = (tempRegVal & ~TMPSNS_RANGE0_HIGH_TEMP_VAL_MASK) | TMPSNS_RANGE0_HIGH_TEMP_VAL(tempCodeVal);
0292             TMPSNS_AIWriteAccess((uint32_t) & (base->RANGE0), tempRegVal);
0293 #else
0294             tempRegVal = (base->RANGE0 & ~TMPSNS_RANGE0_HIGH_TEMP_VAL_MASK) | TMPSNS_RANGE0_HIGH_TEMP_VAL(tempCodeVal);
0295             base->RANGE0 = tempRegVal;
0296 #endif
0297             /* Enable high temperature interrupt */
0298             TMPSNS_EnableInterrupt(base, kTEMPSENSOR_HighTempInterruptStatusEnable);
0299             break;
0300 
0301         case kTEMPMON_PanicAlarmMode:
0302             /* Clear panic alarm value and set a new panic alarm temperature code value */
0303 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0304             tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->RANGE1));
0305             tempRegVal = (tempRegVal & ~TMPSNS_RANGE1_PANIC_TEMP_VAL_MASK) | TMPSNS_RANGE1_PANIC_TEMP_VAL(tempCodeVal);
0306             TMPSNS_AIWriteAccess((uint32_t) & (base->RANGE1), tempRegVal);
0307 #else
0308             tempRegVal =
0309                 (base->RANGE1 & ~TMPSNS_RANGE1_PANIC_TEMP_VAL_MASK) | TMPSNS_RANGE1_PANIC_TEMP_VAL(tempCodeVal);
0310             base->RANGE1 = tempRegVal;
0311 #endif
0312             /* Enable panic temperature interrupt */
0313             TMPSNS_EnableInterrupt(base, kTEMPSENSOR_PanicTempInterruptStatusEnable);
0314             break;
0315 
0316         case kTEMPMON_LowAlarmMode:
0317             /* Clear low alarm value and set a new low alarm temperature code value */
0318 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0319             tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->RANGE0));
0320             tempRegVal = (tempRegVal & ~TMPSNS_RANGE0_LOW_TEMP_VAL_MASK) | TMPSNS_RANGE0_LOW_TEMP_VAL(tempCodeVal);
0321             TMPSNS_AIWriteAccess((uint32_t) & (base->RANGE0_SET), tempRegVal);
0322 #else
0323             tempRegVal   = (base->RANGE0 & ~TMPSNS_RANGE0_LOW_TEMP_VAL_MASK) | TMPSNS_RANGE0_LOW_TEMP_VAL(tempCodeVal);
0324             base->RANGE0 = tempRegVal;
0325 #endif
0326             /* Enable low temperature interrupt */
0327             TMPSNS_EnableInterrupt(base, kTEMPSENSOR_LowTempInterruptStatusEnable);
0328             break;
0329 
0330         default:
0331             assert(false);
0332             break;
0333     }
0334 }
0335 
0336 /*!
0337  * brief Enable interrupt status.
0338  *
0339  * param base TMPSNS base pointer
0340  * param mask The interrupts to enable from tmpsns_interrupt_status_enable_t.
0341  */
0342 void TMPSNS_EnableInterrupt(TMPSNS_Type *base, uint32_t mask)
0343 {
0344 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0345     uint32_t tempRegVal;
0346     tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
0347     TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), tempRegVal | mask);
0348 #else
0349     base->CTRL1 |= mask;
0350 #endif
0351 }
0352 
0353 /*!
0354  * brief Disable interrupt status.
0355  *
0356  * param base TMPSNS base pointer
0357  * param mask The interrupts to disable from tmpsns_interrupt_status_enable_t.
0358  */
0359 void TMPSNS_DisableInterrupt(TMPSNS_Type *base, uint32_t mask)
0360 {
0361 #if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
0362     uint32_t tempRegVal;
0363     tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
0364     TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), tempRegVal & (~mask));
0365 #else
0366     base->CTRL1 &= ~mask;
0367 #endif
0368 }