-
Notifications
You must be signed in to change notification settings - Fork 13.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I2C reads from touchscreen fail (clock stretch issues, gets SCL stuck high on client?) #727
Comments
Forgot to say that I noticed #698. Haven't tried that yet (will at some point), but I don't think it's related since SCL is never pulled down by client after the first read request -- so problem happens earlier than the NACK (but where?..). |
spapadim
changed the title
I2C reads from touchscreen fail (clock stretch issues, SCL stuck high on client?)
I2C reads from touchscreen fail (clock stretch issues, gets SCL stuck high on client?)
Aug 28, 2015
Thanks for the detailed analysis, I expect it will help somebody. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have a Digole LCD + touchscreen module (this one, protocol description here), using it in I2C mode (7-bit address of 0x29). I2C writes work fine, but reads get the bus stuck. Everything works fine on an AVR. Display draws ~60mA (according to my bench supply), so power should not be an issue (my ESP is a Sparkfun Thing -- also tried an Adafruit breakout very briefly).
Everything here is from the Sparkfun Thing (for ESP) and RedBoard (for AVR). Gist with logic analyzer captures (readable with the OLS client) is: https://gist.github.com/6f17e71df82975ee9fdf
The example I'm going with here is very basic, to illustrate issue: an infinite loop that does a non-blocking read of an X,Y touch coordinate. This is done as follows: master writes the string
RPNXYI
, then issues two 2-byte reads, which correspond to 16bit ints for X and Y, respectively (MSB-first). If no finger is touching, then at least one coordinate returned will be out-of-screen-bounds.A couple of issues:
1 - Starting from the AVR, which always works (running the exact same Arduino code), I found out (after some quick exchanges with Digole's support) that the display stretches the clock while waiting for a touchscreen ADC conversion. This can take up to 2ms:
Didn't take long to realize that the software I2C implementation can't handle such a long stretch. However, the 100us limit is well below the WDT timeout -- and even then, if the bus is never released, the device is hosed anyway, so it might as well reboot. But that's a secondary point.
2 - Luckily, it turns out that it's the
RPNXYI
write that triggers the ADC conversion, so simple solution:delay(5)
between writing that string and issuing the I2C read request. Here is what it looks like on the AVR:Problem solved, I thought.
3 - Taking this code with
delay(5)
and recompiling for ESP, I get this instead:As far as I can tell, after ACKing the read request address byte (0x4f), the display module never pulls SCL down ever again. Just gets stuck. So I always read back 0xff 0xff from the first read, and then it's NACKs forever. [Notes: (1) in case you notice clock "period": I set
twi_dcount
to56
, for ~50KHz reduced clock, as part of earlier debugging; (2) if you see the raw OLS captures, pls ignore initial commands to clear screen (CL
), set display orientation (SD3
), and set color (ESCxxx
), -- these are part ofsetup()
, and here I had to start capturing from beginning, since bus gets stuck almost immediately. ]For the life of me, I can't see what the difference is between these two captures (then again, I've been staring at these and more for more than a day, so... ;) ).
FWIW, I also tried upping
#define TWI_CLOCK_STRETCH
to6400000
[sic] from800
, that didn't do anything for the stretch. In fact, the clock stretch seems to be completely ignored by the I2C implementation on the ESP (it doesn't even try to delay for 100us or something, just goes ahead? -- unless my eyes are really crossed, which is likely ;) ). In fact, if I try to run the code without delay on the ESP, the capture looks pretty much the same as the third case (the ESP master pulls up SCL as if nothing happened).PS. On the stretch issue, the same Digole module also implements a blocking read for X, Y (
RPNXYW
). Didn't pursue this as I don't like blocking (I need to update UI based on touch-down, drag, and touch-up events, so I wrote code for that, which works on the AVR -- this example is stripped from there), so not sure how it works, but I suspect that it blocks by stretching the clock... that might be a real issue with the WDT on the ESP, but I would probably argue it's poor API design on the display device.Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: