CH32V003J4M6 PD1 SWIO ピン共用問題 シリアル出力の実装とFlash eraseでの解決方法

RISC-Vコア CH32V003J4M6というSOP8パッケージの8pin品でのUART事情とその改善策の紹介です。

J4M6の8ピンパッケージは、PD1/PD4/PD5とUTXとSWIOが共通ピンです。

で、シリアル出力のデフォルト はUTXピンなので、UARTのシリアル出力を無計画にプログラムしてしまうと、次回からの再書き込みができなくなります。

こんなんエラーが出てボード認識できなくなります。

書き込みのみで、そのまま製品に実装するのなら、次回の書き換えはしないだろうからよいのですが、ファームの開発中となるといろいろ問題です。

ピンが共用されているもんだから、WriterがFlashを消去しようとSWDIOで通信をしようとしても、CH32V003側が他のピンで既に動作してしまっている場合、SWDIOでの通信がもうできなくなっているという状況です。

同じ事象を以下のサイトでも紹介されています。

8PinのRISC-VマイコンCH32V003J4M6にプログラムを書き込めなくなった時の一手段

小ピンマイコンの酷暑(1) CH32V003、8ピンマイコンからのHelloWorld

EEVblog Electronics Community Forum

SWIOピンからシリアル出力が割り当てられてしまっているので、チップとの通信ができなくなってしまっているので以後のFlash消去や再書き込みができないという訳ですね。

これは、UARTなどのシリアルの通信を実装する場合のファーム開発中の作業性に問題になったり、最終製品にはUARTは実装しないが、ファームの開発中にデバッグ用のモニターとしてシリアル出力でターミナルソフトに表示させたいなどの場合に問題になります。

もう、再起込みできなくなってしまったと途方に暮れるのではなく、以下の手法で再度書き込みができるようになります。

まず、プログラムの書き換え手段として2案を紹介します。

その1.Flashを強制消去をしてしまえば再書き込みができます。

前述のリンクでも紹介されていますが、WCH-LinkUtilityでプログラムを全消去してから再度プログラムを書き込むことで再書き込みできるようになります。

WCH-LinkUtility → Target → Clear All Code Flash-By Power off

ですが、書き換えるたびに消去を別のユーティリティソフトで実施するのは、手間だなという面倒くさがり屋さんには、次の手段があります。

その2.プログラムの先頭にdelayを挿入

たとえば、Arduino環境であれば、setupに非Arduino環境であれば、mainの冒頭にdelay(xxx);を設置し、起動直後5秒程度の”待ち”をいれます。

で、書き込み時(例えば、書き込みボタンの押下のタイミング)に電源を入れなおして再起動させます。この5秒の待ち時間の間でFlash eraceができればOkです。reset端子があればいいのですが、CH32V003J4M6の8ピン品には、リセット端子が無くPower on resetのみなので、書き込みのタイミングと電源入れ直しにコツが要ります。

書き込み治具の基板にモーメンタリーのB接点かC接点のプッシュスイッチを付けて書き込みボタンの押下と同時に電源OFF→ONしてあげdelayの待ち時間中にFlashの書き込みが開始でればOKです。

Flashなので多分ですが、その1.も、その2.も手続きは同じことをやっているだと思いますが、好きな方で実装すればよいかも思います。

まぁ、趣味の範囲なので、何とかやりますが、まじめにICEなどの開発デバッグ環境をそろええるとフツーに実装された機能なんだろうと思います。

で、少ないピンの共用問題あるあるなんだけど、デバッグ用に他の汎用ピンにUARTでモニター出力できるようにできればと思い少し調べてみました。(※Arduino環境限定)

その3.ピンのリマップでピン機能を切り替える

J4M6のデフォルトのピン設定が、SWDIOとUART TXが共用であれば、ピン設定を他のピン配置にしちゃえばいいよねということです。

まず、Arduino環境でのピン設定です。

…\Arduino15\packages\WCH\hardware\ch32v\1.0.4\variants\CH32V00x\CH32V003F4

上記に保存されている、インストールされたPeripheralPins.cを参照します。バージョンは、v1.0.4です。

UARTが有効されている場合のUSART1が利用されデフォルトのピン設定が分かります。

TX = PD5, RX = PD6, RTS = PC2, CTS = PD3です。

例えば、Remapレジスタ AFIO_PCFR1を参照すると、USART1_RM1[21:2]を書き換えることでピンマップが変更できそうですが、SOP8 J4M6では、ピンが限定されているのでUSART1_RM1[21:2] = 10しか選べません。

ですが、残念ながらUSART1_RM1[21:2] = 10としても、SWDIOが今度は、RXと共用されてしまうので、いづれにしてもSWDIOが無効化されてしまいます。

でなら、UARTのTXを汎用ピンで実装してしまいましょう。

その4.シリアル出力の実装

シリアルの出力のみ程度なら、サクッと汎用ピンに機能を実装してしまいましょう。

J4M6でなら、例えば、PD6にTXの機能を実装します。

内容としては、ボーレートの設定、汎用ピンの設定、シリアル出力機能の実装です。

※Arduino環境のバグがありますので、delay値は、1/2の値で設定しています。

Arduino構文を使用するとサクッと完結に記述できますが、非Arduinoとすると、まま構文が増えますね。

最終製品に実装する際には、SWDIOは不要になるので、そのままピンを寝かしておくには資産的にもったいないので、ファームの開発中は、delayで書き換えを凌いでいいと思います。

PWMでモーターやサーボを回したりや簡単な音を鳴らしたり、ADCもあるので外部入力のボタン類も実装できますね