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.

MSP430G2231 reset

Other Parts Discussed in Thread: MSP430G2131

Hello,

I'm using a MSP43G2231 in LPM3. I configured the timerA (on the VLO internal oscillator) to generate an interrupt to wake up the msp430 every second, do some stuff, and go back to sleep. It works fine, except that after 9 interrupts, a reset occures. This behavior is very repetitive and I don't understand the reason of this reset.

The watchdog is OFF, if I go to LPM0 instead of LPM3, the problem remains. But if I don't go to sleep at all, then it's working fine (but of course it's not a solution because I need a low consumption).

Any idea? Is there a way to know what was the reset source?

Thank you and best regards,

Simon

 

  • How did you liek the idea of posting your code?

    In your post, you basically say 'I wrote a program and it resets'. It canbe everythign and nothing. There is no known 'MSP resets after 9 wakeups from LPM' bug. So it is likely your (unknown) code.

    Simon Tinguely said:
    Is there a way to know what was the reset source?

    On 5x series, yes. On 2x series, not really. You can detect a watchdog reset by the WDTIFG bit being still set after reset, but that's all.

  • Hello,

     

    Here is my code:

     

    #include <msp430g2131.h>

    #define TXPIN 1

    void send_uart_char(char c);

    void main(void)
    {
    // watchdog
        WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

    // pin configuration
        P1DIR |= 0x01;                              // P1.0 output for led
        P1DIR |= 0x02;                                // P1.1 output for TX
        P1OUT |= 0x02;                                // high state
       
    // clocks configuration
        BCSCTL3 |= LFXT1S_2;                      // LFXT1 = VLO (very low power internal oscillator: 12khz)
        BCSCTL1 = CALBC1_1MHZ;                    // Set DCO to 1MHz
        DCOCTL = CALDCO_1MHZ;
        BCSCTL1 |= DIVA_3;                        // ACLK/8
     
        IFG1 &= ~OFIFG;                           // Clear OSCFault flag
       
       
    // start
        send_uart_char('S');


    // timer A interrupt
        TACCTL0 = CCIE;        // CCR0 interrupt enabled
        TACCR0 = 1500;
        TACTL = TASSEL_1 + MC_1;
     
        _BIS_SR(LPM3_bits + GIE);               // Enter LPM3 w/ interrupt
    }



    // Timer A0 interrupt service routine
    #pragma vector=TIMERA0_VECTOR
    __interrupt void Timer_A(void)
    {
        _BIC_SR_IRQ(LPM3_bits);                 // wake up MSP430
       
        send_uart_char('A');
       
        _BIS_SR(LPM3_bits + GIE);               // sleep: Enter LPM3 w/ interrupt
    }


    // simple debug function to send a char @4800bauds on P1S.1
    void send_uart_char(char c)
    {
        int send_char = 0xFE00;
        int i, j;
       
        send_char |= (c << 1);
       
        for(i = 0; i < 11; i++) {
            P1OUT = (P1OUT & (~(0x01 << TXPIN))) | (((send_char>>i) & 0X01) << TXPIN);
            for(j = 0; j < 14; j++);
        }     
    }

     

    When I open an hyperterminal @4800 bauds, it displays: AAAASAAAAAAAASAAAAAAAASAAAAAAAASAAAAAAAASAAAAAAAASAAAAAAAASAAAAAAAASAAAAAAAASAA

    You can see that a the code restarts periodically. Any idea about what's wrong with my code?

    Best regards,

    Simon

     

    PS: i'm using ti launch pad

  • Simon Tinguely said:
    __interrupt void Timer_A(void)
    {
        _BIC_SR_IRQ(LPM3_bits);                 // wake up MSP430
        send_uart_char('A');
        _BIS_SR(LPM3_bits + GIE);               // sleep: Enter LPM3 w/ interrupt
    }

    Uh, oh, here it comes, the stack flooder.

    What you do:
    You enter LPM in main, waiting for an interrupt.
    Inside teh Timer ISR, you clear the LPM bits in the saved status register ont eh stack (which was placed there upon entering of the ISR).
    Then you send a character. Then you enter LPM while still inside the ISR. The return address from this ISR as well as the saved status register and any register saved on stack because they are used during the ISR (this includes at least the registers used for a function call) remain on stack.
    Anothe rinterrupt comes, again status register and return address (this time to the LPM instruction in your ISR ) are stored on stack. And the registers that need to be saved for the funciton call. Again you enter LPM without pullign all thsi backl from stack. And agian an interrupt comes, saving all this on the stack for the third time. and fourth time, and....eventually the stack has filled all available ram, writinginto th evoid, which likely causes a vacant memory exception and a reset.

    Remove the BIS_SR line from inside the Timer ISR, and use the BIC_SR_IRQ only if you want the main thread to wake up and continue after you leave this ISR.

  • Hello!

    Thank you for reply and explanation!

    Best regards,

    Simon

**Attention** This is a public forum