はじめに
前回までの記事でCH552Tの回路と開発環境について解説しました. 今回はCH552のUSBシリアルのプログラムを紹介します.
マイコンプログラムの最初はLチカをおこなうことが多いですが, 参考文献[1]のブログでLチカとタイマ割り込みのプログラムが紹介されているのでHello Worldのプログラムを公開したいと思います.
※Lチカとタイマ割り込みのプログラムの解説記事がコメント欄などから要望があれば作成します.
プログラム
作成したサンプルプログラムを以下のリンクに置いておきます.
このプログラムは公式が配布しているCH554用シリアル通信プログラムをCH552, CH551用に改造したプログラムです. CH55Xシリーズのサンプルプログラムは互換性があり基本的に流用可能ですが, 使用するマイコンによっては実装されていない機能があるので適時修正が必要です.
もしもCH554のプログラムをCH552, CH551で利用する場合はUSBホスト機能に関するコードを削除してください.
※そのままCH554のプログラムをCH552, CH551に書き込んだ場合はブートローダーが破損するため書き込みが二度とできなくなります.
改造元のプログラムは一番初めの記事で紹介したサンプルプログラムの中にあります.
e_dragon / WCH / source / — Bitbucket
サンプルコードの使い方
サンプルコードが置いてあるgithubのリンクからサンプルプログラムをダウンロードします.
第1回の記事を参考にプロジェクトファイルを作成してください.
作成したプロジェクトファイルの中にダウンロードしたファイルをコピーします.
uVision5を起動し, 「Souse Group 1」の項目で右クリックして画像で示す「Add Existing Files to Group 'Source Group 1'」を選択します.
「Add Existing Files to Group 'Source Group 1'」の画面が出てくるので, 「main.c」「USB_Serial.c」を追加します. そして, 「Public」フォルダ内にある「Debug.C」を追加します.
「main.c」をダブルクリックして開き, 「Rebuild」「Translate」を押してください. エラーが出なければコンパイルが成功しています.
書き込み
書き込みにはWCHISPToolが必要です. インストールしたWCHISPToolを起動し, 「8 Bit CH55X series」のタブを開きます.
次に「Chip model」の欄からCH552を選択します.
最後に「User File」の部分で自分が作成したプログラムのヘックスファイルを参照します. ヘックスファイルは作成したプロジェクトフォルダの「Objects」内にあります.
これで書き込み準備は完了です. 第2回の記事で紹介した回路を作成し書き込みをおこないます.
USBをPCに差し込む際にCH552T書き込み回路についているボタンを押しながら差し込みます. 適切にブートローダーが起動できた場合は, WCHISPToolにCH552の表示が出ます.
「Download」ボタンを押すことでCH552に書き込むことができます.
プログラムの動作確認
今回のプログラムではボーレートが「57600bps」に設定されています. Arduino IDEのシリアルモニタで確認した結果を画像に示します.
USBデバイスクラスについて
サンプルプログラムを理解するために「USB_Serial.c」に記述されているUSBデバイスクラスについて解説します. 完全新規のUSBデバイスを開発する場合は本来なら, USBホスト(パソコン側など)とUSBデバイス(マイコン側など)双方のプログラムを作成する必要があります. しかしUSBデバイスクラスの規格に基づいてUSBデバイスを製作する場合はUSBホスト側のプログラムを作成する必要は基本的にありません. デバイスクラスが用いられる代表的な製品としてキーボードやマウスなどのパソコン用のデバイスがあります.デバイスクラスの表を以下に示します.
表1 USBのデバイスクラスコードについて
デバイスクラス名 | クラスコード(bDevice Class) |
---|---|
Audio | 0x01 |
CDC(Communication Data Class) | 0x02 |
HID(Human Interface Devices) | 0x03 |
Image | 0x06 |
MTP(Media Transfer Protocol) | 0x06 |
Printer | 0x07 |
MSC(Mass Storage Class) | 0x08 |
USB Hub | 0x09 |
CCID | 0x0B |
UVC(USB Video Class) | 0x0E |
PHDC | 0x0F |
Wireless Controller Bluetooth | 0xE0 |
(参考文献[4] より引用)
WCHが販売するUSBシリアル変換IC「CH340」としてCH552Tを認識させるため一部のディスクリプタで異なる設定をおこないますが, 基本的にはCDCクラスと同じプログラムを作成します. CDCクラスはUSBを利用して通信をおこなうために規定された規格でシリアル通信をおこなうことができます[4].
USB・シリアル変換IC CH340G: 半導体 秋月電子通商-電子部品・ネット通販
サンプルプログラムのUSBディスクリプタについて
USBディスクリプタとはUSBの属性などを記述する部分です. ディスクリプタの設定を適切におこなうことで, USBデバイスのデバイスクラスや エンドポイントの設定などをおこなうことができます. 今回のサンプルプログラムに記述されているディスクリプタを以下に示します.
UINT8C DevDesc[18]={0x12,0x01,0x10,0x01,0xff,0x00,0x02,0x08, 0x86,0x1a,0x23,0x55,0x04,0x03,0x00,0x00,0x00,0x01}; UINT8C CfgDesc[39]={0x09,0x02,0x27,0x00,0x01,0x01,0x00,0x80,0xf0,0x09,0x04,0x00,0x00,0x03,0xff,0x01,0x02,0x00,0x07,0x05,0x82,0x02,0x20,0x00,0x00,0x07,0x05,0x02,0x02,0x20,0x00,0x00,0x07,0x05,0x81,0x03,0x08,0x00,0x01};
デバイスディスクリプタ
以下に示すデバイスディスクリプタの表を用いて「DevDesc[18]」の解説をおこないます.
表2 デバイスディスクリプタの解説とサンプルプログラムでの設定
Field | Offset | Size(byte) | 詳細 | 今回の設定値 |
---|---|---|---|---|
bLength | 0 | 1 | ディスクリプタの全体長。デバイスディスクリプタは 18(0x12)Byte 固定。 | 0x12 |
bDescriptorType | 1 | 1 | ディスクリプタの種別番号。DEVICE は 1。 | 0x01 |
bcdUSB | 2 | 2 | USB のバージョン(BCD)。0x100(USB 1.0?)、0x110(USB 1.1)、0x200(USB 2.0)、0x300(USB 3.0) | 0x10,0x01 |
bDeviceClass | 4 | 1 | クラス番号 (USBクラス)。0x0 と 0xFF 以外は USB-IF が予約している。 | 0xff |
bDeviceSubClass | 5 | 1 | サブクラス番号。0x0 と 0xFF 以外は クラス番号に依存する。 | 0x00 |
bDeviceProtocol | 6 | 1 | プロトコル番号。0x0 と 0xFF 以外は クラス、サブクラス番号に依存する。 | 0x02 |
bMaxPacketSize0 | 7 | 1 | エンドポイント0の最大パケットサイズ(Byte)。速度別に規定がある。 | 0x08 |
idVendor | 8 | 2 | ベンダID(VID)。USB-IF より ID を発行(有償)してもらう必要有り。 | 0x86,0x1a |
idProduct | 10 | 2 | プロダクトID(PID)。ベンダー各社がプロダクト毎に ID を自由に振りふれる。 | 0x23,0x55 |
bcdDevice | 12 | 2 | デバイスのバージョン番号(BCD)。 | 0x04,0x03 |
iManufacturer | 14 | 1 | 製造者の ストリングディスクリプタ の Index 番号。0の場合、指定無し。 | 0x00 |
iProduct | 15 | 1 | Product の ストリングディスクリプタ の Index 番号。0の場合、指定無し。 | 0x00 |
iSerialNumber | 16 | 1 | シリアルナンバーのストリングディスクリプタの Index 番号。0の場合、指定無し。複数接続を前提とするならば指定が必要。 | 0x00 |
bNumConfigurations | 17 | 1 | コンフィグレーションディスクリプタの個数。複数の Configuration より複数の Interface の方が好まれるケースが多い。 | 0x01 |
(参考文献[5] より引用)
デバイスディスクリプタの4バイト目「bDeviceClass」の部分でCDCクラスを意味する「0x02」ではなく「0xff」となっています. 今回のプログラムでは「CH340」としてデバイスを認識させるためWCHが公式で出しているCH340のデバイスドライバを使用するからです. Windowsで使用する場合はWindows7以前のOSの場合別途デバイスドライバをインストールする必要があります. Windows8, Windows10ではCH340が標準サポートになっているので必要ないと考えられます[6].
コンフィグレーションディスクリプタ
以下に示すデバイスディスクリプタの表を用いてコンフィグレージョンディスクリプタの解説をおこないます. コンフィグレーションディスクリプタは「CfgDesc[39]」に含まれています. 「CfgDesc[39]」にはインターフェイスディスクリプタ, エンドポイントディスクリプタも含まれているので注意が必要です.
//「CfgDesc[39]」に含まれるコンフィグレーションディスクリプタ 0x09,0x02,0x27,0x00,0x01,0x01,0x00,0x80,0xf0
表3 コンフィグレージョンディスクリプタの解説とサンプルプログラムでの設定
Field | Offset | Size(byte) | 詳細 | 今回の設定値 |
---|---|---|---|---|
bLength | 0 | 1 | Descriptorの全体長。CONFIGURATIONは9(0x09)Byte固定 | 0x09 |
bDescriptorType | 1 | 1 | Descriptor Types。CONFIGURATIONは2。 | 0x02 |
wTotalLength | 2 | 2 | 当該、および従属ディスクリプタの全長 | 0x27,0x00 |
bNumInterface | 4 | 1 | インターフェイスディスクリプタの個数 | 0x01 |
bConfigurationValue | 5 | 1 | Configuration番号。SET_CONFIGURATION時のID。 | 0x01 |
iConfiguration | 6 | 1 | ConfigurationのストリングディスクリプタのIndex番号。0の場合、指定なし | 0x00 |
bmAttribures | 7 | 1 | bit7:予約(1), bit6:Self Power(0/1), bit5:Remote Wakeup機能(0/1), bit4-0:予約(0) | 0x80 |
bMaxPower | 8 | 1 | 必要とするバスからの電流の1/2(mA)。最大 500(=0xFA*2)mA。値の1/2を設定するのは 1 byte に収めたかったため。USB 3.0では消費電流量bMaxPowerの単位が2mAから8mAへ変更されている | 0xf0 |
(参考文献[5] より引用)
インターフェイスディスクリプタ
//「CfgDesc[39]」に含まれるインターフェイスディスクリプタ 0x09,0x04,0x00,0x00,0x03,0xff,0x01,0x02,0x00
表4 インターフェイスディスクリプタの解説とサンプルプログラムでの設定
Field | Offset | Size(byte) | 詳細 | 今回の設定値 |
---|---|---|---|---|
bLength | 0 | 1 | ディスクリプタの長さ。INTERFACE は 9(0x9)Byte 固定。 | 0x09 |
bDescriptorType | 1 | 1 | ディスクリプタの種別。INTERFACE は 4。 | 0x04 |
bInterfaceNumber | 2 | 1 | インターフェイスの識別番号。複合デバイス(Composite device)の場合、異なった値が設定されなければならない。デフォルトは 0。 | 0x00 |
bAlternateSetting | 3 | 1 | 代替設定を選択するための値。bInterfaceNumberが同じで bAlternateSetting が異なる別々のディスクリプタを持っている場合、ホスト側からのSET_INTERFACEコマンドで切り替えることが出来る。デフォルトは 0。 | 0x00 |
bNumEndpoints | 4 | 1 | エンドポイント数(ただし エンドポイント0 は除く) | 0x03 |
bInterfaceClass | 5 | 1 | クラス番号(USBクラス)。bDeviceClass(デバイスディスクリプタ) の設定が 0 だった場合、この設定が参照される。0x0 は未定義、0xFF は Vendor-specific。 | 0xff |
bInterfaceSubClass | 6 | 1 | サブクラス番号。0x0 と 0xFF 以外は クラス番号に依存する。HIDの時はブートプロトコルに対応しているかどうかのフラグとして使われる。 | 0x01 |
bInterfaceProtocol | 7 | 1 | プロトコル番号。0x0 と 0xFF 以外は クラス、サブクラス番号に依存する。HIDのときはbInterfaceSubClassが指定されている時だけ意味を持つ。 | 0x02 |
iInterface | 8 | 1 | Interface の STRING Descriptor の Index 番号。0の場合、指定無し。 | 0x00 |
(参考文献[5] より引用)
エンドポイントディスクリプタ
//「CfgDesc[39]」に含まれるエンドポイントディスクリプタ 0x07,0x05,0x82,0x02,0x20,0x00,0x00 0x07,0x05,0x02,0x02,0x20,0x00,0x00 0x07,0x05,0x81,0x03,0x08,0x00,0x01
エンドポイントディスクリプタは複数あるので表5には今回の設定値を記載しません.
表5 エンドポイントディスクリプタの解説
Field | Offset | Size(byte) | 詳細 |
---|---|---|---|
bLength | 0 | 1 | Descriptor の全体長。ENDPOINT は 7(0x7)Byte 固定。 |
bDescriptorType | 1 | 1 | ディスクリプタの種別番号。ENDPOINT は 5。 |
bEndpointAddress | 2 | 1 | bit 7 : IN=1, OUT=0, bit 6-4 : 予約(0), bit 3-0 : エンドポイント番号 |
bmAttributes | 3 | 1 | bit 7-2 : 予約(0), bit 1-0 : 00=コントロール転送、01=アイソクロナス転送、10=バルク転送、11=インタラプト転送 |
wMaxPacketSize | 4 | 2 | 最大パケット長。 |
bInterval | 6 | 0 | 最大待ち時間。転送方式、速度によって意味合いが異なる。 |
(参考文献[5] より引用)
以上が今回のプログラムのディスクリプタです. CH55Xシリーズを用いてオリジナルの機器を作ることを考えた場合, 自分でディスクリプタの設定を決める必要があるのでディスクリプタについて頭の片隅に置いておくと開発がスムーズに進むと思います.
おわりに
サンプルプログラムの導入方法とディスクリプタについて解説をおこないました. 次回はサンプルプログラム「USB_Serial.c」について解説しようと考えています.
参考文献
[1]べーた, ‘‘Cerevo TechBlog [21日目]激安中華USBマイコンは使えるのか, ” https://tech-blog.cerevo.com/archives/6068/.
[2]江苏沁恒股份有限公司, ‘‘8 位增强型USB 单片机CH552、CH551,” https://datasheet.lcsc.com/szlcsc/Jiangsu-Qin-Heng-CH552T_C111367.pdf.
[3]Infinitegra, ‘‘Infinitegra TechBlog USBデバイスクラス,” http://www.infinitegra.co.jp/blog/?p=43.
[4]AVR-CDC, ‘‘ソフトウェア USB による仮想 COM ポート,”http://www.recursion.jp/prose/avrcdc/driverj.html.
[5]おなかすいたwiki, ‘USB/ディスクリプタ,”http://wiki.onakasuita.org/pukiwiki/?USB%2F%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%BF.
[6]ネクストステップ サポートBlog, ‘‘Arduino NANO 互換品(CH340チップ使用)のデバイスドライバー,”https://support.next-step.asia/tag/ch340-usb%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E5%A4%89%E6%8F%9B%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90/.
[7]Electrodragon, ‘‘Electrodragon Wiki,”https://www.electrodragon.com/w/WCH.