2011-12-07 11 views
2

HIDデバイス、具体的には - > Silicon LabsのUSB-FMラジオリファレンスデザインがあります。 このデバイスはHIDとして公開されています。Android USBホスト、3.2、HIDレポート取得/設定

3.2 USBホストAPIを使用して、HID_REPORT_GET/SETまたは同等の機能を実行するにはどうすればよいですか?

乾杯、 Earlence

答えて

0

私はちょうどAndroidで動作するようにSi470x USBドングルを手に入れました。

private class HidDevice { 
    /** GET_REPORT request code */ 
    public static final int REQUEST_GET_REPORT = 0x01; 
    /** SET_REPORT request code */ 
    public static final int REQUEST_SET_REPORT = 0x09; 
    /** INPUT report type */ 
    public static final int REPORT_TYPE_INPUT = 0x0100; 
    /** OUTPUT report type */ 
    public static final int REPORT_TYPE_OUTPUT = 0x0200; 
    /** FEATURE report type */ 
    public static final int REPORT_TYPE_FEATURE = 0x0300; 

    private Context context; 
    private UsbManager manager; 
    private UsbDevice device; 
    private UsbInterface ifHid = null; 
    private UsbEndpoint epIn = null; 
    private UsbDeviceConnection connection; 

    public HidDevice(Context context, UsbDevice device) throws IOException { 
     this.context = context; 
     this.device = device; 

     for (int i = 0; (this.ifHid == null) && (i < device.getInterfaceCount()); i++) 
      if (device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_HID) { 
       this.ifHid = device.getInterface(i); 
       for (int j = 0; j < ifHid.getEndpointCount(); j++) { 
        UsbEndpoint ep = ifHid.getEndpoint(j); 
        if ((ep.getDirection() == UsbConstants.USB_DIR_IN) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_INT)) 
         epIn = ep; 
       } 
      } 
     if (this.ifHid == null) 
      throw new IllegalArgumentException("Device has no HID interface"); 
     else if (this.epIn == null) 
      throw new IllegalArgumentException("Device has no INTERRUPT IN endpoint (type USB_ENDPOINT_XFER_INT, direction USB_DIR_IN"); 

     this.manager = (UsbManager) context.getSystemService(Context.USB_SERVICE); 
     this.connection = manager.openDevice(device); 
     if (!connection.claimInterface(ifHid, true)) 
      throw new IOException("Failed to claim HID interface"); 
    } 

    public int getFeatureReport(int reportId, byte[] data, int length) { 
     if ((reportId & 0xFF) != reportId) 
      throw new IllegalArgumentException("reportId may only set the lowest 8 bits"); 
     return connection.controlTransfer(
       UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_CLASS | UsbConstants.USB_INTERFACE_SUBCLASS_BOOT, 
       REQUEST_GET_REPORT, 
       reportId | REPORT_TYPE_OUTPUT, 
       ifHid.getId(), data, length, 0); 
    } 

    public int read(byte[] data, int length) { 
     return connection.bulkTransfer(epIn, data, length, 0); 
    } 

    public int sendFeatureReport(int reportId, byte[] data, int length) { 
     if ((reportId & 0xFF) != reportId) 
      throw new IllegalArgumentException("reportId may only set the lowest 8 bits"); 
     return connection.controlTransfer(
       UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_CLASS | UsbConstants.USB_INTERFACE_SUBCLASS_BOOT, 
       REQUEST_SET_REPORT, 
       reportId | REPORT_TYPE_INPUT, 
       ifHid.getId(), data, length, 0); 
    } 
} 

機能レポートを送信またはクエリする際HIDAPIとは異なり、Androidはレポート番号用に別の引数を持っている、ということに注意してください:私は、Androidの周りに小さなラッパークラスを記述することにより、HID一部の呼び出しに解決しました。データ配列をあらかじめ入力する必要はありません。ただし、結果が返されると、結果の配列の最初の要素としてレポート番号が返されます。

ハイレベルなものについてはLinux driverをご覧ください。 hid_open()HidDeviceのコンストラクタに対応し、残りは単純明快でなければなりません。

byte[]配列のデータを結合するときに、Javaの符号なし整数型がないと、望ましくない副作用が生じる可能性があることに注意してください。回避策はdata[i]ではなく(data[i] & 0xFF)を使用することです。

オーディオはこのチャンネルでは転送されません。ドングルは別のオーディオデバイスを実装しています。これは標準のLinuxオーディオデバイスのようです。しかし、私のプロジェクトではRDSデータだけが必要です。

関連する問題