ESP32でGPIO12を使うとFatal Errorになったが解決

published_with_changes 更新日: event_note 公開日:

labelESP32 labelMemo/Note

概要

ESP32でスケッチの書き込み中に突然、"A fatal error occurred: MD5 of file does not match data in flash!"というエラーが出て、全く書き込みできなくなりました。

  • 【対策1.】原因はGPIO12の使用です。GPIO12をどこにも繋がない(OPEN)だとERRORになりません。
  • 【対策2.】ERRORになる書き込み中はGPIO12を繋がないでおき、書き込み後に接続すると使えます。ただし、繋いだままだとESP32の起動ができません。起動時とか、Reboot時は接続を切ってOPENにする必要があります。
  • 【対策3.】espefuse.pyというesptool.pyのコマンドを使って、ESP32を書き換えるとGPIO12を使っても、問題なく起動/Rebootやスケッチの書き込みができます。ただし、書き換えを元には戻せません。


問題発生と対策1、2まで

D1 MINI ESP32を使っています。
今まで、GPIO12はHSPI用に使っていました。AD9833のMISO用としてスケッチ上では指定していましたが、実際は未使用でどこにも未接続でした。

新たなGPIOが必要になったので、未使用のGPIO12に目をつけた次第です。

スケッチを書いてコンパイルまでは問題なく通ったのですが、書き込みが100%と表示された途端に、"A fatal error occurred: MD5 of file does not match data in flash!"というERRORが出ます。

最初はGPIOとの因果関係を推測できず、ネットで情報を探したところ、ひたすら書き込みを繰り返すと書き込めたとか、書き込み速度を遅くすると直ったとかの事例がありましたので、試してみたのですが、残念ながら私のケースではうまくいきませんでした。

右往左往しているうちにネット情報のなかで、”ESP32 ( ESP-WROOM-32 , M5Stack )自分的 トラブルシューティング まとめ”という記事に同じエラー事例を見つけました。ここで、原因がGPIO12にありそうとの情報を得ることができたという経緯になります。

私のケースでもこれがピタリ当てはまり、GPIO12を使わないとOK、書き込みのとき接続を外しておくとOKという現象も同じでした。

対策3

問題は、GPIO12が繋がったままだとESP32を起動できないという点です。ブレッドボード上で試しているときはその都度対応すれば良いのですが、回路をケースに収める段階になったらこれでは何ともならず、対応策を調べました。

上記の記事が引用しているGitHubの情報によると、原因はGPIO12の仕様によるもので、自己解釈すると次のようになります。実測したGPIO12の出力電圧は情報と同じく、起動時1.8V、通常3.3Vでした。
  • GPIO12は、FLASHチップ(VDD_SDIO)へ電力供給する内部レギュレータの出力電圧を決めている。
  • デフォルトは3.3V(High)だが、起動時は1.8V(Low)である。
  • 起動時にLowだと、ESP32は起動できない。
  • 接続する相手によってVDD_SDIOはHigh/Lowが必要になるが、もし、Lowが要らない場合はHighだけに書き換えできる次のプログラムがある。(permanently enabled at 3.3Vと書いているので、たぶん元には戻せない。)
        components / esptool_py / esptool / espefuse.py set_flash_voltage 3.3V

ということなので、VDD_SDIOの書き換えに挑戦してみます。espefuse.pyはPython上で動くesptool.pyというツールプログラムのコマンドです。

windows10環境でのespefuse.pyの導入手順

  1. Pythonのインストール
  2. esptool.pyのインストール
  3. espefuse.pyでのVDD_SDIO書き換え

1.Pythonのインストール

Pythonインストール(Win10)編”に倣ってインストールしました。
注意点はインストール最初のポップアップで、インストールフォルダをメモすることと、pathのチェックを入れることです。

2.esptool.pyのインストール

ESP32でesptool.pyの使い方”に倣ってインストールしました。Python環境でのインストールになります。
Windowsのコマンドプロンプトか、Widows PowerShellからインストールコマンドを実行します。
PS C:\WINDOWS\system32> Python -V              // 確認のため
Python 3.10.1                                  // バージョンが表示されればOK
PS C:\WINDOWS\system32> pip install esptool    // esptoolをインストール
Collecting esptool
  Downloading esptool-3.2.tar.gz (206 kB)
     |████████████████████████████████| 206 kB 6.4 MB/s
<< 省略 >>
Successfully installed bitstring-3.1.9 cffi-1.15.0 cryptography-36.0.0 ecdsa-0.17.0 esptool-3.2 pycparser-2.21 pyserial-3.5 reedsolo-1.5.4 six-1.16.0
WARNING: You are using pip version 21.2.4; however, version 21.3.1 is available.
You should consider upgrading via the 'C:\Users\UserName\AppData\Local\Programs\Python\Python310\python.exe -m pip install --upgrade pip' command.
PS C:\WINDOWS\system32>

3.espefuse.pyでのVDD_SDIO書き換え

Pythonのインストール時に忘れずにpathに✓を入れましたので、C:\WINDOWS\system32>ディレクトリから espefuse.py が実行できます。もしできない場合は、Windowsのシステムからパスを通しに行くか、メモしたインストールフォルダへ移動して、espefuse.py を実行します。

-p はシリアルポートを指定するオプションです。Windowsの場合 -p COM1などと指定します。

念のために変更前の状態を確認しました。XPD_XXXのフューズ類は0であることと、最後の行のFlash voltage (VDD_SDIO)の値を見ておくようです。High for 1.8V, Low/NC for 3.3Vでした。
PS C:\WINDOWS\system32> espefuse.py -p COM13 adc_info  // ESP32はシリアルポートCOM13に接続
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP32
espefuse.py v3.2
ADC VRef calibration: 1093mV
PS C:\WINDOWS\system32> espefuse.py -p COM13 summary  // 変更前の状態を確認
Connecting......

<< 省略 >>

XPD_SDIO_FORCE (BLOCK0):                           Ignore MTDI pin (GPIO12) for VDD_SDIO on reset     = False R/W (0b0)
XPD_SDIO_REG (BLOCK0):                             If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset    = False R/W (0b0)
XPD_SDIO_TIEH (BLOCK0):                            If XPD_SDIO_FORCE & XPD_SDIO_REG                   = 1.8V R/W (0b0)

<< 省略 >>

Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).
PS C:\WINDOWS\system32>
続いて、FLASHへの供給電源の電圧を3.3Vに固定します。途中で、’BURN’と入力を求められるのでその通りにします。
PS C:\WINDOWS\system32> espefuse.py -p COM13 set_flash_voltage 3.3V // 供給電源の電圧を3.3Vに固定
Connecting.....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting..........

<< 省略 >>

This is an irreversible operation!
Type 'BURN' (all capitals) to continue.
BURN
BURN BLOCK0  - OK (all write block bits are set)
Reading updated efuses...
PS C:\WINDOWS\system32>

最後に再び状態を確認してみます。XPD_XXXのフューズ類が1に変わっており、最終行もFlash voltage (VDD_SDIO) set to 3.3V by efuse と変わりました。変更が成功したということになります。
PS C:\WINDOWS\system32> espefuse.py -p COM13 summary // 変更後の状態確認
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting......

<< 省略 >>

XPD_SDIO_FORCE (BLOCK0):                           Ignore MTDI pin (GPIO12) for VDD_SDIO on reset     = True R/W (0b1)
XPD_SDIO_REG (BLOCK0):                             If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset    = True R/W (0b1)
XPD_SDIO_TIEH (BLOCK0):                            If XPD_SDIO_FORCE & XPD_SDIO_REG                   = 3.3V R/W (0b1)

<< 省略 >>

Flash voltage (VDD_SDIO) set to 3.3V by efuse.
PS C:\WINDOWS\system32>

GPIO12のVDD_SDIO書き換えを行ったESP32は、GPIO12への接続をした状態で起動/Rebootができること、スケッチのコンパイルと書き込みができることを確認しました。

Powered by Blogger | Designed by QooQ

keyboard_double_arrow_down

keyboard_double_arrow_down