| ******************** | |
| Using Device Classes | |
| ******************** | |
| A device class needs three matching pieces: a nonzero ``CFG_TUD_*`` instance | |
| count, class descriptors in the configuration descriptor, and the required | |
| application callbacks. Start from the nearest device example instead of | |
| writing descriptors from scratch. | |
| Setup checklist | |
| =============== | |
| 1. Enable the device stack and each class in ``tusb_config.h``. A class value | |
| is normally the maximum number of simultaneous class instances, not a | |
| boolean. | |
| 2. Add the matching ``TUD_*_DESCRIPTOR`` macro to the configuration descriptor | |
| and include its ``TUD_*_DESC_LEN`` in the total length. | |
| 3. Assign unique interface numbers and endpoint addresses. Some functions use | |
| more than one interface; for example, CDC ACM normally uses two. | |
| 4. Implement the descriptor and class callbacks used by the example. | |
| 5. Call ``tud_task()`` regularly, or run it in a dedicated RTOS task. | |
| For example, one CDC ACM function starts with: | |
| .. code-block:: c | |
| // tusb_config.h | |
| #define CFG_TUD_ENABLED 1 | |
| #define CFG_TUD_CDC 1 | |
| // One entry inside the configuration descriptor | |
| TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 0, EPNUM_CDC_NOTIF, 8, | |
| EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), | |
| See :doc:`../../integration` for stack initialization and the full descriptor | |
| callback pattern. | |
| Common configuration options | |
| ============================ | |
| These options apply before the class-specific settings described on the other | |
| pages. Defaults come from ``src/tusb_option.h``. | |
| .. list-table:: | |
| :header-rows: 1 | |
| :widths: 30 18 52 | |
| * - Option | |
| - Default | |
| - What it controls | |
| * - ``CFG_TUD_ENABLED`` | |
| - Root-port mode | |
| - Enables the device stack. Set it explicitly when the selected root-port | |
| mode does not already select device operation. | |
| * - ``CFG_TUD_MAX_SPEED`` | |
| - Root-port mode | |
| - Highest speed for which the device stack and descriptors are built. | |
| High-speed devices also need valid qualifier and other-speed | |
| descriptors. | |
| * - ``CFG_TUD_ENDPOINT0_SIZE`` | |
| - ``64`` bytes | |
| - Control endpoint maximum packet size. It must match ``bMaxPacketSize0`` | |
| in the device descriptor and the controller's capability. | |
| * - ``CFG_TUD_ENDPOINT0_BUFSIZE`` | |
| - Endpoint 0 size | |
| - Staging buffer for control data stages; longer requests are moved | |
| through it in chunks of this size. Keep it a multiple of | |
| ``CFG_TUD_ENDPOINT0_SIZE``. Audio uses it as its control buffer when | |
| ``CFG_TUD_AUDIO_CTRL_BUF_SZ`` fits. | |
| * - ``CFG_TUD_INTERFACE_MAX`` | |
| - ``16`` | |
| - Maximum total USB interfaces across the active configuration, including | |
| every interface used by composite functions. | |
| * - ``CFG_TUD_TASK_EVENTS_PER_RUN`` | |
| - ``16`` | |
| - Maximum events handled by one ``tud_task_ext()`` call. ``0`` removes | |
| the limit; a smaller value reduces one-call latency at the cost of more | |
| task invocations. | |
| * - ``CFG_TUD_ENDPPOINT_MAX`` | |
| - Controller maximum | |
| - Highest endpoint-number pool retained by the stack. Lowering it can | |
| save RAM, but it must cover every configured endpoint number. | |
| * - ``CFG_TUD_MEM_SECTION`` / ``CFG_TUD_MEM_ALIGN`` | |
| - Common USB settings / 4-byte alignment | |
| - Places and aligns controller-facing buffers for DMA. Override these | |
| when the device controller requires a particular RAM region or | |
| alignment. | |
| ``CFG_TUD_ENDPPOINT_MAX`` contains the double ``P`` for compatibility; use the | |
| spelling shown above. | |
| Core API and callbacks | |
| ====================== | |
| .. list-table:: | |
| :header-rows: 1 | |
| :widths: 36 64 | |
| * - API or callback | |
| - What it does | |
| * - ``tusb_init()`` | |
| - Initializes a root port with an explicit role and speed. Call it before | |
| the task function and check its boolean result. With an RTOS, call it | |
| after the scheduler starts, from the task that runs ``tud_task()``. | |
| * - ``tud_task()`` / ``tud_task_ext()`` | |
| - Dispatches bus, control, class, and completion events. The extended | |
| form selects a wait timeout; its ``in_isr`` argument is currently | |
| ignored. Never call either from an ISR. | |
| * - ``tud_connected()`` / ``tud_mounted()`` / ``tud_ready()`` | |
| - Reports progressively stronger states: bus activity, configured by the | |
| host, and configured plus not suspended. Use ``tud_ready()`` before | |
| initiating normal traffic. | |
| * - ``tud_suspended()`` / ``tud_remote_wakeup()`` | |
| - Tests suspend state and requests remote wakeup. Wakeup succeeds only | |
| when the host enabled it and the device is suspended. | |
| * - ``tud_disconnect()`` / ``tud_connect()`` | |
| - Controls the USB pull-up to force a logical detach or attach. Both | |
| always return ``true``; on a controller without pull-up control the | |
| call does nothing. | |
| * - ``tud_mount_cb()`` / ``tud_umount_cb()`` | |
| - Announces configuration and removal. Initialize or discard | |
| configuration-dependent application state here. | |
| * - ``tud_suspend_cb()`` / ``tud_resume_cb()`` | |
| - Announces bus power-state changes. The suspend callback also reports | |
| whether remote wakeup was enabled by the host. | |
| * - ``tud_descriptor_*_cb()`` | |
| - Supplies device, configuration, string, BOS, device qualifier, and | |
| other-speed configuration descriptors on request. Returned storage | |
| must remain valid through the control transfer. | |
| * - ``tud_control_xfer()`` / ``tud_control_status()`` | |
| - Completes the data/status stages of an application-handled control | |
| request. The data length is truncated to the request's ``wLength``. | |
| Interfaces and instances | |
| ======================== | |
| Single-instance helpers such as ``tud_cdc_read()`` operate on instance zero. | |
| Their ``_n_`` forms, such as ``tud_cdc_n_read(itf, ...)``, select a class | |
| instance when the corresponding ``CFG_TUD_*`` value is greater than one. | |
| Class instance numbers are not necessarily USB ``bInterfaceNumber`` values. | |
| Endpoint direction is always described from the USB device's point of view: | |
| * IN sends data from the device to the host. | |
| * OUT receives data from the host at the device. | |
| Buffers and callbacks | |
| ===================== | |
| Most class callbacks run from ``tud_task()``. ``*_isr`` callbacks, such as | |
| ``tud_audio_tx_done_isr()``, and ``tud_event_hook_cb()`` usually run in | |
| interrupt context, but some ports run them synchronously inside the API call | |
| that arms the endpoint (on MUSB, re-arming an OUT endpoint can drain a staged | |
| packet and complete the transfer there). Make them safe in both contexts: no | |
| blocking and no ISR-only OS calls. A few, such as | |
| ``tud_video_prepare_payload_cb()`` and ``tud_network_xmit_cb()``, can also run | |
| inside the API call that triggers them. Keep callbacks short and move lengthy | |
| work to an application task. | |
| Buffered write APIs return the number of bytes accepted, which can be shorter | |
| than requested. Audio is the exception: its FIFOs overwrite the oldest unsent | |
| data when full (see :doc:`audio`). Check the return value and use the class's | |
| flush function when latency matters. Size endpoint and software buffers for | |
| the active bus speed; copy the full-speed/high-speed pattern from an example | |
| that supports both. | |
| Before testing on hardware, verify that: | |
| * the configuration descriptor's total length and interface count are exact; | |
| * every endpoint address is unique within the configuration; | |
| * descriptor packet sizes are legal for the endpoint type and speed, and each | |
| class endpoint buffer (``CFG_TUD_*_EPSIZE`` or ``CFG_TUD_*_EP_BUFSIZE``, see | |
| the class guide) holds at least one packet; | |
| * callbacks never retain a pointer whose documented lifetime has ended. |