I2C EEPROM library for 1k to 512k chip

Committer:
Wodji
Date:
Thu Jun 23 15:57:16 2016 +0000
Revision:
0:68c79e5c722b
Library of i2c eeprom from 1k to 512k chip

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wodji 0:68c79e5c722b 1 /**
Wodji 0:68c79e5c722b 2 *****************************************************************************
Wodji 0:68c79e5c722b 3 * File Name : EEPROM.cpp
Wodji 0:68c79e5c722b 4 *
Wodji 0:68c79e5c722b 5 * Title : I2C EEPROM 24LCXXX Claass Source File
Wodji 0:68c79e5c722b 6 * Revision : 1.0
Wodji 0:68c79e5c722b 7 * Notes :
Wodji 0:68c79e5c722b 8 * Target Board : mbed NXP LPC1768, mbed LPC1114FN28 etc
Wodji 0:68c79e5c722b 9 *
Wodji 0:68c79e5c722b 10 * Revision History:
Wodji 0:68c79e5c722b 11 * When Who Description of change
Wodji 0:68c79e5c722b 12 * ----------- ----------- ----------------------
Wodji 0:68c79e5c722b 13 *
Wodji 0:68c79e5c722b 14 *****************************************************************************
Wodji 0:68c79e5c722b 15 *
Wodji 0:68c79e5c722b 16 * Copyright (C) 2016 wodji
Wodji 0:68c79e5c722b 17 *
Wodji 0:68c79e5c722b 18 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
Wodji 0:68c79e5c722b 19 * and associated documentation files (the "Software"), to deal in the Software without restriction,
Wodji 0:68c79e5c722b 20 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
Wodji 0:68c79e5c722b 21 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Wodji 0:68c79e5c722b 22 * furnished to do so, subject to the following conditions:
Wodji 0:68c79e5c722b 23 *
Wodji 0:68c79e5c722b 24 * The above copyright notice and this permission notice shall be included in all copies or
Wodji 0:68c79e5c722b 25 * substantial portions of the Software.
Wodji 0:68c79e5c722b 26 *
Wodji 0:68c79e5c722b 27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
Wodji 0:68c79e5c722b 28 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Wodji 0:68c79e5c722b 29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
Wodji 0:68c79e5c722b 30 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Wodji 0:68c79e5c722b 31 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Wodji 0:68c79e5c722b 32 *
Wodji 0:68c79e5c722b 33 **/
Wodji 0:68c79e5c722b 34
Wodji 0:68c79e5c722b 35 #include <EEPROM.h>
Wodji 0:68c79e5c722b 36
Wodji 0:68c79e5c722b 37
Wodji 0:68c79e5c722b 38 EEPROM::EEPROM(I2C* i2c, const device_t device, const int deviceAddress) :
Wodji 0:68c79e5c722b 39 _deviceAddress(deviceAddress << 1), _i2c(i2c), _device(device){
Wodji 0:68c79e5c722b 40 }
Wodji 0:68c79e5c722b 41
Wodji 0:68c79e5c722b 42 EEPROM::EEPROM(PinName sda, PinName scl, const device_t device,
Wodji 0:68c79e5c722b 43 const int deviceAddress) : _deviceAddress(deviceAddress << 1), _device(device){
Wodji 0:68c79e5c722b 44 _i2c = new I2C(sda, scl);
Wodji 0:68c79e5c722b 45 }
Wodji 0:68c79e5c722b 46
Wodji 0:68c79e5c722b 47 int EEPROM::read(int memoryAddress, char* data, int dataLength){
Wodji 0:68c79e5c722b 48 int errnum = -1;
Wodji 0:68c79e5c722b 49 if((memoryAddress + dataLength) > _device.maxAddress) return errnum;
Wodji 0:68c79e5c722b 50 int loc_deviceAddress = _deviceAddress;
Wodji 0:68c79e5c722b 51
Wodji 0:68c79e5c722b 52 if (_device < C24LC04){
Wodji 0:68c79e5c722b 53 char loc_memoryAddress = (char)memoryAddress;
Wodji 0:68c79e5c722b 54 errnum = readEXE(loc_deviceAddress, &loc_memoryAddress, 1, data, dataLength);
Wodji 0:68c79e5c722b 55 }
Wodji 0:68c79e5c722b 56 else if (_device > C24LC02 && _device < C24LC32){
Wodji 0:68c79e5c722b 57 int totalBlocksSize = BLOCK_SIZE;
Wodji 0:68c79e5c722b 58 char loc_memoryAddres;
Wodji 0:68c79e5c722b 59 int startBlock, blocksToRead, remindLength, partLength = 0;
Wodji 0:68c79e5c722b 60 int loc_dataLength[_device.blockNumbers];
Wodji 0:68c79e5c722b 61
Wodji 0:68c79e5c722b 62 for (int i = 0; i < _device.blockNumbers; i++){
Wodji 0:68c79e5c722b 63 if (memoryAddress < totalBlocksSize){
Wodji 0:68c79e5c722b 64 startBlock = i;
Wodji 0:68c79e5c722b 65 loc_memoryAddres = memoryAddress - (BLOCK_SIZE * startBlock);
Wodji 0:68c79e5c722b 66 break;
Wodji 0:68c79e5c722b 67 }
Wodji 0:68c79e5c722b 68 else totalBlocksSize =+ BLOCK_SIZE;
Wodji 0:68c79e5c722b 69 }
Wodji 0:68c79e5c722b 70
Wodji 0:68c79e5c722b 71 loc_dataLength[0] = BLOCK_SIZE - loc_memoryAddres;
Wodji 0:68c79e5c722b 72 if (dataLength <= loc_dataLength[0]){
Wodji 0:68c79e5c722b 73 loc_dataLength[0] = dataLength;
Wodji 0:68c79e5c722b 74 blocksToRead = 1;
Wodji 0:68c79e5c722b 75 }
Wodji 0:68c79e5c722b 76 else {
Wodji 0:68c79e5c722b 77 remindLength = dataLength - loc_dataLength[0];
Wodji 0:68c79e5c722b 78 for (int i = 1; i < _device.blockNumbers; i++) {
Wodji 0:68c79e5c722b 79 if (remindLength <= BLOCK_SIZE) {
Wodji 0:68c79e5c722b 80 loc_dataLength[i] = remindLength;
Wodji 0:68c79e5c722b 81 blocksToRead++;
Wodji 0:68c79e5c722b 82 break;
Wodji 0:68c79e5c722b 83 }
Wodji 0:68c79e5c722b 84 loc_dataLength[i] = BLOCK_SIZE;
Wodji 0:68c79e5c722b 85 remindLength -= BLOCK_SIZE;
Wodji 0:68c79e5c722b 86 }
Wodji 0:68c79e5c722b 87 }
Wodji 0:68c79e5c722b 88
Wodji 0:68c79e5c722b 89 for (int i = 0; i < blocksToRead; i++){
Wodji 0:68c79e5c722b 90 loc_deviceAddress &= 0xF0;
Wodji 0:68c79e5c722b 91 loc_deviceAddress |= (startBlock << 1);
Wodji 0:68c79e5c722b 92 errnum = readEXE(loc_deviceAddress, &loc_memoryAddres, 1, &data[partLength], loc_dataLength[i]);
Wodji 0:68c79e5c722b 93 if (errnum != 0) return errnum;
Wodji 0:68c79e5c722b 94 partLength += loc_dataLength[i];
Wodji 0:68c79e5c722b 95 startBlock++;
Wodji 0:68c79e5c722b 96 loc_memoryAddres = 0x00;
Wodji 0:68c79e5c722b 97 }
Wodji 0:68c79e5c722b 98 }
Wodji 0:68c79e5c722b 99 else {
Wodji 0:68c79e5c722b 100 char loc_memoryAddress[2];
Wodji 0:68c79e5c722b 101 loc_memoryAddress[0] = (char)(memoryAddress >> 8); // Read Address High byte set
Wodji 0:68c79e5c722b 102 loc_memoryAddress[1] = (char)memoryAddress; // Read Address Low byte set
Wodji 0:68c79e5c722b 103 errnum = readEXE(loc_deviceAddress, loc_memoryAddress, 2, data, dataLength);
Wodji 0:68c79e5c722b 104 }
Wodji 0:68c79e5c722b 105 return errnum;
Wodji 0:68c79e5c722b 106 }
Wodji 0:68c79e5c722b 107
Wodji 0:68c79e5c722b 108 int EEPROM::write(int memoryAddress, const char* data, int dataLength){
Wodji 0:68c79e5c722b 109 int errnum = -1;
Wodji 0:68c79e5c722b 110 if((memoryAddress + dataLength) > _device.maxAddress) return errnum;
Wodji 0:68c79e5c722b 111
Wodji 0:68c79e5c722b 112 int offset = 0;
Wodji 0:68c79e5c722b 113 while(offset < dataLength) {
Wodji 0:68c79e5c722b 114 int loc_dataLength = _device.pageSize - ((memoryAddress + offset) % _device.pageSize);
Wodji 0:68c79e5c722b 115 if((offset + loc_dataLength) > dataLength) loc_dataLength = dataLength - offset;
Wodji 0:68c79e5c722b 116 errnum = writePage((memoryAddress + offset), (data + offset), loc_dataLength);
Wodji 0:68c79e5c722b 117 if(errnum != 0) return errnum;
Wodji 0:68c79e5c722b 118 offset += loc_dataLength;
Wodji 0:68c79e5c722b 119 }
Wodji 0:68c79e5c722b 120 return errnum;
Wodji 0:68c79e5c722b 121 }
Wodji 0:68c79e5c722b 122
Wodji 0:68c79e5c722b 123 int EEPROM::writePage(int memoryAddress, const char* data, int dataLength){
Wodji 0:68c79e5c722b 124 int errnum = -1;
Wodji 0:68c79e5c722b 125 if(((memoryAddress % _device.pageSize) + dataLength) > _device.pageSize) return errnum;
Wodji 0:68c79e5c722b 126 int loc_deviceAddress = _deviceAddress;
Wodji 0:68c79e5c722b 127
Wodji 0:68c79e5c722b 128 if (_device < C24LC04) {
Wodji 0:68c79e5c722b 129 char loc_memoryAddress = (char)memoryAddress;
Wodji 0:68c79e5c722b 130 errnum = writeEXE(loc_deviceAddress, &loc_memoryAddress, sizeof(loc_memoryAddress), data, dataLength);
Wodji 0:68c79e5c722b 131 }
Wodji 0:68c79e5c722b 132 else if (_device > C24LC02 && _device < C24LC32){
Wodji 0:68c79e5c722b 133 int totalBlocksSize = BLOCK_SIZE;
Wodji 0:68c79e5c722b 134 char loc_memoryAddres;
Wodji 0:68c79e5c722b 135 int startBlock, blocksToWrite, remindLength, partLength = 0;
Wodji 0:68c79e5c722b 136 int loc_dataLength[2];
Wodji 0:68c79e5c722b 137
Wodji 0:68c79e5c722b 138 for (int i = 0; i < _device.blockNumbers; i++){
Wodji 0:68c79e5c722b 139 if (memoryAddress < totalBlocksSize){
Wodji 0:68c79e5c722b 140 startBlock = i;
Wodji 0:68c79e5c722b 141 loc_memoryAddres = memoryAddress - (BLOCK_SIZE * startBlock);
Wodji 0:68c79e5c722b 142 break;
Wodji 0:68c79e5c722b 143 }
Wodji 0:68c79e5c722b 144 else totalBlocksSize =+ BLOCK_SIZE;
Wodji 0:68c79e5c722b 145 }
Wodji 0:68c79e5c722b 146
Wodji 0:68c79e5c722b 147 loc_dataLength[0] = BLOCK_SIZE - loc_memoryAddres;
Wodji 0:68c79e5c722b 148 if (dataLength <= loc_dataLength[0]){
Wodji 0:68c79e5c722b 149 loc_dataLength[0] = dataLength;
Wodji 0:68c79e5c722b 150 blocksToWrite = 1;
Wodji 0:68c79e5c722b 151 }
Wodji 0:68c79e5c722b 152 else {
Wodji 0:68c79e5c722b 153 loc_dataLength[1] = dataLength - loc_dataLength[0];
Wodji 0:68c79e5c722b 154 blocksToWrite = 2;
Wodji 0:68c79e5c722b 155 }
Wodji 0:68c79e5c722b 156
Wodji 0:68c79e5c722b 157 for (int i = 0; i < blocksToWrite; i++){
Wodji 0:68c79e5c722b 158 loc_deviceAddress &= 0xF0;
Wodji 0:68c79e5c722b 159 loc_deviceAddress |= (startBlock << 1);
Wodji 0:68c79e5c722b 160 errnum = writeEXE(loc_deviceAddress, &loc_memoryAddres, 1, &data[partLength], loc_dataLength[i]);
Wodji 0:68c79e5c722b 161 if (errnum != 0) return errnum;
Wodji 0:68c79e5c722b 162 partLength += loc_dataLength[i];
Wodji 0:68c79e5c722b 163 startBlock++;
Wodji 0:68c79e5c722b 164 loc_memoryAddres = 0x00;
Wodji 0:68c79e5c722b 165 }
Wodji 0:68c79e5c722b 166 }
Wodji 0:68c79e5c722b 167 else {
Wodji 0:68c79e5c722b 168 char loc_memoryAddress[2];
Wodji 0:68c79e5c722b 169 loc_memoryAddress[0] = (char)(memoryAddress >> 8); // Write Address High byte set
Wodji 0:68c79e5c722b 170 loc_memoryAddress[1] = (char)memoryAddress; // Write Address Low byte set
Wodji 0:68c79e5c722b 171 errnum = writeEXE(loc_deviceAddress, loc_memoryAddress, sizeof(loc_memoryAddress), data, dataLength);
Wodji 0:68c79e5c722b 172 }
Wodji 0:68c79e5c722b 173 return errnum;
Wodji 0:68c79e5c722b 174 }
Wodji 0:68c79e5c722b 175
Wodji 0:68c79e5c722b 176 int EEPROM::readEXE(int deviceAddress, char* address, int addressLength, char* data, int dataLength){
Wodji 0:68c79e5c722b 177 int errnum;
Wodji 0:68c79e5c722b 178 errnum = _i2c->write(deviceAddress, address, addressLength, true);
Wodji 0:68c79e5c722b 179 if(errnum != 0)return errnum;
Wodji 0:68c79e5c722b 180 return _i2c->read(deviceAddress, data, dataLength, false);
Wodji 0:68c79e5c722b 181 }
Wodji 0:68c79e5c722b 182
Wodji 0:68c79e5c722b 183 int EEPROM::writeEXE(int deviceAddress, char* memoryAddress, int addressLength, const char* data, int dataLength){
Wodji 0:68c79e5c722b 184 int errnum;
Wodji 0:68c79e5c722b 185 char loc_data[addressLength + dataLength];
Wodji 0:68c79e5c722b 186 for(int i = 0; i < addressLength; i++) loc_data[i] = memoryAddress[i];
Wodji 0:68c79e5c722b 187 for(int i = 0; i < dataLength; i++) loc_data[i + addressLength] = data[i];
Wodji 0:68c79e5c722b 188 errnum = _i2c->write(deviceAddress, loc_data, sizeof(loc_data), false);
Wodji 0:68c79e5c722b 189 wait_ms(5);
Wodji 0:68c79e5c722b 190 return errnum;
Wodji 0:68c79e5c722b 191 }