Other Parts Discussed in Thread: MSP430F148, MSP430F5335
Hello,
I am using the MSP430F1611 in a simple application which provides i2c to RS232/485 conversion.
I am having a problem in the i2c interrupt routine where I am writing to the I2CIE register to clear the TXRDYIE bit. For some reason, the bit does not always clear properly. I first clear the bit, then I added a nop just for good measure, then I am reading the bit again, and clearing it again if it was not already cleared. For some reason, the bit is not being cleared on the first attempt sometimes. I am using IAR EW430 7.10.3. Here is the code:
#pragma vector = USART0TX_VECTOR
__interrupt void slave_byte(void){ // slave i2c interface
switch (__even_in_range(I2CIV, 0x10)) { // trigger on interrupt
case I2CIV_NONE: // (0x0000u) /* I2C interrupt vector: No interrupt pending */
break;
case I2CIV_AL: // (0x0002u) /* I2C interrupt vector: Arbitration lost (ALIFG) */
break;
case I2CIV_NACK: // (0x0004u) /* I2C interrupt vector: No acknowledge (NACKIFG) */
break;
case I2CIV_OA: // (0x0006u) /* I2C interrupt vector: Own address (OAIFG) */
i2cbuff_p = 0; // init to first char in i2c buffer
break;
case I2CIV_ARDY: // (0x0008u) /* I2C interrupt vector: Access ready (ARDYIFG) */
break;
case I2CIV_RXRDY: // (0x000Au) /* I2C interrupt vector: Receive ready (RXRDYIFG) */
i2cbuff[i2cbuff_p] = I2CDRB;
if (i2cbuff_p < MAX_I2C_BUFF_P)
if (++i2cbuff_p == 2) {
I2CIE = (OAIE | RXRDYIE); // disable tx interrupt to provide clock stretching and trigger process_i2c FIRST ATTEMPT TO CLEAR TXRDYIE BIT
__no_operation();
if ((I2CIE & TXRDYIE) != 0) // CHECK TO SEE IF BIT ACTUALLY CLEARED
I2CIE = (OAIE | RXRDYIE); // disable tx interrupt to provide clock stretching and trigger process_i2c I AM SETTING A BREAK POINT HERE AND IT
// IS STOPPING HERE ON OCCASTION WITH THE TXRDYIE BIT STILL SET IF I INSPECT IN THE REGISTERS IN IAR.
}
break;
case I2CIV_TXRDY: // (0x000Cu) /* I2C interrupt vector: Transmit ready (TXRDYIFG) */
I2CDRB = i2c_tx_char; // copy outgoing byte
break;
case I2CIV_GC: // (0x000Eu) /* I2C interrupt vector: General call (GCIFG) */
break;
case I2CIV_STT: // (0x0010u) /* I2C interrupt vector: Start condition (STTIFG) */
break;
} // end switch
} // end receive bit interrupt
Any suggestions would be greatly appreciated.
Thanks,
Greg Dunn