This is an automated email from the ASF dual-hosted git repository.

xiaoxiang 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 8b2c8c73e8 arch/tiva: Serial TIOCxBRK BSD-compatible BREAK support
8b2c8c73e8 is described below

commit 8b2c8c73e85df9ec816c15012eeaff3fbb72b99c
Author: Nathan Hartman <[email protected]>
AuthorDate: Wed Feb 8 08:48:39 2023 -0500

    arch/tiva: Serial TIOCxBRK BSD-compatible BREAK support
    
    In the lower half UART driver for Tiva architecture (TM4C12x), adding
    the TIOCxBRK ioctl calls, which allow an application to transmit a BSD
    compatible line BREAK. TIOCSBRK starts the BREAK and TIOCCBRK ends it.
    
    This architecture supports BSD-style BREAK in hardware. We write to
    the BRK bit (bit 0) of the UART Line Control register (UARTLCRH) to
    start the BREAK, which begins after the UART finishes shifting out the
    current character in progress, if any, including its stop bit(s), and
    continues indefinitely until we write to the BRK bit again to stop the
    BREAK.
    
    * arch/arm/src/tiva/Kconfig
      (config TIVA_UART_BREAKS): New. Appears as CONFIG_TIVA_UART_BREAKS
       in code.
    
    * arch/arm/src/tiva/common/tiva_serial.c
      (struct up_dev_s): Add new field 'brk' to indicate line break in
       progress when built with CONFIG_TIVA_UART_BREAKS.
      (up_ioctl): Add cases for TIOCSBRK to turn BSD-compatible break on
       unconditionally and TIOCCBRK to turn break off unconditionally.
      (up_txint): Block enabling TX interrupt if line break in progress.
       This is similar to the STM32F7 implementation.
---
 arch/arm/src/tiva/Kconfig              | 13 +++++++
 arch/arm/src/tiva/common/tiva_serial.c | 64 ++++++++++++++++++++++++++++++++--
 2 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/arch/arm/src/tiva/Kconfig b/arch/arm/src/tiva/Kconfig
index 91eed4cf01..1d69cb7680 100644
--- a/arch/arm/src/tiva/Kconfig
+++ b/arch/arm/src/tiva/Kconfig
@@ -1081,6 +1081,19 @@ config TIVA_HCIUART_SW_TXFLOW
 
 endmenu # HCI UART Driver Configuration
 
+config TIVA_UART_BREAKS
+       bool "Add TIOxSBRK to support sending Breaks"
+       depends on TIVA_UART0 || TIVA_UART1 || TIVA_UART2 || TIVA_UART3 || 
TIVA_UART4 || TIVA_UART5 || TIVA_UART6 || TIVA_UART7
+       default n
+       ---help---
+               Add TIOCxBRK routines to send a BSD compatible line break.
+               TIOCSBRK will start the break and TIOCCBRK will end the break.
+               This implementation uses the BRK bit (bit 0) of the UART Line
+               Control register (UARTLCRH) to send the break. The break begins
+               after the UART finishes shifting out the current character in
+               progress, if any, including its stop bit(s), and continues
+               indefinitely until stopped by software.
+
 config TIVA_SSI0
        bool "SSI0"
        default n
diff --git a/arch/arm/src/tiva/common/tiva_serial.c 
b/arch/arm/src/tiva/common/tiva_serial.c
index e1ce628bb9..683971fb5b 100644
--- a/arch/arm/src/tiva/common/tiva_serial.c
+++ b/arch/arm/src/tiva/common/tiva_serial.c
@@ -301,6 +301,9 @@ struct up_dev_s
 #ifdef CONFIG_SERIAL_OFLOWCONTROL
   bool     oflow;     /* output flow control (CTS) enabled */
 #endif
+#ifdef CONFIG_TIVA_UART_BREAKS
+  bool     brk;       /* true: Line break in progress */
+#endif
 };
 
 /****************************************************************************
@@ -1099,11 +1102,12 @@ static int up_interrupt(int irq, void *context, void 
*arg)
 
 static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
 {
-#if defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || defined(CONFIG_SERIAL_TERMIOS)
+#if defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || defined(CONFIG_SERIAL_TERMIOS) \
+    || defined(CONFIG_TIVA_UART_BREAKS)
   struct inode      *inode = filep->f_inode;
   struct uart_dev_s *dev   = inode->i_private;
 #endif
-#if defined(CONFIG_SERIAL_TERMIOS)
+#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_TIVA_UART_BREAKS)
   struct up_dev_s   *priv  = (struct up_dev_s *)dev->priv;
 #endif
   int                ret   = OK;
@@ -1242,6 +1246,52 @@ static int up_ioctl(struct file *filep, int cmd, 
unsigned long arg)
       break;
 #endif /* CONFIG_SERIAL_TERMIOS */
 
+#ifdef CONFIG_TIVA_UART_BREAKS
+    case TIOCSBRK:  /* BSD compatibility: Turn break on, unconditionally */
+      {
+        irqstate_t flags;
+        uint32_t tx_break;
+
+        flags = enter_critical_section();
+
+        /* Disable any further tx activity */
+
+        priv->brk = true;
+        up_txint(dev, false);
+
+        /* Send a break signal */
+
+        tx_break = up_serialin(priv, TIVA_UART_LCRH_OFFSET);
+        tx_break |= UART_LCRH_BRK;
+        up_serialout(priv, TIVA_UART_LCRH_OFFSET, tx_break);
+
+        leave_critical_section(flags);
+      }
+      break;
+
+    case TIOCCBRK:  /* BSD compatibility: Turn break off, unconditionally */
+      {
+        irqstate_t flags;
+        uint32_t tx_break;
+
+        flags = enter_critical_section();
+
+        /* Stop sending the break signal */
+
+        tx_break = up_serialin(priv, TIVA_UART_LCRH_OFFSET);
+        tx_break &= ~UART_LCRH_BRK;
+        up_serialout(priv, TIVA_UART_LCRH_OFFSET, tx_break);
+
+        /* Enable further tx activity */
+
+        priv->brk = false;
+        up_txint(dev, true);
+
+        leave_critical_section(flags);
+      }
+      break;
+#endif /* CONFIG_TIVA_UART_BREAKS */
+
     default:
       ret = -ENOTTY;
       break;
@@ -1351,6 +1401,16 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
       /* Set to receive an interrupt when the TX fifo is half emptied */
 
 #ifndef CONFIG_SUPPRESS_SERIAL_INTS
+#  ifdef CONFIG_TIVA_UART_BREAKS
+      /* Do not enable TX interrupt if line break in progress */
+
+      if (priv->brk)
+        {
+          leave_critical_section(flags);
+          return;
+        }
+#  endif
+
       priv->im |= UART_IM_TXIM;
       up_serialout(priv, TIVA_UART_IM_OFFSET, priv->im);
 

Reply via email to