This is an automated email from the ASF dual-hosted git repository.
linguini1 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new d32fdfa20b4 arch/arm/stm32: Support optional TX/RX UART GPIOs.
d32fdfa20b4 is described below
commit d32fdfa20b425b08ff5359a9524192f9cc785c4a
Author: alexcekay <[email protected]>
AuthorDate: Wed May 27 11:03:05 2026 +0200
arch/arm/stm32: Support optional TX/RX UART GPIOs.
The STM32 serial drivers already treat 0 as not present for optional
GPIO fields (CTS, RTS), guarding each call site with a != 0 check.
TX and RX GPIO fields lacked this guard, so boards that
define GPIO_UARTx_TX or GPIO_UARTx_RX as 0 (pin not routed) caused
stm32_configgpio(0) to be called, which silently configures PA0 as a
floating input, corrupting any other peripheral using that pin.
Having an optional TX/RX UART is useful for several cases:
* RX-only connections: e.g. radio control input on flight-controllers where
no TX is wired.
* Single-wire (half-duplex) connections: e.g. ESC telemetry connections.
* Output-only NSH which prints output but does not allow entering inputs.
Without a sentinel value for these cases one must assign the unused GPIO to
a NC pin, which is misleading when reading board configuration files.
Add != 0 guards for tx_gpio and rx_gpio across all STM32 serial driver
families.
Using 0 as the sentinel is safe for TX/RX because any valid UART config
requires
GPIO_ALT bits set in the config word, so 0 can never represent a real
TX or RX pin configuration.
Signed-off-by: alexcekay <[email protected]>
---
arch/arm/src/stm32/stm32_serial.c | 74 ++++++++++++++++++++++++---------
arch/arm/src/stm32f7/stm32_serial.c | 56 ++++++++++++++++++-------
arch/arm/src/stm32h5/stm32_serial.c | 49 +++++++++++++++-------
arch/arm/src/stm32h7/stm32_serial.c | 56 ++++++++++++++++++-------
arch/arm/src/stm32l4/stm32l4_serial.c | 55 +++++++++++++++++-------
arch/arm/src/stm32l5/stm32l5_serial.c | 56 ++++++++++++++++++-------
arch/arm/src/stm32n6/stm32_serial.c | 15 +++++--
arch/arm/src/stm32u5/stm32_serial.c | 56 ++++++++++++++++++-------
arch/arm/src/stm32wb/stm32wb_serial.c | 55 +++++++++++++++++-------
arch/arm/src/stm32wl5/stm32wl5_serial.c | 56 ++++++++++++++++++-------
10 files changed, 387 insertions(+), 141 deletions(-)
diff --git a/arch/arm/src/stm32/stm32_serial.c
b/arch/arm/src/stm32/stm32_serial.c
index 9c30f1d5a81..09cbe58c2fc 100644
--- a/arch/arm/src/stm32/stm32_serial.c
+++ b/arch/arm/src/stm32/stm32_serial.c
@@ -1958,8 +1958,15 @@ static int up_setup(struct uart_dev_s *dev)
/* Configure pins for USART use */
- stm32_configgpio(priv->tx_gpio);
- stm32_configgpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32_configgpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -2185,8 +2192,15 @@ static void up_shutdown(struct uart_dev_s *dev)
* then this may need to be a configuration option.
*/
- stm32_unconfiggpio(priv->tx_gpio);
- stm32_unconfiggpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_unconfiggpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32_unconfiggpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -2543,14 +2557,22 @@ static int up_ioctl(struct file *filep, int cmd,
unsigned long arg)
#if defined(CONFIG_STM32_STM32F10XX)
if ((arg & SER_SINGLEWIRE_ENABLED) != 0)
{
- stm32_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) |
- GPIO_CNF_AFOD);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) |
+ GPIO_CNF_AFOD);
+ }
+
cr |= USART_CR3_HDSEL;
}
else
{
- stm32_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) |
- GPIO_CNF_AFPP);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) |
+ GPIO_CNF_AFPP);
+ }
+
cr &= ~USART_CR3_HDSEL;
}
#else
@@ -2565,16 +2587,24 @@ static int up_ioctl(struct file *filep, int cmd,
unsigned long arg)
gpio_val |= ((arg & SER_SINGLEWIRE_PULL_MASK) ==
SER_SINGLEWIRE_PULLDOWN) ? GPIO_PULLDOWN
: GPIO_FLOAT;
- stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
- GPIO_OPENDRAIN)) |
- gpio_val);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
+ GPIO_OPENDRAIN)) |
+ gpio_val);
+ }
+
cr |= USART_CR3_HDSEL;
}
else
{
- stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
- GPIO_OPENDRAIN)) |
- GPIO_PUSHPULL);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
+ GPIO_OPENDRAIN)) |
+ GPIO_PUSHPULL);
+ }
+
cr &= ~USART_CR3_HDSEL;
}
#endif
@@ -2684,7 +2714,6 @@ static int up_ioctl(struct file *filep, int cmd, unsigned
long arg)
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
{
irqstate_t flags;
- uint32_t tx_break;
flags = enter_critical_section();
@@ -2696,9 +2725,13 @@ static int up_ioctl(struct file *filep, int cmd,
unsigned long arg)
/* Configure TX as a GPIO output pin and Send a break signal */
- tx_break = GPIO_OUTPUT | (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) &
- priv->tx_gpio);
- stm32_configgpio(tx_break);
+ if (priv->tx_gpio != 0)
+ {
+ uint32_t tx_break = GPIO_OUTPUT |
+ (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) &
+ priv->tx_gpio);
+ stm32_configgpio(tx_break);
+ }
leave_critical_section(flags);
}
@@ -2712,7 +2745,10 @@ static int up_ioctl(struct file *filep, int cmd,
unsigned long arg)
/* Configure TX back to U(S)ART */
- stm32_configgpio(priv->tx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio(priv->tx_gpio);
+ }
priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS;
diff --git a/arch/arm/src/stm32f7/stm32_serial.c
b/arch/arm/src/stm32f7/stm32_serial.c
index 3779335ad05..dd5a10c0ee0 100644
--- a/arch/arm/src/stm32f7/stm32_serial.c
+++ b/arch/arm/src/stm32f7/stm32_serial.c
@@ -1916,8 +1916,15 @@ static int up_setup(struct uart_dev_s *dev)
/* Configure pins for USART use */
- stm32_configgpio(priv->tx_gpio);
- stm32_configgpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32_configgpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -2129,8 +2136,15 @@ static void up_shutdown(struct uart_dev_s *dev)
* then this may need to be a configuration option.
*/
- stm32_unconfiggpio(priv->tx_gpio);
- stm32_unconfiggpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_unconfiggpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32_unconfiggpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -2454,15 +2468,24 @@ static int up_ioctl(struct file *filep, int cmd,
unsigned long arg)
gpio_val |= (arg & SER_SINGLEWIRE_PULL_MASK) ==
SER_SINGLEWIRE_PULLDOWN ?
GPIO_PULLDOWN : GPIO_FLOAT;
- stm32_configgpio((priv->tx_gpio &
- ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | gpio_val);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio &
+ ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
+ gpio_val);
+ }
+
cr |= USART_CR3_HDSEL;
}
else
{
- stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
- GPIO_OPENDRAIN)) |
- GPIO_PUSHPULL);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
+ GPIO_OPENDRAIN)) |
+ GPIO_PUSHPULL);
+ }
+
cr &= ~USART_CR3_HDSEL;
}
@@ -2669,7 +2692,6 @@ static int up_ioctl(struct file *filep, int cmd, unsigned
long arg)
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
{
irqstate_t flags;
- uint32_t tx_break;
flags = enter_critical_section();
@@ -2681,9 +2703,12 @@ static int up_ioctl(struct file *filep, int cmd,
unsigned long arg)
/* Configure TX as a GPIO output pin and Send a break signal */
- tx_break = GPIO_OUTPUT |
- (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
- stm32_configgpio(tx_break);
+ if (priv->tx_gpio != 0)
+ {
+ uint32_t tx_break = GPIO_OUTPUT |
+ (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
+ stm32_configgpio(tx_break);
+ }
leave_critical_section(flags);
}
@@ -2697,7 +2722,10 @@ static int up_ioctl(struct file *filep, int cmd,
unsigned long arg)
/* Configure TX back to U(S)ART */
- stm32_configgpio(priv->tx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio(priv->tx_gpio);
+ }
priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS;
diff --git a/arch/arm/src/stm32h5/stm32_serial.c
b/arch/arm/src/stm32h5/stm32_serial.c
index f166a51b3e0..4d2e94ad577 100644
--- a/arch/arm/src/stm32h5/stm32_serial.c
+++ b/arch/arm/src/stm32h5/stm32_serial.c
@@ -2171,8 +2171,15 @@ static int stm32serial_setup(struct uart_dev_s *dev)
/* Configure pins for USART use */
- stm32_configgpio(priv->tx_gpio);
- stm32_configgpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32_configgpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -2434,12 +2441,12 @@ static void stm32serial_shutdown(struct uart_dev_s *dev)
* then this may need to be a configuration option.
*/
- if (priv->unconfigure & USART_UNCONFIGURE_TX)
+ if ((priv->unconfigure & USART_UNCONFIGURE_TX) && (priv->tx_gpio != 0))
{
stm32_unconfiggpio(priv->tx_gpio);
}
- if (priv->unconfigure & USART_UNCONFIGURE_RX)
+ if ((priv->unconfigure & USART_UNCONFIGURE_RX) && (priv->rx_gpio != 0))
{
stm32_unconfiggpio(priv->rx_gpio);
}
@@ -2874,17 +2881,24 @@ static int stm32serial_ioctl(struct file *filep, int
cmd,
gpio_val |= GPIO_FLOAT;
}
- stm32_configgpio((priv->tx_gpio &
- ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
- gpio_val);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio &
+ ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
+ gpio_val);
+ }
cr |= USART_CR3_HDSEL;
}
else
{
- stm32_configgpio((priv->tx_gpio &
- ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
- GPIO_PUSHPULL);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio &
+ ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
+ GPIO_PUSHPULL);
+ }
+
cr &= ~USART_CR3_HDSEL;
}
@@ -3091,7 +3105,6 @@ static int stm32serial_ioctl(struct file *filep, int cmd,
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
{
irqstate_t flags;
- uint32_t tx_break;
flags = enter_critical_section();
@@ -3103,9 +3116,12 @@ static int stm32serial_ioctl(struct file *filep, int cmd,
/* Configure TX as a GPIO output pin and Send a break signal */
- tx_break = GPIO_OUTPUT |
- (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
- stm32_configgpio(tx_break);
+ if (priv->tx_gpio != 0)
+ {
+ uint32_t tx_break = GPIO_OUTPUT |
+ (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
+ stm32_configgpio(tx_break);
+ }
leave_critical_section(flags);
}
@@ -3119,7 +3135,10 @@ static int stm32serial_ioctl(struct file *filep, int cmd,
/* Configure TX back to U(S)ART */
- stm32_configgpio(priv->tx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio(priv->tx_gpio);
+ }
priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS;
diff --git a/arch/arm/src/stm32h7/stm32_serial.c
b/arch/arm/src/stm32h7/stm32_serial.c
index 5d2b54f0d48..7860667a245 100644
--- a/arch/arm/src/stm32h7/stm32_serial.c
+++ b/arch/arm/src/stm32h7/stm32_serial.c
@@ -2082,8 +2082,15 @@ static int up_setup(struct uart_dev_s *dev)
/* Configure pins for USART use */
- stm32_configgpio(priv->tx_gpio);
- stm32_configgpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32_configgpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -2314,8 +2321,15 @@ static void up_shutdown(struct uart_dev_s *dev)
* If not, then this may need to be a configuration option.
*/
- stm32_unconfiggpio(priv->tx_gpio);
- stm32_unconfiggpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_unconfiggpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32_unconfiggpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -2644,15 +2658,24 @@ static int up_ioctl(struct file *filep, int cmd,
unsigned long arg)
gpio_val |= (arg & SER_SINGLEWIRE_PULL_MASK) ==
SER_SINGLEWIRE_PULLDOWN ?
GPIO_PULLDOWN : GPIO_FLOAT;
- stm32_configgpio((priv->tx_gpio &
- ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | gpio_val);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio &
+ ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
+ gpio_val);
+ }
+
cr |= USART_CR3_HDSEL;
}
else
{
- stm32_configgpio((priv->tx_gpio &
- ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
- GPIO_PUSHPULL);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio &
+ ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
+ GPIO_PUSHPULL);
+ }
+
cr &= ~USART_CR3_HDSEL;
}
@@ -2859,7 +2882,6 @@ static int up_ioctl(struct file *filep, int cmd, unsigned
long arg)
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
{
irqstate_t flags;
- uint32_t tx_break;
flags = enter_critical_section();
@@ -2871,9 +2893,12 @@ static int up_ioctl(struct file *filep, int cmd,
unsigned long arg)
/* Configure TX as a GPIO output pin and Send a break signal */
- tx_break = GPIO_OUTPUT |
- (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
- stm32_configgpio(tx_break);
+ if (priv->tx_gpio != 0)
+ {
+ uint32_t tx_break = GPIO_OUTPUT |
+ (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
+ stm32_configgpio(tx_break);
+ }
leave_critical_section(flags);
}
@@ -2887,7 +2912,10 @@ static int up_ioctl(struct file *filep, int cmd,
unsigned long arg)
/* Configure TX back to U(S)ART */
- stm32_configgpio(priv->tx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio(priv->tx_gpio);
+ }
priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS;
diff --git a/arch/arm/src/stm32l4/stm32l4_serial.c
b/arch/arm/src/stm32l4/stm32l4_serial.c
index 1b611901861..bf78be0ddf8 100644
--- a/arch/arm/src/stm32l4/stm32l4_serial.c
+++ b/arch/arm/src/stm32l4/stm32l4_serial.c
@@ -1472,8 +1472,15 @@ static int stm32l4serial_setup(struct uart_dev_s *dev)
/* Configure pins for USART use */
- stm32l4_configgpio(priv->tx_gpio);
- stm32l4_configgpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32l4_configgpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32l4_configgpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -1698,8 +1705,15 @@ static void stm32l4serial_shutdown(struct uart_dev_s
*dev)
* then this may need to be a configuration option.
*/
- stm32l4_unconfiggpio(priv->tx_gpio);
- stm32l4_unconfiggpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32l4_unconfiggpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32l4_unconfiggpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -2015,17 +2029,23 @@ static int stm32l4serial_ioctl(struct file *filep, int
cmd,
(arg & SER_SINGLEWIRE_PULL_MASK) == SER_SINGLEWIRE_PULLDOWN ?
GPIO_PULLDOWN : GPIO_FLOAT;
- stm32l4_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
- GPIO_OPENDRAIN)) |
- gpio_val);
+ if (priv->tx_gpio != 0)
+ {
+ stm32l4_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
+ GPIO_OPENDRAIN)) |
+ gpio_val);
+ }
cr |= USART_CR3_HDSEL;
}
else
{
- stm32l4_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
- GPIO_OPENDRAIN)) |
- GPIO_PUSHPULL);
+ if (priv->tx_gpio != 0)
+ {
+ stm32l4_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
+ GPIO_OPENDRAIN)) |
+ GPIO_PUSHPULL);
+ }
cr &= ~USART_CR3_HDSEL;
}
@@ -2233,7 +2253,6 @@ static int stm32l4serial_ioctl(struct file *filep, int
cmd,
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
{
irqstate_t flags;
- uint32_t tx_break;
flags = enter_critical_section();
@@ -2245,9 +2264,12 @@ static int stm32l4serial_ioctl(struct file *filep, int
cmd,
/* Configure TX as a GPIO output pin and Send a break signal */
- tx_break = GPIO_OUTPUT |
- (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
- stm32l4_configgpio(tx_break);
+ if (priv->tx_gpio != 0)
+ {
+ uint32_t tx_break = GPIO_OUTPUT |
+ (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
+ stm32l4_configgpio(tx_break);
+ }
leave_critical_section(flags);
}
@@ -2261,7 +2283,10 @@ static int stm32l4serial_ioctl(struct file *filep, int
cmd,
/* Configure TX back to U(S)ART */
- stm32l4_configgpio(priv->tx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32l4_configgpio(priv->tx_gpio);
+ }
priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS;
diff --git a/arch/arm/src/stm32l5/stm32l5_serial.c
b/arch/arm/src/stm32l5/stm32l5_serial.c
index 26bf1bc2b47..514c57477d5 100644
--- a/arch/arm/src/stm32l5/stm32l5_serial.c
+++ b/arch/arm/src/stm32l5/stm32l5_serial.c
@@ -1392,8 +1392,15 @@ static int stm32l5serial_setup(struct uart_dev_s *dev)
/* Configure pins for USART use */
- stm32l5_configgpio(priv->tx_gpio);
- stm32l5_configgpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32l5_configgpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32l5_configgpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -1618,8 +1625,15 @@ static void stm32l5serial_shutdown(struct uart_dev_s
*dev)
* then this may need to be a configuration option.
*/
- stm32l5_unconfiggpio(priv->tx_gpio);
- stm32l5_unconfiggpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32l5_unconfiggpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32l5_unconfiggpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -1942,17 +1956,24 @@ static int stm32l5serial_ioctl(struct file *filep, int
cmd,
gpio_val |= GPIO_FLOAT;
}
- stm32l5_configgpio((priv->tx_gpio &
- ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
- gpio_val);
+ if (priv->tx_gpio != 0)
+ {
+ stm32l5_configgpio((priv->tx_gpio &
+ ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
+ gpio_val);
+ }
cr |= USART_CR3_HDSEL;
}
else
{
- stm32l5_configgpio((priv->tx_gpio &
- ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
- GPIO_PUSHPULL);
+ if (priv->tx_gpio != 0)
+ {
+ stm32l5_configgpio((priv->tx_gpio &
+ ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
+ GPIO_PUSHPULL);
+ }
+
cr &= ~USART_CR3_HDSEL;
}
@@ -2159,7 +2180,6 @@ static int stm32l5serial_ioctl(struct file *filep, int
cmd,
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
{
irqstate_t flags;
- uint32_t tx_break;
flags = enter_critical_section();
@@ -2171,9 +2191,12 @@ static int stm32l5serial_ioctl(struct file *filep, int
cmd,
/* Configure TX as a GPIO output pin and Send a break signal */
- tx_break = GPIO_OUTPUT |
- (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
- stm32l5_configgpio(tx_break);
+ if (priv->tx_gpio != 0)
+ {
+ uint32_t tx_break = GPIO_OUTPUT |
+ (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
+ stm32l5_configgpio(tx_break);
+ }
leave_critical_section(flags);
}
@@ -2187,7 +2210,10 @@ static int stm32l5serial_ioctl(struct file *filep, int
cmd,
/* Configure TX back to U(S)ART */
- stm32l5_configgpio(priv->tx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32l5_configgpio(priv->tx_gpio);
+ }
priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS;
diff --git a/arch/arm/src/stm32n6/stm32_serial.c
b/arch/arm/src/stm32n6/stm32_serial.c
index d6972700da6..220a34dc3ac 100644
--- a/arch/arm/src/stm32n6/stm32_serial.c
+++ b/arch/arm/src/stm32n6/stm32_serial.c
@@ -730,8 +730,15 @@ static int stm32serial_setup(struct uart_dev_s *dev)
/* Configure pins for USART use */
- stm32_configgpio(priv->tx_gpio);
- stm32_configgpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32_configgpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -858,12 +865,12 @@ static void stm32serial_shutdown(struct uart_dev_s *dev)
* not, then this may need to be a configuration option.
*/
- if (priv->unconfigure & USART_UNCONFIGURE_TX)
+ if ((priv->unconfigure & USART_UNCONFIGURE_TX) && (priv->tx_gpio != 0))
{
stm32_unconfiggpio(priv->tx_gpio);
}
- if (priv->unconfigure & USART_UNCONFIGURE_RX)
+ if ((priv->unconfigure & USART_UNCONFIGURE_RX) && (priv->rx_gpio != 0))
{
stm32_unconfiggpio(priv->rx_gpio);
}
diff --git a/arch/arm/src/stm32u5/stm32_serial.c
b/arch/arm/src/stm32u5/stm32_serial.c
index 7dd49c27b13..a5aea799e96 100644
--- a/arch/arm/src/stm32u5/stm32_serial.c
+++ b/arch/arm/src/stm32u5/stm32_serial.c
@@ -1406,8 +1406,15 @@ static int stm32serial_setup(struct uart_dev_s *dev)
/* Configure pins for USART use */
- stm32_configgpio(priv->tx_gpio);
- stm32_configgpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32_configgpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -1632,8 +1639,15 @@ static void stm32serial_shutdown(struct uart_dev_s *dev)
* then this may need to be a configuration option.
*/
- stm32_unconfiggpio(priv->tx_gpio);
- stm32_unconfiggpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_unconfiggpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32_unconfiggpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -1956,17 +1970,24 @@ static int stm32serial_ioctl(struct file *filep, int
cmd,
gpio_val |= GPIO_FLOAT;
}
- stm32_configgpio((priv->tx_gpio &
- ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
- gpio_val);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio &
+ ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
+ gpio_val);
+ }
cr |= USART_CR3_HDSEL;
}
else
{
- stm32_configgpio((priv->tx_gpio &
- ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
- GPIO_PUSHPULL);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio((priv->tx_gpio &
+ ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
+ GPIO_PUSHPULL);
+ }
+
cr &= ~USART_CR3_HDSEL;
}
@@ -2173,7 +2194,6 @@ static int stm32serial_ioctl(struct file *filep, int cmd,
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
{
irqstate_t flags;
- uint32_t tx_break;
flags = enter_critical_section();
@@ -2185,9 +2205,12 @@ static int stm32serial_ioctl(struct file *filep, int cmd,
/* Configure TX as a GPIO output pin and Send a break signal */
- tx_break = GPIO_OUTPUT |
- (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
- stm32_configgpio(tx_break);
+ if (priv->tx_gpio != 0)
+ {
+ uint32_t tx_break = GPIO_OUTPUT |
+ (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
+ stm32_configgpio(tx_break);
+ }
leave_critical_section(flags);
}
@@ -2201,7 +2224,10 @@ static int stm32serial_ioctl(struct file *filep, int cmd,
/* Configure TX back to U(S)ART */
- stm32_configgpio(priv->tx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32_configgpio(priv->tx_gpio);
+ }
priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS;
diff --git a/arch/arm/src/stm32wb/stm32wb_serial.c
b/arch/arm/src/stm32wb/stm32wb_serial.c
index 83e90867924..e657d7435de 100644
--- a/arch/arm/src/stm32wb/stm32wb_serial.c
+++ b/arch/arm/src/stm32wb/stm32wb_serial.c
@@ -1096,8 +1096,15 @@ static int stm32wb_serial_setup(struct uart_dev_s *dev)
/* Configure pins for USART use */
- stm32wb_configgpio(priv->tx_gpio);
- stm32wb_configgpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32wb_configgpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32wb_configgpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -1320,8 +1327,15 @@ static void stm32wb_serial_shutdown(struct uart_dev_s
*dev)
* then this may need to be a configuration option.
*/
- stm32wb_unconfiggpio(priv->tx_gpio);
- stm32wb_unconfiggpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32wb_unconfiggpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32wb_unconfiggpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -1632,17 +1646,23 @@ static int stm32wb_serial_ioctl(struct file *filep, int
cmd,
(arg & SER_SINGLEWIRE_PULL_MASK) == SER_SINGLEWIRE_PULLDOWN ?
GPIO_PULLDOWN : GPIO_FLOAT;
- stm32wb_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
- GPIO_OPENDRAIN)) |
- gpio_val);
+ if (priv->tx_gpio != 0)
+ {
+ stm32wb_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
+ GPIO_OPENDRAIN)) |
+ gpio_val);
+ }
cr |= USART_CR3_HDSEL;
}
else
{
- stm32wb_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
- GPIO_OPENDRAIN)) |
- GPIO_PUSHPULL);
+ if (priv->tx_gpio != 0)
+ {
+ stm32wb_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK |
+ GPIO_OPENDRAIN)) |
+ GPIO_PUSHPULL);
+ }
cr &= ~USART_CR3_HDSEL;
}
@@ -1850,7 +1870,6 @@ static int stm32wb_serial_ioctl(struct file *filep, int
cmd,
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
{
irqstate_t flags;
- uint32_t tx_break;
flags = enter_critical_section();
@@ -1862,9 +1881,12 @@ static int stm32wb_serial_ioctl(struct file *filep, int
cmd,
/* Configure TX as a GPIO output pin and Send a break signal */
- tx_break = GPIO_OUTPUT |
- (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
- stm32wb_configgpio(tx_break);
+ if (priv->tx_gpio != 0)
+ {
+ uint32_t tx_break = GPIO_OUTPUT |
+ (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
+ stm32wb_configgpio(tx_break);
+ }
leave_critical_section(flags);
}
@@ -1878,7 +1900,10 @@ static int stm32wb_serial_ioctl(struct file *filep, int
cmd,
/* Configure TX back to U(S)ART */
- stm32wb_configgpio(priv->tx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32wb_configgpio(priv->tx_gpio);
+ }
priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS;
diff --git a/arch/arm/src/stm32wl5/stm32wl5_serial.c
b/arch/arm/src/stm32wl5/stm32wl5_serial.c
index 219de08b36c..524483ef5cb 100644
--- a/arch/arm/src/stm32wl5/stm32wl5_serial.c
+++ b/arch/arm/src/stm32wl5/stm32wl5_serial.c
@@ -1155,8 +1155,15 @@ static int stm32wl5serial_setup(struct uart_dev_s *dev)
/* Configure pins for USART use */
- stm32wl5_configgpio(priv->tx_gpio);
- stm32wl5_configgpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32wl5_configgpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32wl5_configgpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -1381,8 +1388,15 @@ static void stm32wl5serial_shutdown(struct uart_dev_s
*dev)
* then this may need to be a configuration option.
*/
- stm32wl5_unconfiggpio(priv->tx_gpio);
- stm32wl5_unconfiggpio(priv->rx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32wl5_unconfiggpio(priv->tx_gpio);
+ }
+
+ if (priv->rx_gpio != 0)
+ {
+ stm32wl5_unconfiggpio(priv->rx_gpio);
+ }
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->cts_gpio != 0)
@@ -1707,17 +1721,24 @@ static int stm32wl5serial_ioctl(struct file *filep, int
cmd,
gpio_val |= GPIO_FLOAT;
}
- stm32wl5_configgpio((priv->tx_gpio &
- ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
- gpio_val);
+ if (priv->tx_gpio != 0)
+ {
+ stm32wl5_configgpio((priv->tx_gpio &
+ ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
+ gpio_val);
+ }
cr |= USART_CR3_HDSEL;
}
else
{
- stm32wl5_configgpio((priv->tx_gpio &
- ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
- GPIO_PUSHPULL);
+ if (priv->tx_gpio != 0)
+ {
+ stm32wl5_configgpio((priv->tx_gpio &
+ ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) |
+ GPIO_PUSHPULL);
+ }
+
cr &= ~USART_CR3_HDSEL;
}
@@ -1924,7 +1945,6 @@ static int stm32wl5serial_ioctl(struct file *filep, int
cmd,
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
{
irqstate_t flags;
- uint32_t tx_break;
flags = enter_critical_section();
@@ -1936,9 +1956,12 @@ static int stm32wl5serial_ioctl(struct file *filep, int
cmd,
/* Configure TX as a GPIO output pin and Send a break signal */
- tx_break = GPIO_OUTPUT |
- (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
- stm32wl5_configgpio(tx_break);
+ if (priv->tx_gpio != 0)
+ {
+ uint32_t tx_break = GPIO_OUTPUT |
+ (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
+ stm32wl5_configgpio(tx_break);
+ }
leave_critical_section(flags);
}
@@ -1952,7 +1975,10 @@ static int stm32wl5serial_ioctl(struct file *filep, int
cmd,
/* Configure TX back to U(S)ART */
- stm32wl5_configgpio(priv->tx_gpio);
+ if (priv->tx_gpio != 0)
+ {
+ stm32wl5_configgpio(priv->tx_gpio);
+ }
priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS;