/* * NAME * serial.c - 17-May-97 00:24:35 * * AUTHOR * Jon Rocatis - jon@funcom.com * * DESCRIPTION * Contains functions for controlling the serial device * */ #include #include #include #include #include #include #include #include #include "upload_protos.h" #include "serial_protos.h" #include "myecoff.h" #include "upload.h" //#define DEBUGSEND #define DEVICE_NAME "serial.device" //#define UNIT_NUMBER 0 //#define DEVICE_NAME "BaudBandit.device" #define UNIT_NUMBER 0 #define BUFSIZE 16384 // Size of ring buffer for incoming bytes from serial #define STACK_SIZE 2048 // Stack size for the serial-reader task /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// struct MsgPort *SerialMPread; struct MsgPort *SerialMPwrite; struct IOExtSer *SerialIOread; struct IOExtSer *SerialIOwrite; UBYTE buffer[BUFSIZE]; // Buffer for incoming bytes from serial interface volatile UBYTE incoming; // The incoming byte from the serial interface BOOL w4bin; // Wait for "binary" BOOL w4y; // Wait for 'Y' struct Task *task; // Our task for reading the serial device struct Task *mainTask; // Ptr to main task static LONG bufIdx; static LONG lineIdx; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void PrintLine() { LONG idx; for ( idx = lineIdx; idx != bufIdx-1; ) { printf( "%c", buffer[ idx ]); idx = (idx + 1) & (BUFSIZE-1); } printf( "\n" ); lineIdx = (bufIdx + 1) & (BUFSIZE-1); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// __saveds void Server(void) { ULONG signals; ULONG serialMask = 0; BOOL status = FALSE; BOOL doPrint = FALSE; bufIdx = 0; SerialMPread = (struct MsgPort *)CreatePort(0,0); SerialIOread = (struct IOExtSer *)CreateExtIO( SerialMPread, sizeof(struct IOExtSer) ); if ( SerialMPread && SerialIOread ) { SerialIOread->IOSer.io_Device = SerialIOwrite->IOSer.io_Device; SerialIOread->IOSer.io_Unit = SerialIOwrite->IOSer.io_Unit; SerialIOread->io_CtlChar = SerialIOwrite->io_CtlChar; if ( SerialSetParams( SerialIOread ) != 0 ) { // puts( "Error setting read serial-parameters!\n" ); // return( FALSE ); Signal( mainTask, SIGBREAKF_CTRL_F ); // Tell main task that we failed! } else { serialMask = (1L << SerialIOread->IOSer.io_Message.mn_ReplyPort->mp_SigBit); SerialIOread->IOSer.io_Command = CMD_CLEAR; SendIO( SerialIOread ); QueueSerRead(); status = TRUE; memset( buffer, 0, sizeof(buffer) ); Signal( mainTask, SIGBREAKF_CTRL_D ); // Tell main task that we're up and running } } else Signal( mainTask, SIGBREAKF_CTRL_F ); // Tell main task that we failed! do { signals = Wait( serialMask | SIGBREAKF_CTRL_F | SIGBREAKF_CTRL_E ); if ( signals & serialMask ) { // We got a byte from the PSX UBYTE temp, prev; temp = incoming; QueueSerRead(); prev = buffer[ (bufIdx-1) & (BUFSIZE-1) ]; buffer[ bufIdx ] = temp; if ((temp == 'Y') && ((prev == 'Y') || (prev == 0x0d)) ) { Signal( mainTask, SIGBREAKF_CTRL_E ); w4y = FALSE; } // Wait for '>>' if ((temp == '>') && (prev == '>')) Signal( mainTask, SIGBREAKF_CTRL_D ); // Tell main task to print stuff when we get a whole line if (doPrint && ((temp == 0x0a) || (temp == '>')) && (prev == 0x0d)) Signal( mainTask, SIGBREAKF_CTRL_E ); // Wait for 'binary' if (w4bin && (temp == 0x0d) && (prev == 'y') && (buffer[(bufIdx-2) & (BUFSIZE-1)] == 'r')) { Signal( mainTask, SIGBREAKF_CTRL_D ); w4bin = FALSE; } bufIdx = (bufIdx + 1) & (BUFSIZE-1); } if ( signals & SIGBREAKF_CTRL_E ) { // Main program wants to get notified each time we get a complete line doPrint = TRUE; // Turn on sensing for complete line lineIdx = bufIdx; // Mark start of line } } while (!(signals & SIGBREAKF_CTRL_F)); if ( status ) { AbortIO( SerialIOread ); DeleteExtIO( SerialIOread ); DeletePort( SerialMPread ); } Signal( mainTask, SIGBREAKF_CTRL_D ); // Tell main task that we're done.. Wait(0L); // Wait for death.. } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL InitTask(void) { ULONG signals; mainTask = FindTask( NULL ); task = CreateTask( "UploadTask", 2, &Server, STACK_SIZE ); if (task) { signals = Wait( SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_F ); if ( signals & SIGBREAKF_CTRL_F ) return( FALSE ); else return( TRUE ); } return( FALSE ); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void FreeTask() { BPTR fh; Signal( task, SIGBREAKF_CTRL_F ); Wait( SIGBREAKF_CTRL_D ); if (fh = Open( "T:temp.dat", MODE_NEWFILE)) { Write( fh, buffer, BUFSIZE ); Close(fh); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * NAME * QueueSerRead * * FUNCTION * Tells the serial device to wait for an incoming header from the PSX * */ void QueueSerRead( void ) { // DIAGNOSE( ("QueueSerRead()\n") ); SerialIOread->IOSer.io_Command = CMD_READ; SerialIOread->IOSer.io_Length = 1; SerialIOread->IOSer.io_Data = (APTR)&incoming; SendIO( SerialIOread ); } /* * NAME * SerialInit * * FUNCTION * Initializes the serial device and sets the baud rate * */ int SerialSetParams( struct IOExtSer *io ) { io->io_ExtFlags = 0; io->io_ReadLen = 8; io->io_WriteLen = 8; io->io_Baud = baudRate; io->io_BrkTime = 750000; io->io_StopBits = 1; io->io_RBufLen = 4096; io->io_SerFlags = SERF_RAD_BOOGIE; io->io_TermArray.TermArray0 = 0x51040303; io->io_TermArray.TermArray1 = 0x03030303; io->IOSer.io_Command = SDCMD_SETPARAMS; return( DoIO((struct IORequest *)io) ); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL SerialInit( void ) { w4bin = w4y = FALSE; SerialMPwrite = (struct MsgPort *)CreatePort(0,0); SerialIOwrite = (struct IOExtSer *)CreateExtIO( SerialMPwrite, sizeof(struct IOExtSer) ); if ( SerialMPwrite && SerialIOwrite ) { SerialIOwrite->io_SerFlags = 0; //SERF_SHARED; if ( OpenDevice(DEVICE_NAME, UNIT_NUMBER, (struct IORequest *)SerialIOwrite, 0) ) { puts( "Error initializing serial.device!" ); return( FALSE ); } if ( SerialSetParams( SerialIOwrite ) != 0) { puts( "Error setting write serial-parameters!\n" ); return( FALSE ); } return( TRUE );  // Success! } return( FALSE ); } /* * NAME * SerialClose * * FUNCTION * Closes all serial device stuff * */ void SerialClose( void ) { CloseDevice( SerialIOwrite ); DeleteExtIO( SerialIOwrite ); DeletePort( SerialMPwrite ); } /* * Sends bytes via serial interface * * Returns when all data has been transfered * */ LONG SerialSend( void *data, LONG len ) { #ifdef DEBUGSEND LONG i; UBYTE *ptr = data; printf("SerialSend() (%d bytes)\n", len); if (len > 16) { for ( i = 0; i < 16; i++ ) printf("%02x ", ptr[i]); printf("... %02x", ptr[len-1]); } else { for ( i = 0; i < len; i++ ) printf("%02x ", ptr[i]); } printf("\n\n"); #endif SerialIOwrite->IOSer.io_Command = CMD_WRITE; SerialIOwrite->IOSer.io_Length = len; SerialIOwrite->IOSer.io_Data = (APTR)data; DoIO( SerialIOwrite ); return( len ); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////