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:
- 3:b2a132553b02
- Parent:
- 2:f3188aaccf80
- Child:
- 4:d8f51b136dbd
--- a/I2CEeprom.cpp Sat Mar 28 00:53:14 2020 +0000 +++ b/I2CEeprom.cpp Sat Mar 28 01:38:00 2020 +0000 @@ -113,23 +113,11 @@ 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 - // write 2 bytes ee address + data size - char* tempBuffer = new char [size + 2]; - if ( tempBuffer == nullptr) { - delete [] tempBuffer; - std::cout << "EE i2c write malloc buf failed \n"; - return 0; - } - convert_address(address,tempBuffer); - memcpy(tempBuffer+2,buffer,size); - - if (m_i2c.write(m_i2cAddress, tempBuffer, size+2) != 0) { - delete [] tempBuffer; + // if size > 64k I + if (m_i2c.write(m_i2cAddress, buffer, size) != 0) { std::cout << "EE i2c write failed\n"; return 0; } - delete [] tempBuffer; waitForWrite(); return size; } @@ -137,29 +125,39 @@ // ret num written size_t I2CEeprom::write(size_t address, const char *buffer, size_t size) { - // Check the address and size fit onto the chip. 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"; + return 0; + } size_t bytesLeft = size; size_t numBytesToWrite - = std::min( size, m_pageSize - (address % m_pageSize)); + = std::min( size, m_pageSize - (address % m_pageSize)); while(bytesLeft) { - if ( ll_write(address,buffer, numBytesToWrite) - == numBytesToWrite) { + 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() { + ThisThread::sleep_for(m_writeCycleTime_ms); // The chip doesn't ACK while writing to the actual EEPROM // so loop trying to do a zero byte write until it is ACKed