/************ defines for serial port *****/
#include <devices/serial.h>
#define SERIALDEVICE "serial.device"
#define SERIALUNIT 0
struct MsgPort *serialreplyport;
struct IOExtSer *serial_req;
int serialopen;
#define MAXLEN 8192
unsigned char buffer[MAXLEN];
char rxbuffer[MAXLEN];



/************ functions for serial port **/

/***** Open the serial port - returns 1 if ok, 0 if error. in case of error all resources opened by this function are released */
openserial(baudrate)
{	/*  Open a message port */
	serialreplyport = (struct MsgPort *) CreatePort( NULL, 0 );
     if( !serialreplyport )
	{	printf("Couldnt create message port \n");
		closeserial();
		return(0);
	}

	/*  Allocate a request block of IoExtSer type */
	serial_req = (struct IOExtSer *)
		CreateExtIO( serialreplyport, sizeof( struct IOExtSer ) );

	if( !serial_req )
	{	printf("Couldnt allocate request block \n");
		closeserial();
		return(0);
	}


	/*  Set flags and open device */
     serial_req->io_SerFlags = SERF_SHARED|SERF_7WIRE;
	serialopen=1;
	if (OpenDevice( SERIALDEVICE, SERIALUNIT, serial_req, 0 ))
	{	printf("Couldnt open the device \n");
		serialopen=0;
		closeserial();
		return(0);
	}

	/*  Set parameters */
	serial_req->io_RBufLen = 16384;	/* Set size of receive buffer */
	serial_req->io_Baud = baudrate;		/* Baud rate */
	serial_req->io_BrkTime = 500000;	/* Set break length */
	serial_req->io_ReadLen = 8;	/* Set word length to 8 bit */
	serial_req->io_WriteLen = 8;		/* Set write word length */
	serial_req->io_StopBits = 1;		/* Set no of stop bits */
	serial_req->io_SerFlags = SERF_SHARED | SERF_XDISABLED | SERF_PARTY_ON;
	serial_req->io_ExtFlags = 0;
	serial_req->IOSer.io_Command = SDCMD_SETPARAMS;


	if (DoIO( serial_req ))
	{	printf("setserial():Couldnt set parameters \n");
		closeserial();
		return(0);
	}
	
	return(1);	
}

/***** closeserial() - close the serial port and release all resources used by it *****/
closeserial()
{	
	/* Close the serial port (if it was succesfully open that is) */
	if (serialopen) {CloseDevice( serial_req); serialopen=NULL;};

	/* Deallocate the serial request block (if it was succesfully allocated) */
	if( serial_req )
	{	DeleteExtIO( serial_req, sizeof( struct IOExtSer ) ); serial_req=NULL;}
	
	/* Remove the reply message port (if it exists) */
	if( serialreplyport )
	{	DeletePort( serialreplyport); serialreplyport=NULL;}
	return(1);
}


/***** Return the number of chars waiting in the buffer or -1 if error */
serchars()
{	serial_req->IOSer.io_Command = SDCMD_QUERY;
	if (DoIO(serial_req))
		return(-1); /* could not get info */
	else
		return((int)serial_req->IOSer.io_Actual);
}

/***** read characters from serial port *****/
readserial(buffer,maxlen)
	char *buffer;
	int maxlen;
{
		int numchars=0,error=0;
		if (buffer==NULL) return(-1);

		/* check serial port for characters and read them */
		numchars=serchars();
		if (numchars>maxlen) numchars=maxlen;
		if (numchars>0)
		{
			serial_req->IOSer.io_Command=CMD_READ;
			serial_req->IOSer.io_Length = numchars;
			serial_req->IOSer.io_Data = (APTR)buffer;
			if (error=DoIO(serial_req)) {printf("Error %d reading port: expected %d characters\n",error,numchars);return(-999);}
		}
		return(numchars);
}

/***** read characters from serial port, without any checking *****/
flushserial(unsigned char *buff,int maxlen, int show)
{
		char buffer[80];
		int count=0;
		if (show) printf("RX-> ");
		if (buff==NULL || maxlen<1) return(0);
		if (serial_req==NULL) return(0);
		/* check serial port for characters and read them */
		while(serchars())
		{
			buffer[0]=0xff;
			serial_req->IOSer.io_Command=CMD_READ;
			serial_req->IOSer.io_Length = 1;
			serial_req->IOSer.io_Data = (APTR)&buff[count];
			if (DoIO(serial_req)) {if (show) printf("!");} else {if (show) printf("+");}
			if (show) printf("%02x ",(int)buff[count]);
			count++;
			if (count>=maxlen) count=maxlen-1;
			if (!serchars()) Delay(10);
		}
		if (show) printf("\n");
		return(count);
}


/***** write characters to serial port *****/		
writeserial(buffer,len)
	char *buffer;
	int len;
{
	int error;
	serial_req->IOSer.io_Command=CMD_WRITE;
	serial_req->IOSer.io_Length = len;
	serial_req->IOSer.io_Data = (APTR)buffer;
	if (error=DoIO(serial_req)) {printf("Error %d writing to port\n",error);return(-1);}	
	return(len);
}

/***** send a single byte to the serial port *****/
sendchar(byte)
	char byte;
{
	int error,len=1;
	serial_req->IOSer.io_Command=CMD_WRITE;
	serial_req->IOSer.io_Length = len;
	serial_req->IOSer.io_Data = (APTR)&byte;
	if (error=DoIO(serial_req)) {printf("Error %d writing to port\n",error);return(-1);}	
	return(len);
}
