//Project : I2CSubroutines.c
//Date    : 5/23/2005
//Author  : Curtis Rhodes w/ help from Dr. Song's example
//Purpose : I2C Memory Chip Interface Subroutines
// Synchronous Serial Port
//	    RC3 (pin 18) == SCL (Clock for Memory Chip)
//	    RC4 (pin 23) == SDA (Serial Data for Memory Chip)
//          
//Chip type   : PIC16F877A
//Clock frequency     : 20 MHz

#include <pic.h>
#include "memory_to_DAC.h"

//======================================================================================================
// initializeI2C()
//======================================================================================================
//Initializes the I2C interface
void initializeI2C(){
	//Initialize I2C
	SSPCON = 0b00111000;
	SSPADD = 4;
	ACKEN = 0;
	ACKDT = 1;
	SSPIF = 0;
}

//======================================================================================================
// send_Start_Bit()
//======================================================================================================
//Sends a start bit through the I2C communication line
void send_Start_Bit(){
	// I2C Start
	SEN = 1;
	while(SSPIF == 0);
	SSPIF = 0;
}

//======================================================================================================
// send_Stop_Bit()
//======================================================================================================
//Sends a stop bit through the I2C communication line
void send_Stop_Bit(){
	//I2C STOP
	PEN = 1;
	while(SSPIF == 0);
	SSPIF = 0;
}

//======================================================================================================
// acknowledge()
//======================================================================================================
//Sends a stop bit through the I2C communication line
void acknowledge(){
	//I2C STOP
	ACKDT = 0;
	ACKEN = 1;
	while(ACKEN == 1) {}
	while(SSPIF == 0);
	SSPIF = 0;
}

//======================================================================================================
// write_Data()
//======================================================================================================
//Sends a byte through the I2C communication line
void write_Data(unsigned int write_data){
	SSPBUF = write_data;
	while(ACKSTAT == 1) {}
	while(SSPIF == 0) {}
	SSPIF = 0;
}

//======================================================================================================
// receive_Data()
//======================================================================================================
//Waits for a byte sent to the PIC through the I2C communication line
void receive_Data(){
	RCEN = 1;
	while(SSPIF == 0) {}
	SSPIF == 0;
	//RCEN = 0;
}

//======================================================================================================
// wait_For_Memory_Write_Completion()
//======================================================================================================
//Waits for the memory to complete its current write cycle
void wait_For_Memory_Write_Completion(int control_byte){
	// Wait Until Device is Ready
	do{
		send_Start_Bit();
		write_Data(control_byte);
	}while(ACKSTAT == 1);
	send_Stop_Bit();
}

//======================================================================================================
// memory_chip_write()
//======================================================================================================
//Places desired data into passed memory chip / address
void memory_chip_write(unsigned char memory_chip, unsigned char address_high, unsigned char address_low, unsigned char data){
	send_Start_Bit();
	write_Data(memory_chip);
	write_Data(address_high);
	write_Data(address_low);
	write_Data(data);
	send_Stop_Bit();
	//wait_For_Memory_Write_Completion(memory_chip);
}

//======================================================================================================
// memory_chip_write()
//======================================================================================================
//Places desired data into passed memory chip / address
unsigned char memory_chip_read(unsigned char memory_chip, unsigned char address_high, unsigned char address_low){
	unsigned char temp;
	send_Start_Bit();
	write_Data((memory_chip & 0b11111110));
	write_Data(address_high);
	write_Data(address_low);
	send_Stop_Bit();
	send_Start_Bit();
	write_Data(memory_chip);
	receive_Data();
	temp = SSPBUF;
	send_Stop_Bit();
	return temp;
}

//======================================================================================================
// start_sequential_read()
//======================================================================================================
//Places desired data into passed memory chip / address
void start_sequential_read(unsigned char memory_chip, unsigned char address_high, unsigned char address_low){
	send_Start_Bit();
	write_Data((memory_chip & 0b11111110));
	write_Data(address_high);
	write_Data(address_low);
	send_Stop_Bit();
	//READ FROM MEMORY
	send_Start_Bit();
	write_Data(memory_chip);
}

//======================================================================================================
// sequential_memory_chip_read()
//======================================================================================================
//Places desired data into passed memory chip / address
unsigned char sequential_memory_chip_read(){
	unsigned char temp;
	receive_Data();
	temp = SSPBUF;
	return temp;
}

//======================================================================================================
// end_sequential_read()
//======================================================================================================
//Places desired data into passed memory chip / address
void end_sequential_read(){
	send_Stop_Bit();
}