/*  Name     : main.c from Peter
 *  Purpose  : Main file for i2c code for PIC12F675.
 */
 #include <htc.h> 

#define _XTAL_FREQ   4000000      // Hz

/* Pin configuration
 * 
 * GP4 = SDA pin for i2c
 * GP5 = SCK pin for i2c
 */
 
#define LED GPIO0

 // Define i2c pins
#define SDA			GPIO4				// Data pin for i2c
#define SCK			GPIO5				// Clock pin for i2c
#define SDA_DIR		TRIS4			// Data pin direction
#define SCK_DIR		TRIS5			// Clock pin direction

#define DataPinADCMask		ANS3	// It is attached on GP4(AN3) pin
#define ClockPinADCMask		ANS3	// It is not attached on any ADC pin

// Define i2c speed
#define I2C_SPEED	1				// kbps 
#define HalfBitDelay 500/I2C_SPEED	// usec

// Define macros
#define Set_SDA_Low		SDA_DIR = 0
#define Set_SDA_High	SDA_DIR = 1
#define Set_SCK_Low		SCK_DIR = 0
#define Set_SCK_High	SCK_DIR = 1

//Function Declarations
void InitI2C(void);
void I2C_Start(void);
void I2C_ReStart(void);
void I2C_Stop(void);
void I2C_Send_ACK(void);
void I2C_Send_NACK(void);
bit  I2C_Write_Byte(unsigned char);
unsigned char I2C_Read_Byte(void);

void InitCCT(void)
{
	ANSEL  = 0x00;       // Set ports as digital I/O, not analog input
	ADCON0 = 0x00;		 // Shut off the A/D Converter
	CMCON  = 0x07;		 // Shut off the Comparator
	VRCON  = 0x00;	     // Shut off the Voltage Reference

}


// Config word
__CONFIG(BORDIS & UNPROTECT & UNPROTECT & MCLRDIS & PWRTEN & WDTDIS & INTIO);

volatile unsigned char tempHI = 0;
volatile unsigned char tempLO = 0;

// Main function
void main()
{

	TRIS0 = 0;
	InitCCT();	// Turn off ADC and comparator to make pins digital IOs
	InitI2C();	// Initialize i2c pins											

	//Setup Device
	I2C_Start();				// Send start bit on i2c
	I2C_Write_Byte(0x90);
	I2C_Write_Byte(0xAC);
	I2C_Write_Byte(0x02);
	I2C_Send_ACK();				// Send ACK bit on i2c
	I2C_Stop();					// Send stop bit on i2c
	
	//Minimum és maximum hőmérsékletekek beállítása
	// Hiszterézis a kettő érték, 6 és 2 közt. (5-3)
	I2C_Start();				// Send start bit on i2c
	I2C_Write_Byte(0x90);
	I2C_Write_Byte(0xA1);
	I2C_Write_Byte(0x06);	// Maximum +6fok (TOUT magas szintre vált)
	I2C_Send_ACK();				// Send ACK bit on i2c
	I2C_Stop();					// Send stop bit on i2c
	
	I2C_Start();				// Send start bit on i2c
	I2C_Write_Byte(0x90);
	I2C_Write_Byte(0xA2);
	I2C_Write_Byte(0x85);	// Minimum +2fok (TOUT alacsony szintre vált)
	I2C_Send_ACK();				// Send ACK bit on i2c
	I2C_Stop();					// Send stop bit on i2c
	
	//Start temp converstion
	I2C_Start();				// Send start bit on i2c
	I2C_Write_Byte(0x90);
	I2C_Write_Byte(0xEE);
	I2C_Send_ACK();				// Send ACK bit on i2c
	I2C_Stop();					// Send stop bit on i2c
	
	/*//Read TempHI
	I2C_Start();
	I2C_Write_Byte(0x90);	// sends address to the device
	__delay_us(HalfBitDelay);
    I2C_Write_Byte(0xAA);	// access the temperature register
	__delay_us(HalfBitDelay);
    I2C_Write_Byte(0x91);	// address device w/read
	__delay_us(HalfBitDelay);  
    tempHI = I2C_Read_Byte(); // Read MSB of temp
    __delay_us(HalfBitDelay);
    I2C_Send_ACK();	// Send back Ack
    __delay_us(HalfBitDelay);
    tempLO = I2C_Read_Byte(); // Read LSB of temp
    __delay_us(HalfBitDelay);
    I2C_Send_ACK();	// Send back NotAck
    __delay_us(HalfBitDelay);
	I2C_Stop();	//Stop I2C communication*/

	while (1){
		LED = !LED;
	   __delay_ms(1000);
	}

}
// Function Purpose: Set initial values of SCK and SDA pins
void InitI2C(void)
{	
	DataPinADCMask  = 1;	// Make analog output
	ClockPinADCMask = 1;	// Make analog output

	// Make SDA and SCK pins input initially
	SDA_DIR = 1;
	SCK_DIR = 1;
	
	// Write zero in output register of SDA and SCK pin
	SDA = 0;
	SCK = 0;
}


// Function Purpose: I2C_Start sends start bit sequence
void I2C_Start(void)
{
	SDA = 0;	// Write zero in output register 
	SCK = 0;	// of SDA and SCK pin

	Set_SCK_High;				// Make SCK pin high
	Set_SDA_High;				// Make SDA pin High
	__delay_us(HalfBitDelay);	// Half bit delay
	Set_SDA_Low;				// Make SDA Low
	__delay_us(HalfBitDelay);	// Half bit delay
}


// Function Purpose: I2C_ReStart sends start bit sequence
void I2C_ReStart(void)
{
	Set_SCK_Low;				// Make SCK pin low

	__delay_us(HalfBitDelay/2);	// Data pin should change it's value,
								// when it is confirm that SCK is low
	Set_SDA_High;				// Make SDA pin High
	
	__delay_us(HalfBitDelay/2);	// 1/4 bit delay
	Set_SCK_High;				// Make SCK pin high
	__delay_us(HalfBitDelay/2);	// 1/4 bit delay
	Set_SDA_Low;				// Make SDA Low
	__delay_us(HalfBitDelay/2);	// 1/4 bit delay
}


//Function : I2C_Stop sends stop bit sequence
void I2C_Stop(void)
{
	Set_SCK_Low;				// Make SCK pin low

	__delay_us(HalfBitDelay/2);	// Data pin should change it's value,
								// when it is confirm that SCK is low
	Set_SDA_Low;				// Make SDA pin low
	
	__delay_us(HalfBitDelay/2);	// 1/4 bit delay
	Set_SCK_High;				// Make SCK pin high
	__delay_us(HalfBitDelay/2);	// 1/4 bit delay
	Set_SDA_High;				// Make SDA high
	__delay_us(HalfBitDelay/2);	// 1/4 bit delay
}



//Function : I2C_Send_ACK sends ACK bit sequence
void I2C_Send_ACK(void)
{
	Set_SCK_Low;				// Make SCK pin low
	__delay_us(HalfBitDelay/2);	// Data pin should change it's value,
								// when it is confirm that SCK is low
	Set_SDA_Low;				// Make SDA Low
	__delay_us(HalfBitDelay/2);	// 1/4 bit delay
	Set_SCK_High;				// Make SCK pin high
	__delay_us(HalfBitDelay);	// Half bit delay
}


//Function : I2C_Send_NACK sends NACK bit sequence
void I2C_Send_NACK(void)
{
	Set_SCK_Low;				// Make SCK pin low
	__delay_us(HalfBitDelay/2);	// Data pin should change it's value,
								// when it is confirm that SCK is low
	Set_SDA_High;				// Make SDA high
	__delay_us(HalfBitDelay/2);	// 1/4 bit delay
	Set_SCK_High;				// Make SCK pin high
	__delay_us(HalfBitDelay);	// Half bit delay
}


// Function Purpose: I2C_Write_Byte transfers one byte
bit I2C_Write_Byte(unsigned char Byte)
{
	static bit ACK = 0;

	unsigned char i;		// Variable to be used in for loop
	
	for(i=0;i<8;i++)		// Repeat for every bit
	{
		Set_SCK_Low;		// Make SCK pin low
		
		__delay_us(HalfBitDelay/2);	// Data pin should change it's value,
									// when it is confirm that SCK is low

		if((Byte<<i)&0x80)  // Place data bit value on SDA pin
			Set_SDA_High;	// If bit is high, make SDA high
		else				// Data is transferred MSB first
			Set_SDA_Low;	// If bit is low, make SDA low

		__delay_us(HalfBitDelay/2);	// Toggle SCK pin
		Set_SCK_High;				// So that slave can
		__delay_us(HalfBitDelay);	// latch data bit
    }
		
	// Get ACK from slave
	Set_SCK_Low;
    Set_SDA_High;
    __delay_us(HalfBitDelay);
    Set_SCK_High;
    __delay_us(HalfBitDelay);

	DataPinADCMask = 0;		// Make digital input
	ACK = SDA;				// Read data pin status
	DataPinADCMask = 1;		// Make analog output

	return ACK;
}


// Function Purpose: I2C_Read_Byte reads one byte
unsigned char I2C_Read_Byte(void)
{
	unsigned char i, RxData = 0;

	for(i=0;i<8;i++)
	{
		Set_SCK_Low;					// Make SCK pin low
		Set_SDA_High;					// Don't drive SDA 
		__delay_us(HalfBitDelay);		// Half bit delay
		Set_SCK_High;					// Make SCK pin high
		__delay_us(HalfBitDelay/2);		// 1/4 bit delay
		DataPinADCMask = 0;				// Make digital input
		RxData = RxData|(SDA<<(7-i));	// Captured received bit
		DataPinADCMask = 1;				// Make analog output
		__delay_us(HalfBitDelay/2);		// 1/4 bit delay
	}
 
    return RxData;						// Return received byte
}

