summaryrefslogtreecommitdiff
path: root/docs/reference/class/cdc.rst
blob: 13f0b463ddc2b926b6d9ecaa6ecbccf98b1eaae2 (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
160
161
162
163
164
165
166
167
168
169
**********
CDC Serial
**********

Roles: device and host.  The standard driver implements CDC ACM virtual serial
ports.  The host driver can also expose FTDI, CP210x, CH34x, and PL2303 USB
serial adapters through the same ``tuh_cdc_*`` API.

Device
======

Enable ``CFG_TUD_CDC`` with the required port count and add one
``TUD_CDC_DESCRIPTOR`` per port.

.. list-table::
   :header-rows: 1
   :widths: 36 18 46

   * - Option
     - Default
     - What it controls
   * - ``CFG_TUD_CDC_RX_BUFSIZE`` / ``CFG_TUD_CDC_TX_BUFSIZE``
     - Device bulk maximum
     - Software FIFO capacity in each direction.  Larger FIFOs absorb longer
       application scheduling gaps.
   * - ``CFG_TUD_CDC_RX_EPSIZE`` / ``CFG_TUD_CDC_TX_EPSIZE``
     - Device bulk maximum
     - Endpoint transfer buffer and descriptor packet size.  Use
       speed-appropriate values.
   * - ``CFG_TUD_CDC_NOTIFY``
     - ``0``
     - Enables the interrupt notification endpoint and serial-state API.
   * - ``CFG_TUD_CDC_RX_PERSISTENT`` / ``CFG_TUD_CDC_TX_PERSISTENT``
     - ``0``
     - Keeps the corresponding FIFO contents across disconnect/reconnect.
       Enable only when stale bytes are intentional.
   * - ``CFG_TUD_CDC_RX_NEED_ZLP``
     - ``0``
     - Enables multi-packet receive transfers terminated by a host-sent
       zero-length packet.  Enable only when the host side supports this
       framing.
   * - ``CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED``
     - ``1``
     - Allows writes made before DTR connection to replace old queued data
       rather than permanently filling the FIFO.

Use speed-dependent values from an example when the device can enumerate at
high speed.  ``CFG_TUD_CDC_NOTIFY`` enables serial-state notifications.

The common data path is:

.. code-block:: c

   void tud_cdc_rx_cb(uint8_t itf) {
     uint8_t buf[64];
     uint32_t count = tud_cdc_n_available(itf);
     uint32_t room = tud_cdc_n_write_available(itf);
     if (count > sizeof(buf)) count = sizeof(buf);
     if (count > room) count = room;

     count = tud_cdc_n_read(itf, buf, count);
     if (count && tud_cdc_n_write(itf, buf, count) == count) {
       tud_cdc_n_write_flush(itf);
     }
   }

Use ``tud_cdc_n_connected()`` when transmission should depend on DTR.  A port
can be mounted while a terminal has not opened it.  Handle line settings in
``tud_cdc_line_state_cb()`` and ``tud_cdc_line_coding_cb()`` if they affect the
physical UART; TinyUSB does not configure that UART for you.

.. list-table::
   :header-rows: 1
   :widths: 39 61

   * - Device API or callback
     - What it does
   * - ``tud_cdc_n_connected()`` / ``tud_cdc_n_ready()``
     - Tests DTR connection, or whether the port is connected and can accept
       output now.
   * - ``tud_cdc_n_available()`` / ``tud_cdc_n_read()``
     - Reports and removes bytes received from the host.
   * - ``tud_cdc_n_write_available()`` / ``tud_cdc_n_write()``
     - Reports TX FIFO room and copies as many bytes as fit; preserve any
       unwritten remainder.
   * - ``tud_cdc_n_write_flush()``
     - Starts transmission of buffered bytes without waiting for the FIFO to
       fill.
   * - ``tud_cdc_rx_cb()`` / ``tud_cdc_tx_complete_cb()``
     - Announces newly buffered receive data or completion of a transmit
       transfer.
   * - ``tud_cdc_line_state_cb()`` / ``tud_cdc_line_coding_cb()``
     - Reports host DTR/RTS and baud/data/parity/stop settings so a UART bridge
       can apply them.

See :doc:`../../examples/device/cdc_dual_ports` for multiple ports and
:doc:`../../examples/device/cdc_msc` for a composite device.

Host
====

Set ``CFG_TUH_CDC`` to the required number of serial interfaces.  Enable only
the adapter families needed by the product:

.. code-block:: c

   #define CFG_TUH_CDC        1
   #define CFG_TUH_CDC_FTDI   1
   #define CFG_TUH_CDC_CP210X 1
   #define CFG_TUH_CDC_CH34X  1
   #define CFG_TUH_CDC_PL2303 1

The RX/TX software FIFO and endpoint buffers default to
``TUH_EPSIZE_BULK_MAX`` through ``CFG_TUH_CDC_RX_BUFSIZE``,
``CFG_TUH_CDC_TX_BUFSIZE``, ``CFG_TUH_CDC_RX_EPSIZE``, and
``CFG_TUH_CDC_TX_EPSIZE``.  Increase FIFO sizes to tolerate application
latency; endpoint sizes normally stay at the host bulk maximum.  Optional
``CFG_TUH_CDC_LINE_CODING_ON_ENUM`` and
``CFG_TUH_CDC_LINE_CONTROL_ON_ENUM`` values apply initial serial settings as
part of enumeration.

``tuh_cdc_mount_cb(idx)`` reports a ready interface.  Read data in
``tuh_cdc_rx_cb(idx)`` using ``tuh_cdc_read_available()`` and
``tuh_cdc_read()``.  Queue output with ``tuh_cdc_write()`` and call
``tuh_cdc_write_flush()`` when it should leave promptly.

Line-control functions such as ``tuh_cdc_set_baudrate()`` and
``tuh_cdc_set_line_coding()`` accept a completion callback.  Their ``_sync``
forms block and should only be used where the host task can continue running.
Support varies by adapter family; in particular, the combined line-coding call
is not implemented for every non-CDC adapter.

.. list-table::
   :header-rows: 1
   :widths: 39 61

   * - Host API or callback
     - What it does
   * - ``tuh_cdc_mounted()`` / ``tuh_cdc_itf_get_info()``
     - Tests an interface index and returns its address, interface descriptor,
       and serial-driver type.
   * - ``tuh_cdc_read_available()`` / ``tuh_cdc_read()``
     - Reports and removes bytes buffered from the serial device.
   * - ``tuh_cdc_write()`` / ``tuh_cdc_write_flush()``
     - Copies output into the class FIFO and starts a USB transfer.
   * - ``tuh_cdc_set_control_line_state()`` /
       ``tuh_cdc_set_line_coding()``
     - Queues DTR/RTS or baud/framing changes and calls the supplied completion
       callback.
   * - ``tuh_cdc_mount_cb()`` / ``tuh_cdc_umount_cb()``
     - Creates or removes application state for a serial interface index.
   * - ``tuh_cdc_rx_cb()`` / ``tuh_cdc_tx_complete_cb()``
     - Announces buffered input or completion of queued class output.

The :doc:`../../examples/host/cdc_msc_hid` example shows enumeration, 115200
8N1 setup, and bidirectional I/O.

Practical notes
===============

* USB CDC transfers bytes, not UART timing.  Baud rate and framing are host
  requests that an application may honor, translate, or ignore.
* A write call can accept fewer bytes than requested.  Preserve and retry the
  remainder instead of silently dropping it.
* For interactive traffic, flush after a logical message.  For throughput,
  allow the FIFO to fill and flush less often.

Specifications used: *Communications Devices Class*, Revision 1.2 (Errata 1),
and *CDC PSTN Subclass*, Revision 1.2, which defines ACM.