I2C slave mode (Wire library) on T4.x vs repeated STARTs

jmarsh

Well-known member
Are there known issues with Wire in slave mode not properly recognizing repeated STARTS correctly, when used on T4.x? I have a pretty good idea what the problem is but I'm a bit puzzled how people are using slave mode for it to have gone unnoticed.
 
Wire slave mode isn't commonly used, so it's quite possible a bug could have gone unnoticed.

I'm curious to hear what you've found. Any chance to share?
 
Consider the case where you want the Teensy to act like an I2C EEPROM, here's a transaction sequence to perform a read:
Screenshot 2025-10-17 130050.png


This should be pretty trivial to implement: register a function with onReceive() to catch the address byte and register another function with onRequest() that writes the bytes for the given address. But what happens is the onRequest hook gets called before the onReceive hook, so it sends the data for the wrong address. I tested the exact same code on an arduino nano and it worked correctly on that device.

From looking at the code in WireIMXRT.cpp, the problem is only the slave STOP interrupt is being handled (LPI2C_SSR_SDF), which doesn't get triggered when a repeated START happens - there's a separate status/interrupt bit for that, LPI2C_SSR_RSF. If that interrupt is enabled and the ISR checks for both (LPI2C_SSR_SDF | LPI2C_SSR_RSF), the hook functions get called in the correct order.
 
FWIW I'm also seeing another issue (not using slave mode, although it may be playing a role) where the transmit FIFO seems to be getting out of sync, the values being returned by endTransmission()/requestFrom() end up being related to the previous transfer rather than the one given for the current call... I will continue investigating, but there's definitely an issue with larger transfers (8+ bytes).
 
If I'm trying to write code to be portable between MCUs it has to be the Wire library.
Similarly Teensy's Wire library should behave the same as the one that regular Arduinos use.
 
Back
Top