home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
datafiles
/
text
/
c_manual
/
devices
/
serialdevice
/
example2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-27
|
23KB
|
561 lines
/***********************************************************/
/* */
/* Amiga C Encyclopedia (ACE) V3.0 Amiga C Club (ACC) */
/* ------------------------------- ------------------ */
/* */
/* Book: ACM Devices Amiga C Club */
/* Chapter: Serial Device Tulevagen 22 */
/* File: Example2.c 181 41 LIDINGO */
/* Author: Anders Bjerin SWEDEN */
/* Date: 92-04-26 */
/* Version: 1.00 */
/* */
/* Copyright 1992, Anders Bjerin - Amiga C Club (ACC) */
/* */
/* Registered members may use this program freely in their */
/* own commercial/noncommercial programs/articles. */
/* */
/***********************************************************/
/* This program demonstrates how you can use the Serial Device */
/* to read and write information from and to the Serial Port. */
/* Since I do not know what you have connected to your serial */
/* port, this program does not do very much. However, the */
/* functions are easy to call, so it should not be hard for */
/* you to change this program into a nice serial communication */
/* package. */
/* */
/* This example is rather similar to Example 1, but this time */
/* we do not wait for the serial port to complete our request. */
/* Instead we do somethings (well not very much) and now and */
/* then checks if the request has been completed. */
#include <exec/types.h> /* STRPTR */
#include <devices/serial.h> /* Serial Device */
/* Size of our data buffer: */
#define MY_BUFFER_SIZE 200
/* Size of the Serial Device's own input buffer: (Must be */
/* at least 512 bytes, but more is recommended.) */
#define INPUT_BUFFER_SIZE 1024
/* Read 8 bits/character: */
#define READ_LENGTH 8
/* Write 8 bits/character: */
#define WRITE_LENGTH 8
/* Sen 1 stop bit between each character: */
#define STOP_LENGTH 1
/* Break time in microseconds: (1/2 sec) */
#define BREAK_TIME 500000
/* Baud rate: */
#define BAUD_RATE 9600
/* Serial flags: (Parity enabled, checking for end of file characters.) */
#define SERIAL_FLAGS SERF_PARTY_ON|SERF_EOFMODE
/* Additional flags: (Mark-space parity not used.) */
#define ADDITIONAL_FLAGS 0
/* Declare a pointer to our reply port: */
struct MsgPort *replymp = NULL;
/* Declare a pointer to our serial request block: */
struct IOExtSer *serial_req = NULL;
/* Store the serial device error here: */
UWORD serial_dever = TRUE;
/* Declare our data buffer: */
BYTE buffer[ MY_BUFFER_SIZE ];
/* Declare our functions: */
/* Our main function: */
void main();
/* Clears and removes everything nice and neatly: */
void clean_up( UBYTE error, STRPTR text );
/* Sets serial parameters: */
UBYTE SetSerParams(
struct IOExtSer *ioreq,
ULONG buffer_length,
ULONG baud_rate,
ULONG break_time,
UBYTE read_length,
UBYTE write_length,
UBYTE stop_length,
UBYTE serial_flags,
ULONG extended_flags,
UBYTE *eof_chars
);
/* Prints some information about the error: */
void SerError( UBYTE error );
/* Sends data to the Serial Port without going to sleep: */
void SerWriteNoWait(
struct IOExtSer *ioreq,
BYTE *data,
ULONG length
);
/* Reads data from the Serial Port without going to sleep: */
void SerReadNoWait(
struct IOExtSer *ioreq,
BYTE *data,
ULONG length
);
void main()
{
/* Error number: */
UBYTE error;
/* The eight end-of-file characters: */
/* They MUST be in descending order! */
UBYTE eof_char[8]={ 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00 };
/* Declare a pointer and set it to NULL: */
struct IOExtSer *ptr = NULL;
/* Get a reply port: (No name, priority 0) */
replymp = (struct MsgPort *)
CreatePort( NULL, 0 );
if( !replymp )
clean_up( 0, "Could not create the reply port!" );
/* Create a serial request block: */
serial_req = (struct IOExtSer *)
CreateExtIO( replymp, sizeof( struct IOExtSer ) );
if( !serial_req )
clean_up( 0, "Not enough memory for the serial request block!" );
/* Open the Serial Device: */
serial_dever = OpenDevice( SERIALNAME, 0, serial_req, 0 );
if( serial_dever )
clean_up( 0, "Could not open the Serial Device!" );
error = (UBYTE) SetSerParams(
serial_req, /* Pointer to our serial request block. */
INPUT_BUFFER_SIZE, /* Size of the Serial Device's own input buffer. */
BAUD_RATE, /* Baud rate (read and write). [112 - 292000] */
BREAK_TIME, /* Break time in microseconds. */
READ_LENGTH, /* # of bits/char (1-8). Parity not included. */
WRITE_LENGTH, /* # of bits/char (1-8). Parity not included. */
STOP_LENGTH, /* # of stop bits between the characters. (1-2) */
SERIAL_FLAGS, /* Serial flags. */
ADDITIONAL_FLAGS, /* Additional flags. */
eof_char /* Pointer to an array of eight end-of-file chr. */
);
/* OK? */
if( error )
clean_up( error, "Could not set the serial parameters!" );
/* These two bytes will turn on the lamp on a Sharp JX-100 */
/* color scanner, if it happens to be connected to your */
/* serial port: (To make this example simple we do not */
/* turn it off.) */
buffer[ 0 ] = 0x4C;
buffer[ 1 ] = 0x31;
/* Send 2 bytes to the serial port and return immediately: */
SerWriteNoWait( serial_req, buffer, 2 );
/* As long as the pointer is not pointing to */
/* the request we should stay in the loop: */
while( ptr == NULL )
{
/* ... do something ... */
/* Well, I do not know what. */
/* Check if the request has been completed: (If the */
/* request has been compleded CheckIO() will return */
/* a pointer to the request, else NULL is returned.) */
ptr = (struct IOExtSer *) CheckIO( serial_req );
}
/* At last the request was completed! */
/* Remove the requstblock's message. (The ptr and ioreq */
/* are in this example identical, so it does not matter */
/* whichever you will use. The paranteces around the */
/* expression is actually unnecessary, but this looks */
/* better.) */
Remove( &(ptr->IOSer.io_Message.mn_Node) );
/* Check if everything is OK? */
if( serial_req->IOSer.io_Error )
SerError( error ); /* ERROR */
else
printf( "Lamp OFF!\n" ); /* OK */
/* Clean up and quit: */
clean_up( 0, "The End!" );
}
/* Close and return everything that has been */
/* opened and allocated before we quit: */
void clean_up( UBYTE error, STRPTR text )
{
/* Print some information about the problem: */
if( error )
SerError( error );
/* Close the Serial Device: */
if( !serial_dever )
CloseDevice( serial_req );
/* Deallocate the serial request block: */
if( serial_req )
DeleteExtIO( serial_req, sizeof( struct IOExtSer ) );
/* Remove the replyport: */
if( replymp )
DeletePort( replymp);
/* Print the message: */
printf( "\n%s\n", text );
/* Quit: */
exit( 0 );
}
/* SetSerParams() sets the serial parameters. It initializes a IOExtSer */
/* structure, and does a SDCMD_SETPARAMS commad. If everything is OK it */
/* returns NULL, else an error number is returned. */
/* */
/* Synopsis: er = SetSerParams( io, bl, br, bt, rl, wl, sl, sf, ef, chr ); */
/* */
/* er: (UBYTE) SetSerParams() returns 0 if everything was OK, else */
/* an error value is returned. See function SerError() for more */
/* information. */
/* */
/* io: (struct IOExtSer *) Pointer to the serial request block you */
/* want to initialize. */
/* */
/* bl: (ULONG) Size of the internal serial buffer which will be used */
/* when you read data. Must be at least 512 (bytes), but more is */
/* recommended. The faster and more data you want to read, the */
/* bigger should the internal buffer be. Some recommended sizes: */
/* 512, 1024, 2048, 4096, 8192 or 16384. */
/* */
/* br: (ULONG) Baud rate. Can be anything between 110 and 292000. */
/* (Up to 292000 is all right for the hardware, but the software */
/* can not cope with this, especially since other tasks may be */
/* running at the same time. You should therefore not use baud */
/* rates above 31250.) Some recommended values: 110, 300, 1200, */
/* 2400, 4800, 9600, 19200 or 31250 (the last is a bit though). */
/* */
/* bt: (ULONG) Break time in micro seconds. All break requests will */
/* be set to this time. */
/* */
/* rl: (UBYTE) How many bits chould be read for each character. */
/* Usually 7 or 8 bits. */
/* */
/* wl: (UBYTE) How many bits chould be written for each character. */
/* Usually 7 or 8 bits. */
/* */
/* sl: (UBYTE) How many stop bits shoud be written or expected. */
/* Normally set to 1, but you may set it to 2 if rl/wl = 7. */
/* */
/* sf: (UBYTE) You may use the following serial flags: */
/* */
/* SERF_PARTY_ON Parity checking/writing is turned on. (The */
/* sum of all data bits are divided by two, and */
/* the remainder is the parity bit. If even */
/* parity is used the bit will be set to 1 if */
/* the remainder is even. If odd parity is used */
/* the parity bit will be set to 0 if the */
/* remainder is even. */
/* */
/* SERF_PARTY_ODD Set this flag if you want to use odd parity. */
/* (The default setting is even parity.) */
/* */
/* SERF_7WIRE This flag should only be used when you call */
/* the OpenDevice(), and not by this function. */
/* If the flag is set, seven-wire "handshaking" */
/* will be used. (Default is three-wire.) */
/* */
/* SERF_QUEUEDBRK Set this flag if you want break commands to */
/* be queued along with all other signals. The */
/* default is that a break command interrupts */
/* the process immediately. */
/* */
/* SERF_RAD_BOOGIE Set this bit if you want high speed mode. */
/* This can be useful when you want to send and */
/* receive signals at high speed. When this flag */
/* is set no parity is used, xON/xOFF handling */
/* is turned off, no break signals are allowed, */
/* and finally only eight-bit characters are */
/* used. */
/* */
/* SERF_SHARED Set this falg if you want to allow other */
/* tasks running at the same time to use the */
/* serial device. The default is exclusive- */
/* access. (If some other task is using the */
/* serial device with the shared bit set, and */
/* you call this function with exclusive access, */
/* your request will fail.) */
/* */
/* SERF_EOFMODE Set this flag if you want to check for end of */
/* file characters. (You may use up to eight end */
/* of file characters, which are specified */
/* below.) */
/* */
/* SERF_XDISABLED xOn/xOFF handling is turned off. (Default is */
/* on.) */
/* */
/* ef: (ULONG) You may use the following extra flags: */
/* */
/* SEXTF_MSPON Set this flag if you want to use mark-space */
/* parity rather than odd-even parity. */
/* */
/* SEXTF_MARK If this and the SEXTF_MSPON flag is set, it */
/* will mark. */
/* */
/* chr: (UBYTE *) Pointer to an array containing eight end of file */
/* characters. If the serial flag "SERF_EOFMODE" is set, the */
/* serial device will check each character which is sent or */
/* received, and if it matches one of the end of file characters */
/* the read/wite request is terminated. */
UBYTE SetSerParams(
struct IOExtSer *ioreq, /* Pointer to our serial request block. */
ULONG buffer_length, /* Size of the Serial Device's own input buffer. */
ULONG baud_rate, /* Baud rate (read and write). [110 - 292000] */
ULONG break_time, /* Break time in microseconds. */
UBYTE read_length, /* Nr of bits, read (1-8). Parity not included. */
UBYTE write_length, /* Nr of bits, write (1-8). Parity not included. */
UBYTE stop_length, /* Nr of bits, stop (1 or 2). */
UBYTE serial_flags, /* Serial flags. */
ULONG extended_flags, /* Additional serial flags. */
UBYTE *eof_chars /* Pointer to an array containing eight end-of- */
/* file characters. */
)
{
int loop; /* Used in the loop. */
UBYTE *ptr; /* Unsigned byte pointer. */
/* Set the size of the Serial Device's own input buffer: */
ioreq->io_RBufLen = buffer_length;
/* Set baud rate: */
ioreq->io_Baud = baud_rate;
/* Set break time (in microseconds): */
ioreq->io_BrkTime = break_time;
/* Nr of bits to read per character: */
ioreq->io_ReadLen = read_length;
/* Nr of bits to write per character: */
ioreq->io_WriteLen = write_length;
/* Nr of stop bits: (Normally 1, if write_length is */
/* equal to 7 you may set stop_length to 2.) */
ioreq->io_StopBits = stop_length;
/* Set serial flags: */
ioreq->io_SerFlags = serial_flags;
/* Set additional flags: */
ioreq->io_ExtFlags = extended_flags;
/* Get the address of the IOTArray: */
ptr = (UBYTE *) &(ioreq->io_TermArray);
/* Set all eight end of file characters: */
for( loop=0; loop < 8; loop++ )
{
/* Copy character after character: */
*ptr = eof_chars[ loop ];
/* Step one byte foreward: */
ptr++;
}
/* All values have now been set, lets do a SDCMD_SETPARAMS request: */
ioreq->IOSer.io_Command = SDCMD_SETPARAMS;
/* Do our request, and when complete return 0 if */
/* OK, else an error value: */
return( (UBYTE) DoIO( ioreq ) );
}
/* SerError() tells the user what went wrong. You give it the error code */
/* you received, and SerError() will print a short description of the */
/* problem. Useful when debugging. */
/* */
/* Synopsis: SerError( error ); */
/* */
/* error: (UBYTE) The error value you want to have explained. */
void SerError( UBYTE error )
{
switch( error )
{
case SerErr_DevBusy:
printf( "Some other task is already using the Serial Device!\n" );
break;
case SerErr_BufErr:
printf( "Not enough memory for the new input buffer!\n" );
break;
case SerErr_InvParam:
printf( "Invalid parameters!\n" );
break;
case SerErr_LineErr:
printf( "Line error!\n" );
break;
case SerErr_ParityErr:
printf( "Problems with the parity!\n" );
break;
case SerErr_TimerErr:
printf( "Timer error!\n" );
break;
case SerErr_BufOverflow:
printf( "Buffer overflowed!\n" );
break;
case SerErr_NoDSR:
printf( "No DSR!\n" );
break;
case SerErr_DetectedBreak:
printf( "A break was detected!\n" );
break;
}
}
/* SerWriteNoWait() sends some data to the Serial Port, but returns */
/* immediately. You only have to give it a pointer to the data you */
/* want to write and tell it how many bytes you want to transfer. */
/* Since it does not wait for the request to be completed, you have */
/* to take care of removing the message yourself. Note that all */
/* requests that have been started must be completed or aborted */
/* before your program may close the serial device. */
/* */
/* Synopsis: error = SerWriteNoWait( io, data, length ); */
/* */
/* io: (struct IOExtSer *) Pointer to an initialized serial */
/* request block. */
/* */
/* data: (BYTE *) Pointer to the first byte of the data you */
/* want to send (write). */
/* */
/* length: (ULONG) How many bytes you want to transfer. If you */
/* want to continue to send data until we have received */
/* an end-of-file character, set the length to -1. (Note */
/* that it will then ONLY stop when it receives one of */
/* the end-of-file characters.) */
void SerWriteNoWait(
struct IOExtSer *ioreq, /* Pointer to our serial request block. */
BYTE *data, /* Pointer to the data you want to send. */
ULONG length /* The length of the data you want to send. */
)
{
/* We want to send (write) some data: */
ioreq->IOSer.io_Command = CMD_WRITE;
/* Give the start address of our data: */
ioreq->IOSer.io_Data = (APTR) data;
/* Set the length of the message: */
ioreq->IOSer.io_Length = length;
/* Do our request and return immediately: */
SendIO( ioreq );
}
/* SerReadNoWait() reads some data from the Serial Port, but returns */
/* immediately. You only have to give it a pointer to some memory */
/* where the data should be stored, and tell it how many bytes you */
/* want to read. Since it does not wait for the request to be */
/* completed, you have to take care of removing the message yourself. */
/* Note that all requests that have been started must be completed or */
/* aborted before your program may close the serial device. */
/* */
/* */
/* Synopsis: error = SerReadNoWait( io, data, length ); */
/* */
/* io: (struct IOExtSer *) Pointer to an initialized serial */
/* request block. */
/* */
/* data: (BYTE *) Pointer to the memory buffer where you want to */
/* store all data. */
/* */
/* length: (ULONG) How many bytes you want to read. If you want to */
/* continue to send data until we have received an end-of- */
/* file character, set the length to -1. (Note that it */
/* will then ONLY stop when it receives one of the end-of- */
/* file characters.) */
void SerReadNoWait(
struct IOExtSer *ioreq, /* Pointer to our serial request block. */
BYTE *data, /* Where the data should be placed. */
ULONG length /* How many bytes you want to read. */
)
{
/* We want to read some data: */
ioreq->IOSer.io_Command = CMD_READ;
/* Give the start address of our data: */
ioreq->IOSer.io_Data = (APTR) data;
/* Set how many bytes you want to read: */
ioreq->IOSer.io_Length = length;
/* Do our request and return immediately: */
DoIO( ioreq );
}