| ********** | |
| 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 per direction, at least the ``_epsize`` of | |
| ``TUD_CDC_DESCRIPTOR``. | |
| * - ``CFG_TUD_CDC_NOTIFY`` | |
| - ``0`` | |
| - Compiles the ``tud_cdc_n_notify_*`` API and its buffer for sending | |
| serial-state and other notifications. The notification endpoint is | |
| opened whenever the descriptor has one, regardless of this option. | |
| * - ``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. RX transfers then can request up to ``CFG_TUD_CDC_RX_EPSIZE`` | |
| (otherwise one packet); make it a multiple of ``_epsize``. | |
| * - ``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. | |
| The common data path polls each port from the application loop, after | |
| ``tud_task()``. Polling is needed if ``tud_cdc_rx_cb()`` can leave bytes unread | |
| (for example because the TX FIFO is full): reception stops while the RX FIFO | |
| has less than one packet of room. | |
| .. code-block:: c | |
| void cdc_echo_task(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()`` | |
| - Both require the device configured and not suspended; ``connected`` | |
| also needs DTR asserted, ``ready`` needs both data endpoints open. | |
| Neither checks TX FIFO room; use ``tud_cdc_n_write_available()``. | |
| * - ``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. | |
| ``tuh_cdc_set_line_coding()`` works with every adapter family; for FTDI, | |
| CP210x, and CH34x it sends the baud rate and data format as two requests. | |
| .. 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 device address and a rebuilt | |
| interface descriptor. ``bInterfaceClass`` reads CDC for every adapter | |
| family; the serial-driver type is not reported. | |
| * - ``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. |