2

I would like to read the values of an IMU sensor from a C project. The device in question is the LSM6DSL, and I am using the IIO kernel drivers. They are working correctly because I am able to read the values by using the command :

cat /sys/bus/iio/devices/iio:device0/in_accel_x_raw
> 2

The issue is that when I want to refill my buffer using the function iio_buffer_refill(struct iio_buffer *buffer) it returns the error code 110, which is a time out. Before that, I enabled some channels to read from, and the buffer was successful created. I made some research about this problem and I believe it is linked with the Interrupt parameters from the device tree.

Here is my device tree for the i2c protocol (I took an example from this link):

lsm6dsl@6b {                                                                  
            compatible = "st,lsm6dsl";                                            
            reg = <0x6b>;                                                         
            interrupt-parent = <&gpio>;                                           
            interrupts = <26 0x4>;                                                
           };

Is it really related to the device tree or am I missing something else ? Thanking you in advance.

[Edit] Here is the source code that creates the buffer and tries to read from it:

struct iio_context *context = iio_create_local_context();
struct iio_device *device = iio_context_get_device(context, 1);
struct iio_channel *chan = iio_device_get_channel(device, 0);
iio_channel_enable(chan);
struct iio_buffer *buff = iio_device_create_buffer(device, 1, false);
if (buff == NULL)
{
  printf("Error %d: %s\n", errno, strerror(errno));
  return (1);
}
printf("Read size is: %ld\n", (long)iio_buffer_refill(buff));
iio_buffer_destroy(buff);

> Read size is: -110
  • I presume the sequence you have is next: `iio_buffer_refill()` -> `local_get_buffer()` -> `device_check_ready()` -> `poll()`. When `poll()` returns 0 (timeout happened, according to `man 2 poll`), `device_check_ready()` returns `-ETIMEDOUT`. So the issue here is that `poll()` wasn't able to catch some event in kernel, which would lead to correct return. This event may be generated by interrupt. So yes, I'd check if kernel actually catches that interrupt. Check the code [here](http://elixir.free-electrons.com/linux/latest/source/drivers/iio/imu/st_lsm6dsx). – Sam Protsenko May 19 '17 at 14:16
  • I'd start from [st_lsm6dsx_fifo_setup()](http://elixir.free-electrons.com/linux/latest/source/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c#L415) function. – Sam Protsenko May 19 '17 at 14:21
  • Thanks for your answer. However I am new to linux kernel and I don't really know what I should be looking for inside the source code, something that says "interupt" ? –  May 19 '17 at 14:36
  • Well... Then it can be hard, won't lie to you :) Basically, you need to understand, that libiio tries to use `poll()` syscall to wait for some data to arrive (as I understood it). `poll()` won't work (throwing timeout error). So what you should look for is: 1) Where that `poll()` is handled in kernel (and if it's being handled at all). 2) Why it's not being triggered (probably by some interrupt). You should start from reading your device driver code I mentioned (which is split into core and i2c parts), and probably you would need to read IIO framework code too. – Sam Protsenko May 19 '17 at 20:19
  • @ynitsed I had a similar problem, but with a completely different device. The solution was to fix interrupt IDs in the device tree. – shycha Aug 06 '18 at 11:15

0 Answers0