//  TT8 specific includes
#include        <TT8.h>                 /* Tattletale Model 8 Definitions */
#include        <tat332.h>              /* 68332 Tattletale (7,8) Hardware Definitions */
#include        <sim332.h>              /* 68332 System Integration Module Definitions */
#include        <qsm332.h>              /* 68332 Queued Serial Module Definitions */
#include        <tpu332.h>              /* 68332 Time Processing Unit Definitions */
#include        <dio332.h>              /* 68332 Digital I/O Port Pin Definitions */
#include        <tt8pic.h>              /* Model 8 PIC Parallel Slave Port Definitions */
#include        <tt8lib.h>              /* definitions and prototypes for Model 8 library */

//  general C includes
#include        <stdio.h>
#include        <stdlib.h>

//  includes for the data logger
#include		"assert.h"
#include		"lpsleep.h"

//  includes for the disk routines
#include		<pcdisk.h>

void low_power_setup_IRQ1 (void);
void low_power_IRQ1_handler (void);

//  start_lp_sleep ()
//
//  Enters the low power sleep mode.  Only wakeup is on a keystroke
//  from COM1
//
void low_power_start_sleep (void)  {
	printf ("Entering low power mode.\n");
	StopWatchStart ();
	while (StopWatchTime () < 100000L)
		{;}

	//  make sure to turn off the power supplies.  Set all SPI interface
	//  pins to 0 so that we don't accidentally power external chips through
	//  these outputs.
//	prep_pins_low_power ();

	//  The disks should all be off, but make sure just in case
	disk_power_off ("A:");
	disk_power_off ("B:");
	disk_power_off ("C:");
	disk_power_off ("D:");
		
	//  install the handler for IRQ1
	low_power_setup_IRQ1 ();
	SerShutDown (1, 1);
	
	//  Accept IRQ1 interrupts, which are tied to the Rxd line
	PConfBus(F,1);

	//  Low voltage regulator not used; conflict with +5 IDE
//	VRegSelect(v3);
//	LMDelay (32766);

	//  stop here until interrupt from RS232
    while (SerByteAvail () == 0)
		Stop (0x2000);

	//  restarted - must have got an IRQ1 interrupt
	SerActivate ();
	printf ("\n\nExiting low power mode\n");
	
//	VRegSelect(v5);			/* return to 5 volt operation */
//	LMDelay (32766);

//	PicAckCmpAlrm();		/* turn off interrupt (ack) */
}





//  low_power_setup_IRQ1
//
//  Code to install a handler for IRQ1.  This allows us to enter the low
//  power sleep mode while we wait for the user to give us a keyboard
//  hit.
void low_power_setup_IRQ1 (void)  {
	static ExcCFrame efp1;

	//  disallow interrupts while we install the handler
	PConfInp(F,1);

	//  interrupts should only be turned on just before entering
	//  the low power sleep mode so that we don't waste time
	//  everytime a keystroke is received

	InstallHandler(low_power_IRQ1_handler, Level_1_Interrupt, &efp1);
}




//  low_power_IRQ1_handler
//
//  Catch the interrupt which wakes us up.  Don't need to do anything
//  with it.
//
void low_power_IRQ1_handler (void)  {
	//  disallow further interrupts.
	PConfInp(F,1);
}



/*******************************************************************************
**      prep_pins_low_power
**      
**      This routine  sets up the port and tpu lines for a stock
**      Model 8 to force possible floating I/O pins (possible source of extra
**      current drain in CMOS circuits) to outputs.  The technique used samples
**      each of the I/O lines as inputs, then configures and writes the sampled
**      value back as outputs.  For this example code, we use a brute force pin-
**      by-pin approach which allows for ease of modification.  Real applications
**      can save quite a bit of code by condensing the pin operations to byte
**      wide configuration of the various ports and putting the tpu settings
**      into a loop.
*******************************************************************************/
void prep_pins_low_power(void)  {
	
	//  The Port D lines used by the QSPI and the Port 1 Com port.  They
	//  are configured elsewhere

	//  68332 PORT E pins are available as either BUS signals or general I/O
	PInpToOut(E,0);		//	E0 -> unused connection to MS system
	PInpToOut(E,1);     //	E1 -> unused connection to MS system
	PInpToOut(E,2);		//	E2 -> unused connection to MS system
	//  Pin 4 will be re-configured by the IDE init software.
	//  Do not call this routine AFTER the IDE init software.
	PInpToOut(E,4);		//	E4 -> DS bus signal; connected to MS system
	
	//  Pins 3, 5, 6, 7 will be reconfigured by the ADC software.
	//  Do not call this routine AFTER the ADC init software
	PInpToOut(E,3);		//	E3 -> Output to ADC board controls CH1 gain
	PInpToOut(E,5);		//	E5 -> Output to ADC board controls Ch2 gain
	PInpToOut(E,6);		//	E6 -> Output to ADC board controls Ch3 gain
	PInpToOut(E,7);		//	E7 -> Output to ADC board controls Ch4 gain

	//  68332 PORT F pins are available as either IRQ's or general I/O
	PConfInp(F,0);      //  sel5vpic (has pullup)
	PConfInp(F,1);      //  IRQ1/Rxd1
	PInpToOut(F,2);     //  Connected to MS system; unused disk IRQ
	PConfInp(F,3);      //  IRQ3/led (has pullup)
	
	//  Pin F4 is used as a Data Ready interrupt from the AD7716 chip.
	//  It is reconfigured by the ADC software.  Do not call this routine
	//  AFTER the ADC init software
	PConfInp(F,4);      //  Connected to Data Ready on the 7716 chip
	PConfInp(F,5);      //  picirq (PIC asserts)
	PConfInp(F,6);      //  connected to TP15;

	PConfOutp(F,7);		//  MAX186 A/D shutdown
	PClear(F,7);

	//  68332 TPU PINS
	TPUGetPin (0);	    	//  1 PPS input from CM
	TPUSetPin(1, CLR);    	//  Clock Sync Output to CM
	TPUSetPin(2, SET);		//  Connection to PS board; CLR to turn on -Sensor 
	TPUSetPin(3, SET);		//  Connection to PS board; CLR to turn on +Sensor 
	TPUSetPin(4, SET);		//  Connection to PS board; CLR to turn on -Analog
	TPUSetPin(5, SET);		//  Connection to PS board; CLR to turn on +Analog
	TPUSetPin(6, CLR);    	//  Connection to MS board; unused IDE reset line
	TPUGetPin(7);	    	//  Connection to CLKEN pin of TT8; set by jumper.
							//  Configure as an input.
	TPUSetPin(9, CLR);    	//  Spare RS232 Tx3 line
	TPUSetPin(10, CLR);   	//  Spare RS232 Rx3 line
	TPUSetPin(11, CLR);   	//  Spare RS232 Tx4 line
	TPUSetPin(12, CLR);   	//  Spare RS232 Rx3 line
	//  next two are nominally no connects;  I've taken state configuration
	//  info and comments from the Onset LPSleep example.
	TPUSetPin(13, SET);   	//  Txd2
	TPUGetPin(14);      	//  Rxd2 (active in shutdown)
	//  REVIEW - should add weak pull-ndown to hardware so we can configure
	//  as an input all the time without worrying about excess current draw
	//  For now, configure as an input regardless of what it does to current.
	TPUGetPin(15);		   	//  connected to F, 6

	return;
	//  Next pin state taken from Onset's LPSleep example
	//  REVIEW - call skip about this
	//  This is currently skipped because it kills the EEPROM read routines.
	TPUSetPin(8, CLR);    	//  -IRQ3 to flash LED (?)
}




