/* Bring in some stuff via RS 232 and scroll it on the LCD of a LP3100
	This program can also be used to receive input from a telnet session to the data port of the EM1000.

	Note:  This is a very simple program that does not take advantage of costatements or rtk at this time
	       The user must wait for the ">" to appear on the terminal or telnet screen prior to entering text.
	       
	       When this program is used in conjunction with an EM1000, it should be viewed as the slave controller
	       that receives a message to be scrolled on an LCD 

	       If you don't see the prompt on your terminal or telnet screen please press the reset buttom on the
	       LP3100 slave to get it.

*/


//	Author:						Richard Jensen Zworld Technical Support
// Revision history:			12/17/99  1.0.0  initial program run
//									12/20/99  1.0.1  added lcd scroll function to allow for variable length strings from the RS 232

#use aascz0.lib								//Included for  Serial Communications AASC use of Z0 port
#use eziolp31.lib								//Included for LP3100 board initialization
#use tl_lp31.lib								//Included for LP3100 LCD functions
#use tl.lib										//Included for LP3100 LCD functions	
#use vdriver.lib								//Included for virtural watch dog & MS_TIMER use 

char rBuf[128];								//To be used by AASC library only.  
char wBuf[128];								//To be used by AASC library only.  

int Scroll(char Array[] , int TopOrBot, int Speed);
void delay(long delaytime);

main()
{
//*********************************************** Board & variables setup *****************************************************	
	auto int count,k, i;
	char scanBuf[128];						//working buffer #2 recommended maximum size
	char localBuf[128];						//Working buffer #1 
	auto struct _Channel *chan;

	lcdInit();									//Initialize hardware
	eioBrdInit(0);									//initialize lp3100  
	VdInit();										//hit virtual watch dog every 25 ms & performs global init
	outport(0x4084,1);							//flip the RS 232 driver anc CTS switches to set 
	outport(0x4083,1);							//up both 232 for operation 
	outport(0x4082,1);	

	chan = aascOpen(DEV_Z0,						//Set communications to use Z0 at 19,200
		0,
		ASCI_PARAM_8N1+ASCI_PARAM_1200*16,
		NULL);

	aascSetReadBuf(chan,rBuf,sizeof(rBuf));	//Designate circular buffers for AASC use
	aascSetWriteBuf(chan,wBuf,sizeof(wBuf));

	memset(scanBuf, '\0', sizeof scanBuf);			//Initialize variables
	memset(localBuf, '\0', sizeof localBuf);		
	count=k=i=0;
//*********************************************** Read input ***************************************************     		
	aascRxSwitch(chan, 1);
	aascTxSwitch(chan, 1);
	aascWriteChar(chan, '>');							//Put prompt on dumb terminal or telnet screen
	while (1)
	{
		if(aascReadChar(chan, &localBuf[i]))  	//Receive input from EM1000 and place in working buffer "localBuf"
		{
		
			if((localBuf[i] != '\r'))	  			//Copy from working buffer #1 to working buffer #2
				{
					scanBuf[i] = localBuf[i];
					i++;
				}
//*********************************************** Send input to LCD via Scroll function ************************
				else
				{
					lcdInit();							//Reset lcd display
					scanBuf[strlen(scanBuf)] = '\0'; 	//Replace \r in string with a null terminator
					Scroll(scanBuf, 1, 600);			 //Scroll once through the string
													
//*********************************************** Set up for next pass *****************************************
					count++;	
					memset(scanBuf, '\0', strlen(scanBuf));		//clean up arrays and variables for reuse
					memset(localBuf, '\0', strlen(localBuf));
					aascFlush(chan);
					k = i = 0;
					aascWriteChar(chan, '>');							//Put prompt on dumb terminal or telnet screen
		      }
		}//********************************* End of if read statement  *******************************************		
   }//************************************ End of while(1) *****************************************************
}//*************************************** End of main *********************************************************


void delay(long delaytime)					//Must use vdriver.lib to gain access to MS_TIMER
{
	//Parameter 1 is the number of milisecond to delay
	
	unsigned long delaystart;
	delaystart = MS_TIMER;	
	while (  MS_TIMER - delaystart <= delaytime );
}

clrLine(int TopBot)
{
	lcdPos(TopBot, 0);						//Start at the beginning of the user specified row
	lcdPrintf("                    ");	//Fill the line wil blanks
}

int Scroll(char Array[] , int TopOrBot, int Speed)
{
	//Parameter 1 is the name of the array to work on
	//Parameter 2 Enter "0" to display on top line of LCD or "1" to display on the bottom.
	//Parameter 3 enter number of desired mili-second delay/speed
	//This program is for use with the 2x20 LCD. Be sure to use correct LCD driver for you given controller
	
	auto char	 Temp[200];								
	auto char	 Temp2[21];								//Array to funnel to display
	auto int i, ArrStart, Ch2Disp, ColPos, MaxNoCol;
	memset(Temp, '\0', sizeof(Temp));
	memset(Temp2, '\0', sizeof(Temp2));
	
	MaxNoCol = 19;									//Maximum column size of a 2x20 LCD  Will need to calculate for a graphics lcd
	if(TopOrBot == 1); 							//Error trap for valid entries.  Default is top line
	else												//For true graphics lcd I must calculate bottom line based on font x,y measurements
		TopOrBot = 0;
	memcpy(Temp, Array, strlen(Array));  	//Make working copy of array to work on
	memcpy(Temp2, Temp, 1);						//Set 1st char of scroll array
	ArrStart = i = 0;
	Ch2Disp = 1;
	ColPos = 19;									//point to last column on lcd.  Will scroll right to left.

	while(strlen(Temp) < MaxNoCol)				//If small array is brought it fill it with blank to get scroll out effect
		Temp[strlen(Temp)] = '\x20';

//while no key has been pressed or no input received continue scrolling
	for( ; (i <= MaxNoCol) && (Temp2[i] != '\0'); i++)								//Scroll in from the right
	{
		clrLine(TopOrBot);
		lcdPos(TopOrBot, ColPos);
   	lcdPrintf("%s", Temp2);
  		delay(Speed);							
		ColPos--;								//Shift one position to the left to accomodate the additional character on next round			
		memcpy(Temp2, Temp, ++Ch2Disp);	//Display one more character then last time			Waitfor when costatement is used ????
	}
	clrLine(TopOrBot);				
	ArrStart++;										//Start copying to scroll array from 1 position less then maximum column width
	i = strlen(Temp);

	while((ArrStart + MaxNoCol) <= i)  							//Shift character scroll
	{     
	  		memcpy(Temp2, &Temp[ArrStart], MaxNoCol + 1);		//Grab next maximum number of characters.  In essence left of array 
			Temp2[sizeof(Temp2)-1] = '\0';					   		//drops off and is replaced on the right
			lcdPos(TopOrBot, 0);			  						//The scroll now takes place in changing the contents of the string displayed.
   		lcdPrintf("%s", Temp2);         																		
   		delay(Speed);							
   		clrLine(TopOrBot);
			ArrStart++;

	}

	MaxNoCol--;																
	while((ArrStart + MaxNoCol <= i) && (MaxNoCol))   			//Scroll out to the left
	{
	  		memcpy(Temp2, &Temp[ArrStart], MaxNoCol + 1);		//Grab next maximum number of characters.  In essence left of array 
			Temp2[MaxNoCol + 1] = '\0';					   		//drops off and is replaced on the right
			lcdPos(TopOrBot, 0);			  						//The scroll now takes place in changing the contents of the string displayed.
   		lcdPrintf("%s", Temp2);         																		
  			delay(Speed);							
			clrLine(TopOrBot);
			ArrStart++;
			MaxNoCol--;
	}
	return(1);
}//********************* End of Scroll function **********************

