Merged in bkueng/nuttx/serial_single-wire_pullup (pull request #994)

serial single-wire: add possibility to specify pull-up instead of open drain

Approved-by: David Sidrane <david.sidrane@nscdg.com>
Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
Beat Küng 2019-08-15 21:58:52 +00:00 committed by Gregory Nutt
parent 04f0ee5198
commit ef233507db
9 changed files with 40 additions and 21 deletions

View File

@ -849,6 +849,12 @@ static int kinetis_ioctl(struct file *filep, int cmd, unsigned long arg)
#ifdef CONFIG_KINETIS_UART_SINGLEWIRE #ifdef CONFIG_KINETIS_UART_SINGLEWIRE
case TIOCSSINGLEWIRE: case TIOCSSINGLEWIRE:
{ {
if ((arg & SER_SINGLEWIRE_PULLUP) != 0)
{
ret = -EINVAL; // Not supported
break;
}
/* Change to single-wire operation. the RXD pin is disconnected from /* Change to single-wire operation. the RXD pin is disconnected from
* the UART and the UART implements a half-duplex serial connection. * the UART and the UART implements a half-duplex serial connection.
* The UART uses the TXD pin for both receiving and transmitting * 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); 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); regval |= (LPUART_CTRL_LOOPS | LPUART_CTRL_RSRC);
} }

View File

@ -1304,6 +1304,12 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
#ifdef CONFIG_KINETIS_UART_SINGLEWIRE #ifdef CONFIG_KINETIS_UART_SINGLEWIRE
case TIOCSSINGLEWIRE: case TIOCSSINGLEWIRE:
{ {
if ((arg & SER_SINGLEWIRE_PULLUP) != 0)
{
ret = -EINVAL; // Not supported
break;
}
/* Change to single-wire operation. the RXD pin is disconnected from /* Change to single-wire operation. the RXD pin is disconnected from
* the UART and the UART implements a half-duplex serial connection. * the UART and the UART implements a half-duplex serial connection.
* The UART uses the TXD pin for both receiving and transmitting * 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); 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); regval |= (UART_C1_LOOPS | UART_C1_RSRC);
} }

View File

@ -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); uint32_t cr = up_serialin(priv, STM32_USART_CR3_OFFSET);
#if defined(CONFIG_STM32_STM32F10XX) #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); stm32_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) | GPIO_CNF_AFOD);
cr |= USART_CR3_HDSEL; cr |= USART_CR3_HDSEL;
@ -1963,14 +1963,15 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
cr &= ~USART_CR3_HDSEL; cr &= ~USART_CR3_HDSEL;
} }
#else #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; cr |= USART_CR3_HDSEL;
} }
else else
{ {
stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL);
cr &= ~USART_CR3_HDSEL; cr &= ~USART_CR3_HDSEL;
} }
#endif #endif

View File

@ -1602,14 +1602,15 @@ static int stm32serial_ioctl(FAR struct file *filep, int cmd,
uint32_t cr = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); 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; cr |= USART_CR3_HDSEL;
} }
else else
{ {
stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL);
cr &= ~USART_CR3_HDSEL; cr &= ~USART_CR3_HDSEL;
} }

View File

@ -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); 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; cr |= USART_CR3_HDSEL;
} }
else else
{ {
stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL);
cr &= ~USART_CR3_HDSEL; cr &= ~USART_CR3_HDSEL;
} }

View File

@ -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); 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; cr |= USART_CR3_HDSEL;
} }
else else
{ {
stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL);
cr &= ~USART_CR3_HDSEL; cr &= ~USART_CR3_HDSEL;
} }

View File

@ -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); 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; cr |= USART_CR3_HDSEL;
} }
else else
{ {
stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); stm32_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL);
cr &= ~USART_CR3_HDSEL; cr &= ~USART_CR3_HDSEL;
} }

View File

@ -1805,14 +1805,15 @@ static int stm32l4serial_ioctl(FAR struct file *filep, int cmd,
uint32_t cr = stm32l4serial_getreg(priv, STM32L4_USART_CR3_OFFSET); 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; cr |= USART_CR3_HDSEL;
} }
else else
{ {
stm32l4_configgpio(priv->tx_gpio | GPIO_PUSHPULL); stm32l4_configgpio((priv->tx_gpio & ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | GPIO_PUSHPULL);
cr &= ~USART_CR3_HDSEL; cr &= ~USART_CR3_HDSEL;
} }

View File

@ -185,6 +185,7 @@
#define TIOCGSINGLEWIRE _TIOC(0x0031) /* Get single-wire mode */ #define TIOCGSINGLEWIRE _TIOC(0x0031) /* Get single-wire mode */
# define SER_SINGLEWIRE_ENABLED (1 << 0) /* Enable/disable single-wire support */ # 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 */ /* Debugging */