Jack Berkhout / EEPROM
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EEPROM.cpp Source File

EEPROM.cpp

00001 /***********************************************************
00002 Author: Bernard Borredon
00003 Version: 1.3
00004   - Correct write(uint32_t address, int8_t data[], uint32_t length) for eeprom >= T24C32.
00005     Tested with 24C02, 24C08, 24C16, 24C64, 24C256, 24C512, 24C1025 on LPC1768 (mbed online and µVision V5.16a).
00006   - Correct main test.
00007     
00008 Date : 12 decembre 2013
00009 Version: 1.2
00010   - Update api documentation
00011   
00012 Date: 11 december 2013
00013 Version: 1.1
00014   - Change address parameter size form uint16_t to uint32_t (error for eeprom > 24C256).
00015   - Change size parameter size from uint16_t to uint32_t (error for eeprom > 24C256).
00016     - Correct a bug in function write(uint32_t address, int8_t data[], uint32_t length) :
00017       last step must be done only if it remain datas to send.
00018     - Add function getName.
00019     - Add function clear.
00020     - Initialize _name array.
00021 
00022 Date: 27 december 2011
00023 Version: 1.0
00024 
00025 Jack: Many thanks Bernard!
00026 
00027 Changed a lot of things by Jack Berkhout 23-11-2016
00028 - Renamed read and write functions so they speak for them selves and do no longer
00029 recursively call themselves, causing hangs.
00030 - Also changed the way they return values. and added double and string handling.
00031 
00032 ************************************************************/
00033 #include "EEPROM.h"
00034 
00035 #define BIT_SET(x,n) (x=x | (0x01<<n))
00036 #define BIT_TEST(x,n) (x & (0x01<<n))
00037 #define BIT_CLEAR(x,n) (x=x & ~(0x01<<n))
00038 
00039 const char * const EEPROM::_name[] = {"24C01","24C02","24C04","24C08","24C16","24C32",
00040                                         "24C64","24C128","24C256","24C512","24C1024","24C1025"};
00041 
00042 /**
00043  * EEPROM(PinName sda, PinName scl, uint8_t address, TypeEeprom type) : _i2c(sda, scl)
00044  *
00045  * Constructor, initialize the eeprom on i2c interface.
00046  * @param sda sda i2c pin (PinName)
00047  * @param scl scl i2c pin (PinName)
00048  * @param address eeprom address, according to eeprom type (uint8_t)
00049  * @param type eeprom type (TypeEeprom) 
00050  * @return none
00051 */
00052 EEPROM::EEPROM(PinName sda, PinName scl, uint8_t address, TypeEeprom type) : _i2c(sda, scl) 
00053 //EEPROM::EEPROM(I2C* i2c, uint8_t address, TypeEeprom type) 
00054 {
00055 //     _i2c = i2c;
00056  
00057     _errnum = EEPROM_NoError;
00058     _type = type;
00059     
00060     // Check address range
00061     _address = address;
00062     switch(type) {
00063         case T24C01 :
00064         case T24C02 :
00065             if(address > 7) {
00066                 _errnum = EEPROM_BadAddress;
00067             }
00068             _address = _address << 1;
00069             _page_write = 8;
00070             _page_number = 1;
00071             break;
00072         case T24C04 :
00073             if(address > 7) {
00074                 _errnum = EEPROM_BadAddress;
00075             }
00076             _address = (_address & 0xFE) << 1;
00077             _page_write = 16;
00078             _page_number = 2;
00079             break;
00080         case T24C08 :
00081             if(address > 7) {
00082                 _errnum = EEPROM_BadAddress;
00083             }
00084             _address = (_address & 0xFC) << 1;
00085             _page_write = 16;
00086             _page_number = 4;
00087             break;
00088         case T24C16 :
00089             _address = 0;
00090             _page_write = 16;
00091             _page_number = 8;
00092             break;
00093         case T24C32 :
00094         case T24C64 :
00095             if(address > 7) {
00096                 _errnum = EEPROM_BadAddress;
00097             }
00098             _address = _address << 1;
00099             _page_write = 32;
00100             _page_number = 1;
00101             break;
00102         case T24C128 :
00103         case T24C256 :
00104             if(address > 3) {
00105                 _errnum = EEPROM_BadAddress;
00106             }
00107             _address = _address << 1;
00108             _page_write = 64;
00109             _page_number = 1;
00110             break;
00111         case T24C512 :
00112             if(address > 3) {
00113                 _errnum = EEPROM_BadAddress;
00114             }
00115             _address = _address << 1;
00116             _page_write = 128;
00117             _page_number = 1;
00118             break;
00119         case T24C1024 :
00120             if(address > 7) {
00121                 _errnum = EEPROM_BadAddress;
00122             }
00123             _address = (_address & 0xFE) << 1;
00124             _page_write = 128;
00125             _page_number = 2;
00126             break;
00127         case T24C1025 :
00128             if(address > 3) {
00129                 _errnum = EEPROM_BadAddress;
00130             }
00131             _address = _address << 1;
00132             _page_write = 128;
00133             _page_number = 2;
00134             break;
00135     }
00136   
00137     // Size in bytes
00138     _size = _type;
00139     if(_type == T24C1025) {
00140         _size = T24C1024;
00141     }
00142     
00143     // Set I2C frequency
00144     _i2c.frequency(400000);
00145 }
00146 
00147 /**
00148  * void write(uint32_t address, int8_t data[], uint32_t length)
00149  *
00150  * Write array of bytes (use the page mode)
00151  * @param address start address (uint32_t)
00152  * @param data bytes array to write (int8_t[])
00153  * @param size number of bytes to write (uint32_t)
00154  * @return none
00155 */
00156 void EEPROM::write_data_array(uint32_t address, uint8_t data[], uint32_t length)
00157 {
00158     uint8_t page;
00159     uint8_t addr = 0;
00160     uint8_t blocs,remain;
00161     uint8_t fpart,lpart;
00162     uint8_t i,j,ind;
00163     uint8_t cmd[129];
00164     int ack;
00165 
00166     // wait until ready
00167     ready();
00168 
00169     // Check error
00170     if(_errnum) {
00171         return;
00172     }
00173     
00174     // Check address
00175     if(!checkAddress(address)) {
00176         _errnum = EEPROM_OutOfRange;
00177         return;
00178     }
00179   
00180     // Check length
00181     if(!checkAddress(address + length - 1)) {
00182         _errnum = EEPROM_OutOfRange;
00183         return;
00184     }
00185   
00186     // Compute blocs numbers
00187     blocs = length / _page_write;
00188     
00189     // Compute remaining bytes
00190     remain = length - blocs * _page_write;
00191 
00192     for(i = 0;i < blocs;i++) {
00193         // Compute page number
00194         page = 0;
00195         if(_type < T24C32) {
00196             page = (uint8_t) (address / 256);
00197         }
00198   
00199         // Device address
00200         addr = EEPROM_Address | _address | (page << 1);
00201   
00202         if(_type < T24C32) {
00203             // Word address
00204             cmd[0] = (uint8_t) (address - page * 256);
00205      
00206             if((uint8_t) ((address + _page_write) / 256) == page) { // Data fit in the same page
00207                 // Add data 
00208                 for(j = 0;j < _page_write;j++) {
00209                     cmd[j + 1] = (uint8_t) data[i * _page_write + j];
00210                 }
00211     
00212                 // Write data
00213                 ack = _i2c.write((int)addr,(char *)cmd,_page_write + 1);
00214                 if(ack != 0) {
00215                     _errnum = EEPROM_I2cError;
00216                     return;
00217                 }
00218   
00219                 // Wait end of write
00220                 ready();
00221        
00222                 // Increment address
00223                 address += _page_write;
00224             }
00225             else { // Data on 2 pages. We must split the write
00226                 // Number of bytes in current page
00227                 fpart = (page + 1) * 256 - address;
00228        
00229                 // Add data for current page
00230                 for(j = 0;j < fpart;j++) {
00231                     cmd[j + 1] = (uint8_t) data[i * _page_write + j];
00232                 }
00233     
00234                 // Write data for current page
00235                 ack = _i2c.write((int)addr,(char *)cmd,fpart + 1);
00236                 if(ack != 0) {
00237                     _errnum = EEPROM_I2cError;
00238                     return;
00239                 }
00240   
00241                 // Wait end of write
00242                 ready();
00243        
00244                 // Increment address
00245                 address += fpart;
00246        
00247                 if(page < _page_number - 1) {
00248                     // Increment page
00249                     page++;
00250        
00251                     // Device address
00252                     addr = EEPROM_Address | _address | (page << 1);
00253        
00254                     // Word address
00255                     cmd[0] = (uint8_t) (address - page * 256);
00256        
00257                     // Data index
00258                     ind = i * _page_write + fpart;
00259        
00260                     // Number of bytes in next page
00261                     lpart = _page_write - fpart;
00262        
00263                     // Add data for next page
00264                     for(j = 0;j < lpart;j++) {
00265                         cmd[j + 1] = (uint8_t) data[ind + j];
00266                     }
00267     
00268                     // Write data for next page
00269                     ack = _i2c.write((int)addr,(char *)cmd,lpart + 1);
00270                     if(ack != 0) {
00271                         _errnum = EEPROM_I2cError;
00272                         return;
00273                     }
00274   
00275                     // Wait end of write
00276                     ready();
00277        
00278                     // Increment address
00279                     address += lpart;
00280                 }
00281             }
00282         }
00283         else {
00284             // First word address (MSB)
00285             cmd[0] = (uint8_t) (address >> 8);
00286        
00287             // Second word address (LSB)
00288             cmd[1] = (uint8_t) address;
00289        
00290             // Add data 
00291             for(j = 0;j < _page_write;j++) {
00292                 cmd[j + 2] = (uint8_t) data[i * _page_write + j];
00293             }
00294     
00295             // Write data
00296             ack = _i2c.write((int)addr,(char *)cmd,_page_write + 2);
00297             if(ack != 0) {
00298                 _errnum = EEPROM_I2cError;
00299                 return;
00300             }
00301   
00302             // Wait end of write
00303             ready();
00304        
00305             // Increment address
00306             address += _page_write;
00307         }
00308     }
00309   
00310     if(remain) {
00311         // Compute page number
00312         page = 0;
00313         if(_type < T24C32) {
00314             page = (uint8_t) (address / 256); 
00315         }
00316         
00317         // Device address
00318         addr = EEPROM_Address | _address | (page << 1);
00319         
00320         if(_type < T24C32) {
00321             // Word address
00322             cmd[0] = (uint8_t) (address - page * 256);
00323   
00324             if((uint8_t) ((address + remain) / 256) == page) { // Data fit in the same page
00325                 // Add data for the current page
00326                 for(j = 0;j < remain;j++)
00327                 cmd[j + 1] = (uint8_t) data[blocs * _page_write + j];
00328                 
00329                 // Write data for the current page
00330                 ack = _i2c.write((int)addr,(char *)cmd,remain + 1);
00331                 if(ack != 0) {
00332                     _errnum = EEPROM_I2cError;
00333                     return;
00334                 }
00335   
00336                 // Wait end of write
00337                 ready();
00338             }
00339             else { // Data on 2 pages. We must split the write
00340                 // Number of bytes in current page
00341                 fpart = (page + 1) * 256 - address;
00342     
00343                 // Add data for current page
00344                 for(j = 0;j < fpart;j++) {
00345                     cmd[j + 1] = (uint8_t) data[blocs * _page_write + j];
00346                 }
00347     
00348                 // Write data for current page
00349                 ack = _i2c.write((int)addr,(char *)cmd,fpart + 1);
00350                 if(ack != 0) {
00351                     _errnum = EEPROM_I2cError;
00352                     return;
00353                 }
00354                 
00355                 // Wait end of write
00356                 ready();
00357                 
00358                 // Increment address
00359                 address += fpart;
00360                 
00361                 if(page < _page_number - 1) {
00362                     // Increment page
00363                     page++;
00364                     
00365                     // Device address
00366                     addr = EEPROM_Address | _address | (page << 1);
00367                     
00368                     // Word address
00369                     cmd[0] = (uint8_t) (address - page * 256);
00370                     
00371                     // Data index
00372                     ind = blocs * _page_write + fpart;
00373                     
00374                     // Number of bytes in next page
00375                     lpart = remain - fpart;
00376     
00377                     // Add data for next page
00378                     for(j = 0;j < lpart;j++) {
00379                         cmd[j + 1] = (uint8_t) data[ind + j];
00380                     }
00381     
00382                     // Write data for next page
00383                     ack = _i2c.write((int)addr,(char *)cmd,lpart + 1);
00384                     if(ack != 0) {
00385                         _errnum = EEPROM_I2cError;
00386                         return;
00387                     }
00388         
00389                     // Wait end of write
00390                     ready();
00391                 }
00392             }
00393         }
00394         else {
00395             // Fist word address (MSB)
00396             cmd[0] = (uint8_t) (address >> 8);
00397             
00398             // Second word address (LSB)
00399             cmd[1] = (uint8_t) address;
00400 
00401             // Add data for the current page
00402             for(j = 0;j < remain;j++) {
00403                 cmd[j + 2] = (uint8_t) data[blocs * _page_write + j];
00404             }
00405             
00406             // Write data for the current page
00407             ack = _i2c.write((int)addr,(char *)cmd,remain + 2);
00408             if(ack != 0) {
00409                 _errnum = EEPROM_I2cError;
00410             return;
00411             }
00412   
00413             // Wait end of write
00414             ready();
00415         }
00416     }
00417 }
00418 
00419 
00420 /**
00421  * void read(uint32_t address, void *data, uint32_t size)
00422  *
00423  * Random read anything
00424  * @param address start address (uint32_t)
00425  * @param data data to read (void *)
00426  * @param size number of bytes to read (uint32_t)
00427  * @return none
00428 */
00429 void EEPROM::read_data(uint32_t address, void *data, uint32_t size)
00430 {
00431     int8_t *cmd = NULL;
00432     
00433     // wait until ready
00434     ready();
00435     
00436     // Check error
00437     if(_errnum) {
00438         return;
00439     }
00440     
00441     // Check address
00442     if(!checkAddress(address + size - 1)) {
00443         _errnum = EEPROM_OutOfRange;
00444         return;
00445     }
00446   
00447     cmd = (int8_t *)malloc(size);
00448     
00449     if(cmd == NULL) {
00450         _errnum = EEPROM_MallocError;
00451         return;
00452     }
00453   
00454 //  read_data_array(address,(int8_t *)cmd,size);
00455   
00456     memcpy(data,cmd,size);
00457     
00458     free(cmd);
00459 }
00460 
00461 /**
00462  * void read(uint32_t address, int8_t *data, uint32_t size)
00463  *
00464  * Sequential read byte
00465  * @param address start address (uint32_t)
00466  * @param data bytes array to read (int8_t[]&)
00467  * @param size number of bytes to read (uint32_t)
00468  * @return none
00469 */
00470 void EEPROM::read_data_array(uint32_t address, uint8_t *data, uint32_t size)
00471 {
00472     uint8_t page;
00473     uint8_t addr;
00474     uint8_t cmd[2];
00475     uint8_t len;
00476     int ack;
00477     
00478     // wait until ready
00479     ready();
00480     
00481     // Check error
00482     if(_errnum) {
00483         return;
00484     }
00485     
00486     // Check address
00487     if(!checkAddress(address)) {
00488         _errnum = EEPROM_OutOfRange;
00489         return;
00490     }
00491     
00492     // Check size
00493     if(!checkAddress(address + size - 1)) {
00494         _errnum = EEPROM_OutOfRange; 
00495         return;
00496     }
00497     
00498     // Compute page number
00499     page = 0;
00500     if(_type < T24C32) {
00501         page = (uint8_t) (address / 256); 
00502     }
00503         
00504     // Device address
00505     addr = EEPROM_Address | _address | (page << 1);
00506     
00507     if(_type < T24C32) {
00508         len = 1;
00509         
00510         // Word address
00511         cmd[0] = (uint8_t) (address - page * 256);
00512     }
00513     else {
00514         len = 2;
00515         
00516         // First word address (MSB)
00517         cmd[0] = (uint8_t) (address >> 8);
00518         
00519         // Second word address (LSB)
00520         cmd[1] = (uint8_t) address;
00521     }
00522     
00523     // Write command 
00524     ack = _i2c.write((int)addr,(char *)cmd,len,true);
00525     if(ack != 0) {
00526         _errnum = EEPROM_I2cError;
00527         return;
00528     }
00529     
00530     // Sequential read
00531     ack = _i2c.read((int)addr,(char *)data,size);
00532     if(ack != 0) {
00533         _errnum = EEPROM_I2cError;
00534         return;
00535     }
00536 }
00537 
00538 /**
00539  * void write(uint32_t address, void *data, uint32_t size)
00540  *
00541  * Write anything (use the page write mode)
00542  * @param address start address (uint32_t)
00543  * @param data data to write (void *)
00544  * @param size number of bytes to write (uint32_t)
00545  * @return none
00546 */
00547 void EEPROM::write_data(uint32_t address, void *data, uint32_t size)
00548 {
00549     int8_t *cmd = NULL;
00550     
00551     // wait until ready
00552     ready();
00553 
00554     // Check error
00555     if(_errnum) {
00556         return;
00557     }
00558     
00559     // Check address
00560     if(!checkAddress(address + size - 1)) {
00561         _errnum = EEPROM_OutOfRange;
00562         return;
00563     }
00564   
00565     cmd = (int8_t *)malloc(size);
00566     if(cmd == NULL) {
00567         _errnum = EEPROM_MallocError;
00568         return;
00569     }
00570 
00571     memcpy(cmd,(uint8_t *)data,size);
00572     
00573     write_data_array(address,(uint8_t *)cmd,size);
00574     
00575     free(cmd);
00576 }
00577 
00578 /**
00579  * void write_uint8_t(uint32_t address, int8_t data)
00580  *
00581  * Write byte
00582  * @param address start address (uint32_t)
00583  * @param data byte to write (int8_t)
00584  * @return none
00585 */
00586 void EEPROM::write_uint8_t(uint32_t address, uint8_t data)
00587 {
00588     uint8_t page;
00589     uint8_t addr;
00590     uint8_t cmd[3];
00591     int len;
00592     int ack;
00593     
00594     // wait until ready
00595     ready();
00596     
00597     // Check error
00598     if(_errnum) {
00599         return;
00600     }
00601     
00602     // Check address
00603     if(!checkAddress(address)) {
00604         _errnum = EEPROM_OutOfRange;
00605         return;
00606     }
00607   
00608     // Compute page number
00609     page = 0;
00610     if(_type < T24C32) {
00611         page = (uint8_t) (address / 256); 
00612     }
00613   
00614     // Device address
00615     addr = EEPROM_Address | _address | (page << 1);
00616  
00617     if(_type < T24C32) {
00618         len = 2;
00619         
00620         // Word address 
00621         cmd[0] = (uint8_t) (address - page * 256);
00622         
00623         // Data
00624         cmd[1] = (uint8_t) data;
00625     }
00626     else {
00627         len = 3;
00628         
00629         // First word address (MSB)
00630         cmd[0] = (uint8_t) ((address >> 8) & 0xff);
00631         
00632         // Second word address (LSB)
00633         cmd[1] = (uint8_t) (address & 0xff);
00634         
00635         // Data
00636         cmd[2] = (uint8_t) data;
00637     }
00638     
00639     ack = _i2c.write((int)addr, (char *)cmd, len);
00640     if(ack != 0) {
00641         _errnum = EEPROM_I2cError;
00642         return;
00643     }
00644     
00645     // Wait end of write
00646 //    ready();
00647 }
00648 
00649 /**
00650  * void write_uint16_t(uint32_t address, int16_t data)
00651  *
00652  * Write short
00653  * @param address start address (uint32_t)
00654  * @param data short to write (int16_t)
00655  * @return none
00656 */
00657 void EEPROM::write_uint16_t(uint32_t address, uint16_t data)
00658 {
00659     int8_t cmd[2];
00660     
00661     // wait until ready
00662     ready();
00663     
00664     // Check error
00665     if(_errnum) {
00666         return;
00667     }
00668     
00669     // Check address
00670     if(!checkAddress(address + 1)) {
00671         _errnum = EEPROM_OutOfRange;
00672         return;
00673     }
00674     
00675     memcpy(cmd,&data,2);
00676     
00677     write_data(address,cmd,2);
00678 }
00679 
00680 /**
00681  * void write_uint32_t(uint32_t address, int32_t data)
00682  *
00683  * Write long
00684  * @param address start address (uint32_t)
00685  * @param data long to write (int32_t)
00686  * @return none
00687 */
00688 void EEPROM::write_uint32_t(uint32_t address, uint32_t data)
00689 {
00690     int8_t cmd[4];
00691     
00692     // wait until ready
00693     ready();
00694     
00695     // Check error
00696     if(_errnum) {
00697         return;
00698     }
00699     
00700     // Check address
00701     if(!checkAddress(address + 3)) {
00702         _errnum = EEPROM_OutOfRange;
00703         return;
00704     }
00705     
00706     memcpy(cmd,&data,4);
00707     
00708     write_data(address,cmd,4);
00709 }
00710 
00711 /**
00712  * void write_float(uint32_t address, float data)
00713  *
00714  * Write float
00715  * @param address start address (uint32_t)
00716  * @param data float to write (float)
00717   * @return none
00718 */
00719 void EEPROM::write_float(uint32_t address, float data)
00720 {
00721     int8_t cmd[4];
00722     
00723     // wait until ready
00724     ready();
00725     
00726     // Check error
00727     if(_errnum) {
00728         return;
00729     }
00730     
00731     // Check address
00732     if(!checkAddress(address + 3)) {
00733         _errnum = EEPROM_OutOfRange;
00734         return;
00735     }
00736     
00737     memcpy(cmd,&data,4);
00738     
00739     write_data(address,cmd,4);
00740 }
00741 
00742 /**
00743  * void write_double(uint32_t address, double data)
00744  *
00745  * Write double
00746  * @param address start address (uint32_t)
00747  * @param data double to write (double)
00748   * @return none
00749 */
00750 void EEPROM::write_double(uint32_t address, double data)
00751 {
00752     int8_t cmd[8];
00753     
00754     // wait until ready
00755     ready();
00756     
00757     // Check error
00758     if(_errnum) {
00759         return;
00760     }
00761     
00762     // Check address
00763     if(!checkAddress(address + 7)) {
00764         _errnum = EEPROM_OutOfRange;
00765         return;
00766     }
00767     
00768     memcpy(cmd,&data,8);
00769     
00770     write_data(address,cmd,8);
00771 }
00772 
00773 /**
00774  * void write_string(uint32_t address, char * data)
00775  *
00776  * Write char *
00777  * @param address start address (uint32_t)
00778  * @param data char * to write (char *)
00779   * @return none
00780 */
00781 void EEPROM::write_string(uint32_t address, char * data)
00782 {
00783     int8_t cmd[32];
00784     
00785     int len = strlen(data);
00786     // wait until ready
00787     ready();
00788     
00789     // Check error
00790     if(_errnum) {
00791         return;
00792     }
00793     
00794     // Check address
00795     if(!checkAddress(address + len)) {
00796         _errnum = EEPROM_OutOfRange;
00797         return;
00798     }
00799 //    for (int i = 
00800     memcpy(cmd,data,len+1);
00801     
00802     write_data(address,cmd,len+1);
00803 }
00804 
00805 /**
00806  * void read(uint32_t address, int8_t& data)
00807  *
00808  * Random read byte
00809  * @param address start address (uint32_t)
00810  * @param data byte to read (int8_t&)
00811  * @return none
00812 */
00813 void EEPROM::read_uint8_t(uint32_t address, uint8_t& data)
00814 {
00815     uint8_t page;
00816     uint8_t addr;
00817     uint8_t cmd[2];
00818     uint8_t len;
00819     int ack;
00820     
00821     // wait until ready
00822     ready();
00823     
00824     // Check error
00825     if(_errnum) {
00826         return;
00827     }
00828     
00829     // Check address
00830     if(!checkAddress(address)) {
00831         _errnum = EEPROM_OutOfRange;
00832         return;
00833     }
00834     
00835     // Compute page number
00836     page = 0;
00837     if(_type < T24C32) {
00838         page = (uint8_t) (address / 256);
00839     }
00840   
00841     // Device address
00842     addr = EEPROM_Address | _address | (page << 1);
00843   
00844     if(_type < T24C32) {
00845         len = 1;
00846         
00847         // Word address
00848         cmd[0] = (uint8_t) (address - page * 256);
00849     }
00850     else {
00851         len = 2;
00852         
00853         // First word address (MSB)
00854         cmd[0] = (uint8_t) (address >> 8);
00855         
00856         // Second word address (LSB)
00857         cmd[1] = (uint8_t)address;
00858     }
00859     
00860     // Write command
00861     ack = _i2c.write((int)addr,(char *)cmd,len,true);
00862     if(ack != 0) {
00863         _errnum = EEPROM_I2cError;
00864         return;
00865     }
00866   
00867     // Read data
00868     ack = _i2c.read((int)addr,(char *)&data,sizeof(data));
00869     if(ack != 0) {
00870         _errnum = EEPROM_I2cError;
00871     }
00872 }
00873 
00874 /**
00875  * void read(int8_t& data)
00876  *
00877  * Current address read byte
00878  * @param data byte to read (int8_t&)
00879  * @return none
00880  */
00881 void EEPROM::read(uint8_t& data)
00882 {
00883     uint8_t addr;
00884     int ack;
00885     
00886     // wait until ready
00887     ready();
00888     
00889     // Check error
00890     if(_errnum) {
00891         return;
00892     }
00893     
00894     // Device address
00895     addr = EEPROM_Address | _address;
00896     
00897     // Read data
00898     ack = _i2c.read((int)addr,(char *)&data,sizeof(data));
00899     if(ack != 0) {
00900         _errnum = EEPROM_I2cError;
00901     }
00902 }
00903 
00904 /**
00905  * int8_t read(uint32_t address, int8_t)
00906  *
00907  * Random read byte
00908  * @param address start address (uint32_t)
00909  * @return data byte to read (int8_t&)
00910 */
00911 uint8_t EEPROM::read_uint8_t(uint32_t address)
00912 {
00913     int8_t cmd[1];
00914     uint8_t data;
00915 
00916     // wait until ready
00917     ready();
00918     
00919     // Check error
00920     if(_errnum) {
00921         return -1;
00922     }
00923     
00924     // Check address
00925     if(!checkAddress(address + 1)) {
00926         _errnum = EEPROM_OutOfRange;
00927         return -1;
00928     }
00929     
00930     read_data_array(address,(uint8_t *)cmd,1);
00931     
00932     memcpy(&data,cmd,1);
00933     return data;
00934 }
00935 
00936 /**
00937  * int16_t read(uint32_t address)
00938  *
00939  * Random read short
00940  * @param address start address (uint32_t)
00941  * @return data short to read (int16_t&)
00942 */
00943 uint16_t EEPROM::read_uint16_t(uint32_t address)
00944 {
00945     int8_t cmd[2];
00946     uint16_t data;
00947         
00948     // wait until ready
00949     ready();
00950 
00951     // Check error
00952     if(_errnum) {
00953         return -1;
00954     }
00955     
00956     // Check address
00957     if(!checkAddress(address + 1)) {
00958         _errnum = EEPROM_OutOfRange;
00959         return -1;
00960     }
00961     
00962     read_data_array(address,(uint8_t *)cmd,2);
00963     
00964     memcpy(&data,cmd,2);
00965     return data;
00966 }
00967 
00968 /**
00969  * int32_t read(uint32_t address)
00970  *
00971  * Random read long
00972  * @param address start address (uint32_t)
00973  * @return data long to read (int32_t&)
00974 */
00975 uint32_t EEPROM::read_uint32_t(uint32_t address)
00976 {
00977     int8_t cmd[4];
00978     uint32_t data;
00979     
00980     // wait until ready
00981     ready();
00982 
00983     // Check error
00984     if(_errnum) {
00985         return -1;
00986     }
00987     
00988     // Check address
00989     if(!checkAddress(address + 3)) {
00990         _errnum = EEPROM_OutOfRange;
00991         return -1;
00992     }
00993     
00994     read_data_array(address,(uint8_t *)cmd,4);
00995     
00996     memcpy(&data,cmd,4);
00997     return data;
00998 }
00999 
01000 /**
01001  * float read(uint32_t address)
01002  *
01003  * Random read float
01004  * @param address start address (uint32_t)
01005  * @return data float to read (float&)
01006  */
01007 //void EEPROM::read_float(uint32_t address, float& data)
01008 float EEPROM::read_float(uint32_t address)
01009 {
01010     int8_t cmd[4];
01011     float data;
01012     
01013     // wait until ready
01014     ready();
01015 
01016     // Check error
01017     if(_errnum) {
01018         return -1.0f;
01019     }
01020     
01021     // Check address
01022     if(!checkAddress(address + 3)) {
01023         _errnum = EEPROM_OutOfRange;
01024         return -1.0f;
01025     }
01026     
01027     read_data_array(address,(uint8_t *)cmd,4);
01028     
01029     memcpy(&data,cmd,4);
01030     return data;
01031 }
01032 
01033 /**
01034  * double read(uint32_t address)
01035  *
01036  * Random read double
01037  * @param address start address (uint32_t)
01038  * @return data double to read (double&)
01039  */
01040 //void EEPROM::read_double(uint32_t address, double& data)
01041 double EEPROM::read_double(uint32_t address)
01042 {
01043     int8_t cmd[8];
01044     double data;
01045     
01046     // wait until ready
01047     ready();
01048 
01049     // Check error
01050     if(_errnum) {
01051         return -1.0f;
01052     }
01053     
01054     // Check address
01055     if(!checkAddress(address + 7)) {
01056         _errnum = EEPROM_OutOfRange;
01057         return -1.0f;
01058     }
01059     
01060     read_data_array(address,(uint8_t *)cmd,8);
01061     
01062     memcpy(&data,cmd,8);
01063     return data;
01064 }
01065 
01066 /**
01067  * double read_string(uint32_t address)
01068  *
01069  * Random read char *
01070  * @param address start address (uint32_t)
01071  * @return data char * to read (char *&)
01072  */
01073 char * EEPROM::read_string(uint32_t address)
01074 {
01075     // wait until ready
01076     ready();
01077 
01078     // Check error
01079     if(_errnum) {
01080         return "";
01081     }
01082     
01083     // Check address
01084     if(!checkAddress(address + 7)) {
01085         _errnum = EEPROM_OutOfRange;
01086         return "";
01087     }
01088     int cont = true;
01089     int i = 0;
01090     while (cont) {
01091         buffer[i] = (char)read_uint8_t(address+i);
01092         if (buffer[i] == 0) {
01093             cont = false;
01094         }
01095         i++;
01096         if (i >= 32) {
01097             cont = false;
01098         }
01099     }
01100     return buffer;
01101 }
01102 
01103 /**
01104  * void clear(void)
01105  *
01106  * Clear eeprom (write with 0)
01107  * @param none
01108  * @return none
01109  */
01110 void EEPROM::clear(void)
01111 {
01112   for(uint32_t i = 0; i < _size / 4; i++) {
01113      write_uint32_t((uint32_t)(i * 4), 0x00000000);  
01114   }
01115 }
01116 
01117 /**
01118  * void ready(void)
01119  *
01120  * Wait eeprom ready
01121  * @param none
01122  * @return none
01123 */
01124 void EEPROM::ready(void)
01125 {
01126     int ack;
01127     uint8_t addr;
01128     uint8_t cmd[2];
01129     
01130     // Check error
01131     if(_errnum) {
01132         return;
01133     }
01134     
01135     // Device address
01136     addr = EEPROM_Address | _address;
01137     
01138     cmd[0] = 0;
01139     
01140     // Wait end of write
01141     do {
01142         ack = _i2c.write((int)addr,(char *)cmd,0);
01143         //wait(0.5);
01144     } while(ack != 0);
01145 }
01146 
01147 /**
01148  * uint32_t getSize(void)
01149  *
01150  * Get eeprom size in bytes
01151  * @param  none
01152  * @return size in bytes (uint32_t)
01153 */
01154 uint32_t EEPROM::getSize(void)
01155 {
01156     return(_size);
01157 }
01158 
01159 /**
01160  * const char* getName(void)
01161  *
01162  * Get eeprom name
01163  * @param none
01164  * @return name (const char*)
01165  */
01166 const char* EEPROM::getName(void)
01167 {
01168     uint8_t i = 0;
01169     
01170     switch(_type) {
01171         case T24C01 :
01172             i = 0;
01173             break;
01174         case T24C02 :
01175             i = 1;
01176             break;
01177         case T24C04 :
01178             i = 2;
01179             break;
01180         case T24C08 :
01181             i = 3;
01182             break;
01183         case T24C16 :
01184             i = 4;
01185             break;
01186         case T24C32 :
01187             i = 5; 
01188             break;
01189         case T24C64 :
01190             i = 6;
01191             break;
01192         case T24C128 :
01193             i = 7;
01194             break;
01195         case T24C256 :
01196             i = 8;
01197             break;
01198         case T24C512 :
01199             i = 9;
01200             break;
01201         case T24C1024 :
01202             i = 10;
01203             break;
01204         case T24C1025 :
01205             i = 11;
01206             break;
01207     }
01208   
01209     return(_name[i]);
01210 }
01211 
01212 /**
01213  * uint8_t getError(void)
01214  *
01215  * Get the current error number (EEPROM_NoError if no error)
01216  * @param none
01217  * @return none
01218 */
01219 uint8_t EEPROM::getError(void)
01220 {
01221     return(_errnum);
01222 }
01223 
01224 /**
01225  * bool checkAddress(uint32_t address)
01226  *
01227  * Check if address is in the eeprom range address
01228  * @param address address to check (uint32_t)
01229  * @return true if in eeprom range, overwise false (bool)
01230 */
01231 bool EEPROM::checkAddress(uint32_t address)
01232 {
01233     bool ret = true;
01234     
01235     switch(_type) {
01236         case T24C01 :
01237             if(address >= T24C01)
01238                 ret = false;
01239             break;
01240         case T24C02 :
01241             if(address >= T24C02)
01242                 ret = false;
01243             break;
01244         case T24C04 :
01245             if(address >= T24C04)
01246                 ret = false;
01247             break;
01248         case T24C08 :
01249             if(address >= T24C08)
01250                 ret = false;
01251             break;
01252         case T24C16 :
01253             if(address >= T24C16)
01254                 ret = false;
01255             break;
01256         case T24C32 :
01257             if(address >= T24C32)
01258                 ret = false;
01259             break;
01260         case T24C64 :
01261             if(address >= T24C64)
01262                 ret = false;
01263             break;
01264         case T24C128 :
01265             if(address >= T24C128)
01266                 ret = false;
01267             break;
01268         case T24C256 :
01269             if(address >= T24C256)
01270                 ret = false;
01271             break;
01272         case T24C512 :
01273             if(address >= T24C512)
01274                 ret = false;
01275             break;
01276         case T24C1024 :
01277             if(address >= T24C1024)
01278                 ret = false;
01279             break;
01280         case T24C1025 :
01281             if(address >= T24C1025 - 1)
01282                 ret = false;
01283             break;
01284     }
01285     
01286     return(ret);
01287 }