Search code examples
cstructstm32microcontrollereeprom

STM32F0 I2C HAL save struct to I2C EEPROM


I need to save a struct:

struct {
  uint16_t value;
  uint16_t flag;
} status;

into an external I2C EEPROM using

HAL_StatusTypeDef HAL_I2C_Mem_Write (I2C_HandleTypeDef * hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t * pData, uint16_t Size, uint32_t Timeout)

function

Can you suggest me a right way to do this?


Solution

  • If you look close all data types store simple bytes, the difference is how the bytes are interpreted.

    Basically you need an uint8_t* pData pointer to a buffer and the number of bytes to be transfered (uint16_t Size). So cast the struct pointer to uint8_t* and get the size using sizeof().

    Here is a simulation, and please forgive me my poor test environment (the ints and unsigned chars).

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct {
      int value;
      int flag;
    } status;
    
    int main(void) {
    
        status stat;
        stat.value = 15;
        stat.flag = 1;
    
        int size = sizeof(status);                            // number of bytes to be sent
        unsigned char* pData;                                 // (uint8_t*) unsigned char* pointer to data
    
        unsigned char eeprom[size];                           // simulated EEPROM
        unsigned char pDataReceived[size];                    // for read back from EEPROM test
        status* read_back;                                    // for read back from EEPROM test
    
        printf("%d %d\n", stat.value, stat.flag);             // verify data in original format
    
        pData = (unsigned char*)(&stat);                      // cast data pointer to (uint8_t*) unsigned char*
        printf("%d %d\n", ((status*)pData)->value, ((status*)pData)->flag);   // verify data after cast
    
        memcpy(eeprom, pData, size);                          // I2C write bytes simulation
        printf("%d %d\n", ((status*)eeprom)->value, ((status*)eeprom)->flag); // verify data in simulated EEPROM
    
        memcpy(pDataReceived, eeprom, size);                  // I2C read bytes simulation
        read_back = (status*)(pDataReceived);                 // cast back to struct type
        printf("%d %d\n", read_back->value, read_back->flag); // verify received data in original format
    
        return 0;
    }
    

    Write example:

    struct status stat;
    // operations on the struct
    uint8_t* addressOfStruct= (uint8_t*)(&stat);
    uint16_t sizeOfStruct  = sizeof(status);
    
    HAL_StatusTypeDef HAL_I2C_Mem_Write (&hi2c, DevAddress, MemAddress, MemAddSize, addressOfStruct, sizeOfStruct, 100);
    

    Read example:

    struct status* read;
    uint16_t sizeOfBuffer = sizeof(status);
    uint8_t receiveBuffer[sizeOfBuffer];
    
    HAL_StatusTypeDef HAL_I2C_Mem_Read (&hi2c, DevAddress, MemAddress, MemAddSize, receiveBuffer, sizeOfBuffer, 100);
    
    read = (status*)(receiveBuffer); // or copy or move the data