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.

MSP430FR5969: I2C(In Slave Mode) Stop condition's ISR(USCI_I2C_UCSTPIFG) section is prematurely executed before last byte from Master is processed.

Part Number: MSP430FR5969

Tool/software:

Main Code:

Fullscreen
1
2
3
4
5
6
7
8
9
10
void main(void)
{
//Init similiar to receive example for MSP430 FR5969
init_I2C();
while(1){
cmd_process();
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Init_I2C():

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void init_I2C(){
WDT_A_hold(WDT_A_BASE);
// Configure Pins for I2C
//Set P1.6 and P1.7 as Secondary Module Function Input.
/*
* Select Port 1
* Set Pin 6, 7 to input Secondary Module Function, (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
*/
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_P1,
GPIO_PIN6 + GPIO_PIN7,
GPIO_SECONDARY_MODULE_FUNCTION
);
/*
* Disable the GPIO power-on default high-impedance mode to activate
* previously configured port settings
*/
PMM_unlockLPM5();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

cmd_process():

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
void cmd_process() {
switch(current_Statemachine) {
case IDLE:
resumeI2CInterrupts();
break;
case HEALTH_CHECK: // Simply Returns the received data
TXData = myPayload;
current_Statemachine = IDLE;
break;
... Rest of the code
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Master Arduino Code(TEENSY):

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <Wire.h>
byte arrToSend[] = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
void test_health_check(int numofBytes)
{
Wire.beginTransmission(0x08); // Address of the MSP430 slave
Wire.write(0x22);
int i;
for(i = 0; i<numofBytes; i++)
{
Wire.write(arrToSend[i]);
}
Wire.endTransmission();
delay(1000);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Where the issue is happening 

The ISR:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void suspendI2CInterrupts() {
EUSCI_B_I2C_disableInterrupt(EUSCI_B0_BASE,
EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_STOP_INTERRUPT
);
}
void resumeI2CInterrupts() {
EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE,
EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_STOP_INTERRUPT
);
__bis_SR_register(CPUOFF + GIE); // Enter LPM with interrupts
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B0_VECTOR)))
#endif
void USCIB0_ISR(void)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


If I send 4 bytes,

For the first three bytes the "USCI_I2C_UCRXIFG0" case is run,

then the stop condition case "USCI_I2C_UCSTPIFG" is run

then the last byte is processed and the "USCI_I2C_UCRXIFG0" case is ran even though its supposed to happen before the stop condition. 


ignore the first run in the serial output, The subsequent ones rewrite the first index because the stop condition is always executed before the last byte is processed, the first byte printed should be "0x22". 
I am Using 5.5K Ohms pullups and the MSP430 provides a VCC of 3.6V.  
MSP430 is slave and Arduino Teensy is Master. 

  • STPIFG has higher priority (in the IV) than RXIFG, so there is a race. If the Stop is recognized before the ISR reads the IV (for the RXIFG), the Stop is presented first. There's only one I2C clock between the Rx completion and the Stop completion, so this is highly probable.

    I (personally) try to avoid using UCSTPIFG at all, for this reason. Alternatively you can check the RXIFG bit directly, but I found that fairly messy to unwind.

**Attention** This is a public forum