USBプロジェクト - ファームウェアに立ち返る (10) [USB]
さあ、いよいよ、わからんようになって来たぞ。
GET_DESCRIPTORリクエストに代表されるコントロール読込み転送のシーケンスを考えます。
やっぱり、割り込みは必要だった
EP0-OUTトランザクション以外には割り込みは必要ないのではないかと考えて試行錯誤をしてきました。 しかし、デスクリプタのように複数のDATA-INトランザクションを送出する場合には、割り込みを使わないとメインルーチンの負荷が重くなってしまい、プログラムが複雑になってしまうことがわかってきました。
そこで、DATA-INシーケンスの開始トリガをメインルーチンで発行したら、あとは自動的にデータが送信されるモデルを作りました。
シーケンス図
このモデルでは、メインルーチン、割り込みサービスルーチン(isr)、EP0-OUT、EP0-IN、ホストをオブジェクトとみなして、データとイベントの受け渡しを表現しています。
メインルーチンは、isrでセットされたsetupReadyフラグををポーリングして、SETUPデータの解析(parser)を開始します。 データの解析が終わったら、デスクリプタへのポインタと長さを指定して、ep0InStart関数を呼び出します。
この関数の中では、エンドポインタに最初のデータを詰めて、TX0E=1として、DATA-INトランザクションを開始します。 もし、TX0E=1とする前にDATA-INトランザクションが始まっても、NAKが返されるので、ホストを待たせることができます。
二回目以降のデータは、isrが詰めます。 そのため、この間、メインルーチンは、他の仕事をすることが出来ます。
STATUS-OUTが到着したら、isrが返答します。 この時にep0InCompleteフラグが発行されるので、メインルーチンが処理の終了を認識することが出来ます。 メインルーチンが、コントロールIN転送の終了に興味を持つ状況は私には想像できないので、きっとこのフラグは、使われることはないでしょう。
デスクリプタのトランザクションへの分割
MC908JB16のエンドポイントのバッファは、8バイトの大きさしかありません。 そのため、デスクリプタを8バイト以下のトランザクションに分割しなくてはなりません。
USB2.0の仕様書、"8.5.3 Control Transfers"と"8.5.3.2 Variable-length Data Stage"に分割の仕方が記述されています。 先に最大サイズのトランザクションを送り、残りをサイズの小さなトランザクションで送ります。 状況により、データ長の大きさが以下のように決まります。
送信要求フラグ | 残りサイズ | 可変長 | トランザクション |
---|---|---|---|
NO | - | - | 送信終了 |
YES | 0 | NO | 送信終了 |
YES | 0 | YES | 0バイト送信 |
YES | 1-7 | - | 1-7バイト送信 |
YES | ≤ 8 | - | 8バイト送信 |
「可変長」は、SETUPトランザクションで要求された大きさよりも送信するデスクリプタの大きさが小さかった場合に適用されます。 サイズの大小によって、最後の長さゼロのトランザクションを送るかどうかを決定しなくてはなりません。 なんと、面倒な。
すべてのデータを送り終えたら送信要求フラグを落とします。
コーディングが間に合わない。
付録 : USBプロジェクト索引
- USBプロジェクト - ファームウェアに立ち返る (1)
- USBプロジェクト - ファームウェアに立ち返る (2)
- USBプロジェクト - ファームウェアに立ち返る (3)
- USBプロジェクト - ファームウェアに立ち返る (4)
- USBプロジェクト - ファームウェアに立ち返る (5)
- USBプロジェクト - ファームウェアに立ち返る (6)
- USBプロジェクト - ファームウェアに立ち返る (7)
- USBプロジェクト - ファームウェアに立ち返る (8)
- USBプロジェクト - ファームウェアに立ち返る (9)
- USBプロジェクト - ファームウェアに立ち返る (10)
- USBプロジェクト - ファームウェアに立ち返る (11)
- USBプロジェクト - ファームウェアに立ち返る (12)
- USBプロジェクト - ファームウェアに立ち返る (13)
- USBプロジェクト - HIDデバイス(1)
- USBプロジェクト - HIDデバイス(2)
- USBプロジェクト - HIDデバイス(3)
- USBプロジェクト - 複合デバイスを考えた
- USBプロジェクト - HIDデバイス(4)
- USBプロジェクト - HIDデバイス(5)
参考文献
USBハード&ソフト開発のすべて―USBコントローラの使い方からWindows/Linuxドライバの作成まで (TECHI―Bus Interface)
- 作者: インターフェース編集部
- 出版社/メーカー: CQ出版
- 発売日: 2006/07
- メディア: 単行本
USBターゲット機器開発のすべて―各種USBコントローラの使い方と基本ソフトウェアの作成法 (TECHI―Bus Interface)
- 作者:
- 出版社/メーカー: CQ出版
- 発売日: 2005/08
- メディア: 単行本
>DATA-INシーケンスの開始トリガをメインルーチンで発行したら、あとは自動的にデータが送信されるモデルを作りました。
ついにデバイス側のエンドポイントの扱い方をマスターされましたね。
後は、これに対応するホスト側の状況(デバイスドライバ、ホストアプリ)の理解とそれをうまく制御する方法(polling-INトランザクションなど)が結びつけば完璧です。ホスト側は、バルク・エンドポイントを扱うようになるまで置いておいて、今はデバイス側をやっつけてしまいましょう。
>「可変長」は、... なんと、面倒な。
このトランスファの終了に関する規則は、USB全般を通じて重要な概念なんですが、コントロール転送の実装では付加的要素です。こういった付加的要素はひとまず置いておいて、まずは骨格を仕上げちゃいましょう。
>コーディングが間に合わない。
いえいえ、順調ですよ。
多くの情報が一時に入ってきたので、それらの情報の関連付けがまだうまくいっていないのでしょう。特にファームウェアのコードサイズとかMCUのパフォーマンスを判断基準に取ったときの優先順位の付け方は、慣れていても難しいものがあります。シーケンス図は全体を見渡せて、情報の関連付けを行うのにとても良い方法です。ここで習得されている考え方は、このMCUに限らずどんなUSB MCUにでも適用できます。ここが踏んばりどころです。じっくり行きましょう。
Tsuneo
by Tsuneo (2008-03-31 17:44)