From: Miloš Pokorný <[email protected]>

---
 arch/arm/src/kinetis/Kconfig           | 52 ++++++++++++++++++++++++++
 arch/arm/src/kinetis/kinetis.h         |  2 +-
 arch/arm/src/kinetis/kinetis_lowputc.c | 40 +++++++++++++++++++-
 arch/arm/src/kinetis/kinetis_serial.c  | 30 ++++++++++++++-
 4 files changed, 119 insertions(+), 5 deletions(-)

diff --git a/arch/arm/src/kinetis/Kconfig b/arch/arm/src/kinetis/Kconfig
index 443020bd89..300969a66f 100644
--- a/arch/arm/src/kinetis/Kconfig
+++ b/arch/arm/src/kinetis/Kconfig
@@ -1396,6 +1396,58 @@ config KINETIS_SERIAL_RXDMA_BUFFER_SIZE
 
                Value given here will be rounded up to next multiple of 32 
bytes.
 
+menu "RS485 transmit enable support"
+
+config UART0_RS485CONTROL
+       bool "Use UART0 RTS as RS-485 transmit enable"
+       default n
+       select SERIAL_RS485CONTROL
+       depends on KINETIS_UART0 && UART0_IFLOWCONTROL
+       ---help---
+               Enable RS-485 transmit enable on UART0.
+
+config UART1_RS485CONTROL
+       bool "Use UART1 RTS as RS-485 transmit enable"
+       default n
+       select SERIAL_RS485CONTROL
+       depends on KINETIS_UART1 && UART1_IFLOWCONTROL
+       ---help---
+               Enable RS-485 transmit enable on UART1.
+
+config UART2_RS485CONTROL
+       bool "Use UART2 RTS as RS-485 transmit enable"
+       default n
+       select SERIAL_RS485CONTROL
+       depends on KINETIS_UART2 && UART2_IFLOWCONTROL
+       ---help---
+               Enable RS-485 transmit enable on UART2.
+
+config UART3_RS485CONTROL
+       bool "Use UART3 RTS as RS-485 transmit enable"
+       default n
+       select SERIAL_RS485CONTROL
+       depends on KINETIS_UART3 && UART3_IFLOWCONTROL
+       ---help---
+               Enable RS-485 transmit enable on UART3.
+
+config UART4_RS485CONTROL
+       bool "Use UART4 RTS as RS-485 transmit enable"
+       default n
+       select SERIAL_RS485CONTROL
+       depends on KINETIS_UART4 && UART4_IFLOWCONTROL
+       ---help---
+               Enable RS-485 transmit enable on UART4.
+
+config UART5_RS485CONTROL
+       bool "Use UART5 RTS as RS-485 transmit enable"
+       default n
+       select SERIAL_RS485CONTROL
+       depends on KINETIS_UART5 && UART5_IFLOWCONTROL
+       ---help---
+               Enable RS-485 transmit enable on UART5.
+
+endmenu # Kinetis RS485 trasmit driver support
+
 endmenu # Kinetis UART Configuration
 
 menu "Kinetis LPUART Configuration"
diff --git a/arch/arm/src/kinetis/kinetis.h b/arch/arm/src/kinetis/kinetis.h
index cd406a91f5..dd3a713d13 100644
--- a/arch/arm/src/kinetis/kinetis.h
+++ b/arch/arm/src/kinetis/kinetis.h
@@ -475,7 +475,7 @@ void kinetis_uartconfigure(uintptr_t uart_base,
                            uint32_t baud, uint32_t clock,
                            unsigned int parity, unsigned int nbits,
                            unsigned int stop2,
-                           bool iflow, bool oflow);
+                           bool iflow, bool oflow, bool rs485control);
 #endif
 
 /****************************************************************************
diff --git a/arch/arm/src/kinetis/kinetis_lowputc.c 
b/arch/arm/src/kinetis/kinetis_lowputc.c
index f80f683540..166121bb2f 100644
--- a/arch/arm/src/kinetis/kinetis_lowputc.c
+++ b/arch/arm/src/kinetis/kinetis_lowputc.c
@@ -53,36 +53,54 @@
 #if !defined(CONFIG_UART0_OFLOWCONTROL)
 #  define CONFIG_UART0_OFLOWCONTROL 0
 #endif
+#if !defined(CONFIG_UART0_RS485CONTROL)
+#  define CONFIG_UART0_RS485CONTROL 0
+#endif
 #if !defined(CONFIG_UART1_IFLOWCONTROL)
 #  define CONFIG_UART1_IFLOWCONTROL 0
 #endif
 #if !defined(CONFIG_UART1_OFLOWCONTROL)
 #  define CONFIG_UART1_OFLOWCONTROL 0
 #endif
+#if !defined(CONFIG_UART1_RS485CONTROL)
+#  define CONFIG_UART1_RS485CONTROL 0
+#endif
 #if !defined(CONFIG_UART2_IFLOWCONTROL)
 #  define CONFIG_UART2_IFLOWCONTROL 0
 #endif
 #if !defined(CONFIG_UART2_OFLOWCONTROL)
 #  define CONFIG_UART2_OFLOWCONTROL 0
 #endif
+#if !defined(CONFIG_UART2_RS485CONTROL)
+#  define CONFIG_UART2_RS485CONTROL 0
+#endif
 #if !defined(CONFIG_UART3_IFLOWCONTROL)
 #  define CONFIG_UART3_IFLOWCONTROL 0
 #endif
 #if !defined(CONFIG_UART3_OFLOWCONTROL)
 #  define CONFIG_UART3_OFLOWCONTROL 0
 #endif
+#if !defined(CONFIG_UART3_RS485CONTROL)
+#  define CONFIG_UART3_RS485CONTROL 0
+#endif
 #if !defined(CONFIG_UART4_IFLOWCONTROL)
 #  define CONFIG_UART4_IFLOWCONTROL 0
 #endif
 #if !defined(CONFIG_UART4_OFLOWCONTROL)
 #  define CONFIG_UART4_OFLOWCONTROL 0
 #endif
+#if !defined(CONFIG_UART4_RS485CONTROL)
+#  define CONFIG_UART4_RS485CONTROL 0
+#endif
 #if !defined(CONFIG_UART5_IFLOWCONTROL)
 #  define CONFIG_UART5_IFLOWCONTROL 0
 #endif
 #if !defined(CONFIG_UART5_OFLOWCONTROL)
 #  define CONFIG_UART5_OFLOWCONTROL 0
 #endif
+#if !defined(CONFIG_UART5_RS485CONTROL)
+#  define CONFIG_UART5_RS485CONTROL 0
+#endif
 
 #if !defined(CONFIG_LPUART0_IFLOWCONTROL)
 #  define CONFIG_LPUART0_IFLOWCONTROL 0
@@ -127,6 +145,7 @@
 #    define CONSOLE_PARITY   CONFIG_UART0_PARITY
 #    define CONSOLE_IFLOW    CONFIG_UART0_IFLOWCONTROL
 #    define CONSOLE_OFLOW    CONFIG_UART0_OFLOWCONTROL
+#    define CONSOLE_RS485CONTROL    CONFIG_UART0_RS485CONTROL
 #  elif defined(CONFIG_UART1_SERIAL_CONSOLE)
 #    define CONSOLE_BASE     KINETIS_UART1_BASE
 #    define CONSOLE_FREQ     BOARD_CORECLK_FREQ
@@ -136,6 +155,7 @@
 #    define CONSOLE_PARITY   CONFIG_UART1_PARITY
 #    define CONSOLE_IFLOW    CONFIG_UART1_IFLOWCONTROL
 #    define CONSOLE_OFLOW    CONFIG_UART1_OFLOWCONTROL
+#    define CONSOLE_RS485CONTROL    CONFIG_UART1_RS485CONTROL
 #  elif defined(CONFIG_UART2_SERIAL_CONSOLE)
 #    define CONSOLE_BASE     KINETIS_UART2_BASE
 #    define CONSOLE_FREQ     BOARD_BUS_FREQ
@@ -145,6 +165,7 @@
 #    define CONSOLE_PARITY   CONFIG_UART2_PARITY
 #    define CONSOLE_IFLOW    CONFIG_UART2_IFLOWCONTROL
 #    define CONSOLE_OFLOW    CONFIG_UART2_OFLOWCONTROL
+#    define CONSOLE_RS485CONTROL    CONFIG_UART2_RS485CONTROL
 #  elif defined(CONFIG_UART3_SERIAL_CONSOLE)
 #    define CONSOLE_BASE     KINETIS_UART3_BASE
 #    define CONSOLE_FREQ     BOARD_BUS_FREQ
@@ -154,6 +175,7 @@
 #    define CONSOLE_PARITY   CONFIG_UART3_PARITY
 #    define CONSOLE_IFLOW    CONFIG_UART3_IFLOWCONTROL
 #    define CONSOLE_OFLOW    CONFIG_UART3_OFLOWCONTROL
+#    define CONSOLE_RS485CONTROL    CONFIG_UART3_RS485CONTROL
 #  elif defined(CONFIG_UART4_SERIAL_CONSOLE)
 #    define CONSOLE_BASE     KINETIS_UART4_BASE
 #    define CONSOLE_FREQ     BOARD_BUS_FREQ
@@ -163,6 +185,7 @@
 #    define CONSOLE_PARITY   CONFIG_UART4_PARITY
 #    define CONSOLE_IFLOW    CONFIG_UART4_IFLOWCONTROL
 #    define CONSOLE_OFLOW    CONFIG_UART4_OFLOWCONTROL
+#    define CONSOLE_RS485CONTROL    CONFIG_UART4_RS485CONTROL
 #  elif defined(CONFIG_UART5_SERIAL_CONSOLE)
 #    define CONSOLE_BASE     KINETIS_UART5_BASE
 #    define CONSOLE_FREQ     BOARD_BUS_FREQ
@@ -172,6 +195,7 @@
 #    define CONSOLE_PARITY   CONFIG_UART5_PARITY
 #    define CONSOLE_IFLOW    CONFIG_UART5_IFLOWCONTROL
 #    define CONSOLE_OFLOW    CONFIG_UART5_OFLOWCONTROL
+#    define CONSOLE_RS485CONTROL    CONFIG_UART5_RS485CONTROL
 #  elif defined(HAVE_UART_CONSOLE)
 #    error "No CONFIG_UARTn_SERIAL_CONSOLE Setting"
 #  endif
@@ -440,7 +464,7 @@ void kinetis_lowsetup(void)
 
   kinetis_uartconfigure(CONSOLE_BASE, CONSOLE_BAUD, CONSOLE_FREQ, \
                         CONSOLE_PARITY, CONSOLE_BITS, CONSOLE_2STOP, \
-                        CONSOLE_IFLOW, CONSOLE_OFLOW);
+                        CONSOLE_IFLOW, CONSOLE_OFLOW, CONSOLE_RS485CONTROL);
 #  endif
 #endif /* HAVE_UART_DEVICE */
 
@@ -593,7 +617,7 @@ void kinetis_lpuartreset(uintptr_t uart_base)
 void kinetis_uartconfigure(uintptr_t uart_base, uint32_t baud,
                            uint32_t clock, unsigned int parity,
                            unsigned int nbits, unsigned int stop2,
-                           bool iflow, bool oflow)
+                           bool iflow, bool oflow, bool rs485control)
 {
   uint32_t     sbr;
   uint32_t     brfa;
@@ -753,11 +777,23 @@ void kinetis_uartconfigure(uintptr_t uart_base, uint32_t 
baud,
   regval &= ~(UART_MODEM_TXCTSE | UART_MODEM_RXRTSE);
 
 #ifdef CONFIG_SERIAL_IFLOWCONTROL
+#ifdef CONFIG_SERIAL_RS485CONTROL
+  if (iflow && rs485control)
+    {
+      regval |= UART_MODEM_TXRTSE;
+      regval |= UART_MODEM_TXRTSPOL;
+    }
+  else
+    {
+      regval |= UART_MODEM_RXRTSE;
+    }
+#else
   if (iflow)
     {
       regval |= UART_MODEM_RXRTSE;
     }
 #endif
+#endif
 
 #ifdef CONFIG_SERIAL_OFLOWCONTROL
   if (oflow)
diff --git a/arch/arm/src/kinetis/kinetis_serial.c 
b/arch/arm/src/kinetis/kinetis_serial.c
index 72d648e390..63fc86e557 100644
--- a/arch/arm/src/kinetis/kinetis_serial.c
+++ b/arch/arm/src/kinetis/kinetis_serial.c
@@ -292,6 +292,9 @@ struct up_dev_s
   uint8_t   stop2;     /* Use 2 stop bits */
 #ifdef CONFIG_SERIAL_IFLOWCONTROL
   bool      iflow;     /* input flow control (RTS) enabled */
+#ifdef CONFIG_SERIAL_RS485CONTROL
+  bool      rs485control;     /* RTS used as transmit enable */
+#endif
 #endif
 #ifdef CONFIG_SERIAL_OFLOWCONTROL
   bool      oflow;     /* output flow control (CTS) enabled */
@@ -482,6 +485,9 @@ static struct up_dev_s g_uart0priv =
 #  if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART0_IFLOWCONTROL)
   .iflow          = true,
   .rts_gpio       = PIN_UART0_RTS,
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_UART0_RS485CONTROL)
+  .rs485control   = true,
+#  endif
 #  endif
 #  ifdef CONFIG_KINETIS_UART0_RXDMA
   .rxdma_reqsrc   = KINETIS_DMA_REQUEST_SRC_UART0_RX,
@@ -533,6 +539,9 @@ static struct up_dev_s g_uart1priv =
 #  if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART1_IFLOWCONTROL)
   .iflow          = true,
   .rts_gpio       = PIN_UART1_RTS,
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_UART1_RS485CONTROL)
+  .rs485control     = true,
+#  endif
 #  endif
 #  ifdef CONFIG_KINETIS_UART1_RXDMA
   .rxdma_reqsrc   = KINETIS_DMA_REQUEST_SRC_UART1_RX,
@@ -584,6 +593,9 @@ static struct up_dev_s g_uart2priv =
 #  if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART2_IFLOWCONTROL)
   .iflow          = true,
   .rts_gpio       = PIN_UART2_RTS,
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_UART2_RS485CONTROL)
+  .rs485control   = true,
+#  endif
 #  endif
 #  ifdef CONFIG_KINETIS_UART2_RXDMA
   .rxdma_reqsrc   = KINETIS_DMA_REQUEST_SRC_UART2_RX,
@@ -635,6 +647,9 @@ static struct up_dev_s g_uart3priv =
 #  if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART3_IFLOWCONTROL)
   .iflow          = true,
   .rts_gpio       = PIN_UART3_RTS,
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_UART3_RS485CONTROL)
+  .rs485control   = true,
+#  endif
 #  endif
 #  ifdef CONFIG_KINETIS_UART3_RXDMA
   .rxdma_reqsrc   = KINETIS_DMA_REQUEST_SRC_UART3_RX,
@@ -686,6 +701,9 @@ static struct up_dev_s g_uart4priv =
 #  if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART4_IFLOWCONTROL)
   .iflow          = true,
   .rts_gpio       = PIN_UART4_RTS,
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_UART4_RS485CONTROL)
+  .rs485control   = true,
+#  endif
 #  endif
 #  ifdef CONFIG_KINETIS_UART4_RXDMA
   .rxdma_reqsrc   = KINETIS_DMA_REQUEST_SRC_UART4_RXTX,
@@ -737,6 +755,9 @@ static struct up_dev_s g_uart5priv =
 #  if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART5_IFLOWCONTROL)
   .iflow          = true,
   .rts_gpio       = PIN_UART5_RTS,
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_UART5_RS485CONTROL)
+  .rs485control   = true,
+#  endif
 #  endif
 #  ifdef CONFIG_KINETIS_UART5_RXDMA
   .rxdma_reqsrc   = KINETIS_DMA_REQUEST_SRC_UART5_RX,
@@ -907,6 +928,11 @@ static int up_setup(struct uart_dev_s *dev)
 #else
   bool iflow = false;
 #endif
+#ifdef CONFIG_SERIAL_RS485CONTROL
+  bool rs485control = priv->rs485control;
+#else
+  bool rs485control = false;
+#endif
 #ifdef CONFIG_SERIAL_OFLOWCONTROL
   bool oflow = priv->oflow;
 #else
@@ -917,7 +943,7 @@ static int up_setup(struct uart_dev_s *dev)
 
   kinetis_uartconfigure(priv->uartbase, priv->baud, priv->clock,
                         priv->parity, priv->bits, priv->stop2,
-                        iflow, oflow);
+                        iflow, oflow, rs485control);
 #endif
 
   /* Make sure that all interrupts are disabled */
@@ -1442,7 +1468,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned 
long arg)
 
         kinetis_uartconfigure(priv->uartbase, priv->baud, priv->clock,
                                 priv->parity, priv->bits, priv->stop2,
-                                iflow, oflow);
+                                iflow, oflow, priv->rs485control);
       }
       break;
 #endif /* CONFIG_SERIAL_TERMIOS */
-- 
2.47.3

Reply via email to