SSブログ

macOSからPi Picoを使う - その17 [Pi Pico]

前回tusb.hを読んでみて、必要なUSB classのヘッダしか読み込まれないし、不要なclass用のコードはリンクされなくて、その呼び出しは関数ポインタを並べた構造体を経由して行われることがわかった。ちょっと遠回りのような気もするけど、なるべくコードサイズを抑えるための配慮だと思われる。組み込みではこうするのが普通なのかな。そのへんはよくわからない。

今日はUSB descriptorをTinyUSBではどう扱うかを見ていく....

15.3  TinyUSBのdescriptor

だいたいの構造はわかったとしよう。つまり
  • tusb_config.hにどのクラスに対応したいかなどを書く
  • main.c(名前はなんでもいい)にそのクラスの読み書き関数を呼ぶことで実体を書く
  • 全体をリンクする
ということらしい。

このあとUSBの規格にかかわる部分が出てくる。非常に細かいところもあって、それはUSBの規格書にまで遡らないといけない。USBの規格書はusb.orgの本家サイトからアクセスできるけど、膨大な量があってどこから見ればいいのかよくわからなくなる。ダイジェストしてくれているところもいくつかあるけど、ダイジェストしすぎてプログラミングには不十分だったりする。誰か過不足のないのを作ってくれないだろうか。

15.3.1  device descriptor

USBデバイスとして動作させるためにはまずdevice descriptorを書かなければいけないはずである。TinyUSBではどうなってるかというと、
src/common/tusb_types.h
に定義がある。
/// USB Device Descriptor
typedef struct TU_ATTR_PACKED
{
  uint8_t  bLength            ; ///< Size of this descriptor in bytes.
  uint8_t  bDescriptorType    ; ///< DEVICE Descriptor Type.
  uint16_t bcdUSB             ; ///< BUSB Specification Release Number in B
  uint8_t  bDeviceClass       ; ///< Class code (assigned by the USB-IF). 
  uint8_t  bDeviceSubClass    ; ///< Subclass code (assigned by the USB-IF). 
  uint8_t  bDeviceProtocol    ; ///< Protocol code (assigned by the USB-IF). 
  uint8_t  bMaxPacketSize0    ; ///< Maximum packet size for endpoint zero (
  
  uint16_t idVendor           ; ///< Vendor ID (assigned by the USB-IF).
  uint16_t idProduct          ; ///< Product ID (assigned by the manufacturer).
  uint16_t bcdDevice          ; ///< Device release number in binary-coded 
  uint8_t  iManufacturer      ; ///< Index of string descriptor describing manu
  uint8_t  iProduct           ; ///< Index of string descriptor describing prod
  uint8_t  iSerialNumber      ; ///< Index of string descriptor describing

  uint8_t  bNumConfigurations ; ///< Number of possible configurations.
} tusb_desc_device_t;
となっていて、いろんなところで解説してくれているdevice descriptorのフィールド名までそのままである。まあ、変える必要もないけど。

ついでにここでそれぞれのフィールドの意味を備忘録として書いておく。すぐ忘れるし。

フィールド名の最初の文字は
b: 1バイト
w: 2バイト
bm: 1バイトのビットマップ
bcd: Binary Coded Decimal、4ビットで10進一桁を表す数値
i: インデクス値

を表している。
Table 1: device descriptorの意味
bLength descriptorのバイト数。Device descriptorは18バイト
bDescriptorType 何のdescriptorかを表す定数。Device descriptorはTUSB_DESC_DEVICE=0x01
bcdUSB USB仕様のリリース番号。USB2.0なら0x0200
bDeviceClass USB仕様参照。0だとinterfaceごとに指定
bDeviceSubClass USB仕様参照。bDeviceClassが0だとこれも0でないといけない
bDeviceProtocol USB仕様参照。0xFFだとベンダ依存
bMaxPacketSize0 endpoint0のpacket size。HullSpeedなら64固定
idVendor ベンダID
idProduct プロダクトID
iManufacturer string descriptorへのindex
iProduct 同上
iSerialNumber 同上
bNumConfigurations configuration descriptorの数

この構造体のメンバを埋めるヘルパ関数でもあるか、と思って探したけどほんのちょっとだけ。自分でUSBの仕様に従って埋めていくしかない。いちおうこのtusb_types.hのファイルの初めの方に読みやすく文字でdefineされた定数がenumであるので、実際にdescriptorを書くときはその定数を使うのがいい。

15.3.2  configuration descriptor

あと同様にconfiguration descriptorは
/// USB Configuration Descriptor
typedef struct TU_ATTR_PACKED
{
  uint8_t  bLength             ; ///< Size of this descriptor in bytes
  uint8_t  bDescriptorType     ; ///< CONFIGURATION Descriptor Type
  uint16_t wTotalLength        ; ///< Total length of data returned for this co
  
  uint8_t  bNumInterfaces      ; ///< Number of interfaces supported by this conf
  uint8_t  bConfigurationValue ; ///< Value to use as an argument to the SetC
  uint8_t  iConfiguration      ; ///< Index of string descriptor describing this 
  uint8_t  bmAttributes        ; ///< Configuration characteristics
  uint8_t  bMaxPower           ; ///< Maximum power consumption of the
} tusb_desc_configuration_t;
となっている。これもフィールドの意味を書いておく。

Table 2: configuration descriptorの意味
bLength: descriptorのバイト数
bDescriptorType configuration descriptorはTUSB_DESC_CONFIGURATION=0x02
wTotalLength: interface, endpoint descriptorまで含めたバイト数
bNumInterfaces: configurationに含まれるinterface descriptorの数
bConfigurationValue: このdescriptorを指定するための番号
iConfiguration: string descriptorへのindex
bmAttributes: ビットフィールド
bMaxPower: 最大消費電力。2mA単位で

bmAttributesはビットフィールドで、
7: 1に固定
6: self-poweredなら1
5: remote-wakeupなら1
4..0: 予約0x0

となっている。

device/subd.hに設定用の簡単なmacroがある。
#define TUD_CONFIG_DESCRIPTOR(config_num, _itfcount, _stridx, _total_len, _attribute, _power_ma)
また、この定義の後にclass別のmacroもある。
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。