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
Diff: I2CEeprom.cpp
- 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); } } -