Request fast global domain to run at 320 MHz during fast UARTE
activity. As request is asynchronous it cannot be called from
an ISR. Due to complexity to handle that without device runtime
power management a requirement is added so that if fast UARTE
is used device runtime PM must be enabled. Clock is request
and released in PM resume and suspended actions which in case
of fast UARTE are only called from thread context.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Low power mode for non-asynchronous API case is only available when
RX is not used (RX pin is not defined). In that case TX starting
function was using uarte_enable_locked() which tracks if UARTE is
used by TX or RX and TXSTOPPED interrupt was disabling UARTE
unconditionally. Because of that following attempt to TX start
was assuming that UARTE is already enabled when it was disabled.
Fixing it by using uarte_disable_locked function in TXSTOPPED
handling.
Code reordering was required to make uarte_disable_locked()
available earlier.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
The assert BUILD_ASSERT(NRF_GPD_FAST_ACTIVE1 == 0); is not correct
given that NRF_GPD_FAST_ACTIVE1 is defined as 1U, and is not used
in the file anyway. Remove the build assert.
Signed-off-by: Bjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>
When fast UARTE instance is used (e.g. UARTE120 in nrf54h20), PM actions
are not ISR safe because they include communication over IPC so they can
only be called from the thread context. Extend driver to support both
PM modes. When non ISR mode is used then uart_rx_enable() and uart_tx()
will return error if they are called from ISR and resume operation
would need to be called because device is suspended. On completion,
driver is calling pm_device_runtime_put_async which can be called from
the ISR context.
Additionally, suspending in the TXSTOPPED and RXTO events has been
moved after user callback. It allows to support the case where
uart_rx_enable() or uart_tx() are called from that callback context.
Since suspending is called after returning from the callback it will
not trigger suspend action because API called in the callback context
will increment the usage counter (when pm_device_runtime_get() is
called).
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Or more precisely, do not remove the workaround for them.
The current HW models are accurate enough in this area for the
workaround to work properly.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
TX part of interrupt driven API was not calling PM device runtime
API. Additionally, when txstopped occurred after poll out it was
not handled correctly.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
b6d45423c6 Added support for pin retention but it was added
only to the case when device PM is used. There is another mode
in which UARTE is disabled when idle (low power mode) and in
that case pin retention must also be added.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
RX FIFO flushing on RXTO event should only be performed when
UARTE peripheral might be disable during inactivity and that
happens when low power modes is enabled or when device runtime
PM is used. Flushing was incrementing flush_cnt which was not
used (flushed data is not copied to the next buffer) which
was causing data loss and invalid RX data length reporting.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
When GPD is managed by pinctrl, pins retention needs to be controlled by
the driver to avoid glitches.
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Optimize function which enables UARTE peripheral. It is called
only when interrupts are locked so data->flags does not require
atomic operation. Use standard logical operations so save few
bytes.
Simplify uarte_disable_locked.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Improved a workaround. When FIFO is not empty then FLUSHRX
task will generate RXSTARTED event to indicated that DMA transfer
was started. This property can be used to detect when FIFO was
not empty and workaroud a HW bug where RX.AMOUNT register is not
updated after flushing empty FIFO.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Add runtime PM to the driver. When asynchronous or interrupt
driven API is used, there are 3 independent paths for enabling
the device: RX, TX and TX poll_out. TX poll_out requires special
handling because number of poll_out calls does not need to much
number of TXSTOPPED interrupts. To handle that special flag is
added. For standard RX and TX is simpler.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
A code ifdefed by UARTE_BAUDRATE_RETENTION_WORKAROUND was missing a
closing bracket. It was missed because CI did not compile any target
that is applying this workaround and enables code compilation.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Add lock to fix race when uart_rx_disable is interrupted by RXTO
event which lead to driver state corruption.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
On uart120 BAUDRATE register is not retained when ENABLE=0 and
because of that BAUDRATE must be set after enabling. Add workaround
to the driver.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Add configurable magic byte instead of fixed 0xAA. In some cases, it
is known that certain bytes are less likely in the transmission and
picking specific magic byte may reduce probability of failure of
detection of the correct amount of flushed data.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Add support for DMM which manages cache and dedicated memory spaces.
Added support for data cache for buffers which are not DMM managed.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Frame timeout is a hardware feature present in newer versions
of UARTE (e.g. in NRF54X platforms) for detecting idle state
on RX line and ending RX after configurable timeout.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Rework driver to support new way of asynchronous RX handling.
Previously RX was handled in two modes: using RXDRDY interrupt for byte
counting or TIMER + PPI. Both modes had flaws. RXDRDY interrupt mode
could miscalculated amount of received bytes when interrupt was not
handled on time. Data was not lost but was not reported on time that
could lead to issues. PPI+TIMER mode requires additional resources
thus it was not the default mode. Often user was not aware of that
option and was expiriencing driver RX faults.
New RX mode is switching buffers when there is new data (RXDRDY event
not set for given amount of time). It does not require additional
resources to get precise byte counting. Additionally, this is in line
with new UARTE feature (RX frame timeout) which is present in nRF54X
devices. The behavior of the driver is the same for legacy devices
and new one. For legacy devices k_timer periodic interrupts are used
to check if there are any new bytes and it is not needed when RX frame
timeout is present.
Improved RX mode is enabled by default
(CONFIG_UART_NRFX_UARTE_ENHANCED_RX=y) but legacy modes are still
available though not recommended to be used.
Note that new RX mode (CONFIG_UART_NRFX_UARTE_ENHANCED_RX=y) behaves
a bit different because timeout always triggers switch of buffers
which means that there will be no UART_RX_RDY events with non-zero
offset. It also means that every UART_RX_RDY will be followed by
UART_RX_BUF_RELEASED.
After rework, driver is recommended to be used for all platforms as it
performs much better and takes much less code than the second UART shim
available for Nordic devices.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Refactor RX asynchronous API function to use a pointer to the RX
async data structure instead of top level data structure pointer.
It improves readability with more concise code.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Update nrfx drivers with the minimum number of bytes that can be sent
in a single call to `uart_fifo_fill`.
Signed-off-by: Jordan Yates <jordan@embeint.com>
This is a leftover from pre-pinctrl era and no longer makes sense.
Driver always manages gpio through pinctrl.
Support removed from uart and uarte shims.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
When rx_flush() was called with NULL buffer it was an indication to
drop data from the FIFO. However, it is still important to get the
correct amount of dropped data because when PPI+TIMER are used to
count bytes those flushed bytes are also counted (because each
byte generates RXDRDY event). If those bytes are not counted then
total amount of reported bytes is not correctly aligned with bytes
counted by TIMER.
Reworking rx_flush() to correctly count number of dropped bytes and
then add this flushed bytes to the total amount of RX bytes
reported to the user in RXTO event handler.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
When interrupt driven instance is using only TX then low power mode
is automatically enabled and then TXSTOPPED interrupt is disabled in
idle so uarte_nrfx_irq_tx_ready_complete() was returning wrong value.
Adding a dedicate flag which holds information is user enabled TX
interrupt.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
The initialization of the UARTE is attempting to handle potential
improper handover from the bootloader. This handling is additional
complexity which should be fixed in the bootloader or whatever
component is failing to deinit the UART properly.
This commit removes the handling of improper handover from the
bootloader, while additionally clearing the ERROR flag when suspending
the UARTE component.
Signed-off-by: Bjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>
Code size can significantly reduced (220 bytes per instance) if data
structure (stored in RAM) is not initilized (can be moved to .bss).
Data for asynchronous API had two fields which can easily be moved
to the configuration structure (which is in ROM) because they do not
change duing runtime.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
When runtime configuration is not enable then we can determine at
compile time what are the hardware settings. Function which
translates zephyr values to nRF register values is not needed as
macros can do that at compile time.
This optimization saves almost 400 bytes of code.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Some UARTE instances may be clocked at higher speeds than 16MHz, so the
baudrate setting needs to be scaled accordingly. This patch parses the
`clocks` property and obtains the clock-frequency property of the
associated clock, assuming it is a fixed-clock. We should ideally have a
proper clock control subsystem where frequency can be queried using an
API, but we're far from there.
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
This is needed to avoid warnings about uninitialized
structure member, which was added in nrfx 3.6.
Signed-off-by: Nikodem Kastelik <nikodem.kastelik@nordicsemi.no>
When low power mode is enabled then whenever UARTE is not active,
driver attempts to put the peripheral into the lowest power state
by stopping and disabling UARTE. However, it did not put pins into
sleep state which could lead to increased current consumption.
Adding pins state handling to the low power mode.
Pins are put into sleep state only if CONFIG_PM_DEVICE=y.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Legacy shim takes less flash so it should be a first choice on cores
with less code memory (like RISCV cores on nrf54h20). Adding new
instances support to the legacy shim.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
UART_RX_RDY event can be generated from UARTE interrupt or k_timer
handler. When ENDRX event occurs then k_timer is stopped (it can
be restarted if there is another buffer provided). However, if UARTE
interrupt priority is higher than k_timer priority (RTC is used
underneath) then k_timer handler may still be executed later.
K_timer notifies new bytes based on RXDRDY HW event which is
counter by the TIMER (using PPI). It may happen that RXDRDY
event arrives due to byte received into RX FIFO but since there is
not buffer provided it stays in that FIFO. Given all this, it
was possible that RX_RDY event was reported from ENDRX UARTE event,
timer was stopped but because UARTE interrupt had higher priority
timer handler is executed after UARTE interrupt is handled. In
timer handler TIMER counter reports more bytes and calls
UART_RX_RDY event with null buffer and non-zero amount of bytes.
Fixed by generating UART_RX_RDY event only if RX buffer is not
null.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Increase the busy wait time granularity while runing in simulation
for poll mode. In this mode, the driver spends a *lot* of time
waiting for the UART to be done. The smallest frame time is
~10µs @ 1Mbps, so busywaiting in very small increments
is very wastefull as we keep shuting down and turning on the simulated
MCU.
Let's increase the busy wait time increments of the driver to 3 micros,
which should not change much the behaviour.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
While waiting for the UART to be ready in ISR
mode, for simulation only, add a tiny delay per
iteration of the busy wait loops to allow
time to pass.
This Z_SPIN_DELAY is an empty macro for any
other target than simulation.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
For simulation, we cannot get the UART regiter address
for the pinctrl config structure from DT, as that
cannot match the one allocated at build time.
So let's override it at runtime with the correct address
which is stored in the UART config structure.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
Instead of getting the hardcoded address from the DT structure
use its symbolic name which will be resolved by the nRF HAL
definitions to the same value.
This allows the GPIO peripherals' addresses to be redefined
for the simulated targets.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
The ISR prototype used when building without the
interrupt driven UART was not matching the
signature for interrupt handlers, which results in
build warnings.
Let's fix it.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
Rework Kconfig to improve handling of multiple UART instances by
using Kconfig template file.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
When rx_timeout is set to a sufficiently small value,
rx_timeout_slab could potentially get set to a greater
than necessary value that causes spurious UART_RX_RDY
events.
Fixes#62828
Signed-off-by: Jacob Preston <jacob.preston@synapse.com>
This commit fixes an issue with the nrfx uarte driver to allow the
async and interrupt driven UART APIs to coexist on different uart
instances. As both APIs cannot be used simultaneously for a given
instance, there is no need to handle
CONFIG_UART_EXCLUSIVE_API_CALLBACKS in this driver.
Signed-off-by: Eivind Jølsgard <eivind.jolsgard@nordicsemi.no>
- use CONFIG_HAS_HW_NRF_* symbols consistently in nRF multi-instance
drivers when creating particular driver instances
- remove unnecessary hidden Kconfig options that indicated the type of
peripheral to be used by a given instance (e.g. SPI, SPIM, or SPIS)
and enabled proper nrfx driver instance; instead, use one option per
peripheral type and include the corresponding shim driver flavor into
compilation basing on that option (not the one that enables the nrfx
driver as it was incorrectly done so far in some cases)
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>