{"action":"created","issue":{"url":"https://api.github.com/repos/spark/firmware/issues/709","labels_url":"https://api.github.com/repos/spark/firmware/issues/709/labels{/name}","comments_url":"https://api.github.com/repos/spark/firmware/issues/709/comments","events_url":"https://api.github.com/repos/spark/firmware/issues/709/events","html_url":"https://github.com/spark/firmware/issues/709","id":112895147,"number":709,"title":"System crash when button interrupt occurs during i2c transmission","user":{"login":"pomplesiegel","id":1450352,"avatar_url":"https://avatars.githubusercontent.com/u/1450352?v=3","gravatar_id":"","url":"https://api.github.com/users/pomplesiegel","html_url":"https://github.com/pomplesiegel","followers_url":"https://api.github.com/users/pomplesiegel/followers","following_url":"https://api.github.com/users/pomplesiegel/following{/other_user}","gists_url":"https://api.github.com/users/pomplesiegel/gists{/gist_id}","starred_url":"https://api.github.com/users/pomplesiegel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pomplesiegel/subscriptions","organizations_url":"https://api.github.com/users/pomplesiegel/orgs","repos_url":"https://api.github.com/users/pomplesiegel/repos","events_url":"https://api.github.com/users/pomplesiegel/events{/privacy}","received_events_url":"https://api.github.com/users/pomplesiegel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/spark/firmware/milestones/18","html_url":"https://github.com/spark/firmware/milestones/0.4.9","labels_url":"https://api.github.com/repos/spark/firmware/milestones/18/labels","id":1458242,"number":18,"title":"0.4.9","description":null,"creator":{"login":"m-mcgowan","id":2465470,"avatar_url":"https://avatars.githubusercontent.com/u/2465470?v=3","gravatar_id":"","url":"https://api.github.com/users/m-mcgowan","html_url":"https://github.com/m-mcgowan","followers_url":"https://api.github.com/users/m-mcgowan/followers","following_url":"https://api.github.com/users/m-mcgowan/following{/other_user}","gists_url":"https://api.github.com/users/m-mcgowan/gists{/gist_id}","starred_url":"https://api.github.com/users/m-mcgowan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/m-mcgowan/subscriptions","organizations_url":"https://api.github.com/users/m-mcgowan/orgs","repos_url":"https://api.github.com/users/m-mcgowan/repos","events_url":"https://api.github.com/users/m-mcgowan/events{/privacy}","received_events_url":"https://api.github.com/users/m-mcgowan/received_events","type":"User","site_admin":false},"open_issues":17,"closed_issues":1,"state":"open","created_at":"2015-12-14T00:04:10Z","updated_at":"2016-01-07T16:36:20Z","due_on":null,"closed_at":null},"comments":14,"created_at":"2015-10-22T21:26:40Z","updated_at":"2016-01-08T22:55:49Z","closed_at":null,"body":"Using system FW 0.4.7 (which now includes changes preventing task switching during i2c transmissions) if a Photon's \"reset\" or \"setup\" button is pressed during an i2c transmission, the system hangs indefinitely (totally unresponsive), as shown by the the static RGB LEDs.\r\n\r\nWe quickly ran across this issue using our full-featured application, as our product uses an i2c port expander to track real-time state of a front panel. This should be easy to reproduce on any program actively using the i2c bus. \r\n\r\n![image](https://cloud.githubusercontent.com/assets/1450352/10677823/a32afae6-78dc-11e5-9bf8-b7eed47360ef.png)\r\n\r\n![img_0208](https://cloud.githubusercontent.com/assets/1450352/10677877/f9c9646e-78dc-11e5-9862-d549982eee89.PNG)\r\n\r\n \r\nAs i mentioned in #698\r\n\r\n> My only question is what would prevent the occasional system instability I saw on Photon when adding os_thread_scheduling(false, NULL); to the Wire methods. Is there a less restrictive call which won't cause crashes/delays to the system FW when pressing the reset button on Photon? I'd imagine that issue would show up elsewhere, for other interrupts?\r\n\r\nBecause locally instantiating a CriticalSection object (done before each i2c call) simply sets and unsets `os_thread_scheduling(true, NULL)` upon its creation and destruction, it makes sense this issue has not gone away. \r\n\r\nI'd imagine this will happen for other Photon pins registered to interrupts as well.\r\n\r\n#### Easiest way to reproduce \r\n1. Attach a Photon to a MCP23017 port expander (at address 0x20) over i2c w/ pull-ups\r\n2. Load the code below on a Photon running system FW 0.4.7\r\n3. While the system is running, quickly tap the \"setup\" button. The goal here is to trigger a button interrupt while task switching is currently disabled by an active `CriticalSection` object on the stack. This should only take a few seconds. \r\n\r\n#### Code to reproduce\r\n\r\n````cpp\r\n#include \"application.h\"\r\n#include \"Adafruit_MCP23017.h\"\r\n\r\nSYSTEM_MODE(MANUAL);\r\nSYSTEM_THREAD(ENABLED);\r\n\r\nAdafruit_MCP23017 myPE; \r\n\r\nvoid setup()\r\n{\r\n  Serial.begin(9600);\r\n\r\n  WiFi.on();\r\n  WiFi.connect();\r\n  Particle.connect();\r\n\r\n  Serial.println(\"Example program w/ real i2c traffic\");\r\n\r\n  myPE.begin();\r\n  myPE.pinMode(0,OUTPUT);\r\n  myPE.pinMode(1,INPUT);\r\n}\r\n\r\nvoid loop()\r\n{\r\n  Particle.process(); \r\n  delayMicroseconds(10);\r\n\r\n  //i2c transactions w/ our PE\r\n  myPE.digitalWrite(0, myPE.digitalRead(1) );\r\n}\r\n````\r\n\r\n#### For context\r\n* The task switching protections inserted by @m-mcgowan in 0.4.7 have proved incredibly effective at eliminating previously commonplace i2c transmission errors. Our error rate has dropped to 0%, which is great.\r\n* However, the last task is to make sure that even with a program which actively (and realistically) uses the i2c bus, no potential instability like this occurs when task switching is disabled.\r\n\r\n#### Our proposal to Particle SQA\r\n@jonlogan, For early highlighting of critical but easily reproducible issues like this, which occur only in a realistic customer application (aka. not Tinker), would you please consider building programs like the example above into your QA regression test regimen before releasing? Historically, a few real-time calls to `Wire`, `SPI`, `Serial` and `Particle.process` within `Loop()` are often all that's necessary to reproduce a serious bug within a new System FW release. I would be happy to provide boiler plate programs to exercise the Photon in the spirit of a realistic customer application following a new System FW release. "},"comment":{"url":"https://api.github.com/repos/spark/firmware/issues/comments/170150346","html_url":"https://github.com/spark/firmware/issues/709#issuecomment-170150346","issue_url":"https://api.github.com/repos/spark/firmware/issues/709","id":170150346,"user":{"login":"pomplesiegel","id":1450352,"avatar_url":"https://avatars.githubusercontent.com/u/1450352?v=3","gravatar_id":"","url":"https://api.github.com/users/pomplesiegel","html_url":"https://github.com/pomplesiegel","followers_url":"https://api.github.com/users/pomplesiegel/followers","following_url":"https://api.github.com/users/pomplesiegel/following{/other_user}","gists_url":"https://api.github.com/users/pomplesiegel/gists{/gist_id}","starred_url":"https://api.github.com/users/pomplesiegel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pomplesiegel/subscriptions","organizations_url":"https://api.github.com/users/pomplesiegel/orgs","repos_url":"https://api.github.com/users/pomplesiegel/repos","events_url":"https://api.github.com/users/pomplesiegel/events{/privacy}","received_events_url":"https://api.github.com/users/pomplesiegel/received_events","type":"User","site_admin":false},"created_at":"2016-01-08T22:55:49Z","updated_at":"2016-01-08T22:55:49Z","body":"and @mohitbhoite, these are the exact symptoms I saw with 0.4.7, so that's what we're watching for here. Nice job. In the past, it was also reproducible at startup by pressing the \"reset\" button. "}}