espefuse.py をラズパイにインストール、実行する方法

ESP32(特に M5Stack Basic等) を使い始めて困るのが、以下のメッセージが表示されて起動できない状況に陥ることです。

```
rst:0x10 (RTCWDT_RTC_RESET),boot:0x37 (SPI_FAST_FLASH_BOOT)
flash read err, 988
ets_main.c 384
```

理由は以下の通りです。

> GPIO12（MTDI pin）にはFLASH電圧設定機能があり、起動時GPIO12がHになっていると、FLASH電源電圧が1.8Vに設定されてしまい正常に起動できない。
> 引用: [ESP32 ブート時のGPIO12によるFLASH電圧設定機能を無効化する / chakokuのブログ(rev4)](https://chakoku.hatenablog.com/entry/2020/01/25/234359)

- 同様の事が [[SOLVED] rst:0x10 (RTCWDT_RTC_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT) flash read err, 1000 - ESP32 Forum](https://www.esp32.com/viewtopic.php?t=9941) でも言及されています。

この症状を改善するには、FLASH電圧設定機能を無効化する(3.3Vに固定化)にすることです。この設定変更に使うのが `espefuse.py` です。
ただ、このツールを動かすためだけにインストールやらなにやらするのが面倒ということもあり、ラズパイでサクッと動かせないか？というのが、このエントリーの趣旨です。

- 他にはGNDが不十分であることが起因の場合もあるようですが、私は本件で安定化に成功しました。

## 論よりコード

Pythonの仮想環境 venv を使えばサクッとできます。

確認環境:

* Raspberry Pi 4 model B

```console:install
python3 -m venv esptool
cd esptool
source bin/activate
pip install esptool
```

これで以下のように `bin/espefuse.py` にインストールされます。

```
$ bin/espefuse.py | head -1
espefuse.py v3.2
```

### あとかたづけ

先にこの環境の削除方法をご案内。

```console
deactivate
cd ../
rm -rf esptool/
```


## `espefuse.py` を使う

M5Stackをラズパイに接続し、シリアルポートを確認します。

```console
$ dmesg | grep cp210x | grep tty
[3430001.666894] usb 1-1.4: cp210x converter now attached to ttyUSB0
```

M5Stackの現状を調査します。
`Flash voltage` が GPIO12 によって決まる状態であることが表示されています。

```console
$ bin/espefuse.py --port /dev/ttyUSB0 summary | grep VDD_SDIO
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)
Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).
```

Flash voltage を 3.3V に固定します。
途中 `BURN` と入力するように促されるので、従ってください。

**注意: M5Stackでは、FLASH電圧設定機能の設定を一度変更すると元に戻すことはできません。**
1.8V動作になると起動できなくなるので、むしろ変更することは無いと思いますので、気にしなくてよいとは思いますが念のため。
※ [espefuse.py のドキュメント](https://docs.espressif.com/projects/esptool/en/latest/esp32/espefuse/index.html#subsequent-changes) には `set_flash_voltage` を使えば変更できるとありますが、M5Stackではできませんでした。

```console
$ bin/espefuse.py --port /dev/ttyUSB0 set_flash_voltage 3.3V
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP32
espefuse.py v3.2

Enable internal flash voltage regulator (VDD_SDIO) to 3.3V.
The following efuses are burned: XPD_SDIO_FORCE, XPD_SDIO_REG, XPD_SDIO_TIEH.

VDD_SDIO setting complete.

Check all blocks for burn...
idx, BLOCK_NAME,          Conclusion
[00] BLOCK0               is not empty
        (written ): 0x0000000400100000000006350000a0000066246f288f413800000000
        (to write): 0x00000000000000000001c00000000000000000000000000000000000
        (coding scheme = NONE)
.
This is an irreversible operation!
Type 'BURN' (all capitals) to continue.
BURN
BURN BLOCK0  - OK (all write block bits are set)
Reading updated efuses...
```

M5Stackの現状を再度調査します。
`Flash voltage` が 3.3V に固定されています。

```console
$ bin/espefuse.py --port /dev/ttyUSB0 summary | grep VDD_SDIO
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)
Flash voltage (VDD_SDIO) set to 3.3V by efuse.
```

## あとがき

バッチリ動くようになりました。

### 参考資料

- [[SOLVED] rst:0x10 (RTCWDT_RTC_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT) flash read err, 1000 - ESP32 Forum](https://esp32.com/viewtopic.php?t=5344)
- https://chakoku.hatenablog.com/entry/2020/01/25/234359
- [ESP32 ブート時のGPIO12によるFLASH電圧設定機能を無効化する - chakokuのブログ(rev4)](https://chakoku.hatenablog.com/entry/2020/01/25/234359)
- [espressif/esptool: Espressif SoC serial bootloader utility](https://github.com/espressif/esptool)
- [Setting Flash Voltage (VDD_SDIO)](https://docs.espressif.com/projects/esptool/en/latest/esp32/espefuse/index.html#setting-flash-voltage-vdd-sdio)

参考にならなかったサイト

- https://teratail.com/questions/265352
    - 解決になってない。

EoT