#include <LPC214X.h>
#include "EEPROM.h"

#define BIT(x) (1 << x)

#define I2C_EN BIT(6)
#define I2C_STA BIT(5)
#define I2C_STO BIT(4)
#define I2C_SI BIT(3)
#define I2C_AA BIT(2)

#define EEPROM_WRITE 0xA0
#define EEPROM_READ 0xA1

void InitEEPROM(void) {
	//PCONP = 0xFFFFFFFF;
//	PINSEL0 = (PINSEL0 & (~(0x03 << 22))) | (0x03 << 22) |
   			  //(PINSEL0 & (~(0x03 << 28))) | (0x03 << 28);
	PINSEL0 |= 0x30C00000;
//	I21SCLH = (14745600/100000 + 1) / 2;
//	I21SCLL = (14745600/100000) / 2;
	I21SCLH = (12000000/100000 + 1) / 2;
	I21SCLL = (12000000/100000) / 2;
	I21CONCLR = I2C_STA | I2C_STO | I2C_SI | I2C_AA;
	I21CONSET = I2C_EN;
	}//InitEEPROM

void AddressEEPROM(unsigned char ChipID, unsigned short Address) {
	volatile unsigned int s;
	do {
		I21CONSET = I2C_STA | I2C_SI; //setup start condition
		I21CONCLR = I2C_SI; //send start condition
		s =  I21CONSET;
		while (~I21CONSET & I2C_SI)
		 s=I21CONSET; //wait for start to be sent
		I21DAT = EEPROM_WRITE | (ChipID & 0x7) << 1; //load the EEPROM address
		I21CONCLR = I2C_STA | I2C_SI; //send EEPROM address
		while (~I21CONSET & I2C_SI); //wait for address to be sent
		s=I21STAT;
		}while (I21STAT != 0x18); //repeat if no ACK received
//	I21DAT = (Address >> 8) & 0xFF; //load high address
//	I21CONCLR = I2C_SI; //send data
//	while (~I21CONSET & I2C_SI); //wait
	I21DAT = Address & 0xFF; //load low address
	I21CONCLR = I2C_SI; //send data
	while (~I21CONSET & I2C_SI); //wait
	}//AddressEEPROM

void WriteEEPROM(unsigned char ChipID, unsigned short Address, unsigned char Data) {
	AddressEEPROM(ChipID, Address);
	I21DAT = Data; //load data
	I21CONCLR = I2C_SI; //send data
	while (~I21CONSET & I2C_SI); //wait for data to be sent
	I21CONSET = I2C_STO; //setup stop condition
	I21CONCLR = I2C_SI; //start sending stop
	while (I21CONSET & I2C_STO); //wait for stop to be sent
	}//WriteEEPROM

unsigned char ReadEEPROM (unsigned char ChipID) {
	unsigned char Data;
	do {
		I21CONSET = I2C_STA | I2C_SI; //setup start condition
		I21CONCLR = I2C_SI; //send start condition
		while (~I21CONSET & I2C_SI); //wait for start to be sent
		I21DAT = EEPROM_READ|(ChipID&0x07)<<1; //load address of eeprom
		I21CONCLR = I2C_STA | I2C_SI; //start sending address
		while (~I21CONSET & I2C_SI); //wait for address to be sent
		} while (I21STAT != 0x40); //repeat if no ack received
	I21CONCLR = I2C_SI; //start reading data
	while (~I21CONSET & I2C_SI); //wait for data to be received
	Data = I21DAT;
	I21CONSET = I2C_STO; //setup stop condition
	I21CONCLR = I2C_SI; //send stop condition
	while (I21CONSET & I2C_STO); //wait for stop to be sent
	return Data; //return the data
	}//ReadEEPROM

void WriteEEPROMpage(unsigned char ChipID, unsigned short Address, unsigned char *Data, char Size) {
	char i;
	AddressEEPROM(ChipID, Address);
	for(i=0;i<Size;i++) {
		I21DAT = *(Data+i); //load data
		I21CONCLR = I2C_SI; //send data
		while (~I21CONSET & I2C_SI); //wait for data to be sent
		}
	I21CONSET = I2C_STO; //setup stop condition
	I21CONCLR = I2C_SI; //start sending stop
	while (I21CONSET & I2C_STO); //wait for stop to be sent
	}//WriteEEPROM

void ReadEEPROMpage (unsigned char ChipID, unsigned short Address, unsigned char *Data, char Size) {
	unsigned char i;
	AddressEEPROM(ChipID, Address);
	do {
		I21CONSET = I2C_STA | I2C_SI; //setup start condition
		I21CONCLR = I2C_SI; //send start condition
		while (~I21CONSET & I2C_SI); //wait for start to be sent
		I21DAT = EEPROM_READ|(ChipID&0x07)<<1; //load address of eeprom
		I21CONCLR = I2C_STA | I2C_SI; //start sending address
		while (~I21CONSET & I2C_SI); //wait for address to be sent
		} while (I21STAT != 0x40); //repeat if no ack received
	for(i=0;i<Size;i++) {
		I21CONCLR = I2C_SI; //start reading data
		while (~I21CONSET & I2C_SI); //wait for data to be received
		*(Data+i) = I21DAT;
		}
	I21CONSET = I2C_STO; //setup stop condition
	I21CONCLR = I2C_SI; //send stop condition
	while (I21CONSET & I2C_STO); //wait for stop to be sent
	}//ReadEEPROM

