2001-07-03 Mike Seirs <mike@poliac.com>

* 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.
This commit is contained in:
Joel Sherrill
2001-07-03 17:56:32 +00:00
parent 6c5e321514
commit caeb33b22d
4 changed files with 179 additions and 148 deletions

View File

@@ -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 <corsepiu@faw.uni-ulm.de>
* comm/Makefile.am: Use *_HEADERS instead of *H_FILES.
* io/Makefile.am: Ditto.
* irq/Makefile.am: Ditto.

View File

@@ -18,6 +18,12 @@
* MODIFICATION/HISTORY:
*
* $Log$
* Revision 1.3 2000/12/05 16:37:38 joel
* 2000-12-01 Joel Sherrill <joel@OARcorp.com>
*
* * 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 <charles.gauthier@nrc.ca>
*
@@ -47,6 +53,7 @@
#include <bsp.h>
#include <irq.h>
#include <rtems/libio.h>
#include <rtems/termiostypes.h>
#include <termios.h>
#include <uart.h>
#include <libcpu/cpuModel.h>
@@ -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 */
NULL, /* firstOpen */
tty1_last_close, /* lastClose */
NULL, /* 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_IRQ_DRIVEN /* outputUsesInterrupts */
};
#else
static rtems_termios_callbacks cb =
{
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 */
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 */
NULL, /* firstOpen */
tty2_last_close, /* lastClose */
NULL, /* 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_IRQ_DRIVEN /* outputUsesInterrupts */
};
#else
static rtems_termios_callbacks cb =
{
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 */
TERMIOS_TASK_DRIVEN /* outputUsesInterrupts */
};
#endif
status = rtems_termios_open (major, minor, arg, &cb);
if(status != RTEMS_SUCCESSFUL)

View File

@@ -7,10 +7,13 @@
* $Id$
*/
#include <stdio.h>
#include <bsp.h>
#include <irq.h>
#include <uart.h>
#include <rtems/libio.h>
#include <rtems/termiostypes.h>
#include <termios.h>
#include <assert.h>
/*
@@ -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 */

View File

@@ -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();