2004-01-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>

PR 563/bsps
	* consolex/consolex.c, consolex/consolex.h, consolex/cTest.c,
	consolex/Makefile.am, consolex/README:
	Remove (Abandoned).
This commit is contained in:
Ralf Corsepius
2004-01-28 02:43:14 +00:00
parent 964c8322e4
commit 3da271f601
7 changed files with 7 additions and 1108 deletions

View File

@@ -1,3 +1,10 @@
2004-01-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
PR 563/bsps
* consolex/consolex.c, consolex/consolex.h, consolex/cTest.c,
consolex/Makefile.am, consolex/README:
Remove (Abandoned).
2004-01-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Add PREINSTALL_DIRS.

View File

@@ -1,2 +0,0 @@
Makefile
Makefile.in

View File

@@ -1,45 +0,0 @@
##
## $Id$
##
PGM = $(ARCH)/consolex.rel
C_FILES = consolex.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
include_HEADERS = consolex.h
OBJS = $(C_O_FILES)
include $(top_srcdir)/../../../../automake/compile.am
include $(top_srcdir)/../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(OBJS)
$(make-rel)
all-local: $(OBJS) $(PGM) $(TMPINSTALL_FILES)
.PRECIOUS: $(PGM)
EXTRA_DIST = README cTest.c consolex.c consolex.h
PREINSTALL_DIRS =
PREINSTALL_FILES =
$(PROJECT_INCLUDE)/$(dirstamp):
@$(mkdir_p) $(PROJECT_INCLUDE)
@: > $(PROJECT_INCLUDE)/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
$(PROJECT_INCLUDE)/consolex.h: consolex.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/consolex.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/consolex.h
CLEANFILES = $(PREINSTALL_FILES)
DISTCLEANFILES = $(PREINSTALL_DIRS)
include $(top_srcdir)/../../../../automake/local.am

View File

@@ -1,97 +0,0 @@
#
# $Id$
#
This driver was submitted by Katsutoshi Shibuya <shibuya@mxb.meshnet.or.jp>.
Configuration
-------------
The application can choose this driver by using "CONSOLEX_DRIVER_TABLE_ENTRY"
in the driver table definition, in place of "CONSOLE_DRIVER_TABLE_ENTRY".
See consolex/cTest.c for an example and consolex/README for more information.
Programmatic Usage
------------------
- You can open 9 devices; console tty00, tty01, tty02, tty03,
rtty00, rtty01, rtty02, rtty03
tty00, rtty00 and console correspond to port#1 of MVME162LX,
tty01 and rtty01 correspond to port#2, and so on.
- tty0x are "cooked" devices. They support following flags on termios
definition;
ISTRIP, INLCR, IGNCR, ICRNL, IUCLC, OLCUC, ONLCR, OCRNL, ICANON, ECHO,
CBAUD, B38400, B19200, B9600, CSIZE, CS8, CS7, PARENB, PARODD, CSTOPB,
- rtty0x are "raw" devices. They support following flags on termios
definition;
CBAUD, B38400, B19200, B9600, CSIZE, CS8, CS7, PARENB, PARODD, CSTOPB,
- The default parameter is;
B38400, CS8, ICRNL, ONLCR, ICANON, ECHO
(but all flags except B38400 and CS8 will be ignored on raw device.)
- All devices support O_NDELAY (non blocking read/write) mode operation.
(Non-blocking cooked mode output is valid, but will not work fine.)
(Non-blocking cooked mode input with ECHO flag may be blocked while sending
echoed character.)
- All devices support hardware flow control by CTS/RTS.
(There is no way to disable it. There are no supports for soft flow control.)
- The application can use tcgetattr or ioctl to obtain the parameters of the
device into struct termios.
- The application can use tcsetattr or ioctl to set the parameters of the
device within the struct temios. The action argument (2nd arg) of the
tcsetattr must be TCSANOW.
- On opening the device, the driver activate DTR line. On closing the device,
the driver deactivate DTR line.
If 2 or more device opening occures at the same time on the same port, only
the first open procedure activates DTR line, and only the last close
procedure deactivate it.
- There are no device locking mechanisms. Application can open same device
several times.
But 2 simultanious reading operation on the same port will cause unexpected
result.
Porting Notes
-------------
- This code can be used for any Zilog SCC based board.
Change the time constant parameters and SCC register base addresses.
- This code is well separated into "device depended part" and "device
independed part".
They can use device independed part for any other board. The device
independed part requires following functions;
void SCCInitialize();
Initialize hardware.
rtems_boolean SCCGetOne(int port, char *ch);
Get one character from port. If no character is in the receiver buffer,
this function returns FALSE, otherwise TRUE.
char SCCGetOneBlocked(int port);
Get one character from port. If no character is in the receiver buffer,
wait it passing the CPU to the other task.
rtems_boolean SCCSendOne(int port, char ch);
Send one character via port. If the transmitter is not ready, this function
returns FALSE, otherwise TRUE.
void SCCSendOneBlocked(int port, char ch);
Send one character via port. Wait until the transmitter is ready, passing
the CPU to the other task.
unsigned32 SCCSetAttributes(int port, struct termios *tm);
Set device attribute according to the information in the struct termios.
c_cflags parameter (baud, parity, stopbits and code size) will be checked.
On the successful completion, this function should return 0.
unsigned32 SCCGetAttributes(int port, struct termios *tm);
Get device attribute according into the struct termios.
c_cflags parameter (baud, parity, stopbits and code size) will be set.
On the successful completion, this function should return 0.
void SCCSetDTR(port);
Activate DTR line.
void SCCResetDTR(port);
Deactivate DTR line.
void SCCSetRTS(port);
Activate RTS line.
void SCCResetRTS(port);
Deactivate RTS line.
int SCCGetCTS(port);
Return non zero when CTS line is activated.
- If you don't want console port, undefine "CONSOLEPORT".
- This code does not use ESCC feature; i.e. does not read register #4/#5/#14

View File

@@ -1,74 +0,0 @@
/*
* Test program for consolex.
*
* NOTE: This program must be put together as an executable. :)
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <rtems.h>
#include <rtems/libio.h>
#include <consolex.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#if ! defined(O_NDELAY)
# if defined(solaris2)
# define O_NDELAY O_NONBLOCK
# elif defined(RTEMS_NEWLIB)
# define O_NDELAY _FNBIO
# endif
#endif
rtems_driver_address_table Device_drivers[] = {
CONSOLEX_DRIVER_TABLE_ENTRY
};
rtems_task Init(rtems_task_argument arg)
{
char buf[128];
int fd;
struct termios t;
printf("Console test.\n");
if((fd = open("/dev/tty00",O_RDWR)) < 0){
printf("Can't open device.\n");
return;
}
tcgetattr(fd,&t);
t.c_cflag = B9600|CS8;
tcsetattr(fd,TCSANOW,&t);
printf("iflag=%07o, oflag=%07o, cflag=%07o, lflag=%07o\n",
t.c_iflag,t.c_oflag,t.c_cflag,t.c_lflag);
do{
write(fd,"Your name? ",11);
read(fd,buf,sizeof(buf));
write(fd,"Hi ",3);
write(fd,buf,strlen(buf));
}while(*buf != '!');
close(fd);
printf("Done.\n");
exit(0);
}
#define CONFIGURE_INIT
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE
#include <confdefs.h>

View File

@@ -1,797 +0,0 @@
/*
* This file contains the MVME162LX extended console IO package.
*
* This file was created originally by
* On-Line Applications Research Corporation (OAR)
* and modified by:
*
* Katsutoshi Shibuya - BU-Denken Co.,Ltd. - Sapporo, JAPAN
*
* featuring support of:
*
* - Multi-SCC chip handling
* - Non-blocking I/O (O_NDELAY flag in libc)
* - Raw mode device (no CR/LF detection)
* - RTS/CTS flow control
*
* REMARKS: This routine requires multiple interrupt vectors
* from SCC_VECTOR (normaly 0x40)
* to SCC_VECTOR+(number of SCC chips)
*
* The original copyright follows;
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* Modifications of respective RTEMS file: COPYRIGHT (c) 1994.
* EISCAT Scientific Association. M.Savitski
*
* This material is a part of the MVME162 Board Support Package
* for the RTEMS executive. Its licensing policies are those of the
* RTEMS above.
*
* $Id$
*/
#define M162_INIT
#include "consolex.h"
#include <bsp.h>
#include <rtems/libio.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define NPORTS 4 /* Number of ports */
#define DEVICEPREFIX "tty"
#define RAWDEVICEPREFIX "rtty"
#define CONSOLEPORT 0 /* port# of console:
undef this if you do not want /dev/console */
#define READRETRY 1 /* Maximum retry count for read one char */
#define WRITERETRY 8 /* Maximum retry count for write one char */
#define PORTFROM 0 /* for debug */
static unsigned char opencount[NPORTS];
/***********************************************************************
Ring buffer for device
***********************************************************************/
#define QUEUE_LENGTH 128 /* Must be 2^n number */
typedef struct {
char buffer[QUEUE_LENGTH];
volatile int head;
volatile int tail;
} ReceiverBuffer;
#define ReceiverBufferInitialize( _buffer ) \
do { \
(_buffer)->head = (_buffer)->tail = 0; \
} while ( 0 )
#define ReceiverBufferIsEmpty( _buffer ) \
( (_buffer)->tail == (_buffer)->head )
#define ReceiverBufferIsNearEmpty( _buffer ) \
( (_buffer)->tail == (((_buffer)->head + 3) & (QUEUE_LENGTH-1)) )
#define ReceiverBufferIsFull( _buffer ) \
( (_buffer)->head == (((_buffer)->tail + 1) & (QUEUE_LENGTH-1)) )
#define ReceiverBufferIsNearFull( _buffer ) \
( (_buffer)->head == (((_buffer)->tail + 3) & (QUEUE_LENGTH-1)) )
#define ReceiverBufferAdd( _buffer, _ch ) \
do { \
rtems_unsigned32 isrlevel; \
\
rtems_interrupt_disable( isrlevel ); \
(_buffer)->tail = ((_buffer)->tail+1) & (QUEUE_LENGTH-1); \
(_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
rtems_interrupt_enable( isrlevel ); \
} while ( 0 )
#define ReceiverBufferRemove( _buffer, _ch ) \
do { \
rtems_unsigned32 isrlevel; \
\
rtems_interrupt_disable( isrlevel ); \
(_buffer)->head = ((_buffer)->head+1) & (QUEUE_LENGTH-1); \
(_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
rtems_interrupt_enable( isrlevel ); \
} while ( 0 )
/***********************************************************************
DEVICE DEPENDED PART
***********************************************************************/
/* Time constant parameters
CAUTION: These parameters are for MVME162LX-213 board.
*/
#define TC38400 0x0006
#define TC19200 0x000e
#define TC9600 0x001e
/* Re-defining SCC register control macros
to support Multi SCC chips */
#undef scc
#if defined(mvme162lx)
static scc_regs *scc[NPORTS] = {
((scc_regs * const) 0xFFF45004),
((scc_regs * const) 0xFFF45000),
((scc_regs * const) 0xFFF45804),
((scc_regs * const) 0xFFF45800)
};
#else
/* XXX fix me */
#warning "MVME162 BSP -- unknown address for SCC's"
static scc_regs *scc[NPORTS] = {
((scc_regs * const) 0xFFF45004),
((scc_regs * const) 0xFFF45000),
((scc_regs * const) 0xFFF45804),
((scc_regs * const) 0xFFF45800)
};
#endif
#undef ZWRITE0
#define ZWRITE0(port, v) (scc[port]->csr = (unsigned char)(v))
#undef ZREAD0
#define ZREAD0(port) (scc[port]->csr)
#undef ZREAD
#define ZREAD(port, n) (ZWRITE0(port, n), (scc[port]->csr))
#undef ZREADD
#define ZREADD(port) (scc[port]->csr=0x08, scc[port]->csr )
#undef ZWRITE
#define ZWRITE(port, n, v) (ZWRITE0(port, n), ZWRITE0(port, v))
#undef ZWRITED
#define ZWRITED(port, v) (scc[port]->csr = 0x08, \
scc[port]->csr = (unsigned char)(v))
static ReceiverBuffer receiverBuffer[NPORTS];
/*
* Control flags (DTR/DCD/RTS/CTS)
*/
static unsigned char wr4[NPORTS];
static unsigned char wr5[NPORTS];
#define SCCSetDTR(port) ZWRITE(port, 5, (wr5[port] |= 0x80))
#define SCCResetDTR(port) ZWRITE(port, 5, (wr5[port] &= ~0x80))
#define SCCSetRTS(port) ZWRITE(port, 5, (wr5[port] |= 0x02))
#define SCCResetRTS(port) ZWRITE(port,5, (wr5[port] &= ~0x02))
#define SCCGetDCD(port) (ZREAD0(port)&0x08)
#define SCCGetCTS(port) (ZREAD0(port)&0x20)
/*
* Interrupt handler for receiver interrupts
*/
static rtems_isr SCCReceiverISR(rtems_vector_number vector)
{
register int ipend, port;
port = (vector-SCC_VECTOR)*2;
ZWRITE0(port, 0x38); /* reset highest IUS */
ipend = ZREAD(port, 3); /* read int pending from A side */
if(ipend == 0x04)
port++; /* channel B intr pending */
else if(ipend == 0x20)
; /* channel A intr pending */
else
return;
ReceiverBufferAdd(&receiverBuffer[port], ZREADD(port));
if(ZREAD(port,1) & 0x70){ /* check error stat */
ZWRITE0(port, 0x30); /* reset error */
}
if(ReceiverBufferIsNearFull(&receiverBuffer[port]))
SCCResetRTS(port);
}
/*
* Initialize
*/
void SCCInitialize()
{
int i;
for(i = PORTFROM; i < NPORTS; i+=2)
ZWRITE(i, 9,0xc0); /* Reset SCC Chip */
for(i = PORTFROM; i < NPORTS; i++){
ReceiverBufferInitialize(&(receiverBuffer[i]));
wr4[i] = 0x44;
ZWRITE(i, 4, wr4[i]); /* x16 clock, 1 stop, parity none */
ZWRITE(i, 1, 0); /* disable interrupts */
ZWRITE(i, 2, SCC_VECTOR+(i/2));
ZWRITE(i, 3, 0xc1); /* receiver enable, 8bits */
wr5[i] = 0x68;
ZWRITE(i, 5, wr5[i]); /* transmitter enable, 8bits, DTR&RTS off */
ZWRITE(i,14, 0); /* stop baudrate gen. */
ZWRITE(i,11,0x50); /* use baurate gen. */
ZWRITE(i,15, 1); /* Select WR7' */
ZWRITE(i, 7, 0); /* Disable all special interrupts */
ZWRITE(i,10, 0);
ZWRITE(i, 1, 0x10); /* int on all Rx chars or special condition */
set_vector(SCCReceiverISR, SCC_VECTOR+(i/2), 1); /* install ISR */
ZWRITE(i, 9, 8); /* master interrupt enable */
ZWRITE(i,12,TC38400&0xff); /* set 38400 baud */
ZWRITE(i,13,TC38400>>8);
ZWRITE(i,14, 3); /* start baudrate gen. */
/* CAUTION: If your SCC use XTAL on RTxC,
write 1 */
}
mcchip->vector_base = 0;
mcchip->gen_control = 2; /* MIEN */
mcchip->SCC_int_ctl = 0x13; /* SCC IEN, IPL3 */
}
/*
* Non-blocking char input
*/
rtems_boolean SCCGetOne(int port, char *ch)
{
int retry = READRETRY;
while(ReceiverBufferIsEmpty(&receiverBuffer[port]))
if(--retry <= 0)
return FALSE;
ReceiverBufferRemove(&receiverBuffer[port],*ch);
if(ReceiverBufferIsNearEmpty(&receiverBuffer[port]))
SCCSetRTS(port);
return TRUE;
}
/*
* Blocking char input
*/
char SCCGetOneBlocked(int port)
{
unsigned char tmp_char;
while (!SCCGetOne(port, &tmp_char))
rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
return tmp_char;
}
/*
* Non-blocking char input
* No longer supports XON/XOFF flow control.
*/
rtems_boolean SCCSendOne(int port, char ch)
{
int retry = WRITERETRY;
if(!SCCGetCTS(port))
return FALSE;
while(!(ZREAD0(port) & TX_BUFFER_EMPTY))
if(--retry <= 0)
return FALSE;
ZWRITED(port, ch);
return TRUE;
}
/*
* Blocking char output
* No longer supports XON/XOFF flow control.
*/
void SCCSendOneBlocked(int port, char ch)
{
while(!SCCSendOne(port, ch))
rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
}
/*
* Set parameters for transmission
*/
unsigned32 SCCSetAttributes(int port, struct termios *t)
{
unsigned char wr3;
ZWRITE(port,1,0); /* Disable interrupt */
ZWRITE(port,3,0); /* Disable receiver */
/* Baud */
switch(t->c_cflag & CBAUD){
case B38400:
ZWRITE(port,12,TC38400&0xff);
ZWRITE(port,13,TC38400>>8);
break;
case B19200:
ZWRITE(port,12,TC19200&0xff);
ZWRITE(port,13,TC19200>>8);
break;
case B9600:
ZWRITE(port,12,TC9600&0xff);
ZWRITE(port,13,TC9600>>8);
break;
}
/* Code size */
wr5[port] &= 0x8f;
wr3 = 0; /* receiver control */
switch(t->c_cflag & CSIZE){
case CS8:
wr5[port] |= 0x60;
wr3 |= 0xc0;
break;
case CS7:
wr5[port] |= 0x20;
wr3 |= 0x40;
break;
}
/* Parity */
wr4[port] &= 0xf0;
if(t->c_cflag & PARENB)
wr4[port] |= 0x01;
if(!(t->c_cflag & PARODD))
wr4[port] |= 0x02;
/* ZWRITE(port,4,wr4[port]);*/
/* Stop bits */
/* wr4[port] = ZREAD(port,4) & 0xfc;*/
if(t->c_cflag & CSTOPB)
wr4[port] |= 0x0c;
else
wr4[port] |= 0x04;
ZWRITE(port,4,wr4[port]); /* TxRx parameters */
ZWRITE(port,5,wr5[port]); /* Transmission parameters */
ZWRITE(port,3,wr3|0x01); /* Enable receiver */
ZWRITE(port,1,0x10); /* Enable interrupt */
return 0;
}
/*
* Get parameters for transmission
*/
unsigned32 SCCGetAttributes(int port, struct termios *t)
{
unsigned32 b;
t->c_cflag = 0;
/* Baud */
b = ZREAD(port,13);
b <<= 8;
b |= ZREAD(port,12);
switch(b){
case TC38400:
t->c_cflag |= B38400;
break;
case TC19200:
t->c_cflag |= B19200;
break;
case TC9600:
t->c_cflag |= B9600;
break;
}
/* Code size */
/* wr = ZREAD(port,5);*/
t->c_cflag &= ~CSIZE;
switch(wr5[port]&0x60){
case 0x60:
t->c_cflag |= CS8;
break;
case 0x20:
t->c_cflag |= CS7;
break;
}
/* Parity */
/* wr = ZREAD(port,4);*/
if(wr4[port] & 0x01)
t->c_cflag |= PARENB;
else
t->c_cflag &= ~PARENB;
if(wr4[port] & 0x02)
t->c_cflag &= ~PARODD;
else
t->c_cflag |= PARODD;
/* Stop bits */
/* wr = ZREAD(port,4);*/
if((wr4[port]&0xc0) == 0xc0)
t->c_cflag |= CSTOPB;
else
t->c_cflag &= ~CSTOPB;
return 0;
}
/***********************************************************************
DEVICE INDEPENDED PART
***********************************************************************/
#define LOCAL_ISTRIP 0x0001
#define LOCAL_INLCR 0x0002
#define LOCAL_IGNCR 0x0004
#define LOCAL_ICRNL 0x0008
#define LOCAL_IUCLC 0x0010
#define LOCAL_OLCUC 0x0020
#define LOCAL_ONLCR 0x0040
#define LOCAL_OCRNL 0x0080
#define LOCAL_ICANON 0x0100
#define LOCAL_ECHO 0x0200
/*
* Device initialize entry point
*/
rtems_device_driver consolex_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code status;
char devname[16];
int i;
SCCInitialize();
#ifdef CONSOLEPORT
status = rtems_io_register_name("/dev/console",major,
(rtems_device_minor_number) CONSOLEPORT);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(status);
#endif
for(i = PORTFROM; i < NPORTS; i++){
/* Register cooked ttys */
sprintf(devname,"/dev/%s%02d",DEVICEPREFIX,i);
status = rtems_io_register_name(strdup(devname),major,
(rtems_device_minor_number) i);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(status);
/* Register raw ttys */
sprintf(devname,"/dev/%s%02d",RAWDEVICEPREFIX,i);
status = rtems_io_register_name(strdup(devname),major,
(rtems_device_minor_number) i+NPORTS);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(status);
}
for(i = 0; i < NPORTS; i++){
opencount[i] = 0;
}
return RTEMS_SUCCESSFUL;
}
/*
* Open entry point
*/
rtems_device_driver consolex_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_libio_open_close_args_t *openargs = (rtems_libio_open_close_args_t *) arg;
if(minor >= NPORTS)
minor -= NPORTS;
if(minor >= NPORTS)
return RTEMS_INVALID_NUMBER;
if(opencount[minor]++ == 0){
/* first open */
SCCSetDTR(minor);
SCCSetRTS(minor);
}
openargs->iop->data0 = LOCAL_ICRNL|LOCAL_ONLCR|LOCAL_ICANON|LOCAL_ECHO;
return RTEMS_SUCCESSFUL;
}
/*
* Close entry point
*/
rtems_device_driver consolex_close(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
if(minor >= NPORTS)
minor -= NPORTS;
if(minor >= NPORTS)
return RTEMS_INVALID_NUMBER;
if(--(opencount[minor]) == 0){
/* closed all */
SCCResetRTS(minor);
SCCResetDTR(minor);
}
return RTEMS_SUCCESSFUL;
}
/*
* read bytes from the serial port.
*/
rtems_device_driver consolex_read_raw(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
char *buffer;
int count;
if(minor >= NPORTS)
return RTEMS_INVALID_NUMBER;
buffer = rw_args->buffer;
count = rw_args->count;
if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
/* Non blocking read */
while(count){
if(!SCCGetOne(minor,buffer))
break;
buffer++;
count--;
}
}else{
/* Blocking read */
while(count){
*buffer = SCCGetOneBlocked(minor);
buffer++;
count--;
}
}
rw_args->bytes_moved = rw_args->count-count;
return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
}
rtems_device_driver consolex_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
char *buffer;
int count;
unsigned32 mode;
if(minor >= NPORTS)
return consolex_read_raw(major,minor-NPORTS,arg);
buffer = rw_args->buffer;
count = rw_args->count;
mode = rw_args->iop->data0;
/* Cooked read */
while(count){
if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
/* Non blocking read */
if(!SCCGetOne(minor,buffer))
break;
}else{
/* Blocking read */
*buffer = SCCGetOneBlocked(minor);
}
if((mode&LOCAL_ICANON) && (*buffer == '\b')){
if(buffer > (char *)(rw_args->buffer)){
buffer--;
count++;
if(mode&LOCAL_ECHO){
SCCSendOneBlocked(minor,'\b');
SCCSendOneBlocked(minor,' ');
SCCSendOneBlocked(minor,'\b');
}
}
continue;
}
if((mode&LOCAL_IGNCR) && (*buffer == '\r'))
continue;
if((mode&LOCAL_INLCR) && (*buffer == '\n'))
*buffer = '\r';
if((mode&LOCAL_ICRNL) && (*buffer == '\r'))
*buffer = '\n';
if((mode&LOCAL_IUCLC) && isupper((int)*buffer))
*buffer = tolower(*buffer);
if(mode&LOCAL_ISTRIP)
*buffer &= 0x7f;
if(mode&LOCAL_ECHO){
/* Caution: Echo back is blocking output */
SCCSendOneBlocked(minor,*buffer);
}
if((mode&LOCAL_ICANON) && (*buffer == '\n')){
buffer++;
count--;
if(count)
*buffer = 0;
if((mode&LOCAL_ECHO)&&(mode&LOCAL_ONLCR))
SCCSendOneBlocked(minor,'\r');
break; /* finish reading */
}
buffer++;
count--;
}
rw_args->bytes_moved = rw_args->count-count;
return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
}
/*
* write bytes to the serial port.
*/
rtems_device_driver consolex_write_raw(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
char *buffer;
int count;
if(minor >= NPORTS)
return RTEMS_INVALID_NUMBER;
buffer = rw_args->buffer;
count = rw_args->count;
if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
/* Non blocking write */
while(count){
if(!SCCSendOne(minor,*buffer))
break;
buffer++;
count--;
}
}else{
/* Blocking write */
while(count){
SCCSendOneBlocked(minor,*buffer);
buffer++;
count--;
}
}
rw_args->bytes_moved = rw_args->count-count;
return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
}
rtems_device_driver consolex_write(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
char *buffer;
int count;
char ch;
unsigned32 mode;
if(minor >= NPORTS)
return consolex_write_raw(major,minor-NPORTS,arg);
buffer = rw_args->buffer;
count = rw_args->count;
mode = rw_args->iop->data0;
/* Cooked write */
while(count){
ch = *buffer;
if((mode&LOCAL_ONLCR) && (ch == '\n')){ /* Output CRLF */
if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
/* Non blocking write */
if(!SCCSendOne(minor,'\r'))
break;
}else{
SCCSendOneBlocked(minor,'\r');
}
}
if((mode&LOCAL_OCRNL) && (ch == '\r'))
ch = '\n';
if((mode&OLCUC) && (islower((int)ch)))
ch = toupper(ch);
if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
/* Non blocking write */
if(!SCCSendOne(minor,ch))
break;
}else{
SCCSendOneBlocked(minor,ch);
}
buffer++;
count--;
}
rw_args->bytes_moved = rw_args->count-count;
return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
}
/*
* IO Control entry point
*/
rtems_device_driver consolex_control(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *)arg;
struct termios *tm = ioarg->buffer;
unsigned32 *mode = &(ioarg->iop->data0);
if(minor >= NPORTS)
minor -= NPORTS;
if(minor >= NPORTS)
return RTEMS_INVALID_NUMBER;
switch(ioarg->command){
case RTEMS_IO_GET_ATTRIBUTES:
tm->c_iflag = tm->c_oflag = tm->c_cflag = tm->c_lflag = 0;
if(*mode & LOCAL_ISTRIP)
tm->c_iflag |= ISTRIP;
if(*mode & LOCAL_INLCR)
tm->c_iflag |= INLCR;
if(*mode & LOCAL_IGNCR)
tm->c_iflag |= IGNCR;
if(*mode & LOCAL_ICRNL)
tm->c_iflag |= ICRNL;
if(*mode & LOCAL_IUCLC)
tm->c_iflag |= IUCLC;
if(*mode & LOCAL_OLCUC)
tm->c_oflag |= OLCUC;
if(*mode & LOCAL_ONLCR)
tm->c_oflag |= ONLCR;
if(*mode & LOCAL_OCRNL)
tm->c_oflag |= OCRNL;
if(*mode & LOCAL_ICANON)
tm->c_lflag |= ICANON;
if(*mode & LOCAL_ECHO)
tm->c_lflag |= ECHO;
ioarg->ioctl_return = SCCGetAttributes(minor,tm);
break;
case RTEMS_IO_SET_ATTRIBUTES:
*mode = 0;
if(tm->c_iflag & ISTRIP)
*mode |= LOCAL_ISTRIP;
if(tm->c_iflag & INLCR)
*mode |= LOCAL_INLCR;
if(tm->c_iflag & IGNCR)
*mode |= LOCAL_IGNCR;
if(tm->c_iflag & ICRNL)
*mode |= LOCAL_ICRNL;
if(tm->c_iflag & IUCLC)
*mode |= LOCAL_IUCLC;
if(tm->c_oflag & OLCUC)
*mode |= LOCAL_OLCUC;
if(tm->c_oflag & ONLCR)
*mode |= LOCAL_ONLCR;
if(tm->c_oflag & OCRNL)
*mode |= LOCAL_OCRNL;
if(tm->c_lflag & ICANON)
*mode |= LOCAL_ICANON;
if(tm->c_lflag & ECHO)
*mode |= LOCAL_ECHO;
ioarg->ioctl_return = SCCSetAttributes(minor,tm);
break;
default:
return RTEMS_NOT_DEFINED;
}
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,93 +0,0 @@
/* consolex.h
*
* This file describes the Extended Console Device Driver
* This driver provides support for the standard C Library.
*
* This file was created originally by
* On-Line Applications Research Corporation (OAR)
* and modified by:
*
* Katsutoshi Shibuya - BU-Denken Co.,Ltd. - Sapporo, JAPAN
*
* featuring support of:
*
* - Multi-SCC chip handling
* - Non-blocking I/O (O_NDELAY flag in libc)
* - Raw mode device (no CR/LF detection)
* - RTS/CTS flow control
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifndef _CONSOLEX_DRIVER_h
#define _CONSOLEX_DRIVER_h
#include <rtems.h>
#include <termios.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CONSOLEX_DRIVER_TABLE_ENTRY \
{ consolex_initialize, consolex_open, consolex_close, \
consolex_read, consolex_write, consolex_control }
rtems_device_driver consolex_initialize(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver consolex_open(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver consolex_close(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver consolex_read(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver consolex_write(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver consolex_control(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
/* Low level IO functions */
void SCCInitialize();
rtems_boolean SCCGetOne(int port, char *ch);
char SCCGetOneBlocked(int port);
rtems_boolean SCCSendOne(int port, char ch);
void SCCSendOneBlocked(int port, char ch);
unsigned32 SCCSetAttributes(int port, struct termios *t);
unsigned32 SCCGetAttributes(int port, struct termios *t);
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */