Driver library for Microchip I2C EERAM (47x04 and 47x16) 4 kbit or 16 kbit EEPROM backed SRAM.
Diff: EERAM.h
- Revision:
- 0:19f9af07424a
- Child:
- 2:bdbf9de0e985
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EERAM.h Tue Apr 25 15:05:37 2017 +0000 @@ -0,0 +1,315 @@ +/** +* @file EERAM.h +* @brief mbed driver for Microchip I2C EERAM devices (47x04 and 47x16) +* @author Mark Peter Vargha, vmp@varghamarkpeter.hu +* @version 1.0.0 +* +* Copyright (c) 2017 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef EERAM_h +#define EERAM_h + +#include "mbed.h" + +//#define DEBUG_EERAM + +#ifdef DEBUG_EERAM +extern Serial serial; +#endif + +union MemoryAddress +{ + uint16_t address; + char bytes[2]; +}; + +enum ProtectedMemoryArea +{ + NONE = 0, U64, U32, U16, U8, U4, U2, ALL +}; + +/** An I2C EERAM interface to communicate with Microchip 47x04 and 47x16 devices +* 4 kbit (512 byte) or 16 kbit (2048 byte) EEPROM backed I2C SRAM +* The device could detect power down and stores SRAM contents in EEPROM. The SRAM is recalled from EEPROM on power up. +* +* <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/20005371C.pdf">47x04 and 47x16 datasheet</a> +* <a href="http://ww1.microchip.com/downloads/cn/AppNotes/cn588417.pdf">Recommended Usage of Microchip I2C EERAM Devices</a> +* <a href="http://ww1.microchip.com/downloads/en/AppNotes/00002257A.pdf">Choosing the Right EERAM VCAP Capacitor</a> +* +* Example: +* @code +#include "mbed.h" +#include "EERAM.h" + +EERAM eeram(I2C_SDA, I2C_SCL, 2048); + +int main() +{ + if (!eeram.isReady(100)) //Checks device with 100 ms timeout + { + printf("Device is not present."); + while (1); + } + eeram.readStatus(); //Reads status register + eeram.setAutoStoreEnabled(true, true); //Set auto store on power down to true and stores if not stored before + while (1) + { + char dataStore[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + eeram.write(0x100, dataStore, 16); //We can not wear EEPROM out, so it is ok to write data to the device frequently. + wait(2.0); + char dataRead[16]; + eeram.read(0x100, dataRead, 16); + wait(2.0); + } +} + +* @endcode +*/ +class EERAM +{ + +public: + + /** Create an I2C EERAM interface, connected to the specified pins, with specified size and with the specified address pins + * @param SDA I2C data line pin + * @param SCL I2C clock line pin + * @param memorySize Size of EERAM, 512 for 47x04 and 2048 for 47x16 + * @param A1 EERAM A1 pin state (true = high, false = low) + * @param A2 EERAM A2 pin state (true = high, false = low) + */ + EERAM(PinName SDA, PinName SCL, uint16_t memorySize, bool A1 = false, bool A2 = false) : + _i2c(SDA, SCL), + _memorySize(memorySize) + { + initialize(A1, A2); + }; + + /** Create an I2C EERAM interface, connected to the I2C, with specified size and with the specified address pins + * @param 12c I2C + * @param memorySize Size of EERAM, 512 for 47x04 and 2048 for 47x16 + * @param A1 EERAM A1 pin state (true = high, false = low) + * @param A2 EERAM A2 pin state (true = high, false = low) + */ + EERAM(I2C &i2c, uint16_t memorySize, bool A1 = false, bool A2 = false) : + _i2c(i2c), + _memorySize(memorySize) + { + initialize(A1, A2); + }; + + /** Writes data to the specified address + * @param address The 16 bit destination address + * @param data Pointer to the data buffer to read from + * @param length Data length + * + * @return + * true on success + * false on fail + */ + bool write(uint16_t address, char *data, int length); + + /** Reads data from the specified address + * @param address The 16 bit source address + * @param data Pointer to the data buffer to read to + * @param length Data length + * + * @return + * true on success + * false on fail + */ + bool read(uint16_t address, char *data, int length); + + /** Fills memory with the specified byte from the specified address + * @param address The 16 bit destination address + * @param data The byte to write + * @param length Memory are to fill with the data byte + * + * @return + * true on success + * false on fail + */ + bool fillMemory(uint16_t address, char data, int length); + + /** Fills the whole memory with the specified byte + * @param data The byte to write + * + * @return + * true on success + * false on fail + */ + bool fillMemory(char data); + + /** Continuously checks I2C EERAM device till ready or reaches timeout + * @param timeout_ms Timeout for busy-wait I2C device polling + * + * @return + * true on ready + * false on timeout + */ + bool isReady(int timeout_ms); + + /** Checks I2C EERAM device one time + * + * @return + * true on ready + * false on not ready + */ + bool isReady(); + + /** Store SRAM in EEPROM + * @param block If true, busy waits for operation end. + * + * @return + * true on success + * false on fail + */ + bool store(bool block); + + /** Recall SRAM from EEPROM + * @param block If true, busy waits for operation end. + * + * @return + * true on success + * false on fail + */ + bool recall(bool block); + + /** Reads status register + * + * @return + * true on success + * false on fail + */ + bool readStatus(); + + /** Gets status register + * + * @return The content of the 8 bit status register + */ + inline uint8_t getStatus() const + { + return _status; + } + + /** Writes the 8 bit status register to the I2C device + * @param block If true, busy waits for operation end. + * + * @return + * true on success + * false on fail + */ + bool writeStatus(bool block); + + /** Writes the 8 bit status register to the I2C device if changed + * @param block If true, busy waits for operation end. + */ + void writeStatusIfChanged(bool block); + + /** Sets protected memory area. The selected area will be write protected. + * @param protectedMemoryArea The enum represents the area from NONE through upper 64, 32, 16, 8, 4, 2 to ALL + * @param store If true, calls writeStatusIfChanged() + */ + void setProtectedMemoryArea(ProtectedMemoryArea protectedMemoryArea, bool store = false); + + /** Gets protected memory area + * Have to call readStatus() to read register's fresh value. + */ + ProtectedMemoryArea getProtectedMemoryArea(); + + /** Gets Memory Modified + * Have to call readStatus() to read register's fresh value. + * @return + * true The SRAM memory have been modified since the last store or recall operation + * false The SRAM memory have not been modified since the last store or recall operation + */ + bool isMemoryModified(); + + /** Sets Auto Store Enabled + * @param enabled Auto store SRAM to EEPROM on power down enabled + * @param store If true, calls writeStatusIfChanged() + */ + void setAutoStoreEnabled(bool enabled, bool store = false); + + /** Gets Auto Store Enabled + * Have to call readStatus() to read register's fresh value. + * @return + * true Auto Store is Enabled + * false Auto Store is not Enabled + */ + bool isAutoStoreEnabled(); + + /** Sets event detected + * @param detected The value of the detected bit + * @param store If true, calls writeStatusIfChanged() + */ + void setEventDetected(bool detected, bool store); + + /** Gets event detected + * Have to call readStatus() to read register's fresh value. + * @return + * true External store event detected (The HS pin pulled up) + * false External event not detected + */ + bool isEventDetected(); + + /** Prints the SRAM content from the given address to the given serial port in human readable format in 1-32 byte long lines + * @param serial The port to print to + */ + void dump(Serial &serial, uint16_t start, uint16_t length, int lineSize = 16); + + /** Prints the whole SRAM content to the given serial port in human readable format in 16 byte long lines + * @param serial The port to print to + */ + void dump(Serial &serial); + + /** Prints the 8 bit status register's contents to the given serial port in human readable format + * @param serial The port to print to + */ + void dumpRegisters(Serial &serial); + +private: + static const uint8_t RW_BIT = 0; + static const uint8_t A1_BIT = 2; + static const uint8_t A2_BIT = 3; + static const uint8_t STATUS_AM_BIT = 7; + static const uint8_t STATUS_ASE_BIT = 1; + static const uint8_t STATUS_EVENT_BIT = 0; + static const uint8_t OPCODE_SRAM = 0b10100000; + static const uint8_t OPCODE_CONTROL = 0b00110000; + static const uint8_t REGISTER_STATUS = 0x0; + static const uint8_t REGISTER_COMMAND = 0x55; + static const uint8_t COMMAND_STORE = 0b00110011; + static const uint8_t COMMAND_RECALL = 0b11011101; + static const int TIME_RECALL_16_MS = 5; + static const int TIME_RECALL_04_MS = 2; + static const int TIME_STORE_16_MS = 25; + static const int TIME_STORE_04_MS = 8; + static const int TIME_STORE_STATUS_MS = 1; + I2C _i2c; + uint16_t _memorySize; + uint8_t _sramAddressWrite; + uint8_t _sramAddressRead; + uint8_t _controlAddressWrite; + uint8_t _controlAddressRead; + uint8_t _status; + uint8_t _statusToWrite; + void initialize(bool A1 = false, bool A2 = false); + bool checkAddressRange(uint16_t start, uint16_t length); + bool writeRegister(uint8_t registerAddress, uint8_t data); + bool setMemoryPointer(uint16_t address, bool stop = true); +}; + +#endif //EERAM_h