USB 制御転送の送信方法 (UWP アプリ)

この記事では、次の方法を示します。

  • USB セットアップ パケットをフォーマットする方法
  • アプリから USB 制御転送を開始する方法

重要な API

通常、USB デバイスと通信するアプリは、複数の制御転送要求を送信します。 これらの要求は、デバイスに関する情報を取得し、ハードウェア ベンダーによって定義された制御コマンドを送信します。 このトピックでは、制御転送と、UWP アプリで書式設定して送信する方法について説明します。

制御転送では、構成情報の読み取りまたは書き込み、またはハードウェア ベンダーによって定義されたデバイス固有の機能を実行できます。 転送が書き込み操作を実行する場合は、OUT 転送です。読み取り操作。これは IN 転送となります。 方向に関係なく、ホスト システム上の UWP アプリなどのソフトウェアは、常に制御転送の要求をビルドして開始します。 アプリは、データの読み取りまたは書き込みを行う制御転送を開始できる場合があります。 その場合、追加のバッファーを送信することが必要になる場合があります。

すべての種類の制御転送に対応するために、Windows.Devices.Usb には次のメソッドが用意されています。

USB 用 Windows ランタイム API の USB コントロール転送。

USB 制御転送は、記述子データの取得や標準コマンドの送信にも使用されます。 ただし、制御転送を手動で構築するのではなく、Windows.Devices.Usb によって提供される特定のメソッドを呼び出して、このような種類の要求を送信することをお勧めします。 たとえば、代替設定を選択するには、SendControlOutTransferAsync (UsbSetupPacket) を呼び出す代わりに SelectSettingAsync を呼び出します。

特定の種類の標準要求の制御転送はサポートされていません。 ただし、デバイスが Windows.Devices.Usb でサポートされているデバイス クラスに属している場合は、デバイス クラスの仕様で定義されているいくつかの要求を送信できます。

開始する前に

  • デバイスを開き、UsbDevice オブジェクトを取得している必要があります。 「USB デバイスへの接続方法 (UWP アプリ)」を参照してください。
  • ベンダー定義の制御コマンドに関する情報を取得します。 通常、これらのコマンドはハードウェア仕様で定義されています。
  • このトピックで示されている完全なコードは、CustomUsbDeviceAccess サンプルの Scenario2_ControlTransfer.cpp および Scenario2_ControlTransfer.h で確認できます。

手順 1: セットアップ パケットを設定する

このトピックでは、さまざまなパターンでライトを点滅させるデバイスに制御転送を送信します。 セットアップ パケットを設定するには、制御コマンドがハードウェア ベンダーによって定義されていることを知っておく必要があります。

  • bmRequestType (D7): OUT
  • bmRequestType (D4): デバイス
  • bmRequestType (D6...D5): ベンダー
  • bRequest: 0x03
  • wValue: 0 ~ 7 (その範囲内の任意の数値を含む)
  • wIndex: 0
  • wLength: 0

制御転送の場合は、転送に関するすべての情報を含むセットアップ パケットを設定する必要があります。要求がデータの読み取りまたは書き込みを行うかどうか、要求の種類などです。 セットアップ パケットの形式は、公式の USB 仕様で定義されています。 セットアップ パケット フィールドの値は、デバイスのハードウェア仕様によって提供されます。

  1. UsbSetupPacket オブジェクトを作成します。

  2. さまざまなプロパティを設定して、UsbSetupPacket オブジェクトを設定します。 次の表に、USB で定義されたセットアップ パケット フィールドと、それらのフィールドに対応するプロパティを示します。

    セクション 9.3 のフィールド プロパティ 説明
    bmRequestType (D7) UsbControlRequestType.Direction 要求の方向。 要求がホストからデバイス (送信転送)、またはデバイスからホスト (転送中) のいずれか
    bmRequestType (D4) UsbControlRequestType.Recipient 要求の受信者。 すべての制御転送は、既定のエンドポイントをターゲットにします。 ただし、受信者はデバイス、インターフェイス、エンドポイントなどである可能性があります。 USB デバイス、インターフェイス、エンドポイント階層の詳細については、「デバイス レイアウト」を参照してください。
    bmRequestType (D6…D5) UsbControlRequestType.ControlTransferType 要求のカテゴリ。 標準、クラス、またはベンダー。
    bRequest UsbSetupPacket.Request 要求の種類。 要求が GET_DESCRIPTOR 要求などの標準要求である場合、その要求は USB 仕様によって定義されます。 それ以外の場合は、ベンダーが定義できます。
    wValue UsbSetupPacket.Value 要求の種類によって異なります。
    wIndex UsbSetupPacket.Index 要求の種類によって異なります。
    wLength UsbSetupPacket.Length この要求で送受信されるデータ パケットの長さ。

![注] 特定の制御転送では、生バイトとして bmRequestType を指定することが必要になる場合があります。 その場合、UsbControlRequestType.AsByte プロパティでバイトを設定できます。

手順 2: 非同期操作を開始して制御転送を送信する

制御転送を送信するには、UsbDevice オブジェクトが必要です。 制御転送では、セットアップ パケットに従うデータ パケットが必要な場合と必要ない場合があります。

コントロール転送を開始するには、SendControlInTransferAsync または SendControlOutTransferAsync のオーバーライドを呼び出します。 転送でデータ パケットが使用される場合は、SendControlOutTransferAsync (UsbSetupPacket, IBuffer)SendControlInTransferAsync (UsbSetupPacket, IBuffer) を呼び出します。 これらのメソッドは、書き込むデータを含む追加パラメーター、またはデバイスからデータを受信するパラメーターを受け取ります。 フローチャートを使用して、呼び出すオーバーライドを決定します。

呼び出しが開始され、非同期操作が行われます。 操作が完了すると、呼び出しは操作の結果を含む IAsyncOperation オブジェクトを返します。 OUT 転送の場合、オブジェクトは転送で送信されたバイト数を返します。 IN 転送の場合、オブジェクトにはデバイスから読み取られたデータを含むバッファーが含まれます。

USB 制御転送コードの例

このコード例では、SuperMUTT デバイスの点滅パターンを変更する制御転送を送信する方法を示します。 転送のセットアップ パケットには、ベンダー定義のコマンドが含まれています。 この例は Scenario2_ControlTransfer.cpp にあります。

async Task SetSuperMuttLedBlinkPatternAsync(Byte pattern)
        {
            UsbSetupPacket initSetupPacket = new UsbSetupPacket
            {
                RequestType = new UsbControlRequestType
                {
                    Direction = UsbTransferDirection.Out,
                    Recipient = UsbControlRecipient.Device,
                    ControlTransferType = UsbControlTransferType.Vendor
                },
                Request = SuperMutt.VendorCommand.SetLedBlinkPattern,
                Value = pattern,
                Length = 0
            };

            UInt32 bytesTransferred = await EventHandlerForDevice.Current.Device.SendControlOutTransferAsync(initSetupPacket);

            MainPage.Current.NotifyUser("The Led blink pattern is set to " + pattern.ToString(), NotifyType.StatusMessage);
        }

このコード例では、SuperMUTT デバイスの点滅パターンを変更する制御転送を送信する方法を示します。 転送のセットアップ パケットには、ベンダー定義のコマンドが含まれています。 この例は Scenario2_ControlTransfer.cpp にあります。

async Task<IBuffer> SendVendorControlTransferInToDeviceRecipientAsync(Byte vendorCommand, UInt32 dataPacketLength)
 {
    // Data will be written to this buffer when we receive it
    var buffer = new Windows.Storage.Streams.Buffer(dataPacketLength);

    UsbSetupPacket initSetupPacket = new UsbSetupPacket
    {
        RequestType = new UsbControlRequestType
        {
            Direction = UsbTransferDirection.In,
            Recipient = UsbControlRecipient.Device,
            ControlTransferType = UsbControlTransferType.Vendor,
        },
        Request = vendorCommand,
        Length = dataPacketLength
    };

    return await EventHandlerForDevice.Current.Device.SendControlInTransferAsync(initSetupPacket, buffer);
}