Skip to content

Commit 4cf1847

Browse files
nordic-krchkartben
authored andcommitted
drivers: serial: nrfx_uarte: Support for low power polling mode
Add support for getting to the lowest power mode when polling is used with disable-rx property and interrupts are not used for that UARTE. So far disabling of the UARTE peripheral was done in the interrupt but in some cases interrupt may not be available and in that case uart_poll_out shall wait until byte is transferred and put UARTE into the lowest power state. Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent 77c2c45 commit 4cf1847

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

drivers/serial/Kconfig.nrfx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ config UART_NRFX_UARTE
2828
imply NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG if !UART_NRFX_UARTE_LEGACY_SHIM
2929
imply NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG if !UART_NRFX_UARTE_LEGACY_SHIM
3030

31+
config UART_NRFX_UARTE_NO_IRQ
32+
bool "Polling without interrupt"
33+
depends on UART_NRFX_UARTE
34+
depends on !UART_ASYNC_API && !UART_INTERRUPT_DRIVEN
35+
help
36+
When enabled, then interrupt handler is not used at all and it is possible
37+
to get to the lowest power state after uart_poll_out if receiver is not used.
38+
3139
config UART_NRFX_UARTE_LEGACY_SHIM
3240
bool "Legacy UARTE shim"
3341
depends on UART_NRFX_UARTE

drivers/serial/uart_nrfx_uarte.c

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@ static inline NRF_UARTE_Type *get_uarte_instance(const struct device *dev)
373373
return config->uarte_regs;
374374
}
375375

376+
#if !defined(CONFIG_UART_NRFX_UARTE_NO_IRQ)
377+
376378
static void endtx_isr(const struct device *dev)
377379
{
378380
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
@@ -388,6 +390,8 @@ static void endtx_isr(const struct device *dev)
388390

389391
}
390392

393+
#endif
394+
391395
/** @brief Disable UARTE peripheral is not used by RX or TX.
392396
*
393397
* It must be called with interrupts locked so that deciding if no direction is
@@ -426,7 +430,7 @@ static void uarte_disable_locked(const struct device *dev, uint32_t dis_mask)
426430
nrf_uarte_disable(get_uarte_instance(dev));
427431
}
428432

429-
#ifdef UARTE_ANY_NONE_ASYNC
433+
#if defined(UARTE_ANY_NONE_ASYNC) && !defined(CONFIG_UART_NRFX_UARTE_NO_IRQ)
430434
/**
431435
* @brief Interrupt service routine.
432436
*
@@ -503,7 +507,7 @@ static void uarte_nrfx_isr_int(const void *arg)
503507
}
504508
#endif /* UARTE_INTERRUPT_DRIVEN */
505509
}
506-
#endif /* UARTE_ANY_NONE_ASYNC */
510+
#endif /* UARTE_ANY_NONE_ASYNC && !CONFIG_UART_NRFX_UARTE_NO_IRQ */
507511

508512
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
509513
/**
@@ -1978,14 +1982,36 @@ static void uarte_nrfx_poll_out(const struct device *dev, unsigned char c)
19781982
}
19791983
}
19801984

1981-
if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) || LOW_POWER_ENABLED(config)) {
1985+
if (!IS_ENABLED(CONFIG_UART_NRFX_UARTE_NO_IRQ) &&
1986+
(IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) || LOW_POWER_ENABLED(config))) {
19821987
nrf_uarte_int_enable(uarte, NRF_UARTE_INT_TXSTOPPED_MASK);
19831988
}
19841989

19851990
*config->poll_out_byte = c;
19861991
tx_start(dev, config->poll_out_byte, 1);
19871992

19881993
irq_unlock(key);
1994+
1995+
if (IS_ENABLED(CONFIG_UART_NRFX_UARTE_NO_IRQ)) {
1996+
key = wait_tx_ready(dev);
1997+
if (!IS_ENABLED(UARTE_HAS_ENDTX_STOPTX_SHORT) &&
1998+
!(config->flags & UARTE_CFG_FLAG_PPI_ENDTX)) {
1999+
nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STOPTX);
2000+
nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_TXSTOPPED);
2001+
while (!nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_TXSTOPPED)) {
2002+
}
2003+
}
2004+
2005+
if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
2006+
if (!(data->flags & UARTE_FLAG_POLL_OUT)) {
2007+
data->flags &= ~UARTE_FLAG_POLL_OUT;
2008+
pm_device_runtime_put(dev);
2009+
}
2010+
} else if (LOW_POWER_ENABLED(config)) {
2011+
uarte_disable_locked(dev, UARTE_FLAG_LOW_POWER_TX);
2012+
}
2013+
irq_unlock(key);
2014+
}
19892015
}
19902016

19912017

@@ -2253,7 +2279,7 @@ static void wait_for_tx_stopped(const struct device *dev)
22532279
NRFX_WAIT_FOR(nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_TXSTOPPED),
22542280
1000, 1, res);
22552281

2256-
if (!ppi_endtx) {
2282+
if (!ppi_endtx && !IS_ENABLED(CONFIG_UART_NRFX_UARTE_NO_IRQ)) {
22572283
nrf_uarte_int_enable(uarte, NRF_UARTE_INT_ENDTX_MASK);
22582284
}
22592285
}
@@ -2398,7 +2424,9 @@ static int uarte_tx_path_init(const struct device *dev)
23982424
}
23992425
nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_ENDTX);
24002426
nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STOPTX);
2401-
nrf_uarte_int_enable(uarte, NRF_UARTE_INT_ENDTX_MASK);
2427+
if (!IS_ENABLED(CONFIG_UART_NRFX_UARTE_NO_IRQ)) {
2428+
nrf_uarte_int_enable(uarte, NRF_UARTE_INT_ENDTX_MASK);
2429+
}
24022430
}
24032431
while (!nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_TXSTOPPED)) {
24042432
}
@@ -2465,9 +2493,10 @@ static int uarte_instance_init(const struct device *dev,
24652493

24662494
/* Depending on configuration standard or direct IRQ is connected. */
24672495
#define UARTE_IRQ_CONNECT(idx, irqn, prio) \
2468-
COND_CODE_1(CONFIG_UART_NRFX_UARTE_DIRECT_ISR, \
2469-
(IRQ_DIRECT_CONNECT(irqn, prio, uarte_##idx##_direct_isr, 0)), \
2470-
(IRQ_CONNECT(irqn, prio, UARTE_GET_ISR(idx), DEVICE_DT_GET(UARTE(idx)), 0)))
2496+
COND_CODE_1(CONFIG_UART_NRFX_UARTE_NO_IRQ, (), \
2497+
(COND_CODE_1(CONFIG_UART_NRFX_UARTE_DIRECT_ISR, \
2498+
(IRQ_DIRECT_CONNECT(irqn, prio, uarte_##idx##_direct_isr, 0)), \
2499+
(IRQ_CONNECT(irqn, prio, UARTE_GET_ISR(idx), DEVICE_DT_GET(UARTE(idx)), 0)))))
24712500

24722501
#define UARTE_IRQ_CONFIGURE(idx) \
24732502
do { \

0 commit comments

Comments
 (0)