1
0
mirror of https://github.com/Interlisp/maiko.git synced 2026-01-18 17:07:24 +00:00
Interlisp.maiko/src/rawrs232c.c
Bruce Mitchener 33369268c1
Include termios as <termios.h>, not <sys/...>. (#118)
termios is available via `<termios.h>` on all supported platforms,
so variants of `<sys/termio.h>` and `<sys/termios.h>` are no
longer needed.
2020-12-22 22:56:54 -08:00

305 lines
6.9 KiB
C

/* $Id: rawrs232c.c,v 1.2 1999/01/03 02:07:31 sybalsky Exp $ (C) Copyright Venue, All Rights
* Reserved */
/************************************************************************/
/* */
/* (C) Copyright 1989-95 Venue. All Rights Reserved. */
/* Manufactured in the United States of America. */
/* */
/************************************************************************/
#include "version.h"
#include <sys/select.h>
#include <sys/types.h>
#include <sys/ttold.h>
#include <sys/time.h>
#include <stropts.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <termios.h>
#include "lispemul.h"
#include "address.h"
#include "adr68k.h"
#include "lsptypes.h"
#include "lispmap.h"
#include "emlglob.h"
#include "lspglob.h"
#include "debug.h"
#include "rawrs232c.h"
#define MIN_CHARS 256
#define MIN_TIME 1
/************************************************************/
/*
raw232c.c
Access RS device from Lisp by using FD
This provides low-level access to RS device.
Created: Feb.12 1991
By Takeshi Shimizu
CopyRight Fuji Xerox Co., LTD 1991
*/
/************************************************************/
LispPTR raw_rs232c_open(LispPTR portname)
{
ONED_ARRAY *head;
char *lispname;
int fd;
if (GetTypeNumber(portname) != TYPE_ONED_ARRAY) error("PORTNAME is not string");
head = (ONED_ARRAY *)Addr68k_from_LADDR(portname);
lispname = (char *)Addr68k_from_LADDR(head->BASE);
if ((fd = open(lispname, O_RDWR)) < 0) {
perror("RS open fail: ");
return (NIL);
}
return (S_POSITIVE | fd);
} /* raw_rs232c_open */
LispPTR raw_rs232c_setparams(LispPTR fd, LispPTR data)
{
RawRSParam *ndata;
struct termios termdata;
/* Get Current params */
if (ioctl((fd & 0xffff), TCGETS, &termdata) < 0) {
perror("RS get params:");
return (NIL);
}
ndata = (RawRSParam *)Addr68k_from_LADDR(data);
/* Input */
termdata.c_iflag |= IXON | IXOFF;
termdata.c_iflag &= ~(INPCK);
/*termdata.c_iflag &= ~IGNBRK;*/
termdata.c_iflag &= ~IGNPAR;
termdata.c_iflag &= ~IUCLC;
if (ndata->InEOL == RAW_RS_CR) {
termdata.c_iflag |= INLCR;
termdata.c_iflag &= ~ICRNL;
}
else if (ndata->InEOL == RAW_RS_LF) {
termdata.c_iflag &= ~INLCR;
termdata.c_iflag |= ICRNL;
} else if (ndata->InEOL == RAW_RS_CRLF) {
termdata.c_iflag &= ~INLCR;
termdata.c_iflag &= ~ICRNL;
}
/* Flow CNT */
if ((ndata->FlowCnt & 0xff) == RAW_RS_XON)
termdata.c_iflag |= IXON | IXOFF;
else {
termdata.c_iflag &= ~(IXON | IXOFF);
}
termdata.c_iflag &= ~(ISTRIP);
/* Output */
termdata.c_oflag |= ~OPOST;
termdata.c_oflag &= ~OLCUC;
termdata.c_oflag &= ~OFILL;
termdata.c_oflag &= ~OFDEL;
termdata.c_oflag &= ~NLDLY;
termdata.c_oflag &= ~CRDLY;
termdata.c_oflag &= ~BSDLY;
termdata.c_oflag &= ~VTDLY;
termdata.c_oflag &= ~FFDLY;
if (ndata->OutEOL == RAW_RS_CR) {
termdata.c_oflag |= ONLRET;
termdata.c_oflag &= ~OCRNL;
termdata.c_oflag &= ~ONLCR;
} else if (ndata->OutEOL == RAW_RS_LF) {
termdata.c_oflag &= ~ONLRET;
termdata.c_oflag |= OCRNL;
termdata.c_oflag &= ~ONLCR;
} else if (ndata->OutEOL == RAW_RS_CRLF) {
termdata.c_oflag &= ~ONLRET;
termdata.c_oflag &= ~OCRNL;
termdata.c_oflag |= ONLCR;
}
/* LOCAL */
termdata.c_lflag &= ~ISIG;
termdata.c_lflag &= ~ICANON;
termdata.c_lflag &= ~XCASE;
if (ndata->Echo == ATOM_T)
termdata.c_lflag |= ECHO;
else
termdata.c_lflag &= ~ECHO;
termdata.c_lflag &= ~ECHOE;
termdata.c_lflag &= ~ECHOK;
termdata.c_lflag &= ~ECHONL;
termdata.c_lflag &= ~NOFLSH;
termdata.c_lflag &= ~TOSTOP;
termdata.c_lflag &= ~ECHOCTL;
termdata.c_lflag &= ~ECHOPRT;
termdata.c_lflag &= ~ECHOKE;
termdata.c_lflag &= ~FLUSHO;
termdata.c_lflag &= ~PENDIN;
/* Minimum and Timeout */
termdata.c_cc[VMIN] = MIN_CHARS;
termdata.c_cc[VTIME] = MIN_TIME;
/* Control */
termdata.c_cflag = (CREAD | HUPCL);
/* Local or DialUP */
if (ndata->LocalLine == ATOM_T)
termdata.c_cflag |= CLOCAL;
else
termdata.c_cflag &= ~CLOCAL;
/* Bau Rate */
if (ndata->BauRate != NIL) {
switch (ndata->BauRate & 0xffff) {
case 1200: termdata.c_cflag |= B1200; break;
case 2400: termdata.c_cflag |= B2400; break;
case 4800: termdata.c_cflag |= B4800; break;
case 9600: termdata.c_cflag |= 96200; break;
default: termdata.c_cflag |= B1200;
}
}
/* CTS/RTS */
if ((ndata->RTSCTSCnt & 0xff) == ATOM_T)
termdata.c_cflag |= CRTSCTS;
else
termdata.c_cflag &= ~CRTSCTS;
/* Character size */
if ((ndata->BitsPerChar & 0xf) == 7)
termdata.c_cflag |= CS7;
else if ((ndata->BitsPerChar & 0xf) == 8)
termdata.c_cflag |= CS8;
else {
error("RS232:Not supported char size");
return (NIL);
}
/* Parity */
if ((ndata->Parity & 0xf) == RAW_RS_NONE) {
termdata.c_iflag &= (~(INPCK));
termdata.c_cflag &= (~PARENB);
} else if ((ndata->Parity & 0xf) == RAW_RS_EVEN)
termdata.c_cflag |= PARENB;
else if ((ndata->Parity & 0xf) == RAW_RS_ODD)
termdata.c_cflag |= (PARENB | PARODD);
/* Stop bits */
if ((ndata->NoOfStopBits & 0x2) == 2)
termdata.c_cflag |= CSTOPB;
else
termdata.c_cflag &= ~(CSTOPB);
/* Set parameters */
if (ioctl((fd & 0xffff), TCSETS, &termdata) < 0) {
perror("RS set params");
return (NIL);
}
return (ATOM_T);
} /* raw_rs232c_setparams */
LispPTR raw_rs232c_close(LispPTR fd)
{
if (close(0xffff & fd) < 0) {
perror("RS close : ");
return (NIL);
} else
return (ATOM_T);
}
LispPTR raw_rs232c_write(LispPTR fd, LispPTR baseptr, LispPTR len)
{
unsigned char *ptr;
ptr = (unsigned char *)Addr68k_from_LADDR(baseptr);
if (write((fd & 0xffff), ptr, (len & 0xffff)) < 0) {
perror("RS-write :");
return (NIL);
}
return (ATOM_T);
}
/* Assume numbers are SMALLPOSP */
struct timeval RS_TimeOut = {0, 0};
LispPTR raw_rs232c_read(LispPTR fd, LispPTR buff, LispPTR nbytes)
{
unsigned char *buffptr;
int length;
u_int real_fd;
fd_set readfds;
real_fd = fd & 0xffff; /* FIXME: should be GetSmallp() ? */
FD_SET(real_fd, &readfds);
select(32, &readfds, NULL, NULL, &RS_TimeOut);
if (FD_ISSET(real_fd, &readfds)) {
buffptr = (unsigned char *)Addr68k_from_LADDR(buff);
if ((length = read(real_fd, buffptr, (nbytes & 0xffff))) < 0) {
perror("RS read :");
return (NIL);
} else {
Irq_Stk_End = Irq_Stk_Check = 0;
return (S_POSITIVE | length);
}
}
return (S_POSITIVE); /* There is nothing to read */
} /* raw_rs232c_read */
LispPTR raw_rs232c_setint(LispPTR fd, LispPTR onoff)
{
extern fd_set LispReadFds;
extern fd_set LispIOFds;
u_int real_fd;
real_fd = (fd & 0xffff); /* FIXME: should be GetSmallp() */
if (onoff == ATOM_T) {
FD_SET(real_fd, &LispReadFds);
FD_SET(real_fd, &LispIOFds);
int_io_open(real_fd);
} else {
int_io_close(real_fd);
FD_CLR(real_fd, &LispReadFds);
FD_CLR(real_fd, &LispIOFds);
}
return (ATOM_T);
}