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

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

Revision:
0:d895cd1cd897
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/edge_utils/edge_reset_mgr.cpp	Tue Apr 03 08:30:29 2018 +0000
@@ -0,0 +1,145 @@
+#include "mbed.h"
+#include "edge_reset_mgr.h"
+
+/**
+  * System Reset Status Register 0 (RCM_SRS0) 0x4007_F000
+  *
+  * bit[7] : POR         Power-On Reset
+  * bit[6] : PIN         External Reset Pin
+  * bit[5] : WDOG        Watchdog
+  * bit[4] : (Reserved)
+  * bit[3] : LOL         Loss-of-Lock Reset
+  * bit[2] : LOC         Loss-of-Clock Reset
+  * bit[1] : LVD         Low-Voltage Detect Reset
+  * bit[0] : WAKEUP      Low Leakage Wakeup Reset
+  */
+#define REG_RCM_SRS0    (uint8_t *)0x4007F000
+#define POR_RESET_BIT   0x80
+#define PIN_RESET_BIT   0x40
+#define WDG_RESET_BIT   0x20
+#define LOL_RESET_BIT   0x08
+#define LOC_RESET_BIT   0x04
+#define LVD_RESET_BIT   0x02
+#define WUP_RESET_BIT   0x01
+
+  /**
+   * System Reset Status Register 1 (RCM_SRS1) 0x4007_F001
+   *
+   * bit[7:6] (Reserved)
+   * bit[5] : SACKERR     Stop Mode Acknowledge Error Reset
+   * bit[4] : (Reserved)
+   * bit[3] : MDM_AP      MDM-AP System Reset Request
+   * bit[2] : SW          Software Reset
+   * bit[1] : LOCKUP      Core Lockup
+   * bit[0] : (Reserved)
+   */
+#define REG_RCM_SRS1     (uint8_t *)0x4007F001
+#define SACK_RESET_BIT   0x20
+#define MDM_RESET_BIT    0x08
+#define SW_RESET_BIT     0x04
+#define LOCKUP_RESET_BIT 0x02
+
+#define IDX_POR_RESET    0
+#define IDX_PIN_RESET    1
+#define IDX_WDG_RESET    2
+#define IDX_LOL_RESET    3
+#define IDX_LOC_RESET    4
+#define IDX_LVD_RESET    5
+#define IDX_WUP_RESET    6
+#define IDX_SACK_RESET   7
+#define IDX_MDM_RESET    8
+#define IDX_SW_RESET     9
+#define IDX_LOCKUP_RESET 10 
+
+const char *reset_reason[] = {
+    "Power On Reset",
+    "Reset Pin Asserted",
+    "Watch Dog Reset",
+    "Loss of Lock Reset",
+    "Loss of Clock Reset",
+    "Low Voltage Detect Reset",
+    "Low Leakage Wakeup Reset",
+    "Stop Mode Acknowledge Error Reset",
+    "MDM-AP System Reset Request",
+    "Software Reset",
+    "Core Lockup Reset",
+    0
+} ;
+
+void print_reset_reason(void) 
+{
+    extern char *reset_reason_str ;
+    int idx = 0 ;
+    uint8_t *data = REG_RCM_SRS0 ;
+    if (*data & POR_RESET_BIT) {
+        idx = IDX_POR_RESET ;
+    }
+    if (*data & PIN_RESET_BIT) {
+        idx = IDX_PIN_RESET ; 
+    }
+    if (*data & WDG_RESET_BIT) {
+        idx = IDX_WDG_RESET ; 
+    }
+    if (*data & LOL_RESET_BIT) {
+        idx = IDX_LOL_RESET ;
+    }
+    if (*data & LVD_RESET_BIT) {
+        idx = IDX_LVD_RESET ;
+    }  
+    if (*data & LOC_RESET_BIT) {
+        idx = IDX_LOC_RESET ;
+    }
+    if (*data & WUP_RESET_BIT) {
+        idx = IDX_WUP_RESET ;
+    }
+    data = REG_RCM_SRS1 ;
+    if (*data & SACK_RESET_BIT) {
+        idx = IDX_SACK_RESET ;
+    }
+    if (*data & MDM_RESET_BIT) {
+        idx = IDX_MDM_RESET ;
+    }
+    if (*data & SW_RESET_BIT) {
+        idx = IDX_SW_RESET ;
+    }
+    if (*data & LOCKUP_RESET_BIT) {
+        idx = IDX_LOCKUP_RESET ;
+    }
+    printf("%s\n", reset_reason[idx]) ;
+    reset_reason_str = (char *)reset_reason[idx] ;
+}
+
+/**
+ * Software Reset
+ * 
+ * From Cortex-M0 Devices Generic User Guide
+ * 4.3.4 Application Interrupt and Reset Control Register
+ *
+ * Bit[31:16] : VECTCKEY
+ * Bit[15]    : ENDIANESS
+ * Bit[14:3]  : (Reserved)
+ * Bit[2]     : SYSRESETREQ
+ * Bit[1]     : VECTCLRACTIVE (reserved for debug use)
+ * Bit[0]     : (Reserved)
+ *
+ * Note: To trigger software reset, both VECTKEY=0x05FA and SYSRESETREQ
+ * must be written at once, therefore the value will be
+ * 0x05FA0004
+ */
+ 
+void software_reset(void)
+{
+     SCB->AIRCR = 0x05FA0004 ; 
+}
+
+/**
+ * reset_watch_dog
+ * reset the watch dog counter
+ * this function must be called within the limit (1sec)
+ */
+ 
+void reset_watch_dog(void) 
+{
+    SIM->SRVCOP = (uint32_t)0x55u;
+    SIM->SRVCOP = (uint32_t)0xAAu;
+}
\ No newline at end of file