CH32V203でArduinoからUSBSerial
Arduino上で、CH32V203のUSBSerialを使おうとしたが、思ったよりも苦労した。 このマイコンのUSBは以前にArduinoから使ったことがあったので、その時と同じようにすれば良いと予想していたが、使い方が変わったりしていて、素直には動かなかったが、動かし方が分かったので、そのコツを書いておく。
CH32V203でArduinoからUSBSerialを使う場合、いくつかの方法がある。その中で最も一般的なのがTinyUSBを使う方法である。 TinyUSBのライブラリは、「ライブラリを管理」から「Adafruit TinyUSB Library」を選ぶことでインストールできる。 最新versionは3.7.7で、それなりに頻繁に更新されているようだ。 すぐに動くと思ったのに、なかなかうまく動かなくて苦労したが、最終的には次のようにすると動くことが分かった。 スケッチ例のCDCのserial_echoを見ると参考になるが、ライブラリのヘッダを取り込んで、TinyUSBDevice.begin(0);を実行してから、SerialTinyUSBをSerialと同様に使えばよい。 以前使ったときには,Adafruit_USBD_CDCオブジェクトをUSBSerialなどの名前で作って使っていたが、使い方が変わったようだ。 私が試したところ、最適化でSmallest with LTOでは、USBがうまく認識せず、Smallestだとうまく動いた。 しかし、その場合には、簡単なプログラムでもコンパイルサイズが24k程と、かなり大きくなった。 また、 Suzuduinoや jobitjosephさんのものなどの、 WCH公式以外のarduino coreで、USB supportを選択できる場合でも、「なし」としないとエラーが出てしまった。 これはおそらくversionの相性の問題だろうと考えている。
サイズがもう少し小さいものとしては、 21km43さんのライブラリを使う方法がある。 これを使うには少しだけ準備が必要である。 ファイルをdownload zipとして取って来て、解凍してからsrcフォルダをCH32V203_USBCDCなどと名前を変えてから、Arduinoのlibrariesフォルダに入れるのである。 使い方は単純で、以下のようにヘッダを取り込んだら、Serialという名前で使える。
#include <usb_serial.h>
こちらも、Smallest with LTOだと駄目で、Newlib Nano + USBDにしても、LTOだと動かない。 やはりSmallestにする必要があり、このときのサイズは15kとなった。 TinyUSBよりは小さいが、それでもまだ大きいと感じる。 また、個人的にはUARTと混同しないように、Serialとは別の名前で動いてくれた方が良いので、usb_serial.hとusb_serial.cppを変更しようかと考えている。
LTOを指定した場合には、割り込みに必要な関数などが使われていないと判断されて、消去されてしまってUSBが動かないのだろう。 これらの関数に、敵切に__attribute__((used))などの指定をつければ、LTOも使えるのでは無いかと思うが、それがどこに定義されているのかを調べるのが大変だろう。 一方、LTOを指定しない時には、使われていない多くの関数が残って、コンパイルサイズが大きくなっていると思われる。 もう少しサイズが小さく出来無いものかな。