From: Alexander Krutwig <alexander.krut...@embedded-brains.de> Update #2841. --- cpukit/dev/Makefile.am | 7 + cpukit/dev/include/dev/serial/nxp-sc16is752.h | 165 +++++++++++++++++ cpukit/dev/preinstall.am | 9 + cpukit/dev/serial/nxp-sc16is752-regs.h | 108 +++++++++++ cpukit/dev/serial/nxp-sc16is752-spi.c | 126 +++++++++++++ cpukit/dev/serial/nxp-sc16is752.c | 257 ++++++++++++++++++++++++++ 6 files changed, 672 insertions(+) create mode 100644 cpukit/dev/include/dev/serial/nxp-sc16is752.h create mode 100644 cpukit/dev/serial/nxp-sc16is752-regs.h create mode 100644 cpukit/dev/serial/nxp-sc16is752-spi.c create mode 100644 cpukit/dev/serial/nxp-sc16is752.c
diff --git a/cpukit/dev/Makefile.am b/cpukit/dev/Makefile.am index 2b65390..cdc3fe8 100644 --- a/cpukit/dev/Makefile.am +++ b/cpukit/dev/Makefile.am @@ -15,6 +15,10 @@ include_dev_spidir = $(includedir)/dev/spi include_dev_spi_HEADERS = include_dev_spi_HEADERS += include/dev/spi/spi.h +include_dev_serialdir = $(includedir)/dev/serial +include_dev_serial_HEADERS = +include_dev_serial_HEADERS += include/dev/serial/nxp-sc16is752.h + include_linuxdir = $(includedir)/linux include_linux_HEADERS = include_linux_HEADERS += include/linux/i2c.h @@ -33,6 +37,9 @@ libdev_a_SOURCES += i2c/i2c-bus.c libdev_a_SOURCES += i2c/i2c-dev.c libdev_a_SOURCES += i2c/switch-nxp-pca9548a.c libdev_a_SOURCES += spi/spi-bus.c +libdev_a_SOURCES += serial/nxp-sc16is752.c +libdev_a_SOURCES += serial/nxp-sc16is752-spi.c +libdev_a_SOURCES += serial/nxp-sc16is752-regs.h include $(srcdir)/preinstall.am include $(top_srcdir)/automake/local.am diff --git a/cpukit/dev/include/dev/serial/nxp-sc16is752.h b/cpukit/dev/include/dev/serial/nxp-sc16is752.h new file mode 100644 index 0000000..9d6cc59 --- /dev/null +++ b/cpukit/dev/include/dev/serial/nxp-sc16is752.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <i...@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _DEV_SERIAL_SC16IS752_H +#define _DEV_SERIAL_SC16IS752_H + +#include <rtems/termiostypes.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup NXP-SC16IS752 Device Support + * + * @ingroup TermiostypesSupport + * + * @brief NXP-SC16IS752 Device Support Internal Data Structures + */ + +typedef struct sc16is752_context sc16is752_context; + +/** + * @brief SC16IS752 device context. + */ +struct sc16is752_context { + rtems_termios_device_context base; + + int (*write_reg)( + sc16is752_context *ctx, + uint8_t addr, + const uint8_t *data, + size_t len + ); + + int (*read_reg)( + sc16is752_context *ctx, + uint8_t addr, + uint8_t *data, + size_t len + ); + + bool (*first_open)(sc16is752_context *ctx); + + void (*last_close)(sc16is752_context *ctx); + + /** + * @brief Interrupt install handler must be given by user before termios device + * creation. + */ + bool (*install_irq)(sc16is752_context *ctx); + + /** + * @brief Interrupt remove handler must be given by user before termios device + * creation. + */ + void (*remove_irq)(sc16is752_context *ctx); + + /** + * @brief Mode must be given by user before termios device creation. + */ + enum { + SC16IS752_MODE_RS232, + SC16IS752_MODE_RS485 + } mode; + + /** + * @brief Input frequency (dependent on crystal) must be given by user before + * termios device creation + */ + uint32_t input_frequency; + + rtems_termios_tty *tty; + + /** + * @brief Shadow interrupt enable register (IER). + */ + uint8_t ier; + + /** + * @brief Characters placed into transmit FIFO. + */ + uint8_t tx_in_progress; + + /** + * @brief Count of free characters in the transmit FIFO. + */ + uint8_t tx_fifo_free; +}; + +/** + * @brief SC16IS752 SPI context. + */ +typedef struct { + sc16is752_context base; + + int fd; + + /* + * @brief chip select shall be set by user before spi bus creation. + */ + uint8_t cs; + + /* + * @brief Message speed shall be set by user before spi bus creation. + */ + uint32_t speed_hz; + + /* + * SPI bus path shall be provided by the user before spi bus creation. + */ + const char *spi_path; +} sc16is752_spi_context; + +/** + * @brief SC16IS752 I2C context. + */ +typedef struct { + sc16is752_context base; + int fd; + /* + * SPI bus path shall be provided by the user before i2c bus creation. + */ + const char *bus_path; +} sc16is752_i2c_context; + +const rtems_termios_device_handler sc16is752_termios_handler; + +/** + * @brief The interrupt handler for receive and transmit operations. + * + * @param[in] arg Function argument. + */ +void sc16is752_interrupt_handler(void *arg); + +/** + * @brief Creates a termios device that runs in polled mode. + * + * @param[in] spi_ctx Pointer to the current spi context. + * @param[in] device_path Buffer which contains the desired device path. + * + * If return value is not RTEMS_SUCCESSFUL, please check the function + * "rtems_termios_device_install" for possible errors. + */ +rtems_status_code sc16is752_spi_create( + sc16is752_spi_context *spi_ctx, + const char *device_path +); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DEV_SERIAL_SC16IS752_H */ diff --git a/cpukit/dev/preinstall.am b/cpukit/dev/preinstall.am index d2e63ba..801bdb5 100644 --- a/cpukit/dev/preinstall.am +++ b/cpukit/dev/preinstall.am @@ -48,6 +48,15 @@ $(PROJECT_INCLUDE)/dev/spi/spi.h: include/dev/spi/spi.h $(PROJECT_INCLUDE)/dev/s $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/dev/spi/spi.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/dev/spi/spi.h +$(PROJECT_INCLUDE)/dev/serial/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE)/dev/serial + @: > $(PROJECT_INCLUDE)/dev/serial/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/dev/serial/$(dirstamp) + +$(PROJECT_INCLUDE)/dev/serial/nxp-sc16is752.h: include/dev/serial/nxp-sc16is752.h $(PROJECT_INCLUDE)/dev/serial/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/dev/serial/nxp-sc16is752.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/dev/serial/nxp-sc16is752.h + $(PROJECT_INCLUDE)/linux/$(dirstamp): @$(MKDIR_P) $(PROJECT_INCLUDE)/linux @: > $(PROJECT_INCLUDE)/linux/$(dirstamp) diff --git a/cpukit/dev/serial/nxp-sc16is752-regs.h b/cpukit/dev/serial/nxp-sc16is752-regs.h new file mode 100644 index 0000000..69dcfdf --- /dev/null +++ b/cpukit/dev/serial/nxp-sc16is752-regs.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <i...@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_ATSAM_SC16IS752_H +#define LIBBSP_ARM_ATSAM_SC16IS752_H + +#include <dev/serial/nxp-sc16is752.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* General register set */ +#define SC16IS752_RHR 0x0 +#define SC16IS752_THR 0x0 +#define SC16IS752_IER 0x1 +#define SC16IS752_FCR 0x2 +#define SC16IS752_IIR 0x2 +#define SC16IS752_LCR 0x3 +#define SC16IS752_MCR 0x4 +#define SC16IS752_LSR 0x5 +#define SC16IS752_MSR 0x6 +#define SC16IS752_TCR 0x6 +#define SC16IS752_SPR 0x7 +#define SC16IS752_TLR 0x7 +#define SC16IS752_TXLVL 0x8 +#define SC16IS752_RXLVL 0x9 +#define SC16IS752_IODIR 0xA +#define SC16IS752_IOSTATE 0xB +#define SC16IS752_IOINTENA 0xC +#define SC16IS752_IOCONTROL 0xE +#define SC16IS752_EFCR 0xF + +/* FCR bits */ +#define FCR_FIFO_EN 0x01 +#define FCR_RX_FIFO_RST 0x02 +#define FCR_TX_FIFO_RST 0x04 +#define FCR_TX_FIFO_TRG_8 0x00 +#define FCR_TX_FIFO_TRG_16 0x10 +#define FCR_TX_FIFO_TRG_32 0x20 +#define FCR_TX_FIFO_TRG_56 0x30 +#define FCR_RX_FIFO_TRG_8 0x00 +#define FCR_RX_FIFO_TRG_16 0x40 +#define FCR_RX_FIFO_TRG_56 0x80 +#define FCR_RX_FIFO_TRG_60 0xc0 + +/* Special register set */ +#define SC16IS752_DLL 0x0 +#define SC16IS752_DLH 0x1 + +/* Enhanced register set */ +#define SC16IS752_EFR 0x2 +#define SC16IS752_XON1 0x4 +#define SC16IS752_XON2 0x5 +#define SC16IS752_XOFF1 0x6 +#define SC16IS752_XOFF2 0x7 + +/* EFCR Bit masks */ +#define EFCR_RS485ENABLE (1 << 0) +#define EFCR_RXENABLE (0 << 1) +#define EFCR_TXENABLE (0 << 2) + +/* IER Bit masks */ +#define IER_ENABLE_RHR_INTERRUPT (1u << 0) +#define IER_ENABLE_THR_INTERRUPT (1u << 1) +#define IER_ENABLE_RECEIVE_LINE_INTERRUPT (1u << 2) +#define IER_ENABLE_MODEM_STATUS_INTERRUPT (1u << 3) + +/* IIR Bit masks */ +#define IIR_TX_INTERRUPT (1u << 1) +#define IIR_RX_INTERRUPT (1u << 2) + +/* LCR Bit masks */ +#define LCR_CHRL_5_BIT (0u << 1) | (0u << 0) +#define LCR_CHRL_6_BIT (0u << 1) | (1u << 0) +#define LCR_CHRL_7_BIT (1u << 1) | (0u << 0) +#define LCR_CHRL_8_BIT (1u << 1) | (1u << 0) +#define LCR_2_STOP_BIT (1u << 2) +#define LCR_SET_PARITY (1u << 3) +#define LCR_EVEN_PARITY (1u << 4) +#define LCR_ENABLE_DIVISOR (1u << 7) + +/* LSR Bit masks */ +#define LSR_TXEMPTY (1u << 5) +#define LSR_RXRDY (1u << 0) +#define LSR_ERROR_BITS (7u << 2) + +/* MCR Bit masks */ +#define MCR_PRESCALE_NEEDED (1u << 0) + +#define SC16IS752_FIFO_DEPTH 64 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_ATSAM_SC16IS752_H */ diff --git a/cpukit/dev/serial/nxp-sc16is752-spi.c b/cpukit/dev/serial/nxp-sc16is752-spi.c new file mode 100644 index 0000000..74e273b --- /dev/null +++ b/cpukit/dev/serial/nxp-sc16is752-spi.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <i...@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include "nxp-sc16is752-regs.h" + +#include <assert.h> +#include <fcntl.h> +#include <inttypes.h> +#include <unistd.h> + +#include <dev/spi/spi.h> + +static void set_default_msg( + struct spi_ioc_transfer *msg, + uint8_t cs, + uint32_t speed, + size_t len, + uint8_t *rx_buf, + const uint8_t *tx_buf +) +{ + msg->rx_buf = rx_buf; + msg->tx_buf = tx_buf; + msg->len = len; + msg->speed_hz = speed; + msg->delay_usecs = 1; + msg->bits_per_word = 8; + msg->cs_change = 0; + msg->rx_nbits = 0; + msg->tx_nbits = 0; + msg->mode = 0; + msg->cs = cs; +} + +static int sc16is752_spi_write_reg( + sc16is752_context *ctx, + uint8_t reg_addr, + const uint8_t *reg_val, + size_t len +) +{ + int rv; + spi_ioc_transfer msg[2]; + uint8_t rx_buf_cmd; + uint8_t rx_buf[len]; + uint8_t tx_buf_cmd; + sc16is752_spi_context *spi_ctx = (sc16is752_spi_context *) ctx; + + tx_buf_cmd = reg_addr << 3; + set_default_msg(&msg[0], spi_ctx->cs, spi_ctx->speed_hz, 1, &rx_buf_cmd, &tx_buf_cmd); + + set_default_msg(&msg[1], spi_ctx->cs, spi_ctx->speed_hz, len, &rx_buf[0], ®_val[0]); + msg[1].cs_change = 1; + + rv = ioctl(spi_ctx->fd, SPI_IOC_MESSAGE(2), &msg[0]); + + return rv; +} + +static int sc16is752_spi_read_reg( + sc16is752_context *ctx, + uint8_t reg_addr, + uint8_t *reg_val, + size_t len +) +{ + int rv; + spi_ioc_transfer msg[2]; + uint8_t rx_buf_cmd; + uint8_t tx_buf_cmd; + uint8_t tx_buf[len]; + sc16is752_spi_context *spi_ctx = (sc16is752_spi_context *) ctx; + + tx_buf_cmd = 0x80 | reg_addr << 3; + + set_default_msg(&msg[0], spi_ctx->cs, spi_ctx->speed_hz, 1, &rx_buf_cmd, &tx_buf_cmd); + + set_default_msg(&msg[1], spi_ctx->cs, spi_ctx->speed_hz, len, ®_val[0], &tx_buf[0]); + msg[1].cs_change = 1; + + rv = ioctl(spi_ctx->fd, SPI_IOC_MESSAGE(2), &msg[0]); + + return rv; +} + +static bool sc16is752_spi_first_open(sc16is752_context *ctx) +{ + sc16is752_spi_context *spi_ctx = (sc16is752_spi_context *) ctx; + spi_ctx->fd = open(spi_ctx->spi_path, O_RDWR); + return spi_ctx->fd >= 0; +} + +static void sc16is752_spi_last_close(sc16is752_context *ctx) +{ + sc16is752_spi_context *spi_ctx = (sc16is752_spi_context *) ctx; + close(spi_ctx->fd); +} + +rtems_status_code sc16is752_spi_create( + sc16is752_spi_context *spi_ctx, + const char *device_path +) +{ + spi_ctx->base.write_reg = sc16is752_spi_write_reg; + spi_ctx->base.read_reg = sc16is752_spi_read_reg; + spi_ctx->base.first_open = sc16is752_spi_first_open; + spi_ctx->base.last_close = sc16is752_spi_last_close; + + return rtems_termios_device_install( + device_path, + &sc16is752_termios_handler, + NULL, + &spi_ctx->base.base + ); +} diff --git a/cpukit/dev/serial/nxp-sc16is752.c b/cpukit/dev/serial/nxp-sc16is752.c new file mode 100644 index 0000000..4601de5 --- /dev/null +++ b/cpukit/dev/serial/nxp-sc16is752.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rt...@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <sys/param.h> + +#include <assert.h> +#include <stdio.h> +#include <fcntl.h> + +#include <dev/serial/nxp-sc16is752.h> +#include "nxp-sc16is752-regs.h" + +#include <rtems/termiostypes.h> + +#define SC16IS752_CONSOLE_BAUD 115200 + +static void write_reg( + sc16is752_context *ctx, + uint8_t addr, + const uint8_t *val, + size_t len +) +{ + ctx->write_reg(ctx, addr, val, len); +} + +static void read_reg( + sc16is752_context *ctx, + uint8_t addr, + uint8_t *val, + size_t len +) +{ + ctx->read_reg(ctx, addr, val, len); +} + +static void sc16is752_set_baud_rate( + sc16is752_context *ctx, + uint32_t value_mcr, + uint32_t divisor +) +{ + uint8_t value_lcr; + uint8_t value_mcr_8bit = (uint8_t)value_mcr; + uint8_t divisor_8bit = (uint8_t)divisor; + uint8_t divisor_shift = divisor >> 8; + + read_reg(ctx, SC16IS752_LCR, &value_lcr, 1); + value_lcr |= LCR_ENABLE_DIVISOR; + + write_reg(ctx, SC16IS752_LCR, &value_lcr, 1); + write_reg(ctx, SC16IS752_MCR, &value_mcr_8bit, 1); + write_reg(ctx, SC16IS752_DLH, &divisor_shift, 1); + write_reg(ctx, SC16IS752_DLL, &divisor_8bit, 1); + value_lcr &= ~LCR_ENABLE_DIVISOR; + write_reg(ctx, SC16IS752_LCR, &value_lcr, 1); +} + +static bool sc16is752_prepare_baud_rate( + sc16is752_context *ctx, + rtems_termios_baud_t baud +) +{ + uint32_t freq = ctx->input_frequency; + uint8_t value_mcr; + uint32_t divisor; + + read_reg(ctx, SC16IS752_MCR, &value_mcr, 1); + + divisor = freq / baud / 16; + if (divisor > 0xFFFF){ + divisor = (freq / (4 * baud)) / 16; + if (divisor > 0xFFFF){ + return false; + } else { + value_mcr |= MCR_PRESCALE_NEEDED; + sc16is752_set_baud_rate(ctx, value_mcr, divisor); + } + } else { + value_mcr &= ~MCR_PRESCALE_NEEDED; + sc16is752_set_baud_rate(ctx, value_mcr, divisor); + } + return true; +} + +static bool sc16is752_set_attributes( + rtems_termios_device_context *base, + const struct termios *term +) +{ + sc16is752_context *ctx = (sc16is752_context *) base; + uint8_t lcr_value = 0; + uint8_t lcr_read_value = 0; + uint8_t efcr_value = 0; + bool baud_successful; + rtems_termios_baud_t baud; + + baud = rtems_termios_baud_to_number(term->c_cflag); + baud_successful = sc16is752_prepare_baud_rate(ctx, baud); + if (!baud_successful){ + return false; + } + + if (ctx->mode == SC16IS752_MODE_RS485){ + efcr_value = EFCR_RS485ENABLE; + } + + if ((term->c_cflag & CREAD) != 0){ + efcr_value |= EFCR_RXENABLE | EFCR_TXENABLE; + } else { + efcr_value |= EFCR_TXENABLE; + } + write_reg(ctx, SC16IS752_EFCR, &efcr_value, 1); + + switch (term->c_cflag & CSIZE) { + case CS5: + lcr_value |= LCR_CHRL_5_BIT; + break; + case CS6: + lcr_value |= LCR_CHRL_6_BIT; + break; + case CS7: + lcr_value |= LCR_CHRL_7_BIT; + break; + case CS8: + lcr_value |= LCR_CHRL_8_BIT; + break; + } + + if ((term->c_cflag & PARENB) != 0){ + if ((term->c_cflag & PARODD) != 0) { + lcr_value &= ~LCR_EVEN_PARITY; + } else { + lcr_value |= LCR_EVEN_PARITY; + } + } else { + lcr_value &= ~LCR_SET_PARITY; + } + + if ((term->c_cflag & CSTOPB) != 0) { + lcr_value |= LCR_2_STOP_BIT; + } else { + lcr_value &= ~LCR_2_STOP_BIT; + } + + write_reg(ctx, SC16IS752_LCR, &lcr_value, 1); + read_reg(ctx, SC16IS752_LCR, &lcr_read_value, 1); + + return true; +} + +static bool sc16is752_first_open( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ + bool ok; + uint8_t fcr; + + (void)args; + sc16is752_context *ctx = (sc16is752_context *) base; + + ctx->tty = tty; + + ok = (*ctx->first_open)(ctx); + if (!ok) { + return ok; + } + + fcr = FCR_FIFO_EN | FCR_RX_FIFO_RST | FCR_TX_FIFO_RST + | FCR_RX_FIFO_TRG_8 | FCR_TX_FIFO_TRG_56; + write_reg(ctx, SC16IS752_FCR, &fcr, 1); + + ctx->ier = IER_ENABLE_RHR_INTERRUPT; + write_reg(ctx, SC16IS752_IER, &ctx->ier, 1); + + rtems_termios_set_initial_baud(tty, SC16IS752_CONSOLE_BAUD); + sc16is752_set_attributes(base, term); + + (*ctx->install_irq)(ctx); + + return true; +} + +static void sc16is752_last_close( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + rtems_libio_open_close_args_t *args +) +{ + (void) tty; + (void) args; + sc16is752_context *ctx = (sc16is752_context *) base; + (*ctx->last_close)(ctx); +} + +static void sc16is752_write( + rtems_termios_device_context *base, + const char *buf, + size_t len +) +{ + sc16is752_context *ctx = (sc16is752_context *) base; + + if (len > 0) { + ctx->ier |= IER_ENABLE_THR_INTERRUPT; + len = MIN(len, SC16IS752_FIFO_DEPTH / 4); + ctx->tx_in_progress = (uint8_t)len; + write_reg(ctx, SC16IS752_THR, (const uint8_t *)&buf[0], len); + write_reg(ctx, SC16IS752_IER, &ctx->ier, 1); + } else { + ctx->tx_in_progress = 0; + ctx->ier &= ~IER_ENABLE_THR_INTERRUPT; + write_reg(ctx, SC16IS752_IER, &ctx->ier, 1); + } +} + +const rtems_termios_device_handler sc16is752_termios_handler = { + .first_open = sc16is752_first_open, + .last_close = sc16is752_last_close, + .write = sc16is752_write, + .set_attributes = sc16is752_set_attributes, + .mode = TERMIOS_IRQ_SERVER_DRIVEN +}; + +void sc16is752_interrupt_handler(void *arg) +{ + sc16is752_context *ctx = (sc16is752_context *) arg; + uint8_t iir = 0; + + read_reg(ctx, SC16IS752_IIR, &iir, 1); + + if((iir & IIR_RX_INTERRUPT) != 0) { + uint8_t buf[SC16IS752_FIFO_DEPTH]; + uint8_t rxlvl = 0; + + read_reg(ctx, SC16IS752_RXLVL, &rxlvl, 1); + rxlvl = MIN(rxlvl, SC16IS752_FIFO_DEPTH); + read_reg(ctx, SC16IS752_RHR, &buf[0], rxlvl); + rtems_termios_enqueue_raw_characters(ctx->tty, (const char *)&buf[0], rxlvl); + } else if ((iir & IIR_TX_INTERRUPT) != 0 && ctx->tx_in_progress > 0) { + rtems_termios_dequeue_characters(ctx->tty, ctx->tx_in_progress); + } +} -- 1.8.4.5 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel