home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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 */
-