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 1:6028bc22d82f, committed 2017-04-25
- Comitter:
- vargham
- Date:
- Tue Apr 25 16:22:53 2017 +0000
- Parent:
- 0:19f9af07424a
- Child:
- 2:bdbf9de0e985
- Commit message:
- Fixed copy/paste example program error.
Changed in this revision
| EERAM.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/EERAM.cpp Tue Apr 25 15:05:37 2017 +0000
+++ b/EERAM.cpp Tue Apr 25 16:22:53 2017 +0000
@@ -1,6 +1,6 @@
/**
-* @file eeram_main.cpp
-* @brief Example program for Microchip I2C EERAM devices (47x04 and 47x16)
+* @file EERAM.cpp
+* @brief mbed driver for Microchip I2C EERAM devices (47x04 and 47x16)
* @author Mark Peter Vargha, vmp@varghamarkpeter.hu
* @version 1.0.0
*
@@ -19,126 +19,277 @@
* 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 EERAM::initialize(bool A1, bool A2)
+{
+ _sramAddressWrite = OPCODE_SRAM;
+ _sramAddressWrite ^= (-A1 ^ _sramAddressWrite) & (1 << A1_BIT);
+ _sramAddressWrite ^= (-A2 ^ _sramAddressWrite) & (1 << A2_BIT);
+ _sramAddressRead = _sramAddressWrite;
+ _sramAddressRead ^= (-true ^ _sramAddressRead) & (1 << RW_BIT);
-void printI2C()
+ _controlAddressWrite = OPCODE_CONTROL;
+ _controlAddressWrite ^= (-A1 ^ _controlAddressWrite) & (1 << A1_BIT);
+ _controlAddressWrite ^= (-A2 ^ _controlAddressWrite) & (1 << A2_BIT);
+ _controlAddressRead = _controlAddressWrite;
+ _controlAddressRead ^= (-true ^ _controlAddressWrite) & (1 << RW_BIT);
+}
+
+bool EERAM::checkAddressRange(uint16_t start, uint16_t length)
{
- //0x41 Discovery Touch
- //0x18 EERAM control
- //0x50 EERAM memory
-
- int error;
- int address;
- int nDevices = 0;
+ return start < _memorySize && start + length <= _memorySize && length > 0;
+}
- serial.printf("Scanning I2C devices...\r\n");
-
- for(address = 1; address < 127; address++ )
+bool EERAM::write(uint16_t address, char *data, int length)
+{
+ bool success = false;
+ success = checkAddressRange(address, length);
+ if (success) success = setMemoryPointer(address, false);
+ int index = 0;
+ while (index < length && success)
{
- 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++;
- }
+ success = _i2c.write(data[index]) == 1;
+ index++;
+ }
+ _i2c.stop();
+ return success;
+}
- }
- serial.printf("I2C scan finished.\r\n");
- if (nDevices == 0)
+bool EERAM::read(uint16_t address, char *data, int length)
+{
+ bool success = checkAddressRange(address, length);
+ if (success) success = setMemoryPointer(address, true);
+ if (success)
{
- serial.printf("No I2C devices found.\r\n");
+ success = _i2c.read(_sramAddressRead, data, length, false) == 0;
}
+ _i2c.stop();
+ return success;
+}
+bool EERAM::writeRegister(uint8_t registerAddress, uint8_t data)
+{
+ _i2c.start();
+ bool success = _i2c.write(_controlAddressWrite) == 1;
+ if (success) success = _i2c.write(registerAddress) == 1;
+ if (success) success = _i2c.write(data) == 1;
+ _i2c.stop();
+ return success;
}
-void fillTestData(char data[], uint8_t start, int length)
+bool EERAM::store(bool block)
+{
+ bool success = writeRegister(REGISTER_COMMAND, COMMAND_STORE);
+ if (success && block)
+ {
+ isReady((_memorySize <= 512 ? TIME_STORE_04_MS: TIME_STORE_16_MS) * 2);
+ }
+ return success;
+}
+
+bool EERAM::recall(bool block)
+{
+ bool success = writeRegister(REGISTER_COMMAND, COMMAND_RECALL);
+ if (success && block)
+ {
+ isReady((_memorySize <= 512 ? TIME_RECALL_04_MS: TIME_RECALL_16_MS) * 2);
+ }
+ return success;
+}
+
+bool EERAM::readStatus()
+{
+ _i2c.start();
+ bool success = _i2c.write(_controlAddressRead) == 1;
+ if (success)
+ {
+ _status = _i2c.read(false);
+ _statusToWrite = _status;
+ }
+ _i2c.stop();
+ return success;
+}
+
+bool EERAM::writeStatus(bool block)
{
- for (int i = 0; i < length; i++) data[i] = start + i;
+ bool success = writeRegister(REGISTER_STATUS, _statusToWrite);
+ if (success)
+ {
+ _status = _statusToWrite;
+ if (block) isReady(TIME_STORE_STATUS_MS * 2);
+ }
+ return success;
+}
+
+void EERAM::writeStatusIfChanged(bool block)
+{
+ if (_statusToWrite != _status) writeStatus(block);
+}
+
+void EERAM::setProtectedMemoryArea(ProtectedMemoryArea protectedMemoryArea, bool store)
+{
+ const uint8_t mask = 0b00011100;
+ _statusToWrite = (_statusToWrite & ~mask) | ((protectedMemoryArea << 2) & mask);
+ if (store) writeStatusIfChanged(false);
+}
+
+ProtectedMemoryArea EERAM::getProtectedMemoryArea()
+{
+ return (ProtectedMemoryArea) ((_status >> 2) & ~(-1 << 3));
+}
+
+bool EERAM::isMemoryModified()
+{
+ return (_status >> STATUS_AM_BIT) & 1;
+}
+
+void EERAM::setAutoStoreEnabled(bool enabled, bool store)
+{
+ _statusToWrite ^= (-enabled ^ _statusToWrite) & (1 << STATUS_ASE_BIT);
+ if (store) writeStatusIfChanged(false);
+}
+
+bool EERAM::isAutoStoreEnabled()
+{
+ return (_status >> STATUS_ASE_BIT) & 1;
}
-void eeramDataTest()
+void EERAM::setEventDetected(bool detected, bool store)
+{
+ _statusToWrite ^= (-detected ^ _statusToWrite) & (1 << STATUS_EVENT_BIT);
+ if (store) writeStatusIfChanged(false);
+}
+
+bool EERAM::isEventDetected()
{
- const int testDataLength = 16;
- char data[testDataLength];
+ return (_status >> STATUS_EVENT_BIT) & 1;
+}
- //Write
- //eeram.fillMemory(0xFF);
+bool EERAM::isReady()
+{
+ bool ready = false;
+ _i2c.start();
+ ready = _i2c.write(_controlAddressWrite) == 1;
+ _i2c.stop();
+ return ready;
+}
- fillTestData(data, 0x0, testDataLength);
- serial.printf("Write %d bytes to 0x0: %d\r\n", testDataLength, eeram.write(0x0, data, testDataLength));
+bool EERAM::isReady(int timeout_ms)
+{
+ bool ready = false;
+ Timer timeoutTimer;
+ timeoutTimer.start();
+ while (!ready && timeoutTimer.read_ms() < timeout_ms)
+ {
+ ready = isReady();
+ if (ready)
+ {
+ break;
+ }
+ }
+ return ready;
+}
- 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));
+void EERAM::dump(Serial &serial, uint16_t start, uint16_t length, int lineSize)
+{
+ const int lineMaxSize = 32;
+ if (!checkAddressRange(start, length) || lineSize > lineMaxSize)
+ {
+ serial.printf("Invalid parameters for memory dump.\r\n");
+ return;
+ }
+ if (!setMemoryPointer(start, true))
+ {
+ serial.printf("Could not set start address for memory dump.\r\n");
+ return;
+ }
+ char buffer[lineMaxSize];
+ int lastLineLength = length % lineSize;
+ int segments = length / lineSize + (lastLineLength > 0 ? 1 : 0);
+ lastLineLength = lastLineLength == 0 ? lineSize : lastLineLength;
+ for (int i = 0; i < segments; i++)
+ {
+ serial.printf("%.4X", start + lineSize * i);
+ _i2c.read(_sramAddressRead, buffer, lineSize, false);
+ for (int j = 0; j < (i == segments - 1 ? lastLineLength : lineSize); j++)
+ {
+ serial.printf(" %.2X", buffer[j]);
+ }
+ serial.printf("\r\n");
+ }
+}
- //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");
+void EERAM::dump(Serial &serial)
+{
+ dump(serial, 0, _memorySize);
+}
+
+bool EERAM::setMemoryPointer(uint16_t address, bool stop)
+{
+ int result = 0;
+ MemoryAddress location;
+ location.address = address;
+ _i2c.start();
+ result = _i2c.write(_sramAddressWrite);
+ if (result == 1) result = _i2c.write(location.bytes[1]);
+ if (result == 1) result = _i2c.write(location.bytes[0]);
+ if (stop) _i2c.stop();
+ return result == 1;
+}
+
+bool EERAM::fillMemory(uint16_t address, char data, int length)
+{
+ int result = 0;
+ result = setMemoryPointer(address, false) ? 1 : 0;
+ int index = 0;
+ while (index < length && result == 1)
+ {
+ result = _i2c.write(data);
+ index++;
+ }
+ _i2c.stop();
+ return result == 1;
+}
- //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++)
+bool EERAM::fillMemory(char data)
+{
+ return fillMemory(0, data, _memorySize);
+}
+
+void EERAM::dumpRegisters(Serial &serial)
+{
+ serial.printf("Control Register Contents\r\n");
+ serial.printf("Event detected: %d\r\n", isEventDetected());
+ serial.printf("Auto Store Enabled: %d\r\n", isAutoStoreEnabled());
+ serial.printf("Protected area: %d = ", getProtectedMemoryArea());
+ switch (getProtectedMemoryArea())
{
- serial.printf("%.2X ", data[i]);
+ case NONE:
+ serial.printf("None");
+ break;
+ case U64:
+ serial.printf("U64");
+ break;
+ case U32:
+ serial.printf("U32");
+ break;
+ case U16:
+ serial.printf("U16");
+ break;
+ case U8:
+ serial.printf("U8");
+ break;
+ case U4:
+ serial.printf("U4");
+ break;
+ case U2:
+ serial.printf("U2");
+ break;
+ case ALL:
+ serial.printf("All");
+ break;
}
serial.printf("\r\n");
-}
-
-void eeramRegisterTest()
-{
- eeram.dumpRegisters(serial);
+ serial.printf("Memory Array Modified: %d\r\n", isMemoryModified());
}
-
-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)
- {
-
- }
-}