Class to provide simple access to I2C EEPROM chiles like Microchip's 24LC range or AMTELS AT24C range. Chips up to 64Kb in size are directly supported. Updated to Mbed OS v 5.1

Dependents:   storage_test

Revision:
12:d9a44fb3b9a6
Parent:
4:d8f51b136dbd
--- a/I2CEeprom.cpp	Sat Mar 28 17:01:58 2020 +0000
+++ b/I2CEeprom.cpp	Sat Mar 28 18:03:39 2020 +0000
@@ -22,6 +22,7 @@
 namespace
 {
 
+//return true if system is little-endian
 inline bool little_endian()
 {
     int n = 1;
@@ -29,6 +30,8 @@
     return(*(char *)&n == 1);
 }
 
+// Put EEprom address into 2 char array
+// in corrcet endiannness
 void convert_address(size_t const & addressIn, char* arOut)
 {
     constexpr size_t int_size = sizeof(size_t);
@@ -50,12 +53,12 @@
 }
 
 I2CEeprom::I2CEeprom(
-     I2C & i2c, 
-     int address, 
-     size_t pageSize, 
-     size_t chipSize,
-     uint8_t writeCycleTime_ms
-     ):
+    I2C & i2c,
+    int address,
+    size_t pageSize,
+    size_t chipSize,
+    uint8_t writeCycleTime_ms
+):
     m_i2c{i2c},
     m_i2cAddress(address),
     m_chipSize(chipSize),
@@ -65,14 +68,13 @@
 
 size_t I2CEeprom::read(size_t address, char &value)
 {
-    // Check the address and size fit onto the chip.
-    if (!checkSpace(address, 1))
-        return 0;
-    char values[2];
-    convert_address(address,values);
-    if (m_i2c.write(m_i2cAddress, values, 2) == 0) {
-        if (m_i2c.read(m_i2cAddress, &value, 1) == 0) {
-            return 1;
+    if (checkSpace(address, 1)) {
+        char values[2];
+        convert_address(address,values);
+        if (m_i2c.write(m_i2cAddress, values, 2) == 0) {
+            if (m_i2c.read(m_i2cAddress, &value, 1) == 0) {
+                return 1;
+            }
         }
     }
     return 0;
@@ -80,14 +82,13 @@
 
 size_t I2CEeprom::read(size_t address, char *buffer, size_t size)
 {
-    // Check the address and size fit onto the chip.
-    if (!checkSpace(address, size))
-        return 0;
-    char values[2];
-    convert_address(address,values);
-    if (m_i2c.write(m_i2cAddress, values, 2) == 0) {
-        if (m_i2c.read(m_i2cAddress, buffer, size) == 0) {
-            return size;
+    if (checkSpace(address, size)) {
+        char values[2];
+        convert_address(address,values);
+        if (m_i2c.write(m_i2cAddress, values, 2) == 0) {
+            if (m_i2c.read(m_i2cAddress, buffer, size) == 0) {
+                return size;
+            }
         }
     }
     return 0;
@@ -95,62 +96,62 @@
 
 size_t I2CEeprom::write(size_t address, char value)
 {
-    // Check the address and size fit onto the chip.
-    if (!checkSpace(address, 1))
-        return 0;
-    char values[3];
-    convert_address(address,values);
-    values[2] = value;
-    if (m_i2c.write(m_i2cAddress, values, 3) != 0) {
+    if (checkSpace(address, 1)) {
+        char values[3];
+        convert_address(address,values);
+        values[2] = value;
+        if (m_i2c.write(m_i2cAddress, values, 3) != 0) {
+            return 0;
+        }
+        waitForWrite();
+        return 1;
+    } else {
         return 0;
     }
-
-    waitForWrite();
-    return 1;
 }
 
 size_t I2CEeprom::ll_write(size_t address, const char *buffer, size_t size)
 {
-    // TODO: change i2c address bits dependent on eeprom data address
-    // if size > 64k I 
-    if (m_i2c.write(m_i2cAddress, buffer, size) != 0) {
+    if (m_i2c.write(m_i2cAddress, buffer, size) == 0) {
+        waitForWrite();
+        return size;
+    } else {
         std::cout << "EE i2c write failed\n";
         return 0;
     }
-    waitForWrite();
-    return size;
 }
 
 size_t I2CEeprom::write(size_t address, const char *buffer, size_t size)
 {
-    if (!checkSpace(address, size)) {
-        return 0;
-    }
-    size_t const malloc_size = std::min(size,m_pageSize) + 2U;
-    char * tempBuffer = new char [malloc_size];
-    if ( tempBuffer == nullptr){
-        std::cout << "EE i2c buf malloc failed\n";
+    if (checkSpace(address, size)) {
+        size_t const malloc_size = std::min(size,m_pageSize) + 2U;
+        char * tempBuffer = new char [malloc_size];
+        if ( tempBuffer == nullptr) {
+            std::cout << "EE i2c buf malloc failed\n";
+            return 0;
+        }
+        size_t bytesLeft = size;
+        size_t numBytesToWrite
+            = std::min( size, m_pageSize - (address % m_pageSize));
+        while( bytesLeft ) {
+            convert_address(address,tempBuffer);
+            memcpy(tempBuffer + 2,buffer, numBytesToWrite);
+            if ( ll_write(address,tempBuffer, numBytesToWrite + 2U)
+                    == numBytesToWrite + 2U) {
+                buffer += numBytesToWrite;
+                address += numBytesToWrite;
+                bytesLeft -= numBytesToWrite;
+                numBytesToWrite = std::min(bytesLeft,m_pageSize);
+            } else {
+                std::cout << "EE i2c write failed\n";
+                break;
+            }
+        }
+        delete [] tempBuffer;
+        return size - bytesLeft;
+    } else {
         return 0;
     }
-    size_t bytesLeft = size;
-    size_t numBytesToWrite
-        = std::min( size, m_pageSize - (address % m_pageSize)); 
-    while(bytesLeft) {
-        convert_address(address,tempBuffer);
-        memcpy(tempBuffer + 2,buffer, numBytesToWrite);
-        if ( ll_write(address,tempBuffer, numBytesToWrite + 2U)
-           == numBytesToWrite + 2U) {
-            buffer += numBytesToWrite;
-            address += numBytesToWrite;
-            bytesLeft -= numBytesToWrite;
-            numBytesToWrite = std::min(bytesLeft,m_pageSize);
-        } else {
-            std::cout << "EE i2c write failed\n";
-            break;
-        }
-    }
-    delete [] tempBuffer;
-    return size - bytesLeft;
 }
 
 void I2CEeprom::waitForWrite()
@@ -163,4 +164,3 @@
         ThisThread::sleep_for(1);
     }
 }
-