home *** CD-ROM | disk | FTP | other *** search
- /*
- ** SerialIO.c
- **
- ** Serial read/write routines
- **
- ** Copyright © 1990-1996 by Olaf `Olsen' Barthel
- ** All Rights Reserved
- **
- ** :ts=4
- */
-
- #ifndef _GLOBAL_H
- #include "Global.h"
- #endif
-
- STATIC BOOL ReadQueued = FALSE,
- WriteQueued = FALSE;
-
- STATIC UBYTE *QueueReadBuffer;
- STATIC LONG QueueReadSize;
-
- /* ResetSerialRead():
- *
- * Reset the read status.
- */
-
- VOID
- ResetSerialRead()
- {
- ReadQueued = FALSE;
- QueueReadBuffer = NULL;
- QueueReadSize = 0;
- }
-
- /* CheckSerialRead():
- *
- * Check if a read request is finished.
- */
-
- BOOL
- CheckSerialRead()
- {
- if(ReadRequest && ReadQueued)
- {
- if(CheckIO((struct IORequest *)ReadRequest))
- return(TRUE);
- }
-
- return(FALSE);
- }
-
- /* WaitSerialRead():
- *
- * Wait for the read request to terminate.
- */
-
- BYTE
- WaitSerialRead()
- {
- if(ReadRequest && ReadQueued)
- {
- ReadQueued = FALSE;
- QueueReadBuffer = NULL;
- QueueReadSize = 0;
-
- return(WaitIO((struct IORequest *)ReadRequest));
- }
- else
- return(0);
- }
-
- /* FlushSerialRead():
- *
- * Forget about the current contents of the serial
- * read buffer.
- */
-
- BYTE
- FlushSerialRead()
- {
- if(ReadRequest)
- {
- UBYTE *WasQueueReadBuffer;
- LONG WasQueueReadSize;
- BOOL WasReading;
-
- WasReading = ReadQueued;
- WasQueueReadBuffer = QueueReadBuffer;
- WasQueueReadSize = QueueReadSize;
-
- StopSerialRead();
-
- DoSerialCmd(CMD_CLEAR);
-
- if(WasReading)
- StartSerialRead(WasQueueReadBuffer,WasQueueReadSize);
- }
-
- return(0);
- }
-
- /* DoSerialBreak():
- *
- * Send a break signal.
- */
-
- BYTE
- DoSerialBreak()
- {
- if(WriteRequest)
- {
- UBYTE *WasQueueReadBuffer;
- LONG WasQueueReadSize;
- BOOL WasReading;
-
- WasReading = ReadQueued;
- WasQueueReadBuffer = QueueReadBuffer;
- WasQueueReadSize = QueueReadSize;
-
- StopSerialRead();
-
- DoSerialCmd(SDCMD_BREAK);
-
- if(WasReading)
- StartSerialRead(WasQueueReadBuffer,WasQueueReadSize);
- }
-
- return(0);
- }
-
- /* CompletelyFlushSerialRead():
- *
- * Flush the serial read buffer over and over again until
- * no more data comes in.
- */
-
- VOID
- CompletelyFlushSerialRead()
- {
- if(ReadRequest && WriteRequest)
- {
- UBYTE *WasQueueReadBuffer;
- LONG WasQueueReadSize;
- BOOL WasReading;
-
- WasReading = ReadQueued;
- WasQueueReadBuffer = QueueReadBuffer;
- WasQueueReadSize = QueueReadSize;
-
- StopSerialRead();
-
- do
- {
- DoSerialCmd(CMD_CLEAR);
-
- DelayTime(1,0);
- }
- while(GetSerialWaiting());
-
- if(WasReading)
- StartSerialRead(WasQueueReadBuffer,WasQueueReadSize);
- }
- }
-
- /* StopSerialRead():
- *
- * Force a read request to terminate.
- */
-
- VOID
- StopSerialRead()
- {
- if(ReadRequest && ReadQueued)
- {
- if(!CheckIO((struct IORequest *)ReadRequest))
- AbortIO((struct IORequest *)ReadRequest);
-
- WaitIO((struct IORequest *)ReadRequest);
-
- ReadQueued = FALSE;
- QueueReadBuffer = NULL;
- QueueReadSize = 0;
- }
- }
-
- /* StartSerialRead(ULONG Length,APTR Data):
- *
- * Start a serial read request asynchronously.
- */
-
- VOID
- StartSerialRead(APTR Data,ULONG Length)
- {
- if(ReadRequest)
- {
- if(ReadQueued)
- StopSerialRead();
-
- ReadRequest->IOSer.io_Command = CMD_READ;
- ReadRequest->IOSer.io_Length = Length;
- ReadRequest->IOSer.io_Data = Data;
-
- ClrSignal(1L << ReadPort->mp_SigBit);
-
- SendIO((struct IORequest *)ReadRequest);
-
- ReadQueued = TRUE;
- QueueReadBuffer = Data;
- QueueReadSize = Length;
- }
- }
-
- /* DoSerialRead(ULONG Length,APTR Data):
- *
- * Perform a read request synchronously.
- */
-
- BYTE
- DoSerialRead(APTR Data,ULONG Length)
- {
- if(ReadRequest)
- {
- if(ReadQueued)
- StopSerialRead();
-
- ReadRequest->IOSer.io_Command = CMD_READ;
- ReadRequest->IOSer.io_Length = Length;
- ReadRequest->IOSer.io_Data = Data;
-
- return(DoIO((struct IORequest *)ReadRequest));
- }
- else
- return(IOERR_SELFTEST);
- }
-
- /* ResetSerialWrite():
- *
- * Reset the write status.
- */
-
- VOID
- ResetSerialWrite()
- {
- WriteQueued = FALSE;
- }
-
- /* WaitSerialWrite():
- *
- * Wait for the write request to terminate.
- */
-
- BYTE
- WaitSerialWrite()
- {
- if(WriteRequest && WriteQueued)
- {
- WriteQueued = FALSE;
-
- return(WaitIO((struct IORequest *)WriteRequest));
- }
- else
- return(0);
- }
-
- /* StopSerialWrite():
- *
- * Force a write request to terminate.
- */
-
- VOID
- StopSerialWrite()
- {
- if(WriteRequest && WriteQueued)
- {
- if(!CheckIO((struct IORequest *)WriteRequest))
- AbortIO((struct IORequest *)WriteRequest);
-
- WaitIO((struct IORequest *)WriteRequest);
-
- WriteQueued = FALSE;
- }
- }
-
- /* StartSerialWrite(ULONG Length,APTR Data):
- *
- * Start a serial write request asynchronously.
- */
-
- VOID
- StartSerialWrite(APTR Data,ULONG Length)
- {
- if(WriteRequest)
- {
- if(WriteQueued)
- StopSerialWrite();
-
- WriteRequest->IOSer.io_Command = CMD_WRITE;
- WriteRequest->IOSer.io_Length = Length;
- WriteRequest->IOSer.io_Data = Data;
-
- ClrSignal(1L << WriteRequest->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
-
- SendIO((struct IORequest *)WriteRequest);
-
- WriteQueued = TRUE;
- }
- }
-
- /* DoSerialWrite(ULONG Length,APTR Data):
- *
- * Perform a write request synchronously.
- */
-
- BYTE
- DoSerialWrite(APTR Data,ULONG Length)
- {
- if(WriteRequest)
- {
- if(WriteQueued)
- StopSerialWrite();
-
- WriteRequest->IOSer.io_Command = CMD_WRITE;
- WriteRequest->IOSer.io_Length = Length;
- WriteRequest->IOSer.io_Data = Data;
-
- return(DoIO((struct IORequest *)WriteRequest));
- }
- else
- return(IOERR_SELFTEST);
- }
-
- /* DoSerialCmd(UWORD Command):
- *
- * Perform single command.
- */
-
- BYTE
- DoSerialCmd(LONG Command)
- {
- if(WriteRequest)
- {
- if(WriteQueued)
- StopSerialWrite();
-
- WriteRequest->IOSer.io_Command = Command;
-
- return(DoIO((struct IORequest *)WriteRequest));
- }
- else
- return(IOERR_SELFTEST);
- }
-
- /* GetSerialWaiting():
- *
- * Query the number of bytes still waiting to be read
- * from the serial port.
- */
-
- ULONG
- GetSerialWaiting()
- {
- ULONG Waiting;
-
- Waiting = 0;
-
- if(ReadQueued)
- {
- if(!CheckSerialRead())
- return(0);
- else
- Waiting += ReadRequest->IOSer.io_Actual;
- }
-
- if(WriteRequest)
- {
- if(WriteQueued)
- StopSerialWrite();
-
- WriteRequest->IOSer.io_Command = SDCMD_QUERY;
-
- DoIO((struct IORequest *)WriteRequest);
-
- Waiting += WriteRequest->IOSer.io_Actual;
- }
-
- return(Waiting);
- }
-
- /* GetSerialStatus():
- *
- * Query the current serial port status.
- */
-
- LONG
- GetSerialStatus()
- {
- if(WriteRequest)
- {
- if(WriteQueued)
- StopSerialWrite();
-
- WriteRequest->IOSer.io_Command = SDCMD_QUERY;
-
- DoIO((struct IORequest *)WriteRequest);
-
- return(WriteRequest->io_Status);
- }
- else
- return(CIAF_COMCD | CIAF_COMDSR);
- }
-
- /* GetSerialInfo(ULONG *Waiting,UWORD *Status):
- *
- * Query both the number of bytes waiting to be read and
- * the current serial status.
- */
-
- VOID
- GetSerialInfo(ULONG *Waiting,UWORD *Status)
- {
- if(WriteRequest)
- {
- if(WriteQueued)
- StopSerialWrite();
-
- WriteRequest->IOSer.io_Command = SDCMD_QUERY;
-
- DoIO((struct IORequest *)WriteRequest);
-
- *Waiting = WriteRequest->IOSer.io_Actual;
- *Status = WriteRequest->io_Status;
- }
- else
- {
- *Waiting = 0;
- *Status = CIAF_COMCD | CIAF_COMDSR;
- }
- }
-
- /* SetSerialAttributes():
- *
- * Set the serial driver attributes.
- */
-
- STATIC VOID
- SetSerialAttributes(struct IOExtSer *Request,struct TagItem *Tags)
- {
- struct TagItem *Tag;
-
- while(Tag = NextTagItem(&Tags))
- {
- switch(Tag->ti_Tag)
- {
- case SERA_Baud:
-
- Request->io_Baud = Tag->ti_Data;
- break;
-
- case SERA_BreakTime:
-
- Request->io_BrkTime = Tag->ti_Data;
- break;
-
- case SERA_BitsPerChar:
-
- Request->io_ReadLen = Tag->ti_Data;
- Request->io_WriteLen = Tag->ti_Data;
- break;
-
- case SERA_StopBits:
-
- Request->io_StopBits = Tag->ti_Data;
- break;
-
- case SERA_BufferSize:
-
- Request->io_RBufLen = Tag->ti_Data;
- break;
-
- case SERA_Parity:
-
- Request->io_ExtFlags &= ~(SEXTF_MSPON | SEXTF_MARK);
- Request->io_SerFlags &= ~(SERF_PARTY_ON | SERF_PARTY_ODD);
-
- switch(Tag->ti_Data)
- {
- case PARITY_EVEN:
-
- Request->io_SerFlags |= SERF_PARTY_ON;
- break;
-
- case PARITY_ODD:
-
- Request->io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
- break;
-
- case PARITY_MARK:
-
- Request->io_SerFlags |= SERF_PARTY_ON;
- Request->io_ExtFlags |= SEXTF_MSPON | SEXTF_MARK;
- break;
-
- case PARITY_SPACE:
-
- Request->io_SerFlags |= SERF_PARTY_ON;
- Request->io_ExtFlags |= SEXTF_MSPON;
- break;
- }
-
- break;
-
- case SERA_Handshaking:
-
- if(Tag->ti_Data == HANDSHAKING_NONE)
- Request->io_SerFlags &= ~SERF_7WIRE;
- else
- Request->io_SerFlags |= SERF_7WIRE;
-
- break;
-
- case SERA_HighSpeed:
-
- if(Tag->ti_Data)
- Request->io_SerFlags |= SERF_RAD_BOOGIE;
- else
- Request->io_SerFlags &= ~SERF_RAD_BOOGIE;
-
- break;
-
- case SERA_Shared:
-
- if(Tag->ti_Data)
- Request->io_SerFlags |= SERF_SHARED;
- else
- Request->io_SerFlags &= ~SERF_SHARED;
-
- break;
- }
- }
-
- Request->io_SerFlags |= SERF_XDISABLED;
- }
-
- /* GetSerialAttributes():
- *
- * Get the serial driver attributes.
- */
-
- STATIC ULONG
- GetSerialAttributes(struct IOExtSer *Request,struct TagItem *Tags)
- {
- struct TagItem *Tag;
- ULONG *Data;
- ULONG Result;
-
- Result = NULL;
-
- while(Tag = NextTagItem(&Tags))
- {
- if(!(Data = (ULONG *)Tag->ti_Data))
- Data = &Result;
-
- switch(Tag->ti_Tag)
- {
- case SERA_Baud:
-
- *Data = Request->io_Baud;
- break;
-
- case SERA_BreakTime:
-
- *Data = Request->io_BrkTime;
- break;
-
- case SERA_BitsPerChar:
-
- *Data = Request->io_ReadLen;
- break;
-
- case SERA_StopBits:
-
- *Data = Request->io_StopBits;
- break;
-
- case SERA_BufferSize:
-
- *Data = Request->io_RBufLen;
- break;
-
- case SERA_Parity:
-
- Request->io_ExtFlags &= ~(SEXTF_MSPON | SEXTF_MARK);
- Request->io_SerFlags &= ~(SERF_PARTY_ON | SERF_PARTY_ODD);
-
- switch(Tag->ti_Data)
- {
- case PARITY_EVEN:
-
- Request->io_SerFlags |= SERF_PARTY_ON;
- break;
-
- case PARITY_ODD:
-
- Request->io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
- break;
-
- case PARITY_MARK:
-
- Request->io_SerFlags |= SERF_PARTY_ON;
- Request->io_ExtFlags |= SEXTF_MSPON | SEXTF_MARK;
- break;
-
- case PARITY_SPACE:
-
- Request->io_SerFlags |= SERF_PARTY_ON;
- Request->io_ExtFlags |= SEXTF_MSPON;
- break;
- }
-
- switch(Request->io_ExtFlags & (SEXTF_MSPON | SEXTF_MARK))
- {
- case SEXTF_MSPON | SEXTF_MARK:
-
- *Data = PARITY_MARK;
- break;
-
- case SEXTF_MSPON:
-
- *Data = PARITY_SPACE;
- break;
-
- default:
-
- switch(Request->io_SerFlags & (SERF_PARTY_ON | SERF_PARTY_ODD))
- {
- case SERF_PARTY_ON | SERF_PARTY_ODD:
-
- *Data = PARITY_ODD;
- break;
-
- case SERF_PARTY_ON:
-
- *Data = PARITY_EVEN;
- break;
-
- default:
-
- *Data = PARITY_NONE;
- break;
- }
-
- break;
- }
-
- break;
-
- case SERA_Handshaking:
-
- if(Request->io_SerFlags & SERF_7WIRE)
- *Data = TRUE;
- else
- *Data = FALSE;
-
- break;
-
- case SERA_HighSpeed:
-
- if(Request->io_SerFlags & SERF_RAD_BOOGIE)
- *Data = TRUE;
- else
- *Data = FALSE;
-
- break;
-
- case SERA_Shared:
-
- if(Request->io_SerFlags & SERF_SHARED)
- *Data = TRUE;
- else
- *Data = FALSE;
-
- break;
- }
- }
-
- return(Result);
- }
-
- /* SetBothSerialAttributes():
- *
- * Set the serial read driver parameters.
- */
-
- BYTE
- SetBothSerialAttributes(Tag FirstTag,...)
- {
- if(ReadRequest && WriteRequest)
- {
- BYTE Result;
-
- if(ReadQueued)
- StopSerialRead();
-
- if(WriteQueued)
- StopSerialWrite();
-
- SetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag);
-
- if(ReadRequest->IOSer.io_Device)
- {
- ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS;
-
- Result = DoIO((struct IORequest *)ReadRequest);
- }
- else
- Result = 0;
-
- if(!Result)
- {
- struct MsgPort *OldWritePort = WriteRequest->IOSer.io_Message.mn_ReplyPort;
-
- CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
-
- WriteRequest->IOSer.io_Message.mn_ReplyPort = OldWritePort;
- }
-
- return(Result);
- }
- else
- return(IOERR_SELFTEST);
- }
-
- /* SetSerialReadAttributes():
- *
- * Set the serial read driver parameters.
- */
-
- BYTE
- SetSerialReadAttributes(Tag FirstTag,...)
- {
- if(ReadRequest)
- {
- if(ReadQueued)
- StopSerialRead();
-
- SetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag);
-
- if(ReadRequest->IOSer.io_Device)
- {
- ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS;
-
- return(DoIO((struct IORequest *)ReadRequest));
- }
- else
- return(0);
- }
- else
- return(IOERR_SELFTEST);
- }
-
- /* GetSerialWriteAttributes():
- *
- * Get the serial write driver parameters.
- */
-
- ULONG
- GetSerialWriteAttributes(Tag FirstTag,...)
- {
- if(WriteRequest)
- return(GetSerialAttributes(WriteRequest,(struct TagItem *)&FirstTag));
- else
- return(NULL);
- }
-
- /* DropDTR(STRPTR Device,LONG Unit):
- *
- * Drops the DTR signal on the currently open device.
- */
-
- BOOL
- DropDTR(STRPTR Device,LONG Unit)
- {
- UBYTE *WasQueueReadBuffer;
- LONG WasQueueReadSize;
- BOOL WasReading;
-
- WasReading = ReadQueued;
- WasQueueReadBuffer = QueueReadBuffer;
- WasQueueReadSize = QueueReadSize;
-
- StopSerialRead();
-
- /* Do we have a valid environment? */
-
- if(WriteRequest)
- {
- /* We'll start with the special line signal control commands */
- /* as supported by the ASDG dual serial board. */
-
- WriteRequest->IOSer.io_Command = SIOCMD_SETCTRLLINES;
- WriteRequest->IOSer.io_Offset = SIOB_DTRF;
- WriteRequest->IOSer.io_Length = 0;
-
- if(!DoIO((struct IORequest *)WriteRequest))
- {
- /* Ok, so that did work. Now we wait a little... */
-
- DelayTime(1,0);
-
- /* And we raise the DTR signal again */
-
- WriteRequest->IOSer.io_Command = SIOCMD_SETCTRLLINES;
- WriteRequest->IOSer.io_Offset = SIOB_DTRF;
- WriteRequest->IOSer.io_Length = SIOB_DTRF;
-
- DoIO((struct IORequest *)WriteRequest);
- }
- else
- {
- /* So that didn't work; we'll have to open and close */
- /* the device in order to make the driver drop the */
- /* DTR signal. */
-
- CloseDevice((struct IORequest *)ReadRequest);
-
- /* Wait a little... */
-
- DelayTime(1,0);
-
- /* And reopen the driver again; note that since we closed */
- /* it nothing should have modified the default settings */
-
- if(OpenSerialDevice(Device,Unit))
- {
- /* Who knows what happened, the device didn't open */
- /* and we will have to clean up now */
-
- ReadRequest->IOSer.io_Device = WriteRequest->IOSer.io_Device = NULL;
-
- return(FALSE);
- }
- }
- }
-
- if(WasReading)
- StartSerialRead(WasQueueReadBuffer,WasQueueReadSize);
-
- return(TRUE);
- }
-
- /* OpenSerialDevice(STRPTR Device,LONG Unit):
- *
- * Open the serial device driver and update the write
- * request as well.
- */
-
- BYTE
- OpenSerialDevice(STRPTR Device,LONG Unit)
- {
- BYTE Result;
-
- Result = OpenDevice(Device,Unit,(struct IORequest *)ReadRequest,0);
-
- if(Result == 0)
- {
- /* Was the write request initialized? */
-
- if(WriteRequest->IOSer.io_Device)
- {
- CopyMem(&WriteRequest->io_CtlChar,&ReadRequest->io_CtlChar,ReadRequest->IOSer.io_Message.mn_Length - offsetof(struct IOExtSer,io_CtlChar));
-
- ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS;
- DoIO((struct IORequest *)ReadRequest);
- }
-
- /* Update the write request */
-
- CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
-
- WriteRequest->IOSer.io_Message.mn_ReplyPort = WritePort;
- }
-
- return(Result);
- }
-