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.

Urgent help needed! CC430F5135 - external 32kHz oscillator stopped - IO locked up with the push of a button

Other Parts Discussed in Thread: CC430F5135

Hello all,


We have been dealing with a strange problem with one of our products for weeks now. Many of our transmitters are locked up after being used for a while.

When they are locked up, the external 32kHz oscillator stops and hitting hardware reset button does not bring the devices back to work. The only way to bring the devices back to work is pulling out the batteries, wait for a while and put them back in.


We have tried many difference tests to try to isolate the problem. I think we are getting closer now. The lock-up only happens when the Cancel button on our transmitters (we have 3 buttons: Bed1, Bed2 and Cancel) is pushed. At first, I thought it could be a firmware bug, but when I switched the functionality of the Cancel button and Bed1 button around, the lock-up now happens on Bed1 instead of Cancel. In other words, the lock-up associates with a specific pin on the board (PIN 2.1). Whatever function I put on that pin, pushing the button on that pin will cause the lock-up. Just to be clear, the lock-up just happens on some of the devices and only happen after we used the button a lot of times.


Another strange problem is sometimes the transmitter is not locked up but only the LED output pin is locked up. By looking at the transmitted packets, we know the device is working normally, but somehow the LED stays on no matter what. Hitting hardware reset button and LED will still stay on, only taking out batteries would fix it. Beside looking at transmitted packets, I also looked at a debugger so I know for sure that the firmware was telling the LED pin to turn on and off and that pin just did not respond.

Has anyone experienced similar problems? Could this be a problem of the CC430F5135 itself?

Thank you! Look forward to your responses.

More details:

We are using CC430F5135 at 5.01 Mhz

PMMCOREV level 0.

void InitOsc(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
    

  UCSCTL4=0x0044; //XT1->ACLK, DCOCLKDIV->SMCLK, DCOCLKDIV->MCLK
 
  // Initialize LFXT1
  P5SEL |= 0x03;                            // Select XT1
  UCSCTL6 |= XCAP_0;                        // Internal load cap //2pF

  // Loop until XT1 fault flag is cleared
  do
  {
    UCSCTL7 &= ~XT1LFOFFG;                  // Clear XT1 fault flags
  }while (UCSCTL7&XT1LFOFFG);               // Test XT1 fault flag

  // Initialize DCO to 5.00MHz
  __bis_SR_register(SCG0);                  // Disable the FLL control loop
  UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
  UCSCTL1 = DCORSEL_3;                      // Set RSELx for DCO = 5.0 MHz //Page 45 datasheet
  UCSCTL2 = FLLD_0 + 152;                    // Set DCO Multiplier for 5.00MHz
                                            // (N + 1) * FLLRef = Fdco
                                            // (152 + 1) * 32768 = 5.01 MHz                                            
  __bic_SR_register(SCG0);                  // Enable the FLL control loop

  // Worst-case settling time for the DCO when the DCO range bits have been
  // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
  // UG for optimization.
  // 32 x 32 x 5.01 MHz / 32,768 Hz = 156250 = MCLK cycles for DCO to settle
  __delay_cycles(156563);

  // Loop until XT1,XT2 & DCO fault flag is cleared
  do
  {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
                                            // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
  }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
 
 
}




static void Setup_IO( void )
{
    
    //LED2
    P1DIR |=BIT1;
    P1OUT &=~BIT1;
    
    P1DIR |=BIT0; //LDO control
    P1OUT &=~BIT0; //LDO off by default
           
    
    PJDIR = 0xFF;    
    //PJREN=0xFF;
    PJOUT = 0x00;
          
    
    //BED1
    P2DIR &=~BIT0;
    P2REN |= ( BIT0 ); //resistors enabled
    P2IES |= ( BIT0 ); //high to low
    P2OUT |= (  BIT0 );   // enable pullups
    P2IFG &= ~( BIT0 );
    P2IE  |= (  BIT0 );
    
    //BED2
    P2DIR &=~BIT2;
    P2REN |=  BIT2; //resistors enabled    
    P2OUT |= BIT2;   // pull up
    P2IES |=  BIT2; //high to low
    P2IFG &= ~BIT2;
    P2IE  |= BIT2;
    
    //Cancel
    P2DIR &=~BIT1;
    P2REN |=  BIT1; //resistors enabled    
    P2IES |=  BIT1; //high to low
    P2OUT |= BIT1;   // pull up    
    P2IFG &= ~BIT1;
    P2IE  |= BIT1;
       
                     
    // Unused pins    
    P1DIR |= ( BIT3 | BIT4 | BIT5 | BIT6 | BIT7 );
    P1REN |= ( BIT3 | BIT4 | BIT5 | BIT6 | BIT7 );
    P1OUT |= ( BIT3 | BIT4 | BIT5 | BIT6 | BIT7 );
            
    
    P2DIR |= (  BIT3 | BIT6 | BIT4  | BIT5 | BIT7); //including 4, 5 and 7 will cause problem with ADC12
    P2REN |= (  BIT3 | BIT6 | BIT4  | BIT5 | BIT7);
    P2OUT &= ~(  BIT3 | BIT6 | BIT4  | BIT5 | BIT7);
    
    
    P3DIR =0xFF;    
    P3REN =0xFF;    
    P3OUT=0x00;
    
}

#pragma vector=PORT2_VECTOR
__interrupt void Button_Interrupt( void )
{    
    LPM3_EXIT;
 
    
    //Cancel
    if ( P2IFG & BIT1 )
    {
        if((P2IN & BIT1)==0)
        {
            Cancel_Counter=CANCEL_DELAY;           
            if(!TimerA1_Started)
            {
              TimerA1_Initialize();
              TimerA1_Started=TRUE;
            }                       
        }        
        
        P2IFG &= ~BIT1;                
    }
    
    
    //BED1
    if ( P2IFG & BIT0 )
    {
        if((P2IN & BIT0)==0)
        {
            Bed1_Counter=BUTTON_DEBOUNCE_TIME;            
            if(!TimerA1_Started)
            {
              TimerA1_Initialize();
              TimerA1_Started=TRUE;
            }                       
        }                
        P2IFG &= ~BIT0;                
    }
    
    
    //BED2
    if ( P2IFG & BIT2 )
    {
        if((P2IN & BIT2)==0)
        {
            Bed2_Counter=BUTTON_DEBOUNCE_TIME;            
            if(!TimerA1_Started)
            {
              TimerA1_Initialize();
              TimerA1_Started=TRUE;
            }                        
        }                
        P2IFG &= ~BIT2;                
    }
                  
}

  • From the posted code, the Setup_IO enables interrupts for the Cancel function on P2.6, whereas the Button_Interrupt function services interrupts for the Cancel function on P2.1.

    Since interrupts have been enabled for changes on P2.6, but are not serviced in the interrupt handler, think that a transition on P2.6 could cause the MSP430 to get locked-up in the interrupt handler. Not sure if this explains your problem.

  • Sorry!

    #pragma vector=PORT2_VECTOR
    __interrupt void Button_Interrupt( void ) was added to this post later and it came from a different version of firmware. That is why you see the inconsistency. So, the inconsistency is only on this post but not on the firmware. I am updating the post now. Sorry about that!

  • I know that in CC430, there is a more efficient way to handle I/O interrupts using PxIV (as included below). But the way I did it in the first post should not cause any problem. Is that right?

    #pragma vector=PORT2_VECTOR
    __interrupt void Port_2(void)
    {
    LPM3_EXIT;

    switch(__even_in_range(P2IV,16))
    {
    case 0: break; // No Interrupt
    case 2: // P2.0 - Bed 1
    if((P2IN & BIT0)==0)
    {
    Bed1_Counter=BUTTON_DEBOUNCE_TIME;
    if(!TimerA1_Started)
    {
    TimerA1_Initialize();
    TimerA1_Started=TRUE;
    }
    }
    break;
    case 4: // P2.1 - Cancel
    if((P2IN & BIT1)==0)
    {
    Cancel_Counter=CANCEL_DELAY;
    if(!TimerA1_Started)
    {
    TimerA1_Initialize();
    TimerA1_Started=TRUE;
    }
    }
    break;
    case 6: // P2.2 - Bed 2
    if((P2IN & BIT2)==0)
    {
    Bed2_Counter=BUTTON_DEBOUNCE_TIME;
    if(!TimerA1_Started)
    {
    TimerA1_Initialize();
    TimerA1_Started=TRUE;
    }
    }
    break;
    case 8: // P2.3

    break;
    case 10: break; // P2.4
    case 12: break; // P2.5
    case 14: break; // P2.6
    case 16: break; // P2.7
    }
    }
  • Khanh Ngo said:
    I know that in CC430, there is a more efficient way to handle I/O interrupts using PxIV (as included below). But the way I did it in the first post should not cause any problem. Is that right?

    Reading from PxIV is more efficient since it avoids the need for core to clear the bits in the PxIFG register. Given that you mentioned other problem symptoms, such as the LED output being stuck on, don't believe that this is the cause of the problems.

    The interrupt handler contains "LPM3_EXIT". Which Low Power Mode is used?

    Wondering if the problem is an errata such as "PMM11" - "MCLK comes up fast on exit from LPM3 and LPM4".

    [If the MLCK is out of spec, it may cause intermittent operation]

  • Thank you for your response.
    We are using LPM3. We looked at PMM11 before.
    Our firmware does not change anything in SVSMLCTL register. That means SVSL and SVML are enabled and running in normal mode and low-power mode of the SVSL and SVML circuits is under hardware control.
    It means we are not affected by PMM11.
    To be sure, we also performed a lot of tests:
    -Use no low power mode
    -Use LPM0
    -Use LPM1
    We experienced the same issue running under the above test conditions.
    So, LPM3 is not the cause of the problem or not the only cause of the problem.
  • Can you attach the debugger after a failure to inspect the state, e.g. see if register configurations have been corrupted?

    That might give a clue about what triggers the lock-up.
  • I tried the debugger before. I did attached the debugger to some of the failed transmitters. As I mentioned, there are 2 cases of failure: oscillator stops or just LED locked up. Most of the times when I attached the debugger to the one with stopped oscillator, the debugger could not initialize. Sometimes I was able to attached to debugger to the running process but the cursor would always stayed at the beginning of the code, it did not show the current state of the program when I pause. I did not try to read the registers though.
    On cases when LED is locked up, checking P1IN in debugger showed that P1.1 (LED)'s value did not change after toggling.
  • Could this perhaps be a hardware problem like latch-up caused by something like ESD on this user-accessible button? Does the board consume excessive current when in this failure state (perhaps use a meter to monitor current before and after failure)? It would make sense if this is the case for the issue to follow the hardware pin rather than the software, as it would probably be due to this pin/button being susceptible due to placement on the board etc, and it would also make sense for it to be on a button that goes to the outside world, as these are usually places were things are most susceptible or likely to have a possible entry point in the enclosure. You could try seeing if you can add some passives or ESD protection circuitry and see if it causes the issue to go away - there is a system-level ESD app note here that might be helpful: www.ti.com/lit/pdf/slaa530

    You may also want to do a test where you enable the crystal oscillator fault interrupt (NMI) and add an interrupt handler to deal with this fault - you could either then signal this somehow just for your testing, or have this NMI ISR try to re-initialize the crystal or take other action. I don't know if it would help in your case or not, but is usually a good practice for system robustness.

    Regards,

    Katie

  • Reading from PxIV also circumvents a problem with access to the PxIFG register - if you are clearing an IFG bit manually, while a different interrupt happens, this interrupt may be lost. Reading PxIF will clear the IFG bit while reporting it, without blocking the hardware setting any other IFG bit at the same time.
  • Thank you for your response. We have found 2 errors in hardware design. VBAT was used instead of VCC at 2 inputs. On this board, VBAT could be 0.7V higher than VCC when LDO is turned on. So this could cause pin lockup. We use 1M resistors on the 2 inputs so we probably do not have pin damage. The second error: 100 ohm series resistor was missing on "Cancel" input.
    We added oscillator fault detection in our firmware just a day before we saw this response and we are testing this firmware with the fix in the hardware for the above errors. So far no fault was detected and the transmitters are working properly.
  • Thank you for your response. We have switched to using PxIV in our recent firmware versions.
  • Hi Khanh,

    I'm so glad to hear you were able to find improvements in your design and that it seems to be working well now! I hope you have good results with the rest of your testing.

    -Katie

  • The MSP digital input pins (and IIRC even the supply pins) have internal clamp diodes to VCC and GND. These diodes can bear up to 2mA. If you keep the input voltage on a pin below VCC+0.3V (the diode forward voltage @2mA) , the current will be below 2mA (and v.v.) and not damage the pin. A series resistor of 1k will have a voltage drop of 2V@2mA. So with 1k series resistor, the damage limit for an applied voltage to the resistor is VCC+2.3V.
    For your 0.7V overvoltage, a series resistor of 270Ohm would be sufficient to prevent damage. However, any overvoltage will result in excess current consumption. And, since this current is routed to VCC through the diodes, will raise VCC. (this caused a lot of people wondering why their MSP seemed to work with no supply voltage attached) So more is better. Just be sure that the up to 50nA input leakage current doesn't pull your input signal below the threshold when the series resistor is too large.

    it should be added that plain analog inputs pins that do not have digital pin functionality (like some of the SD16/SD24 inputs with +-1V input range) do not have clamp diodes.

**Attention** This is a public forum