@@ -223,3 +223,62 @@ instance (``n``) and is used as an argument to the :c:func:`usbd_register_class`
223
223
+-----------------------------------+-------------------------+-------------------------+
224
224
| Bluetooth HCI USB transport layer | :ref: `bt_hci_raw ` | :samp: `bt_hci_{ n } ` |
225
225
+-----------------------------------+-------------------------+-------------------------+
226
+
227
+ CDC ACM UART
228
+ ============
229
+
230
+ CDC ACM implements a virtual UART controller and provides Interrupt-driven UART
231
+ API and Polling UART API.
232
+
233
+ Interrupt-driven UART API
234
+ -------------------------
235
+
236
+ Internally the implementation uses two ringbuffers, these take over the
237
+ function of the TX/RX FIFOs (TX/RX buffers) from the :ref: `uart_interrupt_api `.
238
+
239
+ As described in the :ref: `uart_interrupt_api `, the functions
240
+ :c:func: `uart_irq_update() `, :c:func: `uart_irq_is_pending `,
241
+ :c:func: `uart_irq_rx_ready() `, :c:func: `uart_irq_tx_ready() `
242
+ :c:func: `uart_fifo_read() `, and :c:func: `uart_fifo_fill() `
243
+ should be called from the interrupt handler, see
244
+ :c:func: `uart_irq_callback_user_data_set() `. To prevent undefined behaviour,
245
+ the implementation of these functions checks in what context they are called
246
+ and fails if it is not an interrupt handler.
247
+
248
+ Also, as described in the UART API, :c:func: `uart_irq_is_pending `
249
+ :c:func: `uart_irq_rx_ready() `, and :c:func: `uart_irq_tx_ready() `
250
+ can only be called after :c:func: `uart_irq_update() `.
251
+
252
+ Simplified, the interrupt handler should look something like:
253
+
254
+ .. code-block :: c
255
+
256
+ static void interrupt_handler(const struct device *dev, void *user_data)
257
+ {
258
+ while (uart_irq_update(dev) && uart_irq_is_pending(dev)) {
259
+ if (uart_irq_rx_ready(dev)) {
260
+ int len;
261
+ int n;
262
+
263
+ /* ... */
264
+ n = uart_fifo_read(dev, buffer, len);
265
+ /* ... */
266
+ }
267
+
268
+ if (uart_irq_tx_ready(dev)) {
269
+ int len;
270
+ int n;
271
+
272
+ /* ... */
273
+ n = uart_fifo_fill(dev, buffer, len);
274
+ /* ... */
275
+ }
276
+ }
277
+
278
+ All these functions are not directly dependent on the status of the USB device.
279
+ Filling the TX FIFO does not mean that data is being sent to the host. And
280
+ successfully reading the RX FIFO does not mean that the device is still
281
+ connected to the host. If there is space in the TX FIFO, and the TX interrupt
282
+ is enabled, :c:func: `uart_irq_tx_ready() ` will succeed. If there is data in the
283
+ RX FIFO, and the RX interrupt is enabled, :c:func: `uart_irq_rx_ready() ` will
284
+ succeed. Function :c:func: `uart_irq_tx_complete() ` is not implemented yet.
0 commit comments