Hello,
We're trying to deploy temperature monitor in our project that uses i.MXRT1064. We initialize TEMPMON using SDK example; everything goes well until the very first High Temp interrupt. Then the processor basically goes into interrupt spree, calling TEMP_LOW_HIGH_IRQHandler over and over again. Inspired by this post in the NXP Community we've reduced the ISR to the following, what are we missing?
void TEMP_LOW_HIGH_IRQHandler(void)
{
uint32_t const cleanS0 = TEMPMON->TEMPSENSE0 & ~TEMPMON_TEMPSENSE0_ALARM_VALUE_MASK;
uint32_t const cleanS2 = TEMPMON->TEMPSENSE2 & ~TEMPMON_TEMPSENSE2_LOW_ALARM_VALUE_MASK;
// Clear alarm values
TEMPMON->TEMPSENSE0 = cleanS0;
TEMPMON->TEMPSENSE0 = cleanS0 | TEMPMON_TEMPSENSE0_ALARM_VALUE(1U); // Low count (high temperature)
TEMPMON->TEMPSENSE2 = cleanS2;
TEMPMON->TEMPSENSE2 = cleanS2 | TEMPMON_TEMPSENSE2_LOW_ALARM_VALUE(0xFFEU); // High count (small temperature)
SDK_ISR_EXIT_BARRIER;
}
Also is our assumption that ISR will execute at the TEMPMON measure frequency incorrect? We're setting the divider/frequency value to 49152 for 32KHz RTC Clock, which should correspond to 1500ms measure rate. Yet the interrupts seem to fire faster than every 1 ms.
I am attaching a full example to this Reply:
#include "fsl_debug_console.h"
#include "fsl_tempmon.h"
#include "fsl_clock.h"
extern void BOARD_ConfigMPU(void);
extern void BOARD_InitPins(void);
extern void BOARD_BootClockRUN(void);
extern void BOARD_InitDebugConsole(void);
volatile bool isrTripped = false;
void TEMP_LOW_HIGH_IRQHandler(void)
{
isrTripped = true;
TEMPMON_SetTempAlarm(TEMPMON, 120U, kTEMPMON_HighAlarmMode); // Expand threshold to 120 deg C to stop tripping
SDK_ISR_EXIT_BARRIER;
}
int main(void)
{
uint32_t rtcClockFreq_hz;
float measFreq_hz;
float clockDividerValue;
tempmon_config_t config;
float tempDegC;
/* Board pin, clock, debug console init */
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
// Tempmon Init
rtcClockFreq_hz = CLOCK_GetFreq(kCLOCK_RtcClk);
measFreq_hz = 1 / 1.5F; // Measure every 1.5 seconds
clockDividerValue = rtcClockFreq_hz / measFreq_hz;
TEMPMON_GetDefaultConfig(&config);
config.frequency = (uint16_t)clockDividerValue; // Per UM .frequency is the RTC Clock divider
config.panicAlarmTemp = 85U;
config.highAlarmTemp = 80U;
config.lowAlarmTemp = 5U;
PRINTF("Configuring TEMPMON for %X freq, [%d, %d] deg C \r\n", config.frequency, config.lowAlarmTemp, config.highAlarmTemp);
TEMPMON_Init(TEMPMON, &config);
TEMPMON_StartMeasure(TEMPMON);
EnableIRQ(TEMP_LOW_HIGH_IRQn);
NVIC_SetPriority(TEMP_LOW_HIGH_IRQn, 31U);
// Lower the high temperature threshold to kick off the ISR
SDK_DelayAtLeastUs(3000000U, CLOCK_GetCpuClkFreq());
tempDegC = TEMPMON_GetCurrentTemperature(TEMPMON);
config.highAlarmTemp = (uint32_t)tempDegC - 1U;
PRINTF("Current temperature at %d degC, dropping thresholds to [%d, %d]\r\n", (int16_t)tempDegC, config.lowAlarmTemp, config.highAlarmTemp);
TEMPMON_SetTempAlarm(TEMPMON, config.highAlarmTemp, kTEMPMON_HighAlarmMode);
for (;;)
{
static uint32_t tripCounter = 0U;
if (isrTripped)
{
isrTripped = false;
tempDegC = TEMPMON_GetCurrentTemperature(TEMPMON);
PRINTF("{%d degC, SENSE0=%X}\r\n", (int16_t)tempDegC, TEMPMON->TEMPSENSE0);
if (++tripCounter > 2U)
{
DisableIRQ(TEMP_LOW_HIGH_IRQn);
PRINTF("Interrupt manually disabled. Re-enabling in 3s...\r\n");
tripCounter = 0U;
SDK_DelayAtLeastUs(3000000U, CLOCK_GetCpuClkFreq());
EnableIRQ(TEMP_LOW_HIGH_IRQn);
}
}
}
}
I expect interrupts to stop when threshold is expanded in line 15. However, the following anomalies are observed:
Output:
Configuring TEMPMON for C000 freq, [5, 80] deg C
Current temperature at 41 degC, dropping thresholds to [5, 40]
{40 degC, SENSE0=F004EA02}
{40 degC, SENSE0=F004EA02}
{40 degC, SENSE0=F004EA02}
Interrupt manually disabled. Re-enabling in 3s...
{40 degC, SENSE0=F004EA02}
Check this post, is talking about the same
https://community.nxp.com/t5/i-MX-RT/RT1050-Temperature-Monitor-Panic-Temperature/m-p/844404
Best Regards
@CarlosGarabito thank you for your response. I went over the post in the link that you've provided and I don't believe the two issues are related. Dev on the other end had a user error in their code (specified wrong address). I've also double checked the memory map as suggested in that post and confirmed that it is valid.
Well on SDK, we have an example, which you can use, did you try it?, you can find it, on the import SDK example and driver_examples, temperaturemonitor.