Shop OBEX P1 Docs P2 Docs Learn Events
Preventing your I2C device from jamming up the works... — Parallax Forums

Preventing your I2C device from jamming up the works...

Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
edited 2012-06-05 14:05 in Propeller 1
Recently I ran into an issue using the I2C objects with Wii Controllers.

Seems that if the controller wasn't plugged in, things wouldn't just continue on gracefully, the whole program would freeze.

Some investigation of the I2C code reveals some code that works like this..
repeat until ina[i2cSCL] == _pinHigh   


Apparently this is done to stretch the clock out a bit in case the device is lagging behind the code.

I've started switching that code with something that looks like this..
       repeat 20
          if ina[i2cSCL] == _pinHigh     
             quit


This problem doesn't seem to affect other I2C scenarios, and seems to fix the issues with missing controllers.
Now things carry on without getting stuck. The official version of MIGS will also be updated soon as the I2C object there suffered from the same kinds of issues.

OBC

Comments

  • ZootZoot Posts: 2,227
    edited 2012-06-04 18:28
    I'm curious, why would you want to quit if the slave is clock stretching ? Clock stretching is part of the spec and lets the slave handle requests. It would be better to put a time out in, so that if the slave doesn't release the clock within a certain period of time, then the transaction quits.

    I'm also curious because generally clock stretching is performed by holding the clock line LOW, and given that there should be pull-ups on the I2C bus, how would the missing controller be pulling the clock line low ???
  • Cluso99Cluso99 Posts: 18,069
    edited 2012-06-04 18:29
    Nice fix OBC. We dont run into these problems until something is not right.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-06-04 20:29
    I'm with Zoot. I can't see why this is necessary. The idle state for CLK, with nothing connected, is high -- assuming, of course, that CLK has a pull-up. If it doesn't have a pull-up, one should be added. Otherwise, I'm afraid the software fix will result in a false sense of confidence with other issues lurking just around the corner.

    -Phil
  • ZootZoot Posts: 2,227
    edited 2012-06-04 20:36
    The irony is that there *is* a fix needed -- a timeout in the case of a slave on the I2C bus that uses clock stretching and fails (for some reason) to release SCL. Otherwise you get a hang. The firmware for the Basic Stamps that has native I2C commands (2p, 2px) *does* support clock stretching AND has a timeout in the case of a hung SCL line. The SX/B compiler's I2C assembly supports clock stretching but does NOT include a timeout (I've learned that the hard way). I'm a bit surprised that Prop objects (which are not bound by IP firmware nor compiler output) do not support clock stretching without a hang.

    Mostly I've seen this come up with I2C slaves that are not "hard" chips (e.g. EEPROM, RTCs, etc) but micros themselves, where the setup time for prepping bytes to the master might be much longer then the next clock pulse following addressing from the master.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-06-04 20:46
    Zoot wrote:
    The irony is that there *is* a fix needed...
    But a timeout is not the correct fix for the stated problem: non-connection of a device.

    -Phil
  • ZootZoot Posts: 2,227
    edited 2012-06-04 20:53
    Phil - No, it's not the "correct" solution, although if the non-connected device in OBC's circuit is somehow keeping SCL low, this would prevent the program from hanging. As you said, something seems unusual. In any case, a timeout under such circumstances (infinite loop if a pin is held low) would seem like a good idea.
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2012-06-04 21:10
    My solution is "results driven" -- I suspected there were other hardware issues at play, but it does work, and work consistently here. So far, so good.


    OBC
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-06-04 21:51
    Zoot wrote:
    ...although if the non-connected device in OBC's circuit is somehow keeping SCL low, ...
    Spooky action at a distance? Maybe OBC has discovered a new mechanism for quantum entanglement. :)

    -Phil
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2012-06-05 07:40
    I think that the real problem might stem from an improper STOP condition that might be caused when a slave device is removed in mid-communication with the master. If the master doesn't properly recognize this scenario, it could potentially 'hang' in code.

    The SDA line as well as the SCL line should be investigated during this 'hang' scenario.

    http://www.esacademy.com/en/library/technical-articles-and-documents/miscellaneous/i2c-bus/i2c-bus-events/start-and-stop-conditions.html
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-06-05 08:09
    Here's my suspicion:

    Many Propeller-based designs (e.g. Prop Demo Board) do not include a pull-up on SCL. In cases where the I2C master drives the line both high and low, it's not necessary; but it's not a very good practice to do it that way, since it doesn't accommodate slaves that use clock stretching. Some I2C objects, instead of driving SCL both high and low with outa, use dira to toggle SCL, relying on a pull-up to take care of the logic high. This is the way it should be done, since it can accommodate clock stretching. Due to the the line of code that OBC cites, I suspect that he's using such a driver. But such drivers are not compatible with circuits that do not include the pull-up on SCL. So my guess is that OBC is using a board without the pull-up but that the Wii Controller has one built-in. This would cause the hang that he reports without the controller connected, but normal operation with it plugged in. While it's all very well to include a time-out in the code (which should be there anyway), it would be better still to add a pull-up resistor to SCL.

    -Phil
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2012-06-05 09:59
    Here's my suspicion:

    Many Propeller-based designs (e.g. Prop Demo Board) do not include a pull-up on SCL. In cases where the I2C master drives the line both high and low, it's not necessary; but it's not a very good practice to do it that way, since it doesn't accommodate slaves that use clock stretching. Some I2C objects, instead of driving SCL both high and low with outa, use dira to toggle SCL, relying on a pull-up to take care of the logic high. This is the way it should be done, since it can accommodate clock stretching. Due to the the line of code that OBC cites, I suspect that he's using such a driver. But such drivers are not compatible with circuits that do not include the pull-up on SCL. So my guess is that OBC is using a board without the pull-up but that the Wii Controller has one built-in. This would cause the hang that he reports without the controller connected, but normal operation with it plugged in. While it's all very well to include a time-out in the code (which should be there anyway), it would be better still to add a pull-up resistor to SCL.

    -Phil

    Nick and I opted to remove the "optional" Wii Controller pull-up's from the last run of Quickplayer. I suspect I may include them in the next run, however I did in fact add the pull-up resistor to the board I'm running here without it making a difference in any of the original drivers. As for determining if the controller has an internal pull-up, I'm actually testing with four different controllers; Wii Classic, ClassicPro, Wii Nunchuck, and clone Nunchuck. They have all respond universally to the issue. The biggest issue that I seem to have found is that of having software "lockup" when the controller isn't present. I've re-written MIGS to skip past when the I2C device doesn't communicate in time, then return 0's on all controls when queried.

    OBC
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-06-05 12:02
    Okay, I guess the question I still have is this: if you have a pull-up on SCL, and there's nothing connected to it, what's keeping SCL pulled down that requires timing out?

    -Phil
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2012-06-05 12:28
    Okay, I guess the question I still have is this: if you have a pull-up on SCL, and there's nothing connected to it, what's keeping SCL pulled down that requires timing out?

    -Phil

    You know Phil, I've been scratching my head over the same question.. Hence the final software solution..
    If you've got a clue here, I'd love to know. :)

    OBC
  • photomankcphotomankc Posts: 943
    edited 2012-06-05 12:31
    I don't get that either? My PASM driver will lock up good and solid if the other end stretches the clock forever but I need to figure out a graceful way to abort since the bus is hosed now anyway so what else can you really do if you needed it? But it couldn't care less if the device that I want to talk to isn't there to begin with. You get back 255 and think it's good data unless you took the time to querry the bus for the device first. The only way to lock it up would be to ground the bus somehow.
  • photomankcphotomankc Posts: 943
    edited 2012-06-05 12:35
    You know Phil, I've been scratching my head over the same question.. Hence the final software solution..
    If you've got a clue here, I'd love to know. :)

    OBC

    Is the line really comming up low at boot? Is the initial state of the output register somehow set to output a low in some other cog and pulling it down? That's a head scratcher for sure.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-06-05 12:47
    If a device is powered down but remains connected to the i2c buss, the protection diodes on the device may become forward biased and hold the scl and sda lines low. When you say "unplugged" I assume that means that it is physically disconnected from the i2c buss, but it could also mean that it was unplugged from its power source.

    In general I like to include escape timeouts from code like that, especially when the goal involves other tasks that should continue even when one part fails. In field wiring there are all sorts of things that can go bump in the night. A device simply fails, or it falls into a vat of salt water, or a rat needs the cable jacket for its nest, or somebody fiddles with the wiring, or somebody makes a firmware change that sets the pin low from another cog, etc etc.

    OBC, which i2c driver are you using? Mike's basic_i2c_driver does not support clock stretching, so it would not exhibit the problem. The only device I've used that depended on clock stretching was an ADC, the MAX1239.
  • jmgjmg Posts: 15,183
    edited 2012-06-05 14:05
    They have all respond universally to the issue. The biggest issue that I seem to have found is that of having software "lockup" when the controller isn't present.

    The details are sparse, here.
    Is this a power removal, or a complete disconnect from the pins. Is the bus shared with ANY other devices ?
    Is this a removal while running scenario, or a cold power up, with no remotes plugged in ?

    Clearly something, somewhere has to be pulling the pin low, (or the polled pin is moving ?).

    A small series resistor will let you check the current magnitude and direction with a reasonable multimeter
Sign In or Register to comment.