I am writing some embedded code to interface with an external device over SPI. The device has several registers of varying length and to help keep things straight I have defined the following structure
typedef struct
{
uint16_t Signed :1; // Register is signed or unsigned
uint16_t CommLengthBytes :3; // The width of the register in bytes
uint16_t Address :12; // Register address
}ts_register;
I have then defined each register in my sources as follows
static const ts_register SAGCYC = {0, 1, 0x000};
static const ts_register DISNOLOAD = {0, 1, 0x001};
static const ts_register LCYCMODE = {0, 1, 0x004};
static const ts_register IRMSA = {0, 4, 0x31A};
static const ts_register IRMSB = {0, 4, 0x31B};
static const ts_register VRMS = {0, 4, 0x31C};
etc.
I have a function that will take a pointer to an array of ts_registers and queue up the SPI transfers required to read all of the registers in the array and call a callback function to handle the reply
My issue comes when I try to make the array of ts_registers that I want to read as follows:
ts_register regs_to_read[3] = {VRMS, IRMSA, IRMSB};
This generates the error: "expression must have a constant value" 3 times (once per array element).
Since they are defined as constants, what have I overlooked?
Since they are defined as constants, what have I overlooked?
In C objects declared with the const
modifier aren't true constants. A better name for const would probably be readonly
- what it really means is that the compiler won't let you change it. And you need true constants to initialize objects with static storage (I suspect regs_to_read
is global).
You could try assigning regs_to_read
in a function called before anything else uses that array.
const doesn't make them constants at compile time. Make them #defines and the compiler
will be happy.
I think this may be a compiler issue, and it would be helpful to know your platform and how you are building this code. I just took most of your code, doctored it up to compile it, and compiled on Linux using gcc. There were no warnings.
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
typedef struct
{
uint16_t Signed :1; // Register is signed or unsigned
uint16_t CommLengthBytes :3; // The width of the register in bytes
uint16_t Address :12; // Register address
}ts_register;
int main(int argc, char **argv) {
static const ts_register SAGCYC = {0, 1, 0x000};
static const ts_register DISNOLOAD = {0, 1, 0x001};
static const ts_register LCYCMODE = {0, 1, 0x004};
static const ts_register IRMSA = {0, 4, 0x31A};
static const ts_register IRMSB = {0, 4, 0x31B};
static const ts_register VRMS = {0, 4, 0x31C};
ts_register regs_to_read[3] = {VRMS, IRMSA, IRMSB};
return(0);
}
Have you tried casting the values? It's not always the best thing to do, but will get you around the error.
Have you considered creating #define entries?
Also, please be aware consts take a bit of getting used to in C. They do not always behave the way you might expect.