Skip to content

I2C reads from touchscreen fail (clock stretch issues, gets SCL stuck high on client?) #727

Closed
@spapadim

Description

@spapadim

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:
touch-avr-nodelay-zoom
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:
touch-avr-delay5-zoom
Problem solved, I thought.

3 - Taking this code with delay(5) and recompiling for ESP, I get this instead:
touch-esp-delay5-zoom
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 to 56, 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 of setup(), 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 to 6400000 [sic] from 800, 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions