技術者見習いのメモ書き

電子工作や神社めぐりなどの趣味の話を中心に書いていきます。 Twitter:@hakura_riku

USB機能付き格安マイコンCH552TでUSBシリアル通信をおこなう方法

はじめに

前回までの記事でCH552Tの回路と開発環境について解説しました. 今回はCH552のUSBシリアルのプログラムを紹介します.

マイコンプログラムの最初はLチカをおこなうことが多いですが, 参考文献[1]のブログでLチカとタイマ割り込みのプログラムが紹介されているのでHello Worldのプログラムを公開したいと思います. 

 ※Lチカとタイマ割り込みのプログラムの解説記事がコメント欄などから要望があれば作成します.

プログラム

作成したサンプルプログラムを以下のリンクに置いておきます.

github.com

このプログラムは公式が配布しているCH554用シリアル通信プログラムをCH552, CH551用に改造したプログラムです. CH55Xシリーズのサンプルプログラムは互換性があり基本的に流用可能ですが, 使用するマイコンによっては実装されていない機能があるので適時修正が必要です.

もしもCH554のプログラムをCH552, CH551で利用する場合はUSBホスト機能に関するコードを削除してください.

※そのままCH554のプログラムをCH552, CH551に書き込んだ場合はブートローダーが破損するため書き込みが二度とできなくなります.

改造元のプログラムは一番初めの記事で紹介したサンプルプログラムの中にあります.

e_dragon / WCH / source / — Bitbucket

サンプルコードの使い方

サンプルコードが置いてあるgithubのリンクからサンプルプログラムをダウンロードします.

第1回の記事を参考にプロジェクトファイルを作成してください.

hakura03.hatenablog.com

作成したプロジェクトファイルの中にダウンロードしたファイルをコピーします.

f:id:hakura03:20190418222425p:plain
ダウンロードしたファイルをコピー

uVision5を起動し, 「Souse Group 1」の項目で右クリックして画像で示す「Add Existing Files to Group 'Source Group 1'」を選択します.

f:id:hakura03:20190418222711p:plain
ファイルの追加

「Add Existing Files to Group 'Source Group 1'」の画面が出てくるので, 「main.c」「USB_Serial.c」を追加します. そして, 「Public」フォルダ内にある「Debug.C」を追加します.

f:id:hakura03:20190418223550p:plain
ファイルの追加2

「main.c」をダブルクリックして開き, 「Rebuild」「Translate」を押してください. エラーが出なければコンパイルが成功しています.

f:id:hakura03:20190418224237p:plain
ビルド

f:id:hakura03:20190418224446p:plain
translate

書き込み

書き込みにはWCHISPToolが必要です. インストールしたWCHISPToolを起動し, 「8 Bit CH55X series」のタブを開きます.

f:id:hakura03:20190418225531p:plain
タブを開く

次に「Chip model」の欄からCH552を選択します.

f:id:hakura03:20190418225742p:plain
チップ選択

最後に「User File」の部分で自分が作成したプログラムのヘックスファイルを参照します. ヘックスファイルは作成したプロジェクトフォルダの「Objects」内にあります.

f:id:hakura03:20190418230024p:plain
ヘックスファイル参照

これで書き込み準備は完了です. 第2回の記事で紹介した回路を作成し書き込みをおこないます.

hakura03.hatenablog.com

USBをPCに差し込む際にCH552T書き込み回路についているボタンを押しながら差し込みます. 適切にブートローダーが起動できた場合は, WCHISPToolにCH552の表示が出ます.

f:id:hakura03:20190418230720p:plain
CH552の表示

「Download」ボタンを押すことでCH552に書き込むことができます.

プログラムの動作確認

今回のプログラムではボーレートが「57600bps」に設定されています. Arduino IDEのシリアルモニタで確認した結果を画像に示します.

f:id:hakura03:20190418231412p:plain
シリアルモニタ

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].

wch.cn

コンフィグレーションディスクリプタ

以下に示すデバイスディスクリプタの表を用いてコンフィグレージョンディスクリプタの解説をおこないます. コンフィグレーションディスクリプタは「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.