summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/shared/comm/uart.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2001-07-03 17:56:32 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2001-07-03 17:56:32 +0000
commitcaeb33b22de9493023993090d54e8f4f6156e4cf (patch)
treef67c5fd1d0ad83cb5eca3c7fe960084f58ab86c7 /c/src/lib/libbsp/i386/shared/comm/uart.c
parent2001-07-03 Joel Sherrill <joel@OARcorp.com> (diff)
downloadrtems-caeb33b22de9493023993090d54e8f4f6156e4cf.tar.bz2
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.
Diffstat (limited to 'c/src/lib/libbsp/i386/shared/comm/uart.c')
-rw-r--r--c/src/lib/libbsp/i386/shared/comm/uart.c251
1 files changed, 117 insertions, 134 deletions
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 <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);
@@ -536,6 +514,52 @@ BSP_uart_termios_set(int uart, void *ttyp)
}
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)
{
assert(buf != NULL);
@@ -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 */