前回、MicroPython制御のDMAコントローラもどきにSRAMモジュールを接続。一応、読み書き出来ているのですが、非常に不安定。その嫌疑はIOExpanderを接続しているI2Cバスにかかりました。I2C操作が失敗していることが多いみたいです。まずは信号品質のチェック?そして無理やりSRAMの初期化ができるところまで。
※「MicroPython的午睡」投稿順 Indexはこちら
※M5Stack Grayに書き込んだUIFlow2.0 (Alpha-27)対応のMicroPython処理系とWindowsパソコン上で動作しているThonny 4.0.1で動作確認しています。
I2Cバスの動作をオシロで確認
今回のI2Cバスは、M5Stack Gray内部で使われているI2Cバス(電圧3.3V)を外部に引き出してます。接続するのは2個のIOExpander MCP23017(電源5V)です。信号電圧が異なるので、3.3Vと5Vの変換部にNch. MOSFETを挿入し、そのゲートに3.3Vを加えてます。そしてMOSFETの両側に4.7kΩのプルアップ抵抗を挿入。当然M5Stack側は3.3V、IOExpander側は5Vにプルアップです。これにより5V側のハイ(5V)は3.3V側には伝わらないようになっているハズ。
電圧的にはこれで問題ないハズなのだけれども、I2Cバスの動作をオシロで観察してみると問題点が分かってきました。まずは低電圧(3.3V)側のI2Cバス動作の波形。黄色C1がSCLで、青色C2がSDAです。
上の例などは、問題なく動いているようなのですが、しらばく眺めている内に気づきました。
-
- 時々、ACKが認識されていないことがある。
- 結果、その後のシーケンスが打ち切られて途中で終わってしまっている。
前回のテスト用のMicroPythonコードでは、正常にACKが返ってくる前提で、まったくACKの確認をしてなかったです。手抜きだな~。このACKの取りこぼしに対処するために、I2Cバスを読み書きしたらACKを確認し、取りこぼしがあれば再度実行するようにしないと。
とりあえずHV側(5V)も波形を確認。3.3V側が動けば5V側もしっかり動作しているみたい。
SCL信号がだらだらと動作しつづけてます。暴走状態。これは正常なハンドシェークが出来ぬまま、次の処理をしようとしたときに起きてしまうみたい。このとき、MicroPython自体はソフトウエア的には正常に動作をつづけており、この現象を確認した場合にシェルに制御を戻したりもできます。しかし、ハードウエアI2Cの回路そのものが暴走してしまっているようで、M5Stack自体にRESETかけないと正常復帰できなかったです。むむむ。。。
暫定対策
とりあえずの対策は以下です。
-
- I2Cバス読み書き時ACKを確認(全部じゃないけど。)ACKが返ってこないときにはなるべくリトライする。
- SRAMに書き込めたように思っても、読み出すとエラーである場合もあったので、書き込み後必ずベリファイ・リードする。ベリファイできなかったらここでもリトライ。
- ハードI2Cの「暴走」現象への対処はRESETかけるしかないので、I2CをソフトウエアI2Cに変更する。ソフトI2Cは暴走することはないみたい。
なんだかな~、無理やり感ありだな。信号品質そのものについてはまったく向上なく、ソフトウエアでお茶を濁しています。
回路の変更
ハードI2CからソフトI2Cへの変更にともない、前回の回路のM5Stack接続部分は以下のように変更しました。
動作確認
0x0000番地から0x0FFF番地までの4096バイトにデータを書き込み、読み出してベリファイした結果が以下に。
4096バイトに書き込み成功(ベリファイも)、でもその過程で857回もリトライを繰り返しているみたい。トホホ。
まあ、M5StackからSRAMに主記憶イメージをロードできるようになったので、次回はSRAMにご本尊 8085 を接続してみるか? 無謀だな。