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) 反転させることにより、疑似リセットクロックを生成します。

その後は、通常の起動手順に復帰し、以降はこれまでと同様の動作をします。

main.cpp

Committer:
Rhyme
Date:
2018-04-03
Revision:
0:d895cd1cd897

File content as of revision 0:d895cd1cd897:

#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) ;
    }
}