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;
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.