danstm
danstm

Reputation: 53

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?

Upvotes: 3

Views: 3111

Answers (1)

Bence Kaulics
Bence Kaulics

Reputation: 7271

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

Upvotes: 6

Related Questions