/**********************************************************
DLP_2_FLASH.C

Z-World, 2001

	This program is provided as a Sample ONLY. It is intended for
	use on Rabbit based boards with 2 flash chips in conjunction
	with the sample program DLM_SERIAL_2_FLASH.C. 
	
   It is just a small test program to use as a downloaded program.
   It sends a character continuously over serial port C.

	Directions:
	1)	Compile the program DLM_SERIAL_2_FLASH.C to the Rabbit target.
	   See the instructions in DLM_SERIAL_2_FLASH.C.

	2) In the Compile | Options dialog box in Dynamic C 7.05 or later,
	   click on the "Defines" button, add COMPILE_SECONDARY_PROG
	   to the list of macros, and make sure COMPILE_PRIMARY_PROG is
	   NOT on the list. Compile this program to a BIN file, (include
	   the BIOS). A HEX file will be automatically generated.

   3) Follow the instructions in DLM_SERIAL_2_FLASH.C to download
      the file DLP_2_FLASH.HEX.

**********************************************************/

#ifdef  COMPILE_PRIMARY_PROG
#error "Cannot compile as primary program."
#error "Remove COMPILE_PRIMARY_PROG macro in Compiler | #defines options"
#error "Must Recompile BIOS also. Hit Ctrl-Y then recompile"
#endif

#ifndef  COMPILE_SECONDARY_PROG
#error "Must compile as secondary program."
#error "Put COMPILE_SECONDARY_PROG macro in Compiler | #defines options"
#error "Must Recompile BIOS also. Hit Ctrl-Y then recompile"
#endif


#define CINBUFSIZE  15
#define COUTBUFSIZE 15

#define _232BAUD 57600ul

#define RESTARTSIGNAL "\xaa\xbb\xcc\xbb\xaa" 
#define RESTARTSIGNAL_TIMEOUT 10000 

char  Chip_SW_Func [30];
void  CopyChipSWtoRAM();
void  SwitchChip(int CSOEWE);
void ProcessRestartCommand(char ch);

void RestartDLM();

root main()
{
	int cIn;

	serCopen(_232BAUD);
			
	while (1)
	{
      // Listen for restart command
		cIn=serCgetc();
		if((cIn&0xff80)==0x0080)
		{
		    ProcessRestartCommand(cIn);
		}

		// Send a char
		costate
		{
			waitfor(DelayMs(10));
			waitfor(serCwrFree());
			serCputc('Z');
		}
	}
}

nodebug
void ProcessRestartCommand(char ch)
{
	static unsigned long timelimit;
	static char restart[sizeof(RESTARTSIGNAL)]; 
	static int indx;
#GLOBAL_INIT{ indx = 0;memset(restart,0,sizeof(RESTARTSIGNAL)-1);}
	
	if(!indx)
	{
		timelimit = SEC_TIMER+RESTARTSIGNAL_TIMEOUT;
	}
	else
	{
		if(SEC_TIMER > timelimit)
		{
			indx = 0;
			memset(restart,0,sizeof(RESTARTSIGNAL)-1);		
			return;
		} 
	}
	restart[indx] = ch;
	indx++;
	if(indx==sizeof(RESTARTSIGNAL))
	{
		memset(restart,0,sizeof(RESTARTSIGNAL)-1);		
		indx = 0;
	}
   else if(!memcmp(restart,RESTARTSIGNAL,sizeof(RESTARTSIGNAL)-1))
	{
		RestartDLM();
	}
}

nodebug
void RestartDLM()
{
	serCclose();

	// Put flash switching function in RAM 
	CopyChipSWtoRAM();

	// ...and call it
	SwitchChip(0|0);  // CS0/OE0/WE0
}

#asm nodebug
_SwitchFlashChip::
	ipset 3							  // turn off interrupts
	ld   a,0x51
	ioi  ld (WDTTR),a
	ld   a,0x54
	ioi  ld (WDTTR),a

	ld   a,(MB0CRShadow)         // get shadow reg
   and  0xf0                    // mask out CS/WE/OE bits
   or   l                       // set to new CS,WE,OE 
   ioi  ld (MB0CR),a            // load MMU reg
	ld   hl,0
	jp   (hl)
_EndSwitchFlash::
#endasm

nodebug
void SwitchChip(int CSOEWE)
{
#asm
	call Chip_SW_Func
#endasm
}

nodebug
void  CopyChipSWtoRAM()
{
	// put flash switching function in RAM
	memcpy(	Chip_SW_Func	,
			 	_SwitchFlashChip,
			 	((int)((unsigned)_EndSwitchFlash - (unsigned)_SwitchFlashChip)+1)
   );
}