home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / datafiles / text / c_manual / devices / serialdevice / example1.c < prev    next >
C/C++ Source or Header  |  1995-02-27  |  23KB  |  549 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:    Example1.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 program demonstrates how you can use the Serial Device */
  23. /* to read and write information from and to the Serial Port.  */
  24. /* Since I do not know what you have connected to your serial  */
  25. /* port, this program does not do very much. However, the      */
  26. /* functions are easy to call, so it should not be hard for    */
  27. /* you to change this program into a nice serial communication */
  28. /* package.                                                    */
  29. /*                                                             */
  30. /* If you have a Sharp JX-100 scanner you can run this program */
  31. /* since it will try to turn the lamp on and then off again.   */
  32. /* Very useful! (hmmm...) The progarm does not check if there  */
  33. /* is any contact with the scanner, nor if the lamp really was */
  34. /* turned on or not.                                           */
  35.  
  36.  
  37.  
  38. #include <exec/types.h>        /* STRPTR         */
  39. #include <devices/serial.h>    /* Serial Device  */
  40.  
  41.  
  42.  
  43. /* Size of our data buffer: */
  44. #define MY_BUFFER_SIZE 200
  45.  
  46. /* Size of the Serial Device's own input buffer: (Must be */
  47. /* at least 512 bytes, but more is recommended.)          */
  48. #define INPUT_BUFFER_SIZE 1024
  49.  
  50. /* Read 8 bits/character: */
  51. #define READ_LENGTH   8
  52.  
  53. /* Write 8 bits/character: */
  54. #define WRITE_LENGTH  8
  55.  
  56. /* Sen 1 stop bit between each character: */
  57. #define STOP_LENGTH  1
  58.  
  59. /* Break time in microseconds: (1/2 sec) */
  60. #define BREAK_TIME    500000
  61.  
  62. /* Baud rate: */
  63. #define BAUD_RATE     9600
  64.  
  65. /* Serial flags: (Parity enabled, checking for end of file characters.) */
  66. #define SERIAL_FLAGS SERF_PARTY_ON|SERF_EOFMODE
  67.  
  68. /* Additional flags: (Mark-space parity not used.) */
  69. #define ADDITIONAL_FLAGS 0
  70.  
  71.  
  72.  
  73.  
  74.  
  75. /* Declare a pointer to our reply port: */
  76. struct MsgPort *replymp = NULL;
  77.  
  78. /* Declare a pointer to our serial request block: */
  79. struct IOExtSer *serial_req = NULL;
  80.  
  81. /* Store the serial device error here: */
  82. UWORD serial_dever = TRUE;
  83.  
  84. /* Declare our data buffer: */
  85. BYTE 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: */
  116. UBYTE SerWrite(
  117.   struct IOExtSer *ioreq,
  118.   BYTE *data,
  119.   ULONG length
  120. );
  121.  
  122. /* Reads data from the Serial Port: */
  123. UBYTE SerRead(
  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.   /* The eight end-of-file characters: */
  137.   /* They MUST be in descending order! */
  138.   UBYTE eof_char[8]={ 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00 };
  139.   
  140.   
  141.   
  142.   /* Get a reply port: (No name, priority 0) */
  143.   replymp = (struct MsgPort *)
  144.     CreatePort( NULL, 0 );
  145.   if( !replymp )
  146.     clean_up( 0, "Could not create the reply port!" );
  147.  
  148.  
  149.  
  150.   /* Create a serial request block: */
  151.   serial_req = (struct IOExtSer *)
  152.     CreateExtIO( replymp, sizeof( struct IOExtSer ) );
  153.   if( !serial_req )
  154.     clean_up( 0, "Not enough memory for the serial request block!" );
  155.  
  156.  
  157.  
  158.   /* Open the Serial Device: */
  159.   serial_dever = OpenDevice( SERIALNAME, 0, serial_req, 0 );
  160.   if( serial_dever )
  161.     clean_up( 0, "Could not open the Serial Device!" );
  162.  
  163.  
  164.  
  165.   error = (UBYTE) SetSerParams(
  166.     serial_req,        /* Pointer to our serial request block.          */
  167.     INPUT_BUFFER_SIZE, /* Size of the Serial Device's own input buffer. */
  168.     BAUD_RATE,         /* Baud rate (read and write). [112 - 292000]    */
  169.     BREAK_TIME,        /* Break time in microseconds.                   */
  170.     READ_LENGTH,       /* # of bits/char (1-8). Parity not included.    */
  171.     WRITE_LENGTH,      /* # of bits/char (1-8). Parity not included.    */
  172.     STOP_LENGTH,       /* # of stop bits between the characters. (1-2)  */
  173.     SERIAL_FLAGS,      /* Serial flags.                                 */
  174.     ADDITIONAL_FLAGS,  /* Additional flags.                             */
  175.     eof_char           /* Pointer to an array of eight end-of-file chr. */
  176.   );
  177.  
  178.   /* OK? */
  179.   if( error )
  180.     clean_up( error, "Could not set the serial parameters!" );
  181.  
  182.  
  183.  
  184.   /* These two bytes will turn on the lamp on a Sharp JX-100 */
  185.   /* color scanner, if it happens to be connected to your    */
  186.   /* serial port: (It is a nice scanner...)                  */ 
  187.   buffer[ 0 ] = 0x4C;
  188.   buffer[ 1 ] = 0x31;
  189.   
  190.   /* Send 2 bytes to the serial port: */
  191.   error = SerWrite( serial_req, buffer, 2 ); 
  192.   if( error )
  193.     SerError( error );       /* ERROR */
  194.   else
  195.     printf( "Lamp ON!\n" );  /* OK    */
  196.  
  197.  
  198.  
  199.   /* These two bytes will turn off the lamp on the scanner: */
  200.   buffer[ 0 ] = 0x4C;
  201.   buffer[ 1 ] = 0x30;
  202.   
  203.   /* Send 2 bytes to the serial port: */
  204.   error = SerWrite( serial_req, buffer, 2 ); 
  205.   if( error )
  206.     SerError( error );       /* ERROR */
  207.   else
  208.     printf( "Lamp OFF!\n" ); /* OK    */
  209.  
  210.  
  211.  
  212.   /* Clean up and quit: */
  213.   clean_up( 0, "The End!" );
  214. }
  215.  
  216.  
  217.  
  218. /* Close and return everything that has been */
  219. /* opened and allocated before we quit:      */
  220.  
  221. void clean_up( UBYTE error, STRPTR text )
  222. {
  223.   /* Print some information about the problem: */
  224.   if( error )
  225.     SerError( error );
  226.  
  227.   /* Close the Serial Device: */ 
  228.   if( !serial_dever )
  229.     CloseDevice( serial_req );
  230.  
  231.   /* Deallocate the serial request block: */
  232.   if( serial_req )
  233.     DeleteExtIO( serial_req, sizeof( struct IOExtSer ) );
  234.  
  235.   /* Remove the replyport: */
  236.   if( replymp )
  237.     DeletePort( replymp);
  238.  
  239.   /* Print the message: */
  240.   printf( "\n%s\n", text );
  241.  
  242.   /* Quit: */
  243.   exit( 0 );
  244. }
  245.  
  246.  
  247.  
  248. /* SetSerParams() sets the serial parameters. It initializes a IOExtSer    */
  249. /* structure, and does a SDCMD_SETPARAMS commad. If everything is OK it    */
  250. /* returns NULL, else an error number is returned.                         */
  251. /*                                                                         */
  252. /* Synopsis: er = SetSerParams( io, bl, br, bt, rl, wl, sl, sf, ef, chr ); */
  253. /*                                                                         */
  254. /* er:       (UBYTE) SetSerParams() returns 0 if everything was OK, else   */
  255. /*           an error value is returned. See function SerError() for more  */
  256. /*           information.                                                  */
  257. /*                                                                         */ 
  258. /* io:       (struct IOExtSer *) Pointer to the serial request block you   */
  259. /*           want to initialize.                                           */
  260. /*                                                                         */
  261. /* bl:       (ULONG) Size of the internal serial buffer which will be used */
  262. /*           when you read data. Must be at least 512 (bytes), but more is */
  263. /*           recommended. The faster and more data you want to read, the   */
  264. /*           bigger should the internal buffer be. Some recommended sizes: */
  265. /*           512, 1024, 2048, 4096, 8192 or 16384.                         */
  266. /*                                                                         */
  267. /* br:       (ULONG) Baud rate. Can be anything between 110 and 292000.    */
  268. /*           (Up to 292000 is all right for the hardware, but the software */
  269. /*           can not cope with this, especially since other tasks may be   */
  270. /*           running at the same time. You should therefore not use baud   */
  271. /*           rates above 31250.) Some recommended values: 110, 300, 1200,  */
  272. /*           2400, 4800, 9600, 19200 or 31250 (the last is a bit though).  */
  273. /*                                                                         */
  274. /* bt:       (ULONG) Break time in micro seconds. All break requests will  */
  275. /*           be set to this time.                                          */
  276. /*                                                                         */
  277. /* rl:       (UBYTE) How many bits chould be read for each character.      */
  278. /*           Usually 7 or 8 bits.                                          */
  279. /*                                                                         */
  280. /* wl:       (UBYTE) How many bits chould be written for each character.   */
  281. /*           Usually 7 or 8 bits.                                          */
  282. /*                                                                         */
  283. /* sl:       (UBYTE) How many stop bits shoud be written or expected.      */
  284. /*           Normally set to 1, but you may set it to 2 if rl/wl = 7.      */
  285. /*                                                                         */
  286. /* sf:       (UBYTE) You may use the following serial flags:               */
  287. /*                                                                         */
  288. /*           SERF_PARTY_ON   Parity checking/writing is turned on. (The    */
  289. /*                           sum of all data bits are divided by two, and  */
  290. /*                           the remainder is the parity bit. If even      */
  291. /*                           parity is used the bit will be set to 1 if    */
  292. /*                           the remainder is even. If odd parity is used  */
  293. /*                           the parity bit will be set to 0 if the        */
  294. /*                           remainder is even.                            */
  295. /*                                                                         */
  296. /*           SERF_PARTY_ODD  Set this flag if you want to use odd parity.  */
  297. /*                           (The default setting is even parity.)         */
  298. /*                                                                         */
  299. /*           SERF_7WIRE      This flag should only be used when you call   */
  300. /*                           the OpenDevice(), and not by this function.   */
  301. /*                           If the flag is set, seven-wire "handshaking"  */
  302. /*                           will be used. (Default is three-wire.)        */
  303. /*                                                                         */
  304. /*           SERF_QUEUEDBRK  Set this flag if you want break commands to   */
  305. /*                           be queued along with all other signals. The   */
  306. /*                           default is that a break command interrupts    */
  307. /*                           the process immediately.                      */
  308. /*                                                                         */
  309. /*           SERF_RAD_BOOGIE Set this bit if you want high speed mode.     */
  310. /*                           This can be useful when you want to send and  */
  311. /*                           receive signals at high speed. When this flag */
  312. /*                           is set no parity is used, xON/xOFF handling   */
  313. /*                           is turned off, no break signals are allowed,  */
  314. /*                           and finally only eight-bit characters are     */
  315. /*                           used.                                         */
  316. /*                                                                         */
  317. /*           SERF_SHARED     Set this falg if you want to allow other      */
  318. /*                           tasks running at the same time to use the     */
  319. /*                           serial device. The default is exclusive-      */
  320. /*                           access. (If some other task is using the      */
  321. /*                           serial device with the shared bit set, and    */
  322. /*                           you call this function with exclusive access, */
  323. /*                           your request will fail.)                      */
  324. /*                                                                         */
  325. /*           SERF_EOFMODE    Set this flag if you want to check for end of */
  326. /*                           file characters. (You may use up to eight end */
  327. /*                           of file characters, which are specified       */
  328. /*                           below.)                                       */
  329. /*                                                                         */
  330. /*           SERF_XDISABLED  xOn/xOFF handling is turned off. (Default is  */
  331. /*                           on.)                                          */
  332. /*                                                                         */
  333. /* ef:       (ULONG) You may use the following extra flags:                */
  334. /*                                                                         */
  335. /*           SEXTF_MSPON     Set this flag if you want to use mark-space   */
  336. /*                           parity rather than odd-even parity.           */
  337. /*                                                                         */
  338. /*           SEXTF_MARK      If this and the SEXTF_MSPON flag is set, it   */
  339. /*                           will mark.                                    */
  340. /*                                                                         */
  341. /* chr:      (UBYTE *) Pointer to an array containing eight end of file    */
  342. /*           characters. If the serial flag "SERF_EOFMODE" is set, the     */
  343. /*           serial device will check each character which is sent or      */
  344. /*           received, and if it matches one of the end of file characters */
  345. /*           the read/wite request is terminated.                          */
  346.  
  347. UBYTE SetSerParams(
  348.   struct IOExtSer *ioreq, /* Pointer to our serial request block.          */
  349.   ULONG buffer_length,    /* Size of the Serial Device's own input buffer. */
  350.   ULONG baud_rate,        /* Baud rate (read and write). [110 - 292000]    */
  351.   ULONG break_time,       /* Break time in microseconds.                   */
  352.   UBYTE read_length,      /* Nr of bits, read (1-8). Parity not included.  */
  353.   UBYTE write_length,     /* Nr of bits, write (1-8). Parity not included. */
  354.   UBYTE stop_length,      /* Nr of bits, stop (1 or 2).                    */
  355.   UBYTE serial_flags,     /* Serial flags.                                 */
  356.   ULONG extended_flags,   /* Additional serial flags.                      */
  357.   UBYTE *eof_chars        /* Pointer to an array containing eight end-of-  */
  358.                           /* file characters.                              */
  359. )
  360. {
  361.   int loop;           /* Used in the loop.      */
  362.   UBYTE *ptr;         /* Unsigned byte pointer. */
  363.   
  364.   
  365.   /* Set the size of the Serial Device's own input buffer: */
  366.   ioreq->io_RBufLen = buffer_length;
  367.   
  368.   /* Set baud rate: */
  369.   ioreq->io_Baud = baud_rate;
  370.   
  371.   /* Set break time (in microseconds): */
  372.   ioreq->io_BrkTime = break_time;  
  373.   
  374.   /* Nr of bits to read per character: */
  375.   ioreq->io_ReadLen = read_length;
  376.  
  377.   /* Nr of bits to write per character: */
  378.   ioreq->io_WriteLen = write_length;
  379.   
  380.   /* Nr of stop bits: (Normally 1, if write_length is */
  381.   /* equal to 7 you may set stop_length to 2.)        */
  382.   ioreq->io_StopBits = stop_length;
  383.  
  384.   /* Set serial flags: */
  385.   ioreq->io_SerFlags = serial_flags;
  386.  
  387.   /* Set additional flags: */
  388.   ioreq->io_ExtFlags = extended_flags;
  389.   
  390.   
  391.   /* Get the address of the IOTArray: */
  392.   ptr = (UBYTE *) &(ioreq->io_TermArray);
  393.  
  394.   /* Set all eight end of file characters: */
  395.   for( loop=0; loop < 8; loop++ )
  396.   {
  397.     /* Copy character after character: */
  398.     *ptr = eof_chars[ loop ];
  399.  
  400.     /* Step one byte foreward: */
  401.     ptr++;
  402.   }
  403.   
  404.   
  405.   /* All values have now been set, lets do a SDCMD_SETPARAMS request: */
  406.   ioreq->IOSer.io_Command = SDCMD_SETPARAMS;
  407.   
  408.   /* Do our request, and when complete return 0 if */
  409.   /* OK, else an error value:                      */
  410.   return( (UBYTE) DoIO( ioreq ) );
  411. }
  412.  
  413.  
  414. /* SerError() tells the user what went wrong. You give it the error code */
  415. /* you received, and SerError() will print a short description of the    */
  416. /* problem. Useful when debugging.                                       */
  417. /*                                                                       */
  418. /* Synopsis: SerError( error );                                          */
  419. /*                                                                       */
  420. /* error:    (UBYTE) The error value you want to have explained.         */
  421.  
  422. void SerError( UBYTE error )
  423. {
  424.   switch( error )
  425.   {
  426.     case SerErr_DevBusy:
  427.       printf( "Some other task is already using the Serial Device!\n" );
  428.       break;
  429.     case SerErr_BufErr:
  430.       printf( "Not enough memory for the new input buffer!\n" );
  431.       break;
  432.     case SerErr_InvParam:
  433.       printf( "Invalid parameters!\n" );
  434.       break;
  435.     case SerErr_LineErr:
  436.       printf( "Line error!\n" );
  437.       break;
  438.     case SerErr_ParityErr:
  439.       printf( "Problems with the parity!\n" );
  440.       break;
  441.     case SerErr_TimerErr:
  442.       printf( "Timer error!\n" );
  443.       break;
  444.     case SerErr_BufOverflow:
  445.       printf( "Buffer overflowed!\n" );
  446.       break;
  447.     case SerErr_NoDSR:
  448.       printf( "No DSR!\n" );
  449.       break;
  450.     case SerErr_DetectedBreak:
  451.       printf( "A break was detected!\n" );
  452.       break;
  453.     default:
  454.       printf( "An unknown error was reported! Error nr: %d\n", error );
  455.   }
  456. }
  457.  
  458.  
  459.  
  460. /* SerWrite() sends some data to the Serial Port. You only have to */
  461. /* give it a pointer to the data you want to write and tell it how */
  462. /* many bytes you want to transfer.                                */
  463. /*                                                                 */
  464. /* Synopsis: error = SerWrite( io, data, length );                 */
  465. /*                                                                 */
  466. /* error:    (UBYTE) SerWrite() returns 0 if everything was OK,    */
  467. /*           else an error number is returned.                     */
  468. /*                                                                 */
  469. /* io:       (struct IOExtSer *) Pointer to an initialized serial  */
  470. /*           request block.                                        */
  471. /*                                                                 */
  472. /* data:     (BYTE *) Pointer to the first byte of the data you    */
  473. /*           want to send (write).                                 */
  474. /*                                                                 */
  475. /* length:   (ULONG) How many bytes you want to transfer. If you   */
  476. /*           want to continue to send data until we have received  */
  477. /*           an end-of-file character, set the length to -1. (Note */
  478. /*           that it will then ONLY stop when it receives one of   */
  479. /*           the end-of-file characters.)                          */
  480.  
  481. UBYTE SerWrite(
  482.   struct IOExtSer *ioreq, /* Pointer to our serial request block.     */
  483.   BYTE *data,             /* Pointer to the data you want to send.    */
  484.   ULONG length            /* The length of the data you want to send. */
  485. )
  486. {
  487.   /* We want to send (write) some data: */
  488.   ioreq->IOSer.io_Command = CMD_WRITE;
  489.  
  490.   /* Give the start address of our data: */
  491.   ioreq->IOSer.io_Data = (APTR) data;
  492.  
  493.   /* Set the length of the message: (If you want to continue    */
  494.   /* to write until you have received an end-of-file character, */
  495.   /* set length to -1.)                                         */
  496.   ioreq->IOSer.io_Length = length;
  497.  
  498.   /* Do our request, and return 0 if everything is OK, else */
  499.   /* return an error number:                                */
  500.   return( (UBYTE) DoIO( ioreq ) );
  501. }
  502.  
  503.  
  504.  
  505. /* SerRead() reads some data from the Serial Port. You only have to  */
  506. /* give it a pointer to some memory where the data should be stored, */
  507. /* and tell it how many bytes you want to read. The rest is done     */
  508. /* automatically.                                                    */
  509. /*                                                                   */
  510. /* Synopsis: error = SerRead( io, data, length );                    */
  511. /*                                                                   */
  512. /* error:    (UBYTE) SerRead() returns 0 if everything was OK, eles  */
  513. /*           an error number is returned.                            */
  514. /*                                                                   */
  515. /* io:       (struct IOExtSer *) Pointer to an initialized serial    */
  516. /*           request block.                                          */
  517. /*                                                                   */
  518. /* data:     (BYTE *) Pointer to the memory buffer where you want to */
  519. /*           store all data.                                         */
  520. /*                                                                   */
  521. /* length:   (ULONG) How many bytes you want to read. If you want to */
  522. /*           continue to send data until we have received an end-of- */
  523. /*           file character, set the length to -1. (Note that it     */
  524. /*           will then ONLY stop when it receives one of the end-of- */
  525. /*           file characters.)                                       */
  526.  
  527. UBYTE SerRead(
  528.   struct IOExtSer *ioreq, /* Pointer to our serial request block. */
  529.   BYTE *data,             /* Where the data should be placed.     */
  530.   ULONG length            /* How many bytes you want to read.     */
  531. )
  532. {
  533.   /* We want to read some data: */
  534.   ioreq->IOSer.io_Command = CMD_READ;
  535.  
  536.   /* Give the start address of our data: */
  537.   ioreq->IOSer.io_Data = (APTR) data;
  538.  
  539.   /* Set how many bytes you want to read. (If you want to continue  */
  540.   /* to read data until you have received an end-of-file character, */
  541.   /* set length to -1.)                                             */
  542.   ioreq->IOSer.io_Length = length;
  543.  
  544.   /* Do our request, and return 0 if everything is OK, else */
  545.   /* return an error number:                                */
  546.   return( (UBYTE) DoIO( ioreq ) );
  547. }
  548.  
  549.