STMicroelectronics / st-mems-android-linux-drivers-iio

stm mems iio drivers for Android and Linux platforms.
GNU General Public License v2.0
23 stars 1 forks source link

Configuring a hrtimer-trigger or buffered-trigger for iio-device and ODR in driver lower than actual ODR #15

Closed lukasl277 closed 3 months ago

lukasl277 commented 9 months ago

Hello, I have been having issues with configuring configuring a hrtimer-trigger or buffered-trigger for my iio-device. I am using a ISM330dlc (IMU) and it is connected to a rasberry pi cm4. As a driver I am using the LSM6DSX driver because my IMU is listed as configurable sensor in the Documentation. My problem is that when I load my device tree overlay (dtbo file) the /sys/bus/iio/devices/iio:deviceX/ directory appears but only these files appear. 284557304-52913afb-7326-4841-8317-0c6c70791489 In basically every documentation file, they say that a /sys/bus/iio/devices/iio:deviceX/trigger/ directory should appear and it doesn't matter what I do it doesn't appear. I have checked and the ISM330dlc supports triggers, even 2. Chatgpt has suggested I should change some parameters in the config.txt, but I have checked and every functionality I need. 284559182-2e54f9bb-2852-4d5a-a8cf-f66d86b5caf8 And as you can see everything is set to "m" or "y" so there shouldn't be a problem there. I have also looked into my dts file: 284560141-6d68a484-2aba-4206-b582-7e0101bdc1ea And chatgbt suggested I should do it in this fashion: 284560701-376df592-c917-43f3-bd45-cafaac2f757d

Unfortunately I haven't found anything regarding triggers under this Documentation path linux/Documentation/devicetree/bindings/iio/imu /st,lsm6dsx.yaml .

Also just a side question, is the buffered trigger a hardware trigger from the IMU because that is what I need besides the Hrtimer-trigger. What I really need, is to compare: -polling the Data-ready register to see whether new data is ready which then serves me as an interrupt if the data is ready -waiting for hardware interrupt when new data is ready To compare them I need to know if there is any chance I can do this by using iio-devices or moreover iio-triggers.

And also my ODR can just be configured to 433Hz even though I know for a fact that my IMU can be configured to an ODR of even 1.6KHz. I only need it set to 833Hz but the issue remains. I am a newbie linux, the iio-framework and the device tree, so I would be extremely thankful if you could provide some backround information to your answer, if you think you might have a solution for me. Thank you very much in advance.

rosterloh commented 6 months ago

@lukasl277 I'm try to do exactly the same thing. Do you ever find a solution?

mariotesi commented 6 months ago

Hi,

the LSM6DSX driver in kernel mainline is supported by Linux community. It manage trigger events on FIFO through an hw IRQ line so you need to configure an interrupt line in your device tree. Something like that (this work for rpi 4, address 0x6b depends on SDA0):

        ism330dlc: ism330dlc@6b {
            compatible = "st,ism330dlc";
            reg = <0x6b>;
            interrupt-parent = <&gpio>;
            interrupts = <26 IRQ_TYPE_LEVEL_HIGH>;
            st,int-pin = <1>;
        };
rosterloh commented 6 months ago

That is infact just what I have

lsm6dso@6a {
        compatible = "st,lsm6dso";
        reg = <0x6a>;
        interrupt-parent = <&gpio>;
        interrupts = <22 2>, <27 2>; // IRQ_TYPE_EDGE_FALLING
        st,drdy-int-pin = <1>;
};

When I try to read the device it is incredibly slow and and creating iio_buffers or triggers always fails to init

lukasl277 commented 6 months ago

I found out that you can't use the iio-trigger directory because there is none. So what you have to do is modprobe an hw trigger and an iio buffer have the right interrupt pins configured in your DT and enable your the buffer and channels later on in your iio-device directory. Then if u look in the /dev/i2c-x file there should be data coming in caused by the HW trigger.

rosterloh commented 6 months ago

Thank @lukasl277 this what I tried but the buffer creation and assigning the trigger to the devices still fails in code

RCLCPP_INFO(get_logger(), "* Acquiring device %s", device.c_str());
iio_device *dev = iio_context_find_device(ctx, device.c_str());
if (!dev) {
  RCLCPP_ERROR(get_logger(), "Could not find %s device", device.c_str());
  continue;
}
sensor.dev_name = device.c_str();
sensor.device = dev;

RCLCPP_INFO(get_logger(), "* Initialising IIO streaming channels:");
std::ostringstream log_msg;
log_msg << "  ";
for (unsigned int i = 0; i < iio_device_get_channels_count(dev); ++i) {
  struct iio_channel *chn = iio_device_get_channel(dev, i);
  if (iio_channel_is_scan_element(chn)) {
    log_msg << iio_channel_get_id(chn) << ", ";
    sensor.channel_count++;
  }
}
RCLCPP_INFO(get_logger(), log_msg.str().c_str());
if (sensor.channel_count == 0) {
  RCLCPP_ERROR(get_logger(), "No scan elements found in device");
  continue;
}

sensor.channels = (iio_channel **)calloc(sensor.channel_count, sizeof *sensor.channels);
if (!sensor.channels) {
  RCLCPP_ERROR(get_logger(), "Channel array allocation failed");
  continue;
}
for (unsigned int i = 0; i < sensor.channel_count; ++i) {
  struct iio_channel *chn = iio_device_get_channel(sensor.device, i);
  if (iio_channel_is_scan_element(chn))
    sensor.channels[i] = chn;
  }

  sensor.trigger_name = trigger.c_str();
  RCLCPP_INFO(
    get_logger(), "* Acquiring trigger %s for device: %s", trigger.c_str(), device.c_str());
  sensor.trigger = iio_context_find_device(ctx, sensor.trigger_name);
  if (!sensor.trigger || !iio_device_is_trigger(sensor.trigger)) {
    RCLCPP_ERROR(get_logger(), "No trigger found (try setting up the iio-trig-hrtimer module)");
    continue;
  }

  RCLCPP_INFO(get_logger(), "* Enabling IIO streaming channels for buffered capture");
  for (unsigned int i = 0; i < sensor.channel_count; ++i) {
    iio_channel_enable(sensor.channels[i]);
  }

  RCLCPP_INFO(get_logger(), "* Enabling IIO buffer trigger");
  if (iio_device_set_trigger(sensor.device, sensor.trigger)) {
    RCLCPP_ERROR(get_logger(), "Could not set trigger");
    continue;
  }

  RCLCPP_INFO(get_logger(), "* Creating non-cyclic IIO buffers with %d samples", BUFFER_LENGTH);
  sensor.buffer = iio_device_create_buffer(sensor.device, BUFFER_LENGTH, false);
  if (!sensor.buffer) {
    RCLCPP_ERROR(get_logger(), "Could not create buffer");
    continue;
  }
}

image

lukasl277 commented 6 months ago

I found that this book helped me understand the iio framework more https://www.oreilly.com/library/view/linux-device-drivers/9781785280009/42be7f96-325c-423b-96ab-ceeddeb753c9.xhtml You just have to accept the free trial. I covers basically everything around the topic. Sadly I don't know how else to help you. The only thing that could be of possibility is that you have the wrong i2c bus and interrupt pin configured in your DTS overlay.

sunny52266 commented 6 months ago

@rosterloh Did you manage to find a solution to this issue? I am facing the same issue.

rosterloh commented 6 months ago

@sunny52266 I did not I'm afraid. My solution currently is to replace the IMU with one from a different vendor

sunny52266 commented 6 months ago

@rosterloh I found the solution. Apparently you need to configure the interrupts for the driver to be able to configure buffers and scan elements. otherwise it shows up as we were experiencing.

mariotesi commented 6 months ago

Hi,

the LSM6DSX driver in kernel mainline is supported by Linux community. It manage trigger events on FIFO through an hw IRQ line so you need to configure an interrupt line in your device tree. Something like that (this work for rpi 4, address 0x6b depends on SDA0):

      ism330dlc: ism330dlc@6b {
          compatible = "st,ism330dlc";
          reg = <0x6b>;
          interrupt-parent = <&gpio>;
          interrupts = <26 IRQ_TYPE_LEVEL_HIGH>;
          st,int-pin = <1>;
      };

This is the solution we suggested 2 weeks ago.

This is an off topic thread because the driver you mention is not in this repository being it maintained by Linux community. If you need more support on our products you are kindly invited to reach us on offical support

rosterloh commented 6 months ago

Thanks @sunny52266 but as you can see from my post above on 2nd of Feb I've already configured the interrupts

sunny52266 commented 6 months ago

You have configured st,drdy-pin as per your post. Please also ensure if pin 26 of &gpio is connected to a gpio expander, you need to enable its interrupts too and config that as interrupt controller and define its int pin. Also pl follow:

Hi, the LSM6DSX driver in kernel mainline is supported by Linux community. It manage trigger events on FIFO through an hw IRQ line so you need to configure an interrupt line in your device tree. Something like that (this work for rpi 4, address 0x6b depends on SDA0):

        ism330dlc: ism330dlc@6b {
            compatible = "st,ism330dlc";
            reg = <0x6b>;
            interrupt-parent = <&gpio>;
            interrupts = <26 IRQ_TYPE_LEVEL_HIGH>;
            st,int-pin = <1>;
        };

This is the solution we suggested 2 weeks ago.

This is an off topic thread because the driver you mention is not in this repository being it maintained by Linux community. If you need more support on our products you are kindly invited to reach us on offical support