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

Dependents:   EERAM_example

Committer:
vargham
Date:
Sun Oct 29 18:31:47 2017 +0000
Revision:
7:038c52e2268b
Parent:
6:b3f9b29b07ba
Changed I2C pointer to reference.

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