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:
parent
8b2c8c73e8
commit
375cb09ff0
@ -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
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user