• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# USB Isochronous Transfer
2
3<!--Kit: Basic Services Kit-->
4<!--Subsystem: USB-->
5<!--Owner: @hwymlgitcode-->
6<!--Designer: @w00373942-->
7<!--Tester: @dong-dongzhen-->
8<!--Adviser: @w_Machine_cc-->
9
10## When to Use
11
12Isochronous transfer is a transfer mode in which data is transferred in a fixed time window through the USB protocol. This ensures the timing stability and low latency of data streams, but allows a small amount of data loss (such as video frame loss and audio noise). This transfer mode is applicable to scenarios that have high requirements on continuity and fault tolerance, such as USB headsets, USB speakers, and video conferencing devices.
13
14## Preparing the Environment
15
16### Environment Requirements
17
18- Development tool and configuration:
19
20  DevEco Studio, as the driver development tool, allows you to develop, debug, and package drivers. [Download and install](https://developer.huawei.com/consumer/en/download/) DevEco Studio and verify basic operations to ensure that it can function properly. For details, see [Creating a Project](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-create-new-project) in [DevEco Studio User Guide](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-tools-overview).
21
22
23- SDK version configuration:
24
25  The ArkTs APIs for peripheral management can be used only when the SDK is of API version 16 or later.
26
27
28- HDC configuration:
29
30  HarmonyOS Device Connector (hdc) is a command-line tool for debugging. It can be used to interact with real devices or the Emulators on Windows, Linux, and macOS. For details about the configuration, see [hdc](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/hdc).
31
32### Environment Setup
33
34- Install [DevEco Studio](https://developer.huawei.com/consumer/en/download/) 4.1 or later on the PC.
35- Update the public SDK to API version 16 or later.<!--Del--> For details, see [Switching to Full SDK](../../../../faqs/full-sdk-switch-guide.md).<!--DelEnd-->
36- Install hdc on the PC. You can use it to interact with a real device or the Emulator on Windows, Linux, or macOS.
37- Use a USB cable to connect a device to the PC.
38
39## How to Develop
40
41### Available APIs
42
43| API                                                                                                             | Description                                                     |
44|------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------|
45| usbSubmitTransfer(transfer: UsbDataTransferParams): void                                                         | Submits isochronous, bulk, or interrupt transfer in an asynchronous manner.                                  |
46| usbCancelTransfer(transfer: UsbDataTransferParams): void                                                         | Cancels the submitted asynchronous transfer.                                            |
47
48For details about the APIs of device management and transfer modes, see [@ohos.usbManager (USB Manager)](../../../../reference/apis-basic-services-kit/js-apis-usbManager.md).
49
50### How to Develop
51
52Connect a host to a device and use the **usbSubmitTransfer** API to transfer data. The following steps describe how to implement an interrupt transfer:
53
54> **NOTE**
55>
56> The following sample code shows only a basic process. You should execute the code in a specific method. When calling this method, you must comply with device protocols to ensure proper data transfer and device compatibility.
57
581. Import modules.
59
60    ```ts
61    // Import the usbManager module.
62    import { usbManager } from '@kit.BasicServicesKit';
63    ```
64
652. Obtain the USB device list.
66
67    ```ts
68    // Obtain the list of USB devices connected to the host.
69    let usbDevices: Array<usbManager.USBDevice> = usbManager.getDevices();
70    console.info(`usbDevices: ${usbDevices}`);
71    if(usbDevices.length === 0) {
72      console.error('usbDevices is empty');
73      return;
74    }
75    ```
76
773. Obtain the device operation permissions.
78
79    ```ts
80    // Check whether the first USB device in the list has the access permission.
81    // Name the function based on the specific service.
82    async function transferDefault() {
83        let usbDevice: usbManager.USBDevice = usbDevices[0];
84        if(!usbManager.hasRight(usbDevice.name)) {
85          await usbManager.requestRight(usbDevice.name).then(result => {
86            if(!result) {
87              // If the USB device does not have the access permission and is not granted by the user, the device exits.
88              console.error('The user does not have permission to perform this operation');
89              return;
90            }
91          });
92        }
93    }
94    ```
95
964. Obtain the endpoint for reading data through interrupt transfer.
97
98   ```ts
99   let devicePipe: usbManager.USBDevicePipe = usbManager.connectDevice(usbDevice);
100   let usbConfigs: usbManager.USBConfiguration[] = usbDevice.configs;
101   let usbInterfaces: usbManager.USBInterface[] = [];
102   let usbInterface: usbManager.USBInterface | undefined = undefined
103   let usbEndpoints: usbManager.USBEndpoint[] = [];
104   let usbEndpoint: usbManager.USBEndpoint | undefined = undefined
105   for (let i = 0; i < usbConfigs.length; i++) {
106     usbInterfaces = usbConfigs[i].interfaces;
107     for (let j = 0; j < usbInterfaces.length; j++) {
108       usbEndpoints = usbInterfaces[j].endpoints;
109       usbEndpoint = usbEndpoints.find((value) => {
110         // direction indicates the request direction. The value 0 indicates the written data, and the value 128 indicates the read data.
111         return value.direction === 128 && value.type === usbManager.UsbEndpointTransferType.TRANSFER_TYPE_ISOCHRONOUS;
112       })
113       if (usbEndpoint !== undefined) {
114         usbInterface = usbInterfaces[j];
115         break;
116       }
117     }
118   }
119   if (usbEndpoint === undefined) {
120     console.error(`get usbEndpoint error`)
121     return;
122   }
123   ```
124
1255. Connect to the device and register the communication interface.
126
127    ```ts
128    // Register a communication interface. If the registration is successful, 0 is returned; otherwise, other error codes are returned.
129    let claimInterfaceResult: number = usbManager.claimInterface(devicePipe, usbInterface, true);
130    if (claimInterfaceResult !== 0) {
131      console.error(`claimInterface error = ${claimInterfaceResult}`)
132      return;
133    }
134
135    // When the transfer is of the isochronous type, you need to register a device interface. If the registration is successful, 0 is returned; otherwise, other error codes are returned.
136    if (usbEndpoint.type === usbManager.UsbEndpointTransferType.TRANSFER_TYPE_ISOCHRONOUS) {
137      let setInterfaceResult = usbManager.setInterface(devicePipe, usbInterface);
138      if (setInterfaceResult !== 0) {
139        console.error(`setInterfaceResult error = ${setInterfaceResult}`)
140        return;
141      }
142    }
143    ```
144
1456. Perform data transfer.
146
147   ```ts
148   try {
149     // The communication interface is successfully registered and performs data transfer.
150     let transferParams: usbManager.UsbDataTransferParams = {
151       devPipe: devicePipe,
152       flags: usbManager.UsbTransferFlags.USB_TRANSFER_SHORT_NOT_OK,
153       endpoint: usbEndpoint.address,
154       type: usbManager.UsbEndpointTransferType.TRANSFER_TYPE_ISOCHRONOUS,
155       timeout: 2000,
156       length: 10,
157       callback: () => {},
158       userData: new Uint8Array(10),
159       buffer: new Uint8Array(10),
160       isoPacketCount: 2,
161     };
162
163     transferParams.callback = (err: Error, callBackData: usbManager.SubmitTransferCallback) => {
164       console.info(`callBackData = ${callBackData}`);
165       console.info('transfer success, result = ' + transferParams.buffer.toString());
166     }
167     usbManager.usbSubmitTransfer(transferParams);
168     console.info('USB transfer request submitted.');
169   } catch (error) {
170     console.error(`USB transfer failed: ${error}`);
171   }
172   ```
173
1747. Cancel the data transfer, releases the interface, and closes the USB device pipe.
175
176    ```ts
177    usbManager.usbCancelTransfer(transferParams);
178    usbManager.releaseInterface(devicePipe, usbInterface);
179    usbManager.closePipe(devicePipe);
180    ```
181
182### Verification
183
1841. Connect the host to a device (such as a USB headset) that supports isochronous transfer through a USB interface.
1852. Execute the preceding code.
1863. Search for the keyword **transfer success** in the log. If the keyword is found, the isochronous transfer interface is successfully called.
187