I2C EEPROM library from 24C01 to 24C1025

Dependents:   Digitalni_Sat_MG_AN EEROM_1768 EEPROM_kamal EEPROM_MY ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers eeprom.h Source File

eeprom.h

00001 #ifndef __EEPROM__H_
00002 #define __EEPROM__H_
00003 
00004 /***********************************************************
00005 Author: Bernard Borredon
00006 Date : 21 decembre 2015
00007 Version: 1.3
00008   - Correct write(uint32_t address, int8_t data[], uint32_t length) for eeprom >= T24C32.
00009     Tested with 24C02, 24C08, 24C16, 24C64, 24C256, 24C512, 24C1025 on LPC1768 (mbed online and µVision V5.16a).
00010   - Correct main test.
00011     
00012 Date : 12 decembre 2013
00013 Version: 1.2
00014   - Update api documentation
00015   
00016 Date: 11 december 2013
00017 Version: 1.1
00018   - Change address parameter size form uint16_t to uint32_t (error for eeprom > 24C256).
00019   - Change size parameter size from uint16_t to uint32_t (error for eeprom > 24C256).
00020     - Add EEPROM name as a private static const char array.
00021     - Add function getName.
00022     - Add a test program.
00023 
00024 Date: 27 december 2011
00025 Version: 1.0
00026 ************************************************************/
00027 
00028 // Includes
00029 #include <string> 
00030 
00031 #include "mbed.h"
00032 
00033 // Example
00034 /*
00035 #include <string>
00036 
00037 #include "mbed.h"
00038 #include "eeprom.h"
00039 
00040 #define EEPROM_ADDR 0x0   // I2c EEPROM address is 0x00
00041 
00042 #define SDA p9            // I2C SDA pin
00043 #define SCL p10           // I2C SCL pin
00044 
00045 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
00046 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
00047 
00048 DigitalOut led2(LED2);
00049 
00050 typedef struct _MyData {
00051                          int16_t sdata;
00052                          int32_t idata;
00053                          float fdata;
00054                        } MyData;
00055 
00056 static void myerror(std::string msg)
00057 {
00058   printf("Error %s\n",msg.c_str());
00059   exit(1);
00060 }
00061 
00062 void eeprom_test(void)
00063 {
00064   EEPROM ep(SDA,SCL,EEPROM_ADDR,EEPROM::T24C64);  // 24C64 eeprom with sda = p9 and scl = p10
00065   uint8_t data[256],data_r[256];
00066   int8_t ival;
00067   uint16_t s;
00068   int16_t sdata,sdata_r;
00069   int32_t ldata[1024];
00070   int32_t eeprom_size,max_size;
00071   uint32_t addr;
00072   int32_t idata,idata_r;
00073   uint32_t i,j,k,l,t,id;
00074   float fdata,fdata_r;
00075   MyData md,md_r;
00076     
00077   eeprom_size = ep.getSize();
00078   max_size = MIN(eeprom_size,256);
00079   
00080   printf("Test EEPROM I2C model %s of %d bytes\n\n",ep.getName(),eeprom_size);
00081   
00082   // Test sequential read byte (max_size first bytes)
00083   for(i = 0;i < max_size;i++) {
00084      ep.read(i,ival);
00085      data_r[i] = ival;
00086      if(ep.getError() != 0)
00087        myerror(ep.getErrorMessage());
00088   }
00089   
00090   printf("Test sequential read %d first bytes :\n",max_size);
00091   for(i = 0;i < max_size/16;i++) {
00092      for(j = 0;j < 16;j++) {
00093         addr = i * 16 + j;
00094         printf("%3d ",(uint8_t)data_r[addr]);
00095      }
00096      printf("\n");
00097   }
00098     
00099     // Test sequential read byte (max_size last bytes)
00100   for(i = 0;i < max_size;i++) {
00101         addr = eeprom_size - max_size + i;
00102     ep.read(addr,ival);
00103     data_r[i] = ival;
00104     if(ep.getError() != 0)
00105       myerror(ep.getErrorMessage());
00106   }
00107   
00108   printf("\nTest sequential read %d last bytes :\n",max_size);
00109   for(i = 0;i < max_size/16;i++) {
00110      for(j = 0;j < 16;j++) {
00111         addr = i * 16 + j;
00112         printf("%3d ",(uint8_t)data_r[addr]);
00113      }
00114      printf("\n");
00115   }
00116   
00117   // Test write byte (max_size first bytes)
00118   for(i = 0;i < max_size;i++)
00119      data[i] = i;
00120   
00121   for(i = 0;i < max_size;i++) {
00122      ep.write(i,(int8_t)data[i]);
00123      if(ep.getError() != 0)
00124        myerror(ep.getErrorMessage());
00125   }
00126   
00127   // Test read byte (max_size first bytes)
00128   for(i = 0;i < max_size;i++) {
00129      ep.read(i,(int8_t&)ival);
00130      data_r[i] = (uint8_t)ival;
00131      if(ep.getError() != 0)
00132        myerror(ep.getErrorMessage());
00133   }
00134   
00135   printf("\nTest write and read %d first bytes :\n",max_size);
00136   for(i = 0;i < max_size/16;i++) {
00137      for(j = 0;j < 16;j++) {
00138         addr = i * 16 + j;
00139         printf("%3d ",(uint8_t)data_r[addr]);
00140      }
00141      printf("\n");
00142   }
00143   
00144   // Test current address read byte (max_size first bytes)
00145   ep.read((uint32_t)0,(int8_t&)ival); // current address is 0
00146   data_r[0] = (uint8_t)ival;
00147   if(ep.getError() != 0)
00148     myerror(ep.getErrorMessage());
00149   
00150   for(i = 1;i < max_size;i++) {
00151      ep.read((int8_t&)ival);
00152      data_r[i] = (uint8_t)ival;
00153      if(ep.getError() != 0)
00154        myerror(ep.getErrorMessage());
00155   }
00156   
00157   printf("\nTest current address read %d first bytes :\n",max_size);
00158   for(i = 0;i < max_size/16;i++) {
00159      for(j = 0;j < 16;j++) {
00160         addr = i * 16 + j;
00161         printf("%3d ",(uint8_t)data_r[addr]);
00162      }
00163      printf("\n");
00164   }
00165    
00166   // Test sequential read byte (first max_size bytes)
00167   ep.read((uint32_t)0,(int8_t *)data_r,(uint32_t) max_size);
00168   if(ep.getError() != 0)
00169     myerror(ep.getErrorMessage());
00170   
00171   printf("\nTest sequential read %d first bytes :\n",max_size);
00172   for(i = 0;i < max_size/16;i++) {
00173      for(j = 0;j < 16;j++) {
00174         addr = i * 16 + j;
00175         printf("%3d ",(uint8_t)data_r[addr]);
00176      }
00177      printf("\n");
00178   }
00179   
00180   // Test write short, long, float 
00181   sdata = -15202;
00182     addr = eeprom_size - 16;
00183   ep.write(addr,(int16_t)sdata); // short write at address eeprom_size - 16
00184   if(ep.getError() != 0)
00185     myerror(ep.getErrorMessage());
00186   
00187   idata = 45123;
00188     addr = eeprom_size - 12;
00189   ep.write(addr,(int32_t)idata); // long write at address eeprom_size - 12
00190   if(ep.getError() != 0)
00191     myerror(ep.getErrorMessage());
00192     
00193   fdata = -12.26;
00194     addr = eeprom_size - 8;
00195   ep.write(addr,(float)fdata); // float write at address eeprom_size - 8
00196   if(ep.getError() != 0)
00197     myerror(ep.getErrorMessage());
00198   
00199   // Test read short, long, float
00200   printf("\nTest write and read short (%d), long (%d), float (%f) :\n",
00201            sdata,idata,fdata);  
00202   
00203   ep.read((uint32_t)(eeprom_size - 16),(int16_t&)sdata_r);
00204   if(ep.getError() != 0)
00205     myerror(ep.getErrorMessage());
00206   printf("sdata %d\n",sdata_r);
00207   
00208   ep.read((uint32_t)(eeprom_size - 12),(int32_t&)idata_r);
00209   if(ep.getError() != 0)
00210     myerror(ep.getErrorMessage());
00211   printf("idata %d\n",idata_r);
00212   
00213   ep.read((uint32_t)(eeprom_size - 8),fdata_r);
00214   if(ep.getError() != 0)
00215     myerror(ep.getErrorMessage());
00216   printf("fdata %f\n",fdata_r);
00217   
00218   // Test read and write a structure
00219   md.sdata = -15203;
00220   md.idata = 45124;
00221   md.fdata = -12.27;
00222  
00223   ep.write((uint32_t)(eeprom_size - 32),(void *)&md,sizeof(md)); // write a structure eeprom_size - 32
00224   if(ep.getError() != 0)
00225     myerror(ep.getErrorMessage());
00226     
00227   printf("\nTest write and read a structure (%d %d %f) :\n",md.sdata,md.idata,md.fdata);
00228   
00229   ep.read((uint32_t)(eeprom_size - 32),(void *)&md_r,sizeof(md_r));
00230   if(ep.getError() != 0)
00231     myerror(ep.getErrorMessage());
00232   
00233   printf("md.sdata %d\n",md_r.sdata);
00234   printf("md.idata %d\n",md_r.idata);
00235   printf("md.fdata %f\n",md_r.fdata);
00236     
00237     // Test read and write of an array of the first max_size bytes
00238     for(i = 0;i < max_size;i++)
00239        data[i] = max_size - i - 1;
00240     
00241     ep.write((uint32_t)(0),data,(uint32_t)max_size);
00242   if(ep.getError() != 0)
00243     myerror(ep.getErrorMessage());
00244     
00245     ep.read((uint32_t)(0),data_r,(uint32_t)max_size);
00246   if(ep.getError() != 0)
00247     myerror(ep.getErrorMessage());
00248     
00249     printf("\nTest write and read an array of the first %d bytes :\n",max_size);
00250     for(i = 0;i < max_size/16;i++) {
00251      for(j = 0;j < 16;j++) {
00252         addr = i * 16 + j;
00253         printf("%3d ",(uint8_t)data_r[addr]);
00254      }
00255      printf("\n");
00256   }
00257     printf("\n");
00258   
00259   // Test write and read an array of int32
00260   s = eeprom_size / 4;                // size of eeprom in int32
00261   int ldata_size = sizeof(ldata) / 4; // size of data array in int32
00262   l = s / ldata_size;                 // loop index
00263   
00264   // size of read / write in bytes
00265   t = eeprom_size;
00266   if(t > ldata_size * 4)
00267     t = ldata_size * 4;
00268   
00269   printf("Test write and read an array of %d int32 (write entire memory) :\n",t/4);
00270 
00271   // Write entire eeprom
00272     if(l) {
00273     for(k = 0;k < l;k++) {
00274        for(i = 0;i < ldata_size;i++)
00275           ldata[i] = ldata_size * k + i;
00276         
00277        addr = k * ldata_size * 4;
00278        ep.write(addr,(void *)ldata,t);
00279        if(ep.getError() != 0)
00280          myerror(ep.getErrorMessage());
00281     }  
00282     
00283       printf("Write OK\n");
00284     
00285     // Read entire eeprom
00286       id = 0;
00287     for(k = 0;k < l;k++) {
00288        addr = k * ldata_size * 4;
00289        ep.read(addr,(void *)ldata,t);
00290        if(ep.getError() != 0)
00291          myerror(ep.getErrorMessage());
00292   
00293        // format outputs with 8 words rows
00294        for(i = 0;i < ldata_size / 8;i++) {
00295                 id++;
00296           printf("%4d ",id);
00297           for(j = 0;j < 8;j++) {
00298              addr = i * 8 + j;
00299              printf("%5d ",ldata[addr]);
00300           }
00301           printf("\n");
00302        }
00303     }
00304   }
00305     else {
00306         for(i = 0;i < s;i++)
00307        ldata[i] = i;
00308         
00309     addr = 0;
00310     ep.write(addr,(void *)ldata,t);
00311     if(ep.getError() != 0)
00312       myerror(ep.getErrorMessage());
00313         
00314         printf("Write OK\n");
00315     
00316     // Read entire eeprom
00317       id = 0;
00318     
00319     addr = 0;
00320     ep.read(addr,(void *)ldata,t);
00321     if(ep.getError() != 0)
00322       myerror(ep.getErrorMessage());
00323   
00324     // format outputs with 8 words rows
00325     for(i = 0;i < s / 8;i++) {
00326              id++;
00327        printf("%4d ",id);
00328        for(j = 0;j < 8;j++) {
00329           addr = i * 8 + j;
00330           printf("%5d ",ldata[addr]);
00331        }
00332        printf("\n");
00333     }
00334     }
00335   
00336   // clear eeprom
00337   printf("\nClear eeprom\n");
00338 
00339   ep.clear();
00340   if(ep.getError() != 0)
00341     myerror(ep.getErrorMessage());
00342     
00343   printf("End\n");  
00344     
00345 }
00346 
00347 int main() 
00348 {
00349 
00350   eeprom_test();
00351     
00352   return(0);
00353 }
00354 */
00355 
00356 // Defines
00357 #define EEPROM_Address     0xa0
00358 
00359 #define EEPROM_NoError     0x00
00360 #define EEPROM_BadAddress  0x01
00361 #define EEPROM_I2cError    0x02
00362 #define EEPROM_ParamError  0x03
00363 #define EEPROM_OutOfRange  0x04
00364 #define EEPROM_MallocError 0x05
00365 
00366 #define EEPROM_MaxError       6
00367 
00368 static std::string _ErrorMessageEEPROM[EEPROM_MaxError] = {
00369                                                             "",
00370                                                             "Bad chip address",
00371                                                             "I2C error (nack)",
00372                                                             "Invalid parameter",
00373                                                             "Data address out of range",
00374                                                             "Memory allocation error"
00375                                                           };
00376 
00377 /** EEPROM Class
00378 */
00379 class EEPROM {
00380 public:
00381     enum TypeEeprom {T24C01=128,T24C02=256,T24C04=512,T24C08=1024,T24C16=2048,
00382                      T24C32=4096,T24C64=8192,T24C128=16384,T24C256=32768,
00383                      T24C512=65536,T24C1024=131072,T24C1025=131073} Type;
00384                                          
00385     /**
00386      * Constructor, initialize the eeprom on i2c interface.
00387      * @param sda sda i2c pin (PinName)
00388      * @param scl scl i2c pin (PinName)
00389      * @param address eeprom address, according to eeprom type (uint8_t)
00390      * @param type eeprom type (TypeEeprom) 
00391      * @return none
00392     */
00393     EEPROM(PinName sda, PinName scl, uint8_t address, TypeEeprom type);
00394     
00395     /**
00396      * Random read byte
00397      * @param address start address (uint32_t)
00398      * @param data byte to read (int8_t&)
00399      * @return none
00400     */
00401     void read(uint32_t address, int8_t& data);
00402     
00403     /**
00404      * Random read short
00405      * @param address start address (uint32_t)
00406      * @param data short to read (int16_t&)
00407      * @return none
00408     */
00409     void read(uint32_t address, int16_t& data);
00410     
00411     /**
00412      * Random read long
00413      * @param address start address (uint32_t)
00414      * @param data long to read (int32_t&)
00415      * @return none
00416     */
00417     void read(uint32_t address, int32_t& data);
00418     
00419     /**
00420      * Random read float
00421      * @param address start address (uint32_t)
00422      * @param data float to read (float&)
00423      * @return none
00424     */
00425     void read(uint32_t address, float& data);
00426     
00427     /**
00428      * Random read anything
00429      * @param address start address (uint32_t)
00430      * @param data data to read (void *)
00431      * @param size number of bytes to read (uint32_t)
00432      * @return none
00433     */
00434     void read(uint32_t address, void *data, uint32_t size);
00435     
00436     /**
00437      * Current address read byte
00438      * @param data byte to read (int8_t&)
00439      * @return none
00440     */
00441     void read(int8_t& data);
00442     
00443     /**
00444      * Sequential read byte
00445      * @param address start address (uint32_t)
00446      * @param data bytes array to read (int8_t[]&)
00447      * @param size number of bytes to read (uint32_t)
00448      * @return none
00449     */
00450     void read(uint32_t address, int8_t *data, uint32_t size);
00451     
00452     /**
00453      * Write byte
00454      * @param address start address (uint32_t)
00455      * @param data byte to write (int8_t)
00456      * @return none
00457     */
00458     void write(uint32_t address, int8_t data);
00459     
00460     /**
00461      * Write short
00462      * @param address start address (uint32_t)
00463      * @param data short to write (int16_t)
00464      * @return none
00465     */
00466     void write(uint32_t address, int16_t data);
00467     
00468     /**
00469      * Write long
00470      * @param address start address (uint32_t)
00471      * @param data long to write (int32_t)
00472      * @return none
00473     */
00474     void write(uint32_t address, int32_t data);
00475     
00476     /**
00477      * Write float
00478      * @param address start address (uint32_t)
00479      * @param data float to write (float)
00480      * @return none
00481     */
00482     void write(uint32_t address, float data);
00483     
00484     /**
00485      * Write anything (use the page write mode)
00486      * @param address start address (uint32_t)
00487      * @param data data to write (void *)
00488      * @param size number of bytes to write (uint32_t)
00489      * @return none
00490     */
00491     void write(uint32_t address, void *data, uint32_t size);
00492     
00493     /**
00494      * Write array of bytes (use the page mode)
00495      * @param address start address (uint32_t)
00496      * @param data bytes array to write (int8_t[])
00497      * @param size number of bytes to write (uint32_t)
00498      * @return none
00499     */
00500     void write(uint32_t address, int8_t data[], uint32_t size);
00501     
00502     /**
00503      * Wait eeprom ready
00504      * @param none
00505      * @return none
00506     */
00507     void ready(void);
00508     
00509     /**
00510      * Get eeprom size in bytes
00511      * @param none
00512      * @return size in bytes (uint32_t)
00513     */
00514     uint32_t getSize(void);
00515         
00516     /**
00517      * Get eeprom name
00518      * @param none
00519      * @return name (const char*)
00520     */
00521     const char* getName(void);
00522     
00523     /**
00524      * Clear eeprom (write with 0)
00525      * @param  none
00526      * @return none
00527     */
00528     void clear(void);
00529     
00530      /**
00531      * Get the current error number (EEPROM_NoError if no error)
00532      * @param  none
00533      * @return none
00534     */
00535     uint8_t getError(void);
00536     
00537     /**
00538      * Get current error message
00539      * @param  none
00540      * @return current error message(std::string)
00541     */
00542     std::string getErrorMessage(void)
00543     { 
00544       return(_ErrorMessageEEPROM[_errnum]);
00545     }
00546     
00547 //---------- local variables ----------
00548 private:
00549     I2C _i2c;              // Local i2c communication interface instance
00550     int _address;          // Local i2c address
00551     uint8_t _errnum;       // Error number
00552     TypeEeprom _type;      // EEPROM type
00553     uint8_t _page_write;   // Page write size
00554     uint8_t _page_number;  // Number of page
00555     uint32_t _size;        // Size in bytes
00556     bool checkAddress(uint32_t address); // Check address range
00557     static const char * const _name[]; // eeprom name
00558 //-------------------------------------
00559 };
00560 #endif