We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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.