This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Change from char array to int array R/W nvram over spi

I am having a problem with get and set nvram over a spi bus. The set function shown below has always worked with "Char array" and "int" types, but will not work with "int array'.

Thanks in advance for any help.



Call;

NewPreheatMinutes[3]

NVRAM_GetVariable(NVRAM_PREHEAT_MINUTES, NewPreheatMinutes);

Function definition:

void NVRAM_SetVariable(enum NVRAM_VARIABLE VariableID, void *Value)
{
char spi_buff[3];

case NVRAM_RETHERM_MINUTES:

spi_buff[0] = RethermMinutesByte0MsbAddr | WriteBit;
spi_buff[1] = (*(int*)(Value + 0) & 0xFF00) >> 8;
Spi_SendData(CLOCK, 2, spi_buff);

spi_buff[0] = RethermMinutesByte0LsbAddr | WriteBit;
spi_buff[1] = *(int*)(Value + 0) & 0xFF;
Spi_SendData(CLOCK, 2, spi_buff);

spi_buff[0] = RethermMinutesByte1MsbAddr | WriteBit;
spi_buff[1] = (*(int*)(Value + 1) & 0xFF00) >> 8;
Spi_SendData(CLOCK, 2, spi_buff);

spi_buff[0] = RethermMinutesByte1LsbAddr | WriteBit;
spi_buff[1] = *(int*)(Value + 1) & 0xFF;
Spi_SendData(CLOCK, 2, spi_buff);

spi_buff[0] = RethermMinutesByte2MsbAddr | WriteBit;
spi_buff[1] = (*(int*)(Value + 2) & 0xFF00) >> 8;
Spi_SendData(CLOCK, 2, spi_buff);

spi_buff[0] = RethermMinutesByte2LsbAddr | WriteBit;
spi_buff[1] = *(int*)(Value + 2) & 0xFF;
Spi_SendData(CLOCK, 2, spi_buff);

break;

Parents Reply Children
  • Or just change the precedence:

    *(((int *)Value)+1)

    or why not just change the function declaration to take a pointer to int?

    Stefan

  • Thank you for your input.

    These set and get functions must also work with types enum, char array, int. I cannot change the void.

  • "These set and get functions must also work with types enum, char array, int. I cannot change the void."

    In that case you'll have to add a parameter to specify the type and perform the appropriate cast within the function. eg:

    #define INT 1
    #define FLOAT 2
    etc

    void Func(int type, void *ptr)
    {
    int *intptr;
    float *floatptr;

    switch(type)
    {
    case INT:
    intptr=(int *)ptr;
    //Do int specific stuff here
    break;

    case FLOAT:
    floatptr=(float *)ptr;
    //Do float specific stuff here
    break;

    //etc
    }
    }

    Stefan

  • In C, adding "1" to a pointer does not increment the pointer to the next address (usually, adding a byte). It increments the pointer to point at the next whole object of the type pointed to, which may be several bytes wide. If you have an int* pi with value 0x1000, then (pi + 1) will be 0x1002, not 0x1001. (On Keil C, at least, sizeof(int) == 2. Other compilers will vary.)

    You can't do arithmetic on void pointers because there is no type pointed to. "void" does not have size 1, or even size 0. so "void* pv; p = p + 1;" has no meaning. Sizeof what times 1?

    If you are trying to manipulate generic objects of various types, then you will probably want to cast the void* to a U8*, and do all your arithmetic in bytes.

    This design is headed for roll-your-own object-oriented programming. What you're really trying to do is implement a serialization method for each of a number of different objects.

    I'd suggest making the variable ID list an enum, and using that enum as an index into a table of information about the variable (size and address). Then, the SPI functions can just be coded to send N bytes from address A, and use the values out of the table.

    If the serialization methods become very different, or the objects get complicated, you might wind up with a table of function pointers to handle individual objects.

    I notice the standards committee for the next round of C++ is discussing a typeof() operator. Maybe that will show up in C, as well.

  • Stefan,

    This is the fix!

    int *ptr;

    ptr=(int *)Value;

    Then replace all subsequent "Value" with "ptr".

    Thank You

    Mark