doc: usb: describe CDC ACM virtual UART IRQ API behavior
In general, it mirrors what is described in Interrupt-driven API documentation, but here a little more explicitly and with a simplified example, so that we can finally chisel it into the stone. Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This commit is contained in:
parent
64ee885950
commit
1867e71df2
1 changed files with 59 additions and 0 deletions
|
|
@ -223,3 +223,62 @@ instance (``n``) and is used as an argument to the :c:func:`usbd_register_class`
|
|||
+-----------------------------------+-------------------------+-------------------------+
|
||||
| Bluetooth HCI USB transport layer | :ref:`bt_hci_raw` | :samp:`bt_hci_{n}` |
|
||||
+-----------------------------------+-------------------------+-------------------------+
|
||||
|
||||
CDC ACM UART
|
||||
============
|
||||
|
||||
CDC ACM implements a virtual UART controller and provides Interrupt-driven UART
|
||||
API and Polling UART API.
|
||||
|
||||
Interrupt-driven UART API
|
||||
-------------------------
|
||||
|
||||
Internally the implementation uses two ringbuffers, these take over the
|
||||
function of the TX/RX FIFOs (TX/RX buffers) from the :ref:`uart_interrupt_api`.
|
||||
|
||||
As described in the :ref:`uart_interrupt_api`, the functions
|
||||
:c:func:`uart_irq_update()`, :c:func:`uart_irq_is_pending`,
|
||||
:c:func:`uart_irq_rx_ready()`, :c:func:`uart_irq_tx_ready()`
|
||||
:c:func:`uart_fifo_read()`, and :c:func:`uart_fifo_fill()`
|
||||
should be called from the interrupt handler, see
|
||||
:c:func:`uart_irq_callback_user_data_set()`. To prevent undefined behaviour,
|
||||
the implementation of these functions checks in what context they are called
|
||||
and fails if it is not an interrupt handler.
|
||||
|
||||
Also, as described in the UART API, :c:func:`uart_irq_is_pending`
|
||||
:c:func:`uart_irq_rx_ready()`, and :c:func:`uart_irq_tx_ready()`
|
||||
can only be called after :c:func:`uart_irq_update()`.
|
||||
|
||||
Simplified, the interrupt handler should look something like:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static void interrupt_handler(const struct device *dev, void *user_data)
|
||||
{
|
||||
while (uart_irq_update(dev) && uart_irq_is_pending(dev)) {
|
||||
if (uart_irq_rx_ready(dev)) {
|
||||
int len;
|
||||
int n;
|
||||
|
||||
/* ... */
|
||||
n = uart_fifo_read(dev, buffer, len);
|
||||
/* ... */
|
||||
}
|
||||
|
||||
if (uart_irq_tx_ready(dev)) {
|
||||
int len;
|
||||
int n;
|
||||
|
||||
/* ... */
|
||||
n = uart_fifo_fill(dev, buffer, len);
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
|
||||
All these functions are not directly dependent on the status of the USB device.
|
||||
Filling the TX FIFO does not mean that data is being sent to the host. And
|
||||
successfully reading the RX FIFO does not mean that the device is still
|
||||
connected to the host. If there is space in the TX FIFO, and the TX interrupt
|
||||
is enabled, :c:func:`uart_irq_tx_ready()` will succeed. If there is data in the
|
||||
RX FIFO, and the RX interrupt is enabled, :c:func:`uart_irq_rx_ready()` will
|
||||
succeed. Function :c:func:`uart_irq_tx_complete()` is not implemented yet.
|
||||
|
|
|
|||
Loading…
Reference in a new issue