この記事ははJLCPCBの提供でお送りします。
JLCPCBとは
jlcpcb.com (↑こちらは日本語版のログインページで、お得なクーポンも配布されています。)
JLCPCBとは、プリント基板製造などで有名な上海の企業です。
日本からでもWebページでポチポチするだけでKiCADなどで作成した基板データの製造を依頼できます。
値段もかなりお手頃で、ホビー電子工作ユーザーの間では広く利用されています。
この記事の作例もJLCPCBに基板を発注して実現しました。
前回までのあらすじ
以前作った基板を流用して CH32V003 で遊んでみることにしました。
CH32V003F4P6を自分ではんだ付けしてみる
前回の記事では、CH32V003の開発ボードを使ったため、CH32V003F4P6を直接はんだ付けすることはしませんでした。
しかし、この基板は開発ボードでも、ICを直接実装するでも、どちらでも動作するように作っていたので、今回は直接のはんだ付けを試してみました。
表面実装でピンの間は0.65mmでこれが10*2=20か所はんだ付けします。
うまくはんだ付けできるか心配でしたが、意外と簡単にはんだ付けできました。
過去の実績としてはATmega328が0.8㎜ピッチで32か所というのがありましたが、これと比べると今回のはんだ付けは簡単でした。
というのも、ATmega328はICの4辺すべてに足が出ているQFPと呼ばれるパッケージで、今回の物は2辺に足が出ているTSSOPと呼ばれるパッケージだったというのが大きいです。
分析するに、QFPの方はICの向きが少しずれるとどこかの辺のピンがパッドからずれてしまうのに対し、TSSOPの方はピンのある辺に水平にずれる分には問題ないというのが原因だと感じました。
ピッチは今回のICの方が細かかったですが、その点はあまり気になりませんでした。
温調付きのはんだごてと、フラックスがあれば比較的簡単だと思いますので、挑戦する方はこれらの機材をそろえると良いと思います。
最低限動作に必要な部品
改めて回路を見直してみると、このICは周辺の部品は、ほぼ何もなくても動くことがわかりました。 開発ボードには水晶発振子が付いていましたが、ICの内部にも発振機能があるようで、精度が多少悪くなりますがこちらを使うようにすれば、水晶発振子は不要でした。
いわゆる「おまじないコンデンサ」と言ったりするパスコン(バイパスコンデンサ)を一応1つ取り付けました。
書き込み
書き込みは開発ボードを使った時と同様にWCH-LinkEという専用の書き込み機を使いました。 ソフトウェアは前回の記事で紹介したch32v003funを利用しました。
専用書き込み機を使わずに書き換える方法
WCH-LinkEを使わないと書き換えられないのが少し気になって、調べてみると、WCH社が公式のサンプルとしてUART経由でプログラムを書き換えることが出来るサンプルプログラムを公開していることを知りました。
UARTを使って書き換えるといえば、よく知られている例だとArduino UNOなどの方式です。
この方式は、素朴ですが、ボード上にUSBシリアル変換ICを搭載することで、そのボード単体で開発が完結するという点で魅力的です。 (もちろん一番初めにこのプログラムを書き込むためにWCH-LinkEが必要なのですが、一度書き込んでしまえば以降はUARTで書き換えることが出来ます。)
さらに、このWCH社が提供しているサンプルの細かい問題点を解消したものを74thさんが作っているのを発見したので、今回はこちらを利用しました。
WCH-LinkEにはUSBシリアル変換の機能も搭載されているので、この書き換えの仕組みもWCH-LinkEで動作確認できました。また念のため手元にあったCH340G搭載のUSBシリアル変換モジュールを使っても書き換えが出来ました。
書き込みのためにはPC側で動作する書き込みソフトが必要となります。WCH社公式のWindows専用ツール、74thさん作のCLIツールの2つがありますがどちらでも書き込みできました。
RSTスイッチでリセットされない問題
74thさんが改良したプログラムでは以下の2つの変更が加わっていました
- UART通信の精度を上げるため書き込み速度を115200に低下させる
- 書き換えモードに入るためのピンをプルダウンし、ピンに何もつながっていないときは、実行モードとする
これで随分使いやすくなっていたのですが、74thさんのブログでも言及されているのですが、RSTスイッチの挙動が少し期待と異なるという問題が残っていました。
RSTスイッチは私の利用している開発ボードではタクトスイッチと接続されており、このスイッチを押すことでマイコンボードを「リセット」しプログラムをはじめから実行しなおすことができます。
UARTで書き込みを実現するプログラムは、起動時に特定のピンの状態を確認し、それがHIGHであれば書き込みモードに入り、LOWであれば実行モードに入るというロジックとなっています。
こういう書き込みロジックはESP32などでも採用されており、このようなボードにはBOOTスイッチとRESETスイッチが搭載されていることが一般的です。
BOOTスイッチを押しながらRESETスイッチを押すことで書き込みモードで起動し、BOOTスイッチを押さずにRESETスイッチを押すと、実行モードで起動するというのが期待する動作です。
もちろん手でスイッチを操作する以外にも、USBシリアル変換ICのDTRやRTSの信号をうまく使って、自動的に書き込みモードに入るというようなことも行われたりします。
さて、今回のUARTで書き込みを実現するプログラムを利用する際、このRSTスイッチはどのようにふるまうかというと・・
- 書き込みモードで起動中
- RSTスイッチを押すと、実行モードで起動する
- 書き込みピンをHIGHにしてRSTスイッチを押すと、書き込みモードで起動する
- 実行モードで起動中
- RSTスイッチを押すと、再び実行モードで起動する
- 書き込みピンをHIGHにしてRSTスイッチを押しても、再び実行モードで起動する(ここがおかしい!!)
実行モードで起動中に、書き込みピンをHIGHにしたときに、書き込みモードに移行せず、実行モードとなってしまうことが期待と違うと感じました。
この原因を調べるためにソースコードを見てみると、UARTで書き込みを実現するプログラムは以下のように実装されているようでした
- UARTで書き込みを実現するロジックはFlashメモリのBOOT領域に書き込まれている
- BOOT領域の処理の一番初めに書き込みピンの状態を確認するロジックがある
- ここでLOWが検出されると、User領域から実行するフラグを立ててソフトウェアリセットをする
- User領域を実行中にRSTスイッチによるリセットが起きても、User領域から再実行される
というような動きをしているようでした。(データシートで細かい裏付けをしているわけではなく、あくまで挙動から推測した動きです)
ということで、以下のような処理をUser領域に書くことで、User領域を実行中にRSTスイッチによりリセットされたときにBOOT領域の処理が実行されるようにしてみたところ、期待通りに実行モードで起動中にRSTスイッチを押した際に、書き込みモードで起動することが確認できました。
if(RCC->RSTSCKR & RCC_PINRSTF){ // リセットボタンを押されて起動した場合に真となる FLASH->BOOT_MODEKEYR = FLASH_KEY1; FLASH->BOOT_MODEKEYR = FLASH_KEY2; FLASH->STATR |= (1<<14); NVIC_SystemReset(); }
要は、UARTで書き込みする対象のプログラムに、おまじない的に、このロジックを入れておけば良いということです。
さて、今回はここまでの調査で打ち切りましたが、この先はUSBシリアル変換ICを搭載した基板を作ったり、RSTやDTRで自動プログラム機能を作りこんだ書き込み用のプログラムを作ったりすると、Arduinoっぽく書き込みできる仕組みが作れそうです。
そこまでしてUARTで書き込みしたい?
ここで調査を打ち切ったのは、CH32V003をどこまで頑張って使い倒すか?ということを考えたからです。
実はCH32VシリーズのCH32V203は、CH32V003よりは高いですが、その分スペックも良く、USB経由でのファームウェア書き込みもサポートしています。
ここまでCH32V003をArduino的に書き換える方法を探ってきましたが、そんなに頑張らなくともCH32V203を使えばよいのでは・・?という気がしてきました。
ということで、近いうちにCH32V203を購入して、その使い勝手を確かめてみることとします。
日本で買うなら RISC-V MCU CH32V203 ProMicro Like 開発ボードキット(¥1,500) [74th-034] - 74th Books & Gadgets - BOOTH、AliExpressでもいくつかの開発ボードを見つけることが出来ます。
まとめ
前回記事では、開発ボードを利用していましたが、ICを直接基板に実装する方法も試すことが出来ました。
これにより開発ボードに頼らずに、スタンドアローンなガジェットを作れるようになりました。
Arduino互換のSDKも整備されてきているようなので、次何か作る時の候補に入れておくことにします。