IF_ENABLED expands UART_NRF_UARTE_DEVICE before discarding declarations
for disabled instances. Select the declaration macro before invoking it
to avoid this work.
For blinky on nrf54l15dk/nrf54l15/cpuapp, uncached compilation of
uart_nrfx_uarte.c drops from approximately 4.7 s to 1.3 s.
Assisted-by: Codex:GPT-6
Signed-off-by: Guðni Már Gilbert <gudni.m.g@gmail.com>
cyhal only parks the pad when it knows the TX pin exists. Passing NC
left it floating for the whole sleep. Resolve it from the mux table.
Assisted-by: Copilot:claude-opus-5
Signed-off-by: Richard Mc Sweeney <Richard.McSweeney@infineon.com>
cyhal_uart_putc() returns once the byte is in the FIFO, so poll_out
returned early and a draining shifter made the SCB veto DeepSleep.
This now blocks until the byte is shifted out.
Assisted-by: Copilot:claude-opus-5
Signed-off-by: Richard Mc Sweeney <Richard.McSweeney@infineon.com>
The LPSCI stores no data while S1[OR] is set and only uart_err_check()
cleared it, so interrupt-driven RX stalled after an overrun. Clear OR
in the ISR after the callback and enable the overrun interrupt, as
uart_mcux_lpuart does. Not tested on hardware.
Assisted-by: Claude:opus-5.5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The ISR read the enabled interrupt status and passed it to
disableInterrupt at the end of every callback invocation. This
silently disabled whichever UART interrupt had just fired, causing
the shell and any other interrupt-driven consumer to stop receiving
input after the first event.
Remove the disable call. The TX interrupt flag is level-sensitive and
stays set while the transmit buffer is empty; the registered callback
is responsible for disabling TX interrupts once it has no more data
to send.
Signed-off-by: Gail Rojas <gailroco@gmail.com>
Assisted-by: Claude
The function checked the transmit-complete flag after writing each
byte rather than the transmit-ready flag before. Transmit-complete
fires after the shift register empties, not when the buffer is ready
to accept a new byte, so the old check had the wrong contract and
dropped bytes under load.
Check the transmit-ready flag before writing and extract it into a
local variable so the loop condition stays within the 80-column limit.
Signed-off-by: Gail Rojas <gailroco@gmail.com>
Assisted-by: Claude
The function read from the receive buffer unconditionally and returned
0 even when no byte had arrived, giving callers stale or uninitialized
data. Check the receive interrupt flag before reading and return -1
immediately if the buffer is empty, matching the poll_in contract
required by the Zephyr UART API.
Signed-off-by: Gail Rojas <gailroco@gmail.com>
Assisted-by: Claude
Replace direct NVIC_*PendingIRQ()/NVIC_EnableIRQ()/NVIC_DisableIRQ()
calls with k_irq_clear_pending()/k_irq_set_pending()/k_irq_is_pending() and
irq_enable()/irq_disable(), dropping the driver's dependency on
cmsis_core.h where nothing else needed it.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
poll() reports a hung-up or failed tty as ready, so the interrupt
emulation thread called the UART callback forever while every read
failed: unplugging a USB serial adapter left the application spinning.
native_tty_poll_bottom(), the host side of the poll, now returns EIO on
POLLHUP and POLLERR, EBADF on POLLNVAL and the host's errno when poll()
itself fails, all as NSI_ERRNO_MID_* values, and the thread exits the
process naming the port and the error, as opening it does when it is
missing.
A poll() interrupted by a signal is not an error: it reports no data, and
the thread polls again on its next iteration.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
The EUSART driver incorrectly increments the configured data width
when parity is enabled. Silicon Labs EUSART hardware configures data
bits and parity independently.
As a result, 7-bit configurations with parity use 8 data bits, while
8-bit configurations with parity use 9 data bits.
Remove the parity-dependent adjustment and map the requested UART
data width directly to the EUSART hardware configuration.
Signed-off-by: Emin Ates <m.emin.ates@hotmail.com>
This driver was defining each instance using KConfig, we now have
DT_INST_FOREACH helpers to define multiple instances. Update to
this to allow arbitrary instance counts.
This then allows us to drop the KConfig symbols that once were
used for the above. But we do need to keep part of them around
in the SoC dir as these also set the power enable bits for these
devices. This could most likely be also updated to some form
of automatic PM handling, but for now just keep things simple.
Signed-off-by: Andrew Davis <afd@ti.com>
In the async RX DMA completion callback, dma_reload() and dma_start()
were called after three user-visible callbacks (UART_RX_RDY,
UART_RX_BUF_RELEASED, UART_RX_BUF_REQUEST). During this window the
DMA was idle and only the RX FIFO protected against data loss.
Reorder the callback so that dma_reload() and dma_start() are called
immediately after the driver state is updated, before any user
callbacks are issued. Bytes arriving during the callbacks are then
captured by DMA rather than stalling in the RX FIFO.
Signed-off-by: Michal Chromec <michal.chromec@nxp.com>
Include the UART needed for console output on the Erbium board. Its
original Shakti integration uses 32-bit MMIO accesses at eight-byte
register intervals, while the generic Shakti driver uses four-byte
intervals and mixed access widths.
Use openhwgroup,shakti-uart-v1 to identify the original register layout,
with interrupt enable at 0x30 and receive threshold at 0x40. The later
Erbium UART has a different interrupt register layout. Link the public
register documentation for the supported revision in the binding [1].
Follow the documented transmit flow: wait for space in the FIFO and
write the character. The functional emulator [2] also enqueues data on
the TX write, without additional configuration-register writes.
Provide polling input/output, receive error reporting and fixed 8N1
initialization. Calculate the baud divisor at build time from devicetree
clock-frequency and current-speed. Reject zero baud rates and divisors
outside 1..65535 with build assertions. Keep the divisor in the constant
device configuration and program it once at initialization. Use the
device MMIO API and add the serial Kconfig and CMake integration.
Validate polling transmit and receive with actual input on the public
et-platform functional emulator at 836a4ab600e93. Interrupt-driven,
asynchronous and runtime line-configuration APIs remain unsupported.
[1] 325b32b7ef/doc/uart.md
[2] 836a4ab600/sw-sysemu/devices/shakti_uart.h
Signed-off-by: Afonso Oliveira <afonso.oliveira707@gmail.com>
Assisted-by: Codex:GPT-6
The ip register reports the watermark conditions regardless of the ie
register, so with the TX FIFO empty and the TX interrupt disabled
uart_irq_is_pending() kept returning 1 and callbacks that loop until
nothing is pending never terminated. Mask ip with ie.
Fixes the test_uart_pending case of tests/drivers/uart/uart_basic_api,
run on qemu_riscv32_xip.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
mcux_lpuart_poll_out() waited for the transmit data register to be empty
with interrupts locked, which holds them off for up to a character time.
It now waits with interrupts enabled, and locks them only to check again
and write the character.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5.5
Initialize rx_buf, rx_buf_len, rx_buf_offset, rx_buf_data_len, rx_en,
written, and rx_stopping at declaration. These are always assigned
before use on every path, but static analysis cannot prove this
through the K_SPINLOCK for-loop construct, producing false-positive
uninitialized-read warnings (MISRA C:2012 Rule 9.1).
No functional change.
Signed-off-by: Dominika Kubicz <dominika.kubicz@gmail.com>
A USB bus reset leaves data already in the USB Serial/JTAG IN
FIFO uncommitted: the FIFO is not marked free and the data is
never sent. The host resets the bus several times while
enumerating, so output written before or during enumeration can
stall TX for good while RX keeps working. Whether it hits depends
on boot timing.
Flush the IN FIFO in poll_out() when it is not writable. In
interrupt mode, arm the EP1 IN token interrupt on each bus reset
and flush on the first token, once the host is reading.
Assisted-by: Claude:opus-5
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
SIFIVE_PERIPHERAL_CLOCK_FREQUENCY is the same for every instance, so
use it directly when computing the baud rate divisor instead of
storing a copy in each device config.
Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
For interrupt-driven transfers, PM must be locked until data has
been fully shifted out. Postpone releasing the PM lock until TXC
is reported.
Split handling of TXBL and TXC such that TXBL maps to the user-facing
callback, while TXC is only used internally in the driver. Only handle
TXC and RXOF in the async ISR when an async transfer is active, so the
interrupt-driven API receives them otherwise.
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
If the first RX buffer was filled as soon as the DMA started, the DMA
callback could report UART_RX_DISABLED before rx_enable() emitted
UART_RX_BUF_REQUEST, so the request arrived for a disabled receiver.
Lock interrupts from enabling the RX interrupts until the buffer request
has been emitted, so the DMA completion is handled after the request and
can use a buffer provided in response to it. This also keeps an RX
overflow interrupt from disabling RX before the DMA is started.
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
RX could complete in the DMA callback before rx_enable() enabled the
RX overflow and timeout interrupts, leaving them enabled while RX was
disabled.
Enable the interrupts before starting the DMA, and disable them again
if the DMA fails to start.
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
When the RX DMA buffer was filled and no next buffer was provided, the
DMA callback stopped RX and reported UART_RX_DISABLED, but left the RXOF
and TCMP1 interrupts enabled. A later overrun or receive timeout then
raised async events for a receiver that was already disabled.
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
LOG_WRN_ONCE() keeps one flag per call site, so the warning in
uart_bt_fifo_fill() fires once per boot for all instances. Output
dropped in a later period without a subscriber goes unreported.
Use LOG_WRN_RATELIMIT() so the warning repeats, at most once per
CONFIG_LOG_RATELIMIT_INTERVAL_MS.
Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Arkadiusz Grzelka <arkadiusz.grzelka@arivemb.com>
Run the RX timeout from a k_timer, in interrupt context like the idle
line and DMA events that also flush received data, instead of a
delayable work item on the system work queue. This avoids a work queue
thread wakeup for each burst of received data.
Assisted-by: Claude:opus-5.5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The LPUART driver for NXP devices did not support
the single-wire mode for the UART peripheral.
This has been fixed by switching the TXDIR bit to TX mode upon entry of
function: mcux_lpuart_poll_out() and switching it back to RX mode
at the end of the function when single-wire mode is selected.
Signed-off-by: Luis Casas <luis.casas@nxp.com>
With CONFIG_UART_EXCLUSIVE_API_CALLBACKS, setting the callback of one
API must remove the callback of the other.
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
The transceiver must be manually shut down prior to going to
deep sleep, otherwise the state will be inconsistent on wakeup.
Register a PM notifier to disable and reenable the transceiver.
In the future, this should be implemented as a power management
TURN_ON/TURN_OFF callback called from a power domain driver.
Since no such driver exists yet for Series 2, deal with it ad-hoc
from the UART driver itself.
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
For interrupt-driven transfers, PM must be locked until data has
been fully shifted out. Postpone releasing the PM lock until TXC
is reported.
Split handling of TXFL and TXC such that TXFL maps to the user-facing
callback, while TXC is only used internally in the driver.
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
The interrupt-driven and async APIs share TXC and RXOF. When the
driver had DMA channels, the ISR handled every enabled TXC and RXOF as
an async event, producing spurious UART_TX_DONE and UART_RX_STOPPED
events.
Handle RXTO and RXOF as async events only while async RX is enabled,
and TXC only while an async TX is outstanding.
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
When the RX DMA buffer was filled and no next buffer was provided, the
DMA callback stopped RX and reported UART_RX_DISABLED, but left the RXOF
and RXTO interrupts enabled. A later overrun or receive timeout then
raised async events for a receiver that was already disabled.
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
The emulated UART never initialized its struct uart_config, so
uart_config_get() returned an all-zero configuration until
uart_configure() was called: a baudrate of 0, no parity,
UART_CFG_STOP_BITS_0_5, UART_CFG_DATA_BITS_5 and no flow control. The
current-speed, parity, stop-bits, data-bits and hw-flow-control
properties that the binding inherits from uart-controller.yaml were
ignored.
Users doing a get/modify/set of the configuration then write that bogus
framing back. For instance, modem_cellular_baudrate_update() in the
modem_cellular driver only changes the baudrate, so with the emulator it
configures 5 data bits and 0.5 stop bits, and the original baudrate it
saves for later restoration is 0.
Initialize the configuration from devicetree, as other UART drivers do,
and fall back to 115200 baud, 8 data bits, no parity, 1 stop bit and no
flow control for absent properties. Nodes setting current-speed = <0>
still report a baudrate of 0.
Assisted-by: Claude:opus-5.5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Output written while no peer is subscribed, boot output included, is
buffered for the first peer that subscribes. Once the buffer is full,
an interrupt-driven writer such as the shell stalls: only tx_work frees
buffer space, and it does not run until a peer subscribes.
Keep the buffering, with RTT semantics: while nobody is subscribed, a
full buffer drops new output and the writer never waits.
uart_bt_fifo_fill() reports all of it written and uart_bt_irq_tx_ready()
stays ready.
Also check the return value of every work submit and schedule call.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Arkadiusz Grzelka <devitwise@gmail.com>
Fix an issue that when global configs: CONFIG_UART_INTERRUPT_DRIVEN
and CONFIG_UART_ASYNC_API are enabled simultaneously, the channel
which running interrupt driven mode hit the issue that the hardware
interrupt flags will be never cleared.
Signed-off-by: The.Thanh Nguyen <the.nguyen.yf@renesas.com>
The async API hands caller buffers to the eDMA without any cache
maintenance, so on a core with a data cache TX sends stale data and RX
reports stale bytes unless the buffers sit in DTCM or non-cacheable
memory. Boards placing zephyr,sram in OCRAM, such as vmu_rt1170, are
affected.
Flush TX buffers before starting the DMA, clean and invalidate RX
buffers when they are handed to the DMA, and again for each range
reported in UART_RX_RDY. Select CACHE_MANAGEMENT so the cache API is
backed whenever a data cache is present.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5.5
uart_stm32_configure() disables the USART, applies the new parameters
and returns -ENOTSUP if the baud rate is rejected. The USART is left
disabled with the new framing already applied, so on a console UART
the next poll_out() waits forever for TXE.
Set the baud rate before any other field, and check its range before
writing any register, so a rejected configuration leaves the registers
untouched. configure() then only re-enables the USART and the previous
configuration keeps working.
Fixes#121176
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: YunHung Hua <oliverhua.us@gmail.com>
On the USART path, uart_stm32_set_baudrate() only rejects a USARTDIV
below 16. BRR is 16 bits wide and LL_USART_SetBaudRate() writes the
divider truncated to uint16_t, so a rate whose divider exceeds 0xFFFF
is programmed as a faster rate and the call still returns 0: 1200 baud
from an 84 MHz clock needs a divider of 70000, which is written as 4464
(18817 baud). Reject those rates as well.
Fixes#121176
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: YunHung Hua <oliverhua.us@gmail.com>
UHCI hands received bytes to the DMA only when a packet ends, on
length or after an idle period. rx_disable() stopped the DMA
right away, so bytes still held by UHCI were lost.
Make rx_disable() asynchronous: mask the RX FIFO interrupt, lower
the UART idle threshold and enable the idle EOF, then finish the
stop from a dedicated work item a few character times later. The
EOF moves the pending bytes into the buffer and sets the count
from the descriptor. While the stop is pending, the DMA
completion and the timeout work leave the buffer to the stop
work, and a pending stop is cancelled when the DMA runs out of
buffers first.
Assisted-by: Claude:opus-5
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Bytes received while async RX was off stay in the RX FIFO and are
delivered at the start of the next buffer. Reset the RX FIFO in
rx_enable() before the RX interrupts are armed again.
Assisted-by: Claude:opus-5
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
UART_TX_DONE was raised from the DMA completion, while the tail of
the buffer was still in the TX FIFO. A caller acting on TX_DONE,
for example by disabling RX or suspending the device, cut the
transfer short.
Arm the UART TX_DONE interrupt when the DMA completes and report
the event from the ISR once the transmitter is idle. Release the
TX state before the callback so a chained uart_tx() is accepted,
and reject a new transfer while the FIFO drains. On abort, flush
the TX FIFO and drop the drain PM lock along with the TX state,
and clear the state when a transfer fails to start.
Assisted-by: Claude:opus-5
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Pair the ARC range operations' arch_irq_lock() with arch_irq_unlock()
to avoid decrementing an outer SMP global lock. Use local IRQ locking
for the all-cache operations too; shared SLC locking is unchanged.
Pair irq_lock() with irq_unlock() in the ESP32 USB serial callback to
balance its SMP global lock state.
Signed-off-by: Jinming Zhao <jinmzhao@qti.qualcomm.com>
The PM_DEVICE_ACTION_TURN_ON handler assigns the clock divider through
data->clock, which does not exist with PERI_CLOCK_V2, so every
PM_DEVICE build fails on kit_t2g_c2d6m_lite. Skip it there as
ifx_cat1_uart_init() does: ifx_cat1_uart_configure() assigns the
divider through the clock control driver.
Assisted-by: Claude:opus-5.5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
The RX completion combined the EOF descriptor length with rx_offset,
which double-reported bytes after a finite idle timeout. The GDMA
driver also invokes the RX callback for non-EOF descriptor blocks.
Ignore block callbacks, derive an absolute buffer position from the
EOF descriptor, and protect callbacks and timeout work when RX is
rearmed.
Retain FIFO interrupt counting for RX disable before the open DMA
descriptor has written back its received length. Clamp the count to
the buffer and report only bytes beyond rx_offset. Clear a pending FIFO
interrupt when EOF has already consumed its bytes, so it cannot increment
the next buffer's counter.
Validate initial and successor RX buffer lengths against the UHCI
packet threshold, and clear RX state when DMA setup fails.
Signed-off-by: JiaXiang Liang <moonbite233@gmail.com>
Assisted-by: Codex:gpt-6
An async RX buffer can be released without a successor while RXFIFO
level interrupts remain enabled. A byte left in the FIFO then keeps
the UART ISR running and starves the system timer.
Use the shared RX disable helper to mask interrupts at both async stop
points. Keep the PM lock release in the async paths, as interrupt-driven
RX does not hold that lock. Drop completion and timeout work after the
RX buffer has been released.
Signed-off-by: JiaXiang Liang <moonbite233@gmail.com>
Assisted-by: Codex:gpt-6
uart_async_sf32lb_rx_disable() and uart_async_sf32lb_tx_abort() jump to
their shared unlock label when the DMA channel is busy, which is before
irq_lock() has run, so irq_unlock() writes an uninitialized value to
PRIMASK. Return -EBUSY directly, as the other async entry points
already do on the same check.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5
ifx_cat1_uart_configure() stored the requested uart_config into
data->cfg at the top of the function, before ifx_cat1_uart_set_baud()
ran. When the requested rate is unachievable -- for example 9600 baud on
an SCB clocked from an 8-bit peripheral divider group, where the divider
needed overflows the register -- set_baud() fails and configure()
returns -ENOTSUP, but data->cfg has already been overwritten with the
rejected configuration.
Every subsequent uart_config_get() then returns the bad config, and each
per-test re-init re-applies and re-fails it, cascading a single rejected
reconfigure across an entire suite (observed as drivers.uart.async_api
failing on kit_psc3m5_evk after test_read_abort switches to 9600 baud).
Cache data->cfg only after set_baud() succeeds, so a rejected
reconfigure leaves the previously-applied configuration intact.
Verified on kit_psc3m5_evk/psc3m5fds2afq1 with an SCB on an 8-bit divider
group: uart_configure(9600) is rejected (-ENOTSUP) and uart_config_get()
now returns the prior 115200 config instead of the rejected 9600.
Assisted-by: AI (GitHub Copilot)
Signed-off-by: Bill Waters <bill.waters@infineon.com>
The PDL asserts on zero-length FIFO reads and writes, which the UART
API allows; return 0 for them.
uart_irq_is_pending() and uart_irq_tx_ready() read the latched
interrupt status, which the PDL clears only after the callback
returns, so a callback looping on uart_irq_is_pending() never
returned. Use the RX and TX FIFO levels instead.
Tested with hci_uart on cyw920829m2evk_02/cyw20829b0lkml.
Assisted-by: Copilot:claude-opus-5.5
Signed-off-by: Merin George <merin.george@infineon.com>
The async API, its DMA callbacks and event helpers repeat the full
data->async.dma_rx.<member> and data->async.dma_tx.<member> chains on
every access. The long, repetitive statements make the code hard to
read.
Take a local pointer to the stream (dma_tx, dma_rx) and to the async
context (async) at the top of each function that uses them, and rejoin
the statements that now fit on one line.
No functional change.
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
data_bits_lut and stop_bits_lut are only used inside
uart_infineon_pdl.c. Give them internal linkage so they are no longer
exported as global symbols.
Also remove parity_lut. It was never referenced, because the parity
conversion already uses a switch statement.
Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>