From f20f795d8360886e4ef0ec8d735581f5206f34e6 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 5 Jul 2023 10:17:28 +0200 Subject: [PATCH] cpu/nrf5x_common: fix uart_poweroff() Previously, uart_poweroff() and uart_poweron() were no-ops. This replaces them with the logic to indeed power on and power off the UART device. Co-authored-by: crasbe --- cpu/nrf5x_common/periph/uart.c | 36 ++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/cpu/nrf5x_common/periph/uart.c b/cpu/nrf5x_common/periph/uart.c index 6c223c73b9..cfb2bcd179 100644 --- a/cpu/nrf5x_common/periph/uart.c +++ b/cpu/nrf5x_common/periph/uart.c @@ -28,6 +28,7 @@ * @} */ +#include #include #include @@ -99,6 +100,28 @@ enum { UART_ISR_NUMOF, }; +static inline void set_power(uart_t uart, bool value) +{ + UART_TYPE *dev = uart_config[uart].dev; + + if (value) { + dev->ENABLE = ENABLE_ON; + } + else { + dev->ENABLE = ENABLE_OFF; + } + +#ifndef UARTE_PRESENT + dev->POWER = value; +#endif +} + +static inline bool get_power(uart_t uart) +{ + UART_TYPE *dev = uart_config[uart].dev; + return dev->ENABLE != ENABLE_OFF; +} + int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) { /* ensure the ISR names have been defined as needed */ @@ -115,11 +138,6 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) isr_ctx[uart].rx_cb = rx_cb; isr_ctx[uart].arg = arg; -#ifndef UARTE_PRESENT - /* only the legacy non-EasyDMA UART needs to be powered on explicitly */ - dev->POWER = 1; -#endif - /* reset configuration registers */ dev->CONFIG = 0; @@ -206,7 +224,7 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) } /* enable the UART device */ - dev->ENABLE = ENABLE_ON; + set_power(uart, true); #ifdef MODULE_PERIPH_UART_NONBLOCKING /* set up the TX buffer */ @@ -242,6 +260,7 @@ void uart_poweron(uart_t uart) if (isr_ctx[uart].rx_cb) { uart_config[uart].dev->TASKS_STARTRX = 1; + set_power(uart, true); } } @@ -250,6 +269,7 @@ void uart_poweroff(uart_t uart) assume((unsigned)uart < UART_NUMOF); uart_config[uart].dev->TASKS_STOPRX = 1; + set_power(uart, false); } /* Unify macro names across nRF51 (UART) and nRF52 and newer (UARTE) */ @@ -335,6 +355,10 @@ static void _write_buf(uart_t uart, const uint8_t *data, size_t len) void uart_write(uart_t uart, const uint8_t *data, size_t len) { assume((unsigned)uart < UART_NUMOF); + if (!get_power(uart)) { + /* Device is powered down. Writing anyway would deadlock */ + return; + } #ifdef MODULE_PERIPH_UART_NONBLOCKING for (size_t i = 0; i < len; i++) { /* in IRQ or interrupts disabled */