summaryrefslogtreecommitdiff
path: root/docs/reference/class/device.rst
blob: 8a67a0f452dd71fa9abd7f11ad5e1fb1bc716a2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
********************
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 space for control transfers.  Increase it when a class control
       request must hold more than one endpoint packet.
   * - ``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.
   * - ``tud_task()`` / ``tud_task_ext()``
     - Dispatches bus, control, class, and completion events.  The extended
       form selects a wait timeout and states whether the call is 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.  These
       return ``false`` when the controller cannot provide the operation.
   * - ``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, and high-speed companion
       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
=====================

Class callbacks run when ``tud_task()`` processes an event, unless a header
explicitly labels a helper as ISR-safe.  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.  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 agree with the relevant ``CFG_TUD_*_EPSIZE`` values;
* callbacks never retain a pointer whose documented lifetime has ended.