{"action":"created","issue":{"url":"https://api.github.com/repos/esp8266/Arduino/issues/727","labels_url":"https://api.github.com/repos/esp8266/Arduino/issues/727/labels{/name}","comments_url":"https://api.github.com/repos/esp8266/Arduino/issues/727/comments","events_url":"https://api.github.com/repos/esp8266/Arduino/issues/727/events","html_url":"https://github.com/esp8266/Arduino/issues/727","id":103639750,"number":727,"title":"I2C reads from touchscreen fail (clock stretch issues, SCL stuck high on client?)","user":{"login":"spapadim","id":4348443,"avatar_url":"https://avatars.githubusercontent.com/u/4348443?v=3","gravatar_id":"","url":"https://api.github.com/users/spapadim","html_url":"https://github.com/spapadim","followers_url":"https://api.github.com/users/spapadim/followers","following_url":"https://api.github.com/users/spapadim/following{/other_user}","gists_url":"https://api.github.com/users/spapadim/gists{/gist_id}","starred_url":"https://api.github.com/users/spapadim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spapadim/subscriptions","organizations_url":"https://api.github.com/users/spapadim/orgs","repos_url":"https://api.github.com/users/spapadim/repos","events_url":"https://api.github.com/users/spapadim/events{/privacy}","received_events_url":"https://api.github.com/users/spapadim/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-08-28T03:22:22Z","updated_at":"2015-08-28T03:26:14Z","closed_at":null,"body":"I have a Digole LCD + touchscreen module ([this one](http://digole.com/index.php?productID=1208), protocol description [here](http://www.digole.com/images/file/Tech_Data/Digole_Serial_Display_Adapter-Manual.pdf)), 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).\r\n\r\nEverything here is from the Sparkfun Thing (for ESP) and RedBoard (for AVR). Gist with logic analyzer captures (readable with the [OLS client](http://ols.lxtreme.nl/)) is:   https://gist.github.com/6f17e71df82975ee9fdf\r\n\r\nThe 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.\r\n\r\nA couple of issues:\r\n\r\n1 - 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:\r\n![touch-avr-nodelay-zoom](https://cloud.githubusercontent.com/assets/4348443/9538208/d62e699e-4d0f-11e5-8acd-3c8caf66e69b.png)\r\nDidn'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.\r\n\r\n2 - 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:\r\n![touch-avr-delay5-zoom](https://cloud.githubusercontent.com/assets/4348443/9538245/42ab4e20-4d10-11e5-936c-e10e9f59be10.png)\r\nProblem solved, I thought.\r\n\r\n3 - Taking this code with ``delay(5)`` and recompiling for ESP, I get this instead:\r\n![touch-esp-delay5-zoom](https://cloud.githubusercontent.com/assets/4348443/9538256/6a0b9cc2-4d10-11e5-916a-c39ecd918411.png)\r\nAs 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. ]\r\n\r\nFor 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... ;) ).\r\n\r\nFWIW, 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).\r\n\r\nPS. 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.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/esp8266/Arduino/issues/comments/135623268","html_url":"https://github.com/esp8266/Arduino/issues/727#issuecomment-135623268","issue_url":"https://api.github.com/repos/esp8266/Arduino/issues/727","id":135623268,"user":{"login":"spapadim","id":4348443,"avatar_url":"https://avatars.githubusercontent.com/u/4348443?v=3","gravatar_id":"","url":"https://api.github.com/users/spapadim","html_url":"https://github.com/spapadim","followers_url":"https://api.github.com/users/spapadim/followers","following_url":"https://api.github.com/users/spapadim/following{/other_user}","gists_url":"https://api.github.com/users/spapadim/gists{/gist_id}","starred_url":"https://api.github.com/users/spapadim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spapadim/subscriptions","organizations_url":"https://api.github.com/users/spapadim/orgs","repos_url":"https://api.github.com/users/spapadim/repos","events_url":"https://api.github.com/users/spapadim/events{/privacy}","received_events_url":"https://api.github.com/users/spapadim/received_events","type":"User","site_admin":false},"created_at":"2015-08-28T03:26:14Z","updated_at":"2015-08-28T03:26:14Z","body":"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?..)."}}