Driver library for Microchip I2C EERAM (47x04 and 47x16) 4 kbit or 16 kbit EEPROM backed SRAM.

Dependents:   EERAM_example

Committer:
vargham
Date:
Tue Apr 25 16:22:53 2017 +0000
Revision:
1:6028bc22d82f
Parent:
0:19f9af07424a
Child:
2:bdbf9de0e985
Fixed copy/paste example program error.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vargham 0:19f9af07424a 1 /**
vargham 1:6028bc22d82f 2 * @file EERAM.cpp
vargham 1:6028bc22d82f 3 * @brief mbed driver for Microchip I2C EERAM devices (47x04 and 47x16)
vargham 0:19f9af07424a 4 * @author Mark Peter Vargha, vmp@varghamarkpeter.hu
vargham 0:19f9af07424a 5 * @version 1.0.0
vargham 0:19f9af07424a 6 *
vargham 0:19f9af07424a 7 * Copyright (c) 2017
vargham 0:19f9af07424a 8 *
vargham 0:19f9af07424a 9 * Licensed under the Apache License, Version 2.0 (the "License");
vargham 0:19f9af07424a 10 * you may not use this file except in compliance with the License.
vargham 0:19f9af07424a 11 * You may obtain a copy of the License at
vargham 0:19f9af07424a 12 *
vargham 0:19f9af07424a 13 * http://www.apache.org/licenses/LICENSE-2.0
vargham 0:19f9af07424a 14 *
vargham 0:19f9af07424a 15 * Unless required by applicable law or agreed to in writing, software
vargham 0:19f9af07424a 16 * distributed under the License is distributed on an "AS IS" BASIS,
vargham 0:19f9af07424a 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vargham 0:19f9af07424a 18 * See the License for the specific language governing permissions and
vargham 0:19f9af07424a 19 * limitations under the License.
vargham 0:19f9af07424a 20 */
vargham 0:19f9af07424a 21
vargham 0:19f9af07424a 22 #include "EERAM.h"
vargham 0:19f9af07424a 23
vargham 1:6028bc22d82f 24 void EERAM::initialize(bool A1, bool A2)
vargham 1:6028bc22d82f 25 {
vargham 1:6028bc22d82f 26 _sramAddressWrite = OPCODE_SRAM;
vargham 1:6028bc22d82f 27 _sramAddressWrite ^= (-A1 ^ _sramAddressWrite) & (1 << A1_BIT);
vargham 1:6028bc22d82f 28 _sramAddressWrite ^= (-A2 ^ _sramAddressWrite) & (1 << A2_BIT);
vargham 1:6028bc22d82f 29 _sramAddressRead = _sramAddressWrite;
vargham 1:6028bc22d82f 30 _sramAddressRead ^= (-true ^ _sramAddressRead) & (1 << RW_BIT);
vargham 0:19f9af07424a 31
vargham 1:6028bc22d82f 32 _controlAddressWrite = OPCODE_CONTROL;
vargham 1:6028bc22d82f 33 _controlAddressWrite ^= (-A1 ^ _controlAddressWrite) & (1 << A1_BIT);
vargham 1:6028bc22d82f 34 _controlAddressWrite ^= (-A2 ^ _controlAddressWrite) & (1 << A2_BIT);
vargham 1:6028bc22d82f 35 _controlAddressRead = _controlAddressWrite;
vargham 1:6028bc22d82f 36 _controlAddressRead ^= (-true ^ _controlAddressWrite) & (1 << RW_BIT);
vargham 1:6028bc22d82f 37 }
vargham 1:6028bc22d82f 38
vargham 1:6028bc22d82f 39 bool EERAM::checkAddressRange(uint16_t start, uint16_t length)
vargham 0:19f9af07424a 40 {
vargham 1:6028bc22d82f 41 return start < _memorySize && start + length <= _memorySize && length > 0;
vargham 1:6028bc22d82f 42 }
vargham 0:19f9af07424a 43
vargham 1:6028bc22d82f 44 bool EERAM::write(uint16_t address, char *data, int length)
vargham 1:6028bc22d82f 45 {
vargham 1:6028bc22d82f 46 bool success = false;
vargham 1:6028bc22d82f 47 success = checkAddressRange(address, length);
vargham 1:6028bc22d82f 48 if (success) success = setMemoryPointer(address, false);
vargham 1:6028bc22d82f 49 int index = 0;
vargham 1:6028bc22d82f 50 while (index < length && success)
vargham 0:19f9af07424a 51 {
vargham 1:6028bc22d82f 52 success = _i2c.write(data[index]) == 1;
vargham 1:6028bc22d82f 53 index++;
vargham 1:6028bc22d82f 54 }
vargham 1:6028bc22d82f 55 _i2c.stop();
vargham 1:6028bc22d82f 56 return success;
vargham 1:6028bc22d82f 57 }
vargham 0:19f9af07424a 58
vargham 1:6028bc22d82f 59 bool EERAM::read(uint16_t address, char *data, int length)
vargham 1:6028bc22d82f 60 {
vargham 1:6028bc22d82f 61 bool success = checkAddressRange(address, length);
vargham 1:6028bc22d82f 62 if (success) success = setMemoryPointer(address, true);
vargham 1:6028bc22d82f 63 if (success)
vargham 0:19f9af07424a 64 {
vargham 1:6028bc22d82f 65 success = _i2c.read(_sramAddressRead, data, length, false) == 0;
vargham 0:19f9af07424a 66 }
vargham 1:6028bc22d82f 67 _i2c.stop();
vargham 1:6028bc22d82f 68 return success;
vargham 1:6028bc22d82f 69 }
vargham 0:19f9af07424a 70
vargham 1:6028bc22d82f 71 bool EERAM::writeRegister(uint8_t registerAddress, uint8_t data)
vargham 1:6028bc22d82f 72 {
vargham 1:6028bc22d82f 73 _i2c.start();
vargham 1:6028bc22d82f 74 bool success = _i2c.write(_controlAddressWrite) == 1;
vargham 1:6028bc22d82f 75 if (success) success = _i2c.write(registerAddress) == 1;
vargham 1:6028bc22d82f 76 if (success) success = _i2c.write(data) == 1;
vargham 1:6028bc22d82f 77 _i2c.stop();
vargham 1:6028bc22d82f 78 return success;
vargham 0:19f9af07424a 79 }
vargham 0:19f9af07424a 80
vargham 1:6028bc22d82f 81 bool EERAM::store(bool block)
vargham 1:6028bc22d82f 82 {
vargham 1:6028bc22d82f 83 bool success = writeRegister(REGISTER_COMMAND, COMMAND_STORE);
vargham 1:6028bc22d82f 84 if (success && block)
vargham 1:6028bc22d82f 85 {
vargham 1:6028bc22d82f 86 isReady((_memorySize <= 512 ? TIME_STORE_04_MS: TIME_STORE_16_MS) * 2);
vargham 1:6028bc22d82f 87 }
vargham 1:6028bc22d82f 88 return success;
vargham 1:6028bc22d82f 89 }
vargham 1:6028bc22d82f 90
vargham 1:6028bc22d82f 91 bool EERAM::recall(bool block)
vargham 1:6028bc22d82f 92 {
vargham 1:6028bc22d82f 93 bool success = writeRegister(REGISTER_COMMAND, COMMAND_RECALL);
vargham 1:6028bc22d82f 94 if (success && block)
vargham 1:6028bc22d82f 95 {
vargham 1:6028bc22d82f 96 isReady((_memorySize <= 512 ? TIME_RECALL_04_MS: TIME_RECALL_16_MS) * 2);
vargham 1:6028bc22d82f 97 }
vargham 1:6028bc22d82f 98 return success;
vargham 1:6028bc22d82f 99 }
vargham 1:6028bc22d82f 100
vargham 1:6028bc22d82f 101 bool EERAM::readStatus()
vargham 1:6028bc22d82f 102 {
vargham 1:6028bc22d82f 103 _i2c.start();
vargham 1:6028bc22d82f 104 bool success = _i2c.write(_controlAddressRead) == 1;
vargham 1:6028bc22d82f 105 if (success)
vargham 1:6028bc22d82f 106 {
vargham 1:6028bc22d82f 107 _status = _i2c.read(false);
vargham 1:6028bc22d82f 108 _statusToWrite = _status;
vargham 1:6028bc22d82f 109 }
vargham 1:6028bc22d82f 110 _i2c.stop();
vargham 1:6028bc22d82f 111 return success;
vargham 1:6028bc22d82f 112 }
vargham 1:6028bc22d82f 113
vargham 1:6028bc22d82f 114 bool EERAM::writeStatus(bool block)
vargham 0:19f9af07424a 115 {
vargham 1:6028bc22d82f 116 bool success = writeRegister(REGISTER_STATUS, _statusToWrite);
vargham 1:6028bc22d82f 117 if (success)
vargham 1:6028bc22d82f 118 {
vargham 1:6028bc22d82f 119 _status = _statusToWrite;
vargham 1:6028bc22d82f 120 if (block) isReady(TIME_STORE_STATUS_MS * 2);
vargham 1:6028bc22d82f 121 }
vargham 1:6028bc22d82f 122 return success;
vargham 1:6028bc22d82f 123 }
vargham 1:6028bc22d82f 124
vargham 1:6028bc22d82f 125 void EERAM::writeStatusIfChanged(bool block)
vargham 1:6028bc22d82f 126 {
vargham 1:6028bc22d82f 127 if (_statusToWrite != _status) writeStatus(block);
vargham 1:6028bc22d82f 128 }
vargham 1:6028bc22d82f 129
vargham 1:6028bc22d82f 130 void EERAM::setProtectedMemoryArea(ProtectedMemoryArea protectedMemoryArea, bool store)
vargham 1:6028bc22d82f 131 {
vargham 1:6028bc22d82f 132 const uint8_t mask = 0b00011100;
vargham 1:6028bc22d82f 133 _statusToWrite = (_statusToWrite & ~mask) | ((protectedMemoryArea << 2) & mask);
vargham 1:6028bc22d82f 134 if (store) writeStatusIfChanged(false);
vargham 1:6028bc22d82f 135 }
vargham 1:6028bc22d82f 136
vargham 1:6028bc22d82f 137 ProtectedMemoryArea EERAM::getProtectedMemoryArea()
vargham 1:6028bc22d82f 138 {
vargham 1:6028bc22d82f 139 return (ProtectedMemoryArea) ((_status >> 2) & ~(-1 << 3));
vargham 1:6028bc22d82f 140 }
vargham 1:6028bc22d82f 141
vargham 1:6028bc22d82f 142 bool EERAM::isMemoryModified()
vargham 1:6028bc22d82f 143 {
vargham 1:6028bc22d82f 144 return (_status >> STATUS_AM_BIT) & 1;
vargham 1:6028bc22d82f 145 }
vargham 1:6028bc22d82f 146
vargham 1:6028bc22d82f 147 void EERAM::setAutoStoreEnabled(bool enabled, bool store)
vargham 1:6028bc22d82f 148 {
vargham 1:6028bc22d82f 149 _statusToWrite ^= (-enabled ^ _statusToWrite) & (1 << STATUS_ASE_BIT);
vargham 1:6028bc22d82f 150 if (store) writeStatusIfChanged(false);
vargham 1:6028bc22d82f 151 }
vargham 1:6028bc22d82f 152
vargham 1:6028bc22d82f 153 bool EERAM::isAutoStoreEnabled()
vargham 1:6028bc22d82f 154 {
vargham 1:6028bc22d82f 155 return (_status >> STATUS_ASE_BIT) & 1;
vargham 0:19f9af07424a 156 }
vargham 0:19f9af07424a 157
vargham 1:6028bc22d82f 158 void EERAM::setEventDetected(bool detected, bool store)
vargham 1:6028bc22d82f 159 {
vargham 1:6028bc22d82f 160 _statusToWrite ^= (-detected ^ _statusToWrite) & (1 << STATUS_EVENT_BIT);
vargham 1:6028bc22d82f 161 if (store) writeStatusIfChanged(false);
vargham 1:6028bc22d82f 162 }
vargham 1:6028bc22d82f 163
vargham 1:6028bc22d82f 164 bool EERAM::isEventDetected()
vargham 0:19f9af07424a 165 {
vargham 1:6028bc22d82f 166 return (_status >> STATUS_EVENT_BIT) & 1;
vargham 1:6028bc22d82f 167 }
vargham 0:19f9af07424a 168
vargham 1:6028bc22d82f 169 bool EERAM::isReady()
vargham 1:6028bc22d82f 170 {
vargham 1:6028bc22d82f 171 bool ready = false;
vargham 1:6028bc22d82f 172 _i2c.start();
vargham 1:6028bc22d82f 173 ready = _i2c.write(_controlAddressWrite) == 1;
vargham 1:6028bc22d82f 174 _i2c.stop();
vargham 1:6028bc22d82f 175 return ready;
vargham 1:6028bc22d82f 176 }
vargham 0:19f9af07424a 177
vargham 1:6028bc22d82f 178 bool EERAM::isReady(int timeout_ms)
vargham 1:6028bc22d82f 179 {
vargham 1:6028bc22d82f 180 bool ready = false;
vargham 1:6028bc22d82f 181 Timer timeoutTimer;
vargham 1:6028bc22d82f 182 timeoutTimer.start();
vargham 1:6028bc22d82f 183 while (!ready && timeoutTimer.read_ms() < timeout_ms)
vargham 1:6028bc22d82f 184 {
vargham 1:6028bc22d82f 185 ready = isReady();
vargham 1:6028bc22d82f 186 if (ready)
vargham 1:6028bc22d82f 187 {
vargham 1:6028bc22d82f 188 break;
vargham 1:6028bc22d82f 189 }
vargham 1:6028bc22d82f 190 }
vargham 1:6028bc22d82f 191 return ready;
vargham 1:6028bc22d82f 192 }
vargham 0:19f9af07424a 193
vargham 1:6028bc22d82f 194 void EERAM::dump(Serial &serial, uint16_t start, uint16_t length, int lineSize)
vargham 1:6028bc22d82f 195 {
vargham 1:6028bc22d82f 196 const int lineMaxSize = 32;
vargham 1:6028bc22d82f 197 if (!checkAddressRange(start, length) || lineSize > lineMaxSize)
vargham 1:6028bc22d82f 198 {
vargham 1:6028bc22d82f 199 serial.printf("Invalid parameters for memory dump.\r\n");
vargham 1:6028bc22d82f 200 return;
vargham 1:6028bc22d82f 201 }
vargham 1:6028bc22d82f 202 if (!setMemoryPointer(start, true))
vargham 1:6028bc22d82f 203 {
vargham 1:6028bc22d82f 204 serial.printf("Could not set start address for memory dump.\r\n");
vargham 1:6028bc22d82f 205 return;
vargham 1:6028bc22d82f 206 }
vargham 1:6028bc22d82f 207 char buffer[lineMaxSize];
vargham 1:6028bc22d82f 208 int lastLineLength = length % lineSize;
vargham 1:6028bc22d82f 209 int segments = length / lineSize + (lastLineLength > 0 ? 1 : 0);
vargham 1:6028bc22d82f 210 lastLineLength = lastLineLength == 0 ? lineSize : lastLineLength;
vargham 1:6028bc22d82f 211 for (int i = 0; i < segments; i++)
vargham 1:6028bc22d82f 212 {
vargham 1:6028bc22d82f 213 serial.printf("%.4X", start + lineSize * i);
vargham 1:6028bc22d82f 214 _i2c.read(_sramAddressRead, buffer, lineSize, false);
vargham 1:6028bc22d82f 215 for (int j = 0; j < (i == segments - 1 ? lastLineLength : lineSize); j++)
vargham 1:6028bc22d82f 216 {
vargham 1:6028bc22d82f 217 serial.printf(" %.2X", buffer[j]);
vargham 1:6028bc22d82f 218 }
vargham 1:6028bc22d82f 219 serial.printf("\r\n");
vargham 1:6028bc22d82f 220 }
vargham 1:6028bc22d82f 221 }
vargham 0:19f9af07424a 222
vargham 1:6028bc22d82f 223 void EERAM::dump(Serial &serial)
vargham 1:6028bc22d82f 224 {
vargham 1:6028bc22d82f 225 dump(serial, 0, _memorySize);
vargham 1:6028bc22d82f 226 }
vargham 1:6028bc22d82f 227
vargham 1:6028bc22d82f 228 bool EERAM::setMemoryPointer(uint16_t address, bool stop)
vargham 1:6028bc22d82f 229 {
vargham 1:6028bc22d82f 230 int result = 0;
vargham 1:6028bc22d82f 231 MemoryAddress location;
vargham 1:6028bc22d82f 232 location.address = address;
vargham 1:6028bc22d82f 233 _i2c.start();
vargham 1:6028bc22d82f 234 result = _i2c.write(_sramAddressWrite);
vargham 1:6028bc22d82f 235 if (result == 1) result = _i2c.write(location.bytes[1]);
vargham 1:6028bc22d82f 236 if (result == 1) result = _i2c.write(location.bytes[0]);
vargham 1:6028bc22d82f 237 if (stop) _i2c.stop();
vargham 1:6028bc22d82f 238 return result == 1;
vargham 1:6028bc22d82f 239 }
vargham 1:6028bc22d82f 240
vargham 1:6028bc22d82f 241 bool EERAM::fillMemory(uint16_t address, char data, int length)
vargham 1:6028bc22d82f 242 {
vargham 1:6028bc22d82f 243 int result = 0;
vargham 1:6028bc22d82f 244 result = setMemoryPointer(address, false) ? 1 : 0;
vargham 1:6028bc22d82f 245 int index = 0;
vargham 1:6028bc22d82f 246 while (index < length && result == 1)
vargham 1:6028bc22d82f 247 {
vargham 1:6028bc22d82f 248 result = _i2c.write(data);
vargham 1:6028bc22d82f 249 index++;
vargham 1:6028bc22d82f 250 }
vargham 1:6028bc22d82f 251 _i2c.stop();
vargham 1:6028bc22d82f 252 return result == 1;
vargham 1:6028bc22d82f 253 }
vargham 0:19f9af07424a 254
vargham 1:6028bc22d82f 255 bool EERAM::fillMemory(char data)
vargham 1:6028bc22d82f 256 {
vargham 1:6028bc22d82f 257 return fillMemory(0, data, _memorySize);
vargham 1:6028bc22d82f 258 }
vargham 1:6028bc22d82f 259
vargham 1:6028bc22d82f 260 void EERAM::dumpRegisters(Serial &serial)
vargham 1:6028bc22d82f 261 {
vargham 1:6028bc22d82f 262 serial.printf("Control Register Contents\r\n");
vargham 1:6028bc22d82f 263 serial.printf("Event detected: %d\r\n", isEventDetected());
vargham 1:6028bc22d82f 264 serial.printf("Auto Store Enabled: %d\r\n", isAutoStoreEnabled());
vargham 1:6028bc22d82f 265 serial.printf("Protected area: %d = ", getProtectedMemoryArea());
vargham 1:6028bc22d82f 266 switch (getProtectedMemoryArea())
vargham 0:19f9af07424a 267 {
vargham 1:6028bc22d82f 268 case NONE:
vargham 1:6028bc22d82f 269 serial.printf("None");
vargham 1:6028bc22d82f 270 break;
vargham 1:6028bc22d82f 271 case U64:
vargham 1:6028bc22d82f 272 serial.printf("U64");
vargham 1:6028bc22d82f 273 break;
vargham 1:6028bc22d82f 274 case U32:
vargham 1:6028bc22d82f 275 serial.printf("U32");
vargham 1:6028bc22d82f 276 break;
vargham 1:6028bc22d82f 277 case U16:
vargham 1:6028bc22d82f 278 serial.printf("U16");
vargham 1:6028bc22d82f 279 break;
vargham 1:6028bc22d82f 280 case U8:
vargham 1:6028bc22d82f 281 serial.printf("U8");
vargham 1:6028bc22d82f 282 break;
vargham 1:6028bc22d82f 283 case U4:
vargham 1:6028bc22d82f 284 serial.printf("U4");
vargham 1:6028bc22d82f 285 break;
vargham 1:6028bc22d82f 286 case U2:
vargham 1:6028bc22d82f 287 serial.printf("U2");
vargham 1:6028bc22d82f 288 break;
vargham 1:6028bc22d82f 289 case ALL:
vargham 1:6028bc22d82f 290 serial.printf("All");
vargham 1:6028bc22d82f 291 break;
vargham 0:19f9af07424a 292 }
vargham 0:19f9af07424a 293 serial.printf("\r\n");
vargham 1:6028bc22d82f 294 serial.printf("Memory Array Modified: %d\r\n", isMemoryModified());
vargham 0:19f9af07424a 295 }