/*=====================================================================*
* EE_IF.C function module
*
* EEPROM SPECIFIC FUNCTIONS
*
* Notes:
*	This is designed for a M24C64 64kb I2C serial EEPROM,
*	However, the Get/PutEEByte and Get/PutEEWord routines only access the
*	first 256 bytes of the chip because the address is defined as an
*	unsigned char.
*	The Get/PutEEBlock can access the entire array (address is 16 bits).
*=====================================================================*/

#include <stdio.h>
#include "i2c_if.h"
#include "ee_if.h"

#define EEPromAddr	0xA6

extern unsigned char xdata _i2c_error;

/*---------------------------------------------------------------------*
* FUNCTION: GetEEByte()
*
*	Reads a single byte from the EEPROM at byte address
*	Similarly to GetEEWord(), this function only accesses the first 256
*	bytes of the EEPROM, so address is uchar.
*---------------------------------------------------------------------*/
bit GetEEByte( unsigned char address, unsigned char xdata *ee_data ){

	I2CSendAddr( EEPromAddr, WRITE );
	if( I2CCheckError() > 0 ){
		I2CSendStop();
		return( FALSE );
	}
	I2CSendByte( 0 );
	I2CSendByte( address );

	/* now set device to read */
	I2CSendAddr( EEPromAddr, READ );	// sends 0 again?

	/* and read data */
	*ee_data = I2CGetLastByte();
	I2CSendStop();

	return( TRUE );

} /* end GetEEByte() */

/*---------------------------------------------------------------------*
* FUNCTION: PutEEByte()
*
*	Stores a byte to the EEPROM at byte address
*	Similarly to GetEEByte(), this function only accesses the first 256 bytes
*	of the EEPROM, so address is uchar.
*----------------------------------------------------------------------*/
bit PutEEByte( unsigned char address, unsigned char ee_data ){

	I2CSendAddr( EEPromAddr, WRITE );
	if( I2CCheckError() ){
		I2CSendStop();			// device not found
		return( FALSE );
	}
	I2CSendByte( 0 );	// address MSB
	I2CSendByte( address );
	I2CSendByte( ee_data );
	I2CSendStop();

	return( TRUE );

} // end PutEEByte()

/*---------------------------------------------------------------------*
* FUNCTION: GetEEWord()
*
*	Get a word (int) from the EEPROM at byte address.
*	Since this function is only used to access the first two pages of the
*	array, the high order address bits (A8 - A12, normally part of the device
*	address) are set to zero.
*	Word is retrieved LSB first (LSB is at lower memory address)
*----------------------------------------------------------------------*/
bit GetEEWord( unsigned char address, unsigned int xdata *ee_data ){

	/* first, tell device we are going to write address */
	I2CSendAddr( EEPromAddr, WRITE );
	if( I2CCheckError() ){
		I2CSendStop();
		return( FALSE );
	}

	/* then send address to start reading from */
	I2CSendByte( 0 );
	I2CSendByte( address );

	/* put device in read mode */
	I2CSendAddr( EEPromAddr, READ );

	/* get LSB, acknowledge */
	*ee_data = I2CGetByte();

	/* get MSB, do not acknowledge to signify this is the last byte desired */
	*ee_data += I2CGetLastByte() * 256;
	I2CSendStop();

	return( TRUE );

} /* end GetEEWord() */

/*---------------------------------------------------------------------*
* FUNCTION: PutEEWord()
*
*	Store a word (int) to the EEPROM at byte address
*	This function can only access the first 256 bytes of the EEPROM,
*	so address is uchar.
*	Word is stored LSB first (at lower memory address)
*----------------------------------------------------------------------*/
bit PutEEWord( unsigned char address, unsigned int data_word ){

	unsigned char xdata ee_data;

	I2CSendAddr( EEPromAddr, WRITE );
	if( I2CCheckError() ){
		I2CSendStop();
		return( FALSE );
	}
	I2CSendByte( 0 );	/* address MSB */
	I2CSendByte( address );

	/* send LSB first */
	ee_data = (unsigned char)(data_word & 0xFF);
	I2CSendByte( ee_data );

	/* then send MSB */
	ee_data = (unsigned char)(data_word / 256);
	I2CSendByte( ee_data );

	I2CSendStop();

	return( TRUE );

} /* end PutEEWord() */

/*---------------------------------------------------------------------*
* FUNCTION: GetEEBlock()
*
*	Read a block of data from EEPROM at once
*
*	NOTES:
*		1) block size cannot be greater than one page
*		2) address must be a byte address less than 8192
*	Function fails if error while accessing device. Error is checked only
*	after initial address selection.
*	This function works over the entire EEPROM array, so the byte address
*	is now an unsigned int.
*----------------------------------------------------------------------*/
#ifdef EEBLOCK
bit GetEEBlock( unsigned int address, unsigned char xdata *ee_data, unsigned char size ){

	unsigned char xdata addr_h;
	unsigned char idata i;

	addr_h = EEPromAddr;


	I2CSendAddr( addr_h, WRITE );
	if( I2CCheckError() ){
		I2CSendStop();
		return( FALSE );
	}
	/* send high order address bits */
	I2CSendByte( (unsigned char)(address/256) );

	/* send low order address bits */
	I2CSendByte( (address & 0xFF) );

	/* set device to read */
	I2CSendAddr( addr_h, READ );

	/* read data */
	for( i=0; i< size-1; i++ )
		*ee_data++ = I2CGetByte();
	*ee_data = I2CGetLastByte();

	I2CSendStop();

	return( TRUE );

} /* end GetEEBlock() */


/*---------------------------------------------------------------------*
* FUNCTION: PutEEBlock()
*
*	Write a block of data to EEPROM at once.
*	See GetEEBlock()
*	Please note some devices only let you write up to 16 bytes (one page)
*	at a time, see device specification.
*----------------------------------------------------------------------*/
bit PutEEBlock( unsigned int address, unsigned char xdata *ee_data, unsigned char size ){

	unsigned char xdata addr_h;
	unsigned char idata i;

	addr_h = EEPromAddr;

	I2CSendAddr( addr_h, WRITE );
	if( I2CCheckError() ){
		I2CSendStop();
		return( FALSE );
	}
	/* send high order address bits */
	I2CSendByte( (unsigned char)(address/256) );

	/* send low order address bits */
	I2CSendByte( (address & 0xFF) );

	/* send data */
	for( i=0; i< size; i++ ){
		I2CSendByte( *ee_data++ );
		if( I2CCheckError() ){
			I2CSendStop();
			return( FALSE );
		}
	}

	I2CSendStop();

	return( TRUE );

} /* end PutEEBlock() */
#endif





























