Post Go back to editing

pyadi-iio example w/ADIS16485 timing out

Category: Software
Product Number: ADIS16485
Software Version: 0.0.14

Attempting to use the pyadi-iio lib to read out data from the ADIS16485:

  • The IMU is bolted to an RPIZ board, which is installed on a RPi 4B
  • Using Kuiper Linux, latest version
  • Using pyadi-iio v0.0.14

Created my own DT overlay to get the device to show up on /sys/bus/iio:

Running the simple script:

Results in a TimeOut exception thrown on the adi.rx() call.

Based on this ticket, changing up rx_buffer_size and/or sample_rate didn't change the behavior.

Can you advise?

Thanks - Andrew

Parents
  • My guess would be that you are not getting data at all. Can you open IIO-Scope and try to capture data? Does that timeout as well?

    -Travis

  • Negative, no timeout on IIO-Scope.  Using the DMM tab, selecting device 'adis16485', and, say, the accel x|y|z channels + temp channel all show good data (stationary on desk shows 9.6 m/s^s on adis16485:accel_z).

    It was also my experience earlier that I could see different values showing up in iio_info and/or cat-ing the channels from the appropriate /sys FT branches.

  • With same channels selected as above, the plot window doesn't populate with data at all.  So, I believe that confirms what you were thinking.

    Given that we can get data, but not in a continuous "push" from the device, this wouldn't happen to indicate something to do with the IRQ/data ready line, would it?  If so, is there somewhere in the Linux plumbing we can go to see a count or some other sign of life?  I'm not a DT expert, and the DTS file was put together from various sources, making it a weak link in the chain imho.

    Andrew

  • Moving to Linux forum.   where is the first place to look?

      can you provide a formatted version of you above DT fragment? Its impossible to read as is.

    -Travis

  • Yep, sorry about that.  I used the embed code feature, but it ended up as garbage.  How about this?

    /*
    * adis16485-overlay.dts
    *
    * ADIS16485 IMU (inertial measurement unit) connected to spi0 on Raspberry Pi
    *
    */
    // See:
    //  https://devicetree-specification.readthedocs.io/en/latest/
    //  https://mjmwired.net/kernel/Documentation/devicetree/bindings/pinctrl/brcm,bcm2835-gpio.txt
    //  https://mjmwired.net/kernel/Documentation/devicetree/bindings/gpio
    //  https://www.kernel.org/doc/html/latest/devicetree/overlay-notes.html
    //  https://www.digi.com/resources/examples-guides/use-device-tree-overlays-to-patch-your-device-tree
    //  https://developer-archives.toradex.com/knowledge-base/device-tree-overlays-linux
    //
    /dts-v1/;
    /plugin/;
    
    // #include <dt-bindings/interrupt-controller/irq.h>
    // #include <dt-bindings/gpio/gpio.h>
    
    // From irq.h
    // #define IRQ_TYPE_NONE		0
    // #define IRQ_TYPE_EDGE_RISING	1
    // #define IRQ_TYPE_EDGE_FALLING	2
    // #define IRQ_TYPE_EDGE_BOTH	(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
    // #define IRQ_TYPE_LEVEL_HIGH	4
    // #define IRQ_TYPE_LEVEL_LOW	8
    
    // From gpio.h
    // /* Bit 0 express polarity */
    // #define GPIO_ACTIVE_HIGH 0
    // #define GPIO_ACTIVE_LOW 1
    
    // /* Bit 1 express single-endedness */
    // #define GPIO_PUSH_PULL 0
    // #define GPIO_SINGLE_ENDED 2
    
    // /* Bit 2 express Open drain or open source */
    // #define GPIO_LINE_OPEN_SOURCE 0
    // #define GPIO_LINE_OPEN_DRAIN 4
    
    // /*
    //  * Open Drain/Collector is the combination of single-ended open drain interface.
    //  * Open Source/Emitter is the combination of single-ended open source interface.
    //  */
    // #define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
    // #define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE)
    
    // /* Bit 3 express GPIO suspend/resume and reset persistence */
    // #define GPIO_PERSISTENT 0
    // #define GPIO_TRANSITORY 8
    
    // /* Bit 4 express pull up */
    // #define GPIO_PULL_UP 16
    
    // /* Bit 5 express pull down */
    // #define GPIO_PULL_DOWN 32
    
    / {
        compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709", "brcm,bcm2711";
        
        fragment@0 {
            target = <&spi0>;
            
            __overlay__ {
                status = "okay";
            };
        };
    
        fragment@1 {
            target = <&spidev0>;
            
            __overlay__ {
                status = "disabled";
            };
        };
        
        fragment@2 {
            target = <&spidev1>;
            
            __overlay__ {
                status = "disabled";
            };
        };
        
        /* The non-SPI pins for this device/mcu combo. */
        fragment@3 {
            target = <&gpio>;
            
            __overlay__ {
            
                adis16485_pins: adis16485_pins {
                    /* For the following params: DR, RST. */
                    brcm,pins = <24 12>;
                    brcm,function = <0 1>; /* input, output */
                    // bcrm,pull = <0 0>; /* disable pull-over */
                };
            };
        };
    
        fragment@4 {
            target = <&spi0>;
    
            __overlay__ {
                /* needed to avoid dtc warning */
                #address-cells = <1>;
                #size-cells = <0>;
                
                adis16485: adis16485@0 {
                    compatible = "adi,adis16485";
                    reg = <0>; /* CS0 */
                    pinctrl-names = "default"; /* ctrl pins, as defined above */
                    pinctrl-0 = <&adis16485_pins>;
                    spi-cpha;  /* Mode3 */
                    spi-cpol;  /* ... */
                    reset-gpios = <&gpio 12 1>; /* GPIO_ACTIVE_LOW */
                    spi-max-frequency = <15000000>; /* 15 MHz */
                    interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */
                    interrupt-parent = <&gpio>;
                };
            };
        };
    
    	__overrides__ {
    		device = <&adis16485>,"compatible";
    		drdy_dio1 = <&adis16485_pins>,"brcm,pins:0=23",
    				<&adis16485>,"interrupts:0=23",
    				<&adis16485>,"interrupt-names=DIO1";
    	};
    };
    

    Andrew

  • Great thanks. Will need to wait for  . He is the expert here.

    -Travis

  • Hi Andrew,

    Can you ssh into your board? You can do `cat /proc/interrupts` to check if the interrupts are being triggered at all...

    "interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING"

    Any special reason for this? Are you inverting the signal somehow? AFAIK, this should be RISING... Did you looked at the adis16480-overlay?

    Another thing you can try is to lower the sampling period (or the FFT size if in frequency) in osc.

    - Nuno Sá

  • Thanks for your reply,  .

    Yes, I actually started with this board using SSH, so no problem there.

    Yes, looked into the 16480 overlay, and based my own overlay upon it.

    The "interrupts=..." line was a mistake.  Just changed it to EDGE_RISING, and retested.  No change in behavior, though. 

    Checking /proc/interrups gives this:

    analog@analog:~/Logger $ cat /proc/interrupts
               CPU0       CPU1       CPU2       CPU3
     25:          1          0          0          0     GICv2  99 Level     timer
     26:          0          0          0          0     GICv2  29 Level     arch_timer
     27:      13577      10093      10671      10733     GICv2  30 Level     arch_timer
     33:        193          0          0          0     GICv2  65 Level     fe00b880.mailbox
     36:       7547          0          0          0     GICv2 153 Level     uart-pl011
     37:          0          0          0          0     GICv2 150 Level     fe204000.spi
     38:          0          0          0          0     GICv2 112 Level     bcm2708_fb DMA
     40:        345          0          0          0     GICv2 114 Level     DMA IRQ
     42:          0          0          0          0     GICv2 116 Level     DMA IRQ
     43:          0          0          0          0     GICv2 117 Level     DMA IRQ
     47:       1489          0          0          0     GICv2  66 Level     VCHIQ doorbell
     48:      25489          0          0          0     GICv2 158 Level     mmc1, mmc0
     54:        741          0          0          0     GICv2 189 Level     eth0
     55:        360          0          0          0     GICv2 190 Level     eth0
     61:          0          0          0          0     GICv2 175 Level     PCIe PME
     62:       8323          0          0          0  BRCM STB PCIe MSI 524288 Edge      xhci_hcd
     63:          0          0          0          0  pinctrl-bcm2835  24 Edge      adis16485
    IPI0:          0          0          0          0  CPU wakeup interrupts
    IPI1:          0          0          0          0  Timer broadcast interrupts
    IPI2:        183        274        234        238  Rescheduling interrupts
    IPI3:       7780      12076      27950      13147  Function call interrupts
    IPI4:          0          0          0          0  CPU stop interrupts
    IPI5:         44         36         61         44  IRQ work interrupts
    IPI6:          0          0          0          0  completion interrupts
    Err:          0

    Doesn't look like the interrupt is being triggered.

    Also saw what appears to be an inconsistency in the RPIZ schematic.  Looks like maybe data ready should be coming out on GPIO25.  Updated the overlay and tried GPIO25, and still no data.  /proc/interrupts still showing =0, even on GPIO25.

    Do you think there may still be an error in my DTS?

    Do you expect to see continuously interrupts from the data ready GPIO pin, immediately after the driver and overlay are loaded?  Or, interrupts only when the userland software is trying to get data?

    Next step on my end is to put an LA on the data lines and see if everything is OK at the signal level.

    Andrew

  • Do you expect to see continuously interrupts from the data ready GPIO pin, immediately after the driver and overlay are loaded?  Or, interrupts only when the userland software is trying to get data?

    The interrupts are only present (enabled) when you start a buffered read (eg: in osc capture window).

    Do you think there may still be an error in my DTS?

    Maybe, if there are no interrupts most likely it's because of some error in the overlay... To which pin is the GPIO25 connected? From what I'm seeing, it should be DIO1 right?

    - Nuno Sá

  • Thanks for your reply.

    The interrupts are only present (enabled) when you start a buffered read (eg: in osc capture window).

    OK, good to know.

    To which pin is the GPIO25 connected? From what I'm seeing, it should be DIO1 right?

    The IMU is mounted on an unmodified EVAL-ADISIMU1-RPIZ board.

    From the RPIZ schematic (02_059367b_top.pdf), DIO2 should be on GPIO25.  From previous experience with this IMU (bare metal, not Linux), DIO2 is the default DR line for the ADIS16485.

    Signal chain should be: P2-9 (IMU DIO2) -> P4-22 (RPi GPIO25).

  • Hi,

    From the RPIZ schematic (02_059367b_top.pdf), DIO2 should be on GPIO25.  From previous experience with this IMU (bare metal, not Linux), DIO2 is the default DR line for the ADIS16485.

    Signal chain should be: P2-9 (IMU DIO2) -> P4-22 (RPi GPIO25).

    Then this might be your problem... As you're not specifying 'interrupt-names', DIO1 is the ping being configured as data ready (see here) and it seems we have nothing connect to it.

    Hence you need to add this to your overlay: interrupt-names = "DIO2" so that DIO2 is used as data ready,

    - Nuno Sá

  • OK, that did it!

    Interesting - my initial Python script can retrieve data OK now, but the o-scope app still doesn't display data (nor the DMM, which used to show data).

    The last DTS is entered below.  Note that it does not have overrides enabled in its current state.

    /*
    * adis16485-overlay.dts
    *
    * ADIS16485 IMU (inertial measurement unit) connected to spi0 on Raspberry Pi
    *
    */
    /dts-v1/;
    /plugin/;
    
    // #include <dt-bindings/interrupt-controller/irq.h>
    // #include <dt-bindings/gpio/gpio.h>
    
    // From irq.h
    // #define IRQ_TYPE_NONE		0
    // #define IRQ_TYPE_EDGE_RISING	1
    // #define IRQ_TYPE_EDGE_FALLING	2
    // #define IRQ_TYPE_EDGE_BOTH	(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
    // #define IRQ_TYPE_LEVEL_HIGH	4
    // #define IRQ_TYPE_LEVEL_LOW	8
    
    // From gpio.h
    // /* Bit 0 express polarity */
    // #define GPIO_ACTIVE_HIGH 0
    // #define GPIO_ACTIVE_LOW 1
    
    // /* Bit 1 express single-endedness */
    // #define GPIO_PUSH_PULL 0
    // #define GPIO_SINGLE_ENDED 2
    
    // /* Bit 2 express Open drain or open source */
    // #define GPIO_LINE_OPEN_SOURCE 0
    // #define GPIO_LINE_OPEN_DRAIN 4
    
    // /*
    //  * Open Drain/Collector is the combination of single-ended open drain interface.
    //  * Open Source/Emitter is the combination of single-ended open source interface.
    //  */
    // #define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
    // #define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE)
    
    // /* Bit 3 express GPIO suspend/resume and reset persistence */
    // #define GPIO_PERSISTENT 0
    // #define GPIO_TRANSITORY 8
    
    // /* Bit 4 express pull up */
    // #define GPIO_PULL_UP 16
    
    // /* Bit 5 express pull down */
    // #define GPIO_PULL_DOWN 32
    
    / {
        compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709", "brcm,bcm2711";
        
        fragment@0 {
            target = <&spi0>;
            
            __overlay__ {
                status = "okay";
            };
        };
    
        fragment@1 {
            target = <&spidev0>;
            
            __overlay__ {
                status = "disabled";
            };
        };
        
        fragment@2 {
            target = <&spidev1>;
            
            __overlay__ {
                status = "disabled";
            };
        };
        
        /* The non-SPI pins for this device/mcu combo. */
        fragment@3 {
            target = <&gpio>;
            
            __overlay__ {
            
                adis16485_pins: adis16485_pins {
                    /* For the following params: DR, RST. */
                    brcm,pins = <24 12>;
                    brcm,function = <0 1>; /* input, output */
                    // bcrm,pull = <0 0>; /* disable pull-over */
                };
            };
        };
    
        fragment@4 {
            target = <&spi0>;
    
            __overlay__ {
                /* needed to avoid dtc warning */
                #address-cells = <1>;
                #size-cells = <0>;
                
                adis16485: adis16485@0 {
                    compatible = "adi,adis16485";
                    reg = <0>; /* spi0 */
                    pinctrl-names = "default"; /* ctrl pins, as defined above */
                    pinctrl-0 = <&adis16485_pins>;
                    spi-cpha;  /* Mode3 */
                    spi-cpol;  /* ... */
                    reset-gpios = <&gpio 12 1>; /* GPIO_ACTIVE_LOW */
                    spi-max-frequency = <15000000>; /* 15 MHz */
                    interrupts = <25 1>; /* IRQ_TYPE_EDGE_RISING */
                    interrupt-parent = <&gpio>;
                    interrupt-names = "DIO2";
                };
            };
        };
    
    	// __overrides__ {
    	// 	device = <&adis16485>,"compatible";
    	// 	drdy_dio1 = <&adis16485_pins>,"brcm,pins:0=23",
    	// 			<&adis16485>,"interrupts:0=23",
    	// 			<&adis16485>,"interrupt-names=DIO1";
    	// };
    };
    

Reply
  • OK, that did it!

    Interesting - my initial Python script can retrieve data OK now, but the o-scope app still doesn't display data (nor the DMM, which used to show data).

    The last DTS is entered below.  Note that it does not have overrides enabled in its current state.

    /*
    * adis16485-overlay.dts
    *
    * ADIS16485 IMU (inertial measurement unit) connected to spi0 on Raspberry Pi
    *
    */
    /dts-v1/;
    /plugin/;
    
    // #include <dt-bindings/interrupt-controller/irq.h>
    // #include <dt-bindings/gpio/gpio.h>
    
    // From irq.h
    // #define IRQ_TYPE_NONE		0
    // #define IRQ_TYPE_EDGE_RISING	1
    // #define IRQ_TYPE_EDGE_FALLING	2
    // #define IRQ_TYPE_EDGE_BOTH	(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
    // #define IRQ_TYPE_LEVEL_HIGH	4
    // #define IRQ_TYPE_LEVEL_LOW	8
    
    // From gpio.h
    // /* Bit 0 express polarity */
    // #define GPIO_ACTIVE_HIGH 0
    // #define GPIO_ACTIVE_LOW 1
    
    // /* Bit 1 express single-endedness */
    // #define GPIO_PUSH_PULL 0
    // #define GPIO_SINGLE_ENDED 2
    
    // /* Bit 2 express Open drain or open source */
    // #define GPIO_LINE_OPEN_SOURCE 0
    // #define GPIO_LINE_OPEN_DRAIN 4
    
    // /*
    //  * Open Drain/Collector is the combination of single-ended open drain interface.
    //  * Open Source/Emitter is the combination of single-ended open source interface.
    //  */
    // #define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
    // #define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE)
    
    // /* Bit 3 express GPIO suspend/resume and reset persistence */
    // #define GPIO_PERSISTENT 0
    // #define GPIO_TRANSITORY 8
    
    // /* Bit 4 express pull up */
    // #define GPIO_PULL_UP 16
    
    // /* Bit 5 express pull down */
    // #define GPIO_PULL_DOWN 32
    
    / {
        compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709", "brcm,bcm2711";
        
        fragment@0 {
            target = <&spi0>;
            
            __overlay__ {
                status = "okay";
            };
        };
    
        fragment@1 {
            target = <&spidev0>;
            
            __overlay__ {
                status = "disabled";
            };
        };
        
        fragment@2 {
            target = <&spidev1>;
            
            __overlay__ {
                status = "disabled";
            };
        };
        
        /* The non-SPI pins for this device/mcu combo. */
        fragment@3 {
            target = <&gpio>;
            
            __overlay__ {
            
                adis16485_pins: adis16485_pins {
                    /* For the following params: DR, RST. */
                    brcm,pins = <24 12>;
                    brcm,function = <0 1>; /* input, output */
                    // bcrm,pull = <0 0>; /* disable pull-over */
                };
            };
        };
    
        fragment@4 {
            target = <&spi0>;
    
            __overlay__ {
                /* needed to avoid dtc warning */
                #address-cells = <1>;
                #size-cells = <0>;
                
                adis16485: adis16485@0 {
                    compatible = "adi,adis16485";
                    reg = <0>; /* spi0 */
                    pinctrl-names = "default"; /* ctrl pins, as defined above */
                    pinctrl-0 = <&adis16485_pins>;
                    spi-cpha;  /* Mode3 */
                    spi-cpol;  /* ... */
                    reset-gpios = <&gpio 12 1>; /* GPIO_ACTIVE_LOW */
                    spi-max-frequency = <15000000>; /* 15 MHz */
                    interrupts = <25 1>; /* IRQ_TYPE_EDGE_RISING */
                    interrupt-parent = <&gpio>;
                    interrupt-names = "DIO2";
                };
            };
        };
    
    	// __overrides__ {
    	// 	device = <&adis16485>,"compatible";
    	// 	drdy_dio1 = <&adis16485_pins>,"brcm,pins:0=23",
    	// 			<&adis16485>,"interrupts:0=23",
    	// 			<&adis16485>,"interrupt-names=DIO1";
    	// };
    };
    

Children
  • but the o-scope app still doesn't display data (nor the DMM, which used to show data).

    For the capture window, try to lower the sample rate... The DMM is more interesting and I honestly don't know why it's not working for you. It's just about reading the attributes directly which means there's no buffering involved nor interrupts. So, changing the pin for data ready should have no effect...

    - Nuno Sá