home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
199.lha
/
GimmeLib
/
communic.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-12-27
|
9KB
|
379 lines
/*
* FILE: communic.c
* Support routines for accessing, reading and writing to the serial port.
*
* NOTE: these routines provide EXCLUSIVE access to the serial port for one
* task only. This shouldn't be too great a problem given the nature of the
* serial port.
*
* Public Domain, but keep our names in it as the original authors.
* 11-May-87 Scotte Zinn created
* 15-Mar-88 Jan Sven Trabandt changed c_set_error to a macro
* made sure it works with short (16 bit) ints
* 27-Apr-88 Jan Sven Trabandt lots of goodies
* 31-Oct-88 Jan Sven Trabandt added to gimme.lib (finally)
*/
#define I_AM_COMMUNIC
#include "gimmelib/gimmefuncs.h"
#include "gimmelib/communic.h"
#include <devices/serial.h>
#define C_NOT_OPEN 0
#define BUFFER_LENGTH 4096
#define INIT_VALUE 29451
#define initialized() ((SHORT)initial != 0)
#define channel_open() ((SHORT)system_state != C_NOT_OPEN)
#define c_set_error(err) (c_error = err)
static struct IOExtSer *IORser = NULL;
static struct MsgPort *SPort = NULL;
static struct timerequest *treq = NULL;
static char EOLchar = DEFAULT_EOL;
static SHORT system_state = C_NOT_OPEN;
static SHORT initial = 0;
short c_error;
/* forward declarations */
static short c_getchar();
short c_init()
{
if( !initialized() ) {
/* Set system state to channel not open and set initialized flag */
Forbid();
initial = INIT_VALUE;
system_state = C_NOT_OPEN;
Permit();
}
return( c_set_error(C_ERR_OK) );
} /* c_init */
short c_open( parms )
struct c_parameters *parms;
{
short error;
if( !parms ) {
return( c_set_error(C_ERR_BADPARM) );
}
if( !initialized() )
return( c_set_error(C_ERR_INITIAL) );
if( channel_open() )
return( c_set_error(C_ERR_OPEN) );
/* Now access timer device for future time-outs and to get a Port */
if( !(treq = accessTimer(UNIT_VBLANK, &SPort)) ) {
return( c_set_error(C_ERR_CANT) );
}
IORser = (struct IOExtSer *) CreateExtIO( SPort,
(ULONG)sizeof(struct IOExtSer) );
if( !IORser ) {
releaseTimer( treq, NULL );
return( c_set_error(C_ERR_CANT) );
}
if( parms->C_MODE == C_SER_7 ) {
IORser->io_SerFlags = SERB_7WIRE | SERB_XDISABLED;
}
if( OpenDevice(SERIALNAME, 0L, IORser, 0L) ) {
DeleteExtIO( IORser, (ULONG)sizeof(struct IOExtSer) );
releaseTimer( treq, NULL );
return( c_set_error(C_ERR_CANT) );
}
system_state = -1; /* Now set channel opened */
if( error = c_setup(parms) ) {
CloseDevice( IORser );
DeleteExtIO( IORser, (ULONG)sizeof(struct IOExtSer) );
releaseTimer( treq, NULL );
system_state = C_NOT_OPEN;
return( c_set_error(error) );
}
EOLchar = DEFAULT_EOL;
/* Channel is now successfully opened */
return( c_set_error(C_ERR_OK) );
} /* c_open */
short c_setup( parms )
struct c_parameters *parms;
{
if( !(initialized() && channel_open()) ) /* important to check here */
return( c_set_error(C_ERR_CHAN) );
if( !parms ) {
return( c_set_error(C_ERR_BADPARM) );
}
/* Now set parameters as requested */
IORser->io_ReadLen = parms->C_RLEN;
IORser->io_BrkTime = 750000L;
IORser->io_Baud = parms->C_BAUD;
IORser->io_WriteLen = parms->C_WLEN;
IORser->io_StopBits = parms->C_STOP;
IORser->io_RBufLen = BUFFER_LENGTH;
/* Setup parity bits with validation */
IORser->io_SerFlags &= ~(SERB_PARTY_ODD & SERB_PARTY_ON);
switch( parms->C_PARITY ) {
case C_NO_PARITY:
break;
case C_ODD_PARITY:
IORser->io_SerFlags |= SERB_PARTY_ODD | SERB_PARTY_ON;
break;
case C_EVEN_PARITY:
IORser->io_SerFlags |= SERB_PARTY_ON;
break;
default:
return( c_set_error(C_ERR_PARITY) );
} /* switch */
IORser->IOSer.io_Command = SDCMD_SETPARAMS;
IORser->io_TermArray.TermArray0 = 0x51040303;
IORser->io_TermArray.TermArray1 = 0x03030303;
if( DoIO(IORser) )
return( c_set_error(C_ERR_PARAMS) );
/* Parameters were changed as needed */
return( c_set_error(C_ERR_OK) );
} /* c_setup */
/* internal use only!
static short c_getchar( cinput, secs, micros )
char *cinput;
ULONG secs, micros;
{
APTR myptr;
short iodone = 0;
/* Send request for read a character */
IORser->IOSer.io_Data = (APTR) cinput;
IORser->IOSer.io_Length = 1;
IORser->IOSer.io_Command = CMD_READ;
SendIO( IORser );
if( CheckIO(IORser) ) {
Remove( IORser );
return( c_set_error(C_ERR_OK) );
} else {
timeDelayAsync( secs, micros, UNIT_VBLANK, treq );
WaitPort( SPort );
while( myptr = (APTR) GetMsg(SPort) ) {
if( myptr == (APTR) IORser ) {
iodone = -1;
}
} /* while */
if( iodone ) {
killTimeDelay( treq );
return( c_set_error(C_ERR_OK) );
}
}
/* Abort the requested IO and return error condition */
AbortIO( IORser );
Remove( IORser );
return( c_set_error(C_ERR_GET) );
} /* c_getchar */
short c_getc( cinput )
char *cinput;
{
#ifdef GIMME_WIMPY
if( !(initialized() && channel_open()) )
return( c_set_error(C_ERR_CHAN) );
if( !buffer ) {
return( c_set_error(C_ERR_BADPARM) );
}
#endif
return( c_getchar(cinput, BIG_SECS, BIG_MICROS) );
} /* c_getc */
short c_emptyc()
{
short err;
char cinput;
#ifdef GIMME_WIMPY
if( !(initialized() && channel_open()) )
return( c_set_error(C_ERR_CHAN) );
#endif
/* Empty the buffer */
while( (err = c_getchar(&cinput, SMALL_SECS, SMALL_MICROS)) == C_ERR_OK ) {
} /* while */
/* Check for a buffer empty error and replace with ok status */
if( err == C_ERR_GET ) {
c_set_error(err = C_ERR_OK);
}
/* Return status of empty */
return( err );
} /* c_emptyc */
short c_putc( coutput )
char coutput;
{
#ifdef GIMME_WIMPY
if( !(initialized() && channel_open()) )
return( c_set_error(C_ERR_CHAN) );
#endif
/* Now send character thru channel */
IORser->IOSer.io_Data = (APTR) &coutput;
IORser->IOSer.io_Length = 1;
IORser->IOSer.io_Command = CMD_WRITE;
if( DoIO(IORser) ) {
return( c_set_error(C_ERR_PUT) );
}
return( c_set_error(C_ERR_OK) );
} /* c_putc */
short c_gets( buffer, num_to_get )
char *buffer;
SHORT num_to_get;
{
register SHORT i;
short error;
#ifdef GIMME_WIMPY
if( !(initialized() && channel_open()) )
return( c_set_error(C_ERR_CHAN) );
if( !buffer ) {
return( c_set_error(C_ERR_BADPARM) );
}
#endif
if( num_to_get <= 0 ) {
return( c_set_error(C_ERR_ILLEGAL) );
}
/* Now get the specified number of characters */
for( i = num_to_get; --i >= 0; ++buffer ) {
if( error = c_getchar(buffer, BIG_SECS, BIG_MICROS) ) {
return( c_set_error(error) );
}
} /* for */
return( c_set_error(C_ERR_OK) );
} /* c_gets */
short c_getline( buffer, num_to_get )
char *buffer;
SHORT num_to_get;
{
register SHORT i;
short error;
#ifdef GIMME_WIMPY
if( !(initialized() && channel_open()) )
return( c_set_error(C_ERR_CHAN) );
if( !buffer ) {
return( c_set_error(C_ERR_BADPARM) );
}
#endif
if( num_to_get <= 0 ) {
return( c_set_error(C_ERR_ILLEGAL) );
}
/* Now get the specified number of characters */
for( i = num_to_get; --i >= 0; ++buffer ) {
if( error = c_getchar(buffer, SMALL_SECS, SMALL_MICROS) ) {
*buffer = '\0';
return( c_set_error(error) );
}
if( *buffer == EOLchar ) {
break;
}
} /* for */
return( c_set_error(C_ERR_OK) );
} /* c_getline */
short c_setEOL( character )
char character;
{
#ifdef GIMME_WIMPY
if( !(initialized() && channel_open()) )
return( c_set_error(C_ERR_CHAN) );
#endif
EOLchar = character;
return( c_set_error(C_ERR_OK) );
} /* c_setEOL */
short c_puts( buffer, num_to_put )
char *buffer;
SHORT num_to_put;
{
short error;
#ifdef GIMME_WIMPY
if( !(initialized() && channel_open()) )
return( c_set_error(C_ERR_CHAN) );
if( !buffer ) {
return( c_set_error(C_ERR_BADPARM) );
}
#endif
if( num_to_put <= 0 ) {
return( c_set_error(C_ERR_ILLEGAL) );
}
/* Now send the characters thru channel */
IORser->IOSer.io_Data = (APTR) buffer;
IORser->IOSer.io_Length = num_to_put;
IORser->IOSer.io_Command = CMD_WRITE;
if( DoIO(IORser) ) {
return( c_set_error(C_ERR_PUT) );
}
return( c_set_error(C_ERR_OK) );
} /* c_puts */
short c_close()
{
short err;
#ifdef GIMME_WIMPY
if( !(initialized() && channel_open()) )
return( c_set_error(C_ERR_CHAN) );
#endif
if( err = c_emptyc() ) { /* Empty the buffer */
return( err );
}
/* Now close device and channel */
CloseDevice( IORser );
DeleteExtIO( IORser, (ULONG)sizeof(struct IOExtSer) );
releaseTimer( treq, NULL ); /* Now close timer device */
SPort = NULL;
system_state = C_NOT_OPEN;
return( c_set_error(C_ERR_OK) );
} /* c_close */
short c_done()
{
if( initialized() ) {
/* Set system state to channel not open and clear initialized flag */
Forbid();
initial = 0;
system_state = C_NOT_OPEN;
Permit();
}
return( c_set_error(C_ERR_OK) );
} /* c_done */