////////////////////////////////////////////////////////////////////////////////
//
//     PIC16F877 + TPA81 + LCD03 example
//     Written October 2005 by Gerald Coe, using HITECH PIC16 compiler
// 
//		 Displays TPA81 temperature readings on the LCD03
//		 Note - assumes a 20MHz crystal
//		 
//     This code is Freeware - Use it for any purpose you like.
//
///////////////////////////////////////////////////////////////////////////////


#include <pic.h>
#include <stdio.h>
	 
__CONFIG(0x3b32);								// configuration register - see PIC data sheet for details		

#define TPA81_ADDR	0xD0					// Factory supplied default address

void clrscn(void);							// prototypes
void cursor(char pos);
void print(char *p);
void setup(void);
void get_tpa81(void);

char s[41];										// buffer used to hold text to print
unsigned char t[10];							// holds software rev, ambiant and 8 sensor temperatures

void main(void)
{
	setup();										// sets up the PIC16F877 I2C port
	clrscn();									// clears the LCD03 disply
	cursor(3);									// sets cursor to 1st row of LCD03
	sprintf(s,"TPA81 Thermopile");		// text, printed into our buffer
	print(s);									// send it to the LCD03

	while(1) {									// loop forever
		get_tpa81();							// reads TPA81 data into an array
		cursor(21);								// sets cursor to 2nd row of LCD03
		sprintf(s,"Rev %d, Ambient %d ", t[0], t[1]);
		print(s);								// send it to the LCD03	
		cursor(41);								// sets cursor to 3rd row of LCD03
		sprintf(s,"T1 %02d, %02d, %02d, %02d T4", t[2], t[3], t[4], t[5]);
		print(s);								// send it to the LCD03	
		cursor(61);								// sets cursor to 4th row of LCD03
		sprintf(s,"T5 %02d, %02d, %02d, %02d T8", t[6], t[7], t[8], t[9]);
		print(s);								// send it to the LCD03	
		
	}
}

void get_tpa81(void)
{
char x;

	SEN = 1;										// send start bit
	while(SEN);									// and wait for it to clear
	ACKDT = 0;									// acknowledge bit
	SSPIF = 0;
	SSPBUF = TPA81_ADDR;						// tpa81 I2C address
	while(!SSPIF);								// wait for interrupt
	SSPIF = 0;									// then clear it.
	SSPBUF = 0;									// address of register to start reading from - software Rev 
	while(!SSPIF);								// 
	SSPIF = 0;									//
	RSEN = 1;									// send repeated start bit
	while(RSEN);								// and wait for it to clear
	SSPIF = 0;									//
	SSPBUF = TPA81_ADDR+1;					// tpa81 I2C address - with read bit set
	while(!SSPIF);								// wait for interrupt
	SSPIF = 0;									// then clear it.

	for(x=0; x<9; x++) {
		RCEN = 1;								// start receiving
		while(!STAT_BF);						// wait for data
		t[x] = SSPBUF;							// and get it
		ACKEN = 1;								// start acknowledge sequence
		while(ACKEN);							// wait for ack. sequence to end
	}

	RCEN = 1;									// start receiving last byte
	while(!STAT_BF);							// wait for 8th and last pixel
	t[9] = SSPBUF;								// and get it
	ACKDT = 1;									// not acknowledge for last byte
	ACKEN = 1;									// start acknowledge sequence
	while(ACKEN);								// wait for ack. sequence to end
	PEN = 1;										// send stop bit
	while(PEN);
}

void clrscn(void)
{
	SEN = 1;								// send start bit
	while(SEN);							// and wait for it to clear

	SSPIF = 0;
	SSPBUF = 0xc6;						// LCD03 I2C address
	while(!SSPIF);						// wait for interrupt
	SSPIF = 0;							// then clear it.

	SSPBUF = 0;							// address of register to write to 
	while(!SSPIF);						// 
	SSPIF = 0;							//

	SSPBUF = 12;						// clear screen 
	while(!SSPIF);						// 
	SSPIF = 0;							//

	SSPBUF = 4;							// cursor off 
	while(!SSPIF);						// 
	SSPIF = 0;							//
	 
	PEN = 1;								// send stop bit
	while(PEN);							//
}

		
void cursor(char pos)
{
	SEN = 1;								// send start bit
	while(SEN);							// and wait for it to clear

	SSPIF = 0;
	SSPBUF = 0xc6;						// LCD03 I2C address
	while(!SSPIF);						// wait for interrupt
	SSPIF = 0;							// then clear it.

	SSPBUF = 0;							// address of register to write to 
	while(!SSPIF);						// 
	SSPIF = 0;							//

	SSPBUF = 2;							// set cursor 
	while(!SSPIF);						// 
	SSPIF = 0;							//
	SSPBUF = pos;						//  
	while(!SSPIF);						// 
	SSPIF = 0;							//
	 
	PEN = 1;								// send stop bit
	while(PEN);							//
}

		
void print(char *p)
{
	SEN = 1;								// send start bit
	while(SEN);							// and wait for it to clear

	SSPIF = 0;
	SSPBUF = 0xc6;						// LCD03 I2C address
	while(!SSPIF);						// wait for interrupt
	SSPIF = 0;							// then clear it.

	SSPBUF = 0;							// address of register to write to 
	while(!SSPIF);						// 
	SSPIF = 0;							//

	while(*p) {
		SSPBUF = *p++;					// write the data 
		while(!SSPIF);					// 
		SSPIF = 0;						// 
	}

	PEN = 1;								// send stop bit
	while(PEN);							//
}


void setup(void)
{
unsigned long x;

	PORTB = 0xff;
	TRISB = 0xff;	
	TRISC = 0xff;
	PORTC = 0xff;

	SSPSTAT = 0x80;
	SSPCON = 0x38;
	SSPCON2 = 0x00;
	SSPADD = 50;						// SCL = 91khz with 20Mhz Osc

	for(x=0; x<300000L; x++);		// wait for LCD03 to initialise		
}

