Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:19f9af07424a, committed 2017-04-25
- Comitter:
- vargham
- Date:
- Tue Apr 25 15:05:37 2017 +0000
- Child:
- 1:6028bc22d82f
- Commit message:
- EERAM initial commit
Changed in this revision
| EERAM.cpp | Show annotated file Show diff for this revision Revisions of this file |
| EERAM.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/EERAM.cpp Tue Apr 25 15:05:37 2017 +0000
@@ -0,0 +1,144 @@
+/**
+* @file eeram_main.cpp
+* @brief Example program 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.
+*/
+
+#include "mbed.h"
+#include "EERAM.h"
+
+#define PIN_I2C_SDA PC_9
+#define PIN_I2C_SCL PA_8
+
+#define I2C_FREQUENCY 1000000
+
+Serial serial(PA_9, PA_10); //Tx, Rx
+I2C i2c(PIN_I2C_SDA, PIN_I2C_SCL); //SDA, SCL
+EERAM eeram(i2c, 2048);
+
+void printI2C()
+{
+ //0x41 Discovery Touch
+ //0x18 EERAM control
+ //0x50 EERAM memory
+
+ int error;
+ int address;
+ int nDevices = 0;
+
+ serial.printf("Scanning I2C devices...\r\n");
+
+ for(address = 1; address < 127; address++ )
+ {
+ i2c.start();
+ error = i2c.write(address << 1); //We shift it left because mbed takes in 8 bit addreses
+ i2c.stop();
+ if (error == 1)
+ {
+ serial.printf("I2C device found at address 0x%X\r\n", address); //Returns 7-bit addres
+ nDevices++;
+ }
+
+ }
+ serial.printf("I2C scan finished.\r\n");
+ if (nDevices == 0)
+ {
+ serial.printf("No I2C devices found.\r\n");
+ }
+
+}
+
+void fillTestData(char data[], uint8_t start, int length)
+{
+ for (int i = 0; i < length; i++) data[i] = start + i;
+}
+
+void eeramDataTest()
+{
+ const int testDataLength = 16;
+ char data[testDataLength];
+
+ //Write
+ //eeram.fillMemory(0xFF);
+
+ fillTestData(data, 0x0, testDataLength);
+ serial.printf("Write %d bytes to 0x0: %d\r\n", testDataLength, eeram.write(0x0, data, testDataLength));
+
+ fillTestData(data, 0x50, testDataLength);
+ serial.printf("Write %d bytes to 0x500: %d\r\n", testDataLength, eeram.write(0x500, data, testDataLength));
+
+ fillTestData(data, 0x70, testDataLength);
+ serial.printf("Write %d bytes to 0x700: %d\r\n", testDataLength, eeram.write(0x700, data, testDataLength));
+
+ //Dump
+ serial.printf("Dump contents 0x0, 16\r\n");
+ eeram.dump(serial, 0x0, testDataLength);
+ serial.printf("Dump contents 0x500, 16\r\n");
+ eeram.dump(serial, 0x500, testDataLength);
+ serial.printf("Dump contents 0x700, 16\r\n");
+ eeram.dump(serial, 0x700, testDataLength);
+ //serial.printf("Dump all\r\n");
+ //eeram.dump(serial);
+ serial.printf("Dump done\r\n");
+
+ //Read back
+ fillTestData(data, 0x0, testDataLength);
+ serial.printf("Read back 16 bytes from 0x500: %d\r\n", eeram.read(0x500, data, testDataLength));
+ serial.printf("%.4X ", 0x500);
+ for (int i = 0; i < testDataLength; i++)
+ {
+ serial.printf("%.2X ", data[i]);
+ }
+ serial.printf("\r\n");
+}
+
+void eeramRegisterTest()
+{
+ eeram.dumpRegisters(serial);
+}
+
+int main()
+{
+ serial.baud(460800);
+ i2c.frequency(I2C_FREQUENCY); //Hz
+ serial.printf("\r\nI2C EERAM example\r\n");
+
+ //printI2C();
+
+ serial.printf("Is EERAM device ready?\r\n");
+ while (!eeram.isReady());
+ serial.printf("Device is ready.\r\n");
+
+ eeram.readStatus();
+ eeram.setAutoStoreEnabled(true);
+ eeram.setProtectedMemoryArea(U64);
+ eeram.writeStatusIfChanged(true);
+ serial.printf("Status: %.2X\r\n", eeram.getStatus());
+
+ eeramDataTest();
+
+ eeramRegisterTest();
+
+ //eeram.store(true);
+ //eeram.recall(true);
+
+ while (true)
+ {
+
+ }
+}
--- /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