Jack Berkhout / EEPROM
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 // App address asignments
00357 // uint8_t  0x0000
00358 #define EEPROM_UINT8_BASE       0x0000
00359 #define EEPROM_RUN_HOUR         0x0008
00360 #define EEPROM_TOTAL_RUN_HOURS  0x000C
00361 
00362 #define EEPROM_BT_NAME          0x0010
00363 #define EEPROM_BT_PSWD          0x0020
00364 
00365 #define EEPROM_OUTPUT_GROUPS    0x0040
00366 #define EEPROM_OUTPUT_WIRES     0x0100
00367 
00368 // uint16_t 0x0100
00369 #define EEPROM_UINT16_BASE      0x0200
00370 // uint32_t 0x0200
00371 #define EEPROM_UINT32_BASE      0x0400
00372 // float    0x0300
00373 #define EEPROM_FLOAT_BASE       0x0600
00374 #define EEPROM_DMX512_RGB_CAL   0x0600 // 3 * channels
00375 // float    0x0300
00376 #define EEPROM_ADC0_ACS712_BASE 0x0800
00377 
00378 
00379 // Defines
00380 #define EEPROM_Address     0xa0
00381 
00382 #define EEPROM_NoError     0x00
00383 #define EEPROM_BadAddress  0x01
00384 #define EEPROM_I2cError    0x02
00385 #define EEPROM_ParamError  0x03
00386 #define EEPROM_OutOfRange  0x04
00387 #define EEPROM_MallocError 0x05
00388 
00389 #define EEPROM_MaxError       6
00390 
00391 static std::string _ErrorMessageEEPROM[EEPROM_MaxError] = {
00392                                                             "",
00393                                                             "Bad chip address",
00394                                                             "I2C error (nack)",
00395                                                             "Invalid parameter",
00396                                                             "Data address out of range",
00397                                                             "Memory allocation error"
00398                                                           };
00399 
00400 /** EEPROM Class
00401 */
00402 class EEPROM {
00403 
00404 public:
00405     enum TypeEeprom {T24C01=128,T24C02=256,T24C04=512,T24C08=1024,T24C16=2048,
00406                      T24C32=4096,T24C64=8192,T24C128=16384,T24C256=32768,
00407                      T24C512=65536,T24C1024=131072,T24C1025=131073} Type;
00408                                          
00409     /**
00410      * Constructor, initialize the eeprom on i2c interface.
00411      * @param sda sda i2c pin (PinName)
00412      * @param scl scl i2c pin (PinName)
00413      * @param address eeprom address, according to eeprom type (uint8_t)
00414      * @param type eeprom type (TypeEeprom) 
00415      * @return none
00416     */
00417     EEPROM(PinName sda, PinName scl, uint8_t address, TypeEeprom type);
00418 //    EEPROM(I2C* i2c = 0, uint8_t address, TypeEeprom type);
00419     
00420     /**
00421      * Write anything (use the page write mode)
00422      * @param address start address (uint32_t)
00423      * @param data data to write (void *)
00424      * @param size number of bytes to write (uint32_t)
00425      * @return none
00426     */
00427     void write_data(uint32_t address, void *data, uint32_t size);
00428     
00429     /**
00430      * Write array of bytes (use the page mode)
00431      * @param address start address (uint32_t)
00432      * @param data bytes array to write (int8_t[])
00433      * @param size number of bytes to write (uint32_t)
00434      * @return none
00435     */
00436     void write_data_array(uint32_t address, uint8_t data[], uint32_t size);
00437 
00438     
00439     /**
00440      * Random read anything
00441      * @param address start address (uint32_t)
00442      * @param data data to read (void *)
00443      * @param size number of bytes to read (uint32_t)
00444      * @return none
00445     */
00446     void read_data(uint32_t address, void *data, uint32_t size);
00447     
00448     /**
00449      * Sequential read byte
00450      * @param address start address (uint32_t)
00451      * @param data bytes array to read (int8_t[]&)
00452      * @param size number of bytes to read (uint32_t)
00453      * @return none
00454     */
00455     void read_data_array(uint32_t address, uint8_t *data, uint32_t size);
00456 
00457 
00458 
00459     /**
00460      * Random read byte
00461      * @param address start address (uint32_t)
00462      * @param data byte to read (int8_t&)
00463      * @return none
00464     */
00465     void read_uint8_t(uint32_t address, uint8_t& data);
00466 
00467     uint8_t read_uint8_t(uint32_t address);
00468     
00469     /**
00470      * Random read short
00471      * @param address start address (uint32_t)
00472      * @param data short to read (int16_t&)
00473      * @return none
00474     */
00475     uint16_t read_uint16_t(uint32_t address);
00476     
00477     /**
00478      * Random read long
00479      * @param address start address (uint32_t)
00480      * @param data long to read (int32_t&)
00481      * @return uint32_t
00482     */
00483     uint32_t read_uint32_t(uint32_t address);
00484     
00485     /**
00486      * Random read float
00487      * @param address start address (uint32_t)
00488      * @param data float to read (float&)
00489      * @return float
00490     */
00491     float read_float(uint32_t address);
00492     
00493     /**
00494      * Random read double
00495      * @param address start address (uint32_t)
00496      * @param data double to read (double&)
00497      * @return double
00498     */
00499     double read_double(uint32_t address);
00500 
00501     /**
00502      * Random read string
00503      * @param address start address (uint32_t)
00504      * @param data char * to read (char *)
00505      * @return char *
00506     */
00507     char * read_string(uint32_t address);
00508 
00509     /**
00510      * Current address read byte
00511      * @param data byte to read (int8_t&)
00512      * @return none
00513     */
00514     void read(uint8_t& data);
00515     
00516     /**
00517      * Write byte
00518      * @param address start address (uint32_t)
00519      * @param data byte to write (int8_t)
00520      * @return none
00521     */
00522     void write_uint8_t(uint32_t address, uint8_t data);
00523     
00524     /**
00525      * Write short
00526      * @param address start address (uint32_t)
00527      * @param data short to write (int16_t)
00528      * @return none
00529     */
00530     void write_uint16_t(uint32_t address, uint16_t data);
00531     
00532     /**
00533      * Write long
00534      * @param address start address (uint32_t)
00535      * @param data long to write (int32_t)
00536      * @return none
00537     */
00538     void write_uint32_t(uint32_t address, uint32_t data);
00539     
00540     /**
00541      * Write float
00542      * @param address start address (uint32_t)
00543      * @param data float to write (float)
00544      * @return none
00545     */
00546     void write_float(uint32_t address, float data);
00547 
00548     /**
00549      * Write double
00550      * @param address start address (uint32_t)
00551      * @param data double to write (double)
00552      * @return none
00553     */
00554     void write_double(uint32_t address, double data);
00555 
00556     /**
00557      * Write * data
00558      * @param address start address (uint32_t)
00559      * @param data * data to write (* data)
00560      * @return none
00561     */
00562     void write_string(uint32_t address, char * data);
00563     
00564     
00565     
00566     
00567     
00568     
00569     
00570     
00571     /**
00572      * Wait eeprom ready
00573      * @param none
00574      * @return none
00575     */
00576     void ready(void);
00577     
00578     /**
00579      * Get eeprom size in bytes
00580      * @param none
00581      * @return size in bytes (uint32_t)
00582     */
00583     uint32_t getSize(void);
00584         
00585     /**
00586      * Get eeprom name
00587      * @param none
00588      * @return name (const char*)
00589     */
00590     const char* getName(void);
00591     
00592     /**
00593      * Clear eeprom (write with 0)
00594      * @param  none
00595      * @return none
00596     */
00597     void clear(void);
00598     
00599      /**
00600      * Get the current error number (EEPROM_NoError if no error)
00601      * @param  none
00602      * @return none
00603     */
00604     uint8_t getError(void);
00605     
00606     /**
00607      * Get current error message
00608      * @param  none
00609      * @return current error message(std::string)
00610     */
00611     std::string getErrorMessage(void)
00612     { 
00613       return(_ErrorMessageEEPROM[_errnum]);
00614     }
00615     
00616 protected:
00617 //    *I2C      _i2c;
00618 
00619 //---------- local variables ----------
00620 private:
00621     I2C _i2c;              // Local i2c communication interface instance
00622     int _address;          // Local i2c address
00623     uint8_t _errnum;       // Error number
00624     TypeEeprom _type;      // EEPROM type
00625     uint8_t _page_write;   // Page write size
00626     uint8_t _page_number;  // Number of page
00627     uint32_t _size;        // Size in bytes
00628     bool checkAddress(uint32_t address); // Check address range
00629     static const char * const _name[]; // eeprom name
00630     
00631     char buffer[32];
00632 //-------------------------------------
00633 };
00634 #endif