home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / gfx / misc / imagefx_sdk / sas / scanlib / ser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-30  |  9.9 KB  |  438 lines

  1. /*
  2.  * Serial Port Routines for Scanners.
  3.  *
  4.  * May only be used by one person at a time!!
  5.  *
  6.  */
  7.  
  8. #include <exec/types.h>
  9. #include <exec/execbase.h>
  10. #include <exec/libraries.h>
  11. #include <devices/serial.h>
  12. #include <resources/misc.h>
  13. #include <clib/exec_protos.h>
  14. #include <clib/alib_protos.h>
  15. #include <clib/misc_protos.h>
  16. #include <string.h>
  17. #include <scan/modall.h>
  18.  
  19.  
  20. extern struct ExecBase *SysBase;
  21.  
  22.  
  23. /* timer.asm */
  24. struct timerequest     *CreateTimer (long);
  25. void                    DeleteTimer (struct timerequest *);
  26. int                     WaitTimer (long, long);
  27. struct timerequest     *QueueTimer (struct timerequest *, long, long);
  28. void                    AbortTimer (struct timerequest *);
  29.  
  30.  
  31.  
  32. /* Unfortunately, this will fail on slower or faster machines... */
  33. #define ONESECOND          (0x000AFFFFL)  /* 7FFFFF on an A2620 */
  34. #define MAXTIMEOUT         (0xFFFFFFFFL)
  35.  
  36. #define AllocStruct(S)     (S *)AllocMem (sizeof(S), MEMF_CLEAR)
  37. #define FreeStruct(p,S)    FreeMem ((p), sizeof(S))
  38.  
  39. int  DirectSerRead (UBYTE *, short, long);
  40. void DirectSerWrite (UBYTE *, short);
  41. void DirectSerBaud (long);
  42. void DirectSerFlush (void);
  43.  
  44. static struct IOExtSer    *ReadReq = NULL;
  45. static struct IOExtSer    *WriteReq = NULL;
  46. static struct MsgPort     *ReadPort = NULL;
  47. static struct MsgPort     *WritePort = NULL;
  48. static short               DevOpen = FALSE;
  49. static UBYTE               ReadBuf[8];
  50.  
  51. static short               Direct = FALSE;
  52.  
  53. struct Library            *MiscBase;
  54.  
  55. /*
  56.    QueueSerRead() - Queue up a read of one character from serial port.
  57. */
  58.  
  59. static void QueueSerRead (void)
  60. {
  61.    if (!Direct) {
  62.       ReadReq->IOSer.io_Command = CMD_READ;
  63.       ReadReq->IOSer.io_Flags = 0;
  64.       ReadReq->IOSer.io_Data = (APTR)ReadBuf;
  65.       ReadReq->IOSer.io_Length = 1;
  66.       SendIO ((struct IORequest *)ReadReq);
  67.    }
  68. }
  69.  
  70. void SerClose (void)
  71. {
  72.    if (!Direct) {
  73.  
  74.       if (DevOpen) {
  75.          if (!CheckIO((struct IORequest *)ReadReq)) {
  76.             AbortIO((struct IORequest *)ReadReq);
  77.             WaitIO((struct IORequest *)ReadReq);
  78.          }
  79.          CloseDevice ((struct IORequest *)ReadReq);
  80.       }
  81.  
  82.       if (WriteReq)
  83.          DeleteExtIO ((struct IORequest *)WriteReq);
  84.  
  85.       if (ReadReq)
  86.          DeleteExtIO ((struct IORequest *)ReadReq);
  87.  
  88.       if (WritePort)
  89.          DeletePort (WritePort);
  90.  
  91.       if (ReadPort)
  92.          DeletePort (ReadPort);
  93.  
  94.       ReadPort = WritePort = NULL;
  95.       ReadReq = WriteReq = NULL;
  96.       DevOpen = FALSE;
  97.  
  98.    }
  99.    else {
  100.       FreeMiscResource (MR_SERIALBITS);
  101.       FreeMiscResource (MR_SERIALPORT);
  102.    }
  103. }
  104.  
  105. /*
  106.    FlushDevice() - Attempt to flush the given device from memory.
  107.                    Used to get serial.device to release its hold
  108.                    on the misc.resource even when it's not using
  109.                    it.
  110. */
  111.  
  112. static void FlushDevice (char *name)
  113. {
  114.    struct Device *devpoint;
  115.  
  116.    Forbid();
  117.    if (devpoint = (struct Device *)FindName (&SysBase->DeviceList, name))
  118.       RemDevice (devpoint);
  119.    Permit();
  120. }
  121.  
  122. /*
  123.    SerOpen() - Open the serial port.
  124. */
  125.  
  126. int SerOpen (char *device, int unit, long baud, BOOL direct)
  127. {
  128.    int i;
  129.    char *user;
  130.  
  131.    if (device == NULL)
  132.       device = Prefs.SerDevice;
  133.  
  134.    if (unit < 0)
  135.       unit = Prefs.SerUnit;
  136.  
  137.    Direct = FALSE;
  138.    if (!strcmp("serial.device", device) && direct) Direct = TRUE;
  139.  
  140.    if (!Direct) {
  141.  
  142.       SetError(0);
  143.  
  144.       ReadPort = CreatePort (NULL, 0);
  145.       if (ReadPort == NULL) {
  146.          SerClose();
  147.          ReturnError(ERR_Memory, FALSE);
  148.       }
  149.  
  150.       WritePort = CreatePort (NULL, 0);
  151.       if (WritePort == NULL) {
  152.          SerClose();
  153.          ReturnError(ERR_Memory, FALSE);
  154.       }
  155.  
  156.       ReadReq = (struct IOExtSer *)CreateExtIO (ReadPort,
  157.                                                          sizeof(struct IOExtSer));
  158.       if (ReadReq == NULL) {
  159.          SerClose();
  160.          ReturnError(ERR_Memory, FALSE);
  161.       }
  162.  
  163.       WriteReq = (struct IOExtSer *)CreateExtIO (WritePort,
  164.                                                          sizeof(struct IOExtSer));
  165.       if (WriteReq == NULL) {
  166.          SerClose();
  167.          ReturnError(ERR_Memory, FALSE);
  168.       }
  169.  
  170.       ReadReq->io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;
  171.       ReadReq->io_Baud = 9600L;
  172.  
  173.       i = OpenDevice (device, unit, (struct IORequest *)ReadReq, 0);
  174.       if (i) {
  175.          SerClose();
  176.          ReturnError(ERR_NoSerial, FALSE);
  177.       }
  178.       DevOpen = TRUE;
  179.  
  180.       WriteReq->IOSer.io_Device = ReadReq->IOSer.io_Device;
  181.       WriteReq->IOSer.io_Unit = ReadReq->IOSer.io_Unit;
  182.  
  183.       ReadReq->IOSer.io_Command = SDCMD_SETPARAMS;
  184.       ReadReq->IOSer.io_Flags = 0;
  185.       ReadReq->io_RBufLen = 32768L;
  186.       ReadReq->io_ExtFlags = 0;
  187.       ReadReq->io_Baud = baud;
  188.       ReadReq->io_ReadLen = ReadReq->io_WriteLen = 8;
  189.       ReadReq->io_StopBits = 1;
  190.       ReadReq->io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;
  191.       DoIO ((struct IORequest *)ReadReq);
  192.  
  193.       QueueSerRead();
  194.       return (TRUE);
  195.  
  196.    }
  197.    else {
  198.  
  199.       FlushDevice ("serial.device");   /* Kludge for bug in OS */
  200.  
  201.       MiscBase = OpenResource ("misc.resource");
  202.       if (MiscBase == NULL) {
  203.          // Errorf (TXT(E_NoMisc));
  204.          ReturnError(ERR_NoSerial, FALSE);
  205.       }
  206.  
  207.       user = AllocMiscResource (MR_SERIALPORT, "ImageFX_20");
  208.       if (user) {
  209.          // Errorf (TXT(E_SerOwned), user);
  210.          ReturnError(ERR_NoSerial, FALSE);
  211.       }
  212.       user = AllocMiscResource (MR_SERIALBITS, "ImageFX_20");
  213.       if (user) {
  214.          FreeMiscResource (MR_SERIALPORT);
  215.          // Errorf (TXT(E_SerOwned), user);
  216.          ReturnError(ERR_NoSerial, FALSE);
  217.       }
  218.  
  219.       DirectSerBaud (baud);
  220.       return(TRUE);
  221.    }
  222. }
  223.  
  224. /*
  225.    SerBaud() - Change serial baud rate.
  226. */
  227.  
  228. void SerBaud (long baud)
  229. {
  230.    if (!Direct) {
  231.  
  232.       if ((CheckIO((struct IORequest *)ReadReq)) == NULL) {
  233.          AbortIO ((struct IORequest *)ReadReq);
  234.          WaitIO ((struct IORequest *)ReadReq);
  235.       }
  236.  
  237.       ReadReq->IOSer.io_Command = SDCMD_SETPARAMS;
  238.       ReadReq->IOSer.io_Flags = 0;
  239.       ReadReq->io_RBufLen = 32768L;
  240.       ReadReq->io_ExtFlags = 0;
  241.       ReadReq->io_Baud = baud;
  242.       ReadReq->io_ReadLen = ReadReq->io_WriteLen = 8;
  243.       ReadReq->io_StopBits = 1;
  244.       ReadReq->io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;
  245.       DoIO ((struct IORequest *)ReadReq);
  246.  
  247.       SerFlush();
  248.       QueueSerRead();
  249.  
  250.    }
  251.    else {
  252.  
  253.       DirectSerBaud (baud);
  254.  
  255.    }
  256. }
  257.  
  258. int TimedSerRead (UBYTE *buf, int len, int timeout)
  259. {
  260.    struct timerequest *timer;
  261.    char *bptr;
  262.    ULONG sigs, tsig, rsig;
  263.    int actual, rlen;
  264.  
  265.    if (timeout < 1) timeout = 1;
  266.  
  267.    if (Direct) {
  268.       return (DirectSerRead (buf, len, (timeout * ONESECOND)));
  269.    }
  270.  
  271.    actual = 0;
  272.  
  273.    timer = CreateTimer (UNIT_VBLANK);
  274.  
  275.    tsig = 1L << timer->tr_node.io_Message.mn_ReplyPort->mp_SigBit;
  276.    rsig = 1L << ReadPort->mp_SigBit;
  277.  
  278.    QueueTimer(timer, timeout, 0);
  279.  
  280.    bptr = buf;
  281.    for (;;) {
  282.  
  283.       sigs = Wait(rsig | tsig);
  284.  
  285.       if (CheckIO((struct IORequest *)ReadReq)) {
  286.  
  287.          /* read the byte that satisfied the request */
  288.          WaitIO((struct IORequest *)ReadReq);
  289.          *bptr++ = ReadBuf[0];
  290.          len--; actual++;
  291.  
  292.          /* read all available pending bytes now */
  293.          if (len > 0) {
  294.             ReadReq->IOSer.io_Command = SDCMD_QUERY;
  295.             DoIO((struct IORequest *)ReadReq);
  296.             rlen = ReadReq->IOSer.io_Actual;
  297.             if (rlen > 0) {
  298.                if (rlen > len) rlen = len;
  299.                ReadReq->IOSer.io_Command = CMD_READ;
  300.                ReadReq->IOSer.io_Length = rlen;
  301.                ReadReq->IOSer.io_Data = bptr;
  302.                DoIO((struct IORequest *)ReadReq);
  303.                rlen = ReadReq->IOSer.io_Actual;
  304.                bptr += rlen; actual += rlen; len -= rlen;
  305.             }
  306.          }
  307.  
  308.          /* queue up another read request */
  309.          QueueSerRead();
  310.          if (len <= 0) {
  311.             AbortTimer(timer);
  312.             break;
  313.          }
  314.       }
  315.  
  316.       if (sigs & tsig) {
  317.          GetMsg (timer->tr_node.io_Message.mn_ReplyPort);
  318.          break;
  319.       }
  320.  
  321.    }
  322.  
  323.    DeleteTimer(timer);
  324.  
  325.    return(actual);
  326. }
  327.  
  328.  
  329. /*
  330.    SerRead() - Read a given number of characters from the serial port.
  331.                Returns the number of characters actually read.
  332. */
  333.  
  334. void SerRead (UBYTE *buf, int len)
  335. {
  336.    UBYTE *bptr, *rptr;
  337.    int i;
  338.  
  339.    if (!Direct) {
  340.  
  341.       bptr = buf;
  342.       for (;;) {
  343.          WaitIO ((struct IORequest *)ReadReq);    /* Wait for read complete */
  344.          rptr = (UBYTE *)ReadReq->IOSer.io_Data;
  345.          for (i = 0; i < ReadReq->IOSer.io_Actual && len; i++) {
  346.             *bptr++ = *rptr++;
  347.             len--;
  348.          }
  349.          if (len == 0) break;    /* Done, dude. */
  350.          ReadReq->IOSer.io_Data = (APTR)bptr;
  351.          ReadReq->IOSer.io_Length = len;        /* Remaining length */
  352.          ReadReq->IOSer.io_Flags = 0;
  353.          SendIO ((struct IORequest *)ReadReq);
  354.       }
  355.       QueueSerRead();
  356.  
  357.    }
  358.    else {
  359.  
  360.       DirectSerRead (buf, len, MAXTIMEOUT);
  361.  
  362.    }
  363. }
  364.  
  365. /*
  366.  * SerPutc() - Write a single byte to the serial port.
  367.  */
  368.  
  369. void SerPutc (UBYTE c)
  370. {
  371.    UBYTE realc = c;
  372.  
  373.    if (!Direct) {
  374.       WriteReq->IOSer.io_Command = CMD_WRITE;
  375.       WriteReq->IOSer.io_Flags = 0;
  376.       WriteReq->IOSer.io_Data = (APTR)&realc;
  377.       WriteReq->IOSer.io_Length = 1;
  378.       DoIO ((struct IORequest *)WriteReq);
  379.    }
  380.    else {
  381.       DirectSerWrite (&realc, 1);
  382.    }
  383. }
  384.  
  385. /*
  386.  * SerWrite() - Write several bytes to the serial port.
  387.  */
  388.  
  389. void SerWrite (UBYTE *s, int len)
  390. {
  391.    if (!Direct) {
  392.       WriteReq->IOSer.io_Command = CMD_WRITE;
  393.       WriteReq->IOSer.io_Flags = 0;
  394.       WriteReq->IOSer.io_Data = (APTR)s;
  395.       WriteReq->IOSer.io_Length = len;
  396.       DoIO ((struct IORequest *)WriteReq);
  397.    }
  398.    else {
  399.       DirectSerWrite (s, len);
  400.    }
  401. }
  402.  
  403.  
  404. /*
  405.    SerFlush() - Flush out the serial port.
  406. */
  407.  
  408. void SerFlush (void)
  409. {
  410.    if (!Direct) {
  411.       WriteReq->IOSer.io_Command = CMD_CLEAR;
  412.       DoIO ((struct IORequest *)WriteReq);
  413.    }
  414.    else {
  415.       DirectSerFlush();
  416.    }
  417. }
  418.  
  419. static
  420. BOOL Disabled = FALSE;
  421.  
  422. void SerDisable (void)
  423. {
  424.    if (Direct) { Disable(); Disabled = TRUE; }
  425. }
  426.  
  427. void SerEnable (void)
  428. {
  429.    if (Direct) { Enable(); Disabled = FALSE; }
  430. }
  431.  
  432. int SerDirect (void)
  433. {
  434.    if (Disabled) return((int)Direct);
  435.    return(FALSE);
  436. }
  437.  
  438.