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.
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 }
Generated on Fri Jul 15 2022 02:08:33 by 1.7.2