TEMPMON drowns i.MXRT1064 in interrupts

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

TEMPMON drowns i.MXRT1064 in interrupts

692 Views
StanAk
Contributor I

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.

0 Kudos
Reply
4 Replies

647 Views
StanAk
Contributor I

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:

  • Interrupts keep coming
  • Interrupts are triggering at a (much) faster rate than 1.5 seconds
  • When interrupts are manually disabled and then re-enabled later they get triggered again despite conditions not met

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}

0 Kudos
Reply

664 Views
CarlosGarabito
NXP TechSupport
NXP TechSupport
0 Kudos
Reply

652 Views
StanAk
Contributor I

@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.

0 Kudos
Reply

628 Views
CarlosGarabito
NXP TechSupport
NXP TechSupport

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.

0 Kudos
Reply