mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 13:27:01 +08:00
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.
This commit is contained in:
committed by
Xiang Xiao
parent
8b2c8c73e8
commit
375cb09ff0
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/fs/ioctl.h>
|
||||||
#include <nuttx/serial/serial.h>
|
#include <nuttx/serial/serial.h>
|
||||||
|
|
||||||
#include <arch/board/board.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)
|
static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SERIAL_TERMIOS
|
#if defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || defined(CONFIG_SERIAL_TERMIOS)
|
||||||
struct inode *inode;
|
struct inode *inode = filep->f_inode;
|
||||||
struct uart_dev_s *dev;
|
struct uart_dev_s *dev = inode->i_private;
|
||||||
struct up_dev_s *priv;
|
#endif
|
||||||
int ret = OK;
|
#if defined(CONFIG_SERIAL_TERMIOS)
|
||||||
|
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||||
DEBUGASSERT(filep, filep->f_inode);
|
#endif
|
||||||
inode = filep->f_inode;
|
int ret = OK;
|
||||||
dev = inode->i_private;
|
|
||||||
|
|
||||||
DEBUGASSERT(dev, dev->priv);
|
|
||||||
priv = (struct up_dev_s *)dev->priv;
|
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case xxx: /* Add commands here */
|
#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT
|
||||||
break;
|
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:
|
case TCGETS:
|
||||||
{
|
{
|
||||||
struct termios *termiosp = (struct termios *)arg;
|
struct termios *termiosp = (struct termios *)arg;
|
||||||
|
tcflag_t ccflag = 0;
|
||||||
|
|
||||||
if (!termiosp)
|
if (!termiosp)
|
||||||
{
|
{
|
||||||
@@ -838,11 +850,36 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Other termios fields are not yet returned.
|
if (priv->bits >= 5 && priv->bits <= 8)
|
||||||
* Note that only cfsetospeed is not necessary because we have
|
{
|
||||||
|
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.
|
* knowledge that only one speed is supported.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
termiosp->c_cflag = ccflag;
|
||||||
|
|
||||||
cfsetispeed(termiosp, priv->baud);
|
cfsetispeed(termiosp, priv->baud);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -850,6 +887,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
|||||||
case TCSETS:
|
case TCSETS:
|
||||||
{
|
{
|
||||||
struct termios *termiosp = (struct termios *)arg;
|
struct termios *termiosp = (struct termios *)arg;
|
||||||
|
unsigned int nbits;
|
||||||
|
|
||||||
if (!termiosp)
|
if (!termiosp)
|
||||||
{
|
{
|
||||||
@@ -857,6 +895,44 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
|||||||
break;
|
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.
|
/* TODO: Handle other termios settings.
|
||||||
* Note that only cfgetispeed is used because we have knowledge
|
* Note that only cfgetispeed is used because we have knowledge
|
||||||
* that only one speed is supported.
|
* 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);
|
priv->bits, priv->stopbits2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif /* CONFIG_SERIAL_TERMIOS */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = -ENOTTY;
|
ret = -ENOTTY;
|
||||||
@@ -874,9 +951,6 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
#else
|
|
||||||
return -ENOTTY;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
Reference in New Issue
Block a user