
#include <reg936.h>//SFR description needs to be included
#include "eeprom.h" 
static bit meeprombusy;//flag that indicates if the EEPROM is busy or not 
/***********************************************************************
DESC:    Initializes the EEPROM. Enables EEPROM interrupt
RETURNS: Nothing
CAUTION: Set EA to 1 after calling to enable all interrupts
************************************************************************/
void eeprom_init(void)
{  
  meeprombusy = 0;//initially eeprom is not busy  
  IP1 &= 0x7F;//set isr priority to 0
  IP1H &= 0x7F;  
  EIEE = 1;//enable eeprom interrupt
}
/***********************************************************************
DESC:    Reads a location in the EEPROM.
         If either global interrupts or the EEPROM interrupt is disabled
         then the function will return when the operation is complete.
         If global interrupts and the EEPROM interrupt are enabled, the
         function will return immediately and an interrupt will occur
         when the operation is complete.
RETURNS: The 8-bit value read if interrupts are disabled, otherwise
         0x00 will be returned.
CAUTION: eeprom_init must be called first
************************************************************************/
unsigned char eeprom_read(unsigned int address)//9-bit address to read (0x000 - 0x1FF)
{  
  while (meeprombusy);//wait for previous operation to complete  
  meeprombusy = 1;//eeprom now busy 
  DEECON = (address >> 8) & 0x01;//store bit 8 of address
                    //byte operation, clear interrupt flag
  DEEADR = address & 0xFF;//store bits 0-7 of address   
  if (!EA || !EIEE)//if not using interrupt then poll for end of operation
  {    
    while (!(DEECON & 0x80));//wait for operation to complete    
    meeprombusy = 0;//eeprom no longer busy    
    return DEEDAT;//return value
  }
  return 0x00;
}
/***********************************************************************
DESC:    Writes to a location in the EEPROM.
         If either global interrupts or the EEPROM interrupt is disabled
         then the function will return when the operation is complete.
         If global interrupts and the EEPROM interrupt are enabled, the
         function will return immediately and an interrupt will occur
         when the operation is complete.
RETURNS: Nothing
CAUTION: eeprom_init must be called first
************************************************************************/
void eeprom_write(unsigned int address, unsigned char value)//9-bit address to write to (0x000 - 0x1FF)
{
  bit eacopy;//value to write  
  while (meeprombusy);//wait for previous operation to complete  
  meeprombusy = 1;//eeprom now busy  
  DEECON = (address >> 8) & 0x01;//store bit 8 of address
                    //byte operation, clear interrupt flag
  eacopy = EA;
  EA = 0; //disable interrupts  
  DEEDAT = value;//store value to write   
  DEEADR = address & 0xFF;//store bits 0-7 of address  
  EA = eacopy;//restore interrupts  
  if (!EA || !EIEE)//if not using interrupt then poll for end of operation
  {     
    while (!(DEECON & 0x80));//wait for operation to complete    
    meeprombusy = 0;//eeprom no longer busy
  }
}

/***********************************************************************
DESC:    EEPROM Interrupt Service Routine
         Called when an EEPROM operation has completed
         Uses register bank 1
RETURNS: Nothing
CAUTION: eeprom_init must be called first
************************************************************************/
void eeprom_isr(void) interrupt 14 using 1
{  
  DEECON &= ~0x80;//clear EEIF flag 
  meeprombusy = 0;//eeprom no longer busy
}
