311 lines
9.7 KiB
C
311 lines
9.7 KiB
C
|
/*
|
||
|
* Copyright 2020-2021 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
|
||
|
******************************************************************************/
|
||
|
static void TMPSNS_AIWriteAccess(uint32_t address, uint32_t data);
|
||
|
static uint32_t TMPSNS_AIReadAccess(uint32_t address);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* 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;
|
||
|
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;
|
||
|
|
||
|
/* Power up the temperature sensor */
|
||
|
ControlVal = TMPSNS_CTRL1_PWD(0x00U);
|
||
|
|
||
|
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;
|
||
|
|
||
|
TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), ControlVal);
|
||
|
|
||
|
/* 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)
|
||
|
{
|
||
|
TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), TMPSNS_CTRL1_PWD_MASK);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* 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;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* 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 = 20;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* @brief start the temperature measurement process.
|
||
|
*
|
||
|
* @param base TMPSNS base pointer.
|
||
|
*/
|
||
|
void TMPSNS_StartMeasure(TMPSNS_Type *base)
|
||
|
{
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* @brief stop the measurement process.
|
||
|
*
|
||
|
* @param base TMPSNS base pointer
|
||
|
*/
|
||
|
void TMPSNS_StopMeasure(TMPSNS_Type *base)
|
||
|
{
|
||
|
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));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* 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;
|
||
|
uint32_t statusVal;
|
||
|
float actualTempVal;
|
||
|
|
||
|
/* 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;
|
||
|
|
||
|
/* Calculate actual temperature */
|
||
|
actualTempVal =
|
||
|
(-s_Ts21 - sqrtf(s_Ts21_2 - 4.0f * s_Ts22 * (s_Ts20 + s_Ts25c - (float)measureTempVal))) / (2.0f * s_Ts22);
|
||
|
|
||
|
/* 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);
|
||
|
|
||
|
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 */
|
||
|
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);
|
||
|
/* 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 */
|
||
|
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);
|
||
|
/* 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 */
|
||
|
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);
|
||
|
/* 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)
|
||
|
{
|
||
|
uint32_t tempRegVal;
|
||
|
|
||
|
tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
|
||
|
TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), tempRegVal | mask);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* 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)
|
||
|
{
|
||
|
uint32_t tempRegVal;
|
||
|
|
||
|
tempRegVal = TMPSNS_AIReadAccess((uint32_t) & (base->CTRL1));
|
||
|
TMPSNS_AIWriteAccess((uint32_t) & (base->CTRL1), tempRegVal & (~mask));
|
||
|
}
|