diff --git a/arch/arm/src/kinetis/kinetis_lpserial.c b/arch/arm/src/kinetis/kinetis_lpserial.c index 177a4a7e6be..46908022296 100644 --- a/arch/arm/src/kinetis/kinetis_lpserial.c +++ b/arch/arm/src/kinetis/kinetis_lpserial.c @@ -849,6 +849,12 @@ static int kinetis_ioctl(struct file *filep, int cmd, unsigned long arg) #ifdef CONFIG_KINETIS_UART_SINGLEWIRE case TIOCSSINGLEWIRE: { + if ((arg & SER_SINGLEWIRE_PULLUP) != 0) + { + ret = -EINVAL; // Not supported + break; + } + /* Change to single-wire operation. the RXD pin is disconnected from * the UART and the UART implements a half-duplex serial connection. * The UART uses the TXD pin for both receiving and transmitting @@ -856,7 +862,7 @@ static int kinetis_ioctl(struct file *filep, int cmd, unsigned long arg) regval = kinetis_serialin(priv, KINETIS_LPUART_CTRL_OFFSET); - if (arg == SER_SINGLEWIRE_ENABLED) + if ((arg & SER_SINGLEWIRE_ENABLED) != 0) { regval |= (LPUART_CTRL_LOOPS | LPUART_CTRL_RSRC); } diff --git a/arch/arm/src/kinetis/kinetis_serial.c b/arch/arm/src/kinetis/kinetis_serial.c index d5e8890b343..c9f4d944fb4 100644 --- a/arch/arm/src/kinetis/kinetis_serial.c +++ b/arch/arm/src/kinetis/kinetis_serial.c @@ -1304,6 +1304,12 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) #ifdef CONFIG_KINETIS_UART_SINGLEWIRE case TIOCSSINGLEWIRE: { + if ((arg & SER_SINGLEWIRE_PULLUP) != 0) + { + ret = -EINVAL; // Not supported + break; + } + /* Change to single-wire operation. the RXD pin is disconnected from * the UART and the UART implements a half-duplex serial connection. * The UART uses the TXD pin for both receiving and transmitting @@ -1311,7 +1317,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) regval = up_serialin(priv, KINETIS_UART_C1_OFFSET); - if (arg == SER_SINGLEWIRE_ENABLED) + if ((arg & SER_SINGLEWIRE_ENABLED) != 0) { regval |= (UART_C1_LOOPS | UART_C1_RSRC); } diff --git a/arch/arm/src/stm32/stm32_serial.c b/arch/arm/src/stm32/stm32_serial.c index 2227bc4f418..9afe350cce4 100644 --- a/arch/arm/src/stm32/stm32_serial.c +++ b/arch/arm/src/stm32/stm32_serial.c @@ -1952,7 +1952,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) uint32_t cr = up_serialin(priv, STM32_USART_CR3_OFFSET); #if defined(CONFIG_STM32_STM32F10XX) - if (arg == SER_SINGLEWIRE_ENABLED) + if ((arg & SER_SINGLEWIRE_ENABLED) != 0) { stm32_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) | GPIO_CNF_AFOD); cr |= USART_CR3_HDSEL; @@ -1963,14 +1963,15 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) cr &= ~USART_CR3_HDSEL; } #else - if (arg == SER_SINGLEWIRE_ENABLED) + if ((arg & SER_SINGLEWIRE_ENABLED) != 0) { - stm32_configgpio(priv->tx_gpio | GPIO_OPENDRAIN); + uint32_t gpio_val = (arg & SER_SINGLEWIRE_PULLUP) ? GPIO_PULLUP : GPIO_OPENDRAIN; + stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | gpio_val); cr |= USART_CR3_HDSEL; } else { - stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); + stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL); cr &= ~USART_CR3_HDSEL; } #endif diff --git a/arch/arm/src/stm32f0l0g0/stm32_serial_v1.c b/arch/arm/src/stm32f0l0g0/stm32_serial_v1.c index 97bf3fbe2d4..44801cad12a 100644 --- a/arch/arm/src/stm32f0l0g0/stm32_serial_v1.c +++ b/arch/arm/src/stm32f0l0g0/stm32_serial_v1.c @@ -1602,14 +1602,15 @@ static int stm32serial_ioctl(FAR struct file *filep, int cmd, uint32_t cr = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); - if (arg == SER_SINGLEWIRE_ENABLED) + if ((arg & SER_SINGLEWIRE_ENABLED) != 0) { - stm32_configgpio(priv->tx_gpio | GPIO_OPENDRAIN); + uint32_t gpio_val = (arg & SER_SINGLEWIRE_PULLUP) ? GPIO_PULLUP : GPIO_OPENDRAIN; + stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | gpio_val); cr |= USART_CR3_HDSEL; } else { - stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); + stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL); cr &= ~USART_CR3_HDSEL; } diff --git a/arch/arm/src/stm32f0l0g0/stm32_serial_v2.c b/arch/arm/src/stm32f0l0g0/stm32_serial_v2.c index 5ea9c2fc037..8abaf03163a 100644 --- a/arch/arm/src/stm32f0l0g0/stm32_serial_v2.c +++ b/arch/arm/src/stm32f0l0g0/stm32_serial_v2.c @@ -1161,14 +1161,15 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) uint32_t cr = up_serialin(priv, STM32_USART_CR3_OFFSET); - if (arg == SER_SINGLEWIRE_ENABLED) + if ((arg & SER_SINGLEWIRE_ENABLED) != 0) { - stm32_configgpio(priv->tx_gpio | GPIO_OPENDRAIN); + uint32_t gpio_val = (arg & SER_SINGLEWIRE_PULLUP) ? GPIO_PULLUP : GPIO_OPENDRAIN; + stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | gpio_val); cr |= USART_CR3_HDSEL; } else { - stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); + stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL); cr &= ~USART_CR3_HDSEL; } diff --git a/arch/arm/src/stm32f7/stm32_serial.c b/arch/arm/src/stm32f7/stm32_serial.c index baa1e4c877c..dbf2dac63b6 100644 --- a/arch/arm/src/stm32f7/stm32_serial.c +++ b/arch/arm/src/stm32f7/stm32_serial.c @@ -2125,14 +2125,15 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) uint32_t cr = up_serialin(priv, STM32_USART_CR3_OFFSET); - if (arg == SER_SINGLEWIRE_ENABLED) + if ((arg & SER_SINGLEWIRE_ENABLED) != 0) { - stm32_configgpio(priv->tx_gpio | GPIO_OPENDRAIN); + uint32_t gpio_val = (arg & SER_SINGLEWIRE_PULLUP) ? GPIO_PULLUP : GPIO_OPENDRAIN; + stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | gpio_val); cr |= USART_CR3_HDSEL; } else { - stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); + stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL); cr &= ~USART_CR3_HDSEL; } diff --git a/arch/arm/src/stm32h7/stm32_serial.c b/arch/arm/src/stm32h7/stm32_serial.c index fe59bdd2266..942bc15028d 100644 --- a/arch/arm/src/stm32h7/stm32_serial.c +++ b/arch/arm/src/stm32h7/stm32_serial.c @@ -1529,14 +1529,15 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) uint32_t cr = up_serialin(priv, STM32_USART_CR3_OFFSET); - if (arg == SER_SINGLEWIRE_ENABLED) + if ((arg & SER_SINGLEWIRE_ENABLED) != 0) { - stm32_configgpio(priv->tx_gpio | GPIO_OPENDRAIN); + uint32_t gpio_val = (arg & SER_SINGLEWIRE_PULLUP) ? GPIO_PULLUP : GPIO_OPENDRAIN; + stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | gpio_val); cr |= USART_CR3_HDSEL; } else { - stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); + stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL); cr &= ~USART_CR3_HDSEL; } diff --git a/arch/arm/src/stm32l4/stm32l4_serial.c b/arch/arm/src/stm32l4/stm32l4_serial.c index f7e2558559a..45dc13ae0e1 100644 --- a/arch/arm/src/stm32l4/stm32l4_serial.c +++ b/arch/arm/src/stm32l4/stm32l4_serial.c @@ -1805,14 +1805,15 @@ static int stm32l4serial_ioctl(FAR struct file *filep, int cmd, uint32_t cr = stm32l4serial_getreg(priv, STM32L4_USART_CR3_OFFSET); - if (arg == SER_SINGLEWIRE_ENABLED) + if ((arg & SER_SINGLEWIRE_ENABLED) != 0) { - stm32l4_configgpio(priv->tx_gpio | GPIO_OPENDRAIN); + uint32_t gpio_val = (arg & SER_SINGLEWIRE_PULLUP) ? GPIO_PULLUP : GPIO_OPENDRAIN; + stm32l4_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | gpio_val); cr |= USART_CR3_HDSEL; } else { - stm32l4_configgpio(priv->tx_gpio | GPIO_PUSHPULL); + stm32l4_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL); cr &= ~USART_CR3_HDSEL; } diff --git a/include/nuttx/serial/tioctl.h b/include/nuttx/serial/tioctl.h index 614b126984b..e8dd02d3072 100644 --- a/include/nuttx/serial/tioctl.h +++ b/include/nuttx/serial/tioctl.h @@ -185,6 +185,7 @@ #define TIOCGSINGLEWIRE _TIOC(0x0031) /* Get single-wire mode */ # define SER_SINGLEWIRE_ENABLED (1 << 0) /* Enable/disable single-wire support */ +# define SER_SINGLEWIRE_PULLUP (1 << 1) /* Enable Pull-up on TX (Open-Drain otherwise) */ /* Debugging */