analogdevicesinc / libiio

A cross platform library for interfacing with local and remote Linux IIO devices
http://analogdevicesinc.github.io/libiio/
GNU Lesser General Public License v2.1
484 stars 312 forks source link

iio_stream_get_next_block causes Invalid argument #1117

Open illiw99 opened 8 months ago

illiw99 commented 8 months ago

I am using a ADIS16460 device on an Raspberry PI connected to an SPI and encountered following problem in my Code:

#include <iio/iio.h>
#include <iio/iio-debug.h>
#include <string.h>
#include <stdio.h>

int main(void)
{
    struct iio_context *ctx;
    const char *chn_name = "accel_z";

    struct iio_device *dev0;
    struct iio_channel *dev0_chn;
    struct iio_channels_mask *dev0_mask;
    struct iio_buffer *dev0_buff;
    struct iio_stream *dev0_stream;
    size_t dev0_sample_sz;

    printf("* Acquiring IIO context *\n");
    ctx = iio_create_context(NULL, NULL);

    printf("* Acquiring ADI14640 streaming device *\n");
    dev0 = iio_context_find_device(ctx, "iio:device0");

    printf("* Acquiring IIO channels *\n");
    dev0_chn = iio_device_find_channel(dev0, chn_name, false);
    printf("* Channelname: %s *\n", iio_channel_get_id(dev0_chn));

    printf("* Acquiring IIO channel mask *\n");
    dev0_mask = iio_create_channels_mask(iio_device_get_channels_count(dev0));

    printf("* Enabling IIO channel mask *\n");
    iio_channel_enable(dev0_chn, dev0_mask);

    printf("* Creating IIO buffers *\n");
    dev0_buff = iio_device_create_buffer(dev0, 0, dev0_mask);
    size_t sample = iio_device_get_sample_size(dev0, dev0_mask);

    printf("* Creating IIO streams *\n");
    dev0_stream = iio_buffer_create_stream(dev0_buff, 4, 4);

    printf("* Reading IIO streams *\n");
    const struct iio_block* block = iio_stream_get_next_block(dev0_stream);

    return 0;
}

Getting the error "ERROR: iio:device0: Unable to enable buffer: Invalid argument (22)", when calling iio_stream_get_next_block(dev0_stream).

Since I am very new to this scene, I have got a few questions:

  1. Why getting the "Unable to enable buffer"?
  2. Why do I have to run the code in sudo, to even create the buffer in row "dev0_buff = iio_device_create_buffer(dev0, 0, dev0_mask);"?
  3. Is ADIS16460 even capable to use buffered reading?
  4. When getting the block object from iio_stream_get_next_block() how do i read the block, to get the sensor data as double values?
  5. Since the datasheet of ADIS16460 says, it's capable of 2048 SPS, how to achive this speed? (Tried it with the python pyaid-iio library, reading all channels with attr_read and was far of the 20480 SPS).

Thanks for the help!

rgetz commented 8 months ago

ADIS16460 Datasheet states a few things:

The actual sample rate will be limited by either. (and you didn't spec your SPI rate).

nunojsa commented 8 months ago

Since the datasheet of ADIS16460 says, it's capable of 2048 SPS, how to achive this speed? (Tried it with the python pyaid-iio library, reading all channels with attr_read and was far of the 20480 SPS).

AFAIR, that driver does not support burst mode which might slow things down a bit. Also, as @rgetz stated, you're not giving any info about your SPI speed. But typically, you won't be able to get 100% of the samples because Linux is not realtime, hence there are latencies inherent to the IIO buffer triggered mechanism...

Since you're using a RPI, changing this driver parameter might help you with having better performance. The point is polling in your spi transfers so IRQs don't get in the way.

illiw99 commented 8 months ago

@rgetz and @nunojsa, thanks for the fast reply!

The attribute spi-max-frequency in the device tree overlay is set to 2000000 (2MHz), does that mean the SPI is operating with 2MHz constantly (random guessing -> No). How can I inspect the set SPI speed, other than with a logic analyzer, is there a way to inspect this on linux?

If the speed is set to 2MHz, what does it mean to my sensor reading rate for every channel on the device?

Do you have an answer to the other questions, poorly i can't even get the iio_stream running?

pcercuei commented 8 months ago

I don't know that part, but looking at the driver, it seems that you need to set up a trigger first.