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

Dependents:   EERAM_example

Committer:
vargham
Date:
Thu Apr 27 17:33:49 2017 +0000
Revision:
3:a869096d7a5d
Parent:
2:bdbf9de0e985
Child:
4:fd84e2f0d1de
Added array handling.

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 3:a869096d7a5d 5 * @version 1.2.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 2:bdbf9de0e985 39 void EERAM::putAddressIntoBuffer(uint16_t address, char *data)
vargham 2:bdbf9de0e985 40 {
vargham 2:bdbf9de0e985 41 MemoryAddress location;
vargham 2:bdbf9de0e985 42 location.address = address;
vargham 2:bdbf9de0e985 43 data[0] = location.bytes[1];
vargham 2:bdbf9de0e985 44 data[1] = location.bytes[0];
vargham 2:bdbf9de0e985 45 }
vargham 2:bdbf9de0e985 46
vargham 1:6028bc22d82f 47 bool EERAM::checkAddressRange(uint16_t start, uint16_t length)
vargham 0:19f9af07424a 48 {
vargham 1:6028bc22d82f 49 return start < _memorySize && start + length <= _memorySize && length > 0;
vargham 1:6028bc22d82f 50 }
vargham 0:19f9af07424a 51
vargham 1:6028bc22d82f 52 bool EERAM::write(uint16_t address, char *data, int length)
vargham 1:6028bc22d82f 53 {
vargham 1:6028bc22d82f 54 bool success = false;
vargham 1:6028bc22d82f 55 success = checkAddressRange(address, length);
vargham 1:6028bc22d82f 56 if (success) success = setMemoryPointer(address, false);
vargham 1:6028bc22d82f 57 int index = 0;
vargham 1:6028bc22d82f 58 while (index < length && success)
vargham 0:19f9af07424a 59 {
vargham 1:6028bc22d82f 60 success = _i2c.write(data[index]) == 1;
vargham 1:6028bc22d82f 61 index++;
vargham 1:6028bc22d82f 62 }
vargham 1:6028bc22d82f 63 _i2c.stop();
vargham 1:6028bc22d82f 64 return success;
vargham 1:6028bc22d82f 65 }
vargham 0:19f9af07424a 66
vargham 2:bdbf9de0e985 67 bool EERAM::write(char *data, int length)
vargham 2:bdbf9de0e985 68 {
vargham 2:bdbf9de0e985 69 bool success = false;
vargham 2:bdbf9de0e985 70 success = _i2c.write(_sramAddressWrite, data, length) == 0;
vargham 2:bdbf9de0e985 71 return success;
vargham 2:bdbf9de0e985 72 }
vargham 2:bdbf9de0e985 73
vargham 1:6028bc22d82f 74 bool EERAM::read(uint16_t address, char *data, int length)
vargham 1:6028bc22d82f 75 {
vargham 1:6028bc22d82f 76 bool success = checkAddressRange(address, length);
vargham 1:6028bc22d82f 77 if (success) success = setMemoryPointer(address, true);
vargham 1:6028bc22d82f 78 if (success)
vargham 0:19f9af07424a 79 {
vargham 1:6028bc22d82f 80 success = _i2c.read(_sramAddressRead, data, length, false) == 0;
vargham 0:19f9af07424a 81 }
vargham 1:6028bc22d82f 82 _i2c.stop();
vargham 1:6028bc22d82f 83 return success;
vargham 1:6028bc22d82f 84 }
vargham 0:19f9af07424a 85
vargham 2:bdbf9de0e985 86 bool EERAM::read(char *data, int length)
vargham 2:bdbf9de0e985 87 {
vargham 2:bdbf9de0e985 88 bool success = setMemoryPointer((uint8_t)data[1], (uint8_t)data[0], true);
vargham 2:bdbf9de0e985 89 if (success)
vargham 2:bdbf9de0e985 90 {
vargham 2:bdbf9de0e985 91 success = _i2c.read(_sramAddressRead, data + 2, length - 2, false) == 0;
vargham 2:bdbf9de0e985 92 }
vargham 2:bdbf9de0e985 93 _i2c.stop();
vargham 2:bdbf9de0e985 94 return success;
vargham 2:bdbf9de0e985 95 }
vargham 2:bdbf9de0e985 96
vargham 1:6028bc22d82f 97 bool EERAM::writeRegister(uint8_t registerAddress, uint8_t data)
vargham 1:6028bc22d82f 98 {
vargham 1:6028bc22d82f 99 _i2c.start();
vargham 1:6028bc22d82f 100 bool success = _i2c.write(_controlAddressWrite) == 1;
vargham 1:6028bc22d82f 101 if (success) success = _i2c.write(registerAddress) == 1;
vargham 1:6028bc22d82f 102 if (success) success = _i2c.write(data) == 1;
vargham 1:6028bc22d82f 103 _i2c.stop();
vargham 1:6028bc22d82f 104 return success;
vargham 0:19f9af07424a 105 }
vargham 0:19f9af07424a 106
vargham 1:6028bc22d82f 107 bool EERAM::store(bool block)
vargham 1:6028bc22d82f 108 {
vargham 1:6028bc22d82f 109 bool success = writeRegister(REGISTER_COMMAND, COMMAND_STORE);
vargham 1:6028bc22d82f 110 if (success && block)
vargham 1:6028bc22d82f 111 {
vargham 1:6028bc22d82f 112 isReady((_memorySize <= 512 ? TIME_STORE_04_MS: TIME_STORE_16_MS) * 2);
vargham 1:6028bc22d82f 113 }
vargham 1:6028bc22d82f 114 return success;
vargham 1:6028bc22d82f 115 }
vargham 1:6028bc22d82f 116
vargham 1:6028bc22d82f 117 bool EERAM::recall(bool block)
vargham 1:6028bc22d82f 118 {
vargham 1:6028bc22d82f 119 bool success = writeRegister(REGISTER_COMMAND, COMMAND_RECALL);
vargham 1:6028bc22d82f 120 if (success && block)
vargham 1:6028bc22d82f 121 {
vargham 1:6028bc22d82f 122 isReady((_memorySize <= 512 ? TIME_RECALL_04_MS: TIME_RECALL_16_MS) * 2);
vargham 1:6028bc22d82f 123 }
vargham 1:6028bc22d82f 124 return success;
vargham 1:6028bc22d82f 125 }
vargham 1:6028bc22d82f 126
vargham 1:6028bc22d82f 127 bool EERAM::readStatus()
vargham 1:6028bc22d82f 128 {
vargham 1:6028bc22d82f 129 _i2c.start();
vargham 1:6028bc22d82f 130 bool success = _i2c.write(_controlAddressRead) == 1;
vargham 1:6028bc22d82f 131 if (success)
vargham 1:6028bc22d82f 132 {
vargham 1:6028bc22d82f 133 _status = _i2c.read(false);
vargham 1:6028bc22d82f 134 _statusToWrite = _status;
vargham 1:6028bc22d82f 135 }
vargham 1:6028bc22d82f 136 _i2c.stop();
vargham 1:6028bc22d82f 137 return success;
vargham 1:6028bc22d82f 138 }
vargham 1:6028bc22d82f 139
vargham 1:6028bc22d82f 140 bool EERAM::writeStatus(bool block)
vargham 0:19f9af07424a 141 {
vargham 1:6028bc22d82f 142 bool success = writeRegister(REGISTER_STATUS, _statusToWrite);
vargham 1:6028bc22d82f 143 if (success)
vargham 1:6028bc22d82f 144 {
vargham 1:6028bc22d82f 145 _status = _statusToWrite;
vargham 1:6028bc22d82f 146 if (block) isReady(TIME_STORE_STATUS_MS * 2);
vargham 1:6028bc22d82f 147 }
vargham 1:6028bc22d82f 148 return success;
vargham 1:6028bc22d82f 149 }
vargham 1:6028bc22d82f 150
vargham 1:6028bc22d82f 151 void EERAM::writeStatusIfChanged(bool block)
vargham 1:6028bc22d82f 152 {
vargham 1:6028bc22d82f 153 if (_statusToWrite != _status) writeStatus(block);
vargham 1:6028bc22d82f 154 }
vargham 1:6028bc22d82f 155
vargham 1:6028bc22d82f 156 void EERAM::setProtectedMemoryArea(ProtectedMemoryArea protectedMemoryArea, bool store)
vargham 1:6028bc22d82f 157 {
vargham 1:6028bc22d82f 158 const uint8_t mask = 0b00011100;
vargham 1:6028bc22d82f 159 _statusToWrite = (_statusToWrite & ~mask) | ((protectedMemoryArea << 2) & mask);
vargham 1:6028bc22d82f 160 if (store) writeStatusIfChanged(false);
vargham 1:6028bc22d82f 161 }
vargham 1:6028bc22d82f 162
vargham 1:6028bc22d82f 163 ProtectedMemoryArea EERAM::getProtectedMemoryArea()
vargham 1:6028bc22d82f 164 {
vargham 1:6028bc22d82f 165 return (ProtectedMemoryArea) ((_status >> 2) & ~(-1 << 3));
vargham 1:6028bc22d82f 166 }
vargham 1:6028bc22d82f 167
vargham 1:6028bc22d82f 168 bool EERAM::isMemoryModified()
vargham 1:6028bc22d82f 169 {
vargham 1:6028bc22d82f 170 return (_status >> STATUS_AM_BIT) & 1;
vargham 1:6028bc22d82f 171 }
vargham 1:6028bc22d82f 172
vargham 1:6028bc22d82f 173 void EERAM::setAutoStoreEnabled(bool enabled, bool store)
vargham 1:6028bc22d82f 174 {
vargham 1:6028bc22d82f 175 _statusToWrite ^= (-enabled ^ _statusToWrite) & (1 << STATUS_ASE_BIT);
vargham 1:6028bc22d82f 176 if (store) writeStatusIfChanged(false);
vargham 1:6028bc22d82f 177 }
vargham 1:6028bc22d82f 178
vargham 1:6028bc22d82f 179 bool EERAM::isAutoStoreEnabled()
vargham 1:6028bc22d82f 180 {
vargham 1:6028bc22d82f 181 return (_status >> STATUS_ASE_BIT) & 1;
vargham 0:19f9af07424a 182 }
vargham 0:19f9af07424a 183
vargham 1:6028bc22d82f 184 void EERAM::setEventDetected(bool detected, bool store)
vargham 1:6028bc22d82f 185 {
vargham 1:6028bc22d82f 186 _statusToWrite ^= (-detected ^ _statusToWrite) & (1 << STATUS_EVENT_BIT);
vargham 1:6028bc22d82f 187 if (store) writeStatusIfChanged(false);
vargham 1:6028bc22d82f 188 }
vargham 1:6028bc22d82f 189
vargham 1:6028bc22d82f 190 bool EERAM::isEventDetected()
vargham 0:19f9af07424a 191 {
vargham 1:6028bc22d82f 192 return (_status >> STATUS_EVENT_BIT) & 1;
vargham 1:6028bc22d82f 193 }
vargham 0:19f9af07424a 194
vargham 1:6028bc22d82f 195 bool EERAM::isReady()
vargham 1:6028bc22d82f 196 {
vargham 1:6028bc22d82f 197 bool ready = false;
vargham 1:6028bc22d82f 198 _i2c.start();
vargham 1:6028bc22d82f 199 ready = _i2c.write(_controlAddressWrite) == 1;
vargham 1:6028bc22d82f 200 _i2c.stop();
vargham 1:6028bc22d82f 201 return ready;
vargham 1:6028bc22d82f 202 }
vargham 0:19f9af07424a 203
vargham 1:6028bc22d82f 204 bool EERAM::isReady(int timeout_ms)
vargham 1:6028bc22d82f 205 {
vargham 1:6028bc22d82f 206 bool ready = false;
vargham 1:6028bc22d82f 207 Timer timeoutTimer;
vargham 1:6028bc22d82f 208 timeoutTimer.start();
vargham 1:6028bc22d82f 209 while (!ready && timeoutTimer.read_ms() < timeout_ms)
vargham 1:6028bc22d82f 210 {
vargham 1:6028bc22d82f 211 ready = isReady();
vargham 1:6028bc22d82f 212 if (ready)
vargham 1:6028bc22d82f 213 {
vargham 1:6028bc22d82f 214 break;
vargham 1:6028bc22d82f 215 }
vargham 1:6028bc22d82f 216 }
vargham 1:6028bc22d82f 217 return ready;
vargham 1:6028bc22d82f 218 }
vargham 0:19f9af07424a 219
vargham 1:6028bc22d82f 220 void EERAM::dump(Serial &serial, uint16_t start, uint16_t length, int lineSize)
vargham 1:6028bc22d82f 221 {
vargham 1:6028bc22d82f 222 const int lineMaxSize = 32;
vargham 1:6028bc22d82f 223 if (!checkAddressRange(start, length) || lineSize > lineMaxSize)
vargham 1:6028bc22d82f 224 {
vargham 1:6028bc22d82f 225 serial.printf("Invalid parameters for memory dump.\r\n");
vargham 1:6028bc22d82f 226 return;
vargham 1:6028bc22d82f 227 }
vargham 1:6028bc22d82f 228 if (!setMemoryPointer(start, true))
vargham 1:6028bc22d82f 229 {
vargham 1:6028bc22d82f 230 serial.printf("Could not set start address for memory dump.\r\n");
vargham 1:6028bc22d82f 231 return;
vargham 1:6028bc22d82f 232 }
vargham 1:6028bc22d82f 233 char buffer[lineMaxSize];
vargham 1:6028bc22d82f 234 int lastLineLength = length % lineSize;
vargham 1:6028bc22d82f 235 int segments = length / lineSize + (lastLineLength > 0 ? 1 : 0);
vargham 1:6028bc22d82f 236 lastLineLength = lastLineLength == 0 ? lineSize : lastLineLength;
vargham 1:6028bc22d82f 237 for (int i = 0; i < segments; i++)
vargham 1:6028bc22d82f 238 {
vargham 1:6028bc22d82f 239 serial.printf("%.4X", start + lineSize * i);
vargham 1:6028bc22d82f 240 _i2c.read(_sramAddressRead, buffer, lineSize, false);
vargham 1:6028bc22d82f 241 for (int j = 0; j < (i == segments - 1 ? lastLineLength : lineSize); j++)
vargham 1:6028bc22d82f 242 {
vargham 1:6028bc22d82f 243 serial.printf(" %.2X", buffer[j]);
vargham 1:6028bc22d82f 244 }
vargham 1:6028bc22d82f 245 serial.printf("\r\n");
vargham 1:6028bc22d82f 246 }
vargham 1:6028bc22d82f 247 }
vargham 0:19f9af07424a 248
vargham 1:6028bc22d82f 249 void EERAM::dump(Serial &serial)
vargham 1:6028bc22d82f 250 {
vargham 1:6028bc22d82f 251 dump(serial, 0, _memorySize);
vargham 1:6028bc22d82f 252 }
vargham 1:6028bc22d82f 253
vargham 1:6028bc22d82f 254 bool EERAM::setMemoryPointer(uint16_t address, bool stop)
vargham 1:6028bc22d82f 255 {
vargham 1:6028bc22d82f 256 MemoryAddress location;
vargham 1:6028bc22d82f 257 location.address = address;
vargham 2:bdbf9de0e985 258 return setMemoryPointer(location.bytes[0], location.bytes[1], stop);
vargham 2:bdbf9de0e985 259 }
vargham 2:bdbf9de0e985 260
vargham 2:bdbf9de0e985 261 bool EERAM::setMemoryPointer(uint8_t address_0, uint8_t address_1, bool stop)
vargham 2:bdbf9de0e985 262 {
vargham 2:bdbf9de0e985 263 int result = 0;
vargham 1:6028bc22d82f 264 _i2c.start();
vargham 1:6028bc22d82f 265 result = _i2c.write(_sramAddressWrite);
vargham 2:bdbf9de0e985 266 if (result == 1) result = _i2c.write(address_1);
vargham 2:bdbf9de0e985 267 if (result == 1) result = _i2c.write(address_0);
vargham 1:6028bc22d82f 268 if (stop) _i2c.stop();
vargham 1:6028bc22d82f 269 return result == 1;
vargham 1:6028bc22d82f 270 }
vargham 1:6028bc22d82f 271
vargham 1:6028bc22d82f 272 bool EERAM::fillMemory(uint16_t address, char data, int length)
vargham 1:6028bc22d82f 273 {
vargham 1:6028bc22d82f 274 int result = 0;
vargham 1:6028bc22d82f 275 result = setMemoryPointer(address, false) ? 1 : 0;
vargham 1:6028bc22d82f 276 int index = 0;
vargham 1:6028bc22d82f 277 while (index < length && result == 1)
vargham 1:6028bc22d82f 278 {
vargham 1:6028bc22d82f 279 result = _i2c.write(data);
vargham 1:6028bc22d82f 280 index++;
vargham 1:6028bc22d82f 281 }
vargham 1:6028bc22d82f 282 _i2c.stop();
vargham 1:6028bc22d82f 283 return result == 1;
vargham 1:6028bc22d82f 284 }
vargham 0:19f9af07424a 285
vargham 1:6028bc22d82f 286 bool EERAM::fillMemory(char data)
vargham 1:6028bc22d82f 287 {
vargham 1:6028bc22d82f 288 return fillMemory(0, data, _memorySize);
vargham 1:6028bc22d82f 289 }
vargham 1:6028bc22d82f 290
vargham 1:6028bc22d82f 291 void EERAM::dumpRegisters(Serial &serial)
vargham 1:6028bc22d82f 292 {
vargham 2:bdbf9de0e985 293 serial.printf("Status Register Contents\r\n");
vargham 1:6028bc22d82f 294 serial.printf("Event detected: %d\r\n", isEventDetected());
vargham 1:6028bc22d82f 295 serial.printf("Auto Store Enabled: %d\r\n", isAutoStoreEnabled());
vargham 1:6028bc22d82f 296 serial.printf("Protected area: %d = ", getProtectedMemoryArea());
vargham 1:6028bc22d82f 297 switch (getProtectedMemoryArea())
vargham 0:19f9af07424a 298 {
vargham 1:6028bc22d82f 299 case NONE:
vargham 1:6028bc22d82f 300 serial.printf("None");
vargham 1:6028bc22d82f 301 break;
vargham 1:6028bc22d82f 302 case U64:
vargham 1:6028bc22d82f 303 serial.printf("U64");
vargham 1:6028bc22d82f 304 break;
vargham 1:6028bc22d82f 305 case U32:
vargham 1:6028bc22d82f 306 serial.printf("U32");
vargham 1:6028bc22d82f 307 break;
vargham 1:6028bc22d82f 308 case U16:
vargham 1:6028bc22d82f 309 serial.printf("U16");
vargham 1:6028bc22d82f 310 break;
vargham 1:6028bc22d82f 311 case U8:
vargham 1:6028bc22d82f 312 serial.printf("U8");
vargham 1:6028bc22d82f 313 break;
vargham 1:6028bc22d82f 314 case U4:
vargham 1:6028bc22d82f 315 serial.printf("U4");
vargham 1:6028bc22d82f 316 break;
vargham 1:6028bc22d82f 317 case U2:
vargham 1:6028bc22d82f 318 serial.printf("U2");
vargham 1:6028bc22d82f 319 break;
vargham 1:6028bc22d82f 320 case ALL:
vargham 1:6028bc22d82f 321 serial.printf("All");
vargham 1:6028bc22d82f 322 break;
vargham 0:19f9af07424a 323 }
vargham 0:19f9af07424a 324 serial.printf("\r\n");
vargham 1:6028bc22d82f 325 serial.printf("Memory Array Modified: %d\r\n", isMemoryModified());
vargham 0:19f9af07424a 326 }