Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BEAR_Protocol_Edited BufferedSerial Debug MaxSonar PID Process QEI UI iSerial mbed
Fork of clean_V1 by
eeprom.cpp
00001 /*********************************************************** 00002 Author: Bernard Borredon 00003 Date: 27 december 2011 00004 Version: 1.0 00005 ************************************************************/ 00006 #include "mbed.h" 00007 #include "eeprom.h" 00008 00009 #define BIT_SET(x,n) (x=x | (0x01<<n)) 00010 #define BIT_TEST(x,n) (x & (0x01<<n)) 00011 #define BIT_CLEAR(x,n) (x=x & ~(0x01<<n)) 00012 00013 EEPROM::EEPROM(PinName sda, PinName scl, uint8_t address, TypeEeprom type) : _i2c(sda, scl) 00014 { 00015 00016 _errnum = EEPROM_NoError; 00017 _type = type; 00018 00019 // Check address range 00020 _address = address; 00021 switch(type) { 00022 case T24C01 : 00023 case T24C02 : 00024 if(address > 7) { 00025 _errnum = EEPROM_BadAddress; 00026 } 00027 _address = _address << 1; 00028 _page_write = 8; 00029 _page_number = 1; 00030 break; 00031 case T24C04 : 00032 if(address > 7) { 00033 _errnum = EEPROM_BadAddress; 00034 } 00035 _address = (_address & 0xFE) << 1; 00036 _page_write = 16; 00037 _page_number = 2; 00038 break; 00039 case T24C08 : 00040 if(address > 7) { 00041 _errnum = EEPROM_BadAddress; 00042 } 00043 _address = (_address & 0xFC) << 1; 00044 _page_write = 16; 00045 _page_number = 4; 00046 break; 00047 case T24C16 : 00048 _address = 0; 00049 _page_write = 16; 00050 _page_number = 8; 00051 break; 00052 case T24C32 : 00053 case T24C64 : 00054 if(address > 7) { 00055 _errnum = EEPROM_BadAddress; 00056 } 00057 _address = _address << 1; 00058 _page_write = 32; 00059 _page_number = 1; 00060 break; 00061 case T24C128 : 00062 case T24C256 : 00063 if(address > 3) { 00064 _errnum = EEPROM_BadAddress; 00065 } 00066 _address = _address << 1; 00067 _page_write = 64; 00068 _page_number = 1; 00069 break; 00070 case T24C512 : 00071 if(address > 3) { 00072 _errnum = EEPROM_BadAddress; 00073 } 00074 _address = _address << 1; 00075 _page_write = 128; 00076 _page_number = 1; 00077 break; 00078 case T24C1024 : 00079 if(address > 7) { 00080 _errnum = EEPROM_BadAddress; 00081 } 00082 _address = (_address & 0xFE) << 1; 00083 _page_write = 128; 00084 _page_number = 2; 00085 break; 00086 case T24C1025 : 00087 if(address > 3) { 00088 _errnum = EEPROM_BadAddress; 00089 } 00090 _address = _address << 1; 00091 _page_write = 128; 00092 _page_number = 2; 00093 break; 00094 } 00095 00096 // Size in bytes 00097 _size = _type; 00098 if(_type == T24C1025) 00099 _size = T24C1024; 00100 00101 // Set I2C frequency 00102 _i2c.frequency(100000); 00103 } 00104 00105 void EEPROM::write(uint16_t address, int8_t data) 00106 { 00107 uint8_t page; 00108 uint8_t addr; 00109 uint8_t cmd[3]; 00110 int len; 00111 int ack; 00112 00113 // Check error 00114 if(_errnum) 00115 return; 00116 00117 // Check address 00118 if(!checkAddress(address)) { 00119 _errnum = EEPROM_OutOfRange; 00120 return; 00121 } 00122 00123 // Compute page number 00124 page = 0; 00125 if(_type < T24C32) 00126 page = (uint8_t) (address / 256); 00127 00128 // Device address 00129 addr = EEPROM_Address | _address | (page << 1); 00130 00131 if(_type < T24C32) { 00132 len = 2; 00133 00134 // Word address 00135 cmd[0] = (uint8_t) (address - page * 256); 00136 00137 // Data 00138 cmd[1] = (uint8_t) data; 00139 } else { 00140 len = 3; 00141 00142 // First word address (MSB) 00143 cmd[0] = (uint8_t) (address >> 8); 00144 00145 // Second word address (LSB) 00146 cmd[1] = (uint8_t) address; 00147 00148 // Data 00149 cmd[2] = (uint8_t) data; 00150 } 00151 00152 // printf("len %d address %02x cmd[0] %02x cmd[1] %02x cmd[2] %02x\n",len,addr,cmd[0],cmd[1],cmd[2]); 00153 00154 ack = _i2c.write((int)addr,(char *)cmd,len); 00155 if(ack != 0) { 00156 _errnum = EEPROM_I2cError; 00157 return; 00158 } 00159 00160 // Wait end of write 00161 ready(); 00162 00163 } 00164 00165 void EEPROM::write(uint16_t address, int8_t data[], uint16_t length) 00166 { 00167 uint8_t page; 00168 uint8_t addr; 00169 uint8_t blocs,remain; 00170 uint8_t fpart,lpart; 00171 uint8_t i,j,ind; 00172 uint8_t cmd[129]; 00173 int ack; 00174 00175 // Check error 00176 if(_errnum) 00177 return; 00178 00179 // Check address 00180 if(!checkAddress(address)) { 00181 _errnum = EEPROM_OutOfRange; 00182 return; 00183 } 00184 00185 // Check length 00186 if(!checkAddress(address + length - 1)) { 00187 _errnum = EEPROM_OutOfRange; 00188 return; 00189 } 00190 00191 // Compute blocs numbers 00192 blocs = length / _page_write; 00193 00194 // Compute remaining bytes 00195 remain = length - blocs * _page_write; 00196 00197 for(i = 0; i < blocs; i++) { 00198 // Compute page number 00199 page = 0; 00200 if(_type < T24C32) 00201 page = (uint8_t) (address / 256); 00202 00203 // Device address 00204 addr = EEPROM_Address | _address | (page << 1); 00205 00206 if(_type < T24C32) { 00207 // Word address 00208 cmd[0] = (uint8_t) (address - page * 256); 00209 00210 if((uint8_t) ((address + _page_write) / 256) == page) { // Data fit in the same page 00211 // Add data 00212 for(j = 0; j < _page_write; j++) 00213 cmd[j + 1] = (uint8_t) data[i * _page_write + j]; 00214 00215 // Write data 00216 ack = _i2c.write((int)addr,(char *)cmd,_page_write + 1); 00217 if(ack != 0) { 00218 _errnum = EEPROM_I2cError; 00219 return; 00220 } 00221 00222 // Wait end of write 00223 ready(); 00224 00225 // Increment address 00226 address += _page_write; 00227 } else { // Data on 2 pages. We must split the write 00228 // Number of bytes in current page 00229 fpart = (page + 1) * 256 - address; 00230 00231 // Add data for current page 00232 for(j = 0; j < fpart; j++) 00233 cmd[j + 1] = (uint8_t) data[i * _page_write + j]; 00234 00235 // Write data for current page 00236 ack = _i2c.write((int)addr,(char *)cmd,fpart + 1); 00237 if(ack != 0) { 00238 _errnum = EEPROM_I2cError; 00239 return; 00240 } 00241 00242 // Wait end of write 00243 ready(); 00244 00245 // Increment address 00246 address += fpart; 00247 00248 if(page < _page_number - 1) { 00249 // Increment page 00250 page++; 00251 00252 // Device address 00253 addr = EEPROM_Address | _address | (page << 1); 00254 00255 // Word address 00256 cmd[0] = (uint8_t) (address - page * 256); 00257 00258 // Data index 00259 ind = i * _page_write + fpart; 00260 00261 // Number of bytes in next page 00262 lpart = _page_write - fpart; 00263 00264 // Add data for next page 00265 for(j = 0; j < lpart; j++) 00266 cmd[j + 1] = (uint8_t) data[ind + j]; 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 } else { 00283 // First word address (MSB) 00284 cmd[0] = (uint8_t) (address >> 8); 00285 00286 // Second word address (LSB) 00287 cmd[1] = (uint8_t) address; 00288 00289 // Add data 00290 for(j = 0; j < _page_write; j++) 00291 cmd[j + 2] = (uint8_t) data[i * _page_write + j]; 00292 00293 // Write data 00294 ack = _i2c.write((int)addr,(char *)cmd,_page_write + 2); 00295 if(ack != 0) { 00296 _errnum = EEPROM_I2cError; 00297 return; 00298 } 00299 00300 // Wait end of write 00301 ready(); 00302 00303 // Increment address 00304 address += _page_write; 00305 } 00306 } 00307 00308 // Compute page number 00309 page = 0; 00310 if(_type < T24C32) 00311 page = (uint8_t) (address / 256); 00312 00313 // Device address 00314 addr = EEPROM_Address | _address | (page << 1); 00315 00316 if(_type < T24C32) { 00317 // Word address 00318 cmd[0] = (uint8_t) (address - page * 256); 00319 00320 if((uint8_t) ((address + remain) / 256) == page) { // Data fit in the same page 00321 // Add data for the current page 00322 for(j = 0; j < remain; j++) 00323 cmd[j + 1] = (uint8_t) data[blocs * _page_write + j]; 00324 00325 // Write data for the current page 00326 ack = _i2c.write((int)addr,(char *)cmd,remain + 1); 00327 if(ack != 0) { 00328 _errnum = EEPROM_I2cError; 00329 return; 00330 } 00331 00332 // Wait end of write 00333 ready(); 00334 } else { // Data on 2 pages. We must split the write 00335 // Number of bytes in current page 00336 fpart = (page + 1) * 256 - address; 00337 00338 // Add data for current page 00339 for(j = 0; j < fpart; j++) 00340 cmd[j + 1] = (uint8_t) data[blocs * _page_write + j]; 00341 00342 // Write data for current page 00343 ack = _i2c.write((int)addr,(char *)cmd,fpart + 1); 00344 if(ack != 0) { 00345 _errnum = EEPROM_I2cError; 00346 return; 00347 } 00348 00349 // Wait end of write 00350 ready(); 00351 00352 // Increment address 00353 address += fpart; 00354 00355 if(page < _page_number - 1) { 00356 // Increment page 00357 page++; 00358 00359 // Device address 00360 addr = EEPROM_Address | _address | (page << 1); 00361 00362 // Word address 00363 cmd[0] = (uint8_t) (address - page * 256); 00364 00365 // Data index 00366 ind = blocs * _page_write + fpart; 00367 00368 // Number of bytes in next page 00369 lpart = remain - fpart; 00370 00371 // Add data for next page 00372 for(j = 0; j < lpart; j++) 00373 cmd[j + 1] = (uint8_t) data[ind + j]; 00374 00375 // Write data for next page 00376 ack = _i2c.write((int)addr,(char *)cmd,lpart + 1); 00377 if(ack != 0) { 00378 _errnum = EEPROM_I2cError; 00379 return; 00380 } 00381 00382 // Wait end of write 00383 ready(); 00384 } 00385 } 00386 } else { 00387 // Fist word address (MSB) 00388 cmd[0] = (uint8_t) (address >> 8); 00389 00390 // Second word address (LSB) 00391 cmd[1] = (uint8_t) address; 00392 00393 // Add data for the current page 00394 for(j = 0; j < remain; j++) 00395 cmd[j + 2] = (uint8_t) data[blocs * _page_write + j]; 00396 00397 // Write data for the current page 00398 ack = _i2c.write((int)addr,(char *)cmd,remain + 2); 00399 if(ack != 0) { 00400 _errnum = EEPROM_I2cError; 00401 return; 00402 } 00403 00404 // Wait end of write 00405 ready(); 00406 } 00407 00408 } 00409 00410 void EEPROM::write(uint16_t address, int16_t data) 00411 { 00412 int8_t cmd[2]; 00413 00414 // Check error 00415 if(_errnum) 00416 return; 00417 00418 // Check address 00419 if(!checkAddress(address + 1)) { 00420 _errnum = EEPROM_OutOfRange; 00421 return; 00422 } 00423 00424 memcpy(cmd,&data,2); 00425 00426 write(address,cmd,2); 00427 00428 } 00429 00430 void EEPROM::write(uint16_t address, int32_t data) 00431 { 00432 int8_t cmd[4]; 00433 00434 // Check error 00435 if(_errnum) 00436 return; 00437 00438 // Check address 00439 if(!checkAddress(address + 3)) { 00440 _errnum = EEPROM_OutOfRange; 00441 return; 00442 } 00443 00444 memcpy(cmd,&data,4); 00445 00446 write(address,cmd,4); 00447 00448 } 00449 00450 void EEPROM::write(uint16_t address, float data) 00451 { 00452 int8_t cmd[4]; 00453 00454 // Check error 00455 if(_errnum) 00456 return; 00457 00458 // Check address 00459 if(!checkAddress(address + 3)) { 00460 _errnum = EEPROM_OutOfRange; 00461 return; 00462 } 00463 00464 memcpy(cmd,&data,4); 00465 00466 write(address,cmd,4); 00467 00468 } 00469 00470 void EEPROM::write(uint16_t address, void *data, uint16_t size) 00471 { 00472 int8_t *cmd = NULL; 00473 00474 // Check error 00475 if(_errnum) 00476 return; 00477 00478 // Check address 00479 if(!checkAddress(address + size - 1)) { 00480 _errnum = EEPROM_OutOfRange; 00481 return; 00482 } 00483 00484 cmd = (int8_t *)malloc(size); 00485 if(cmd == NULL) { 00486 _errnum = EEPROM_MallocError; 00487 return; 00488 } 00489 00490 memcpy(cmd,data,size); 00491 00492 write(address,cmd,size); 00493 00494 free(cmd); 00495 00496 } 00497 00498 void EEPROM::read(uint16_t address, int8_t& data) 00499 { 00500 uint8_t page; 00501 uint8_t addr; 00502 uint8_t cmd[2]; 00503 uint8_t len; 00504 int ack; 00505 00506 // Check error 00507 if(_errnum) 00508 return; 00509 00510 // Check address 00511 if(!checkAddress(address)) { 00512 _errnum = EEPROM_OutOfRange; 00513 return; 00514 } 00515 00516 // Compute page number 00517 page = 0; 00518 if(_type < T24C32) 00519 page = (uint8_t) (address / 256); 00520 00521 // Device address 00522 addr = EEPROM_Address | _address | (page << 1); 00523 00524 if(_type < T24C32) { 00525 len = 1; 00526 00527 // Word address 00528 cmd[0] = (uint8_t) (address - page * 256); 00529 } else { 00530 len = 2; 00531 00532 // First word address (MSB) 00533 cmd[0] = (uint8_t) (address >> 8); 00534 00535 // Second word address (LSB) 00536 cmd[1] = (uint8_t)address; 00537 } 00538 00539 // Write command 00540 ack = _i2c.write((int)addr,(char *)cmd,len,true); 00541 if(ack != 0) { 00542 _errnum = EEPROM_I2cError; 00543 return; 00544 } 00545 00546 // Read data 00547 ack = _i2c.read((int)addr,(char *)&data,sizeof(data)); 00548 if(ack != 0) { 00549 _errnum = EEPROM_I2cError; 00550 return; 00551 } 00552 00553 } 00554 00555 void EEPROM::read(uint16_t address, int8_t *data, uint16_t size) 00556 { 00557 uint8_t page; 00558 uint8_t addr; 00559 uint8_t cmd[2]; 00560 uint8_t len; 00561 int ack; 00562 00563 // Check error 00564 if(_errnum) 00565 return; 00566 00567 // Check address 00568 if(!checkAddress(address)) { 00569 _errnum = EEPROM_OutOfRange; 00570 return; 00571 } 00572 00573 // Check size 00574 if(!checkAddress(address + size - 1)) { 00575 _errnum = EEPROM_OutOfRange; 00576 return; 00577 } 00578 00579 // Compute page number 00580 page = 0; 00581 if(_type < T24C32) 00582 page = (uint8_t) (address / 256); 00583 00584 // Device address 00585 addr = EEPROM_Address | _address | (page << 1); 00586 00587 if(_type < T24C32) { 00588 len = 1; 00589 00590 // Word address 00591 cmd[0] = (uint8_t) (address - page * 256); 00592 } else { 00593 len = 2; 00594 00595 // First word address (MSB) 00596 cmd[0] = (uint8_t) (address >> 8); 00597 00598 // Second word address (LSB) 00599 cmd[1] = (uint8_t) address; 00600 } 00601 00602 // Write command 00603 ack = _i2c.write((int)addr,(char *)cmd,len,true); 00604 if(ack != 0) { 00605 _errnum = EEPROM_I2cError; 00606 return; 00607 } 00608 00609 // Sequential read 00610 ack = _i2c.read((int)addr,(char *)data,size); 00611 if(ack != 0) { 00612 _errnum = EEPROM_I2cError; 00613 return; 00614 } 00615 00616 } 00617 00618 void EEPROM::read(int8_t& data) 00619 { 00620 uint8_t addr; 00621 int ack; 00622 00623 // Check error 00624 if(_errnum) 00625 return; 00626 00627 // Device address 00628 addr = EEPROM_Address | _address; 00629 00630 // Read data 00631 ack = _i2c.read((int)addr,(char *)&data,sizeof(data)); 00632 if(ack != 0) { 00633 _errnum = EEPROM_I2cError; 00634 return; 00635 } 00636 00637 } 00638 00639 void EEPROM::read(uint16_t address, int16_t& data) 00640 { 00641 int8_t cmd[2]; 00642 00643 // Check error 00644 if(_errnum) 00645 return; 00646 00647 // Check address 00648 if(!checkAddress(address + 1)) { 00649 _errnum = EEPROM_OutOfRange; 00650 return; 00651 } 00652 00653 read(address,cmd,2); 00654 00655 memcpy(&data,cmd,2); 00656 00657 } 00658 00659 void EEPROM::read(uint16_t address, int32_t& data) 00660 { 00661 int8_t cmd[4]; 00662 00663 // Check error 00664 if(_errnum) 00665 return; 00666 00667 // Check address 00668 if(!checkAddress(address + 3)) { 00669 _errnum = EEPROM_OutOfRange; 00670 return; 00671 } 00672 00673 read(address,cmd,4); 00674 00675 memcpy(&data,cmd,4); 00676 00677 } 00678 00679 void EEPROM::read(uint16_t address, float& data) 00680 { 00681 int8_t cmd[4]; 00682 00683 // Check error 00684 if(_errnum) 00685 return; 00686 00687 // Check address 00688 if(!checkAddress(address + 3)) { 00689 _errnum = EEPROM_OutOfRange; 00690 return; 00691 } 00692 00693 read(address,cmd,4); 00694 00695 memcpy(&data,cmd,4); 00696 00697 } 00698 00699 void EEPROM::read(uint16_t address, void *data, uint16_t size) 00700 { 00701 int8_t *cmd = NULL; 00702 00703 // Check error 00704 if(_errnum) 00705 return; 00706 00707 // Check address 00708 if(!checkAddress(address + size - 1)) { 00709 _errnum = EEPROM_OutOfRange; 00710 return; 00711 } 00712 00713 cmd = (int8_t *)malloc(size); 00714 if(cmd == NULL) { 00715 _errnum = EEPROM_MallocError; 00716 return; 00717 } 00718 00719 read(address,cmd,size); 00720 00721 memcpy(data,cmd,size); 00722 00723 free(cmd); 00724 00725 } 00726 00727 void EEPROM::ready(void) 00728 { 00729 int ack; 00730 uint8_t addr; 00731 uint8_t cmd; 00732 00733 // Check error 00734 if(_errnum) 00735 return; 00736 00737 // Device address 00738 addr = EEPROM_Address | _address; 00739 00740 cmd = 0; 00741 /* 00742 // Wait end of write 00743 do { 00744 ack = _i2c.write((int)addr,(char *)cmd,0); 00745 } while(ack != 0); 00746 */ 00747 wait_ms(5); 00748 } 00749 00750 uint32_t EEPROM::getSize(void) 00751 { 00752 return(_size); 00753 } 00754 00755 uint8_t EEPROM::getError(void) 00756 { 00757 return(_errnum); 00758 } 00759 00760 bool EEPROM::checkAddress(uint16_t address) 00761 { 00762 bool ret = true; 00763 00764 switch(_type) { 00765 case T24C01 : 00766 if(address >= T24C01) 00767 ret = false; 00768 break; 00769 case T24C02 : 00770 if(address >= T24C02) 00771 ret = false; 00772 break; 00773 case T24C04 : 00774 if(address >= T24C04) 00775 ret = false; 00776 break; 00777 case T24C08 : 00778 if(address >= T24C08) 00779 ret = false; 00780 break; 00781 case T24C16 : 00782 if(address >= T24C16) 00783 ret = false; 00784 break; 00785 case T24C32 : 00786 if(address >= T24C32) 00787 ret = false; 00788 break; 00789 case T24C64 : 00790 if(address >= T24C64) 00791 ret = false; 00792 break; 00793 case T24C128 : 00794 if(address >= T24C128) 00795 ret = false; 00796 break; 00797 case T24C256 : 00798 if(address >= T24C256) 00799 ret = false; 00800 break; 00801 case T24C512 : 00802 if(address >= T24C512) 00803 ret = false; 00804 break; 00805 case T24C1024 : 00806 if(address >= T24C1024) 00807 ret = false; 00808 break; 00809 case T24C1025 : 00810 if(address >= T24C1025 - 1) 00811 ret = false; 00812 break; 00813 } 00814 00815 return(ret); 00816 }
Generated on Tue Jul 12 2022 19:12:03 by
1.7.2
