MSC-MOD20 > SDモジュール ソフト > v0.7 > SD_Init()まで > 1回目のSD_Init()が失敗する

```txt:動作確認
ESP8266 (気圧計で使用したユニバーサル基板: I2Cを4.7kでプルアップ)
SDモジュール: MSC-MOD20 ( http://www.microtechnica-shop.jp/shopdetail/000000000026/ )
Analog Discovery 2 (以下AD2)
```

http://qiita.com/7of9/items/1a4ceb8d32ddff8a6070
の続き。

MSC-MOD20の癖を見つける。

## code v0.7

[v0.7 @ github](https://github.com/yasokada/esp8266_160730_MSC-MOD20p1/releases/tag/v0.7)

v0.2以降の主な変更

- I2C処理を別ファイル化
  - 他のマイコン対応を考慮
- MSC-MOD20関連の処理を別ファイル化
  - ソースのメンテ性を高める
- SD_Init()を追加

メイン処理は以下となった。

```c:esp8266_160730_MSC-MOD20p1.ino
#include <Wire.h>
#include "esp8266_160730_i2cWrapper.h"

/*
 * v0.7 2016 Jul. 30
 *   - MSCMOD20lib: add MSCMOD_InitSD()
 *   - MSCMOD20lib: add receiveAck()
 * v0.6 2016 Jul. 30
 *   - separate MSC-MOD20 functions to external file
 * v0.5 2016 Jul. 30
 *   - separate i2c setup/read/write to external file
 *   - rename readData() to readCode()
 *   - readData() takes adr param
 * v0.4 2016 Jul. 30
 *   - rename helloWorld() to checkWithAck()
 *   - add sendData()
 *   - rename readAck() to readReply()
 *   - readAck() returns bool type
 * v0.3 2016 Jul. 30
 *   - add readAck()
 *   - add isData()
 *   - readData() returns char type
 *   - add readBootBanner()
 * v0.2 2016 Jul. 30
 *   - fix bug > Device Address was not 7 bit 
 * v0.1 2016 Jul. 30
 *   - add readData()
 *   - add helloWorld()
 *   - add loop()
 *   - add setup()
 */

void setup() {
  Serial.begin(115200);
  Serial.println("");

  i2c_setup();
  char rcvstr[100] = { 0 };
  MSCMOD_ReadBootBanner(/*rcvmaxlen=*/100, rcvstr);
  if (strlen(rcvstr) > 0) {
    Serial.print(rcvstr);
  }
}

void loop() {  

  if (MSCMOD_InitSD(/* dstPtr=*/NULL)) {
    Serial.println("init SD: OK");
  } else {
    Serial.println("init SD: NG");    
  }
  
//  char rcvstr[5] = { 0 };
//  if (MSCMOD_CheckWithAck(rcvstr)) {
//    Serial.print(rcvstr);
//  } else {
//    Serial.println("ACK NG");
//  }
  
  delay(3000); // msec
}
```

## 結果

```txt:結果
 GHI Electronics, LLC 
----------------------
 ALFAT SoC Processor 
!00
init SD: NG
init SD: OK
init SD: OK
init SD: OK
```

Power on boot直後のSD Initが必ず失敗する。

癖なのか、仕様なのか。取説をもっと読む必要がある。

MSC-MOD20の起動時のメッセージ文字列があることで、Power on boot直後のSD Init()のI2C波形をとるのが難しい。
追加のI/Oピンを使ってrising edgeを発生させ、それをトリガしないといけないだろうか。


## AD2で測定してみた

> 追加のI/Oピンを使ってrising edgeを発生させ、それをトリガしないといけないだろうか。

とりあえずやってみた。

### Power on boot後、1回目の波形

コマンドに対する応答がない。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b8cd90b4-b28e-bd5c-acab-8c240104b98f.png)

### Power on boot後、2回目以降の波形

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/50354bc5-78fb-f8c7-64e9-5e29667b0140.png)

### 備考

取説上でこの旨の記載は見つかっていない。

Power on boot直後に別コマンド(`<LF>`)を送っても状況は変わらず。
上記の「1回目」と同じタイミングで`<LF>`を送信した時には応答がある。SD Initコマンド自体の癖かもしれない。


## 失敗の状況
(追記 2016/07/31)

### 回数について

- setup()内で3回連続SD_Init()すると3回ともNGとなった
  - 1回目だけの問題ではないようだ
- 上記に関して、3回の実施前に3秒の待ち、を入れた
  - 待ちを入れても3回ともNGとなった
  - Power on bootからの経過時間だけの問題でもないようだ
 
I2CBUSYピンを使うのがいいのかもしれない。

### 関連forum
(追記 2016/07/31)

以下においてもI2Cでの初期化処理(Iコマンド)にて応答がないという例がある。
https://www.ghielectronics.com/community/forum/topic?id=12544

serial interfaceでは問題なく、I2Cでは問題がある、というのもこちらの状況に似ている。

### I2C BUSY信号について
(追記 2016/08/02)

I2C BUSY(ピン2)がHレベルの時にはMSC-MOD20にコマンドを送信してはいけない。

SD_Init()に関して、I2C BUSYが関係するか見てみた。

以下は失敗している時。I2C BUSYにはなっていない。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/fd4b486e-af1b-1c62-475d-07c9c945a453.png)

以下は成功している時。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/fc5da865-9395-2f21-ee85-9a276b6a931a.png)

I2C BUSYは関係ないようだ。

### 他のコマンド
(追記 2016/08/02)

Vコマンドをsetup()内で3回連続実行してもすべて成功した。

https://www.ghielectronics.com/community/forum/topic?id=12544
> Does I2C work with V command? Repeated?

It worked.

## とりあえずの対応
(追記 2016/08/02)

setup()内で以下のような処理とした。

```
Test_SDInit();
delay(200); // msec // not worked with 20, 50, 100 msec
Test_SDInit();
delay(200); // msec
Test_SDInit();
delay(200); // msec  
```

上記の場合、2回目以降のTest_SDInit()は成功する。

実装方法としては以下で対応することになりそうだ。

- SDInit()を1回実行する
- 200msec待つ
- SDInit()を再度実行する

200msecも待つのは無駄に感じるが仕方がない。

## ツールでの確認
(追記 2016/08/06)

UARTの送受信タイミングを計るツールを作って測定してみた。
http://qiita.com/7of9/items/c018b2fa3e3a62f8c556

UART通信で確認したところ、だいたい150msec程度で応答がある。3回の実行で起動直後だけ特殊かというと、そうでもないような気がする。

I2Cの応答処理に癖があるようだ。UALFATの時もこういう点があったので同じようなものだろう。