From caeb33b22de9493023993090d54e8f4f6156e4cf Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 3 Jul 2001 17:56:32 +0000 Subject: 2001-07-03 Mike Seirs * comm/tty_drv.c, comm/uart.c, comm/uart.h: Adds the capability to use task driven serial I/O to ti386 BSPs. This patch leaves thex default I/O mode to be IRQ. If you want to use task I/O mode, then the tty_drv.c file needs to be modified. Basically, all you need to change is the data values of the termios callbacks structure. This callback structure is used in the tty1_open and tty2_open functions. The values you need to set are commented out in the source code. --- c/src/lib/libbsp/i386/shared/ChangeLog | 11 ++ c/src/lib/libbsp/i386/shared/comm/tty_drv.c | 63 +++++-- c/src/lib/libbsp/i386/shared/comm/uart.c | 251 +++++++++++++--------------- c/src/lib/libbsp/i386/shared/comm/uart.h | 2 + 4 files changed, 179 insertions(+), 148 deletions(-) (limited to 'c/src/lib') diff --git a/c/src/lib/libbsp/i386/shared/ChangeLog b/c/src/lib/libbsp/i386/shared/ChangeLog index 7e94048a6b..74b499cd49 100644 --- a/c/src/lib/libbsp/i386/shared/ChangeLog +++ b/c/src/lib/libbsp/i386/shared/ChangeLog @@ -1,4 +1,15 @@ + * comm/tty_drv.c, comm/uart.c, comm/uart.h: Adds the capability + to use task driven serial I/O to ti386 BSPs. This patch leaves thex + default I/O mode to be IRQ. If you want to use task I/O mode, + then the tty_drv.c file needs to be modified. Basically, all + you need to change is the data values of the termios callbacks + structure. This callback structure is used in the tty1_open + and tty2_open functions. The values you need to set are commented + out in the source code. + +2001-06-19 Ralf Corsepius + * comm/Makefile.am: Use *_HEADERS instead of *H_FILES. * io/Makefile.am: Ditto. * irq/Makefile.am: Ditto. diff --git a/c/src/lib/libbsp/i386/shared/comm/tty_drv.c b/c/src/lib/libbsp/i386/shared/comm/tty_drv.c index 490260675f..502ab6c4f9 100644 --- a/c/src/lib/libbsp/i386/shared/comm/tty_drv.c +++ b/c/src/lib/libbsp/i386/shared/comm/tty_drv.c @@ -18,6 +18,12 @@ * MODIFICATION/HISTORY: * * $Log$ + * Revision 1.3 2000/12/05 16:37:38 joel + * 2000-12-01 Joel Sherrill + * + * * pc386/console/console.c, pc386/console/serial_mouse.c, + * pc386/console/vgainit.c, shared/comm/tty_drv.c: Remove warnings. + * * Revision 1.2 2000/10/18 16:10:50 joel * 2000-10-18 Charles-Antoine Gauthier * @@ -47,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -175,17 +182,31 @@ tty1_open(rtems_device_major_number major, void *arg) { rtems_status_code status; +#ifndef USE_TASK_DRIVEN + static rtems_termios_callbacks cb = + { + NULL, /* firstOpen */ + tty1_last_close, /* lastClose */ + NULL, /* poll read */ + BSP_uart_termios_write_com1, /* write */ + tty1_conSetAttr, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */ + }; +#else static rtems_termios_callbacks cb = { - NULL, /* firstOpen */ - tty1_last_close, /* lastClose */ - NULL, /* poll read */ + NULL, /* firstOpen */ + tty1_last_close, /* lastClose */ + BSP_uart_termios_read_com1, /* poll read */ BSP_uart_termios_write_com1, /* write */ - tty1_conSetAttr, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ + tty1_conSetAttr, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* outputUsesInterrupts */ }; +#endif status = rtems_termios_open( major, minor, arg, &cb ); if(status != RTEMS_SUCCESSFUL) @@ -451,17 +472,31 @@ tty2_open(rtems_device_major_number major, void *arg) { rtems_status_code status; +#ifndef USE_TASK_DRIVEN + static rtems_termios_callbacks cb = + { + NULL, /* firstOpen */ + tty2_last_close, /* lastClose */ + NULL, /* poll read */ + BSP_uart_termios_write_com2, /* write */ + tty2_conSetAttr, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */ + }; +#else static rtems_termios_callbacks cb = { - NULL, /* firstOpen */ - tty2_last_close, /* lastClose */ - NULL, /* poll read */ + NULL, /* firstOpen */ + tty2_last_close, /* lastClose */ + BSP_uart_termios_read_com2, /* poll read */ BSP_uart_termios_write_com2, /* write */ - tty2_conSetAttr, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ + tty2_conSetAttr, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* outputUsesInterrupts */ }; +#endif status = rtems_termios_open (major, minor, arg, &cb); if(status != RTEMS_SUCCESSFUL) diff --git a/c/src/lib/libbsp/i386/shared/comm/uart.c b/c/src/lib/libbsp/i386/shared/comm/uart.c index 91cb5f9be9..50554cc142 100644 --- a/c/src/lib/libbsp/i386/shared/comm/uart.c +++ b/c/src/lib/libbsp/i386/shared/comm/uart.c @@ -7,10 +7,13 @@ * $Id$ */ +#include #include #include #include #include +#include +#include #include /* @@ -19,7 +22,9 @@ struct uart_data { + int ioMode; int hwFlow; + unsigned int ier; unsigned long baud; unsigned long databits; unsigned long parity; @@ -232,61 +237,31 @@ BSP_uart_set_attributes void BSP_uart_intr_ctrl(int uart, int cmd) { + int iStatus = (int)INTERRUPT_DISABLE; assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); switch(cmd) { - case BSP_UART_INTR_CTRL_DISABLE: - uwrite(uart, IER, INTERRUPT_DISABLE); - break; case BSP_UART_INTR_CTRL_ENABLE: - if(uart_data[uart].hwFlow) - { - uwrite(uart, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - } - else - { - uwrite(uart, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - } + iStatus |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE | TRANSMIT_ENABLE); + if ( uart_data[uart].hwFlow ) { + iStatus |= MODEM_ENABLE; + } break; case BSP_UART_INTR_CTRL_TERMIOS: - if(uart_data[uart].hwFlow) - { - uwrite(uart, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - } - else - { - uwrite(uart, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - } + iStatus |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE); + if ( uart_data[uart].hwFlow ) { + iStatus |= MODEM_ENABLE; + } break; case BSP_UART_INTR_CTRL_GDB: - uwrite(uart, IER, RECEIVE_ENABLE); - break; - default: - assert(0); + iStatus |= RECEIVE_ENABLE; break; } + + uart_data[uart].ier = iStatus; + uwrite(uart, IER, iStatus); return; } @@ -494,11 +469,13 @@ void uart_set_driver_handler( int port, void ( *handler )( void *, char *, int void BSP_uart_termios_set(int uart, void *ttyp) { + struct rtems_termios_tty *p = (struct rtems_termios_tty *)ttyp; unsigned char val; assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); if(uart == BSP_UART_COM1) { + uart_data[uart].ioMode = p->device.outputUsesInterrupts; if(uart_data[uart].hwFlow) { val = uread(uart, MSR); @@ -516,6 +493,7 @@ BSP_uart_termios_set(int uart, void *ttyp) } else { + uart_data[uart].ioMode = p->device.outputUsesInterrupts; if(uart_data[uart].hwFlow) { val = uread(uart, MSR); @@ -535,6 +513,52 @@ BSP_uart_termios_set(int uart, void *ttyp) return; } +int +BSP_uart_termios_read_com1(int uart) +{ + int off = (int)0; + char buf[40]; + + /* read bytes */ + while (( off < sizeof(buf) ) && ( uread(BSP_UART_COM1, LSR) & DR )) { + buf[off++] = uread(BSP_UART_COM1, RBR); + } + + /* write out data */ + if ( off > 0 ) { + rtems_termios_enqueue_raw_characters(termios_ttyp_com1, buf, off); + } + + /* enable receive interrupts */ + uart_data[BSP_UART_COM1].ier |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE); + uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier); + + return ( EOF ); +} + +int +BSP_uart_termios_read_com2(int uart) +{ + int off = (int)0; + char buf[40]; + + /* read current byte */ + while (( off < sizeof(buf) ) && ( uread(BSP_UART_COM1, LSR) & DR )) { + buf[off++] = uread(BSP_UART_COM1, RBR); + } + + /* write out data */ + if ( off > 0 ) { + rtems_termios_enqueue_raw_characters(termios_ttyp_com2, buf, off); + } + + /* enable receive interrupts */ + uart_data[BSP_UART_COM2].ier |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE); + uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier); + + return ( EOF ); +} + int BSP_uart_termios_write_com1(int minor, const char *buf, int len) { @@ -560,27 +584,11 @@ BSP_uart_termios_write_com1(int minor, const char *buf, int len) uwrite(BSP_UART_COM1, THR, *buf & 0xff); /* Enable interrupts if necessary */ - if(!termios_tx_active_com1 && uart_data[BSP_UART_COM1].hwFlow) - { - termios_tx_active_com1 = 1; - uwrite(BSP_UART_COM1, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - } - else if(!termios_tx_active_com1) - { - termios_tx_active_com1 = 1; - uwrite(BSP_UART_COM1, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - } + if ( !termios_tx_active_com1 ) { + termios_tx_active_com1 = 1; + uart_data[BSP_UART_COM1].ier |= TRANSMIT_ENABLE; + uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier); + } return 0; } @@ -608,31 +616,14 @@ BSP_uart_termios_write_com2(int minor, const char *buf, int len) } /* Write character */ - uwrite(BSP_UART_COM2, THR, *buf & 0xff); /* Enable interrupts if necessary */ - if(!termios_tx_active_com2 && uart_data[BSP_UART_COM2].hwFlow) - { - termios_tx_active_com2 = 1; - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - } - else if(!termios_tx_active_com2) - { - termios_tx_active_com2 = 1; - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - } + if ( !termios_tx_active_com2 ) { + termios_tx_active_com2 = 1; + uart_data[BSP_UART_COM2].ier |= TRANSMIT_ENABLE; + uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier); + } return 0; } @@ -697,34 +688,30 @@ BSP_uart_termios_isr_com1(void) * if there is nothing more to send. */ - ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1); - /* If nothing else to send disable interrupts */ - if(ret == 0 && uart_data[BSP_UART_COM1].hwFlow) - { - uwrite(BSP_UART_COM1, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - termios_tx_active_com1 = 0; - } - else if(ret == 0) - { - uwrite(BSP_UART_COM1, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - termios_tx_active_com1 = 0; - } + ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1); + if ( ret == 0 ) { + termios_tx_active_com1 = 0; + uart_data[BSP_UART_COM1].ier &= ~(TRANSMIT_ENABLE); + uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier); + } break; case RECEIVER_DATA_AVAIL : case CHARACTER_TIMEOUT_INDICATION: - /* RX data ready */ - assert(off < sizeof(buf)); - buf[off++] = uread(BSP_UART_COM1, RBR); + if ( uart_data[BSP_UART_COM1].ioMode == TERMIOS_TASK_DRIVEN ) { + /* ensure interrupts are enabled */ + if ( uart_data[BSP_UART_COM1].ier & RECEIVE_ENABLE ) { + /* disable interrupts and notify termios */ + uart_data[BSP_UART_COM1].ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE); + uwrite(BSP_UART_COM1, IER, uart_data[BSP_UART_COM1].ier); + rtems_termios_rxirq_occured(termios_ttyp_com1); + } + } + else { + /* RX data ready */ + assert(off < sizeof(buf)); + buf[off++] = uread(BSP_UART_COM1, RBR); + } break; case RECEIVER_ERROR: /* RX error: eat character */ @@ -796,34 +783,30 @@ BSP_uart_termios_isr_com2() * if there is nothing more to send. */ - ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1); - /* If nothing else to send disable interrupts */ - if(ret == 0 && uart_data[BSP_UART_COM2].hwFlow) - { - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - termios_tx_active_com2 = 0; - } - else if(ret == 0) - { - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - termios_tx_active_com2 = 0; - } + ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1); + if ( ret == 0 ) { + termios_tx_active_com2 = 0; + uart_data[BSP_UART_COM2].ier &= ~(TRANSMIT_ENABLE); + uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier); + } break; case RECEIVER_DATA_AVAIL : case CHARACTER_TIMEOUT_INDICATION: - /* RX data ready */ - assert(off < sizeof(buf)); - buf[off++] = uread(BSP_UART_COM2, RBR); + if ( uart_data[BSP_UART_COM2].ioMode == TERMIOS_TASK_DRIVEN ) { + /* ensure interrupts are enabled */ + if ( uart_data[BSP_UART_COM2].ier & RECEIVE_ENABLE ) { + /* disable interrupts and notify termios */ + uart_data[BSP_UART_COM2].ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE); + uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier); + rtems_termios_rxirq_occured(termios_ttyp_com2); + } + } + else { + /* RX data ready */ + assert(off < sizeof(buf)); + buf[off++] = uread(BSP_UART_COM2, RBR); + } break; case RECEIVER_ERROR: /* RX error: eat character */ diff --git a/c/src/lib/libbsp/i386/shared/comm/uart.h b/c/src/lib/libbsp/i386/shared/comm/uart.h index d5687bf453..116ae15c60 100644 --- a/c/src/lib/libbsp/i386/shared/comm/uart.h +++ b/c/src/lib/libbsp/i386/shared/comm/uart.h @@ -20,6 +20,8 @@ int BSP_uart_polled_status(int uart); void BSP_uart_polled_write(int uart, int val); int BSP_uart_polled_read(int uart); void BSP_uart_termios_set(int uart, void *ttyp); +int BSP_uart_termios_read_com1(int uart); +int BSP_uart_termios_read_com2(int uart); int BSP_uart_termios_write_com1(int minor, const char *buf, int len); int BSP_uart_termios_write_com2(int minor, const char *buf, int len); void BSP_uart_termios_isr_com1(); -- cgit v1.2.3