ESP32をFT232HでJTAGデバッグする時にハマったこと

#JTAGデバッガーとは
ESP32で開発している方の多くはArduino IDEを使っているのではないでしょうか。
Arduino IDEではデバッグ時にコードの流れや変数の値を確認するのに、シリアルモニタに表示させるなどの方法をとるのが一般的ですよね。でも、ちょっとまどろっこしい。そこでJTAGデバッガーを使うと「変数の値をサクッと見る」「プログラムを一時的に止める」といったことができるようになります。

#本記事の内容
本来であればVisual Studio Codeをインストールして、PlatformIOをインストールして、FT232Hを用意して、などと書くと良いのでしょうがそのあたりは良く書かれた記事がいくつもありますので他の方に譲ります。この記事では私がハマったところだけを紹介します。(人はこれを単なる備忘録という)
ただ、他の方の記事の中には自分の環境となにかが違うのか、その通りにやっても上手くいかないケースがあります。この記事は「私の環境ではこのやり方で上手くいきました」という例として、参考にして頂ければと思います。

今回は以下の組合せでの環境を想定しています。
・ESP32ボード
・JTAGデバッガ- FT232H(今回はAdafruit製を利用 http://akizukidenshi.com/catalog/g/gM-08942)
・ESP-IDF
・Visual Studio Code
・PlatformIO(https://platformio.org)
・Mac

#ハマリポイント1 - MacとFTDI
JTAGデバッガーは各社からいろいろな製品が出ていますが、ESP32では今回紹介するFT232HやFT2232HといったFTDIチップを載せたものがよく使われます。FTDIといえば(USB端子の無い)Arduino Pro Miniなどにプログラムを書き込む際に使われるUSB-シリアル変換アダプタなどで聞き覚えのある方もいるかと思います。今回使うFT232HもUSB-シリアル変換アダプタの一種でちょっと高級版(?)といったところでしょうか。
ドライバもFTDIの標準ドライバを使うのですが、これがMacの場合にはいくつかの理由でハマリポイントの1つとなっています。

macOSは、OS X 10.11(El Capitan))からFTDI VCP(仮想シリアルポート)ドライバが標準でインストールされています。ですがFTDIのページにはドライバが用意されていますので普通に考えれば(良かれと思って)これをインストールしてしまうでしょう。するとドライバが二重に登録された状態になって問題が出ることがあります。

OS X macOS Mojave 10.14対応 FTDI VCPドライバをインストールする方法
https://low-energy.net/misc/osx-ftdi-vcp-driver/

ただし、上記は単純なUSB-シリアル変換の場合。FTDIのシリアルドライバには「VCPドライバ」と「D2XXドライバ」の2種類が存在します。FT232HをJTAGデバッガーとして使うには、VCPドライバではなくD2XX ドライバを使います。

D2XX Direct Drivers
https://www.ftdichip.com/Drivers/D2XX.htm

はい、ここからダウンロードしてインストールすればいいんです。それだけ。
しかし私はこのダウンロードページからリンクされているVideo Install Guideを見てしまったんです。それによるとD2xxHelperなるものもインストールせよ、と。しかーし、私の環境ではそれまで認識していたFT232Hが、D2xxHelperをインストールした途端に全く認識しない状況になってしまいました。結局、D2xxHelper関連のファイルをTerminalからチマチマ削除したり、D2XXドライバを再インストールしたりと面倒なことになりました。

参考(にしないで)
Video Install Guide
https://youtu.be/Ir2PVz1870E

##(追記
ここまでの説明はちょっと足りなかったので補足。
D2XXドライバをインストールしてもVCPドライバ(Apple製あるいはFTDI製)が有効になっているとそちらが優先されてしまいます。そこでVCPドライバを無効にする方法を紹介します。
Terminalから以下のコマンドを操作して、現在有効なFTDI VCPドライバを確認し、あればそれをアンロード(無効)する手順です。

```
user$ kextstat | grep FTDI
○○○.kext ← 有効なFTDI VCPドライバが表示される
user$ sudo kextunload ○○○.kext 
user$ kextstat | grep FTDI
user$ ← 何も表示されなければOK
```

#ハマリポイント1.5 - Catalina以降の場合
Catalina(macOS 10.15)以降ではkext(カーネルエクステンション)に代わり、dext(ドライバエクステンション)を利用するようになっています。「AppleUSBFTDI.kextとかいう名前だったのになあ、DriverKit-AppleUSBFTDI.dextってなんじゃろ?」とならないようにご注意ください。
なお、dextファイルはSystemフォルダ配下にいるため、基本的にリネームや削除が出来ないので注意が必要です。無効にする方法は同じように以下の通りになります。

```
user$ sudo kextunload /System/Library/DriverExtensions/com.apple.DriverKit-AppleUSBFTDI.dext
user$ kextstat | grep FTDI
user$ ← 何も表示されなければOK

有効にする場合
user$ sudo kextload /System/Library/DriverExtensions/com.apple.DriverKit-AppleUSBFTDI.dext
```

#ハマリポイント2 - EN(リセット)端子
FT232Hを使ったJTAGデバッグについては、(Windowsですが)こちらの記事が参考になります。

ESP32をPlatformIO上でJTAG(FT232H)デバッグする
https://lang-ship.com/blog/?p=453

まず結線については次の通りとなっています。

| FT232H |信号名| ESP32 |
|:---|:---|:---|
|D0 |TCK |GPIO13 |
|D1 |TDI |GPIO12 |
|D2 |TDO |GPIO15 |
|D3 |TMS |GPIO14 |
|C1 |nSRST |EN <- 接続不要|
|GND |GND |GND |

しかし、私の環境では書込みはできるもののデバッグ環境の起動中にエラーが出たりと安定しない。そこで後述する設定ファイルをいろいろと試すこと数時間…症状は変われど全く改善せず。
ふと思い立って試しにEN端子の接続を外してみたら、大正解。というわけで、上の表の通りEN端子は接続不要です。

#ハマリポイント3 - 設定ファイル
PlatformIOでは、OpenOCDベースのデバッガ環境が用意されています。今回は標準で提供されているFT2232H minimodule用の設定ファイル編集して使います。
「FT232H」「リセット端子未配線」の状態での設定ファイルの内容は以下の通り。

platformio.ini 

```
[env:esp32dev]
platform = espressif32
framework = espidf
board = esp32dev
debug_tool = minimodule
upload_port = minimodule
upload_protocol = minimodule
```

~/.platformio/packages/tool-openocd-esp32/share/openocd/scripts/interface/ftdi/minimodule.cfg

```
interface ftdi
ftdi_vid_pid 0x0403 0x6014
ftdi_layout_init 0x0008 0x000b
ftdi_layout_signal nSRST -data 0x0020 -oe 0x0020
```

##(追記
なお、minimodule.cfg内は「#」でコメントを記述できますが、行の途中から使うことは出来ません。途中で使うと設定が正常に反映されないので注意。

```
# comment ← 行頭から書き始めるコメントは有効。
interface ftdi
ftdi_vid_pid 0x0403 0x6014 # VID,PID ← 行の途中から#でコメントはNG。設定も反映されない。
```

#おわりに
そのうち同じようなことでまたハマりそうだわ、と思って備忘録として残したのですが雑すぎですね…(笑
私自身以外のどなたかお一人にでもお役に立てる事を願って。