summaryrefslogtreecommitdiffstats
path: root/bsps/arm/imxrt/mcux-sdk/drivers/tempsensor/fsl_tempsensor.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--bsps/arm/imxrt/mcux-sdk/drivers/tempsensor/fsl_tempsensor.c368
1 files changed, 368 insertions, 0 deletions
diff --git a/bsps/arm/imxrt/mcux-sdk/drivers/tempsensor/fsl_tempsensor.c b/bsps/arm/imxrt/mcux-sdk/drivers/tempsensor/fsl_tempsensor.c
new file mode 100644
index 0000000000..fa6a5cc0c4
--- /dev/null
+++ b/bsps/arm/imxrt/mcux-sdk/drivers/tempsensor/fsl_tempsensor.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright 2020-2022 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_tempsensor.h"
+#include "math.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.tempsensor"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+static void TMPSNS_AIWriteAccess(uint32_t address, uint32_t data);
+static uint32_t TMPSNS_AIReadAccess(uint32_t address);
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+const static float s_Ts20 = 133.6f;
+const static float s_Ts21 = -5.39f;
+const static float s_Ts21_2 = 29.0521f; /*!< It means (s_Ts21* s_Ts21) */
+const static float s_Ts22 = 0.002f;
+static float s_Ts25c;
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+/*!
+ * brief Initializes the TMPSNS module.
+ *
+ * param base TMPSNS base pointer
+ * param config Pointer to configuration structure.
+ */
+
+void TMPSNS_Init(TMPSNS_Type *base, const tmpsns_config_t *config)
+{
+ assert(NULL != config);
+ uint32_t controlVal = 0x00U;
+ uint32_t temp;
+
+ temp =
+ (ANADIG_TEMPSENSOR_TEMPSNS_OTP_TRIM_VALUE_TEMPSNS_TEMP_VAL_MASK & ANADIG_TEMPSENSOR->TEMPSNS_OTP_TRIM_VALUE) >>
+ 10;
+ s_Ts25c = (float)temp;
+
+ /* Select normal temperature measuring mode */
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ controlVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL0));
+ TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL0), controlVal & (~TMPSNS_CTRL0_V_SEL_MASK));
+#else
+ base->CTRL0 &= ~TMPSNS_CTRL0_V_SEL_MASK;
+#endif
+
+ if (config->measureMode == kTEMPSENSOR_SingleMode)
+ {
+ controlVal = TMPSNS_CTRL1_FREQ(0x00U);
+ }
+ else if (config->measureMode == kTEMPSENSOR_ContinuousMode)
+ {
+ controlVal = TMPSNS_CTRL1_FREQ(config->frequency);
+ }
+ else
+ {
+ ; /* Intentional empty for MISRA C-2012 rule 15.7*/
+ }
+
+ /* Enable finish interrupt status */
+ controlVal |= TMPSNS_CTRL1_FINISH_IE_MASK;
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ /* Power up the temperature sensor */
+ controlVal &= ~TMPSNS_CTRL1_PWD_MASK;
+ TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), controlVal);
+#else
+ base->CTRL1 |= controlVal;
+ /* Power up the temperature sensor */
+ base->CTRL1 &= ~TMPSNS_CTRL1_PWD_MASK;
+#endif
+
+ /* Set alarm temperature */
+ TMPSNS_SetTempAlarm(base, config->highAlarmTemp, kTEMPMON_HighAlarmMode);
+ TMPSNS_SetTempAlarm(base, config->panicAlarmTemp, kTEMPMON_PanicAlarmMode);
+ TMPSNS_SetTempAlarm(base, config->lowAlarmTemp, kTEMPMON_LowAlarmMode);
+}
+
+/*!
+ * brief Deinitializes the TMPSNS module.
+ *
+ * param base TMPSNS base pointer
+ */
+void TMPSNS_Deinit(TMPSNS_Type *base)
+{
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), TMPSNS_CTRL1_PWD_MASK);
+#else
+ base->CTRL1 |= TMPSNS_CTRL1_PWD_MASK;
+#endif
+}
+
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+/*!
+ * brief AI interface write access.
+ *
+ * param base TMPSNS base pointer
+ */
+static void TMPSNS_AIWriteAccess(uint32_t address, uint32_t data)
+{
+ /* AI bridge setting: AIRWB and ADDR
+ Write: 0x00
+ Address: offset from base address
+ */
+ ANADIG_MISC->VDDLPSR_AI_CTRL = (0x00UL << 16) | (address & 0xFFFFU);
+ /* Write data into related register through AI bridge */
+ ANADIG_MISC->VDDLPSR_AI_WDATA = data;
+ /* AI toggle */
+ ANADIG_TEMPSENSOR->TEMPSENSOR ^= ANADIG_TEMPSENSOR_TEMPSENSOR_TEMPSNS_AI_TOGGLE_MASK;
+}
+
+/*!
+ * brief AI interface read access.
+ *
+ * param base TMPSNS base pointer
+ */
+static uint32_t TMPSNS_AIReadAccess(uint32_t address)
+{
+ uint32_t ret;
+
+ /* AI bridge setting: AIRWB and ADDR
+ Read: 0x01
+ Address: offset from base address
+ */
+ ANADIG_MISC->VDDLPSR_AI_CTRL = (0x01UL << 16) | (address & 0xFFFFU);
+ /* AI toggle */
+ ANADIG_TEMPSENSOR->TEMPSENSOR ^= ANADIG_TEMPSENSOR_TEMPSENSOR_TEMPSNS_AI_TOGGLE_MASK;
+ /* Read data from related register through AI bridge */
+ ret = ANADIG_MISC->VDDLPSR_AI_RDATA_TMPSNS;
+
+ return ret;
+}
+#endif /* FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE */
+
+/*!
+ * brief Gets the default configuration structure.
+ *
+ * This function initializes the TMPSNS configuration structure to a default value. The default
+ * values are:
+ * tempmonConfig->frequency = 0x00U;
+ * tempmonConfig->highAlarmTemp = 25U;
+ * tempmonConfig->panicAlarmTemp = 80U;
+ * tempmonConfig->lowAlarmTemp = 20U;
+ *
+ * param config Pointer to a configuration structure.
+ */
+void TMPSNS_GetDefaultConfig(tmpsns_config_t *config)
+{
+ assert(config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ /* Default measurement mode */
+ config->measureMode = kTEMPSENSOR_SingleMode;
+ /* Default measure frequency */
+ config->frequency = 0x00U;
+ /* Default high alarm temperature */
+ config->highAlarmTemp = 25;
+ /* Default panic alarm temperature */
+ config->panicAlarmTemp = 80;
+ /* Default low alarm temperature */
+ config->lowAlarmTemp = 5;
+}
+
+/*!
+ * @brief start the temperature measurement process.
+ *
+ * @param base TMPSNS base pointer.
+ */
+void TMPSNS_StartMeasure(TMPSNS_Type *base)
+{
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ uint32_t controlVal;
+ /* Read CTRL1 value*/
+ controlVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
+ /* Start measurement */
+ TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), controlVal | TMPSNS_CTRL1_SET_START_MASK);
+#else
+ base->CTRL1 |= TMPSNS_CTRL1_SET_START_MASK;
+#endif
+}
+
+/*!
+ * @brief stop the measurement process.
+ *
+ * @param base TMPSNS base pointer
+ */
+void TMPSNS_StopMeasure(TMPSNS_Type *base)
+{
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ uint32_t controlVal;
+ /* Read CTRL1 value*/
+ controlVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
+ /* Start measurement */
+ TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), controlVal & (~TMPSNS_CTRL1_SET_START_MASK));
+#else
+ base->CTRL1 &= ~TMPSNS_CTRL1_SET_START_MASK;
+#endif
+}
+
+/*!
+ * brief Get current temperature with the fused temperature calibration data.
+ *
+ * param base TMPSNS base pointer
+ * return current temperature with degrees Celsius.
+ */
+float TMPSNS_GetCurrentTemperature(TMPSNS_Type *base)
+{
+ uint32_t measureTempVal;
+ float actualTempVal;
+
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ /* Waiting for measurement finished */
+ while (0U == (TMPSNS_AIReadAccess((uint32_t) & (base->STATUS0)) & TMPSNS_STATUS0_FINISH_MASK))
+ {
+ }
+ /* Ready to read measured temperature value */
+ measureTempVal = (TMPSNS_AIReadAccess((uint32_t) & (base->STATUS0)) & TMPSNS_STATUS0_TEMP_VAL_MASK) >>
+ TMPSNS_STATUS0_TEMP_VAL_SHIFT;
+#else
+ /* Waiting for measurement finished */
+ while (0U == (base->STATUS0 & TMPSNS_STATUS0_FINISH_MASK))
+ {
+ }
+ /* Ready to read measured temperature value */
+ measureTempVal = (base->STATUS0 & TMPSNS_STATUS0_TEMP_VAL_MASK) >> TMPSNS_STATUS0_TEMP_VAL_SHIFT;
+#endif
+
+ /* Calculate actual temperature */
+ actualTempVal =
+ (-s_Ts21 - sqrtf(s_Ts21_2 - 4.0f * s_Ts22 * (s_Ts20 + s_Ts25c - (float)measureTempVal))) / (2.0f * s_Ts22);
+
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ uint32_t statusVal;
+ /* Read STATUS0 value */
+ statusVal = TMPSNS_AIReadAccess((uint32_t) & (base->STATUS0));
+ /* Clear the FINISH flag */
+ TMPSNS_AIWriteAccess((uint32_t) & (base->STATUS0), statusVal | TMPSNS_STATUS0_FINISH_MASK);
+#else
+ /* Clear the FINISH flag */
+ base->STATUS0 |= TMPSNS_STATUS0_FINISH_MASK;
+#endif
+
+ return actualTempVal;
+}
+
+/*!
+ * brief Set the temperature count (raw sensor output) that will generate an alarm interrupt.
+ *
+ * param base TMPSNS base pointer
+ * param tempVal The alarm temperature with degrees Celsius
+ * param alarmMode The alarm mode.
+ */
+void TMPSNS_SetTempAlarm(TMPSNS_Type *base, int32_t tempVal, tmpsns_alarm_mode_t alarmMode)
+{
+ float temp;
+ int32_t tempCodeVal;
+ uint32_t tempRegVal;
+
+ /* Calculate alarm temperature code value */;
+ temp = (-2.0f * s_Ts22 * (float)tempVal - s_Ts21) * (-2.0f * s_Ts22 * (float)tempVal - s_Ts21);
+ temp = (temp - (s_Ts21_2 - 4.0f * s_Ts22 * (s_Ts20 + s_Ts25c))) / (4.0f * s_Ts22);
+ tempCodeVal = (int32_t)temp;
+
+ switch (alarmMode)
+ {
+ case kTEMPMON_HighAlarmMode:
+ /* Clear alarm value and set a new high alarm temperature code value */
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->RANGE0));
+ tempRegVal = (tempRegVal & ~TMPSNS_RANGE0_HIGH_TEMP_VAL_MASK) | TMPSNS_RANGE0_HIGH_TEMP_VAL(tempCodeVal);
+ TMPSNS_AIWriteAccess((uint32_t) & (base->RANGE0), tempRegVal);
+#else
+ tempRegVal = (base->RANGE0 & ~TMPSNS_RANGE0_HIGH_TEMP_VAL_MASK) | TMPSNS_RANGE0_HIGH_TEMP_VAL(tempCodeVal);
+ base->RANGE0 = tempRegVal;
+#endif
+ /* Enable high temperature interrupt */
+ TMPSNS_EnableInterrupt(base, kTEMPSENSOR_HighTempInterruptStatusEnable);
+ break;
+
+ case kTEMPMON_PanicAlarmMode:
+ /* Clear panic alarm value and set a new panic alarm temperature code value */
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->RANGE1));
+ tempRegVal = (tempRegVal & ~TMPSNS_RANGE1_PANIC_TEMP_VAL_MASK) | TMPSNS_RANGE1_PANIC_TEMP_VAL(tempCodeVal);
+ TMPSNS_AIWriteAccess((uint32_t) & (base->RANGE1), tempRegVal);
+#else
+ tempRegVal =
+ (base->RANGE1 & ~TMPSNS_RANGE1_PANIC_TEMP_VAL_MASK) | TMPSNS_RANGE1_PANIC_TEMP_VAL(tempCodeVal);
+ base->RANGE1 = tempRegVal;
+#endif
+ /* Enable panic temperature interrupt */
+ TMPSNS_EnableInterrupt(base, kTEMPSENSOR_PanicTempInterruptStatusEnable);
+ break;
+
+ case kTEMPMON_LowAlarmMode:
+ /* Clear low alarm value and set a new low alarm temperature code value */
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->RANGE0));
+ tempRegVal = (tempRegVal & ~TMPSNS_RANGE0_LOW_TEMP_VAL_MASK) | TMPSNS_RANGE0_LOW_TEMP_VAL(tempCodeVal);
+ TMPSNS_AIWriteAccess((uint32_t) & (base->RANGE0_SET), tempRegVal);
+#else
+ tempRegVal = (base->RANGE0 & ~TMPSNS_RANGE0_LOW_TEMP_VAL_MASK) | TMPSNS_RANGE0_LOW_TEMP_VAL(tempCodeVal);
+ base->RANGE0 = tempRegVal;
+#endif
+ /* Enable low temperature interrupt */
+ TMPSNS_EnableInterrupt(base, kTEMPSENSOR_LowTempInterruptStatusEnable);
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+}
+
+/*!
+ * brief Enable interrupt status.
+ *
+ * param base TMPSNS base pointer
+ * param mask The interrupts to enable from tmpsns_interrupt_status_enable_t.
+ */
+void TMPSNS_EnableInterrupt(TMPSNS_Type *base, uint32_t mask)
+{
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ uint32_t tempRegVal;
+ tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
+ TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), tempRegVal | mask);
+#else
+ base->CTRL1 |= mask;
+#endif
+}
+
+/*!
+ * brief Disable interrupt status.
+ *
+ * param base TMPSNS base pointer
+ * param mask The interrupts to disable from tmpsns_interrupt_status_enable_t.
+ */
+void TMPSNS_DisableInterrupt(TMPSNS_Type *base, uint32_t mask)
+{
+#if defined(FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE) && FSL_FEATURE_TMPSNS_HAS_AI_INTERFACE
+ uint32_t tempRegVal;
+ tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
+ TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), tempRegVal & (~mask));
+#else
+ base->CTRL1 &= ~mask;
+#endif
+}