Search code examples
cpointersstructtypedefeeprom

Using a pointer to access typedef struct


Objective: Writing to an internal buffer from the values of members of a structure.

I have a structure that contains members of type Uint16 (unsigned int); here is a small portion of it:

typedef unsigned int    Uint16;
typedef struct 
{
    Uint16 ee_Speed_Control_Mode;
    Uint16 ee_Motor_Type;
    Uint16 ee_Max_Electrical_Speed;
    Uint16 ee_Carrier_Frequency;
    Uint16 ee_Rated_Motor_Frequency;
    Uint16 ee_Rated_Motor_Current;
    Uint16 ee_Rs; // extern
    Uint16 ee_Rr; // extern
    Uint16 ee_L_lkg; // extern
    Uint16 ee_Lm;    // extern
    Uint16 ee_No_Load_Current;
    Uint16 ee_Phase_Reversal;
    .....
    .....
} EEPROM_PARAMETERS;

EEPROM_PARAMETERS eepromParameters;

My attempt:

Here is a function that is intended to write to eeprom: (Most of it is not shown for simplicity; the focus is occurring in the 'for' loop

void eeprom_write(Uint16 address, Uint32 *data, Int16 len)
{
    Uint16 i;

    // Multiple bytes will be written
    // Page Write operation will be used
    // Page Write bits to be sent:

    // bit 0: Start condition, a high-to-low transition of SDA with SCL high
    startCondition();

    // bits 1-8: Device address
    I2caRegs.I2CDXR = DEVICE_ADDRESS_WRITE;

    // bit 9: EEPROM outputs 0 as ACK bit
    // Check for ACK bit
    while (I2caRegs.I2CDRR != 0)
    {
        wait();
    }

    // bits 10-17, bit 18 (ACK) and bits 19-26: two 8-bit word addresses
    I2caRegs.I2CDXR = address;

    // After setting the address, page write is capable of writing 64 bytes without stopping
    // The EEPROM will respond with a zero after each data word has been received
    // The data word address lower 6 bits are internally incremented following the receipt of each data word
    // If more than 64 data words are written, data word addresses will "roll over" and previous data will be overwritten

    for (i = 0; i < len; i++)
    {
        // How to increment address in data structure?
        I2caRegs.I2CDXR = *data++; 
    }

    // After page write operation is complete, execute stop condition
    stopCondition();
}

When I try to call this function with my parameters..

eeprom_write(0, &eepromParameters, sizeof(eepromParameters) );

I get a incompatible type error:

error #169: argument of type "EEPROM_PARAMETERS *" is incompatible with parameter of type "Uint16 *"

My next thought would be that I need a middle man to bring them together and make it a compatible match. Any tips please on what I can try? Thanks


Solution

  • The problem is the declaration and usage of data. If you declare it as

    void eeprom_write(Uint16 address, EEPROM_PARAMETERS* data, Int16 len);
    

    and call it as

    eeprom_write(0, &eepromParameters, sizeof(eepromParameters));
    

    It will fall over in

    *data++
    

    since it will increment by the size of EEPROM_PARAMTERS. If the prototype is declared as

    void eeprom_write(Uint16 address, UInt16* data, Int16 len);
    

    It needs to be called as

    eeprom_write(0, &eepromParameters.ee_Speed_Control_Mode, sizeof(eepromParameters) / sizeof(Uint16));
    

    This assumes that everything in EEPROM_PARAMETERS is Uint16. Another way of doing this is to use enums.

    enum EEOffsets
    {
        ee_Speed_Control_Mode,
        ee_Motor_Type,
        ee_Max_Electrical_Speed,
        ee_Carrier_Frequency,
        ...
        ee_Max
    };
    
    // Initialize the parameters
    Uint16 eepromParameters[ee_Max] = { ... };
    
    // If you need to assign
    eepromParameters[ee_Carrier_Frequency] = 85;
    ...
    eeprom_write(0, eepromParameters, ee_Max);