home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / datafiles / text / c_manual / devices / serialdevice / example3.c < prev    next >
C/C++ Source or Header  |  1995-02-27  |  26KB  |  626 lines

  1. /***********************************************************/
  2. /*                                                         */
  3. /* Amiga C Encyclopedia (ACE) V3.0      Amiga C Club (ACC) */
  4. /* -------------------------------      ------------------ */
  5. /*                                                         */
  6. /* Book:    ACM Devices                 Amiga C Club       */
  7. /* Chapter: Serial Device               Tulevagen 22       */
  8. /* File:    Example3.c                  181 41  LIDINGO    */
  9. /* Author:  Anders Bjerin               SWEDEN             */
  10. /* Date:    92-04-26                                       */
  11. /* Version: 1.00                                           */
  12. /*                                                         */
  13. /*   Copyright 1992, Anders Bjerin - Amiga C Club (ACC)    */
  14. /*                                                         */
  15. /* Registered members may use this program freely in their */
  16. /*     own commercial/noncommercial programs/articles.     */
  17. /*                                                         */
  18. /***********************************************************/
  19.  
  20.  
  21.  
  22. /* This example is rather similar to Example 1, but this time  */
  23. /* we do not wait for the serial port to complete our request. */
  24. /* We are instead trying to read and write at the same time.   */
  25. /* To be able to do several requests simultaneously we need    */
  26. /* one request block for each command. In this example we use  */
  27. /* three separate request blocks.                              */
  28.  
  29.  
  30.  
  31. #include <exec/types.h>        /* STRPTR         */
  32. #include <devices/serial.h>    /* Serial Device  */
  33.  
  34.  
  35.  
  36. /* Size of our data buffer: */
  37. #define MY_BUFFER_SIZE 200
  38.  
  39. /* Size of the Serial Device's own input buffer: (Must be */
  40. /* at least 512 bytes, but more is recommended.)          */
  41. #define INPUT_BUFFER_SIZE 1024
  42.  
  43. /* Read 8 bits/character: */
  44. #define READ_LENGTH   8
  45.  
  46. /* Write 8 bits/character: */
  47. #define WRITE_LENGTH  8
  48.  
  49. /* Sen 1 stop bit between each character: */
  50. #define STOP_LENGTH  1
  51.  
  52. /* Break time in microseconds: (1/2 sec) */
  53. #define BREAK_TIME    500000
  54.  
  55. /* Baud rate: */
  56. #define BAUD_RATE     9600
  57.  
  58. /* Serial flags: (Parity enabled, checking for end of file characters.) */
  59. #define SERIAL_FLAGS SERF_PARTY_ON|SERF_EOFMODE
  60.  
  61. /* Additional flags: (Mark-space parity not used.) */
  62. #define ADDITIONAL_FLAGS 0
  63.  
  64.  
  65.  
  66.  
  67.  
  68. /* Declare a pointer to our reply port: */
  69. struct MsgPort *replymp = NULL;
  70.  
  71. /* Declare pointers to our serial request blocks:      */
  72. /* One is used for reading, the other for writing, and */
  73. /* finally the last one is used for other commands.    */
  74. struct IOExtSer *serial_req_read = NULL;    /* Read    */
  75. struct IOExtSer *serial_req_write = NULL;   /* Write   */
  76. struct IOExtSer *serial_req_command = NULL; /* Command */
  77.  
  78. /* Store the serial device error here: */
  79. UWORD serial_dever = TRUE;
  80.  
  81. /* Declare two data buffers. The first one will contain the  */
  82. /* information we want to send, and the other will be filled */
  83. /* with all data we have collected:                          */
  84. BYTE read_buffer[ MY_BUFFER_SIZE ];
  85. BYTE write_buffer[ MY_BUFFER_SIZE ];
  86.  
  87.  
  88.  
  89.  
  90. /* Declare our functions: */
  91.  
  92. /* Our main function: */
  93. void main();
  94.  
  95. /* Clears and removes everything nice and neatly: */
  96. void clean_up( UBYTE error, STRPTR text );
  97.  
  98. /* Sets serial parameters: */
  99. UBYTE SetSerParams(
  100.   struct IOExtSer *ioreq,
  101.   ULONG buffer_length,
  102.   ULONG baud_rate,
  103.   ULONG break_time,
  104.   UBYTE read_length,
  105.   UBYTE write_length,
  106.   UBYTE stop_length,
  107.   UBYTE serial_flags,
  108.   ULONG extended_flags,
  109.   UBYTE *eof_chars
  110. );
  111.  
  112. /* Prints some information about the error: */
  113. void SerError( UBYTE error );
  114.  
  115. /* Sends data to the Serial Port without going to sleep: */
  116. void SerWriteNoWait(
  117.   struct IOExtSer *ioreq,
  118.   BYTE *data,
  119.   ULONG length
  120. );
  121.  
  122. /* Reads data from the Serial Port without going to sleep: */
  123. void SerReadNoWait(
  124.   struct IOExtSer *ioreq,
  125.   BYTE *data,
  126.   ULONG length
  127. );
  128.  
  129.  
  130.  
  131. void main()
  132. {
  133.   /* Error number: */
  134.   UBYTE error;
  135.   
  136.   /* Byte pointers, used to copy the request blocks: */
  137.   BYTE *r_ptr;
  138.   BYTE *w_ptr;
  139.   BYTE *c_ptr;
  140.  
  141.   /* Loop variable: */
  142.   int loop;
  143.  
  144.   /* The eight end-of-file characters: */
  145.   /* They MUST be in descending order! */
  146.   UBYTE eof_char[8]={ 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00 };
  147.  
  148.   
  149.   
  150.   /* Get a reply port: (No name, priority 0) */
  151.   replymp = (struct MsgPort *)
  152.     CreatePort( NULL, 0 );
  153.   if( !replymp )
  154.     clean_up( 0, "Could not create the reply port!" );
  155.  
  156.  
  157.  
  158.   /* Create request block "Read": */
  159.   serial_req_read = (struct IOExtSer *)
  160.     CreateExtIO( replymp, sizeof( struct IOExtSer ) );
  161.   if( !serial_req_read )
  162.     clean_up( 0, "Not enough memory for the request block Read!" );
  163.  
  164.   /* Create request block "Write": */
  165.   serial_req_write = (struct IOExtSer *)
  166.     CreateExtIO( replymp, sizeof( struct IOExtSer ) );
  167.   if( !serial_req_write )
  168.     clean_up( 0, "Not enough memory for the request block Write!" );
  169.  
  170.   /* Create request block "Command": */
  171.   serial_req_command = (struct IOExtSer *)
  172.     CreateExtIO( replymp, sizeof( struct IOExtSer ) );
  173.   if( !serial_req_command )
  174.     clean_up( 0, "Not enough memory for the request block Command!" );
  175.  
  176.  
  177.  
  178.  
  179.   /* Open the serial device for the read request: */
  180.   serial_dever = OpenDevice( SERIALNAME, 0, serial_req_read, 0 );
  181.   if( serial_dever )
  182.     clean_up( 0, "Could not open the Serial Device!" );
  183.  
  184.   /* Since we can not open the serial device any more    */
  185.   /* for the other request (we use exclusive access), we */
  186.   /* have to copy the whole read request block into the  */
  187.   /* write and command request block.                    */
  188.  
  189.   /* Get the start address of all request blocks: */
  190.   r_ptr = (BYTE *) serial_req_read;
  191.   w_ptr = (BYTE *) serial_req_write;
  192.   c_ptr = (BYTE *) serial_req_command;
  193.  
  194.   /* Copy the request block, byte by byte: */
  195.   for( loop=0; loop < sizeof( struct IOExtSer ); loop++ )
  196.   {
  197.     /* Copy one byte: */
  198.     *w_ptr = *r_ptr; /* Write   */
  199.     *c_ptr = *r_ptr; /* Command */
  200.     
  201.     /* Step one byte foreward: */
  202.     w_ptr++;
  203.     r_ptr++;
  204.     c_ptr++;
  205.   }
  206.  
  207.  
  208.  
  209.   /* Set the serial parameters: */
  210.   error = (UBYTE) SetSerParams(
  211.     serial_req_command, /* Pointer to our serial request block.          */
  212.     INPUT_BUFFER_SIZE,  /* Size of the Serial Device's own input buffer. */
  213.     BAUD_RATE,          /* Baud rate (read and write). [112 - 292000]    */
  214.     BREAK_TIME,         /* Break time in microseconds.                   */
  215.     READ_LENGTH,        /* # of bits/char (1-8). Parity not included.    */
  216.     WRITE_LENGTH,       /* # of bits/char (1-8). Parity not included.    */
  217.     STOP_LENGTH,        /* # of stop bits between the characters. (1-2)  */
  218.     SERIAL_FLAGS,       /* Serial flags.                                 */
  219.     ADDITIONAL_FLAGS,   /* Additional flags.                             */
  220.     eof_char            /* Pointer to an array of eight end-of-file chr. */
  221.   );
  222.  
  223.   /* OK? */
  224.   if( error )
  225.     clean_up( error, "Could not set the serial parameters!" );
  226.  
  227.  
  228.  
  229.  
  230.   /* Send 0 bytes to the serial port and return immediately: */
  231.   /* (Since I do not know what you have connected to your    */
  232.   /* serial port, it is best not to do anything.)            */
  233.   SerWriteNoWait( serial_req_write, write_buffer, 0 ); 
  234.  
  235.   /* Collect 0 bytes from the serial port and return immediately: */
  236.   SerReadNoWait( serial_req_read, read_buffer, 0 ); 
  237.  
  238.  
  239.  
  240.   /* Do whatever you want... */
  241.  
  242.  
  243.  
  244.   /* When you are using asynchronious commands you have to be  */
  245.   /* careful with cleaning up. All requests you have started   */
  246.   /* MUST have been completed or aborted before you may close  */
  247.   /* the device. All reply massages must also be removed from  */
  248.   /* the reply port.                                           */
  249.   /*                                                           */
  250.   /* There exist several different ways on how to wait for     */
  251.   /* requests to be completed. In example 2 we used the        */
  252.   /* function CheckIO(), and Remove(). In this example will    */
  253.   /* we use the WaitIO() which puts our program to sleep and   */
  254.   /* will first wake up when the request have been completed.  */
  255.   /* WaitIO() will automatically remove the reply messages,    */
  256.   /* and if the request have already been competed it will     */
  257.   /*  immediately return.                                      */
  258.   /*                                                           */
  259.   /* The difference between a busy wait and a task sleep is    */
  260.   /* that your program can do other things while waiting if    */
  261.   /* you are using the busy wait. The task sleep should be     */
  262.   /* used if you do not want to do anything while waiting.     */
  263.   /*                                                           */
  264.   /* NOTE! Do NOT use a busy wait if you can manage with a     */
  265.   /* task sleep! Computer time should always be used with      */
  266.   /* care.                                                     */
  267.   /*                                                           */
  268.   /* We have three request blocks that has to be looked after. */
  269.   /* The "Command" block was only used by the SetSerParams()   */
  270.   /* function and was used as a synchronous request. [DoIO()]  */
  271.   /* We will therefore (nor should we) wait for it to be       */
  272.   /* completed or try to remove any reply message. The two     */
  273.   /* other request blocks were on the other hand asynchronous, */
  274.   /* and we must therefore both wait for them to be completed  */
  275.   /* and make sure that the reply messages are removed. The    */
  276.   /* WaitIO() function will do both of these things.           */
  277.   /*                                                           */
  278.   /* NOTE! Do NOT try to wait for a reuest that has not been   */
  279.   /* started [either by a SendIO() or BeginIO()].              */
  280.  
  281.   /* Task sleep... (It does not matter in which order we wait.) */
  282.   WaitIO( serial_req_read );
  283.   WaitIO( serial_req_write );
  284.  
  285.  
  286.  
  287.   /* Clean up and quit: */
  288.   clean_up( 0, "The End!" );
  289. }
  290.  
  291.  
  292.  
  293. /* Close and return everything that has been */
  294. /* opened and allocated before we quit:      */
  295.  
  296. void clean_up( UBYTE error, STRPTR text )
  297. {
  298.   /* Print some information about the problem: */
  299.   if( error )
  300.     SerError( error );
  301.  
  302.   /* Close the Serial Device: */ 
  303.   if( !serial_dever )
  304.     CloseDevice( serial_req_read );
  305.  
  306.   /* Deallocate the serial "read" request block: */
  307.   if( serial_req_read )
  308.     DeleteExtIO( serial_req_read, sizeof( struct IOExtSer ) );
  309.  
  310.   /* Deallocate the serial "write" request block: */
  311.   if( serial_req_write )
  312.     DeleteExtIO( serial_req_write, sizeof( struct IOExtSer ) );
  313.  
  314.   /* Deallocate the serial "command" request block: */
  315.   if( serial_req_command )
  316.     DeleteExtIO( serial_req_command, sizeof( struct IOExtSer ) );
  317.  
  318.   /* Remove the replyport: */
  319.   if( replymp )
  320.     DeletePort( replymp);
  321.  
  322.   /* Print the message: */
  323.   printf( "\n%s\n", text );
  324.  
  325.   /* Quit: */
  326.   exit( 0 );
  327. }
  328.  
  329.  
  330.  
  331. /* SetSerParams() sets the serial parameters. It initializes a IOExtSer    */
  332. /* structure, and does a SDCMD_SETPARAMS commad. If everything is OK it    */
  333. /* returns NULL, else an error number is returned.                         */
  334. /*                                                                         */
  335. /* Synopsis: er = SetSerParams( io, bl, br, bt, rl, wl, sl, sf, ef, chr ); */
  336. /*                                                                         */
  337. /* er:       (UBYTE) SetSerParams() returns 0 if everything was OK, else   */
  338. /*           an error value is returned. See function SerError() for more  */
  339. /*           information.                                                  */
  340. /*                                                                         */ 
  341. /* io:       (struct IOExtSer *) Pointer to the serial request block you   */
  342. /*           want to initialize.                                           */
  343. /*                                                                         */
  344. /* bl:       (ULONG) Size of the internal serial buffer which will be used */
  345. /*           when you read data. Must be at least 512 (bytes), but more is */
  346. /*           recommended. The faster and more data you want to read, the   */
  347. /*           bigger should the internal buffer be. Some recommended sizes: */
  348. /*           512, 1024, 2048, 4096, 8192 or 16384.                         */
  349. /*                                                                         */
  350. /* br:       (ULONG) Baud rate. Can be anything between 110 and 292000.    */
  351. /*           (Up to 292000 is all right for the hardware, but the software */
  352. /*           can not cope with this, especially since other tasks may be   */
  353. /*           running at the same time. You should therefore not use baud   */
  354. /*           rates above 31250.) Some recommended values: 110, 300, 1200,  */
  355. /*           2400, 4800, 9600, 19200 or 31250 (the last is a bit though).  */
  356. /*                                                                         */
  357. /* bt:       (ULONG) Break time in micro seconds. All break requests will  */
  358. /*           be set to this time.                                          */
  359. /*                                                                         */
  360. /* rl:       (UBYTE) How many bits chould be read for each character.      */
  361. /*           Usually 7 or 8 bits.                                          */
  362. /*                                                                         */
  363. /* wl:       (UBYTE) How many bits chould be written for each character.   */
  364. /*           Usually 7 or 8 bits.                                          */
  365. /*                                                                         */
  366. /* sl:       (UBYTE) How many stop bits shoud be written or expected.      */
  367. /*           Normally set to 1, but you may set it to 2 if rl/wl = 7.      */
  368. /*                                                                         */
  369. /* sf:       (UBYTE) You may use the following serial flags:               */
  370. /*                                                                         */
  371. /*           SERF_PARTY_ON   Parity checking/writing is turned on. (The    */
  372. /*                           sum of all data bits are divided by two, and  */
  373. /*                           the remainder is the parity bit. If even      */
  374. /*                           parity is used the bit will be set to 1 if    */
  375. /*                           the remainder is even. If odd parity is used  */
  376. /*                           the parity bit will be set to 0 if the        */
  377. /*                           remainder is even.                            */
  378. /*                                                                         */
  379. /*           SERF_PARTY_ODD  Set this flag if you want to use odd parity.  */
  380. /*                           (The default setting is even parity.)         */
  381. /*                                                                         */
  382. /*           SERF_7WIRE      This flag should only be used when you call   */
  383. /*                           the OpenDevice(), and not by this function.   */
  384. /*                           If the flag is set, seven-wire "handshaking"  */
  385. /*                           will be used. (Default is three-wire.)        */
  386. /*                                                                         */
  387. /*           SERF_QUEUEDBRK  Set this flag if you want break commands to   */
  388. /*                           be queued along with all other signals. The   */
  389. /*                           default is that a break command interrupts    */
  390. /*                           the process immediately.                      */
  391. /*                                                                         */
  392. /*           SERF_RAD_BOOGIE Set this bit if you want high speed mode.     */
  393. /*                           This can be useful when you want to send and  */
  394. /*                           receive signals at high speed. When this flag */
  395. /*                           is set no parity is used, xON/xOFF handling   */
  396. /*                           is turned off, no break signals are allowed,  */
  397. /*                           and finally only eight-bit characters are     */
  398. /*                           used.                                         */
  399. /*                                                                         */
  400. /*           SERF_SHARED     Set this falg if you want to allow other      */
  401. /*                           tasks running at the same time to use the     */
  402. /*                           serial device. The default is exclusive-      */
  403. /*                           access. (If some other task is using the      */
  404. /*                           serial device with the shared bit set, and    */
  405. /*                           you call this function with exclusive access, */
  406. /*                           your request will fail.)                      */
  407. /*                                                                         */
  408. /*           SERF_EOFMODE    Set this flag if you want to check for end of */
  409. /*                           file characters. (You may use up to eight end */
  410. /*                           of file characters, which are specified       */
  411. /*                           below.)                                       */
  412. /*                                                                         */
  413. /*           SERF_XDISABLED  xOn/xOFF handling is turned off. (Default is  */
  414. /*                           on.)                                          */
  415. /*                                                                         */
  416. /* ef:       (ULONG) You may use the following extra flags:                */
  417. /*                                                                         */
  418. /*           SEXTF_MSPON     Set this flag if you want to use mark-space   */
  419. /*                           parity rather than odd-even parity.           */
  420. /*                                                                         */
  421. /*           SEXTF_MARK      If this and the SEXTF_MSPON flag is set, it   */
  422. /*                           will mark.                                    */
  423. /*                                                                         */
  424. /* chr:      (UBYTE *) Pointer to an array containing eight end of file    */
  425. /*           characters. If the serial flag "SERF_EOFMODE" is set, the     */
  426. /*           serial device will check each character which is sent or      */
  427. /*           received, and if it matches one of the end of file characters */
  428. /*           the read/wite request is terminated.                          */
  429.  
  430. UBYTE SetSerParams(
  431.   struct IOExtSer *ioreq, /* Pointer to our serial request block.          */
  432.   ULONG buffer_length,    /* Size of the Serial Device's own input buffer. */
  433.   ULONG baud_rate,        /* Baud rate (read and write). [110 - 292000]    */
  434.   ULONG break_time,       /* Break time in microseconds.                   */
  435.   UBYTE read_length,      /* Nr of bits, read (1-8). Parity not included.  */
  436.   UBYTE write_length,     /* Nr of bits, write (1-8). Parity not included. */
  437.   UBYTE stop_length,      /* Nr of bits, stop (1 or 2).                    */
  438.   UBYTE serial_flags,     /* Serial flags.                                 */
  439.   ULONG extended_flags,   /* Additional serial flags.                      */
  440.   UBYTE *eof_chars        /* Pointer to an array containing eight end-of-  */
  441.                           /* file characters.                              */
  442. )
  443. {
  444.   int loop;           /* Used in the loop.      */
  445.   UBYTE *ptr;         /* Unsigned byte pointer. */
  446.   
  447.   
  448.   /* Set the size of the Serial Device's own input buffer: */
  449.   ioreq->io_RBufLen = buffer_length;
  450.   
  451.   /* Set baud rate: */
  452.   ioreq->io_Baud = baud_rate;
  453.   
  454.   /* Set break time (in microseconds): */
  455.   ioreq->io_BrkTime = break_time;  
  456.   
  457.   /* Nr of bits to read per character: */
  458.   ioreq->io_ReadLen = read_length;
  459.  
  460.   /* Nr of bits to write per character: */
  461.   ioreq->io_WriteLen = write_length;
  462.   
  463.   /* Nr of stop bits: (Normally 1, if write_length is */
  464.   /* equal to 7 you may set stop_length to 2.)        */
  465.   ioreq->io_StopBits = stop_length;
  466.  
  467.   /* Set serial flags: */
  468.   ioreq->io_SerFlags = serial_flags;
  469.  
  470.   /* Set additional flags: */
  471.   ioreq->io_ExtFlags = extended_flags;
  472.   
  473.   
  474.   /* Get the address of the IOTArray: */
  475.   ptr = (UBYTE *) &(ioreq->io_TermArray);
  476.  
  477.   /* Set all eight end of file characters: */
  478.   for( loop=0; loop < 8; loop++ )
  479.   {
  480.     /* Copy character after character: */
  481.     *ptr = eof_chars[ loop ];
  482.  
  483.     /* Step one byte foreward: */
  484.     ptr++;
  485.   }
  486.   
  487.   
  488.   /* All values have now been set, lets do a SDCMD_SETPARAMS request: */
  489.   ioreq->IOSer.io_Command = SDCMD_SETPARAMS;
  490.   
  491.   /* Do our request, and when complete return 0 if */
  492.   /* OK, else an error value:                      */
  493.   return( (UBYTE) DoIO( ioreq ) );
  494. }
  495.  
  496.  
  497. /* SerError() tells the user what went wrong. You give it the error code */
  498. /* you received, and SerError() will print a short description of the    */
  499. /* problem. Useful when debugging.                                       */
  500. /*                                                                       */
  501. /* Synopsis: SerError( error );                                          */
  502. /*                                                                       */
  503. /* error:    (UBYTE) The error value you want to have explained.         */
  504.  
  505. void SerError( UBYTE error )
  506. {
  507.   switch( error )
  508.   {
  509.     case SerErr_DevBusy:
  510.       printf( "Some other task is already using the Serial Device!\n" );
  511.       break;
  512.     case SerErr_BufErr:
  513.       printf( "Not enough memory for the new input buffer!\n" );
  514.       break;
  515.     case SerErr_InvParam:
  516.       printf( "Invalid parameters!\n" );
  517.       break;
  518.     case SerErr_LineErr:
  519.       printf( "Line error!\n" );
  520.       break;
  521.     case SerErr_ParityErr:
  522.       printf( "Problems with the parity!\n" );
  523.       break;
  524.     case SerErr_TimerErr:
  525.       printf( "Timer error!\n" );
  526.       break;
  527.     case SerErr_BufOverflow:
  528.       printf( "Buffer overflowed!\n" );
  529.       break;
  530.     case SerErr_NoDSR:
  531.       printf( "No DSR!\n" );
  532.       break;
  533.     case SerErr_DetectedBreak:
  534.       printf( "A break was detected!\n" );
  535.       break;
  536.   }
  537. }
  538.  
  539.  
  540.  
  541. /* SerWriteNoWait() sends some data to the Serial Port, but returns */
  542. /* immediately. You only have to give it a pointer to the data you  */
  543. /* want to write and tell it how many bytes you want to transfer.   */
  544. /* Since it does not wait for the request to be completed, you have */
  545. /* to take care of removing the message yourself. Note that all     */
  546. /* requests that have been started must be completed or aborted     */
  547. /* before your program may close the serial device.                 */
  548. /*                                                                  */
  549. /* Synopsis: error = SerWriteNoWait( io, data, length );            */
  550. /*                                                                  */
  551. /* io:       (struct IOExtSer *) Pointer to an initialized serial   */
  552. /*           request block.                                         */
  553. /*                                                                  */
  554. /* data:     (BYTE *) Pointer to the first byte of the data you     */
  555. /*           want to send (write).                                  */
  556. /*                                                                  */
  557. /* length:   (ULONG) How many bytes you want to transfer. If you    */
  558. /*           want to continue to send data until we have received   */
  559. /*           an end-of-file character, set the length to -1. (Note  */
  560. /*           that it will then ONLY stop when it receives one of    */
  561. /*           the end-of-file characters.)                           */
  562.  
  563. void SerWriteNoWait(
  564.   struct IOExtSer *ioreq, /* Pointer to our serial request block.     */
  565.   BYTE *data,             /* Pointer to the data you want to send.    */
  566.   ULONG length            /* The length of the data you want to send. */
  567. )
  568. {
  569.   /* We want to send (write) some data: */
  570.   ioreq->IOSer.io_Command = CMD_WRITE;
  571.  
  572.   /* Give the start address of our data: */
  573.   ioreq->IOSer.io_Data = (APTR) data;
  574.  
  575.   /* Set the length of the message: */
  576.   ioreq->IOSer.io_Length = length;
  577.  
  578.   /* Do our request and return immediately: */
  579.   SendIO( ioreq );
  580. }
  581.  
  582.  
  583.  
  584. /* SerReadNoWait() reads some data from the Serial Port, but returns  */
  585. /* immediately. You only have to give it a pointer to some memory     */
  586. /* where the data should be stored, and tell it how many bytes you    */
  587. /* want to read. Since it does not wait for the request to be         */
  588. /* completed, you have to take care of removing the message yourself. */
  589. /* Note that all requests that have been started must be completed or */
  590. /* aborted before your program may close the serial device.           */
  591. /*                                                                    */
  592. /*                                                                    */
  593. /* Synopsis: error = SerReadNoWait( io, data, length );               */
  594. /*                                                                    */
  595. /* io:       (struct IOExtSer *) Pointer to an initialized serial     */
  596. /*           request block.                                           */
  597. /*                                                                    */
  598. /* data:     (BYTE *) Pointer to the memory buffer where you want to  */
  599. /*           store all data.                                          */
  600. /*                                                                    */
  601. /* length:   (ULONG) How many bytes you want to read. If you want to  */
  602. /*           continue to send data until we have received an end-of-  */
  603. /*           file character, set the length to -1. (Note that it      */
  604. /*           will then ONLY stop when it receives one of the end-of-  */
  605. /*           file characters.)                                        */
  606.  
  607. void SerReadNoWait(
  608.   struct IOExtSer *ioreq, /* Pointer to our serial request block. */
  609.   BYTE *data,             /* Where the data should be placed.     */
  610.   ULONG length            /* How many bytes you want to read.     */
  611. )
  612. {
  613.   /* We want to read some data: */
  614.   ioreq->IOSer.io_Command = CMD_READ;
  615.  
  616.   /* Give the start address of our data: */
  617.   ioreq->IOSer.io_Data = (APTR) data;
  618.  
  619.   /* Set how many bytes you want to read: */
  620.   ioreq->IOSer.io_Length = length;
  621.  
  622.   /* Do our request and return immediately: */
  623.   DoIO( ioreq );
  624. }
  625.  
  626.