/* $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 #include #include #include #include #include #include #include #include #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 *)NativeAligned4FromLAddr(portname); lispname = (char *)NativeAligned2FromLAddr(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 *)NativeAligned4FromLAddr(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 *)NativeAligned2FromLAddr(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 *)NativeAligned2FromLAddr(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); }