/*
	ECHO485.C

	Port Z1 device echo program. This program echos transmission received
	from the 485 port of a controller. This program listens to the 485
	channel, wait for transmission to stop for 200ms, then turn on the
	transmit driver and echoes the entire string back, then returns to
	listen mode. This program is useful for debugging or testing the 485
	drivers/routines of another controller.
	
*/

#define N_WATCHDOG 0				//	no need for virtual watchdog
#define _VD_NOHITWD				//	no need to hit watchdog in the backgound

#use vdriver.lib					//	vdriver.lib for timing
#use aascz1.lib					//	AASC driver for channel 1

main() {
	char rBuf[0x400];
	char wBuf[0x400];
	auto char localBuf[0x400];
	auto unsigned count;
	auto struct _Channel *chan;
	auto char *pCur;
	auto unsigned remaining;
	auto unsigned long timeMark;
	
	VdInit();

	chan = aascOpen(DEV_Z1,							//	open channel 1 for 9600bps
		0,
		ASCI_PARAM_8N1+ASCI_PARAM_1200*8,
		NULL);

	aascSetReadBuf(chan,rBuf,sizeof(rBuf));	//	assign read and write buffers
	aascSetWriteBuf(chan,wBuf,sizeof(wBuf));
	aascTxSwitch(chan,1);							//	enable both transmit and
	aascRxSwitch(chan,1);							//	receive

	off_485();
	
	while (1) {
		hitwd();

		timeMark = MS_TIMER;							//	remember time mark
		count = aascReadBufLeft(chan);			//	what is the current
															//	number of bytes read?
		while (!count || (MS_TIMER - timeMark < 200)) {
			//	stick in loop if nothing is received or it's been less than
			//	200ms since last character was received
			if (aascReadBufLeft(chan) != count) {	//	more bytes received
				timeMark = MS_TIMER;						//	reset time mark
				count = aascReadBufLeft(chan);		//	and keep new count
			}
			hitwd();										//	hit watchdog explicitly
		}

		if (count > sizeof(localBuf)) {			//	this means trouble
			//	how to handle it is application/controller specific
		}
		
		aascReadBlk(chan,localBuf,count,1);		//	after 200ms, read entire string

		on_485();										//	enable transmit driver
		aascWriteBlk(chan,localBuf,count,1);	//	echo now!
		while (aascReadBufLeft(chan) < count) {	//	wait for string transmitted
			hitwd();											//	(locally echoed)
		}
		off_485();										//	then disable transmit driver
		
		aascFlushRdBuf(chan);						//	just in case, flush buffer
		hitwd();
	}
}
