This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430F5342: Variable corruption when WDT ISR running continuosly

Part Number: MSP430F5342

Tool/software: Code Composer Studio

Hi,

I have some code that I have modified for product enhancements.  Part of the modification was to change the WDT (in counter mode) from being called for a timed period (to wake up the processor) to running continuously and using a counter to wake up the processor. The reason for the change was to allow 2mS time counts to be used for timing purposes.

 

However, in the main section of code, I call a function to read from an external RTC (below in purple, no error returned). There are no I2C bus errors and the data in the sub-function returns the correct value. However, in the calling function one of the variables within the data structure (rtcInput.dateTime.Year) is now 0 rather than 20 - rarely other elements within the data structure are corrupted. This is a irregular occasional error and is presumed to occur when the ISR is actioned during this period.

 

If I stop the ISR (or disable ISRs before the call and re-enable after) there are no errors.

I cannot see why the WDT ISR is corrupting the data.

Thanks
Mike

bool RTC_GetDateTime(dateTime_mS *dateTimePtr)
{
    bool retval = STATUS_SUCCESS;
    volatile dateTime_mS rtcInput = {0};

    // Read Date & Time Registers
    if (!USCI_B1_I2C_Read(RTC_SLAVE_ADD, RTC_SECONDS, sizeof(dateTime_t), (uint8_t*)&rtcInput)) retval = STATUS_FAIL;

    // This line allows a break point catch the occasional date error until cause is fixed.
    if (rtcInput.dateTime.Year == 0)
        rtcInput.dateTime.Year = 0;

// other code follows…

//*********************************************************

//This is the ISR causing the corruption...
#pragma vector=WDT_VECTOR
__interrupt void WDT_A_ISR (void)
{
    if (!--timeoutWDT)
    {
        if (!contRunning) WDT_Stop();
        LPM3_EXIT;
    }
    mSeconds += WDT_INTERVAL_mS;
    if (mSeconds>999) mSeconds = 999; 

    if(contRunning)
    {
        loopTime += WDT_INTERVAL_mS;
        if (loopTime > MAIN_LOOP_TIME)
        {
            LPM3_EXIT;
            loopTime = 0;
        }
    }
}

  • My first guess is that the I2C read is running off the end of rtcInput into the caller's stack frame (the stack grows downward). Perhaps this hazard was always in there and the more frequent ISR "blips" have pushed it into the open.

    The I2C unit is a bit arcane and timing-dependent, so it's not always easy to predict the event ordering. I get by by making the anti-buffer-overrun bulletproof.

  • Hi,

    It seems that the I2C was reading a corrupt date and that was being read (school boy error in not using pointers properly to see the read value!).  Anyway, the I2C is not timing out but the wrong value is being read and returned.

    It looks like that on occasion (using a scope and toggling spare processor pins in the interrupt), the interrupt is occasionally occurring when the I2C is in progress which is causing the wrong value to be read - though the data register is the 6th register in a read series and is read from the ReceiveByteFinish function that terminates the read cycle (the other values are read using a ReadByteNext function).

    I'm surprised that there would be an error if the I2C is paused for the interrupt (which takes ~100uS to complete) as the I2C timing to controlled by the main code.

    Anyway, I have disabled interrupts while the I2C is being used and this seems to have cured the issue.

    Regards

    Mike

  • Hi Mike,

    Thanks for following up with us on this! Glad to hear things are working. 

    Mitch