Issue in wire library for I2C Slave on SAMD51 Thing Plus
JordanMajd opened this issue · 1 comments
Issue
Using the Thing Plus as an I2C slave:
- Hangs up the i2c bus and itself whenever an i2c operation occurs.
- Does not show up on the bus at registered address.
- Does not invoke
onRequestoronReceivecallbacks.
This issue also affects Adafruit SAMD51 boards, an issue tracking a fix for their Wire lib and variants is in the ArduinoCore-samd repo.
Reproduction
Sample Program:
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin(0x08);
Wire.onRequest(requestHandler);
Serial.println("Setup complete");
}
void loop() {
Serial.println(millis());
delay(100);
}
void requestHandler() {
Serial.println("Req: responding 6 bytes");
Wire.write("bytess");
}Upon running i2cdetect the device stops printing timestamps in the loop. i2cdetect is sluggish, and shows no available addresses, not even other devices on the bus:
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- i2cget is unable to read values from the board:
$ i2cget -y 1 8
Error: Read failedExplanation
Thing Plus' Wire lib was written for a SAMD21, which has a single Sercom interrupt for I2C slave operations. Whereas, the SAMD51 uses 4 Sercom Interrupts when being used as an I2C slave.
Workaround
Near the top of the repro sketch sketch declare each of the 4 SERCOM3 interrupt handlers:
void SERCOM3_0_Handler() { Wire.onService(); }
void SERCOM3_1_Handler() { Wire.onService(); }
void SERCOM3_2_Handler() { Wire.onService(); }
void SERCOM3_3_Handler() { Wire.onService(); }Now both i2cdetect and i2cget are nominal:
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- 08 -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- 1a -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
$ i2cget -y 1 8
0x62Fix
Update Wire.h to support 4 sercom interrupt handlers for a wire interface in addition to declaring the handlers in the Thing Plus variant.h.
I'm submitting a PR to Adafruit and can also submit one here.
added in v1.7.2, thanks!