Skip to content

Description on UART API (uart.h) is vague, semantics unclear, possibly questionable #3457

@zephyrbot

Description

@zephyrbot

Reported by Paul Sokolovsky:

Reading thru uart.h, there're few questionable docstrings for functions, let's go thru the few:

{code:java}

  • @brief Enable RX interrupt in IER.
    static inline void uart_irq_rx_enable(struct device *dev)
    {code}

Using acronyms like "IER" leaves an impression that the API is adhoc, designed/tailored for a particular hardware, nor a generic UART interface.

{code:java}

  • @brief Check if nothing remains to be transmitted
    static inline int uart_irq_tx_empty(struct device *dev)
    {code}

The semantics from the description doesn't seem to be useful. The expected meaning of "tx empty" (from how corresponding condition/IRQ/status bits are usually called in various SoCs) is "there's a room in tx FIFO". That's useful, because in that case we can write more data into FIFO. Note that this works even for degenerate case of FIFO of depth 1 (i.e. single TX data register).

{code:java}

  • @brief Check if Rx IRQ has been raised.
    static inline int uart_irq_rx_ready(struct device *dev)
    {code}

That's too generic. An apparent description should be "check if one or more characters are ready in receive FIFO" (also works for a case of single RX data reg).

{code:java}

  • @brief Check if Tx IRQ has been raised.
    static inline int uart_irq_tx_ready(struct device *dev)
    {code}

Similar to rx_ready, and with semantics of tx_empty clearly defined, the meaning of this should be "entire tx FIFO has been transmitted". This event is rarely useful in practice. A case when it's useful is e.g. when one wants to disable UART block (e.g. to save power). Then, one needs to wait for transmission to complete before doing this. It would make sense to rename this to tc_complete.

Note that I may get semantics of tx_empty vs tx_ready reversed. But again, this is based on how vendors often (well, maybe sometimes) call the things, at least for a case when there's single TX register. It being empty means that more data can be written into it. So, if the original semantics is reversed to what I propose, then there's still possibility that some implementer may get it wrong. Then we probably should rename the calls to disambiguate. As an example, STM32 implements both tx_empty and tx_ready using the same underlying flag, TXE (tx register empty), which can't be right. Note also that tx_enable and tx_disable work with another bit, TC (tx complete), which is also likely not right (before commit 8c079e9, it worked with TXE[IE]).

{code:java}

  • @brief Update cached contents of IIR.
    static inline int uart_irq_update(struct device *dev)
    {code}

I would say what this call should do is clear, unfortunately, the description throws it all off. It should update cached contents of IIR, but what is there's no "IIR"? Undefined behavior, anything is possible. Indeed, STM32 for some reason acknowledges (resets) TC bit. Even the datasheet says: "The TC bit can also be cleared by writing a '0' to it. This clearing sequence is recommended only for multibuffer communication." (multibuffer == apparently double-buffered DMA one, which we don't do).

(Imported from Jira ZEP-2016)

Metadata

Metadata

Assignees

Labels

area: UARTUniversal Asynchronous Receiver-TransmitterbugThe issue is a bug, or the PR is fixing a bugpriority: mediumMedium impact/importance bug

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions