MicroPython的午睡(142)M5Stack、SoftI2Cで無理やりSRAM初期化

Joseph Halfmoon

前回、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です。LV_I2Cwave

上の例などは、問題なく動いているようなのですが、しらばく眺めている内に気づきました。

    • 時々、ACKが認識されていないことがある。
    • 結果、その後のシーケンスが打ち切られて途中で終わってしまっている。

前回のテスト用のMicroPythonコードでは、正常にACKが返ってくる前提で、まったくACKの確認をしてなかったです。手抜きだな~。このACKの取りこぼしに対処するために、I2Cバスを読み書きしたらACKを確認し、取りこぼしがあれば再度実行するようにしないと。

とりあえずHV側(5V)も波形を確認。3.3V側が動けば5V側もしっかり動作しているみたい。HV_I2Cwave

ただね、一番の問題はこれです。IOEX_Hang

SCL信号がだらだらと動作しつづけてます。暴走状態。これは正常なハンドシェークが出来ぬまま、次の処理をしようとしたときに起きてしまうみたい。このとき、MicroPython自体はソフトウエア的には正常に動作をつづけており、この現象を確認した場合にシェルに制御を戻したりもできます。しかし、ハードウエアI2Cの回路そのものが暴走してしまっているようで、M5Stack自体にRESETかけないと正常復帰できなかったです。むむむ。。。

暫定対策

とりあえずの対策は以下です。

    1. I2Cバス読み書き時ACKを確認(全部じゃないけど。)ACKが返ってこないときにはなるべくリトライする。
    2. SRAMに書き込めたように思っても、読み出すとエラーである場合もあったので、書き込み後必ずベリファイ・リードする。ベリファイできなかったらここでもリトライ。
    3. ハードI2Cの「暴走」現象への対処はRESETかけるしかないので、I2CをソフトウエアI2Cに変更する。ソフトI2Cは暴走することはないみたい。

なんだかな~、無理やり感ありだな。信号品質そのものについてはまったく向上なく、ソフトウエアでお茶を濁しています。

回路の変更

ハードI2CからソフトI2Cへの変更にともない、前回の回路のM5Stack接続部分は以下のように変更しました。SOFTI2Connection

動作確認

0x0000番地から0x0FFF番地までの4096バイトにデータを書き込み、読み出してベリファイした結果が以下に。SOFTI2Cresults

4096バイトに書き込み成功(ベリファイも)、でもその過程で857回もリトライを繰り返しているみたい。トホホ。

まあ、M5StackからSRAMに主記憶イメージをロードできるようになったので、次回はSRAMにご本尊 8085 を接続してみるか? 無謀だな。

MicroPython的午睡(141)M5Stack、SRAMモジュール読み書き、ダメダメよ へ戻る

MicroPython的午睡(143)RPi PicoでM5Stackを挿げ替える へ進む