Renamed read and write functions so they speak for them selves and do no longer recursively call themselves, causing hangs. Also changed the way they return values. and added double and string handling.

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 }