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.

MSP430G2955: Problem with ignition by push button when the device is always on.

Part Number: MSP430G2955

Hello everyone.

I have a problem with a batch of 150 thermo-hygrometers that we are manufacturing for a client, we are using the MSP430G2955.

The circuit is always on since it is powered by a power adapter and a lithium battery, the ignition is done by pressing a button connected to P1.1 and keeping it pressed for 6 seconds, there is a second button connected to P1.0 that depending The length of time it is pressed puts the device into setup mode.

When I load the firmware and perform the test with the debugger the device turns on correctly, when I unplug it and turn it on without the FET programmer it also turns on correctly, but after a day the device doesn't turn on, and I don't know why.

I have tried everything, using a while loop and get it out of there reading the state of P1IN, interrupts, combining interrupts and reading the pin. When using interrupts I noticed that the GIE bit went to zero for NO apparent reason, so I implemented a routine to continually check the state of the interrupt and reset it.

The last thing I tried is to restart the microcontroller every hour continuously to prevent it from becoming unresponsive over time, I do that by enabling WDT again, but even with all those settings the device remains the same, after one or two days it stops responding and it dont turn on.

At this moment I still don't know what is happening, I don't know if it influences the fact that it has neodymium magnets nearby (they are for sticking the device to refrigerators).

As the code is extensive (more than 4,000 lines) I only attach the lines referring to the ignition.The circuit has two voltage regulators, the first keeps the MSP430G2955 always on, the second turns on the rest of the circuit when enabled by the microcontroller pin P4.7. I apologize for having the code so messy and sometimes redundant, but I have made many modifications to it and still haven't debugged it properly, this is the state of the program at the moment.

void Hab_int()
{
    if (__get_SR_register() & GIE){__delay_cycles (1);}      // GIE
    else{__bis_SR_register(GIE);}
    if (P1DIR & BIT0){P1DIR &=~BIT0;}                   // pulsadores
    if (P1DIR & BIT1){P1DIR &=~BIT1;}
    if (P1SEL & BIT0){P1SEL &=~BIT0;}                  // Func Especiales
    if (P1SEL & BIT1){P1SEL &=~BIT1;}
    if (P1SEL2 & BIT0){P1SEL2 &=~BIT0;}                  // Func Especiales
    if (P1SEL2 & BIT1){P1SEL2 &=~BIT1;}
    if (P1IE & BIT1){__delay_cycles (1);}                  // hab interrupcion P1.1
    else {P1IE |= BIT1;}
    if (P1IES & BIT1){P1IES &=~BIT1;}                  // Interrupción por flanco de subida
    if (P1IFG & BIT1){P1IFG &= ~(BIT1);}                // baja flag de interrupción de P1.1


}
void confini()
{
    Hab_int();
    retardo_ver();     ////delay 2 seg
    P3DIR |=BIT7;
    P3OUT |=BIT7;   //Linea CS
    P3DIR |=BIT6;
    P3OUT |=BIT6;   //Linea RD
    P3DIR |=BIT5;
    P3OUT |=BIT5;   //Linea WR
    P3DIR |=BIT4;
    P3OUT |=BIT4;   //Linea DATA
    P1DIR |=BIT5;
    P1DIR &=~BIT4;
    P1OUT |=BIT5;   // pines de comunicacion con el ESP
    P4DIR |=BIT6;
    P4OUT |=BIT6;   // Tx Texas y Rx SIM7070
    P2DIR &=~BIT3;  //Rx Texas y Tx SIM7070
    P4DIR &=~BIT5;
    P4DIR |=BIT4;
    P4OUT |=BIT4;   //CTS entrada RTS salida
    P3DIR &=~BIT3;
    P3DIR |=BIT2;
    P3OUT |=BIT2;      //pines bluetooth
    P2SEL |=BIT2;       //canal ADC para el voltaje de la bateria
    P4DIR |=BIT3;
    P4OUT &=~BIT3;   // pin pwrkey
    P4DIR &=~BIT1;      //señal de bateria
    retardo_ver();      //1/2tiempo necesario pin pwrkey
    P4OUT |=BIT3;
    retardo_ver();
    P4OUT &=~BIT3;      //pulso en  pwrkey
    LCD_comando(2)
    ;retardo_com();     //comando LCD_off
    LCD_comando(1);
    retardo_com();     //comando Sys_en
    LCD_comando(24);
    retardo_com();     //comando RC-256K
    LCD_comando(43);
    retardo_com();     //comando Bias 1/3, 4 comunes
    LCD_comando(227);
    retardo_com();     //comando normal
    LCD_comando(3);
    retardo_com();     //comando LCD_on
    retardo_tecla();
    operativo1=0;
    operativo2=0;
    operativo3=0;
    operativo4=0;
    operativo5=0;
    operativo7=0;
    temporal1=0;
    temporal2=0;
    temporal3=0;
    temporal4=0;
    return;
}

int main(void)
{
    __delay_cycles (1000);
    WDTCTL = WDTPW | WDTHOLD;
    __delay_cycles(1000000UL);
    BCSCTL1 = CALBC1_8MHZ;
    DCOCTL = CALDCO_8MHZ;
    contreset=0;
    estado=0;
    retardo_tecla();            //espero para que se estabilice el inicio
    SDA_configsal;
    SCL_configsal;
    SCL_bajo;
    SDA_bajo;
    retardo_ver();      
    limite=LEER_Ver(0x98);      //I read the EEPROM memory address where I store if the device is on (1) or off (0)

    while (1)
    {
        Hab_int();

        while (estado==0)
        {
            P1DIR=0;
            P2DIR=0;
            P3DIR=0;
            P4DIR=0x01;    //dejo el 4.0 como salida para el pin de activacion
            P4OUT&=~BIT0;   // Turn off the device
            retardo_ver();      //doy tiempo para que se apaguen bien los modulos
            P1DIR &=~BIT0; 
            P1DIR &=~BIT1;   // pulsadores
            SDA_configsal;
            SCL_configsal;
            SCL_bajo;
            SDA_bajo;
            retardo_com();    // estado inicial I2C
            if (limite=='1')
            {
                P4OUT|=BIT0;  //Turn on the device
                confini();
                for(cont=0;cont<32;cont++)  //Clear the LCD Screen
                {
                    escribir_LCD(cont,0);tbit (30000);
                }      
                estado=10;
            }
            else{estado=5;}
        }

        while (estado==5)
        {
            retardo_med();
             Hab_int();
             contreset++;
             if (contreset==5900)
             {
                 WDTCTL = WDTPW;
                 retardo_med();     //delay 1 seg
                 contreset=0;
             }
        }

        while (estado==8)
        {
            if (P1IN & BIT1)
            {
                sostenedor=0;
                configura=0;       //Blanqueo el registro para el tiempo de encendido
                while (sostenedor<=40)
                {
                    retardo_tecla();
                    if (P1IN & BIT0){configura++;}
                    if (P1IN & BIT1){sostenedor++;}
                    else{sostenedor=100;}
                }
                if(sostenedor<99)
                {
                    P4OUT|=BIT0;  //Turn On the device
                    P1DIR &=~BIT1; 
                    P1DIR &=~BIT0;
                    confini();
                    apagador=0;
                    ESC_Ver(0x98,'1'); I write 1 in the EEPROM memory address where I store the state of the device.
                    for(cont=0;cont<32;cont++)
                    {
                    escribir_LCD(cont,0);
                    tbit (30000);
                    }      //Blanqueo la pantalla
                    if (configura==0){estado=10;}
                    else
                    {
                        if (configura<12){estado=140;}
                        else
                        {
                            if (configura<25){estado=100;}
                            else{estado=40;}
                        }
                    }
                    retardo_tecla();
                }
                else{estado=5;}
            }
            else{estado=5;}
            retardo_tecla();
        }
        
.........   more program

#pragma vector=PORT1_VECTOR
__interrupt void P1_ISR(void)
{
  char registro;
  char sostenedor;
  char contadort;
  if (P1IFG & BIT1) // comprobar fuente de la interrupción P1.1
  {
    registro=LEER_Ver(0x98); //indico en memoria que el dispositivo esta apagado
    if (registro=='1')
    {
        sostenedor=0;       //Blanqueo el registro para el tiempo de encendido
        while (sostenedor<=12)
        {
            retardo_tecla();
            P1DIR &=~BIT1;
            if (P1IN & BIT1){sostenedor++;}
            else{sostenedor=100;}
        }
        if(sostenedor<99)
        {
            ESC_Ver(0x98,'0'); //indico en memoria que el dispositivo esta apagado
            limite=LEER_Ver(0x98);      //
            estado=0;
            P4OUT&=~BIT0;       //turn off the device
            apagador=10;
            retardo_ver();
            P1DIR=0;
            P2DIR=0;
            P3DIR=0;
            P4DIR=0x01;    //dejo el 4.0 como salida para el pin de activacion
            P1DIR &=~BIT1; 
            P1DIR &=~BIT0;  // pulsadores
            P1IE |= BIT1;         // habilita la interrupción de P1.1
            P1IES &=~BIT1;        // Interrupción por flanco de subida
            P1IFG &= ~(BIT1);     // baja flag de interrupción de P1.1
        }
    }
    else
    {
        estado=8;
    }
    P1IFG &= ~BIT1; // puesta a cero del flag de interrupción P1.1
  }
  else
  {
      estado=0;
      apagador=10;
      ESC_Ver(0x98,'1'); //indico en memoria que el dispositivo esta encendido
      P4DIR|=BIT7;
      retardo_tecla();
      P4OUT |=BIT7;
      retardo_tecla();
  }
  return;
}
        

  • Hi,

    When the device is unresponsive, can you connect the FET to it to determine where it is in your code? Can you probe around your circuit to determine that the regulators are operating properly?

    What is the intended mechanism for turning the device on? 

    Can you try running your device without a neodymium magnet attached to see if that is related?

    Regards,

    Evan

  • Hi Evan

    Yes, when the device does not respond I can connect the FET, but how can I do the monitoring after disconnecting it?

    The device turns on when I connect the battery, from that moment on it always remains energized, I first connect the battery, let it charge enough, then load the program and after that it always stays on, and after one or two days it stops turning on with the button.

  • What is the voltage of the battery when the device stops working? Could it be the battery has run out of charge? Have you checked your SVS settings?

    Evan

  • Greeting

    The battery stays above 3V in the worst case. I have not done any SVS configuration, so the device must be working with the factory configuration.

  • I'm having a little trouble following all the states, but it looks like if you reach estado=5, and don't see a button push for 100 minutes, you trigger a Watchdog reset. I mention this since you mentioned that something over 1 hour of idle time was the pass/fail point.

    A Watchdog reset issues a PUC reset, which (in the F2 series) doesn't reset all the devices. You should probably audit your startup sequence to make sure you put all the peripherals in a known state even if they're already running. In most cases this can be done just by using "=" (rather than "|=") to set the peripheral registers. The ADC in particular requires a little more, but maybe you're not using that.

  • Hi Bruce

    but it looks like if you reach estado=5, and don't see a button push for 100 minutes, you trigger a Watchdog reset

    Yes, I did that only as a test to prevent the microcontroller from stopping responding after a while, but apparently there are some devices (not all) that even freeze before an hour and never turn on again.

    You should probably audit your startup sequence to make sure you put all the peripherals in a known state even if they're already running. In most cases this can be done just by using "=" (rather than "|=") to set the peripheral registers

    Ok, I'm going to do that and try.

**Attention** This is a public forum