diff options
author | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-07-31 23:45:21 +0000 |
---|---|---|
committer | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-07-31 23:45:21 +0000 |
commit | 5613fbf73362a2e94ba18c8671669703f77da191 (patch) | |
tree | 323f6bd35c6522a6c72895c19f536742f822f54e /nuttx/arch/arm/src/lpc17xx | |
parent | 4f4e8123b61339fa053b597f14dd0697b675eebf (diff) |
LPC17xx serial now supports minimal termios ioctls; serial driver ioctl methods should not set errno variable
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4994 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx/arch/arm/src/lpc17xx')
-rw-r--r-- | nuttx/arch/arm/src/lpc17xx/lpc17_serial.c | 207 |
1 files changed, 138 insertions, 69 deletions
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_serial.c b/nuttx/arch/arm/src/lpc17xx/lpc17_serial.c index 10b4a4838d..ced1c5d665 100644 --- a/nuttx/arch/arm/src/lpc17xx/lpc17_serial.c +++ b/nuttx/arch/arm/src/lpc17xx/lpc17_serial.c @@ -47,6 +47,9 @@ #include <string.h> #include <errno.h> #include <debug.h> +#ifdef CONFIG_SERIAL_TERMIOS +# include <termios.h> +#endif #include <nuttx/irq.h> #include <nuttx/arch.h> @@ -136,14 +139,17 @@ struct uart_ops_s g_uart_ops = static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; #endif + #ifdef CONFIG_LPC17_UART1 static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; #endif + #ifdef CONFIG_LPC17_UART2 static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; #endif + #ifdef CONFIG_LPC17_UART3 static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; @@ -273,16 +279,16 @@ static uart_dev_t g_uart3port = #ifdef HAVE_CONSOLE # if defined(CONFIG_UART0_SERIAL_CONSOLE) -# define CONSOLE_DEV g_uart0port /* UART0=console */ -# define TTYS0_DEV g_uart0port /* UART0=ttyS0 */ +# define CONSOLE_DEV g_uart0port /* UART0=console */ +# define TTYS0_DEV g_uart0port /* UART0=ttyS0 */ # ifdef CONFIG_LPC17_UART1 -# define TTYS1_DEV g_uart1port /* UART0=ttyS0;UART1=ttyS1 */ +# define TTYS1_DEV g_uart1port /* UART0=ttyS0;UART1=ttyS1 */ # ifdef CONFIG_LPC17_UART2 -# define TTYS2_DEV g_uart2port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2 */ +# define TTYS2_DEV g_uart2port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2 */ # ifdef CONFIG_LPC17_UART3 -# define TTYS3_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2;UART3=ttyS3 */ +# define TTYS3_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2;UART3=ttyS3 */ # else -# undef TTYS3_DEV /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS;No ttyS3 */ +# undef TTYS3_DEV /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS;No ttyS3 */ # endif # else # ifdef CONFIG_LPC17_UART3 @@ -294,18 +300,18 @@ static uart_dev_t g_uart3port = # endif # else # ifdef CONFIG_LPC17_UART2 -# define TTYS1_DEV g_uart2port /* UART0=ttyS0;UART2=ttyS1;No ttyS3 */ +# define TTYS1_DEV g_uart2port /* UART0=ttyS0;UART2=ttyS1;No ttyS3 */ # ifdef CONFIG_LPC17_UART3 -# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART2=ttyS1;UART3=ttyS2;No ttyS3 */ +# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART2=ttyS1;UART3=ttyS2;No ttyS3 */ # else -# undef TTYS2_DEV /* UART0=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */ +# undef TTYS2_DEV /* UART0=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */ # endif -# undef TTYS3_DEV /* No ttyS3 */ +# undef TTYS3_DEV /* No ttyS3 */ # else # ifdef CONFIG_LPC17_UART3 -# define TTYS1_DEV g_uart3port /* UART0=ttyS0;UART3=ttyS1;No ttyS2;No ttyS3 */ +# define TTYS1_DEV g_uart3port /* UART0=ttyS0;UART3=ttyS1;No ttyS2;No ttyS3 */ # else -# undef TTYS1_DEV /* UART0=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# undef TTYS1_DEV /* UART0=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ # endif # undef TTYS2_DEV /* No ttyS2 */ # undef TTYS3_DEV /* No ttyS3 */ @@ -372,100 +378,100 @@ static uart_dev_t g_uart3port = # endif # else # ifdef CONFIG_LPC17_UART1 -# define TTYS1_DEV g_uart1port /* UART2=ttyS0;UART1=ttyS1 */ +# define TTYS1_DEV g_uart1port /* UART2=ttyS0;UART1=ttyS1 */ # ifdef CONFIG_LPC17_UART3 -# define TTYS2_DEV g_uart3port /* UART2=ttyS0;UART1=ttyS1;UART3=ttyS2 */ +# define TTYS2_DEV g_uart3port /* UART2=ttyS0;UART1=ttyS1;UART3=ttyS2 */ # else -# undef TTYS2_DEV /* UART2=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ +# undef TTYS2_DEV /* UART2=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ # endif -# undef TTYS3_DEV /* No ttyS3 */ +# undef TTYS3_DEV /* No ttyS3 */ # else # ifdef CONFIG_LPC17_UART3 -# define TTYS1_DEV g_uart3port /* UART2=ttyS0;UART3=ttyS1;No ttyS3 */ +# define TTYS1_DEV g_uart3port /* UART2=ttyS0;UART3=ttyS1;No ttyS3 */ # else -# undef TTYS1_DEV /* UART2=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# undef TTYS1_DEV /* UART2=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ # endif -# undef TTYS2_DEV /* No ttyS2 */ -# undef TTYS3_DEV /* No ttyS3 */ +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ # endif # endif # elif defined(CONFIG_UART3_SERIAL_CONSOLE) -# define CONSOLE_DEV g_uart3port /* UART3=console */ -# define TTYS0_DEV g_uart3port /* UART3=ttyS0 */ +# define CONSOLE_DEV g_uart3port /* UART3=console */ +# define TTYS0_DEV g_uart3port /* UART3=ttyS0 */ # ifdef CONFIG_LPC17_UART0 -# define TTYS1_DEV g_uart0port /* UART3=ttyS0;UART0=ttyS1 */ +# define TTYS1_DEV g_uart0port /* UART3=ttyS0;UART0=ttyS1 */ # ifdef CONFIG_LPC17_UART1 -# define TTYS2_DEV g_uart1port /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS2 */ +# define TTYS2_DEV g_uart1port /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS2 */ # ifdef CONFIG_LPC17_UART2 -# define TTYS3_DEV g_uart2port /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS2;UART2=ttyS3 */ +# define TTYS3_DEV g_uart2port /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS2;UART2=ttyS3 */ # else -# undef TTYS3_DEV /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS;No ttyS3 */ +# undef TTYS3_DEV /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS;No ttyS3 */ # endif # else # ifdef CONFIG_LPC17_UART2 -# define TTYS2_DEV g_uart2port /* UART3=ttyS0;UART0=ttyS1;UART2=ttys2;No ttyS3 */ +# define TTYS2_DEV g_uart2port /* UART3=ttyS0;UART0=ttyS1;UART2=ttys2;No ttyS3 */ # else -# undef TTYS2_DEV /* UART3=ttyS0;UART0=ttyS1;No ttyS2;No ttyS3 */ +# undef TTYS2_DEV /* UART3=ttyS0;UART0=ttyS1;No ttyS2;No ttyS3 */ # endif -# undef TTYS3_DEV /* No ttyS3 */ +# undef TTYS3_DEV /* No ttyS3 */ # endif # else # ifdef CONFIG_LPC17_UART1 -# define TTYS1_DEV g_uart1port /* UART3=ttyS0;UART1=ttyS1 */ +# define TTYS1_DEV g_uart1port /* UART3=ttyS0;UART1=ttyS1 */ # ifdef CONFIG_LPC17_UART2 -# define TTYS2_DEV g_uart2port /* UART3=ttyS0;UART1=ttyS1;UART2=ttyS2;No ttyS3 */ +# define TTYS2_DEV g_uart2port /* UART3=ttyS0;UART1=ttyS1;UART2=ttyS2;No ttyS3 */ # else -# undef TTYS2_DEV /* UART3=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ +# undef TTYS2_DEV /* UART3=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ # endif -# undef TTYS3_DEV /* No ttyS3 */ +# undef TTYS3_DEV /* No ttyS3 */ # else # ifdef CONFIG_LPC17_UART2 -# define TTYS1_DEV g_uart2port /* UART3=ttyS0;UART2=ttyS1;No ttyS3;No ttyS3 */ -# undef TTYS3_DEV /* UART3=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */ +# define TTYS1_DEV g_uart2port /* UART3=ttyS0;UART2=ttyS1;No ttyS3;No ttyS3 */ +# undef TTYS3_DEV /* UART3=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */ # else -# undef TTYS1_DEV /* UART3=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# undef TTYS1_DEV /* UART3=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ # endif -# undef TTYS2_DEV /* No ttyS2 */ -# undef TTYS3_DEV /* No ttyS3 */ +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ # endif # endif # endif #else /* No console */ -# define TTYS0_DEV g_uart0port /* UART0=ttyS0 */ +# define TTYS0_DEV g_uart0port /* UART0=ttyS0 */ # ifdef CONFIG_LPC17_UART1 -# define TTYS1_DEV g_uart1port /* UART0=ttyS0;UART1=ttyS1 */ +# define TTYS1_DEV g_uart1port /* UART0=ttyS0;UART1=ttyS1 */ # ifdef CONFIG_LPC17_UART2 -# define TTYS2_DEV g_uart2port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2 */ +# define TTYS2_DEV g_uart2port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2 */ # ifdef CONFIG_LPC17_UART3 -# define TTYS3_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2;UART3=ttyS3 */ +# define TTYS3_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2;UART3=ttyS3 */ # else -# undef TTYS3_DEV /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS;No ttyS3 */ +# undef TTYS3_DEV /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS;No ttyS3 */ # endif # else # ifdef CONFIG_LPC17_UART3 -# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART3=ttys2;No ttyS3 */ +# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART3=ttys2;No ttyS3 */ # else -# undef TTYS2_DEV /* UART0=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ +# undef TTYS2_DEV /* UART0=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ # endif -# undef TTYS3_DEV /* No ttyS3 */ +# undef TTYS3_DEV /* No ttyS3 */ # endif # else # ifdef CONFIG_LPC17_UART2 -# define TTYS1_DEV g_uart2port /* UART0=ttyS0;UART2=ttyS1;No ttyS3 */ +# define TTYS1_DEV g_uart2port /* UART0=ttyS0;UART2=ttyS1;No ttyS3 */ # ifdef CONFIG_LPC17_UART3 -# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART2=ttyS1;UART3=ttyS2;No ttyS3 */ +# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART2=ttyS1;UART3=ttyS2;No ttyS3 */ # else -# undef TTYS2_DEV /* UART0=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */ +# undef TTYS2_DEV /* UART0=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */ # endif -# undef TTYS3_DEV /* No ttyS3 */ +# undef TTYS3_DEV /* No ttyS3 */ # else # ifdef CONFIG_LPC17_UART3 -# define TTYS1_DEV g_uart3port /* UART0=ttyS0;UART3=ttyS1;No ttyS2;No ttyS3 */ +# define TTYS1_DEV g_uart3port /* UART0=ttyS0;UART3=ttyS1;No ttyS2;No ttyS3 */ # else -# undef TTYS1_DEV /* UART0=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# undef TTYS1_DEV /* UART0=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ # endif -# undef TTYS2_DEV /* No ttyS2 */ -# undef TTYS3_DEV /* No ttyS3 */ +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ # endif # endif #endif /*HAVE_CONSOLE*/ @@ -524,6 +530,7 @@ static inline void up_restoreuartint(struct up_dev_s *priv, uint32_t ier) static inline void up_enablebreaks(struct up_dev_s *priv, bool enable) { uint32_t lcr = up_serialin(priv, LPC17_UART_LCR_OFFSET); + if (enable) { lcr |= UART_LCR_BRK; @@ -532,6 +539,7 @@ static inline void up_enablebreaks(struct up_dev_s *priv, bool enable) { lcr &= ~UART_LCR_BRK; } + up_serialout(priv, LPC17_UART_LCR_OFFSET, lcr); } @@ -793,7 +801,6 @@ static inline uint32_t lpc17_uartdl(uint32_t baud, uint8_t divcode) switch (divcode) { - case SYSCON_PCLKSEL_CCLK4: /* PCLK_peripheral = CCLK/4 */ num = (LPC17_CCLK / 4); break; @@ -811,6 +818,7 @@ static inline uint32_t lpc17_uartdl(uint32_t baud, uint8_t divcode) num = (LPC17_CCLK / 8); break; } + return num / (baud << 4); } @@ -950,6 +958,7 @@ static int up_attach(struct uart_dev_s *dev) up_enable_irq(priv->irq); } + return ret; } @@ -1121,18 +1130,17 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) { case TIOCSERGSTRUCT: { - struct up_dev_s *user = (struct up_dev_s*)arg; - if (!user) - { - *get_errno_ptr() = EINVAL; - ret = ERROR; - } - else - { - memcpy(user, dev, sizeof(struct up_dev_s)); - } - } - break; + struct up_dev_s *user = (struct up_dev_s*)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ { @@ -1151,9 +1159,68 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) } break; +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios*)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Other termios fields are not yet returned. + * Note that cfsetospeed is not necessary because we have + * knowledge that only one speed is supported. + * Both cfset(i|o)speed() translate to cfsetspeed. + */ + + cfsetispeed(termiosp, priv->baud); + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios*)arg; + uint32_t lcr; /* Holds current values of line control register */ + uint16_t dl; /* Divisor latch */ + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Handle other termios settings. + * Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + /* Get the c_speed field in the termios struct */ + + priv->baud = cfgetispeed(termiosp); + + /* DLAB open latch */ + + lcr = getreg32(priv->uartbase + LPC17_UART_LCR_OFFSET); + up_serialout(priv, LPC17_UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); + + /* Set the BAUD divisor */ + + dl = lpc17_uartdl(priv->baud, priv->cclkdiv); + up_serialout(priv, LPC17_UART_DLM_OFFSET, dl >> 8); + up_serialout(priv, LPC17_UART_DLL_OFFSET, dl & 0xff); + + /* Clear DLAB */ + + up_serialout(priv, LPC17_UART_LCR_OFFSET, lcr); + } + break; +#endif + default: - *get_errno_ptr() = ENOTTY; - ret = ERROR; + ret = -ENOTTY; break; } @@ -1201,6 +1268,7 @@ static void up_rxint(struct uart_dev_s *dev, bool enable) { priv->ier &= ~UART_IER_RBRIE; } + up_serialout(priv, LPC17_UART_IER_OFFSET, priv->ier); } @@ -1264,6 +1332,7 @@ static void up_txint(struct uart_dev_s *dev, bool enable) priv->ier &= ~UART_IER_THREIE; up_serialout(priv, LPC17_UART_IER_OFFSET, priv->ier); } + irqrestore(flags); } |