#Talking to a I2C EEPROM using the STM32 HAL libraries
This mostly a note to my future self. This code is based on the excellent answers provided at the ST forums, but combined here as a complete class. This was used to talk to a standard I2C EEPROM, 24LC256. The following header file definitions are required for the class :
#define EEPROM_ADDRESS 0xA0
#define EEPROM_MAXPKT 32 //(page size)
#define EEPROM_WRITE 10 //time to wait in ms
#define EEPROM_TIMEOUT 5*EEPROM_WRITE //timeout while writing
#define EEPROM_SECTIONSIZE 64
These setup the I2C address, the maximum page size of the EEPROM (32 used here for compadability). along with the timeouts. Section size is used internally similar to a ‘bucket’ that each object stored, is stored in.
Below follow the class functions used for accesing the memory.
void Eeprom::begin(I2C_HandleTypeDef* i2cPort)
{
//init the eeprom object
i2c_port = i2cPort;
}
//This is basically just a nicer wrapper
void Eeprom::readObject(structObject* settings, int section)
{
//Read a screen settings object from eeprom
readEEPROM(section * EEPROM_SECTIONSIZE, (uint8_t*) settings, sizeof(StructObject));
}
void Eeprom::saveObject(structObject* settings, int section)
{
writeEEPROM(section * EEPROM_SECTIONSIZE, (uint8_t*) settings, sizeof(StructObject));
}
HAL_StatusTypeDef Eeprom::readEEPROM(uint16_t address, uint8_t* MemTarget,
uint16_t Size)
{
uint16_t Counter = 0;
HAL_StatusTypeDef Result = HAL_OK;
while (Counter < Size && Result == HAL_OK)
{
uint16_t Diff = Size - Counter;
if (Diff >= EEPROM_MAXPKT)
{
//Multi-Byte
Result = HAL_I2C_Mem_Read(i2c_port, EEPROM_ADDRESS,
address + Counter, I2C_MEMADD_SIZE_16BIT,
&MemTarget[Counter], EEPROM_MAXPKT, EEPROM_TIMEOUT);
Counter += EEPROM_MAXPKT;
}
else
{
//and the remaining ones...low packet size
Result = HAL_I2C_Mem_Read(i2c_port, EEPROM_ADDRESS,
address + Counter, I2C_MEMADD_SIZE_16BIT,
&MemTarget[Counter], Diff, EEPROM_TIMEOUT);
Counter += Diff;
}
HAL_Delay(EEPROM_WRITE / 2);
}
return Result;
}
HAL_StatusTypeDef Eeprom::writeEEPROM(uint16_t address, uint8_t* MemTarget,
uint16_t Size)
{
uint16_t Counter = 0;
HAL_StatusTypeDef Result = HAL_OK;
while (Counter < Size && Result == HAL_OK)
{
uint16_t Diff = Size - Counter;
if (Diff >= EEPROM_MAXPKT)
{
//Multi-Byte
Result = HAL_I2C_Mem_Write(i2c_port, EEPROM_ADDRESS,
address + Counter, I2C_MEMADD_SIZE_16BIT,
&MemTarget[Counter], EEPROM_MAXPKT, EEPROM_TIMEOUT);
Counter += EEPROM_MAXPKT;
}
else
{
//and the remaining ones...low packet size
Result = HAL_I2C_Mem_Write(i2c_port, EEPROM_ADDRESS,
address + Counter, I2C_MEMADD_SIZE_16BIT,
&MemTarget[Counter], Diff, EEPROM_TIMEOUT);
Counter += Diff;
}
HAL_Delay(EEPROM_WRITE);
}
return Result;
}