/*=====================================================================* * 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 #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