blob: 13f0b463ddc2b926b6d9ecaa6ecbccf98b1eaae2 [file]
**********
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.