Closed neilt6 closed 6 years ago
I think I may have found the culprit, the i2c_slave_read()
implementation for the LPC11Uxx microcontrollers (and possibly others) appears to be flawed:
int i2c_slave_read(i2c_t *obj, char *data, int length) {
int count = 0;
int status;
do {
i2c_clear_SI(obj);
i2c_wait_SI(obj);
status = i2c_status(obj);
if((status == 0x80) || (status == 0x90)) {
data[count] = I2C_DAT(obj) & 0xFF;
}
count++;
} while (((status == 0x80) || (status == 0x90) ||
(status == 0x060) || (status == 0x70)) && (count < length));
/* The previous loop exited after the expected number of bytes were received, but before
the master set the stop condition, which means this insidious piece of code will run
every time. Since when do slaves issue stop conditions anyway, is that even legal? */
if(status != 0xA0) {
i2c_stop(obj);
}
i2c_clear_SI(obj);
return count;
}
As indicated by my comments, the routine is issuing it's own stop condition before the master is able to, which is probably causing the I2C peripheral on the LPC1549 to enter a state that isn't handled by the library (arbitration lost perhaps?). At any rate, patching the routine to wait for a stop condition from the master fixed my problem. Would someone else care to verify my findings so that we can start working on a PR?
GitHib issue review: Closed due to inactivity. Please re-file if critical issues found.
I'm unable to communicate with an mbed-based I2C slave using an LPC1549. Here is the code I'm using to reproduce the problem:
I2C Master Code (running on LPC1549)
Output
I2C Slave Code (running on LPC11U24)
Output
The I2C master code works fine on an LPC11U68, but throws up errors on an LPC1549. I've traced these errors to _i2capi.c line 122 and line 187, but I haven't been able to figure out what's causing them.