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 375cb09ff0 arch/pic32mz: Serial support for termios
375cb09ff0 is described below

commit 375cb09ff0612aa763a9485bf6c276be8803b245
Author: Nathan Hartman <[email protected]>
AuthorDate: Wed Feb 8 09:07:38 2023 -0500

    arch/pic32mz: Serial support for termios
    
    Previously, it was impossible to build for PIC32MZ architecture with
    CONFIG_SERIAL_TERMIOS because it introduced compiler errors in the
    lower half driver.
    
    Fixing the compiler errors and adding an implementation of the
    TIOCSERGSTRUCT, TCGETS, and TCSETS ioctl calls.
    
    * arch/mips/src/pic32mz/pic32mz_serial.c
      (): Include nuttx/fs/ioctl.h, needed for the TIOCSERGSTRUCT, TCGETS,
       and TCSETS defines.
      (up_ioctl): Fix compile breakage. Implement TIOCSERGSTRUCT. Make
       TCGETS return data bits, parity, and stop bits. Make TCSETS apply
       changes to data bits, parity, and stop bits.
---
 arch/mips/src/pic32mz/pic32mz_serial.c | 112 +++++++++++++++++++++++++++------
 1 file changed, 93 insertions(+), 19 deletions(-)

diff --git a/arch/mips/src/pic32mz/pic32mz_serial.c 
b/arch/mips/src/pic32mz/pic32mz_serial.c
index 53c3f8508e..47ca3ab225 100644
--- a/arch/mips/src/pic32mz/pic32mz_serial.c
+++ b/arch/mips/src/pic32mz/pic32mz_serial.c
@@ -39,6 +39,7 @@
 
 #include <nuttx/irq.h>
 #include <nuttx/arch.h>
+#include <nuttx/fs/ioctl.h>
 #include <nuttx/serial/serial.h>
 
 #include <arch/board/board.h>
@@ -810,27 +811,38 @@ static int up_interrupt(int irq, void *context, void *arg)
 
 static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
 {
-#ifdef CONFIG_SERIAL_TERMIOS
-  struct inode      *inode;
-  struct uart_dev_s *dev;
-  struct up_dev_s   *priv;
-  int                ret = OK;
-
-  DEBUGASSERT(filep, filep->f_inode);
-  inode = filep->f_inode;
-  dev   = inode->i_private;
-
-  DEBUGASSERT(dev, dev->priv);
-  priv = (struct up_dev_s *)dev->priv;
+#if defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || defined(CONFIG_SERIAL_TERMIOS)
+  struct inode      *inode = filep->f_inode;
+  struct uart_dev_s *dev   = inode->i_private;
+#endif
+#if defined(CONFIG_SERIAL_TERMIOS)
+  struct up_dev_s   *priv  = (struct up_dev_s *)dev->priv;
+#endif
+  int                ret   = OK;
 
   switch (cmd)
     {
-    case xxx: /* Add commands here */
-      break;
+#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT
+    case TIOCSERGSTRUCT:
+      {
+         struct up_dev_s *user = (struct up_dev_s *)arg;
+         if (!user)
+           {
+             ret = -EINVAL;
+           }
+         else
+           {
+             memcpy(user, dev, sizeof(struct up_dev_s));
+           }
+       }
+       break;
+#endif
 
+#ifdef CONFIG_SERIAL_TERMIOS
     case TCGETS:
       {
         struct termios *termiosp = (struct termios *)arg;
+        tcflag_t ccflag = 0;
 
         if (!termiosp)
           {
@@ -838,11 +850,36 @@ static int up_ioctl(struct file *filep, int cmd, unsigned 
long arg)
             break;
           }
 
-        /* TODO:  Other termios fields are not yet returned.
-         * Note that only cfsetospeed is not necessary because we have
+        if (priv->bits >= 5 && priv->bits <= 8)
+          {
+            ccflag |= (CS5 + (priv->bits - 5));
+          }
+
+        if (priv->stopbits2)
+          {
+            ccflag |= CSTOPB;
+          }
+
+        if (priv->parity == 1)
+          {
+            ccflag |= PARENB;
+          }
+        else if (priv->parity == 2)
+          {
+            ccflag |= PARENB | PARODD;
+          }
+
+        /* TODO: Other termios fields are not yet returned.
+         *
+         * TODO: append support for CCTS_OFLOW, CRTS_IFLOW, HUPCL, and
+         *       CLOCAL as well as os-compliant break sequence.
+         *
+         * Note that cfsetospeed is not necessary because we have
          * knowledge that only one speed is supported.
          */
 
+        termiosp->c_cflag = ccflag;
+
         cfsetispeed(termiosp, priv->baud);
       }
       break;
@@ -850,6 +887,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned 
long arg)
     case TCSETS:
       {
         struct termios *termiosp = (struct termios *)arg;
+        unsigned int nbits;
 
         if (!termiosp)
           {
@@ -857,6 +895,44 @@ static int up_ioctl(struct file *filep, int cmd, unsigned 
long arg)
             break;
           }
 
+        /* Perform some sanity checks before accepting any changes */
+
+        if (termiosp->c_cflag & CRTSCTS)
+          {
+            /* We don't support flow control right now, so we report an
+             * error
+             */
+
+            ret = -EINVAL;
+            break;
+          }
+
+        nbits = (termiosp->c_cflag & CSIZE) + 5;
+        if ((nbits < 8) || (nbits > 9))
+          {
+            /* We only support 8 or 9 data bits on this arch, so we
+             * report an error
+             */
+
+            ret = -EINVAL;
+            break;
+          }
+
+        /* Sanity checks passed; apply settings. */
+
+        priv->bits = nbits;
+
+        if (termiosp->c_cflag & PARENB)
+          {
+            priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2;
+          }
+        else
+          {
+            priv->parity = 0;
+          }
+
+        priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0;
+
         /* TODO:  Handle other termios settings.
          * Note that only cfgetispeed is used because we have knowledge
          * that only one speed is supported.
@@ -867,6 +943,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned 
long arg)
                               priv->bits, priv->stopbits2);
       }
       break;
+#endif /* CONFIG_SERIAL_TERMIOS */
 
     default:
       ret = -ENOTTY;
@@ -874,9 +951,6 @@ static int up_ioctl(struct file *filep, int cmd, unsigned 
long arg)
     }
 
   return ret;
-#else
-  return -ENOTTY;
-#endif
 }
 
 /****************************************************************************

Reply via email to