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.
Hello everybody,
I am using a CC430F5137 for a wireless sensor.
I interface the CC430 with a Honeywell magnetometer (HMC5883L) using an I2C bus. The magnetometer is read every 2 seconds using I2C bus. The system is located on the ground into a plastic case and works fine for weeks but randomly gets stuck and stops accessing to the magnetometer via I2C.
After many attempts I managed to understand that the system is quite sensitive to moisture because, as soon as it is exposed to a source of humidity suddenly the CC430 gets stuck into the I2C interrupt subroutine.
Particularly the CC430 enters the USCI_B0 interrupt subroutine and gets stuck on the instruction at line 10:
#pragma vector = USCI_B0_VECTOR __interrupt void USCI_B0_ISR(void) { switch(__even_in_range(UCB0IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: // Vector 4: NACKIFG I2C_failure = 0x01; //sensor_failure is due to SoC to I2C peripheral communication error __bic_SR_register_on_exit(LPM1_bits); // Exit active CPU break; case 6: break; // Vector 6: STTIFG case 8: break; // Vector 8: STPIFG case 10: // Vector 10: RXIFG RXByteCtr--; // Decrement RX byte counter if (RXByteCtr) { *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData if (RXByteCtr == 1) // Only one byte left? UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition } else { *PRxData = UCB0RXBUF; // Move final RX data to PRxData __bic_SR_register_on_exit(LPM1_bits); // Exit active CPU } I2C_failure = 0; // NO I2C sensor_failure break; case 12: // Vector 12: TXIFG if (TXByteCtr) // Check TX byte counter { UCB0TXBUF = *PTxData++; // Load TX buffer TXByteCtr--; // Decrement TX byte counter } else { UCB0CTL1 |= UCTXSTP; // I2C stop condition UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag __bic_SR_register_on_exit(LPM1_bits); // Exit LPM0 } I2C_failure = 0; // NO I2C sensor_failure break; default: break; } }
The problem is that the CC430 never exits from the interrupt and gets stuck on the line 10 instruction without signalling the NACK situation.
The only way to restore the system is with a strong reset.
The other strange this is that if I place a breakpoint on thisinstruction, the Debugger never stops there and looks running but, as soon as I pause it, the code execution results stuck on that instruction.
The questions are three:
In order to be more detailed I also want to underline that the CC430 gets stuck on that instruction after having entered a first time the interrupt subroutine for loading the first byte to be sent in the UCB0RXBUF buffer (instruction 32). The UCTXSTT bit, furthermore, gets never reset (as it should be after I2C address sending) and firmware gets stuck on the line 10 instruction.
Waiting for your reply,
Best regards,
Claudio
The only reason I can think of why the code could be stuck in the __bic_SR_register_on_exit line is that you already have a stack overflow and this instruction causes a write to some vital register.
However, I rather think that you are subject to code optimization and re-arrangement. The compiler might have joined the three __bic instructions in your ISR into one, and the debugger shows you the first when breaking, while you actually are at one of the others. From the program counter at the break moment, the debugger cannot know. You should disable optimizations when debugging. Also, a look at the assembly view may shed some light on it.
I hope that I2C_failure (and all other global vars used in the ISR) is declared as volatile, or else main might not notice the changes done in the interrupt (by looking at a local register copy of that variable, which of course won’t change)
I2C is quite robust. However, on noisy environment as well as on bus topologies with rather high parasitic and line capacitances, stronger pull-up resistors (down to 1k) are required. Same for high I2C bus speeds (100-400kHz). Look at the waveforms with a scope.
**Attention** This is a public forum