Hi,
We are having an issue where sometimes the msp stops replying correctly on the i2c until it gets reset.
The msp acts as slave.
When it starts to misbehave, the msp acknowledges the address, the data received, but stops acknowledging afterwards. SCL gets stuck low when it should ack. SCL stays low for 32ms, and then bus is restarted in the handling of USCI_I2C_UCCLTOIFG
However the msp keeps misbehaving after the bus reset, with the same pattern. It works ok only if I reset the msp completely.
Here is how I reset the bus.
case USCI_I2C_UCCLTOIFG: //Timeout of the bus, reset i2c ucBusyDetectionCounter += 1; P1SEL1 &= ~(BIT6); // Generate NACK by releasing SDA, P1SEL1 &= ~(BIT7); // then SCL, via disconnecting from the I2C UCB0CTLW0 |= UCSWRST; // Reset UCB0CTLW0 |= UCMODE_3 | UCSYNC; // I2C mode, sync mode UCB0I2COA0 = SLAVE_ADDR | UCOAEN; // Own Address and enable UCB0CTLW0 &= ~UCSWRST; P1SEL1 |= (BIT6|BIT7); // Re-connect pins to I2C UCB0IE |= UCRXIE + UCSTPIE + UCCLTOIE; // Enable RX and TX interrupt break;
I suppose I have two issues:
1: Some internal issue which prevents it to reach next state
2: An incomplete bus restart which fails to correct it.
From the doc:
The clock is stretched by the eUSCI_B under the following conditions:
1: The internal shift register is expecting data, but the TXIFG is still pending
2: The internal shift register is full, but the RXIFG is still pending
3: The arbitration lost interrupt is pending => Unlikely, it is handled in the same routine than USCI_I2C_UCCLTOIFG which works fine
4: UCSWACK in UCBxCTLW1 is selected and UCBxI2COA0 did cause a match => Not possible, UCSWACK is not activated
I'm currently digging into the first two causes for clock stretching.
My questions:
- Have you seen such issue? Any pointer which could help me understand the root cause of the issue?
- Do you see any issue with the bus reset code?
Notes:
I'm quite sure the i2c master is not the issue, the problem stops when the msp is reset, and the communication with other i2c slaves is ok.
Thanks,
Cédric