According to the i2C.h as follows:
/**
* @brief I2C initialization parameters
*/
typedef struct{
i2c_mode_t mode; /*!< I2C mode */
gpio_num_t sda_io_num; /*!< GPIO number for I2C sda signal */
gpio_pullup_t sda_pullup_en; /*!< Internal GPIO pull mode for I2C sda signal*/
gpio_num_t scl_io_num; /*!< GPIO number for I2C scl signal */
gpio_pullup_t scl_pullup_en; /*!< Internal GPIO pull mode for I2C scl signal*/
union {
struct {
uint32_t clk_speed; /*!< I2C clock frequency for master mode, (no higher than 1MHz for now) */
} master;
struct {
uint8_t addr_10bit_en; /*!< I2C 10bit address mode enable for slave mode */
uint16_t slave_addr; /*!< I2C address for slave mode */
} slave;
};
}i2c_config_t;
I wrote the following assignment:
const i2c_port_t i2c_master_port = (i2c_port_t)I2C_MASTER_NUM;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = (gpio_pullup_t)GPIO_PULLUP_ENABLE,
.scl_pullup_en = (gpio_pullup_t)GPIO_PULLUP_ENABLE,
.master = {.clk_speed = I2C_MASTER_FREQ_HZ},
};
Which reports 2 errors (sorry its in French so I added my own translation into English):
At line .sda_pullup_en (translated as: "Out-of-order initializers are not standard in C++"):
[{
"code": "2904",
"severity": 8,
"message": "les initialiseurs hors service ne sont pas standard en C++",
"source": "C/C++",
"startLineNumber": 103,
"startColumn": 9,
"endLineNumber": 103,
"endColumn": 9
}
At line .master (translated as: "a designator for an anonymous union member can only appear between braces that match that anonymous union"):
"owner": "C/C++",
"code": "2358",
"severity": 8,
"message": "un désignateur pour un membre d'union anonyme peut uniquement apparaître entre des accolades qui correspondent à cette union anonyme",
"source": "C/C++",
"startLineNumber": 105,
"startColumn": 9,
"endLineNumber": 105,
"endColumn": 9
}]
[UPDATE] My initial code writings was as follows:
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = (gpio_pullup_t)GPIO_PULLUP_ENABLE,
.scl_pullup_en = (gpio_pullup_t)GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ
};
And were producing those two errors:
At .sda_pullup_en =
line (109) (translated as: "out of order initializers are not standard in C++"):
[{
"owner": "C/C++",
"code": "2904",
"severity": 8,
"message": "les initialiseurs hors service ne sont pas standard en C++",
"source": "C/C++",
"startLineNumber": 109,
"startColumn": 3,
"endLineNumber": 109,
"endColumn": 3
}]
At .master.clk_speed =
line (111), translated as:
[{
"owner": "C/C++",
"code": "2358",
"severity": 8,
"message": "un désignateur pour un membre d'union anonyme peut uniquement apparaître entre des accolades qui correspondent à cette union anonyme",
"source": "C/C++",
"startLineNumber": 111,
"startColumn": 3,
"endLineNumber": 111,
"endColumn": 3
},{
"owner": "cpp",
"severity": 8,
"message": "expected primary-expression before '.' token",
"startLineNumber": 111,
"startColumn": 3,
"endLineNumber": 111,
"endColumn": 3
},{
"owner": "C/C++",
"code": "136",
"severity": 8,
"message": "classe \"i2c_config_t\" n'a pas de champ \"clk_speed\"",
"source": "C/C++",
"startLineNumber": 111,
"startColumn": 10,
"endLineNumber": 111,
"endColumn": 10
}]
How to fix my code?
@hcheung gave the right answer about the order of the members.
But regarding the anonymous union, his solution does not work.
I finally came up with the solution:
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = I2C_MASTER_SCL_IO,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
{ {I2C_MASTER_FREQ_HZ}}
};
Anonymous union are not standard but compiler extension and should actually be named. But here, the struct belongs to a third-party lib I cannot update.
So the solution is that I need to put an open curry braces to catch the first member of the union and then provide the value I am interested in. Very important to note that it sounds we can only reach the first union member as we can't name it.
Additional note: You can also be explicit about the clock speed as follows:
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = I2C_MASTER_SCL_IO,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
{{.clk_speed = I2C_MASTER_FREQ_HZ}}
};