forked from Imagelibrary/rtems
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:
@@ -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.
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
Reference in New Issue
Block a user