Unknown origin of error


markus.prager@...
 

Hi everyone

I am currently trying to write a driver for an STMicroelectronics LIS3DHH accelerometer. I based my code on the existing LIS2DH code that is already integrated in Zephyr and tried to adapt it to the LIS3DHH. Now when I try to build my project I get an error that i can't quite figure out where it is coming or originating from since it is occurring in an automatically generated file:

from /home/markus/driver_test_lis3dhh/my-workspace/zephyr/drivers/sensor/spi_lis3dhh/lis3dhh.c:7:
/home/markus/driver_test_lis3dhh/my-workspace/iots-fiso-id-p2-zephyr/build/zephyr/include/generated/devicetree_unfixed.h:24457:36: error: 'DT_N_S_soc_S_spi_40003800_S_lis3dhh_11_P_spi_max_frequency' undeclared here (not in a function); did you mean 'DT_N_S_soc_S_spi_40003800_S_lis3dhh_11_P_compatible_IDX_0'?
24457 | #define DT_N_INST_0_st_lis3dhh     DT_N_S_soc_S_spi_40003800_S_lis3dhh_11

I guess it looks like it is coming from the devicetree, but I can't see anything wrong with that one. I am doing all this on a custom board, so the devicetree I wrote myself - so I guess chances are high I did something wrong there, but I don't know what it could be.

So here is the relevant part of my devicetree if that helps:

&spi2 {
    pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pb14 &spi2_mosi_pb15>;/*PIN34,PIN35,PIN36*/
    cs-gpios = <&gpioc 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;/* PC6, Acc_CS */
    status = "okay";
 
    lis3dhh: lis3dhh@11 {
        compatible = "st,lis3dhh","st,spi_lis3dhh";
        reg = <0x11>;
        label = "LIS3DHH";
        spi-max-frequency = <10000000>; /*max. 10MHz*/
        int1-gpios = <&gpioc 7 GPIO_ACTIVE_HIGH>; /*PC7*/
        int2-gpios = <&gpioc 8 GPIO_ACTIVE_HIGH>;  /*PC8 */
    };
};

Any suggestions, hints or directions are very welcome.
Thanks in advance,
Markus


markus.prager@...
 

Alright, so thanks to Nick (thank you!) I have now narrowed down my problem a little.

as a background, here is the C code that is causing the issue (i marked the error-origin in fat characters):

#define LIS3DHH_SPI_CFG(inst)                         \
    (&(struct lis3dhh_spi_cfg){                       \
        .spi_conf = {                                 \
            .frequency =                              \
              DT_INST_PROP(inst, clock_frequency),  \
            .operation = (SPI_WORD_SET(8) |           \
                          SPI_OP_MODE_MASTER |        \
                          SPI_MODE_CPOL |             \
                          SPI_MODE_CPHA),             \
            .slave = DT_INST_REG_ADDR(inst),          \
            .cs = LIS3DHH_SPI_CS_PTR(inst),           \
        },                                            \
        .cs_gpios_label = LIS3DHH_SPI_CS_LABEL(inst), \
    })


So the problem is the devicetree that i am trying to use. Nick suggested i move the "spi-max-frequency" from the lis3dhh device to the spi2 node (like the spi yaml file suggests -> dts/bindings/spi/spi-device.yaml). So something like this:

&spi2 {
    pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pb14 &spi2_mosi_pb15>;/*PIN34,PIN35,PIN36*/
    cs-gpios = <&gpioc 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;/* PC6, Acc_CS */
    status = "okay";
    spi-max-frequency = <10000000>; /*max. 10MHz*/
 
    lis3dhh: lis3dhh@11 {
        compatible = "st,lis3dhh","st,spi_lis3dhh";
        reg = <0x11>;
        label = "LIS3DHH";
        int1-gpios = <&gpioc 7 GPIO_ACTIVE_HIGH>; /*PC7*/
        int2-gpios = <&gpioc 8 GPIO_ACTIVE_HIGH>;  /*PC8 */
    };
};


However, this lead me to realize that my devicetree does not access the normal spi-device.yaml but rather the st,stm32-spi.yaml which is accessing  st,stm32-spi-common.yaml .
Now this file is not actually demanding a "spi-max-frequency" value at all. Though spi-controller.yaml it is possible to assign it a clock-frequency though.

So what I have tried now is adding that clock-frequency in both my code and in the devicetree. Now when i try that, i get the following error (i tried both options of adding it under the lis3dhh device and the spi node):

/home/markus/driver_test_lis3dhh/my-workspace/iots-fiso-id-p2-zephyr/build/zephyr/include/generated/devicetree_unfixed.h:24461:36: error: 'DT_N_S_soc_S_spi_40003800_S_lis3dhh_11_P_clock_frequency' undeclared here (not in a function); did you mean 'DT_N_S_soc_S_spi_40003800_S_lis3dhh_11_P_compatible'?
24461 | #define DT_N_INST_0_st_lis3dhh     DT_N_S_soc_S_spi_40003800_S_lis3dhh_11

I also tried editing st,stm32-spi-common.yaml to include an spi-max-frequency value.
Here I get the following error:

/home/markus/driver_test_lis3dhh/my-workspace/iots-fiso-id-p2-zephyr/build/zephyr/include/generated/devicetree_unfixed.h:24461:36: error: 'DT_N_S_soc_S_spi_40003800_S_lis3dhh_11_P_spi_max_frequency' undeclared here (not in a function); did you mean 'DT_N_S_soc_S_spi_40003800_P_spi_max_frequency'?
24461 | #define DT_N_INST_0_st_lis3dhh     DT_N_S_soc_S_spi_40003800_S_lis3dhh_11

So I guess there is an issue with me trying to access the wrong level of the devicetree? If I understand the error correctly, it is telling me that I am trying to access spi-max-frequency on the lis3dhh device (which i also gave that attribute by the way) but that does not exist and I should rather address the spi node's spi-max-frequency.
Now I don't really understand how I change this. Either accessing the node's spi-max-frequency or how to tell the devicetree to use the lis3dhh's spi-max-frequency attribute.


Again, I am very thankful for any advice.
Cheers,
Markus


lairdjm
 

Hi Markus,
Do you have the include at the top of the driver you're developing which incluces the spi-device.yaml file, e.g. from one of the other LIS2XX devices:
include: ["spi-device.yaml", "st,lis2dh-common.yaml"]

The SPI frequency should be for the device not the SPI controller, not that I've tested it and don't know if it's implemented or works but in theory you could have an SPI bus with 3 devices attached, one device could take at 250Kbps, one at 1Mbps and the other at 20Mbps hence the SPI maximum frequency being part of the device configuration 
Thanks,
Jamie

On Fri, 2021-09-10 at 06:07 -0700, markus.prager via lists.zephyrproject.org wrote:

Alright, so thanks to Nick (thank you!) I have now narrowed down my problem a little.

as a background, here is the C code that is causing the issue (i marked the error-origin in fat characters):

#define LIS3DHH_SPI_CFG(inst)                         \
    (&(struct lis3dhh_spi_cfg){                       \
        .spi_conf = {                                 \
            .frequency =                              \
              DT_INST_PROP(inst, clock_frequency),  \
            .operation = (SPI_WORD_SET(8) |           \
                          SPI_OP_MODE_MASTER |        \
                          SPI_MODE_CPOL |             \
                          SPI_MODE_CPHA),             \
            .slave = DT_INST_REG_ADDR(inst),          \
            .cs = LIS3DHH_SPI_CS_PTR(inst),           \
        },                                            \
        .cs_gpios_label = LIS3DHH_SPI_CS_LABEL(inst), \
    })


So the problem is the devicetree that i am trying to use. Nick suggested i move the "spi-max-frequency" from the lis3dhh device to the spi2 node (like the spi yaml file suggests ->dts/bindings/spi/spi-device.yaml). So something like this:

&spi2 {
    pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pb14 &spi2_mosi_pb15>;/*PIN34,PIN35,PIN36*/
    cs-gpios = <&gpioc 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;/* PC6, Acc_CS */
    status = "okay";
    spi-max-frequency = <10000000>; /*max. 10MHz*/
 
    lis3dhh: lis3dhh@11 {
        compatible = "st,lis3dhh","st,spi_lis3dhh";
        reg = <0x11>;
        label = "LIS3DHH";
        int1-gpios = <&gpioc 7 GPIO_ACTIVE_HIGH>; /*PC7*/
        int2-gpios = <&gpioc 8 GPIO_ACTIVE_HIGH>;  /*PC8 */
    };
};


However, this lead me to realize that my devicetree does not access the normal spi-device.yaml but rather the st,stm32-spi.yamlwhich is accessing  st,stm32-spi-common.yaml .
Now this file is not actually demanding a "spi-max-frequency" value at all. Thoughspi-controller.yaml it is possible to assign it a clock-frequency though.

So what I have tried now is adding that clock-frequency in both my code and in the devicetree. Now when i try that, i get the following error (i tried both options of adding it under the lis3dhh device and the spi node):

/home/markus/driver_test_lis3dhh/my-workspace/iots-fiso-id-p2-zephyr/build/zephyr/include/generated/devicetree_unfixed.h:24461:36: error: 'DT_N_S_soc_S_spi_40003800_S_lis3dhh_11_P_clock_frequency' undeclared here (not in a function); did you mean 'DT_N_S_soc_S_spi_40003800_S_lis3dhh_11_P_compatible'?
24461 | #define DT_N_INST_0_st_lis3dhh     DT_N_S_soc_S_spi_40003800_S_lis3dhh_11

I also tried editing st,stm32-spi-common.yamlto include an spi-max-frequency value.
Here I get the following error:

/home/markus/driver_test_lis3dhh/my-workspace/iots-fiso-id-p2-zephyr/build/zephyr/include/generated/devicetree_unfixed.h:24461:36: error: 'DT_N_S_soc_S_spi_40003800_S_lis3dhh_11_P_spi_max_frequency' undeclared here (not in a function); did you mean 'DT_N_S_soc_S_spi_40003800_P_spi_max_frequency'?
24461 | #define DT_N_INST_0_st_lis3dhh     DT_N_S_soc_S_spi_40003800_S_lis3dhh_11

So I guess there is an issue with me trying to access the wrong level of the devicetree? If I understand the error correctly, it is telling me that I am trying to access spi-max-frequency on the lis3dhh device (which i also gave that attribute by the way) but that does not exist and I should rather address the spi node's spi-max-frequency.
Now I don't really understand how I change this. Either accessing the node's spi-max-frequency or how to tell the devicetree to use the lis3dhh's spi-max-frequency attribute.


Again, I am very thankful for any advice.
Cheers,
Markus



markus.prager@...
 

Thanks for the directions, Jamie.

I have fixed that issue with the frequency - however I am now having problems with my chip-select gpio. I do not seem to be able to properly access a specific cs-gpio pin, even though I am fairly certain I declared it correctly in my devicetree.

Devicetree for spi2 on my board

&spi2 {
pinctrl-0 = <&spi2_sck_pb13
&spi2_miso_pb14 &spi2_mosi_pb15>;/*PIN34,PIN35,PIN36*/
cs-gpios = <&gpioc 6 GPIO_ACTIVE_LOW>;/* PC6, Acc_CS */
status = "okay";
};

This is based on the information found in "spi-device.yaml".


My devicetree overlay for the lis3dhh sensor

&spi2 {
lis3dhh: lis3dhh@0 {
compatible = "st,lis3dhh","st,spi_lis3dhh";
status = "okay";
reg = <0>;
label = "LIS3DHH";
spi-max-frequency = <1000000>;
irq-gpios = <&gpioc 7 GPIO_ACTIVE_HIGH>, <&gpioc 8 GPIO_ACTIVE_HIGH>; //INT1, PC7 & INT2, PC8
};
};


My spi init function (based on the init function I found for the lis2dh sensor)

int lis3dhh_spi_init(const struct device *dev)
{
struct lis3dhh_data *lis3dhh_drv_data = dev->data;
const struct lis3dhh_config *cfg = dev->config;
const struct lis3dhh_spi_cfg *spi_cfg = cfg->bus_cfg.spi_cfg;
LOG_ERR("config->cs: %p", spi_cfg->spi_conf.cs);
LOG_ERR("config->cs->gpio_dev: %p", spi_cfg->spi_conf.cs->gpio_dev);

lis3dhh_drv_data->hw_tf = &lis3dhh_spi_transfter_fn;

if (spi_cfg->cs_gpios_label != NULL)
{
lis3dhh_drv_data->cs_ctrl.gpio_dev = device_get_binding(spi_cfg->cs_gpios_label);
if (!lis3dhh_drv_data->cs_ctrl.gpio_dev)
{
LOG_ERR("unable to get GPIO SPI CS device");
return -ENODEV; //no such device
}
LOG_DBG("SPI GPIO CS configured on %s:%u", spi_cfg->cs_gpios_label, lis3dhh_drv_data->cs_ctrl.gpio_pin);
}
if (spi_cfg->cs_gpios_label == NULL) {LOG_ERR("spi_cfg cs_gpios_label is NULL");}
return 0;
}



The spi init function is called from this lis3dhh init function:

int lis3dhh_init(const struct device *dev)
{
struct lis3dhh_data *lis3dhh_drv_data = dev->data;
const struct lis3dhh_config *cfg = dev->config;
int status;
uint8_t id;

lis3dhh_drv_data->bus = device_get_binding(
cfg->bus_name);

if (!lis3dhh_drv_data->bus)
{
LOG_ERR("master not found: %s", cfg->bus_name);
return -EINVAL; // error: invalid value
}
cfg->bus_init(dev); //spi bus initialization

status = lis3dhh_drv_data->hw_tf->read_reg(
dev, LIS3DHH_REG_WAI,
&id);

if (status < 0)
{
LOG_ERR("failed to read chip id.");
return status;
}

if (id != LIS3DHH_CHIP_ID)
{
LOG_ERR("invalid chip id: %02x (hex)\n", id);
return -EINVAL; // error: invalid value
}

LOG_INF("bus=%s", cfg->bus_name);
status = lis3dhh_drv_data->hw_tf->write_reg(dev, LIS3DHH_CTRL_REG1,
(LIS3DHH_CTRL_REG1_NORM_MODE_EN |
LIS3DHH_CTRL_REG1_IF_ADD_INC |
LIS3DHH_CTRL_REG1_BOOT));
if (status < 0)
{
LOG_ERR("failed to configure ctrl reg 1");
printk("failed to configure ctrl reg 1");
return status;
}
status = lis3dhh_drv_data->hw_tf->write_reg(dev, LIS3DHH_CTRL_REG4, LIS3DHH_CTRL_REG4_ONE_1);
return status;
}



Now i get these logs:
[00:00:00.002,000] <err> lis3dhh: config->cs: 0x200004e4
[00:00:00.002,000] <err> lis3dhh: config->cs->gpio_dev: (nil)
[00:00:00.002,000] <err> lis3dhh: spi_cfg cs_gpios_label is NULL
[00:00:00.014,000] <inf> spi_ll_stm32: CS control inhibited (no GPIO device)
[00:00:00.017,000] <err> lis3dhh: invalid chip id: 00

I just don't understand why my program does not seem to be able to access the given cs-gpio from the devicetree file.

Thanks again in advance for any directions,
Markus