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;
}
}