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

Dependents:   EERAM_example

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