Driver library for Microchip I2C EERAM (47x04 and 47x16) 4 kbit or 16 kbit EEPROM backed SRAM.
Embed:
(wiki syntax)
Show/hide line numbers
EERAM.cpp
Go to the documentation of this file.
00001 /** 00002 * @file EERAM.cpp 00003 * @brief mbed driver for Microchip I2C EERAM devices (47x04 and 47x16) 00004 * @author Mark Peter Vargha, vmp@varghamarkpeter.hu 00005 * @version 1.4.0 00006 * 00007 * Copyright (c) 2017 00008 * 00009 * Licensed under the Apache License, Version 2.0 (the "License"); 00010 * you may not use this file except in compliance with the License. 00011 * You may obtain a copy of the License at 00012 * 00013 * http://www.apache.org/licenses/LICENSE-2.0 00014 * 00015 * Unless required by applicable law or agreed to in writing, software 00016 * distributed under the License is distributed on an "AS IS" BASIS, 00017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00018 * See the License for the specific language governing permissions and 00019 * limitations under the License. 00020 */ 00021 00022 #include "EERAM.h" 00023 00024 void EERAM::initialize(bool A1, bool A2) 00025 { 00026 _sramAddressWrite = OPCODE_SRAM; 00027 _sramAddressWrite ^= (-A1 ^ _sramAddressWrite) & (1 << A1_BIT); 00028 _sramAddressWrite ^= (-A2 ^ _sramAddressWrite) & (1 << A2_BIT); 00029 _sramAddressRead = _sramAddressWrite; 00030 _sramAddressRead ^= (-true ^ _sramAddressRead) & (1 << RW_BIT); 00031 00032 _controlAddressWrite = OPCODE_CONTROL; 00033 _controlAddressWrite ^= (-A1 ^ _controlAddressWrite) & (1 << A1_BIT); 00034 _controlAddressWrite ^= (-A2 ^ _controlAddressWrite) & (1 << A2_BIT); 00035 _controlAddressRead = _controlAddressWrite; 00036 _controlAddressRead ^= (-true ^ _controlAddressWrite) & (1 << RW_BIT); 00037 } 00038 00039 void EERAM::putAddressIntoBuffer(uint16_t address, char *data) 00040 { 00041 data[0] = (address >> (8 * 0)) & 0xff; 00042 data[1] = (address >> (8 * 1)) & 0xff; 00043 } 00044 00045 bool EERAM::checkAddressRange(uint16_t start, uint16_t length) 00046 { 00047 return start < _memorySize && start + length <= _memorySize && length > 0; 00048 } 00049 00050 bool EERAM::writeBytes(uint16_t address, char *data, int length) 00051 { 00052 bool success = false; 00053 success = checkAddressRange(address, length); 00054 if (success) success = setMemoryPointer(address, false); 00055 int index = 0; 00056 while (index < length && success) 00057 { 00058 success = _i2c.write(data[index]) == 1; 00059 index++; 00060 } 00061 _i2c.stop(); 00062 return success; 00063 } 00064 00065 bool EERAM::writeBytes(char *data, int length) 00066 { 00067 bool success = false; 00068 success = _i2c.write(_sramAddressWrite, data, length) == 0; 00069 return success; 00070 } 00071 00072 bool EERAM::readBytes(uint16_t address, char *data, int length) 00073 { 00074 bool success = checkAddressRange(address, length); 00075 if (success) success = setMemoryPointer(address, true); 00076 if (success) 00077 { 00078 success = _i2c.read(_sramAddressRead, data, length, false) == 0; 00079 } 00080 _i2c.stop(); 00081 return success; 00082 } 00083 00084 bool EERAM::readBytes(char *data, int length) 00085 { 00086 bool success = setMemoryPointer((uint8_t)data[1], (uint8_t)data[0], true); 00087 if (success) 00088 { 00089 success = _i2c.read(_sramAddressRead, data + 2, length - 2, false) == 0; 00090 } 00091 _i2c.stop(); 00092 return success; 00093 } 00094 00095 bool EERAM::writeRegister(uint8_t registerAddress, uint8_t data) 00096 { 00097 _i2c.start(); 00098 bool success = _i2c.write(_controlAddressWrite) == 1; 00099 if (success) success = _i2c.write(registerAddress) == 1; 00100 if (success) success = _i2c.write(data) == 1; 00101 _i2c.stop(); 00102 return success; 00103 } 00104 00105 bool EERAM::store(bool block) 00106 { 00107 bool success = writeRegister(REGISTER_COMMAND, COMMAND_STORE); 00108 if (success && block) 00109 { 00110 isReady((_memorySize <= 512 ? TIME_STORE_04_MS: TIME_STORE_16_MS) * 2); 00111 } 00112 return success; 00113 } 00114 00115 bool EERAM::recall(bool block) 00116 { 00117 bool success = writeRegister(REGISTER_COMMAND, COMMAND_RECALL); 00118 if (success && block) 00119 { 00120 isReady((_memorySize <= 512 ? TIME_RECALL_04_MS: TIME_RECALL_16_MS) * 2); 00121 } 00122 return success; 00123 } 00124 00125 bool EERAM::readStatus() 00126 { 00127 _i2c.start(); 00128 bool success = _i2c.write(_controlAddressRead) == 1; 00129 if (success) 00130 { 00131 _status = _i2c.read(false); 00132 _statusToWrite = _status; 00133 } 00134 _i2c.stop(); 00135 return success; 00136 } 00137 00138 bool EERAM::writeStatus(bool block) 00139 { 00140 bool success = writeRegister(REGISTER_STATUS, _statusToWrite); 00141 if (success) 00142 { 00143 _status = _statusToWrite; 00144 if (block) isReady(TIME_STORE_STATUS_MS * 2); 00145 } 00146 return success; 00147 } 00148 00149 void EERAM::writeStatusIfChanged(bool block) 00150 { 00151 if (_statusToWrite != _status) writeStatus(block); 00152 } 00153 00154 void EERAM::setProtectedMemoryArea(ProtectedMemoryArea protectedMemoryArea, bool store) 00155 { 00156 const uint8_t mask = 0b00011100; 00157 _statusToWrite = (_statusToWrite & ~mask) | ((protectedMemoryArea << 2) & mask); 00158 if (store) writeStatusIfChanged(false); 00159 } 00160 00161 ProtectedMemoryArea EERAM::getProtectedMemoryArea() 00162 { 00163 return (ProtectedMemoryArea) ((_status >> 2) & ~(-1 << 3)); 00164 } 00165 00166 bool EERAM::isMemoryModified() 00167 { 00168 return (_status >> STATUS_AM_BIT) & 1; 00169 } 00170 00171 void EERAM::setAutoStoreEnabled(bool enabled, bool store) 00172 { 00173 _statusToWrite ^= (-enabled ^ _statusToWrite) & (1 << STATUS_ASE_BIT); 00174 if (store) writeStatusIfChanged(false); 00175 } 00176 00177 bool EERAM::isAutoStoreEnabled() 00178 { 00179 return (_status >> STATUS_ASE_BIT) & 1; 00180 } 00181 00182 void EERAM::setEventDetected(bool detected, bool store) 00183 { 00184 _statusToWrite ^= (-detected ^ _statusToWrite) & (1 << STATUS_EVENT_BIT); 00185 if (store) writeStatusIfChanged(false); 00186 } 00187 00188 bool EERAM::isEventDetected() 00189 { 00190 return (_status >> STATUS_EVENT_BIT) & 1; 00191 } 00192 00193 bool EERAM::isReady() 00194 { 00195 bool ready = false; 00196 _i2c.start(); 00197 ready = _i2c.write(_controlAddressWrite) == 1; 00198 _i2c.stop(); 00199 return ready; 00200 } 00201 00202 bool EERAM::isReady(int timeout_ms) 00203 { 00204 bool ready = false; 00205 Timer timeoutTimer; 00206 timeoutTimer.start(); 00207 while (!ready && timeoutTimer.read_ms() < timeout_ms) 00208 { 00209 ready = isReady(); 00210 if (ready) 00211 { 00212 break; 00213 } 00214 } 00215 return ready; 00216 } 00217 00218 void EERAM::dump(Serial &serial, uint16_t start, uint16_t length, int lineSize) 00219 { 00220 const int lineMaxSize = 32; 00221 if (!checkAddressRange(start, length) || lineSize > lineMaxSize) 00222 { 00223 serial.printf("Invalid parameters for memory dump.\r\n"); 00224 return; 00225 } 00226 if (!setMemoryPointer(start, true)) 00227 { 00228 serial.printf("Could not set start address for memory dump.\r\n"); 00229 return; 00230 } 00231 char buffer[lineMaxSize]; 00232 int lastLineLength = length % lineSize; 00233 int segments = length / lineSize + (lastLineLength > 0 ? 1 : 0); 00234 lastLineLength = lastLineLength == 0 ? lineSize : lastLineLength; 00235 for (int i = 0; i < segments; i++) 00236 { 00237 serial.printf("%.4X", start + lineSize * i); 00238 _i2c.read(_sramAddressRead, buffer, lineSize, false); 00239 for (int j = 0; j < (i == segments - 1 ? lastLineLength : lineSize); j++) 00240 { 00241 serial.printf(" %.2X", buffer[j]); 00242 } 00243 serial.printf("\r\n"); 00244 } 00245 } 00246 00247 void EERAM::dump(Serial &serial) 00248 { 00249 dump(serial, 0, _memorySize); 00250 } 00251 00252 bool EERAM::setMemoryPointer(uint16_t address, bool stop) 00253 { 00254 return setMemoryPointer((address >> (8 * 1)) & 0xff, (address >> (8 * 0)) & 0xff, stop); 00255 } 00256 00257 bool EERAM::setMemoryPointer(uint8_t address_0, uint8_t address_1, bool stop) 00258 { 00259 int result = 0; 00260 _i2c.start(); 00261 result = _i2c.write(_sramAddressWrite); 00262 if (result == 1) result = _i2c.write(address_1); 00263 if (result == 1) result = _i2c.write(address_0); 00264 if (stop) _i2c.stop(); 00265 return result == 1; 00266 } 00267 00268 bool EERAM::fillMemory(uint16_t address, char data, int length) 00269 { 00270 int result = 0; 00271 result = setMemoryPointer(address, false) ? 1 : 0; 00272 int index = 0; 00273 while (index < length && result == 1) 00274 { 00275 result = _i2c.write(data); 00276 index++; 00277 } 00278 _i2c.stop(); 00279 return result == 1; 00280 } 00281 00282 bool EERAM::fillMemory(char data) 00283 { 00284 return fillMemory(0, data, _memorySize); 00285 } 00286 00287 void EERAM::dumpRegisters(Serial &serial) 00288 { 00289 serial.printf("Status Register Contents\r\n"); 00290 serial.printf("Event detected: %d\r\n", isEventDetected()); 00291 serial.printf("Auto Store Enabled: %d\r\n", isAutoStoreEnabled()); 00292 serial.printf("Protected area: %d = ", getProtectedMemoryArea()); 00293 switch (getProtectedMemoryArea()) 00294 { 00295 case NONE: 00296 serial.printf("None"); 00297 break; 00298 case U64: 00299 serial.printf("U64"); 00300 break; 00301 case U32: 00302 serial.printf("U32"); 00303 break; 00304 case U16: 00305 serial.printf("U16"); 00306 break; 00307 case U8: 00308 serial.printf("U8"); 00309 break; 00310 case U4: 00311 serial.printf("U4"); 00312 break; 00313 case U2: 00314 serial.printf("U2"); 00315 break; 00316 case ALL: 00317 serial.printf("All"); 00318 break; 00319 } 00320 serial.printf("\r\n"); 00321 serial.printf("Memory Array Modified: %d\r\n", isMemoryModified()); 00322 }
Generated on Fri Jul 15 2022 21:14:32 by 1.7.2