diff options
Diffstat (limited to 'nuttx/drivers/serial')
-rw-r--r-- | nuttx/drivers/serial/Kconfig | 1054 | ||||
-rw-r--r-- | nuttx/drivers/serial/Make.defs | 50 | ||||
-rw-r--r-- | nuttx/drivers/serial/lowconsole.c | 132 | ||||
-rw-r--r-- | nuttx/drivers/serial/serial.c | 1377 | ||||
-rw-r--r-- | nuttx/drivers/serial/serialirq.c | 186 | ||||
-rw-r--r-- | nuttx/drivers/serial/uart_16550.c | 1164 |
6 files changed, 0 insertions, 3963 deletions
diff --git a/nuttx/drivers/serial/Kconfig b/nuttx/drivers/serial/Kconfig deleted file mode 100644 index 119923a69..000000000 --- a/nuttx/drivers/serial/Kconfig +++ /dev/null @@ -1,1054 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see misc/tools/kconfig-language.txt. -# - -config DEV_LOWCONSOLE - bool "Low-level console support" - default n - depends on ARCH_LOWPUTC - ---help--- - Use the simple, low-level, write-only serial console driver (minimal support) - -config SERIAL_REMOVABLE - bool - -config 16550_UART - bool "16550 UART Chip support" - default n - -if 16550_UART -config 16550_UART0 - bool "16550 UART0" - default n - -if 16550_UART0 -config 16550_UART0_BASE - hex "16550 UART0 base address" - -config 16550_UART0_CLOCK - int "16550 UART0 clock" - -config 16550_UART0_IRQ - int "16550 UART0 IRQ number" - -config 16550_UART0_BAUD - int "16550 UART0 BAUD" - default 115200 - -config 16550_UART0_PARITY - int "16550 UART0 parity" - default 0 - ---help--- - 16550 UART0 parity. 0=None, 1=Odd, 2=Even. Default: None - -config 16550_UART0_BITS - int "16550 UART0 number of bits" - default 8 - ---help--- - 16550 UART0 number of bits. Default: 8 - -config 16550_UART0_2STOP - int "16550 UART0 two stop bits" - default 0 - ---help--- - 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit - -config 16550_UART0_RXBUFSIZE - int "16550 UART0 Rx buffer size" - default 256 - ---help--- - 16550 UART0 Rx buffer size. Default: 256 - -config 16550_UART0_TXBUFSIZE - int "16550 UART0 Tx buffer size" - default 256 - ---help--- - 16550 UART0 Tx buffer size. Default: 256 - -endif - -config 16550_UART1 - bool "16550 UART1" - default n - -if 16550_UART1 -config 16550_UART1_BASE - hex "16550 UART1 base address" - -config 16550_UART1_CLOCK - int "16550 UART1 clock" - -config 16550_UART1_IRQ - int "16550 UART1 IRQ number" - -config 16550_UART1_BAUD - int "16550 UART1 BAUD" - default 115200 - -config 16550_UART1_PARITY - int "16550 UART1 parity" - default 0 - ---help--- - 16550 UART1 parity. 0=None, 1=Odd, 2=Even. Default: None - -config 16550_UART1_BITS - int "16550 UART1 number of bits" - default 8 - ---help--- - 16550 UART1 number of bits. Default: 8 - -config 16550_UART1_2STOP - int "16550 UART1 two stop bits" - default 0 - ---help--- - 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit - -config 16550_UART1_RXBUFSIZE - int "16550 UART1 Rx buffer size" - default 256 - ---help--- - 16550 UART1 Rx buffer size. Default: 256 - -config 16550_UART1_TXBUFSIZE - int "16550 UART1 Tx buffer size" - default 256 - ---help--- - 16550 UART1 Tx buffer size. Default: 256 - -endif - -config 16550_UART2 - bool "16550 UART2" - default n - -if 16550_UART2 -config 16550_UART2_BASE - hex "16550 UART2 base address" - -config 16550_UART2_CLOCK - int "16550 UART2 clock" - -config 16550_UART2_IRQ - int "16550 UART2 IRQ number" - -config 16550_UART2_BAUD - int "16550 UART2 BAUD" - default 115200 - -config 16550_UART2_PARITY - int "16550 UART2 parity" - default 0 - ---help--- - 16550 UART2 parity. 0=None, 1=Odd, 2=Even. Default: None - -config 16550_UART2_BITS - int "16550 UART2 number of bits" - default 8 - ---help--- - 16550 UART2 number of bits. Default: 8 - -config 16550_UART2_2STOP - int "16550 UART2 two stop bits" - default 0 - ---help--- - 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit - -config 16550_UART2_RXBUFSIZE - int "16550 UART2 Rx buffer size" - default 256 - ---help--- - 16550 UART2 Rx buffer size. Default: 256 - -config 16550_UART2_TXBUFSIZE - int "16550 UART2 Tx buffer size" - default 256 - ---help--- - 16550 UART2 Tx buffer size. Default: 256 - -endif - -config 16550_UART3 - bool "16550 UART3" - default n - -if 16550_UART3 -config 16550_UART3_BASE - hex "16550 UART3 base address" - -config 16550_UART3_CLOCK - int "16550 UART3 clock" - -config 16550_UART3_IRQ - int "16550 UART3 IRQ number" - -config 16550_UART3_BAUD - int "16550 UART3 BAUD" - default 115200 - -config 16550_UART3_PARITY - int "16550 UART3 parity" - default 0 - ---help--- - 16550 UART3 parity. 0=None, 1=Odd, 2=Even. Default: None - -config 16550_UART3_BITS - int "16550 UART3 number of bits" - default 8 - ---help--- - 16550 UART3 number of bits. Default: 8 - -config 16550_UART3_2STOP - int "16550 UART3 two stop bits" - default 0 - ---help--- - 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit - -config 16550_UART3_RXBUFSIZE - int "16550 UART3 Rx buffer size" - default 256 - ---help--- - 16550 UART3 Rx buffer size. Default: 256 - -config 16550_UART3_TXBUFSIZE - int "16550 UART3 Tx buffer size" - default 256 - ---help--- - 16550 UART3 Tx buffer size. Default: 256 - -endif - -choice - prompt "16550 Serial Console" - default 16550_NO_SERIAL_CONSOLE - -config 16550_UART0_SERIAL_CONSOLE - bool "16550 UART0 serial console" - depends on 16550_UART0 - -config 16550_UART1_SERIAL_CONSOLE - bool "16550 UART1 serial console" - depends on 16550_UART1 - -config 16550_UART2_SERIAL_CONSOLE - bool "16550 UART2 serial console" - depends on 16550_UART2 - -config 16550_UART3_SERIAL_CONSOLE - bool "16550 UART3 serial console" - depends on 16550_UART3 - -config 16550_NO_SERIAL_CONSOLE - bool "No 16550 serial console" - -endchoice - -config 16550_SUPRESS_CONFIG - bool "Suppress 16550 configuration" - default n - ---help--- - This option is useful, for example, if you are using a bootloader - that configures the 16550_UART. In that case, you may want to - just leave the existing console configuration in place. Default: n - -config 16550_REGINCR - int "Address increment between 16550 registers" - default 1 - ---help--- - The address increment between 16550 registers. Options are 1, 2, or 4. - Default: 1 - -config 16550_REGWIDTH - int "Bit width of 16550 registers" - default 8 - ---help--- - The bit width of registers. Options are 8, 16, or 32. Default: 8 - -config 16550_ADDRWIDTH - int "Address width of 16550 registers" - default 8 - ---help--- - The bit width of registers. Options are 8, 16, or 32. Default: 8 - -endif - -# -# MCU serial peripheral driver? -# - -config ARCH_HAVE_UART - bool -config ARCH_HAVE_UART0 - bool -config ARCH_HAVE_UART1 - bool -config ARCH_HAVE_UART2 - bool -config ARCH_HAVE_UART3 - bool -config ARCH_HAVE_UART4 - bool -config ARCH_HAVE_UART5 - bool -config ARCH_HAVE_UART6 - bool - -config ARCH_HAVE_USART0 - bool -config ARCH_HAVE_USART1 - bool -config ARCH_HAVE_USART2 - bool -config ARCH_HAVE_USART3 - bool -config ARCH_HAVE_USART4 - bool -config ARCH_HAVE_USART5 - bool -config ARCH_HAVE_USART6 - bool - -config MCU_SERIAL - bool - default y if ARCH_HAVE_UART || ARCH_HAVE_UART0 || ARCH_HAVE_USART0 || ARCH_HAVE_UART1 || ARCH_HAVE_USART1 || \ - ARCH_HAVE_UART2 || ARCH_HAVE_USART2 || ARCH_HAVE_UART3 || ARCH_HAVE_USART3 || \ - ARCH_HAVE_UART4 || ARCH_HAVE_USART4 || ARCH_HAVE_UART5 || ARCH_HAVE_USART5 || ARCH_HAVE_UART6 || ARCH_HAVE_USART6 - -# -# Standard serial driver configuration -# - -config STANDARD_SERIAL - bool "Enable standard \"upper-half\" serial driver" - default y if MCU_SERIAL - default n if !MCU_SERIAL - depends on !DEV_LOWCONSOLE - ---help--- - Enable the standard, upper-half serial driver used by most MCU serial peripherals. - -config CONFIG_SERIAL_NPOLLWAITERS - int "Number of poll threads" - default 2 - depends on !DISABLE_POLL && STANDARD_SERIAL - ---help--- - Maximum number of threads than can be waiting for POLL events. - Default: 2 - -# -# U[S]ARTn_XYZ settings for MCU serial drivers -# - -choice - prompt "Serial console" - depends on MCU_SERIAL - default NO_SERIAL_CONSOLE - -config UART_SERIAL_CONSOLE - bool "UART" - depends on ARCH_HAVE_UART - -config UART0_SERIAL_CONSOLE - bool "UART0" - depends on ARCH_HAVE_UART0 - -config USART0_SERIAL_CONSOLE - bool "USART0" - depends on ARCH_HAVE_USART0 - -config UART1_SERIAL_CONSOLE - bool "UART1" - depends on ARCH_HAVE_UART1 - -config USART1_SERIAL_CONSOLE - bool "USART1" - depends on ARCH_HAVE_USART1 - -config UART2_SERIAL_CONSOLE - bool "UART2" - depends on ARCH_HAVE_UART2 - -config USART2_SERIAL_CONSOLE - bool "USART2" - depends on ARCH_HAVE_USART2 - -config UART3_SERIAL_CONSOLE - bool "UART3" - depends on ARCH_HAVE_UART3 - -config USART3_SERIAL_CONSOLE - bool "USART3" - depends on ARCH_HAVE_USART3 - -config UART4_SERIAL_CONSOLE - bool "UART4" - depends on ARCH_HAVE_UART4 - -config USART4_SERIAL_CONSOLE - bool "USART4" - depends on ARCH_HAVE_USART4 - -config UART5_SERIAL_CONSOLE - bool "UART5" - depends on ARCH_HAVE_UART5 - -config USART5_SERIAL_CONSOLE - bool "USART5" - depends on ARCH_HAVE_USART5 - -config UART6_SERIAL_CONSOLE - bool "UART6" - depends on ARCH_HAVE_UART6 - -config USART6_SERIAL_CONSOLE - bool "USART6" - depends on ARCH_HAVE_USART6 - -config NO_SERIAL_CONSOLE - bool "No serial console" - -endchoice - -menu "UART Configuration" - depends on ARCH_HAVE_UART - -config UART_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config UART_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config UART_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the UART. - -config UART_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config UART_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config UART_2STOP - int "use 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "UART0 Configuration" - depends on ARCH_HAVE_UART0 - -config UART0_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config UART0_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config UART0_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the UART. - -config UART0_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config UART0_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config UART0_2STOP - int "use 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "USART0 Configuration" - depends on ARCH_HAVE_USART0 - -config USART0_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config USART0_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config USART0_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the USART. - -config USART0_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config USART0_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config USART0_2STOP - int "use 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "UART1 Configuration" - depends on ARCH_HAVE_UART1 - -config UART1_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config UART1_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config UART1_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the UART. - -config UART1_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config UART1_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config UART1_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "USART1 Configuration" - depends on ARCH_HAVE_USART1 - -config USART1_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config USART1_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config USART1_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the USART. - -config USART1_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config USART1_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config USART1_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "UART2 Configuration" - depends on ARCH_HAVE_UART2 - -config UART2_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config UART2_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config UART2_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the UART. - -config UART2_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config UART2_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config UART2_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "USART2 Configuration" - depends on ARCH_HAVE_USART2 - -config USART2_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config USART2_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config USART2_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the USART. - -config USART2_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config USART2_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config USART2_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "UART3 Configuration" - depends on ARCH_HAVE_UART3 - -config UART3_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config UART3_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config UART3_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the UART. - -config UART3_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config UART3_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config UART3_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "USART3 Configuration" - depends on ARCH_HAVE_USART3 - -config USART3_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config USART3_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config USART3_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the USART. - -config USART3_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config USART3_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config USART3_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "UART4 Configuration" - depends on ARCH_HAVE_UART4 - -config UART4_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config UART4_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config UART4_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the UART. - -config UART4_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config UART4_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config UART4_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "USART4 Configuration" - depends on ARCH_HAVE_USART4 - -config USART4_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config USART4_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config USART4_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the USART. - -config USART4_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config USART4_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config USART4_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "UART5 Configuration" - depends on ARCH_HAVE_UART5 - -config UART5_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config UART5_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config UART5_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the UART. - -config UART5_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config UART5_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config UART5_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "USART5 Configuration" - depends on ARCH_HAVE_USART5 - -config USART5_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config USART5_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config USART5_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the USART. - -config USART5_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config USART5_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config USART5_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "USART6 Configuration" - depends on ARCH_HAVE_USART6 - -config USART6_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config USART6_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config USART6_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the USART. - -config USART6_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config USART6_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config USART6_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu - -menu "UART6 Configuration" - depends on ARCH_HAVE_UART6 - -config UART6_RXBUFSIZE - int "receive buffer size" - default 256 - help - Characters are buffered as they are received. This specifies - the size of the receive buffer. - -config UART6_TXBUFSIZE - int "transmit buffer size" - default 256 - help - Characters are buffered before being sent. This specifies - the size of the transmit buffer. - -config UART6_BAUD - int "baud rate" - default 115200 - help - The configured BAUD of the UART. - -config UART6_BITS - int "character size" - default 8 - help - The number of bits. Must be either 7 or 8. - -config UART6_PARITY - int "parity setting" - default 0 - help - 0=no parity, 1=odd parity, 2=even parity - -config UART6_2STOP - int "uses 2 stop bits" - default 0 - help - 1=Two stop bits - -endmenu diff --git a/nuttx/drivers/serial/Make.defs b/nuttx/drivers/serial/Make.defs deleted file mode 100644 index b99f4eb36..000000000 --- a/nuttx/drivers/serial/Make.defs +++ /dev/null @@ -1,50 +0,0 @@ -############################################################################ -# drivers/serial/Make.defs -# -# Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt <gnutt@nuttx.org> -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - -ifneq ($(CONFIG_NFILE_DESCRIPTORS),0) - -# Include serial drivers - -CSRCS += serial.c serialirq.c lowconsole.c - -ifeq ($(CONFIG_16550_UART),y) - CSRCS += uart_16550.c -endif - -# Include serial build support - -DEPPATH += --dep-path serial -VPATH += :serial -endif diff --git a/nuttx/drivers/serial/lowconsole.c b/nuttx/drivers/serial/lowconsole.c deleted file mode 100644 index 1fac49a57..000000000 --- a/nuttx/drivers/serial/lowconsole.c +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** - * drivers/serial/lowconsole.c - * - * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/arch.h> -#include <nuttx/fs/fs.h> - -/**************************************************************************** - * Definitions - ****************************************************************************/ - -/* The architecture must provide up_putc for this driver */ - -#ifndef CONFIG_ARCH_LOWPUTC -# error "Architecture must provide up_putc() for this driver" -#endif - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static ssize_t lowconsole_read(struct file *filep, char *buffer, size_t buflen); -static ssize_t lowconsole_write(struct file *filep, const char *buffer, size_t buflen); -static int lowconsole_ioctl(struct file *filep, int cmd, unsigned long arg); - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -static const struct file_operations g_consoleops = -{ - 0, /* open */ - 0, /* close */ - lowconsole_read, /* read */ - lowconsole_write, /* write */ - 0, /* seek */ - lowconsole_ioctl /* ioctl */ -#ifndef CONFIG_DISABLE_POLL - , 0 /* poll */ -#endif -}; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: lowconsole_ioctl - ****************************************************************************/ - -static int lowconsole_ioctl(struct file *filep, int cmd, unsigned long arg) -{ - return -ENOTTY; -} - -/**************************************************************************** - * Name: lowconsole_read - ****************************************************************************/ - -static ssize_t lowconsole_read(struct file *filep, char *buffer, size_t buflen) -{ - return 0; -} - -/**************************************************************************** - * Name: lowconsole_write - ****************************************************************************/ - -static ssize_t lowconsole_write(struct file *filep, const char *buffer, size_t buflen) -{ - ssize_t ret = buflen; - - for (; buflen; buflen--) - { - up_putc(*buffer++); - } - return ret; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: lowconsole_init -****************************************************************************/ - -void lowconsole_init(void) -{ - (void)register_driver("/dev/console", &g_consoleops, 0666, NULL); -} diff --git a/nuttx/drivers/serial/serial.c b/nuttx/drivers/serial/serial.c deleted file mode 100644 index 0fed1d6c5..000000000 --- a/nuttx/drivers/serial/serial.c +++ /dev/null @@ -1,1377 +0,0 @@ -/************************************************************************************ - * drivers/serial/serial.c - * - * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ************************************************************************************/ - -/************************************************************************************ - * Included Files - ************************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <sys/ioctl.h> -#include <stdint.h> -#include <stdbool.h> -#include <unistd.h> -#include <semaphore.h> -#include <string.h> -#include <fcntl.h> -#include <poll.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/irq.h> -#include <nuttx/arch.h> -#include <nuttx/fs/fs.h> -#include <nuttx/serial/serial.h> - -/************************************************************************************ - * Definitions - ************************************************************************************/ - -/* The architecture must provide up_putc for this driver */ - -#ifndef CONFIG_ARCH_LOWPUTC -# error "Architecture must provide up_putc() for this driver" -#endif - -#define uart_putc(ch) up_putc(ch) - -#define HALF_SECOND_MSEC 500 -#define HALF_SECOND_USEC 500000L - -/************************************************************************************ - * Private Types - ************************************************************************************/ - -/************************************************************************************ - * Private Function Prototypes - ************************************************************************************/ - -static int uart_open(FAR struct file *filep); -static int uart_close(FAR struct file *filep); -static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen); -static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); -static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg); -#ifndef CONFIG_DISABLE_POLL -static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup); -#endif - -/************************************************************************************ - * Private Variables - ************************************************************************************/ - -static const struct file_operations g_serialops = -{ - uart_open, /* open */ - uart_close, /* close */ - uart_read, /* read */ - uart_write, /* write */ - 0, /* seek */ - uart_ioctl /* ioctl */ -#ifndef CONFIG_DISABLE_POLL - , uart_poll /* poll */ -#endif -}; - -/************************************************************************************ - * Private Functions - ************************************************************************************/ - -/************************************************************************************ - * Name: uart_takesem - ************************************************************************************/ - -static int uart_takesem(FAR sem_t *sem, bool errout) -{ - /* Loop, ignoring interrupts, until we have successfully acquired the semaphore */ - - while (sem_wait(sem) != OK) - { - /* The only case that an error should occur here is if the wait was awakened - * by a signal. - */ - - ASSERT(get_errno() == EINTR); - - /* When the signal is received, should we errout? Or should we just continue - * waiting until we have the semaphore? - */ - - if (errout) - { - return -EINTR; - } - } - - return OK; -} - -/************************************************************************************ - * Name: uart_givesem - ************************************************************************************/ - -#define uart_givesem(sem) (void)sem_post(sem) - -/**************************************************************************** - * Name: uart_pollnotify - ****************************************************************************/ - -#ifndef CONFIG_DISABLE_POLL -static void uart_pollnotify(FAR uart_dev_t *dev, pollevent_t eventset) -{ - int i; - - for (i = 0; i < CONFIG_SERIAL_NPOLLWAITERS; i++) - { - struct pollfd *fds = dev->fds[i]; - if (fds) - { -#ifdef CONFIG_SERIAL_REMOVABLE - fds->revents |= ((fds->events | (POLLERR|POLLHUP)) & eventset); -#else - fds->revents |= (fds->events & eventset); -#endif - if (fds->revents != 0) - { - fvdbg("Report events: %02x\n", fds->revents); - sem_post(fds->sem); - } - } - } -} -#else -# define uart_pollnotify(dev,event) -#endif - -/************************************************************************************ - * Name: uart_putxmitchar - ************************************************************************************/ - -static int uart_putxmitchar(FAR uart_dev_t *dev, int ch) -{ - irqstate_t flags; - int nexthead; - int ret; - - /* Increment to see what the next head pointer will be. We need to use the "next" - * head pointer to determine when the circular buffer would overrun - */ - - nexthead = dev->xmit.head + 1; - if (nexthead >= dev->xmit.size) - { - nexthead = 0; - } - - /* Loop until we are able to add the character to the TX buffer */ - - for (;;) - { - if (nexthead != dev->xmit.tail) - { - dev->xmit.buffer[dev->xmit.head] = ch; - dev->xmit.head = nexthead; - return OK; - } - else - { - /* Inform the interrupt level logic that we are waiting. This and - * the following steps must be atomic. - */ - - flags = irqsave(); - -#ifdef CONFIG_SERIAL_REMOVABLE - /* Check if the removable device is no longer connected while we - * have interrupts off. We do not want the transition to occur - * as a race condition before we begin the wait. - */ - - if (dev->disconnected) - { - irqrestore(flags); - return -ENOTCONN; - } -#endif - /* Wait for some characters to be sent from the buffer with the TX - * interrupt enabled. When the TX interrupt is enabled, uart_xmitchars - * should execute and remove some of the data from the TX buffer. - */ - - dev->xmitwaiting = true; - uart_enabletxint(dev); - ret = uart_takesem(&dev->xmitsem, true); - uart_disabletxint(dev); - irqrestore(flags); - -#ifdef CONFIG_SERIAL_REMOVABLE - /* Check if the removable device was disconnected while we were - * waiting. - */ - - if (dev->disconnected) - { - return -ENOTCONN; - } -#endif - /* Check if we were awakened by signal. */ - - if (ret < 0) - { - /* A signal received while waiting for the xmit buffer to become - * non-full will abort the transfer. - */ - - return -EINTR; - } - } - } - - /* We won't get here. Some compilers may complain that this code is - * unreachable. - */ - - return OK; -} - -/************************************************************************************ - * Name: uart_irqwrite - ************************************************************************************/ - -static inline ssize_t uart_irqwrite(FAR uart_dev_t *dev, FAR const char *buffer, size_t buflen) -{ - ssize_t ret = buflen; - - /* Force each character through the low level interface */ - - for (; buflen; buflen--) - { - int ch = *buffer++; - - /* If this is the console, then we should replace LF with CR-LF */ - - if (ch == '\n') - { - uart_putc('\r'); - } - - /* Output the character, using the low-level direct UART interfaces */ - - uart_putc(ch); - } - - return ret; -} - -/************************************************************************************ - * Name: uart_write - ************************************************************************************/ - -static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t buflen) -{ - FAR struct inode *inode = filep->f_inode; - FAR uart_dev_t *dev = inode->i_private; - ssize_t nread = buflen; - int ret; - char ch; - - /* We may receive console writes through this path from interrupt handlers and - * from debug output in the IDLE task! In these cases, we will need to do things - * a little differently. - */ - - if (up_interrupt_context() || getpid() == 0) - { -#ifdef CONFIG_SERIAL_REMOVABLE - /* If the removable device is no longer connected, refuse to write to - * the device. - */ - - if (dev->disconnected) - { - return -ENOTCONN; - } -#endif - - /* up_putc() will be used to generate the output in a busy-wait loop. - * up_putc() is only available for the console device. - */ - - if (dev->isconsole) - { - irqstate_t flags = irqsave(); - ret = uart_irqwrite(dev, buffer, buflen); - irqrestore(flags); - return ret; - } - else - { - return -EPERM; - } - } - - /* Only one user can access dev->xmit.head at a time */ - - ret = (ssize_t)uart_takesem(&dev->xmit.sem, true); - if (ret < 0) - { - /* A signal received while waiting for access to the xmit.head will - * abort the transfer. - */ - - return ret; - } - -#ifdef CONFIG_SERIAL_REMOVABLE - /* If the removable device is no longer connected, refuse to write to the - * device. This check occurs after taking the xmit.sem because the - * disconnection event might have occurred while we were waiting for - * access to the transmit buffers. - */ - - if (dev->disconnected) - { - uart_givesem(&dev->xmit.sem); - return -ENOTCONN; - } -#endif - - /* Loop while we still have data to copy to the transmit buffer. - * we add data to the head of the buffer; uart_xmitchars takes the - * data from the end of the buffer. - */ - - uart_disabletxint(dev); - for (; buflen; buflen--) - { - ch = *buffer++; - - /* Do output post-processing */ - -#ifdef CONFIG_SERIAL_TERMIOS - - if (dev->tc_oflag & OPOST) - { - - /* Mapping CR to NL? */ - - if ((ch == '\r') && (dev->tc_oflag & OCRNL)) - { - ch = '\n'; - } - - /* Are we interested in newline processing? */ - - if ((ch == '\n') && (dev->tc_oflag & (ONLCR | ONLRET))) - { - ret = uart_putxmitchar(dev, '\r'); - - if (ret != OK) - { - break; - } - } - - /* Specifically not handled: - * - * OXTABS - primarily a full-screen terminal optimisation - * ONOEOT - Unix interoperability hack - * OLCUC - Not specified by Posix - * ONOCR - low-speed interactive optimisation - */ - - } - -#else /* !CONFIG_SERIAL_TERMIOS */ - - /* If this is the console, convert \n -> \r\n */ - - if (dev->isconsole && ch == '\n') - { - ret = uart_putxmitchar(dev, '\r'); - } - -#endif - - /* Put the character into the transmit buffer */ - - ret = uart_putxmitchar(dev, ch); - - if (ret != OK) - { - break; - } - - } - - if (dev->xmit.head != dev->xmit.tail) - { - uart_enabletxint(dev); - } - - uart_givesem(&dev->xmit.sem); - - /* uart_putxmitchar() might return an error under one of two - * conditions: (1) The wait for buffer space might have been - * interrupted by a signal (ret should be -EINTR), or (2) if - * CONFIG_SERIAL_REMOVABLE is defined, then uart_putxmitchar() - * might also return if the serial device was disconnected - * (wtih -ENOTCONN). - */ - - if (ret < 0) - { - /* POSIX requires that we return -1 and errno set if no data was - * transferred. Otherwise, we return the number of bytes in the - * interrupted transfer. - */ - - if (buflen < nread) - { - /* Some data was transferred. Return the number of bytes that were - * successfully transferred. - */ - - nread -= buflen; - } - else - { - /* No data was transferred. Return the negated error. The VFS layer - * will set the errno value appropriately). - */ - - nread = -ret; - } - } - - return nread; -} - -/************************************************************************************ - * Name: uart_read - ************************************************************************************/ - -static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen) -{ - FAR struct inode *inode = filep->f_inode; - FAR uart_dev_t *dev = inode->i_private; - irqstate_t flags; - ssize_t recvd = 0; - int16_t tail; - int ret; - char ch; - - /* Only one user can access dev->recv.tail at a time */ - - ret = uart_takesem(&dev->recv.sem, true); - if (ret < 0) - { - /* A signal received while waiting for access to the recv.tail will avort - * the transfer. After the transfer has started, we are committed and - * signals will be ignored. - */ - - return ret; - } - - /* Loop while we still have data to copy to the receive buffer. - * we add data to the head of the buffer; uart_xmitchars takes the - * data from the end of the buffer. - */ - - while (recvd < buflen) - { -#ifdef CONFIG_SERIAL_REMOVABLE - /* If the removable device is no longer connected, refuse to read any - * further from the device. - */ - - if (dev->disconnected) - { - if (recvd == 0) - { - recvd = -ENOTCONN; - } - - break; - } -#endif - - /* Check if there is more data to return in the circular buffer. - * NOTE: Rx interrupt handling logic may aynchronously increment - * the head index but must not modify the tail index. The tail - * index is only modified in this function. Therefore, no - * special handshaking is required here. - * - * The head and tail pointers are 16-bit values. The only time that - * the following could be unsafe is if the CPU made two non-atomic - * 8-bit accesses to obtain the 16-bit head index. - */ - - tail = dev->recv.tail; - if (dev->recv.head != tail) - { - /* Take the next character from the tail of the buffer */ - - ch = dev->recv.buffer[tail]; - - /* Increment the tail index. Most operations are done using the - * local variable 'tail' so that the final dev->recv.tail update - * is atomic. - */ - - if (++tail >= dev->recv.size) - { - tail = 0; - } - - dev->recv.tail = tail; - -#ifdef CONFIG_SERIAL_TERMIOS - - /* Do input processing if any is enabled */ - - if (dev->tc_iflag & (INLCR | IGNCR | ICRNL)) - { - - /* \n -> \r or \r -> \n translation? */ - - if ((ch == '\n') && (dev->tc_iflag & INLCR)) - { - ch = '\r'; - } - else if ((ch == '\r') && (dev->tc_iflag & ICRNL)) - { - ch = '\n'; - } - - /* discarding \r ? */ - if ((ch == '\r') & (dev->tc_iflag & IGNCR)) - { - continue; - } - - } - - /* Specifically not handled: - * - * All of the local modes; echo, line editing, etc. - * Anything to do with break or parity errors. - * ISTRIP - we should be 8-bit clean. - * IUCLC - Not Posix - * IXON/OXOFF - no xon/xoff flow control. - */ - -#endif - - /* store the received character */ - - *buffer++ = ch; - recvd++; - - } - -#ifdef CONFIG_DEV_SERIAL_FULLBLOCKS - /* No... then we would have to wait to get receive more data. - * If the user has specified the O_NONBLOCK option, then just - * return what we have. - */ - - else if (filep->f_oflags & O_NONBLOCK) - { - /* If nothing was transferred, then return the -EAGAIN - * error (not zero which means end of file). - */ - - if (recvd < 1) - { - recvd = -EAGAIN; - } - - break; - } -#else - /* No... the circular buffer is empty. Have we returned anything - * to the caller? - */ - - else if (recvd > 0) - { - /* Yes.. break out of the loop and return the number of bytes - * received up to the wait condition. - */ - - break; - } - - /* No... then we would have to wait to get receive some data. - * If the user has specified the O_NONBLOCK option, then do not - * wait. - */ - - else if (filep->f_oflags & O_NONBLOCK) - { - /* Break out of the loop returning -EAGAIN */ - - recvd = -EAGAIN; - break; - } -#endif - /* Otherwise we are going to have to wait for data to arrive */ - - else - { - /* Disable Rx interrupts and test again... */ - - uart_disablerxint(dev); - - /* If the Rx ring buffer still empty? Bytes may have been addded - * between the last time that we checked and when we disabled Rx - * interrupts. - */ - - if (dev->recv.head == dev->recv.tail) - { - /* Yes.. the buffer is still empty. Wait for some characters - * to be received into the buffer with the RX interrupt re- - * enabled. All interrupts are disabled briefly to assure - * that the following operations are atomic. - */ - - flags = irqsave(); - -#ifdef CONFIG_SERIAL_REMOVABLE - /* Check if the removable device is no longer connected while - * we have interrupts off. We do not want the transition to - * occur as a race condition before we begin the wait. - */ - - if (dev->disconnected) - { - uart_enablerxint(dev); - irqrestore(flags); - ret = -ENOTCONN; - break; - } -#endif - /* Now wait with the Rx interrupt re-enabled. NuttX will - * automatically re-enable global interrupts when this thread - * goes to sleep. - */ - - dev->recvwaiting = true; - uart_enablerxint(dev); - ret = uart_takesem(&dev->recvsem, true); - irqrestore(flags); - - /* Was a signal received while waiting for data to be - * received? Was a removable device disconnected while - * we were waiting? - */ - -#ifdef CONFIG_SERIAL_REMOVABLE - if (ret < 0 || dev->disconnected) -#else - if (ret < 0) -#endif - { - /* POSIX requires that we return after a signal is received. - * If some bytes were read, we need to return the number of bytes - * read; if no bytes were read, we need to return -1 with the - * errno set correctly. - */ - - if (recvd == 0) - { - /* No bytes were read, return -EINTR (the VFS layer will - * set the errno value appropriately. - */ - -#ifdef CONFIG_SERIAL_REMOVABLE - recvd = dev->disconnected ? -ENOTCONN : -EINTR; -#else - recvd = -EINTR; -#endif - } - - break; - } - } - else - { - /* No... the ring buffer is no longer empty. Just re-enable Rx - * interrupts and accept the new data on the next time through - * the loop. - */ - - uart_enablerxint(dev); - } - } - } - - uart_givesem(&dev->recv.sem); - return recvd; -} - -/************************************************************************************ - * Name: uart_ioctl - ************************************************************************************/ - -static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) -{ - FAR struct inode *inode = filep->f_inode; - FAR uart_dev_t *dev = inode->i_private; - - /* Handle TTY-level IOCTLs here */ - /* Let low-level driver handle the call first */ - - int ret = dev->ops->ioctl(filep, cmd, arg); - - /* - * The device ioctl() handler returns -ENOTTY when it doesn't know - * how to handle the command. Check if we can handle it here. - */ - if (ret == -ENOTTY) - { - switch (cmd) - { - - case FIONREAD: - { - int count; - irqstate_t state = irqsave(); - - /* determine the number of bytes available in the buffer */ - - if (dev->recv.tail <= dev->recv.head) - { - count = dev->recv.head - dev->recv.tail; - } - else - { - count = dev->recv.size - (dev->recv.tail - dev->recv.head); - } - - irqrestore(state); - - *(int *)arg = count; - ret = 0; - - break; - } - - case FIONWRITE: - { - int count; - irqstate_t state = irqsave(); - - /* determine the number of bytes free in the buffer */ - - if (dev->xmit.head < dev->xmit.tail) - { - count = dev->xmit.tail - dev->xmit.head - 1; - } - else - { - count = dev->xmit.size - (dev->xmit.head - dev->xmit.tail) - 1; - } - - irqrestore(state); - - *(int *)arg = count; - ret = 0; - - break; - } - } - } - - /* Append any higher level TTY flags */ - - else if (ret == OK) - { - switch (cmd) - { -#ifdef CONFIG_SERIAL_TERMIOS - case TCGETS: - { - struct termios *termiosp = (struct termios*)arg; - - if (!termiosp) - { - ret = -EINVAL; - break; - } - - /* and update with flags from this layer */ - - termiosp->c_iflag = dev->tc_iflag; - termiosp->c_oflag = dev->tc_oflag; - termiosp->c_lflag = dev->tc_lflag; - } - - break; - - case TCSETS: - { - struct termios *termiosp = (struct termios*)arg; - - if (!termiosp) - { - ret = -EINVAL; - break; - } - - /* update the flags we keep at this layer */ - - dev->tc_iflag = termiosp->c_iflag; - dev->tc_oflag = termiosp->c_oflag; - dev->tc_lflag = termiosp->c_lflag; - } - - break; -#endif - } - } - return ret; -} - -/**************************************************************************** - * Name: uart_poll - ****************************************************************************/ - -#ifndef CONFIG_DISABLE_POLL -int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) -{ - FAR struct inode *inode = filep->f_inode; - FAR uart_dev_t *dev = inode->i_private; - pollevent_t eventset; - int ndx; - int ret; - int i; - - /* Some sanity checking */ - -#if CONFIG_DEBUG - if (!dev || !fds) - { - return -ENODEV; - } -#endif - - /* Are we setting up the poll? Or tearing it down? */ - - ret = uart_takesem(&dev->pollsem, true); - if (ret < 0) - { - /* A signal received while waiting for access to the poll data - * will abort the operation. - */ - - return ret; - } - - if (setup) - { - /* This is a request to set up the poll. Find an available - * slot for the poll structure reference - */ - - for (i = 0; i < CONFIG_SERIAL_NPOLLWAITERS; i++) - { - /* Find an available slot */ - - if (!dev->fds[i]) - { - /* Bind the poll structure and this slot */ - - dev->fds[i] = fds; - fds->priv = &dev->fds[i]; - break; - } - } - - if (i >= CONFIG_SERIAL_NPOLLWAITERS) - { - fds->priv = NULL; - ret = -EBUSY; - goto errout; - } - - /* Should we immediately notify on any of the requested events? - * First, check if the xmit buffer is full. - * - * Get exclusive access to the xmit buffer indices. NOTE: that we do not - * let this wait be interrupted by a signal (we probably should, but that - * would be a little awkward). - */ - - eventset = 0; - (void)uart_takesem(&dev->xmit.sem, false); - - ndx = dev->xmit.head + 1; - if (ndx >= dev->xmit.size) - { - ndx = 0; - } - - if (ndx != dev->xmit.tail) - { - eventset |= (fds->events & POLLOUT); - } - - uart_givesem(&dev->xmit.sem); - - /* Check if the receive buffer is empty. - * - * Get exclusive access to the recv buffer indices. NOTE: that we do not - * let this wait be interrupted by a signal (we probably should, but that - * would be a little awkward). - */ - - (void)uart_takesem(&dev->recv.sem, false); - if (dev->recv.head != dev->recv.tail) - { - eventset |= (fds->events & POLLIN); - } - - uart_givesem(&dev->recv.sem); - -#ifdef CONFIG_SERIAL_REMOVABLE - /* Check if a removable device has been disconnected. */ - - if (dev->disconnected) - { - eventset |= (POLLERR|POLLHUP); - } -#endif - - if (eventset) - { - uart_pollnotify(dev, eventset); - } - - } - else if (fds->priv) - { - /* This is a request to tear down the poll. */ - - struct pollfd **slot = (struct pollfd **)fds->priv; - -#ifdef CONFIG_DEBUG - if (!slot) - { - ret = -EIO; - goto errout; - } -#endif - - /* Remove all memory of the poll setup */ - - *slot = NULL; - fds->priv = NULL; - } - -errout: - uart_givesem(&dev->pollsem); - return ret; -} -#endif - -/************************************************************************************ - * Name: uart_close - * - * Description: - * This routine is called when the serial port gets closed. - * It waits for the last remaining data to be sent. - * - ************************************************************************************/ - -static int uart_close(FAR struct file *filep) -{ - FAR struct inode *inode = filep->f_inode; - FAR uart_dev_t *dev = inode->i_private; - irqstate_t flags; - - /* Get exclusive access to the close semaphore (to synchronize open/close operations. - * NOTE: that we do not let this wait be interrupted by a signal. Technically, we - * should, but almost no one every checks the return value from close() so we avoid - * a potential memory leak by ignoring signals in this case. - */ - - (void)uart_takesem(&dev->closesem, false); - if (dev->open_count > 1) - { - dev->open_count--; - uart_givesem(&dev->closesem); - return OK; - } - - /* There are no more references to the port */ - - dev->open_count = 0; - - /* Stop accepting input */ - - uart_disablerxint(dev); - - /* Now we wait for the transmit buffer to clear */ - - while (dev->xmit.head != dev->xmit.tail) - { -#ifndef CONFIG_DISABLE_SIGNALS - usleep(HALF_SECOND_USEC); -#else - up_mdelay(HALF_SECOND_MSEC); -#endif - } - - /* And wait for the TX fifo to drain */ - - while (!uart_txempty(dev)) - { -#ifndef CONFIG_DISABLE_SIGNALS - usleep(HALF_SECOND_USEC); -#else - up_mdelay(HALF_SECOND_MSEC); -#endif - } - - /* Free the IRQ and disable the UART */ - - flags = irqsave(); /* Disable interrupts */ - uart_detach(dev); /* Detach interrupts */ - if (!dev->isconsole) /* Check for the serial console UART */ - { - uart_shutdown(dev); /* Disable the UART */ - } - - irqrestore(flags); - - uart_givesem(&dev->closesem); - return OK; - } - -/************************************************************************************ - * Name: uart_open - * - * Description: - * This routine is called whenever a serial port is opened. - * - ************************************************************************************/ - -static int uart_open(FAR struct file *filep) -{ - struct inode *inode = filep->f_inode; - uart_dev_t *dev = inode->i_private; - uint8_t tmp; - int ret; - - /* If the port is the middle of closing, wait until the close is finished. - * If a signal is received while we are waiting, then return EINTR. - */ - - ret = uart_takesem(&dev->closesem, true); - if (ret < 0) - { - /* A signal received while waiting for the last close operation. */ - - return ret; - } - -#ifdef CONFIG_SERIAL_REMOVABLE - /* If the removable device is no longer connected, refuse to open the - * device. We check this after obtaining the close semaphore because - * we might have been waiting when the device was disconnected. - */ - - if (dev->disconnected) - { - ret = -ENOTCONN; - goto errout_with_sem; - } -#endif - - /* Start up serial port */ - /* Increment the count of references to the device. */ - - tmp = dev->open_count + 1; - if (tmp == 0) - { - /* More than 255 opens; uint8_t overflows to zero */ - - ret = -EMFILE; - goto errout_with_sem; - } - - /* Check if this is the first time that the driver has been opened. */ - - if (tmp == 1) - { - irqstate_t flags = irqsave(); - - /* If this is the console, then the UART has already been initialized. */ - - if (!dev->isconsole) - { - /* Perform one time hardware initialization */ - - ret = uart_setup(dev); - if (ret < 0) - { - irqrestore(flags); - goto errout_with_sem; - } - } - - /* In any event, we do have to configure for interrupt driven mode of - * operation. Attach the hardware IRQ(s). Hmm.. should shutdown() the - * the device in the rare case that uart_attach() fails, tmp==1, and - * this is not the console. - */ - - ret = uart_attach(dev); - if (ret < 0) - { - uart_shutdown(dev); - irqrestore(flags); - goto errout_with_sem; - } - - /* Mark the io buffers empty */ - - dev->xmit.head = 0; - dev->xmit.tail = 0; - dev->recv.head = 0; - dev->recv.tail = 0; - - /* initialise termios state */ - -#ifdef CONFIG_SERIAL_TERMIOS - - dev->tc_iflag = 0; - if (dev->isconsole == true) - { - - /* enable \n -> \r\n translation for the console */ - - dev->tc_oflag = OPOST | ONLCR; - } - else - { - dev->tc_oflag = 0; - } - -#endif - - /* Enable the RX interrupt */ - - uart_enablerxint(dev); - irqrestore(flags); - } - - /* Save the new open count on success */ - - dev->open_count = tmp; - -errout_with_sem: - uart_givesem(&dev->closesem); - return ret; -} - -/************************************************************************************ - * Public Functions - ************************************************************************************/ - -/************************************************************************************ - * Name: uart_register - * - * Description: - * Register serial console and serial ports. - * - ************************************************************************************/ - -int uart_register(FAR const char *path, FAR uart_dev_t *dev) -{ - sem_init(&dev->xmit.sem, 0, 1); - sem_init(&dev->recv.sem, 0, 1); - sem_init(&dev->closesem, 0, 1); - sem_init(&dev->xmitsem, 0, 0); - sem_init(&dev->recvsem, 0, 0); -#ifndef CONFIG_DISABLE_POLL - sem_init(&dev->pollsem, 0, 1); -#endif - - /* Setup termios flags */ - -#ifdef CONFIG_SERIAL_TERMIOS - - if (dev->isconsole == true) - { - - /* enable \n -> \r\n translation for the console as early as possible */ - - dev->tc_oflag = OPOST | ONLCR; - dev->tc_iflag = 0; - } - -#endif - - dbg("Registering %s\n", path); - return register_driver(path, &g_serialops, 0666, dev); -} - -/************************************************************************************ - * Name: uart_datareceived - * - * Description: - * This function is called from uart_recvchars when new serial data is place in - * the driver's circular buffer. This function will wake-up any stalled read() - * operations that are waiting for incoming data. - * - ************************************************************************************/ - -void uart_datareceived(FAR uart_dev_t *dev) -{ - /* Is there a thread waiting for read data? */ - - if (dev->recvwaiting) - { - /* Yes... wake it up */ - - dev->recvwaiting = false; - (void)sem_post(&dev->recvsem); - } - - /* Notify all poll/select waiters that they can read from the recv buffer */ - - uart_pollnotify(dev, POLLIN); - -} - -/************************************************************************************ - * Name: uart_datasent - * - * Description: - * This function is called from uart_xmitchars after serial data has been sent, - * freeing up some space in the driver's circular buffer. This function will - * wake-up any stalled write() operations that was waiting for space to buffer - * outgoing data. - * - ************************************************************************************/ - -void uart_datasent(FAR uart_dev_t *dev) -{ - /* Is there a thread waiting for space in xmit.buffer? */ - - if (dev->xmitwaiting) - { - /* Yes... wake it up */ - - dev->xmitwaiting = false; - (void)sem_post(&dev->xmitsem); - } - - /* Notify all poll/select waiters that they can write to xmit buffer */ - - uart_pollnotify(dev, POLLOUT); -} - -/************************************************************************************ - * Name: uart_connected - * - * Description: - * Serial devices (like USB serial) can be removed. In that case, the "upper - * half" serial driver must be informed that there is no longer a valid serial - * channel associated with the driver. - * - * In this case, the driver will terminate all pending transfers wint ENOTCONN and - * will refuse all further transactions while the "lower half" is disconnected. - * The driver will continue to be registered, but will be in an unusable state. - * - * Conversely, the "upper half" serial driver needs to know when the serial - * device is reconnected so that it can resume normal operations. - * - * Assumptions/Limitations: - * This function may be called from an interrupt handler. - * - ************************************************************************************/ - -#ifdef CONFIG_SERIAL_REMOVABLE -void uart_connected(FAR uart_dev_t *dev, bool connected) -{ - irqstate_t flags; - - /* Is the device disconnected? */ - - flags = irqsave(); - dev->disconnected = !connected; - if (!connected) - { - /* Yes.. wake up all waiting threads. Each thread should detect the - * disconnection and return the ENOTCONN error. - */ - - /* Is there a thread waiting for space in xmit.buffer? */ - - if (dev->xmitwaiting) - { - /* Yes... wake it up */ - - dev->xmitwaiting = false; - (void)sem_post(&dev->xmitsem); - } - - /* Is there a thread waiting for read data? */ - - if (dev->recvwaiting) - { - /* Yes... wake it up */ - - dev->recvwaiting = false; - (void)sem_post(&dev->recvsem); - } - - /* Notify all poll/select waiters that and hangup occurred */ - - uart_pollnotify(dev, (POLLERR|POLLHUP)); - } - - irqrestore(flags); -} -#endif - - - diff --git a/nuttx/drivers/serial/serialirq.c b/nuttx/drivers/serial/serialirq.c deleted file mode 100644 index fda5b4afb..000000000 --- a/nuttx/drivers/serial/serialirq.c +++ /dev/null @@ -1,186 +0,0 @@ -/************************************************************************************ - * drivers/serial/serialirq.c - * - * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ************************************************************************************/ - -/************************************************************************************ - * Included Files - ************************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <semaphore.h> -#include <debug.h> -#include <nuttx/serial/serial.h> - -/************************************************************************************ - * Pre-processor Definitions - ************************************************************************************/ - -/************************************************************************************ - * Private Types - ************************************************************************************/ - -/************************************************************************************ - * Private Function Prototypes - ************************************************************************************/ - -/************************************************************************************ - * Private Variables - ************************************************************************************/ - -/************************************************************************************ - * Private Functions - ************************************************************************************/ - -/************************************************************************************ - * Public Functions - ************************************************************************************/ - -/************************************************************************************ - * Name: uart_xmitchars - * - * Description: - * This function is called from the UART interrupt handler when an interrupt - * is received indicating that there is more space in the transmit FIFO. This - * function will send characters from the tail of the xmit buffer while the driver - * write() logic adds data to the head of the xmit buffer. - * - ************************************************************************************/ - -void uart_xmitchars(FAR uart_dev_t *dev) -{ - uint16_t nbytes = 0; - - /* Send while we still have data & room in the fifo */ - - while (dev->xmit.head != dev->xmit.tail && uart_txready(dev)) - { - /* Send the next byte */ - - uart_send(dev, dev->xmit.buffer[dev->xmit.tail]); - nbytes++; - - /* Increment the tail index */ - - if (++(dev->xmit.tail) >= dev->xmit.size) - { - dev->xmit.tail = 0; - } - } - - /* When all of the characters have been sent from the buffer disable the TX - * interrupt. - */ - - if (dev->xmit.head == dev->xmit.tail) - { - uart_disabletxint(dev); - } - - /* If any bytes were removed from the buffer, inform any waiters there there is - * space available. - */ - - if (nbytes) - { - uart_datasent(dev); - } -} - -/************************************************************************************ - * Name: uart_receivechars - * - * Description: - * This function is called from the UART interrupt handler when an interrupt - * is received indicating that are bytes available in the receive fifo. This - * function will add chars to head of receive buffer. Driver read() logic will - * take characters from the tail of the buffer. - * - ************************************************************************************/ - -void uart_recvchars(FAR uart_dev_t *dev) -{ - unsigned int status; - int nexthead = dev->recv.head + 1; - uint16_t nbytes = 0; - - if (nexthead >= dev->recv.size) - { - nexthead = 0; - } - - /* Loop putting characters into the receive buffer until either there are no - * further characters to available. - */ - - while (uart_rxavailable(dev)) - { - char ch = uart_receive(dev, &status); - - /* If the RX buffer becomes full, then the serial data is discarded. This is - * necessary because on most serial hardware, you must read the data in order - * to clear the RX interrupt. An option on some hardware might be to simply - * disable RX interrupts until the RX buffer becomes non-FULL. However, that - * would probably just cause the overrun to occur in hardware (unless it has - * some large internal buffering). - */ - - if (nexthead != dev->recv.tail) - { - /* Add the character to the buffer */ - - dev->recv.buffer[dev->recv.head] = ch; - nbytes++; - - /* Increment the head index */ - - dev->recv.head = nexthead; - if (++nexthead >= dev->recv.size) - { - nexthead = 0; - } - } - } - - /* If any bytes were added to the buffer, inform any waiters there there is new - * incoming data available. - */ - - if (nbytes) - { - uart_datareceived(dev); - } -} diff --git a/nuttx/drivers/serial/uart_16550.c b/nuttx/drivers/serial/uart_16550.c deleted file mode 100644 index 8fb71bfd2..000000000 --- a/nuttx/drivers/serial/uart_16550.c +++ /dev/null @@ -1,1164 +0,0 @@ -/**************************************************************************** - * drivers/serial/uart_16550.c - * Serial driver for 16550 UART - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> -#include <unistd.h> -#include <semaphore.h> -#include <string.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/irq.h> -#include <nuttx/arch.h> -#include <nuttx/serial/serial.h> -#include <nuttx/fs/ioctl.h> -#include <nuttx/serial/uart_16550.h> - -#include <arch/board/board.h> - -#ifdef CONFIG_16550_UART - -/**************************************************************************** - * Pre-processor definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct u16550_s -{ - uart_addrwidth_t uartbase; /* Base address of UART registers */ -#ifndef CONFIG_16550_SUPRESS_CONFIG - uint32_t baud; /* Configured baud */ - uint32_t uartclk; /* UART clock frequency */ -#endif -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - uart_datawidth_t ier; /* Saved IER value */ - uint8_t irq; /* IRQ associated with this UART */ -#endif -#ifndef CONFIG_16550_SUPRESS_CONFIG - uint8_t parity; /* 0=none, 1=odd, 2=even */ - uint8_t bits; /* Number of bits (7 or 8) */ - bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ -#endif -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static int u16550_setup(struct uart_dev_s *dev); -static void u16550_shutdown(struct uart_dev_s *dev); -static int u16550_attach(struct uart_dev_s *dev); -static void u16550_detach(struct uart_dev_s *dev); -#ifndef CONFIG_SUPPRESS_SERIAL_INTS -static int u16550_interrupt(int irq, void *context); -#endif -static int u16550_ioctl(struct file *filep, int cmd, unsigned long arg); -static int u16550_receive(struct uart_dev_s *dev, uint32_t *status); -static void u16550_rxint(struct uart_dev_s *dev, bool enable); -static bool u16550_rxavailable(struct uart_dev_s *dev); -static void u16550_send(struct uart_dev_s *dev, int ch); -static void u16550_txint(struct uart_dev_s *dev, bool enable); -static bool u16550_txready(struct uart_dev_s *dev); -static bool u16550_txempty(struct uart_dev_s *dev); - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -struct uart_ops_s g_uart_ops = -{ - .setup = u16550_setup, - .shutdown = u16550_shutdown, - .attach = u16550_attach, - .detach = u16550_detach, - .ioctl = u16550_ioctl, - .receive = u16550_receive, - .rxint = u16550_rxint, - .rxavailable = u16550_rxavailable, - .send = u16550_send, - .txint = u16550_txint, - .txready = u16550_txready, - .txempty = u16550_txempty, -}; - -/* I/O buffers */ - -#ifdef CONFIG_16550_UART0 -static char g_uart0rxbuffer[CONFIG_16550_UART0_RXBUFSIZE]; -static char g_uart0txbuffer[CONFIG_16550_UART0_TXBUFSIZE]; -#endif -#ifdef CONFIG_16550_UART1 -static char g_uart1rxbuffer[CONFIG_16550_UART1_RXBUFSIZE]; -static char g_uart1txbuffer[CONFIG_16550_UART1_TXBUFSIZE]; -#endif -#ifdef CONFIG_16550_UART2 -static char g_uart2rxbuffer[CONFIG_16550_UART2_RXBUFSIZE]; -static char g_uart2txbuffer[CONFIG_16550_UART2_TXBUFSIZE]; -#endif -#ifdef CONFIG_16550_UART3 -static char g_uart3rxbuffer[CONFIG_16550_UART3_RXBUFSIZE]; -static char g_uart3txbuffer[CONFIG_16550_UART3_TXBUFSIZE]; -#endif - -/* This describes the state of the LPC17xx uart0 port. */ - -#ifdef CONFIG_16550_UART0 -static struct u16550_s g_uart0priv = -{ - .uartbase = CONFIG_16550_UART0_BASE, -#ifndef CONFIG_16550_SUPRESS_CONFIG - .baud = CONFIG_16550_UART0_BAUD, - .uartclk = CONFIG_16550_UART0_CLOCK, -#endif -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - .irq = CONFIG_16550_UART0_IRQ, -#endif -#ifndef CONFIG_16550_SUPRESS_CONFIG - .parity = CONFIG_16550_UART0_PARITY, - .bits = CONFIG_16550_UART0_BITS, - .stopbits2 = CONFIG_16550_UART0_2STOP, -#endif -}; - -static uart_dev_t g_uart0port = -{ - .recv = - { - .size = CONFIG_16550_UART0_RXBUFSIZE, - .buffer = g_uart0rxbuffer, - }, - .xmit = - { - .size = CONFIG_16550_UART0_TXBUFSIZE, - .buffer = g_uart0txbuffer, - }, - .ops = &g_uart_ops, - .priv = &g_uart0priv, -}; -#endif - -/* This describes the state of the LPC17xx uart1 port. */ - -#ifdef CONFIG_16550_UART1 -static struct u16550_s g_uart1priv = -{ - .uartbase = CONFIG_16550_UART1_BASE, -#ifndef CONFIG_16550_SUPRESS_CONFIG - .baud = CONFIG_16550_UART1_BAUD, - .uartclk = CONFIG_16550_UART1_CLOCK, -#endif -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - .irq = CONFIG_16550_UART1_IRQ, -#endif -#ifndef CONFIG_16550_SUPRESS_CONFIG - .parity = CONFIG_16550_UART1_PARITY, - .bits = CONFIG_16550_UART1_BITS, - .stopbits2 = CONFIG_16550_UART1_2STOP, -#endif -}; - -static uart_dev_t g_uart1port = -{ - .recv = - { - .size = CONFIG_16550_UART1_RXBUFSIZE, - .buffer = g_uart1rxbuffer, - }, - .xmit = - { - .size = CONFIG_16550_UART1_TXBUFSIZE, - .buffer = g_uart1txbuffer, - }, - .ops = &g_uart_ops, - .priv = &g_uart1priv, -}; -#endif - -/* This describes the state of the LPC17xx uart1 port. */ - -#ifdef CONFIG_16550_UART2 -static struct u16550_s g_uart2priv = -{ - .uartbase = CONFIG_16550_UART2_BASE, -#ifndef CONFIG_16550_SUPRESS_CONFIG - .baud = CONFIG_16550_UART2_BAUD, - .uartclk = CONFIG_16550_UART2_CLOCK, -#endif -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - .irq = CONFIG_16550_UART2_IRQ, -#endif -#ifndef CONFIG_16550_SUPRESS_CONFIG - .parity = CONFIG_16550_UART2_PARITY, - .bits = CONFIG_16550_UART2_BITS, - .stopbits2 = CONFIG_16550_UART2_2STOP, -#endif -}; - -static uart_dev_t g_uart2port = -{ - .recv = - { - .size = CONFIG_16550_UART2_RXBUFSIZE, - .buffer = g_uart2rxbuffer, - }, - .xmit = - { - .size = CONFIG_16550_UART2_TXBUFSIZE, - .buffer = g_uart2txbuffer, - }, - .ops = &g_uart_ops, - .priv = &g_uart2priv, -}; -#endif - -/* This describes the state of the LPC17xx uart1 port. */ - -#ifdef CONFIG_16550_UART3 -static struct u16550_s g_uart3priv = -{ - .uartbase = CONFIG_16550_UART3_BASE, -#ifndef CONFIG_16550_SUPRESS_CONFIG - .baud = CONFIG_16550_UART3_BAUD, - .uartclk = CONFIG_16550_UART3_CLOCK, -#endif -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - .irq = CONFIG_16550_UART3_IRQ, -#endif -#ifndef CONFIG_16550_SUPRESS_CONFIG - .parity = CONFIG_16550_UART3_PARITY, - .bits = CONFIG_16550_UART3_BITS, - .stopbits2 = CONFIG_16550_UART3_2STOP, -#endif -}; - -static uart_dev_t g_uart3port = -{ - .recv = - { - .size = CONFIG_16550_UART3_RXBUFSIZE, - .buffer = g_uart3rxbuffer, - }, - .xmit = - { - .size = CONFIG_16550_UART3_TXBUFSIZE, - .buffer = g_uart3txbuffer, - }, - .ops = &g_uart_ops, - .priv = &g_uart3priv, -}; -#endif - -/* Which UART with be tty0/console and which tty1? tty2? tty3? */ - -#if defined(CONFIG_16550_UART0_SERIAL_CONSOLE) -# define CONSOLE_DEV g_uart0port /* UART0=console */ -# define TTYS0_DEV g_uart0port /* UART0=ttyS0 */ -# ifdef CONFIG_16550_UART1 -# define TTYS1_DEV g_uart1port /* UART0=ttyS0;UART1=ttyS1 */ -# ifdef CONFIG_16550_UART2 -# define TTYS2_DEV g_uart2port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2 */ -# ifdef CONFIG_16550_UART3 -# 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 */ -# endif -# else -# ifdef CONFIG_16550_UART3 -# 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 */ -# endif -# undef TTYS3_DEV /* No ttyS3 */ -# endif -# else -# ifdef CONFIG_16550_UART2 -# define TTYS1_DEV g_uart2port /* UART0=ttyS0;UART2=ttyS1;No ttyS3 */ -# ifdef CONFIG_16550_UART3 -# 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 */ -# endif -# undef TTYS3_DEV /* No ttyS3 */ -# else -# ifdef CONFIG_16550_UART3 -# 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 */ -# endif -# undef TTYS2_DEV /* No ttyS2 */ -# undef TTYS3_DEV /* No ttyS3 */ -# endif -# endif -#elif defined(CONFIG_16550_UART1_SERIAL_CONSOLE) -# define CONSOLE_DEV g_uart1port /* UART1=console */ -# define TTYS0_DEV g_uart1port /* UART1=ttyS0 */ -# ifdef CONFIG_16550_UART -# define TTYS1_DEV g_uart0port /* UART1=ttyS0;UART0=ttyS1 */ -# ifdef CONFIG_16550_UART2 -# define TTYS2_DEV g_uart2port /* UART1=ttyS0;UART0=ttyS1;UART2=ttyS2 */ -# ifdef CONFIG_16550_UART3 -# define TTYS3_DEV g_uart3port /* UART1=ttyS0;UART0=ttyS1;UART2=ttyS2;UART3=ttyS3 */ -# else -# undef TTYS3_DEV /* UART1=ttyS0;UART0=ttyS1;UART2=ttyS;No ttyS3 */ -# endif -# else -# ifdef CONFIG_16550_UART3 -# define TTYS2_DEV g_uart3port /* UART1=ttyS0;UART0=ttyS1;UART3=ttys2;No ttyS3 */ -# else -# undef TTYS2_DEV /* UART1=ttyS0;UART0=ttyS1;No ttyS2;No ttyS3 */ -# endif -# undef TTYS3_DEV /* No ttyS3 */ -# endif -# else -# ifdef CONFIG_16550_UART2 -# define TTYS1_DEV g_uart2port /* UART1=ttyS0;UART2=ttyS1 */ -# ifdef CONFIG_16550_UART3 -# define TTYS2_DEV g_uart3port /* UART1=ttyS0;UART2=ttyS1;UART3=ttyS2;No ttyS3 */ -# else -# undef TTYS2_DEV /* UART1=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */ -# endif -# undef TTYS3_DEV /* No ttyS3 */ -# else -# ifdef CONFIG_16550_UART3 -# define TTYS1_DEV g_uart3port /* UART1=ttyS0;UART3=ttyS1;No ttyS2;No ttyS3 */ -# else -# undef TTYS1_DEV /* UART1=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ -# endif -# undef TTYS2_DEV /* No ttyS2 */ -# undef TTYS3_DEV /* No ttyS3 */ -# endif -# endif -#elif defined(CONFIG_16550_UART2_SERIAL_CONSOLE) -# define CONSOLE_DEV g_uart2port /* UART2=console */ -# define TTYS0_DEV g_uart2port /* UART2=ttyS0 */ -# ifdef CONFIG_16550_UART -# define TTYS1_DEV g_uart0port /* UART2=ttyS0;UART0=ttyS1 */ -# ifdef CONFIG_16550_UART1 -# define TTYS2_DEV g_uart1port /* UART2=ttyS0;UART0=ttyS1;UART1=ttyS2 */ -# ifdef CONFIG_16550_UART3 -# define TTYS3_DEV g_uart3port /* UART2=ttyS0;UART0=ttyS1;UART1=ttyS2;UART3=ttyS3 */ -# else -# undef TTYS3_DEV /* UART2=ttyS0;UART0=ttyS1;UART1=ttyS;No ttyS3 */ -# endif -# else -# ifdef CONFIG_16550_UART3 -# define TTYS2_DEV g_uart3port /* UART2=ttyS0;UART0=ttyS1;UART3=ttys2;No ttyS3 */ -# else -# undef TTYS2_DEV /* UART2=ttyS0;UART0=ttyS1;No ttyS2;No ttyS3 */ -# endif -# undef TTYS3_DEV /* No ttyS3 */ -# endif -# else -# ifdef CONFIG_16550_UART1 -# define TTYS1_DEV g_uart1port /* UART2=ttyS0;UART1=ttyS1 */ -# ifdef CONFIG_16550_UART3 -# define TTYS2_DEV g_uart3port /* UART2=ttyS0;UART1=ttyS1;UART3=ttyS2 */ -# else -# undef TTYS2_DEV /* UART2=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ -# endif -# undef TTYS3_DEV /* No ttyS3 */ -# else -# ifdef CONFIG_16550_UART3 -# define TTYS1_DEV g_uart3port /* UART2=ttyS0;UART3=ttyS1;No ttyS3 */ -# else -# undef TTYS1_DEV /* UART2=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ -# endif -# undef TTYS2_DEV /* No ttyS2 */ -# undef TTYS3_DEV /* No ttyS3 */ -# endif -# endif -#elif defined(CONFIG_16550_UART3_SERIAL_CONSOLE) -# define CONSOLE_DEV g_uart3port /* UART3=console */ -# define TTYS0_DEV g_uart3port /* UART3=ttyS0 */ -# ifdef CONFIG_16550_UART -# define TTYS1_DEV g_uart0port /* UART3=ttyS0;UART0=ttyS1 */ -# ifdef CONFIG_16550_UART1 -# define TTYS2_DEV g_uart1port /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS2 */ -# ifdef CONFIG_16550_UART2 -# 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 */ -# endif -# else -# ifdef CONFIG_16550_UART2 -# 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 */ -# endif -# undef TTYS3_DEV /* No ttyS3 */ -# endif -# else -# ifdef CONFIG_16550_UART1 -# define TTYS1_DEV g_uart1port /* UART3=ttyS0;UART1=ttyS1 */ -# ifdef CONFIG_16550_UART2 -# 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 */ -# endif -# undef TTYS3_DEV /* No ttyS3 */ -# else -# ifdef CONFIG_16550_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 */ -# else -# undef TTYS1_DEV /* UART3=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ -# endif -# undef TTYS2_DEV /* No ttyS2 */ -# undef TTYS3_DEV /* No ttyS3 */ -# endif -# endif -#endif - -/************************************************************************************ - * Inline Functions - ************************************************************************************/ - -/**************************************************************************** - * Name: u16550_serialin - ****************************************************************************/ - -static inline uart_datawidth_t u16550_serialin(struct u16550_s *priv, int offset) -{ - return uart_getreg(priv->uartbase, offset); -} - -/**************************************************************************** - * Name: u16550_serialout - ****************************************************************************/ - -static inline void u16550_serialout(struct u16550_s *priv, int offset, uart_datawidth_t value) -{ - uart_putreg(priv->uartbase, offset, value); -} - -/**************************************************************************** - * Name: u16550_disableuartint - ****************************************************************************/ - -#ifndef CONFIG_SUPPRESS_SERIAL_INTS -static inline void u16550_disableuartint(struct u16550_s *priv, uart_datawidth_t *ier) -{ - if (ier) - { - *ier = priv->ier & UART_IER_ALLIE; - } - - priv->ier &= ~UART_IER_ALLIE; - u16550_serialout(priv, UART_IER_OFFSET, priv->ier); -} -#else -# define u16550_disableuartint(priv,ier) -#endif - -/**************************************************************************** - * Name: u16550_restoreuartint - ****************************************************************************/ - -#ifndef CONFIG_SUPPRESS_SERIAL_INTS -static inline void u16550_restoreuartint(struct u16550_s *priv, uint32_t ier) -{ - priv->ier |= ier & UART_IER_ALLIE; - u16550_serialout(priv, UART_IER_OFFSET, priv->ier); -} -#else -# define u16550_restoreuartint(priv,ier) -#endif - -/**************************************************************************** - * Name: u16550_enablebreaks - ****************************************************************************/ - -static inline void u16550_enablebreaks(struct u16550_s *priv, bool enable) -{ - uint32_t lcr = u16550_serialin(priv, UART_LCR_OFFSET); - if (enable) - { - lcr |= UART_LCR_BRK; - } - else - { - lcr &= ~UART_LCR_BRK; - } - u16550_serialout(priv, UART_LCR_OFFSET, lcr); -} - -/************************************************************************************ - * Name: u16550_divisor - * - * Descrption: - * Select a divider to produce the BAUD from the UART_CLK. - * - * BAUD = UART_CLK / (16 * DL), or - * DIV = UART_CLK / BAUD / 16 - * - * Ignoring the fractional divider for now. - * - ************************************************************************************/ - -#ifndef CONFIG_16550_SUPRESS_CONFIG -static inline uint32_t u16550_divisor(struct u16550_s *priv) -{ - return (priv->uartclk + (priv->baud << 3)) / (priv->baud << 4); -} -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: u16550_setup - * - * Description: - * Configure the UART baud, bits, parity, fifos, etc. This - * method is called the first time that the serial port is - * opened. - * - ****************************************************************************/ - -static int u16550_setup(struct uart_dev_s *dev) -{ -#ifndef CONFIG_16550_SUPRESS_CONFIG - struct u16550_s *priv = (struct u16550_s*)dev->priv; - uint16_t div; - uint32_t lcr; - - /* Clear fifos */ - - u16550_serialout(priv, UART_FCR_OFFSET, (UART_FCR_RXRST|UART_FCR_TXRST)); - - /* Set trigger */ - - u16550_serialout(priv, UART_FCR_OFFSET, (UART_FCR_FIFOEN|UART_FCR_RXTRIGGER_8)); - - /* Set up the IER */ - -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - priv->ier = u16550_serialin(priv, UART_IER_OFFSET); -#endif - - /* Set up the LCR */ - - lcr = 0; - switch (priv->bits) - { - case 5 : - lcr |= UART_LCR_WLS_7BIT; - break; - - case 6 : - lcr |= UART_LCR_WLS_7BIT; - break; - - case 7 : - lcr |= UART_LCR_WLS_7BIT; - break; - - default: - case 8 : - lcr |= UART_LCR_WLS_7BIT; - break; - } - - if (priv->stopbits2) - { - lcr |= UART_LCR_STB; - } - - if (priv->parity == 1) - { - lcr |= UART_LCR_PEN; - } - else if (priv->parity == 2) - { - lcr |= (UART_LCR_PEN|UART_LCR_EPS); - } - - /* Enter DLAB=1 */ - - u16550_serialout(priv, UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); - - /* Set the BAUD divisor */ - - div = u16550_divisor(priv); - u16550_serialout(priv, UART_DLM_OFFSET, div >> 8); - u16550_serialout(priv, UART_DLL_OFFSET, div & 0xff); - - /* Clear DLAB */ - - u16550_serialout(priv, UART_LCR_OFFSET, lcr); - - /* Configure the FIFOs */ - - u16550_serialout(priv, UART_FCR_OFFSET, - (UART_FCR_RXTRIGGER_8|UART_FCR_TXRST|UART_FCR_RXRST|UART_FCR_FIFOEN)); -#endif - return OK; -} - -/**************************************************************************** - * Name: u16550_shutdown - * - * Description: - * Disable the UART. This method is called when the serial - * port is closed - * - ****************************************************************************/ - -static void u16550_shutdown(struct uart_dev_s *dev) -{ - struct u16550_s *priv = (struct u16550_s*)dev->priv; - u16550_disableuartint(priv, NULL); -} - -/**************************************************************************** - * Name: u16550_attach - * - * Description: - * Configure the UART to operation in interrupt driven mode. This method is - * called when the serial port is opened. Normally, this is just after the - * the setup() method is called, however, the serial console may operate in - * a non-interrupt driven mode during the boot phase. - * - * RX and TX interrupts are not enabled when by the attach method (unless the - * hardware supports multiple levels of interrupt enabling). The RX and TX - * interrupts are not enabled until the txint() and rxint() methods are called. - * - ****************************************************************************/ - -static int u16550_attach(struct uart_dev_s *dev) -{ -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - struct u16550_s *priv = (struct u16550_s*)dev->priv; - int ret; - - /* Attach and enable the IRQ */ - - ret = irq_attach(priv->irq, u16550_interrupt); -#ifndef CONFIG_ARCH_NOINTC - if (ret == OK) - { - /* Enable the interrupt (RX and TX interrupts are still disabled - * in the UART - */ - - up_enable_irq(priv->irq); - } -#endif - return ret; -#else - return OK; -#endif -} - -/**************************************************************************** - * Name: u16550_detach - * - * Description: - * Detach UART interrupts. This method is called when the serial port is - * closed normally just before the shutdown method is called. The exception is - * the serial console which is never shutdown. - * - ****************************************************************************/ - -static void u16550_detach(struct uart_dev_s *dev) -{ -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - struct u16550_s *priv = (struct u16550_s*)dev->priv; -#ifndef CONFIG_ARCH_NOINTC - up_disable_irq(priv->irq); -#endif - irq_detach(priv->irq); -#endif -} - -/**************************************************************************** - * Name: u16550_interrupt - * - * Description: - * This is the UART interrupt handler. It will be invoked when an - * interrupt received on the 'irq' It should call uart_transmitchars or - * uart_receivechar to perform the appropriate data transfers. The - * interrupt handling logic must be able to map the 'irq' number into the - * appropriate u16550_s structure in order to call these functions. - * - ****************************************************************************/ - -#ifndef CONFIG_SUPPRESS_SERIAL_INTS -static int u16550_interrupt(int irq, void *context) -{ - struct uart_dev_s *dev = NULL; - struct u16550_s *priv; - uint32_t status; - int passes; - -#ifdef CONFIG_16550_UART0 - if (g_uart0priv.irq == irq) - { - dev = &g_uart0port; - } - else -#endif -#ifdef CONFIG_16550_UART1 - if (g_uart1priv.irq == irq) - { - dev = &g_uart1port; - } - else -#endif -#ifdef CONFIG_16550_UART2 - if (g_uart2priv.irq == irq) - { - dev = &g_uart2port; - } - else -#endif -#ifdef CONFIG_16550_UART3 - if (g_uart3priv.irq == irq) - { - dev = &g_uart3port; - } -#endif - ASSERT(dev != NULL); - priv = (struct u16550_s*)dev->priv; - - /* Loop until there are no characters to be transferred or, - * until we have been looping for a long time. - */ - - for (passes = 0; passes < 256; passes++) - { - /* Get the current UART status and check for loop - * termination conditions - */ - - status = u16550_serialin(priv, UART_IIR_OFFSET); - - /* The UART_IIR_INTSTATUS bit should be zero if there are pending - * interrupts - */ - - if ((status & UART_IIR_INTSTATUS) != 0) - { - /* Break out of the loop when there is no longer a - * pending interrupt - */ - - break; - } - - /* Handle the interrupt by its interrupt ID field */ - - switch (status & UART_IIR_INTID_MASK) - { - /* Handle incoming, receive bytes (with or without timeout) */ - - case UART_IIR_INTID_RDA: - case UART_IIR_INTID_CTI: - { - uart_recvchars(dev); - break; - } - - /* Handle outgoing, transmit bytes */ - - case UART_IIR_INTID_THRE: - { - uart_xmitchars(dev); - break; - } - - /* Just clear modem status interrupts (UART1 only) */ - - case UART_IIR_INTID_MSI: - { - /* Read the modem status register (MSR) to clear */ - - status = u16550_serialin(priv, UART_MSR_OFFSET); - vdbg("MSR: %02x\n", status); - break; - } - - /* Just clear any line status interrupts */ - - case UART_IIR_INTID_RLS: - { - /* Read the line status register (LSR) to clear */ - - status = u16550_serialin(priv, UART_LSR_OFFSET); - vdbg("LSR: %02x\n", status); - break; - } - - /* There should be no other values */ - - default: - { - dbg("Unexpected IIR: %02x\n", status); - break; - } - } - } - - return OK; -} -#endif - -/**************************************************************************** - * Name: u16550_ioctl - * - * Description: - * All ioctl calls will be routed through this method - * - ****************************************************************************/ - -static int u16550_ioctl(struct file *filep, int cmd, unsigned long arg) -{ - struct inode *inode = filep->f_inode; - struct uart_dev_s *dev = inode->i_private; - struct u16550_s *priv = (struct u16550_s*)dev->priv; - int ret = OK; - - switch (cmd) - { - case TIOCSERGSTRUCT: - { - struct u16550_s *user = (struct u16550_s*)arg; - if (!user) - { - set_errno(EINVAL); - ret = ERROR; - } - else - { - memcpy(user, dev, sizeof(struct u16550_s)); - } - } - break; - - case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ - { - irqstate_t flags = irqsave(); - u16550_enablebreaks(priv, true); - irqrestore(flags); - } - break; - - case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ - { - irqstate_t flags; - flags = irqsave(); - u16550_enablebreaks(priv, false); - irqrestore(flags); - } - break; - - default: - set_errno(ENOTTY); - ret = ERROR; - break; - } - - return ret; -} - -/**************************************************************************** - * Name: u16550_receive - * - * Description: - * Called (usually) from the interrupt level to receive one - * character from the UART. Error bits associated with the - * receipt are provided in the return 'status'. - * - ****************************************************************************/ - -static int u16550_receive(struct uart_dev_s *dev, uint32_t *status) -{ - struct u16550_s *priv = (struct u16550_s*)dev->priv; - uint32_t rbr; - - *status = u16550_serialin(priv, UART_LSR_OFFSET); - rbr = u16550_serialin(priv, UART_RBR_OFFSET); - return rbr; -} - -/**************************************************************************** - * Name: u16550_rxint - * - * Description: - * Call to enable or disable RX interrupts - * - ****************************************************************************/ - -static void u16550_rxint(struct uart_dev_s *dev, bool enable) -{ -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - struct u16550_s *priv = (struct u16550_s*)dev->priv; - if (enable) - { - priv->ier |= UART_IER_ERBFI; - } - else - { - priv->ier &= ~UART_IER_ERBFI; - } - u16550_serialout(priv, UART_IER_OFFSET, priv->ier); -#endif -} - -/**************************************************************************** - * Name: u16550_rxavailable - * - * Description: - * Return true if the receive fifo is not empty - * - ****************************************************************************/ - -static bool u16550_rxavailable(struct uart_dev_s *dev) -{ - struct u16550_s *priv = (struct u16550_s*)dev->priv; - return ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_DR) != 0); -} - -/**************************************************************************** - * Name: u16550_send - * - * Description: - * This method will send one byte on the UART - * - ****************************************************************************/ - -static void u16550_send(struct uart_dev_s *dev, int ch) -{ - struct u16550_s *priv = (struct u16550_s*)dev->priv; - u16550_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch); -} - -/**************************************************************************** - * Name: u16550_txint - * - * Description: - * Call to enable or disable TX interrupts - * - ****************************************************************************/ - -static void u16550_txint(struct uart_dev_s *dev, bool enable) -{ -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - struct u16550_s *priv = (struct u16550_s*)dev->priv; - irqstate_t flags; - - flags = irqsave(); - if (enable) - { - priv->ier |= UART_IER_ETBEI; - u16550_serialout(priv, UART_IER_OFFSET, priv->ier); - - /* Fake a TX interrupt here by just calling uart_xmitchars() with - * interrupts disabled (note this may recurse). - */ - - uart_xmitchars(dev); - } - else - { - priv->ier &= ~UART_IER_ETBEI; - u16550_serialout(priv, UART_IER_OFFSET, priv->ier); - } - - irqrestore(flags); -#endif -} - -/**************************************************************************** - * Name: u16550_txready - * - * Description: - * Return true if the tranmsit fifo is not full - * - ****************************************************************************/ - -static bool u16550_txready(struct uart_dev_s *dev) -{ - struct u16550_s *priv = (struct u16550_s*)dev->priv; - return ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0); -} - -/**************************************************************************** - * Name: u16550_txempty - * - * Description: - * Return true if the transmit fifo is empty - * - ****************************************************************************/ - -static bool u16550_txempty(struct uart_dev_s *dev) -{ - struct u16550_s *priv = (struct u16550_s*)dev->priv; - return ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0); -} - -/**************************************************************************** - * Name: u16550_putc - * - * Description: - * Write one character to the UART (polled) - * - ****************************************************************************/ - -static void u16550_putc(struct u16550_s *priv, int ch) -{ - while ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0); - u16550_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch); -} - -/**************************************************************************** - * Public Funtions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_earlyserialinit - * - * Description: - * Performs the low level UART initialization early in debug so that the - * serial console will be available during bootup. This must be called - * before uart_serialinit. - * - * NOTE: Configuration of the CONSOLE UART was performed by uart_lowsetup() - * very early in the boot sequence. - * - ****************************************************************************/ - -void up_earlyserialinit(void) -{ - /* Configure all UARTs (except the CONSOLE UART) and disable interrupts */ - -#ifdef CONFIG_16550_UART0 - u16550_disableuartint(&g_uart0priv, NULL); -#endif -#ifdef CONFIG_16550_UART1 - u16550_disableuartint(&g_uart1priv, NULL); -#endif -#ifdef CONFIG_16550_UART2 - u16550_disableuartint(&g_uart2priv, NULL); -#endif -#ifdef CONFIG_16550_UART3 - u16550_disableuartint(&g_uart3priv, NULL); -#endif - - /* Configuration whichever one is the console */ - -#ifdef CONSOLE_DEV - CONSOLE_DEV.isconsole = true; - u16550_setup(&CONSOLE_DEV); -#endif -} - -/**************************************************************************** - * Name: up_serialinit - * - * Description: - * Register serial console and serial ports. This assumes that - * up_earlyserialinit was called previously. - * - ****************************************************************************/ - -void up_serialinit(void) -{ -#ifdef CONSOLE_DEV - (void)uart_register("/dev/console", &CONSOLE_DEV); -#endif -#ifdef TTYS0_DEV - (void)uart_register("/dev/ttyS0", &TTYS0_DEV); -#endif -#ifdef TTYS1_DEV - (void)uart_register("/dev/ttyS1", &TTYS1_DEV); -#endif -#ifdef TTYS2_DEV - (void)uart_register("/dev/ttyS2", &TTYS2_DEV); -#endif -#ifdef TTYS3_DEV - (void)uart_register("/dev/ttyS3", &TTYS3_DEV); -#endif -} - -/**************************************************************************** - * Name: up_putc - * - * Description: - * Provide priority, low-level access to support OS debug writes - * - ****************************************************************************/ - -#ifdef HAVE_16550_CONSOLE -int up_putc(int ch) -{ - struct u16550_s *priv = (struct u16550_s*)CONSOLE_DEV.priv; -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - uart_datawidth_t ier; - - u16550_disableuartint(priv, &ier); -#endif - - /* Check for LF */ - - if (ch == '\n') - { - /* Add CR */ - - u16550_putc(priv, '\r'); - } - - u16550_putc(priv, ch); -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - u16550_restoreuartint(priv, ier); -#endif - return ch; -} -#endif - -#endif /* CONFIG_16550_UART */ |