I2C hang recover function added
Dependencies: UniGraphic mbed vt100
In this version, check_i2c_pins function was added in edge_mgr.cpp.
プログラムの起動時、I2Cモジュールを初期化する前に、I2Cに使用するピンの電位を確認し
もし一方でも Low に張り付いていた場合、SCL を GPIO 出力に設定して
所定回数 (I2C_UNLOCK_TRIAL_CYCLE) 反転させることにより、疑似リセットクロックを生成します。
その後は、通常の起動手順に復帰し、以降はこれまでと同様の動作をします。
Diff: edge_utils/edge_mgr.cpp
- Revision:
- 1:1af1fd910340
- Parent:
- 0:d895cd1cd897
--- a/edge_utils/edge_mgr.cpp Tue Apr 03 08:30:29 2018 +0000 +++ b/edge_utils/edge_mgr.cpp Fri Apr 06 04:17:34 2018 +0000 @@ -322,7 +322,7 @@ */ #define I2C_UNLOCK_TRIAL_CYCLE 50 -void check_i2c_pins(PinName sda_pin, PinName scl_pin) +void check_i2c_pins(PinName sda_pin, PinName scl_pin, int number) { DigitalIn *sda_in = 0 ; DigitalIn *scl_in = 0 ; @@ -330,8 +330,9 @@ int count = 0 ; sda_in = new DigitalIn(sda_pin, PullUp) ; scl_in = new DigitalIn(scl_pin, PullUp) ; + printf("I2C%d pin ", number) ; if ((*sda_in == 0) || (*scl_in == 0)) { /* bus hang! */ - printf("I2C pin hang detected, trying to clear\n") ; + printf("hang detected, trying to clear ... ") ; delete scl_in ; scl_in = 0 ; scl_out = new DigitalOut(scl_pin) ; @@ -341,8 +342,13 @@ *scl_out = 1 ; wait(0.01) ; } + if (*sda_in != 0) { + printf("Cleared!\n") ; + } else { + printf("Failed to Clear, proceeding\n") ; + } } else { - printf("I2C pin condition OK\n") ; + printf("condition OK\n") ; } if (sda_in) { delete sda_in ; } if (scl_in) { delete scl_in ; } @@ -352,10 +358,10 @@ void init_sensors(void) { printf("=== Initializing Sensor(s) ===\n") ; - check_i2c_pins(PIN_I2C0_SDA, PIN_I2C0_SCL) ; + check_i2c_pins(PIN_I2C0_SDA, PIN_I2C0_SCL, 0) ; edge_i2c0 = new I2C(PIN_I2C0_SDA, PIN_I2C0_SCL) ; - check_i2c_pins(PIN_I2C1_SDA, PIN_I2C1_SCL) ; + check_i2c_pins(PIN_I2C1_SDA, PIN_I2C1_SCL, 1) ; edge_i2c1 = new I2C(PIN_I2C1_SDA, PIN_I2C1_SCL) ; if (display) {