#include <p24FJ128GA006.h>
#include <stdio.h>
#include "../mcu/serial.h"
#include "SEEP.h"
#include "../mcu/delay.h"

void InitSEEP(void)
{
	I2C1BRG = 0x13;			// 400kHz
	I2C1CONbits.I2CEN = 1;
	I2C1CONbits.DISSLW = 1;
}

void i2c_waitForIdle(void)
{
    /* Wait until I2C Bus is Inactive */
	while(I2C1CONbits.ACKEN || I2C1CONbits.RCEN || I2C1CONbits.PEN || I2C1CONbits.RSEN || I2C1CONbits.SEN || I2C1STATbits.TRSTAT);
}

void i2c_start()
{
	i2c_waitForIdle();
	I2C1CONbits.SEN = 1;
	if(I2C1STATbits.BCL) uart_puts(0, "Start Failed(bus collision occor)\r");
}

void i2c_repStart()
{
	i2c_waitForIdle();
	I2C1CONbits.RSEN = 1;
	if(I2C1STATbits.BCL) uart_puts(0, "Start Failed(bus collision occor)\r");
}

void i2c_stop()
{
	i2c_waitForIdle();
	I2C1CONbits.PEN=1;
	if(I2C1STATbits.BCL) uart_puts(0, "Start Failed(bus collision occor)\r");
}

int i2c_read( unsigned char ack )
{
	unsigned char i2cReadData;

	i2c_waitForIdle();

	I2C1CONbits.RCEN=1;

	i2c_waitForIdle();

	i2cReadData = I2C1RCV;

	i2c_waitForIdle();

	if ( ack )
	{
		I2C1CONbits.ACKDT=0;
	}
	else
	{
		I2C1CONbits.ACKDT=1;
	}
	I2C1CONbits.ACKEN=1;               // send acknowledge sequence

	return( i2cReadData );
}

unsigned char i2c_write( uint8 i2cWriteData )
{
	i2c_waitForIdle();
	I2C1TRN = i2cWriteData;

	if(I2C1STATbits.IWCOL) uart_puts(0, "Write Failed(write collision occor)\r");
	return ( !I2C1STATbits.ACKSTAT  ); // function returns '1' if transmission is acknowledged
}

void eeprom_write_byte(uint8 add, uint8 dat)
{
	i2c_start();
	i2c_write(0xa0);
	i2c_write(add);
	i2c_write(dat);
	i2c_stop();
	wait_1ms(5);
}

uint8 eeprom_read_byte(uint8 add)
{
	unsigned char data;

	i2c_start();
	i2c_write(0xa0);
	i2c_write(add);
	i2c_repStart();
	i2c_write(0xa1);
	data = i2c_read(0);
	i2c_stop();
	return(data);
}

void eeprom_write_word(uint8 add, uint16 dat)
{
	eeprom_write_byte(add, dat);
	add++;
	eeprom_write_byte(add, dat>>8);
}

uint16 eeprom_read_word(uint8 add)
{
	uint16 ret;

	ret = eeprom_read_byte(add);
	add++;
	ret |= eeprom_read_byte(add) << 8;
	return ret;
}

void eeprom_write_block(void *pointer_ram, uint8 add_eeprom, size_t n)
{
	uint8 *pt1;
	pt1 = (uint8 *)pointer_ram;

	for(;n;n--) {
		eeprom_write_byte(add_eeprom, *pt1++);
		add_eeprom++;
	}
}

void eeprom_read_block(void *pointer_ram, uint8 add_eeprom, size_t n)
{
	uint8 *pt1;
	pt1 = (uint8 *)pointer_ram;

	for(;n;n--) {
		*pt1++ = eeprom_read_byte(add_eeprom);
		add_eeprom++;
	}
}
