********** 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.