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.

MSP430F2272 will reboot itself if both i2c stop condition interrupt and interval timer interrupt are used simultaneously

Other Parts Discussed in Thread: MSP430F2272, MSP430F2619

I found that the MSP430F2272 will reboot itself if both i2c stop condition interrupt and interval timer interrupt are used simultaneously.

The source code is shown below.

The reboot issue will be resolved if I disable the i2c stop condition interrupt or reduce statements in the interval timer ISR.

What is wrong with it?

#include <msp430x22x2.h>

unsigned int g_One_Second_Counter     = 0;
unsigned int g_Quad_Second_Counter    = 0;
unsigned int g_Conut512_For_1_Second  = 0;
unsigned int g_Conut1356_For_3_Second = 0;

void main(void)
{
    /* wdt hold */
    WDTCTL = WDTPW | WDTHOLD;

    /* flash lock */
    FCTL1 = FWKEY;
    FCTL3 = FWKEY + LOCK;

    /* DCOCLK = 16MHz */
    DCOCTL  =   *(unsigned char *) CALDCO_16MHZ_; //0x10f8;
    BCSCTL1 =   *(unsigned char *) CALBC1_16MHZ_; //0x10f9;
    BCSCTL1 |= XT2OFF;

    /* MCLK = SMCLK = DCOCLK=16MHz */
    BCSCTL2 = 0x40;

    /* load 12.5 pF capacitor for 3.2768kHz xtal */
    BCSCTL3 = 0x0c;

    /* enable xtal */
    P2SEL |= 0xc0;

    /* iic slave mode config */
    UCB0CTL1 |= UCSWRST;
    UCB0CTL0 = (UCMODE_3|UCSYNC);
    UCB0I2COA = 0x0069;        //slave address = 0x69
    UCB0I2CIE |= UCSTTIE;      //enable STT ISR
    UCB0I2CIE |= UCSTPIE;      //enable STP ISR
    P3SEL |= 0x03;             //port3 SCL/SDA config
    UCB0CTL1 &= (~UCSWRST);
    IE2 |= (UCB0TXIE|UCB0RXIE); //enable tx/rx ISR

    /* interval timer config*/
    WDTCTL = WDT_ADLY_1_9;  // ACLK, 1.9ms
    IE1 |= WDTIE;

    /* enable global interrupt generation*/
    __enable_interrupt();

    while (1)
    {
        __no_operation();
    };
}

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCIB0_RX_ISR(void)
{

    if (UCB0STAT&UCSTTIFG)
    {
        UCB0STAT&=(~UCSTTIFG);
    }
    else if (UCB0STAT&UCSTPIFG)
    {
        UCB0STAT&=(~UCSTPIFG);
    }
}

#define _UCB0RXIFG_  (0x04)
#define _UCB0TXIFG_  (0x08)
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCIB0_TX_ISR(void)
{
    if (IFG2&_UCB0RXIFG_)
    {
        unsigned char Rx1Byte = UCB0RXBUF;
    }
    else if (IFG2&_UCB0TXIFG_)
    {
        UCB0TXBUF = 0xaa;
    }
}


/** Watch Dog Interval Timer ISR
*
**/
#pragma vector= WDT_VECTOR
__interrupt void WDT_Interval_Timer_ISR(void)
{
    if (g_One_Second_Counter == 0)
    {
        if (g_Conut512_For_1_Second==128 )
            g_Quad_Second_Counter++;
        if (g_Conut512_For_1_Second==256 )
            g_Quad_Second_Counter++;
        if (g_Conut512_For_1_Second==384 )
            g_Quad_Second_Counter++;
        if (g_Conut512_For_1_Second==511 )
            g_Quad_Second_Counter++;
        if (g_Quad_Second_Counter>=25)
            g_One_Second_Counter = 1;
    }
    g_Conut1356_For_3_Second++;
    if (g_Conut1356_For_3_Second>=1536 )
    {
        g_Conut1356_For_3_Second = 0 ;
    }
}

 

  • eric chung said:
    #define _UCB0RXIFG_  (0x04)

    Why that? Why don't you just use UCB0RXIFG?

    eric chung said:
        UCB0CTL0 = (UCMODE_3|UCSYNC);

    UCSYNC bit is read-only, as the UCB does not have an async mode, but it's not critical..

    eric chung said:
    MSP430F2272 will reboot itself if both i2c stop condition interrupt and interval timer interrupt are used simultaneously

    Strange, I don't see anything that could cause a reboot. The code may have some issues (e.g. certain chains of STP and STT will cause an interrupt for STP which is gone because of an STT, perhaps just in the middle of your IF construct), but it shouldn't lock the system or reboot it.

     

  •  

    I saw the cpu went to the address 0xfffe, so the Msp430f2272  would reboot itselt when it met the reset vector.

  • eric chung said:
    I saw the cpu went to the address 0xfffe

    This is usually a sign of a missing ISR (an unhandled but enabled interrupt). Unoccupied entries in the vector table hold 0xffff, so the CPU fetches this address (ignoring the LSB) and jumps to 0xfffe as the expected start address of the ISR. Where of course is no ISR, and after wrapping over to 0x0000, you'll get a memory access violation that triggers a reset.

    I wonder what you are doing with the flash controller. Leave it alone if you're not writing to flash (and you don't in your code). These lines have no effect anyway as 0/LOCK is the default state after power-up.

    I would move the declaration of Rx1Byte to the start of the ISR rather than mid-function, btu this shouldn't cause a problem too.

    The only thing left is a misconfiguration in your program settings, leading to wrong ISR addresses but then the debugger should complain about a wrong target ID.
    A possibility is a bug in the header files or the linker command file for your MSP, but then I wonder why this didn't appear earlier.

    A last-resort test would be to write ISRs (with endless loop)  for ALL possible vectors and test where the processor ends up. Well, it's a good execise in forensic debugging :)

  • In my full souce code, I saw the CPU register PC was equal to 0xFDXX  when I halt the FET debugger. Then the PC went forward step by step. The CPU would reboot itself when the PC reach 0xFFFE. It doesn't seem like a unhandled ISR case.I never saw  the CPU jump to 0xFFFE in the source code shown above, but it is the version that could cause a reboot most easily.

    To reproduce the reboot issue, a I2C master  must be connected to the MSP430f2272 I2C slave. If the I2C master is configured in fast mode (400Kbps) and accesses to the MSP430f2272 I2C slave continuously, the MSP430f2272 will reboot itself in one second.

     

  • eric chung said:
    In my full souce code, I saw the CPU register PC was equal to 0xFDXX  when I halt the FET debugger

    Very strange. This rather looks like a stack overflow or index-out-of-bounds error (when writing to an array or through a pointer), where the return address on the stack is clobbered, so the PC does not return to the proper address after a function call or interrupt.

    You said 'in my full source code'. Maybe the problem is located there, in the handling/storing of the incoming data.

  • Yes, It looks like the reboot issue is causd by stack over flow, but  both pointer and array are not uesd in my source code. The souce code shown above will also cause a reboot if the msp430f22772 is connected to a I2C Master(host).  The cput reboot itself when it return from I2C ISR.

  • I really doN't see what's causing the problem. All enabled interrupts have a proper ISR. And the code (at least what you posted of it) really isn't that complex.

    The only thing that is a bit off (but not really) is the definition of rxchar inside the if. It is allowed in C++ but not in C. Variabel sshould be declared at function start. It is possible that this confuses the optimizer in the compiler, causing code that messes up the stack. Not very likely, but  bugs happen. Even in commercial compilers :)

    The other thing I already mentioned: the if chain for STP and STT might unde rsome ciscumstances not give the desired result. It i spossible that STP is cleared by a following STT, right between the IFs. However, worst thing that could happen is that the interrupt is unhandled on the first run and the ISR is executed a second time. No showstopper.

  • Dear Eric,

    I would like to know that did you solve the reboot issue ? I have the same trouble in my project but with the UART0 and UART1 of MSP430F2619.  The UART0 was used to receive data when UART0 Rx has been interrupted, and the P2 was used to monitor button trigger event, if P2IN.BIT0=1 then UART1 send out a string.  The MCU sometimes reboots after UART1 sending out string, but not always happens every time.

    I think your answer will be my solution. 

    Sunglin.

**Attention** This is a public forum