#include <p18f452.h>

/*	Example code for C18 compiler and PIC18F452, author: Jindong Liu, 23/07/2004

   Compass board uses address 1100000 - 0xc0
   This code shows how to program a PIC18F452 to communicate
   with the compass module via the I2C bus. It uses the hardware
   I2C port on the PIC, this is the MSSP. The PIC is assumed
   to use an 8MHz crystal, otherwise adjust SSPADD in the
   setup routine.
*/


void setup(void);
void read_compass(unsigned char *buffer);

int 		compass_high;
int		compass_low;
int 		compass;
unsigned char 	compasschar[4];
unsigned char 	version, compassbyte;

void main(void)
{
	setup();
	while(1)
	{
		read_compass(compasschar);
		version = compasschar[0];
		compassbyte = compasschar[1];
		compass_low =  compasschar[3];
		compass_high =	compasschar[2];
		compass = (compass_high<<8) + compass_low;
		//the compass range: 0-3599, compassbyte range: 0-255.	

	}
}

//COMPASS ROUTINE
void read_compass(unsigned char *buffer)
{
	SSPCON2bits.SEN = 1;					// send start bit
	while(SSPCON2bits.SEN);				// and wait for it to clear
	SSPCON2bits.ACKDT = 0;				// acknowledge bit

	PIR1bits.SSPIF = 0;
	SSPBUF = 0xC0;						// 11000000 - write command
	while(!PIR1bits.SSPIF);					// wait for interrupt
	PIR1bits.SSPIF = 0;					// then clear it.

	SSPBUF = 0;						// read from address 0 
	while(!PIR1bits.SSPIF);					// 
	PIR1bits.SSPIF = 0;					// 

	SSPCON2bits.RSEN = 1;					// send repeated start bit
	while(SSPCON2bits.RSEN);				// and wait for it to clear

	PIR1bits.SSPIF = 0;
	SSPBUF = 0xC1;						// 11000001 - read command
	while(!PIR1bits.SSPIF);					// wait for interrupt
	PIR1bits.SSPIF = 0;					// then clear it.
		
	SSPCON2bits.RCEN = 1;					// start receiving
	while(!SSPSTATbits.BF);					// wait for data
	buffer[0] = SSPBUF;					// and get it
	SSPCON2bits.ACKEN = 1;				// start acknowledge sequence
	while(SSPCON2bits.ACKEN);				// wait for ack. sequence to end
	
	SSPCON2bits.RCEN = 1;					// start receiving
	while(!SSPSTATbits.BF);					// wait for data
	buffer[1] = SSPBUF;					// and get it
	SSPCON2bits.ACKEN = 1;				// start acknowledge sequence
	while(SSPCON2bits.ACKEN);				// wait for ack. sequence to end

	SSPCON2bits.RCEN = 1;					// start receiving
	while(!SSPSTATbits.BF);					// wait for data
	buffer[2] = SSPBUF;					// and get it
	SSPCON2bits.ACKEN = 1;				// start acknowledge sequence
	while(SSPCON2bits.ACKEN);				// wait for ack. sequence to end

	SSPCON2bits.RCEN = 1;					// start receiving
	while(!SSPSTATbits.BF);					// wait for data
	buffer[3] = SSPBUF;					// and get it
	SSPCON2bits.ACKDT = 1;				// not acknowledge for last byte
	SSPCON2bits.ACKEN = 1;				// start acknowledge sequence
	while(SSPCON2bits.ACKEN);				// wait for ack. sequence to end

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


void setup(void)
{
char x;
	TRISC = 0x18;			// RC3-4 are inputs
	SSPSTAT = 0x80;		// slew rate disabled for Standard Speed mode (100 kHz and 1 MHz)
	SSPCON1  = 0x38;		// I2C Master mode, clock = FOSC / (4 * (SSPADD+1))
	SSPCON2 = 0x00;		// not a lot
	SSPADD  = 19;			// baud rate in address reg 100k in 8Mhz, clock = Fosc/(4*(SSPADD+1))
	x = SSPBUF;			// dummy read clears BF
}

