home *** CD-ROM | disk | FTP | other *** search
- /*
- * Serial Port Routines for Scanners.
- *
- * May only be used by one person at a time!!
- *
- */
-
- #include <exec/types.h>
- #include <exec/execbase.h>
- #include <exec/libraries.h>
- #include <devices/serial.h>
- #include <resources/misc.h>
- #include <clib/exec_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/misc_protos.h>
- #include <string.h>
- #include <scan/modall.h>
-
-
- extern struct ExecBase *SysBase;
-
-
- /* timer.asm */
- struct timerequest *CreateTimer (long);
- void DeleteTimer (struct timerequest *);
- int WaitTimer (long, long);
- struct timerequest *QueueTimer (struct timerequest *, long, long);
- void AbortTimer (struct timerequest *);
-
-
-
- /* Unfortunately, this will fail on slower or faster machines... */
- #define ONESECOND (0x000AFFFFL) /* 7FFFFF on an A2620 */
- #define MAXTIMEOUT (0xFFFFFFFFL)
-
- #define AllocStruct(S) (S *)AllocMem (sizeof(S), MEMF_CLEAR)
- #define FreeStruct(p,S) FreeMem ((p), sizeof(S))
-
- int DirectSerRead (UBYTE *, short, long);
- void DirectSerWrite (UBYTE *, short);
- void DirectSerBaud (long);
- void DirectSerFlush (void);
-
- static struct IOExtSer *ReadReq = NULL;
- static struct IOExtSer *WriteReq = NULL;
- static struct MsgPort *ReadPort = NULL;
- static struct MsgPort *WritePort = NULL;
- static short DevOpen = FALSE;
- static UBYTE ReadBuf[8];
-
- static short Direct = FALSE;
-
- struct Library *MiscBase;
-
- /*
- QueueSerRead() - Queue up a read of one character from serial port.
- */
-
- static void QueueSerRead (void)
- {
- if (!Direct) {
- ReadReq->IOSer.io_Command = CMD_READ;
- ReadReq->IOSer.io_Flags = 0;
- ReadReq->IOSer.io_Data = (APTR)ReadBuf;
- ReadReq->IOSer.io_Length = 1;
- SendIO ((struct IORequest *)ReadReq);
- }
- }
-
- void SerClose (void)
- {
- if (!Direct) {
-
- if (DevOpen) {
- if (!CheckIO((struct IORequest *)ReadReq)) {
- AbortIO((struct IORequest *)ReadReq);
- WaitIO((struct IORequest *)ReadReq);
- }
- CloseDevice ((struct IORequest *)ReadReq);
- }
-
- if (WriteReq)
- DeleteExtIO ((struct IORequest *)WriteReq);
-
- if (ReadReq)
- DeleteExtIO ((struct IORequest *)ReadReq);
-
- if (WritePort)
- DeletePort (WritePort);
-
- if (ReadPort)
- DeletePort (ReadPort);
-
- ReadPort = WritePort = NULL;
- ReadReq = WriteReq = NULL;
- DevOpen = FALSE;
-
- }
- else {
- FreeMiscResource (MR_SERIALBITS);
- FreeMiscResource (MR_SERIALPORT);
- }
- }
-
- /*
- FlushDevice() - Attempt to flush the given device from memory.
- Used to get serial.device to release its hold
- on the misc.resource even when it's not using
- it.
- */
-
- static void FlushDevice (char *name)
- {
- struct Device *devpoint;
-
- Forbid();
- if (devpoint = (struct Device *)FindName (&SysBase->DeviceList, name))
- RemDevice (devpoint);
- Permit();
- }
-
- /*
- SerOpen() - Open the serial port.
- */
-
- int SerOpen (char *device, int unit, long baud, BOOL direct)
- {
- int i;
- char *user;
-
- if (device == NULL)
- device = Prefs.SerDevice;
-
- if (unit < 0)
- unit = Prefs.SerUnit;
-
- Direct = FALSE;
- if (!strcmp("serial.device", device) && direct) Direct = TRUE;
-
- if (!Direct) {
-
- SetError(0);
-
- ReadPort = CreatePort (NULL, 0);
- if (ReadPort == NULL) {
- SerClose();
- ReturnError(ERR_Memory, FALSE);
- }
-
- WritePort = CreatePort (NULL, 0);
- if (WritePort == NULL) {
- SerClose();
- ReturnError(ERR_Memory, FALSE);
- }
-
- ReadReq = (struct IOExtSer *)CreateExtIO (ReadPort,
- sizeof(struct IOExtSer));
- if (ReadReq == NULL) {
- SerClose();
- ReturnError(ERR_Memory, FALSE);
- }
-
- WriteReq = (struct IOExtSer *)CreateExtIO (WritePort,
- sizeof(struct IOExtSer));
- if (WriteReq == NULL) {
- SerClose();
- ReturnError(ERR_Memory, FALSE);
- }
-
- ReadReq->io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;
- ReadReq->io_Baud = 9600L;
-
- i = OpenDevice (device, unit, (struct IORequest *)ReadReq, 0);
- if (i) {
- SerClose();
- ReturnError(ERR_NoSerial, FALSE);
- }
- DevOpen = TRUE;
-
- WriteReq->IOSer.io_Device = ReadReq->IOSer.io_Device;
- WriteReq->IOSer.io_Unit = ReadReq->IOSer.io_Unit;
-
- ReadReq->IOSer.io_Command = SDCMD_SETPARAMS;
- ReadReq->IOSer.io_Flags = 0;
- ReadReq->io_RBufLen = 32768L;
- ReadReq->io_ExtFlags = 0;
- ReadReq->io_Baud = baud;
- ReadReq->io_ReadLen = ReadReq->io_WriteLen = 8;
- ReadReq->io_StopBits = 1;
- ReadReq->io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;
- DoIO ((struct IORequest *)ReadReq);
-
- QueueSerRead();
- return (TRUE);
-
- }
- else {
-
- FlushDevice ("serial.device"); /* Kludge for bug in OS */
-
- MiscBase = OpenResource ("misc.resource");
- if (MiscBase == NULL) {
- // Errorf (TXT(E_NoMisc));
- ReturnError(ERR_NoSerial, FALSE);
- }
-
- user = AllocMiscResource (MR_SERIALPORT, "ImageFX_20");
- if (user) {
- // Errorf (TXT(E_SerOwned), user);
- ReturnError(ERR_NoSerial, FALSE);
- }
- user = AllocMiscResource (MR_SERIALBITS, "ImageFX_20");
- if (user) {
- FreeMiscResource (MR_SERIALPORT);
- // Errorf (TXT(E_SerOwned), user);
- ReturnError(ERR_NoSerial, FALSE);
- }
-
- DirectSerBaud (baud);
- return(TRUE);
- }
- }
-
- /*
- SerBaud() - Change serial baud rate.
- */
-
- void SerBaud (long baud)
- {
- if (!Direct) {
-
- if ((CheckIO((struct IORequest *)ReadReq)) == NULL) {
- AbortIO ((struct IORequest *)ReadReq);
- WaitIO ((struct IORequest *)ReadReq);
- }
-
- ReadReq->IOSer.io_Command = SDCMD_SETPARAMS;
- ReadReq->IOSer.io_Flags = 0;
- ReadReq->io_RBufLen = 32768L;
- ReadReq->io_ExtFlags = 0;
- ReadReq->io_Baud = baud;
- ReadReq->io_ReadLen = ReadReq->io_WriteLen = 8;
- ReadReq->io_StopBits = 1;
- ReadReq->io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;
- DoIO ((struct IORequest *)ReadReq);
-
- SerFlush();
- QueueSerRead();
-
- }
- else {
-
- DirectSerBaud (baud);
-
- }
- }
-
- int TimedSerRead (UBYTE *buf, int len, int timeout)
- {
- struct timerequest *timer;
- char *bptr;
- ULONG sigs, tsig, rsig;
- int actual, rlen;
-
- if (timeout < 1) timeout = 1;
-
- if (Direct) {
- return (DirectSerRead (buf, len, (timeout * ONESECOND)));
- }
-
- actual = 0;
-
- timer = CreateTimer (UNIT_VBLANK);
-
- tsig = 1L << timer->tr_node.io_Message.mn_ReplyPort->mp_SigBit;
- rsig = 1L << ReadPort->mp_SigBit;
-
- QueueTimer(timer, timeout, 0);
-
- bptr = buf;
- for (;;) {
-
- sigs = Wait(rsig | tsig);
-
- if (CheckIO((struct IORequest *)ReadReq)) {
-
- /* read the byte that satisfied the request */
- WaitIO((struct IORequest *)ReadReq);
- *bptr++ = ReadBuf[0];
- len--; actual++;
-
- /* read all available pending bytes now */
- if (len > 0) {
- ReadReq->IOSer.io_Command = SDCMD_QUERY;
- DoIO((struct IORequest *)ReadReq);
- rlen = ReadReq->IOSer.io_Actual;
- if (rlen > 0) {
- if (rlen > len) rlen = len;
- ReadReq->IOSer.io_Command = CMD_READ;
- ReadReq->IOSer.io_Length = rlen;
- ReadReq->IOSer.io_Data = bptr;
- DoIO((struct IORequest *)ReadReq);
- rlen = ReadReq->IOSer.io_Actual;
- bptr += rlen; actual += rlen; len -= rlen;
- }
- }
-
- /* queue up another read request */
- QueueSerRead();
- if (len <= 0) {
- AbortTimer(timer);
- break;
- }
- }
-
- if (sigs & tsig) {
- GetMsg (timer->tr_node.io_Message.mn_ReplyPort);
- break;
- }
-
- }
-
- DeleteTimer(timer);
-
- return(actual);
- }
-
-
- /*
- SerRead() - Read a given number of characters from the serial port.
- Returns the number of characters actually read.
- */
-
- void SerRead (UBYTE *buf, int len)
- {
- UBYTE *bptr, *rptr;
- int i;
-
- if (!Direct) {
-
- bptr = buf;
- for (;;) {
- WaitIO ((struct IORequest *)ReadReq); /* Wait for read complete */
- rptr = (UBYTE *)ReadReq->IOSer.io_Data;
- for (i = 0; i < ReadReq->IOSer.io_Actual && len; i++) {
- *bptr++ = *rptr++;
- len--;
- }
- if (len == 0) break; /* Done, dude. */
- ReadReq->IOSer.io_Data = (APTR)bptr;
- ReadReq->IOSer.io_Length = len; /* Remaining length */
- ReadReq->IOSer.io_Flags = 0;
- SendIO ((struct IORequest *)ReadReq);
- }
- QueueSerRead();
-
- }
- else {
-
- DirectSerRead (buf, len, MAXTIMEOUT);
-
- }
- }
-
- /*
- * SerPutc() - Write a single byte to the serial port.
- */
-
- void SerPutc (UBYTE c)
- {
- UBYTE realc = c;
-
- if (!Direct) {
- WriteReq->IOSer.io_Command = CMD_WRITE;
- WriteReq->IOSer.io_Flags = 0;
- WriteReq->IOSer.io_Data = (APTR)&realc;
- WriteReq->IOSer.io_Length = 1;
- DoIO ((struct IORequest *)WriteReq);
- }
- else {
- DirectSerWrite (&realc, 1);
- }
- }
-
- /*
- * SerWrite() - Write several bytes to the serial port.
- */
-
- void SerWrite (UBYTE *s, int len)
- {
- if (!Direct) {
- WriteReq->IOSer.io_Command = CMD_WRITE;
- WriteReq->IOSer.io_Flags = 0;
- WriteReq->IOSer.io_Data = (APTR)s;
- WriteReq->IOSer.io_Length = len;
- DoIO ((struct IORequest *)WriteReq);
- }
- else {
- DirectSerWrite (s, len);
- }
- }
-
-
- /*
- SerFlush() - Flush out the serial port.
- */
-
- void SerFlush (void)
- {
- if (!Direct) {
- WriteReq->IOSer.io_Command = CMD_CLEAR;
- DoIO ((struct IORequest *)WriteReq);
- }
- else {
- DirectSerFlush();
- }
- }
-
- static
- BOOL Disabled = FALSE;
-
- void SerDisable (void)
- {
- if (Direct) { Disable(); Disabled = TRUE; }
- }
-
- void SerEnable (void)
- {
- if (Direct) { Enable(); Disabled = FALSE; }
- }
-
- int SerDirect (void)
- {
- if (Disabled) return((int)Direct);
- return(FALSE);
- }
-
-