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: main.cpp
- Revision:
- 0:d895cd1cd897
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Apr 03 08:30:29 2018 +0000 @@ -0,0 +1,130 @@ +#include "mbed.h" +#include "vt100.h" +#include "afLib.h" +#include "af_mgr.h" +#include "edge_mgr.h" +#include "edge_time.h" +#include "edge_reset_mgr.h" +/** + * afero poc1.5 25-Dec-2017 version + * from this version, watch dog timer joined again. + */ + +vt100 *tty = 0 ; +uint32_t wait_tolerance = 500 ; /* 5sec */ +uint32_t connect_tolerance = 60 ; /* after 60 trials, reboot */ +uint32_t wait_count = 0 ; +uint32_t connect_trial_count = 0 ; + +/** + * wait_connection + * When gConnected == false, which is connection is lost. + * Each 5sec check attribute ATTR_WIFI_STDY_STATE to see + * if the connection has recovered. + * Meantime even if connection is established communicated + * data is invalid, so AF_SYSTEM_ASR_STATE is also + * checked for gLinked ; + * And in case connect_tolerance trials failed + * try to reboot the system if it can improve the situation. + */ +void wait_connection(void) +{ + int result ; + wait_count++ ; + if (wait_count > wait_tolerance) { + reset_watch_dog() ; + if (gConnected == false) { + result = afero->getAttribute(ATTR_WIFI_STDY_STATE) ; + if (result != afSUCCESS) { + print_af_error(result) ; + } + } + if (gLinked == false) { + result = afero->getAttribute(AF_SYSTEM_ASR_STATE) ; + if (result != afSUCCESS) { + print_af_error(result) ; + } + } + connect_trial_count++ ; + if (connect_trial_count > connect_tolerance) { + reboot_edge() ; + } + wait_count = 0 ; + } +} + +void init_hardware(void) +{ + int i ; + int result ; + + reset_watch_dog() ; + init_display() ; + reset_watch_dog() ; + init_aflib() ; + reset_watch_dog() ; + init_sensors() ; + reset_watch_dog() ; + init_timer() ; + + while(true) { + reset_watch_dog() ; + for (i = 0 ; i < 10 ; i++ ) { + afero->loop() ; + reset_watch_dog() ; + } + if ((gLinked == true)&&(gConnected == true)) { + wait_count = 0 ; + connect_trial_count = 0 ; + if (afero->isIdle()) { + result = init_edge_attribute() ; + if (result == 0) { + break ; + } + } + } else { /* gLinked == false */ + wait_connection() ; + } + wait_ms(10) ; + } + do { +// while(!afero->isIdle()) { + reset_watch_dog() ; + for (i = 0 ; i < 10 ; i++ ) { + afero->loop() ; + wait_ms(100) ; + } + } while(!afero->isIdle()) ; + edge_mgr_status = EDGE_MGR_RUNNING ; +} + +// main() runs in its own thread in the OS +int main() { + static uint32_t count_robin = 0 ; + + tty = new vt100() ; +// tty->cls() ; + printf("Afero test program (ver. %s) started\n", __DATE__) ; + printf("=== Reset Reason ===\n") ; + print_reset_reason() ; + printf("====================\n") ; + + init_hardware() ; + + edge_splash() ; + + while (true) { + count_robin++ ; + afero->loop() ; + if ((gLinked == true)&&(gConnected == true)) { + wait_count = 0 ; + connect_trial_count = 0 ; + if (afero->isIdle()) { + edge_loop(count_robin) ; + } + } else { /* gLinked == false */ + wait_connection() ; + } + wait_ms(10) ; + } +}