マイコンに書き込むには、たいてい専用のライターをつなぐ。WCHのCH32V003は、そのデータ線が1本しかない。電源とグランドを別にすれば、やりとりはSWIOと呼ぶ1本の線だけで済む。送りと受けを同じ線でやる以上、タイミングがずれれば何も読めない。Ishu1519氏は手元のESP32-S3をそのライターに仕立て、チップの検出からフラッシュの書き込み、読み戻しの照合、リセットまでを実機で通した。ソースコードと配線図はMITライセンスでGitHubに置いてある。
配線は単純だ。ESP32-S3のGPIO10とCH32V003の7番ピン(PD1/SWIO)を1本でつなぎ、3.3Vのプルアップを入れる。電源とグランドもESP32-S3側から供給する。PCからはUSBシリアルでつなぎ、Pythonで書いたホストツールにバイナリと書き込み先アドレスを渡すと、チップの確認から書き込み、照合、書いたプログラムの起動までを1回のコマンドでこなす。手作業で確かめたいときのために、シリアル経由の対話コマンドも用意してある。
SWIOの信号はESP32-S3のコアでビットバンギング、つまりソフトウェアからピンを直接叩いて作る。専用の周辺回路を使わないぶん、待ち時間はCPUのサイクル数で数える。Ishu1519氏は遅延関数の実測値を約48サイクルとして書き込んでいる。その上でRISC-Vのデバッグ用インターフェースを操り、チップIDを読んで対象を確かめる。フラッシュは3段階のキーで解除し、64バイトのページ単位で消去して書き込み、そのつど読み戻して照合する。
つまずいた場所も本人が書き残している。最初はデバッグ用のレジスターが0xFFFFFFFFしか返さず、SWIOの立ち上げ手順とタイミング、それに物理的な配線が合うまでこの状態が続いた。次は逆の症状で、書き込みも照合も通り、CH32V003自体は動いているのにモーターが回らない。原因はモータードライバーCP6208の2つ目の入力がHighのままだったことで、グランドへ落とすと回り出した。
土台にしたのは、CNLohr氏のch32v003funとBlueSyncLine氏によるSWIOの実装だ。リポジトリにはESP32-S3側のファームウェアのほか、CH32V003で動かすLチカのサンプル、配線とピン割り当ての表、シリアルコマンドの仕様書が入っている。Ishu1519氏は、この方式をほかのESP32や、同じSWIOを使うCH32V00xシリーズへ移せるかに関心を示している。書き込み用の道具を買い足さずにCH32V003を試したい人には、手持ちのボードで始める足がかりになるだろう。