Skip to content

uart: nrfx_uarte: drivers/serial/uart_nrfx_uarte.c: uarte_nrfx_isr_int disables uarte TXSTOPPED if PM_DEVICE_RUNTIME enabled during interrupt driven output #91387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 task done
helpfulchicken opened this issue Jun 10, 2025 · 0 comments
Labels
bug The issue is a bug, or the PR is fixing a bug

Comments

@helpfulchicken
Copy link

helpfulchicken commented Jun 10, 2025

Describe the bug

Interrupt driven UART output fails when using nRF UARTE in v4.0 if CONFIG_PM_DEVICE_RUNTIME is enabled while not using low power mode for the UART.

Platform: nRF, such as nRF52840DK

I've narrowed it down to a specific set of changes from a specific commit: 3ce19da
https://github.com/zephyrproject-rtos/zephyr/aabd3a1826d750f2ae4b271894837a91f42186bc/drivers/serial/uart_nrfx_uarte.c#L351-L372

bool txstopped = nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_TXSTOPPED);
if (txstopped && (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) || LOW_POWER_ENABLED(config))) {
unsigned int key = irq_lock();
if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) &&
(data->flags & UARTE_FLAG_POLL_OUT)) {
data->flags &= ~UARTE_FLAG_POLL_OUT;
pm_device_runtime_put(dev);
} else {
nrf_uarte_disable(uarte);
}
#ifdef UARTE_INTERRUPT_DRIVEN
if (!data->int_driven || data->int_driven->fifo_fill_lock == 0)
#endif
{
nrf_uarte_int_disable(uarte, NRF_UARTE_INT_TXSTOPPED_MASK);
}
irq_unlock(key);
}

Prior to this commit, this conditional branch only executes nrf_uarte_disable after a TxStopped event if the UART was configured for low power.

Now this conditional branch also executes nrf_uarte_disable on line 358 after a TxStopped event if CONFIG_PM_DEVICE_RUNTIME is enabled while transmit is NOT polling based. This breaks the prior interrupt based transmit behaviour where a user could use their interrupt driven callback to load data into the uart fifo after each TxStopped event without the uarte unexpectedly being disabled.

The commit originally introducing that nrf_uarte_disable call (f075fee) talks about adding low power mode for the uarte peripheral, so I believe the intent is that it is only called if the uart is actually configured for low power mode, not as a side effect of CONFIG_PM_DEVICE_RUNTIME=y plus using interrupt driven transmit.

By the same logic, the nrf_uarte_int_disable section highlighted below might be unintentionally called, but it would be easy to workaround by re-enabling the tx irq from the user uart irq callback.

#ifdef UARTE_INTERRUPT_DRIVEN
if (!data->int_driven || data->int_driven->fifo_fill_lock == 0)
#endif
{
nrf_uarte_int_disable(uarte, NRF_UARTE_INT_TXSTOPPED_MASK);
}


Suggested fix:
Add a condition to 'else' branch requiring LOW_POWER_ENABLED(config), so that as originally intended it is only called after the TXSTOPPED event if the uart is configured for low power.

	if (txstopped && (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) || LOW_POWER_ENABLED(config))) {
		unsigned int key = irq_lock();

		if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) &&
		    (data->flags & UARTE_FLAG_POLL_OUT)) {
			data->flags &= ~UARTE_FLAG_POLL_OUT;
			pm_device_runtime_put(dev);
		} else if (LOW_POWER_ENABLED(config)){
			nrf_uarte_disable(uarte);
		}

Regression

  • This is a regression.

Steps to reproduce

Reproduction notes:

  • take an interrupt driven UART program, target a nRF board with a UARTE peripheral
  • use interrupt driven UART to send data, like filling the uart fifo from the user irq callback
  • enable CONFIG_PM_DEVICE_RUNTIME
  • ensure the devicetree for the UART has compatible = "nordic,nrf-uarte" and doesn't have low-power-enable
  • note that the nrf uarte peripheral gets disabled as soon as a TXSTOPPED event is processed, so refilling the uart fifo from the user irq callback doesn't get the expected result, even if the uarte tx irq is re-enabled by the user.

Relevant log output

Impact

Major – Severely degrades functionality; workaround is difficult or unavailable.

Environment

OS: Windows
Toolchain: Zephyr 4.0

Additional Context

nRF family target,
uarte peripheral enabled, (compatible = "nordic,nrf-uarte"), without low power enabled
config enabling CONFIG_PM_DEVICE_RUNTIME and CONFIG_UART_INTERRUPT_DRIVEN

@helpfulchicken helpfulchicken added the bug The issue is a bug, or the PR is fixing a bug label Jun 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug The issue is a bug, or the PR is fixing a bug
Projects
None yet
Development

No branches or pull requests

1 participant