ESP32のIO12ピンに何かつなぐと書き込めなくなる

# 背景
ESP32に書き込もうとするとエラーが出て書き込めない。ディスプレイ1つを引っこ抜くと動く。
原因はIO12ピンにSPIのCSピンをつないでいたこと。

調べると様々な解決策があり、体系的にまとめた記事がなかったため、執筆



解決策をサクッと見たかったら [こちら、espefuse.pyで、IO12ピンの設定を変える](#espefusepyでio12ピンの設定を変える)

# エラー内容
エラーの出方が様々でデバッグに難航したが、原因はIO12ピンにSPIのCSピンをつないでいたこと。
A fatal error occurred: MD5 of file does not match data in flash!
A fatal error occurred: Packet content transfer stopped (received 8 bytes)

# 環境
- platformio
- windows11
- ESP32+display2個+mp3プレイヤー+加速度センサ
- ピンアサイン的にどうしてもCSピンをIO12から動かせない状況
# 試したこと
## 書きこめた
### espefuse.pyで、IO12ピンの設定を変える
1. ESP32をPCにつなぎ、デバイスマネージャーでCOM何ポートとして認識されているかを確認します。

2. [espressiffのesptoolリポジトリ](https://github.com/espressif/esptool/releases)から、esptool-v4.7.0-win64.zipをダウンロードして展開します。（バージョンは適宜変更してください）

3. powershellやgit bashなどで展開したディレクトリまで移動し、以下を実行してESP32のポートを指定します。
    ```
     .\espefuse --port COM10 summary
    ```
    すると表示された文章の一番下に<code>Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V)</code>の表記が見られるので、これを変更します。


4. 続いて以下のコマンドで電圧の設定を行います。
    ```
    .\espefuse --port COM10 set_flash_voltage 3.3V
    ```
    `This is an irreversible operation!Type 'BURN' (all capitals) to continue.`と聞かれるので`BURN`も入力しましょう

5. もう一度`.\espefuse --port COM10 summary`を実行して、`Flash voltage (VDD_SDIO) set to 3.3V by efuse.`が出ていれば変更完了です。書き込めると思います。

###  解説
[esp-idfのgithubのNote about GPIO12 (ESP32 only)](https://github.com/espressif/esp-idf/blob/master/examples/storage/sd_card/sdmmc/README.md#note-about-gpio12-esp32-only)を読むと、IO12ピンは、フラッシュチップへの供給電圧(VDD_SDIO)を決めるのに使われていて、LOWなら電圧が3.3V、HIGHなら電圧が1.8Vに決まります。どこにもつながっていないときは、プルダウン抵抗でLOWに落とされ、ESP32に3.3Vが供給されます。しかし、IO12が何処かにつながって、HIGHになっているときは、電源電圧が1.8Vとなるため、フラッシュチップが起動せず書き込みができない状態となるようです。今回実行したコマンド`.\espefuse --port COM10 set_flash_voltage 3.3V`で、IO12の状態に関わらず、フラッシュチップへの供給電源電圧3.3Vに設定すると、無事電源が供給されて書き込めるようになる、ということでした。

供給電圧が1.8VのときはビルトインBASICモードに入るようです。イースターエッグ機能らしい。
[BASIC INTERPRETER HIDDEN IN ESP32 SILICON](https://hackaday.com/2016/10/27/basic-interpreter-hidden-in-esp32-silicon/)
[Easter Egg of ESP32](https://macsbug.wordpress.com/2017/01/04/easter-egg-of-esp-32/)
[ESP32を始めてみる BASIC編](https://ken5owata.hatenablog.com/entry/2017/02/07/005254)

    
### 参考記事
- 色々調べてようやくここまでたどり着いたが、この問題で苦戦してる人は結構いそう）
    - [ESP32 ブート時のGPIO12によるFLASH電圧設定機能を無効化する](https://chakoku.hatenablog.com/entry/2020/01/25/234359)
    - [ESP32でHSPIを使っていると初期化を繰り返すことがある問題](https://qiita.com/nichicon/items/43cc870701383fd14d53)

### その他の解決策
- ピンアサインを変える（今回はこの方法が使えないが、一旦別に変えてみて動作確認できた）
- IO12ピンにつながっているディスプレイを書き込み時に抜いてもう一度差す

## 書き込めなかった
- ESP32マイコンを変える→うまく書き込めてしまう個体もあり、不安定
- A fatal error occurred: MD5 of file does not match data in flash!でググってみた
    - [M5STACKやESP32ボードで発生する a fatal error occurred:MD5 の修復方法](https://massa4649.com/m5stack-md5-fatal-error/)を参考にフラッシュを初期化してみる
    - [A fatal error occurred: MD5 of file does not match data in flash! でエラーになりesp32に書き込みができない](https://qiita.com/afkfkl/questions/f52798632bb4ab16cb88)を参考にFWアップロードスピードを遅くする
    - [ESP32 ( ESP-WROOM-32 , M5Stack )自分的 トラブルシューティング まとめ](https://www.mgo-tec.com/blog-entry-trouble-shooting-esp32-wroom.html/6)の３８．A fatal error occurred: MD5 of file does not match data in flash! というエラーが出る(Arduino core ESP32 でコンパイル書き込み時)を参考に、ディスプレイの設定をVSPIからHSPIに変えてみる
- ENピンとGNDピンの間に0.1μF入れる