Ben Brown bio photo

Ben Brown

Electronics and Embedded Systems Engineering

Email Twitter Facebook Github

Contents

#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;
}