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

**      uwlogger.c -- Tattletale Model-8 U.W. Data Logger

**

**      Programmer:                             bpa

**

**      Last Update:                          Wed, July 27, 1994

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



#include        <TT8.h>

#include        <setjmp.h>



#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	<dio332.h>		/* 68332 Digital I/O Port Pin Definitions */

#include	<tt8lib.h>		/* definitions and prototypes for Model 8 library */



#include        <stdio.h>

#include        <stdlib.h>

#include        <time.h>

#include        <userio.h>





/*

**      MAX-132 Control Byte Format for QSPI serial transmit commands

*/

	#define         C_CONVERT       0x82    /* Command to convert with status */

	#define         C_CHAN0         0x81    /* Command to enable Channel 0 */

	#define         C_CHAN1         0x91    /* Command to enable Channel 1 */

	#define         C_CHAN2         0xA1    /* Command to enable Channel 2 */

	#define         C_CHAN3         0xB1    /* Command to enable Channel 3 */

	#define         C_CHAN4         0xC1    /* Command to enable Channel 4 */

	#define         C_CHAN5         0xD1    /* Command to enable Channel 5 */

	#define         C_CHAN6         0xE1    /* Command to enable Channel 6 */

	#define         C_CHAN7         0xF1    /* Command to enable Channel 7 */

	#define         C_CHAN8         0x01    /* Command to enable Channel 8 */

	#define         C_CHAN9         0x11    /* Command to enable Channel 9 */

	#define         C_CHAN10        0x21    /* Command to enable Channel 10 */

	#define         C_CHAN11        0x31    /* Command to enable Channel 11 */

	#define         C_CHAN12        0x41    /* Command to enable Channel 12 */

	#define         C_CHAN13        0x51    /* Command to enable Channel 13 */

	#define         C_CHAN14        0x61    /* Command to enable Channel 14 */

	#define         C_CHAN15        0x71    /* Command to enable Channel 15 */



	

	#define         C_STAT_READL    0x02    /* Command to get status & data bits 2 thru 0 & sign */

	#define         C_READH         0x04    /* Command to read MSB bits 18 thru 11 */

	#define         C_READM         0x00    /* Command to read data bits 10 thru 3 */

	#define         C_ZERO          0x92    /* Command to Zero A-D with status */



/*  P R O T O T Y P E S  */

void maxatod(void);

void Max132Setup(void);

void Max132Read(short Chan);

void Max132Zero(short Chan);

void Max539Write(short Value);

void ADHandler(void);



static ptr      bufstart, bufend, bufptr;

static short    startFlag = 0;

static short    getCh0Fast;

short           mux; 

short           *words;

char            scandata[86];

unsigned long int        high_b, middle_b, lsb, sign ;

long int        last_zeroout, zeroout, output;

long int        chandata[25];      /* temp. channel data indexed storage */ 

long int        last_chandata[25];

int             SIGN_MASK = 8;

int             LSB_MASK = 7;

int             MSB_MASK = 127;

long            memsize;

int             UserHappy,scan_no,i,j,k,l,m,n;

char            cmd;

unsigned int    no_sleeps;              /* sleep period */

char            echo_key;



#define         BUFBYTES                500l

#define		HERTZ50			FALSE	/* True for EUROPE, False for USA */

        

/*--------------------------------------------------------------*/

void main(void)

    {

	short DAout=0;



	InitTT8(NO_WATCHDOG, TT8_TPU);	/* setup Model 8 for running C programs */



	printf("\nU.W. Tattletale Model-8 Based Data Logger\n");

	InstallHandler(ADHandler, QSPI_INT_VECTOR, 0);

	if ((bufstart = malloc(BUFBYTES)) == 0)

	{

	     printf("\nCan't allocate buffer \n");

	     exit (1);

	}

	Max132Setup();

//	while (QueryYesNo("\nCycle Readings", TRUE))

	for(;;)

	{

		maxatod();

	        Max539Write(DAout);

		printf("D/A = %u\n\n",DAout);

		DAout+=128;

		if(DAout==4224)DAout=0;

		DelayMilliSecs(1000l);

	}

}                                       /* end of MAIN */



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

**      main

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

void maxatod( void )

    {

	bufptr = bufstart;                  /* define memory space */

	bufend = bufstart + BUFBYTES - 1;

	words = (short *) bufstart;

	    

	/* Setup to do A to D sampling */

//	for (mux = 1; mux < 7; mux++) 

//	{                            /* for each of 11 Mux channels */

//	Max132Zero(mux);                /* kick start the first A-D read */

//	DelayMilliSecs(02l);          /* Delay 65ms for MAX132 running at 32KHz */

//	}

//	bufptr = bufstart;	      /* discard previous readings */

//	for (mux = 1; mux < 7; mux++) 

//	{                            /* for each of 11 Mux channels */

//	Max132Zero(mux);                /* get the 1st A/D zero */

//	DelayMilliSecs(02l);          /* Delay 65ms for MAX132 running at 32KHz */

//	}

//	sprintf(scandata, "%06d",k); /* save scan # in string */

//

	for (mux = 1; mux < 7; mux++) 

	{                            /* for each of 11 Mux channels */

	    Max132Read(mux);             /* fetch A-D data @ mux */

	    DelayMilliSecs(010l);        /* Delay 65ms for MAX132 running at 32KHz */

	}                              /* have 6 readings now */

//	DelayMilliSecs(02l); 

//	Max132Zero(1);

//	DelayMilliSecs(02l);

//	Max132Zero(2);                  /* 15th conversion ~ 1 sec */

//	DelayMilliSecs(02l); 

//	Max132Zero(3);

	

	/* Decode binary data */

	/* Each data word has been stored as 4 words in the Array words[] */

	/* The first word is just status from the A/D chip. */

	/* The second word is the MSBs 18 thru 11. */

	/* The third word is the middle bits 10 thru 3. */

	/* The fourth word is the LSBs 2 thru 0 (D2 - D0) & the sign (D3). */

	/* Note that the data is Two's Complement. */

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

	/*    Note the first data word is garbage due to the

	**    inherit delay in the MAX132, so throw it away.

	**    The second data word is status only, so no need.

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

	/*    This routine prints the 11 data words

	**    as a voltage based on a +/- 5 volt input

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

	

	n = 0;                      

	while( n < 24)              /*  we did 15 conversions */

	{

	    high_b = words[n+1];

	    high_b = high_b & MSB_MASK;

	    high_b *= 2048;

	    middle_b = words[n+2]; 

	    middle_b *= 8;

	    lsb = words[n+3]; 

	    lsb = lsb & LSB_MASK;

	    sign = words[n+3]; 

	    sign = sign & SIGN_MASK;

	    if (sign > 1)

	    {    

		sign = -1;

	    }

	    else

	    {    

		sign = 1;

	    }       

	    output = (high_b + middle_b + lsb) * sign;

	    /* correct 2's complement sign & limit to +/- 16 bits */

	    if (output < 0)

	    {

		output = ((output + 262143) * (-1))/4;

	    }

	    else

	    {

		output = output/4;

	    }

	    /* Only take the Zerovolt data on the second line */

		      

	    /* 16 conversions correspond to 64 words

	    1st word is garbage, 2nd word position, is status

	    3rd & 16th word positions are auto zero readings, 

	    4th through 14th word positions are the Mux data

	    on channel 0 of the MAX-232  */

//printf("%2d %02x %02x %02x %02x\n",n,words[n],words[n+1],words[n+2],words[n+3]);	       

	    switch( n )

	    {

//		case 0:

//		case 4:

//		    break;

//

//		case 28:

//		    break;

//

//		case 8:          /* look @ 1st zero reading */

//		    zeroout = output;

//		    break;

//		

//		case 32:         /* look @ last zero reading */

//		    zeroout = (zeroout + output) / 2;

//		    break;    

//		    

		default:         /* get A/D readings */

		    chandata[n/4] = output;

	    }

//printf("%d %ld\n",n,output);

	    n = n + 4;          /* n+=4;   */

	}       /*  close n loop */

	for(n=0;n<7;n++)

		printf("%d %ld\n",n,chandata[n]);

    }       /* maxatod() */





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

**      Max132Setup             Setup MAX-132 for generic use with QSPI

**

**      Performs generic initialization of QSPI registers for working the MAXIM

**      MAX-132 A-D converter with the Model 7 QSPI.  Routines accessing this part

**      will need to perform additional initialization based on the desired access

**      modes and data rates.

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

void Max132Setup(void)

	{

	/* Set QPDR to determine pin states when between transfers */

	_QPDR->SCK = 0;

	_QPDR->PCS0 =_QPDR->PCS1 = _QPDR->PCS2 = 0;

	_QPDR->MOSI = 0;

	_QPDR->PCS3 = 1;



	/* Set QDDR to determine which pins are Outputs & Inputs*/

	_QDDR->PCS0 = _QDDR->SCK = _QDDR->MOSI = OUTP;     /* outputs */

	_QDDR->PCS1 = _QDDR->PCS2 = _QDDR->PCS3 = OUTP;		   /* outputs */

	_QDDR->MISO = INP;                                 /* inputs */



	/* Set QPAR to determine which pins are assigned to QSPI */

	_QPAR->PCS0 = _QPAR->MISO = _QPAR->MOSI = BUS;     /* buss (SCK is automatic) */



	_QPAR->PCS1 = _QPAR->PCS2 = BUS;

	_QPAR->PCS3 = INP;





	*SPCR0 =        84               /* 84 = 100 KHz */ /* baud rate (2 is max)             */

			|       (8 << 10)                   /* 8 bits per transfer  */

			|       M_MSTR  &       SET         /* 1 = Master, 0 = Slave */

			|       M_WOMQ  &       CLR         /* 1 = open drain, 0 = cmos */

			|       M_CPOL  &       CLR         /* 1 = inactive SCK high  */

			|       M_CPHA  &       CLR         /* 1 = chg lding edge, capt folng */

	;



	*SPCR2 =        0                                   /* NEWQP */

			|       0 << 8                      /* ENDQP */

			|       M_SPIFIE&       CLR         /* SPI finished rupt enable = 1  */

			|       M_WREN  &       CLR         /* wraparound enable = 1 */

			|       M_WRTO  &       CLR         /* wrap to */

	;



	*SPCR3 =        	M_LOOPQ &       CLR         /* QSPI loop mode, 1=on */

			|       M_HMIE  &       CLR         /* HALTA & MODF interrupt enable */

			|       M_HALT  &       CLR         /* Halt                         */

	;



	*SPCR1 =        1                                   /* DTL delay after transfer */

			|       (1 << 8)                    /* DSCKL delay before SCK   */

			|       M_SPE   &       CLR         /* QSPI enable = 1, 0 = I/O */

	;



	SPICMD[0] =		M_CONT  &       CLR	    /* 1=Continuous  */

			|       M_BITSE &       CLR	    /* 0=8 bits, 1=use SPCR0 */

			|       M_DT    &       CLR	    /* 0=no delay after, 1=use SPCR1 */

			|       M_DSCK  &       CLR	    /* 0=1/2SCK, 1=use SPCR1    */

			;





	}       /* Max132Setup() */



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

**      Max132Zero              Initiate the MAX-132 by zeroing the inputs 

**

**                              The user must store the zero value to correct

**                              the data for each channel.

**      

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

void Max132Zero(short Chan)

    {

	*SPCR0 =        84               /* 84 = 100 KHz */ /* baud rate (2 is max)   */

			|       (8 << 10)                   /* 8 bits per transfer   */

			|       M_MSTR  &       SET         /* 1 = Master, 0 = Slave  */

			|       M_WOMQ  &       CLR         /* 1 = open drain, 0 = cmos  */

			|       M_CPOL  &       CLR         /* 1 = inactive SCK high */

			|       M_CPHA  &       CLR         /* 1 = chg lding edge, capt folng */

			;



	*SPCR2 =        0                                  /* NEWQP */

			|       3 << 8                      /* ENDQP */

			|       M_SPIFIE&       SET         /* SPI finished rupt enable = 1   */

			|       M_WREN  &       CLR         /* wraparound enable = 1   */

			|       M_WRTO  &       CLR         /* Halt assert  */

			;

	

	*SPCR3 =        	M_LOOPQ &       CLR         /* QSPI loop mode, 1=on      */

			|       M_HMIE  &       CLR         /* HALTA & MODF interrupt enable */

			|       M_HALT  &       CLR         /* Halt                         */

			;



	*SPCR1 =        1                                 /* DTL delay after transfer   */

			|       (1 << 8)                   /* DSCKL delay before SCK    */

			|       M_SPE   &       CLR         /* QSPI enable = 1, 0 = I/O    */

			;

	

	SPIXMT[15] = C_CHAN0;

	SPIXMT[0] = C_READH | (HERTZ50 ? 0x40 : 0x00);                                   

	SPIXMT[1] = C_READM | (HERTZ50 ? 0x40 : 0x00);

	SPIXMT[2] = C_STAT_READL | (HERTZ50 ? 0x40 : 0x00);                                    

	SPIXMT[3] = C_ZERO | (HERTZ50 ? 0x40 : 0x00);                                    

	

	SPICMD[15] =    	M_CONT  &       CLR /* 1=keep CS active  */

			|       M_BITSE &       CLR /* 0=8 bits, 1=use SPCR0  */

			|       M_DT    &       SET /* 0=no delay after, 1=use SPCR1  */

			|       M_DSCK  &       SET /* 0=1/2SCK, 1=use SPCR1   */

			;



	SPICMD[0] =     	M_CONT  &       CLR /* 1=keep CS active    */

			|       M_BITSE &       CLR /* 0=8 bits, 1=use SPCR0  */

			|       M_DT    &       SET /* 0=no delay after, 1=use SPCR1 */

			|       M_DSCK  &       SET /* 0=1/2SCK, 1=use SPCR1  */

			|	Chan		    /* Channel selected */

			;



	SPICMD[1] = SPICMD[0];

	SPICMD[2] = SPICMD[0];

	SPICMD[3] = SPICMD[0];



	startFlag = 1;

	_SPSR->SPIF = 0;                                    /* clear any old results */

	_SPCR1->SPE = 1;                                    /* start the read */

	

    }         /* Max132Zero() */



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

**      Max132Read              Start the MAX-132 sampling 

**      

**      Routine to do a single A to D conversion on Channel #Chan.

**               Chan can be an integer from 0 to 15.

**                 Output data is Two's Complement

**

**      !!!!! Important Note !!!!!   

**      Due to the design of the MAX-132 chip and the necessity of trying to

**      maintain efficieny of the data flow, when the user sends a command

**      to the A-D to do a conversion, the data received at that time is

**      from the previous conversion, ie the data is always one cycle behind.

**      

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

void Max132Read(short Chan)

	{

	Chan += 0x08;



	*SPCR0 =        84               /* 84 = 100 KHz */ /* baud rate (2 is max)   */

			|       (8 << 10)                   /* 8 bits per transfer   */

			|       M_MSTR  &       SET         /* 1 = Master, 0 = Slave  */

			|       M_WOMQ  &       CLR         /* 1 = open drain, 0 = cmos  */

			|       M_CPOL  &       CLR         /* 1 = inactive SCK high */

			|       M_CPHA  &       CLR         /* 1 = chg lding edge, capt folng */

			;



	*SPCR2 =        0                                   /* NEWQP */

			|       3 << 8                      /* ENDQP */

			|       M_SPIFIE&       SET         /* SPI finished rupt enable = 1   */

			|       M_WREN  &       CLR         /* wraparound enable = 1   */

			|       M_WRTO  &       CLR         /* Halt assert    */

			;

	

	*SPCR3 =        	M_LOOPQ &       CLR         /* QSPI loop mode, 1=on      */

			|       M_HMIE  &       CLR         /* HALTA & MODF interrupt enable */

			|       M_HALT  &       CLR         /* Halt                         */

			;

							   

	*SPCR1 =        1                                 /* DTL delay after transfer   */

			|       (1 << 8)                   /* DSCKL delay before SCK    */

			|       M_SPE   &       CLR         /* QSPI enable = 1, 0 = I/O    */

			;



	SPIXMT[15] = C_CHAN0;

	SPIXMT[0] = C_READH | (HERTZ50 ? 0x40 : 0x00);                                   

	SPIXMT[1] = C_READM | (HERTZ50 ? 0x40 : 0x00);

	SPIXMT[2] = C_STAT_READL | (HERTZ50 ? 0x40 : 0x00);                                    

	SPIXMT[3] = C_CONVERT | (HERTZ50 ? 0x40 : 0x00);

	

	SPICMD[15] =    	M_CONT  &       CLR /* 1=keep CS active  */

			|       M_BITSE &       CLR /* 0=8 bits, 1=use SPCR0  */

			|       M_DT    &       SET /* 0=no delay after, 1=use SPCR1  */

			|       M_DSCK  &       SET /* 0=1/2SCK, 1=use SPCR1   */

			|	Chan		/* Channel selected */

			;



	SPICMD[0] =     	M_CONT  &       CLR /* 1=keep CS active    */

			|       M_BITSE &       CLR /* 0=8 bits, 1=use SPCR0  */

			|       M_DT    &       SET /* 0=no delay after, 1=use SPCR1 */

			|       M_DSCK  &       SET /* 0=1/2SCK, 1=use SPCR1  */

			|	Chan		/* Channel selected */

			;



	SPICMD[1] = SPICMD[0];

	SPICMD[2] = SPICMD[0];

	SPICMD[3] = SPICMD[0];



	startFlag = 1;

	_SPSR->SPIF = 0;                                   /* clear any old results */

	_SPCR1->SPE = 1;                                   /* start the read */

	

	}       /* Max132Read() */





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

**      Max132Read              Start the MAX-132 sampling 

**      

**      Routine to do a single A to D conversion on Channel #Chan.

**               Chan can be an integer from 0 to 15.

**                 Output data is Two's Complement

**

**      !!!!! Important Note !!!!!   

**      Due to the design of the MAX-132 chip and the necessity of trying to

**      maintain efficieny of the data flow, when the user sends a command

**      to the A-D to do a conversion, the data received at that time is

**      from the previous conversion, ie the data is always one cycle behind.

**      

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

void Max539Write(short Value)

	{



	*SPCR0 =        84               /* 84 = 100 KHz */ /* baud rate (2 is max)   */

			|       (12 << 10)                  /* 12 bits per transfer   */

			|       M_MSTR  &       SET         /* 1 = Master, 0 = Slave  */

			|       M_WOMQ  &       CLR         /* 1 = open drain, 0 = cmos  */

			|       M_CPOL  &       CLR         /* 1 = inactive SCK high */

			|       M_CPHA  &       CLR         /* 1 = chg lding edge, capt folng */

			;



	*SPCR2 =        0                                   /* NEWQP */

			|       0 << 8                      /* ENDQP */

			|       M_SPIFIE&       CLR         /* SPI finished rupt enable = 1   */

			|       M_WREN  &       CLR         /* wraparound enable = 1   */

			|       M_WRTO  &       CLR         /* Halt assert    */

			;

	

	*SPCR3 =        	M_LOOPQ &       CLR         /* QSPI loop mode, 1=on      */

			|       M_HMIE  &       CLR         /* HALTA & MODF interrupt enable */

			|       M_HALT  &       CLR         /* Halt                         */

			;

							   

	*SPCR1 =        1                                 /* DTL delay after transfer   */

			|       (1 << 8)                   /* DSCKL delay before SCK    */

			|       M_SPE   &       CLR         /* QSPI enable = 1, 0 = I/O    */

			;



	SPIXMT[0] = Value & 0x0fff;                                   

	

	SPICMD[0] =     	M_CONT  &       CLR /* 1=keep CS active    */

			|       M_BITSE &       SET /* 0=8 bits, 1=use SPCR0  */

			|       M_DT    &       SET /* 0=no delay after, 1=use SPCR1 */

			|       M_DSCK  &       SET /* 0=1/2SCK, 1=use SPCR1  */

			|	0x0f		/* Channel 7 */

			;





	startFlag = 1;

	_SPSR->SPIF = 0;                                   /* clear any old results */

	_SPCR1->SPE = 1;                                   /* start the read */

	

	}       /* Max539Write() */





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

**      ADHandler

**      

**      Interrupt handler for MAX-132

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

void ADHandler(void)

	{

#asm

;	       move.w  $FFFD00,_getCh0Fast     ; get first byte before it gets overwritten



		movem.l a0-a1,-(a7)             ; save used registers



		move.l  _bufptr,a0

		lea     $FFFD00,a1

		move.l  (a1)+,(a0)+             ; two words at a time

		move.l  (a1)+,(a0)+     

;		move.w  _getCh0Fast,-8(a0)     ; re-insert first byte

		move.l  a0,_bufptr

;

		tst.b   $FFFC1F                 ; clear interrupt

		move.b  #0,$FFFC1F

;

		cmp.l   _bufend,a0

		blt     exit

		move.l  _bufstart,_bufptr       ; wrap to beginning

;

;       SET FLAG HERE TO PROCESS BUFFERED DATA

;

;               

exit

		movem.l (a7)+,a0-a1     ; restore used registers

		bclr.b	#4,$FFFA11

		rte

#endasm



	}       /* ADHandler() */



