Post Go back to editing

ADIS16448 iio driver on Nvidia Jetson TK1

Hello,

I am attempting to set up an ADIS16448 imu on a Nvidia Jetson TK1 over SPI. I have been following the guide here to configure the Jetson TK1 for spidev.

After following this guide, I have verified that I can communicate out over the SPI interface on the TK1 using the configured spidev interface by tweaking the ioctl commands as shown in the code sample from the tutorial.

I have compiled the kernel modules and made sure that they are loaded:

    username@host:~$ lsmod

    Module                  Size  Used by

    dm_crypt               12216  0

    bnep                   11872  2

    rfcomm                 46483  0

    rtc_as3722              3212  0

    bluetooth             279594  10 bnep,rfcomm

    rfkill                 14634  3 bluetooth

    parport_pc             28658  0

    parport                27466  1 parport_pc

    adis16400              10748  0

    adis_lib                5597  1 adis16400

    nvhost_vi               2908  0

The tutorial linked above has the following snippet from the device tree:

spi@7000d400 {
        compatible = "nvidia,tegra114-spi";
        reg = <0x7000d400 0x200>;
        interrupts = <0x0 0x3b 0x4>;
        nvidia,dma-request-selector = <0x7 0xf>;
        nvidia,memory-clients = <0xe>;
        #address-cells = <0x1>;
        #size-cells = <0x0>;
        status = "okay";
        spi-max-frequency = <0x17d7840>;

        spi0_0 {
            #address-cells = <0x1>;
            #size-cells = <0x0>;
            compatible = "spidev";
            reg = <0x0>;
            spi-max-frequency = <0x17d7840>;
            spi-cpha;
            nvidia,enable-hw-based-cs;
            nvidia,cs-setup-clk-count = <0x1e>;
            nvidia,cs-hold-clk-count = <0x1e>;
            nvidia,rx-clk-tap-delay = <0x1f>;
            nvidia,tx-clk-tap-delay = <0x0>;
        };
    };

where spi0_0 corresponds to the spidev device that presents itself as /dev/spidev0.0

My guess is that I need to join the IMU to this same spi bus, but I am unsure how. I have attempted to follow this similar issue that deals with the same concepts on the beaglebone, but the device tree is so vastly different that I am uncertain whether I am doing it right.

By adding the spi0_1 entry (as seen below), I was able to get your IIO driver to present itself. Note that when I have it configured like this, the spidev device seems to be unable to access the chip select line (as verified by my logic analyzer). I believe that both devices want to use reg = <0x0> for their chip select.

  spi@7000d400 {
                compatible = "nvidia,tegra114-spi";
                reg = <0x7000d400 0x200>;
                interrupts = <0x0 0x3b 0x4>;
                nvidia,dma-request-selector = <0x7 0xf>;
                nvidia,memory-clients = <0xe>;
                #address-cells = <0x1>;
                #size-cells = <0x0>;
                status = "okay";
                spi-max-frequency = <0x17d7840>;

                spi0_0 {
                        #address-cells = <0x1>;
                        #size-cells = <0x0>;
                        compatible = "spidev";
                        reg = <0x1>;
                        spi-max-frequency = <0x17d7840>;
                        spi-cpha;
                        nvidia,enable-hw-based-cs;
                        nvidia,cs-setup-clk-count = <0x1e>;
                        nvidia,cs-hold-clk-count = <0x1e>;
                        nvidia,rx-clk-tap-delay = <0x1f>;
                        nvidia,tx-clk-tap-delay = <0x0>;

                };

                spi0_1{
                    #address-cells = <0x1>;
                    #size-cells = <0x0>;
                    compatible = "adi,adis16400";
                    reg = <0x0>;
                    spi-cpha;
                    spi-cpol;
                    spi-max-frequency = <0x17d7840>;
                    nvidia,enable-hw-based-cs;
                    nvidia,cs-setup-clk-count = <0x10>;
                    nvidia,cs-hold-clk-count = <0x10>;
                    nvidia,rx-clk-tap-delay = <0x28>;
                    nvidia,tx-clk-tap-delay = <0x0>;
                };

        };

My issue is that when I add the spi0_1 piece, the device shows up under the IIO but when I attempt to read values, they all return "0". I am new to the concept of device trees, so I believe that I am close, but I just need to tweak these entries somehow.

Any info on how to get data out of the device from this stage would be helpful =)

Thank you,

Curtis

  • Hi,

    Your spi-max-frequency property in the devicetree is set to 25MHz. The ADIS16448 is only rated for up to 2MHz, that's something that should be changed. The other thing is that you set the compatible string to adi,adis16400 while you said you had a ADIS16448. While both devices use the same driver they still have a slightly different register map layout and the driver needs to know which of them it is. Try using "adi,adis16448" for the compatible string.

    - Lars

  • Hi Curtis,

         I am also working on interfacting IMU with the iio similar to your attempt. Even i had the same issue but if you comment out the

                        #nvidia,cs-setup-clk-count = <0x10>; 

                        #nvidia,cs-hold-clk-count = <0x10>; 

                        #nvidia,rx-clk-tap-delay = <0x28>; 

                        #nvidia,tx-clk-tap-delay = <0x0>; 

    you get some readings on the accel_x_raw. I feel there is something wrong with the setup. Please post us if you got better results.

    Thanks,

    Benzun

  • Neither suggestion seems to affect my results, although by looking at the source code, It seems changing the device to adis16448 has loaded in the proper configurations for the biasing and scales.

    I'll keep playing around with parameters.

  • Hi,

       Looks like there is a lower bound on the ma freq generated by the TK1. The lowest freq is around 3Mhz.

    https://devtalk.nvidia.com/default/topic/823132/embedded-systems/-customkernel-the-grinch-21-3-4-for-jetson-tk1-develop

         Have you analyzed it with a signal analyzer? In my case there seems to be garbage generated every few cycles which i feel is due to not setting the delays correctly.

    Thanks,

    Benzun

  • Interesting find Benzun. I'll be following that thread as well now.

    I have taken to following the ioctl() tutorial in the neurorobotictech tutorial.

    If you set spidev up as the tutorial suggests and tweak some parameters in the ArduinoSPI sample code (runs on the TK1 to request data from an arduino), the TK1 can write the parameters out to the device through spidev and using a logic analyzer, I can verify that the device responds to MOSI requests. I am unable to receive the data on the TK1 itself.

    This is not the case still on the IIO side, where I still receive "0"s.

  • It seems that my original TK1 had a bad MISO port... I have since moved to a new TK1.

    On this new board, I am able to get values in from the IIO driver, but like was mentioned, I am unable to drop the max frequency below 3.2MHz without it defaulting back to 25MHz. The IIO driver is working for me, responding with data at this 3.2MHz freq. Considering it is outside of the operating range of the IMU, I do not trust the data that it returns.

    This is not an issue with the IMU or the IIO driver at this stage. Thanks for the help so far

    , have you been able to drop the frequency lower than 3MHz? It seems that I have control in the 3.2-25MHz range, both using device tree modifications and spidev settings, but I can't get lower than 3.2MHz in either case.

  • No I also found it difficult to operate it below 3.2Mhz. How did you diagonize that that the MISO port is not working? I found out that my level converter was not working well. I am trying to debug electrical issues associate with it.

    I have two TK1 boards just incase one does not function well. Were you using any IIO triggers?

  • I figured out the MISO port by basically running the loopback test described in the raspberry pi documentation for SPI. I unplugged everything, shorted MOSI to MISO, and running sample code from the link, you should receive in (on the linux side) exactly what you send out with that setup.

    I had my device tree set up like my first device tree listing in my original post for this to work.

  • Hi  Curtis, Benzun :

    I'm trying to get ADS16445 working in Jetson TK1 .

    Pretty much followed the .dts listing for spi0_1 and spi0_2 slaves @ regs <1> and <2>.

    *Could get /dev/spidev0.1  enumerated ("spidev") .

    * While the system comes up, tries to install  /dev/spidev0.2  - as "adis16400" device - as entered in .dts

     

    dmesg shows the following -

    [   11.211908] adis16400 spi0.2: Power supply below 4.75V.

     

    [   11.218919] adis16400 spi0.2: Power supply above 5.25V.

     

    [   11.225858] adis16400 spi0.2: Flash update failed.

     

    [   11.232407] adis16400 spi0.2: SPI failure.

     

    [   11.238153] adis16400 spi0.2: Sensor overrange.

     

    [   11.244368] adis16400 spi0.2: Self test error.

     

    [   11.250526] adis16400 spi0.2: Flash checksum error.

     

    [   11.257103] adis16400 spi0.2: Alarm 1 active.

     

    [   11.262896] adis16400 spi0.2: Alarm 2 active.

     

    [   11.268722] adis16400 spi0.2: Z-axis gyroscope self-test failure.

     

    [   11.276318] adis16400 spi0.2: Y-axis gyroscope self-test failure.

     

    [   11.283804] adis16400 spi0.2: X-axis gyroscope self-test failure.

     

    [   11.291246] adis16400 spi0.2: X-axis accelerometer self-test failure.

     

    [   11.299249] adis16400 spi0.2: Y-axis accelerometer self-test failure.

     

    [   11.306920] adis16400 spi0.2: Z-axis accelerometer self-test failure.

     

    [   11.314714] adis16400 spi0.2: Self-test failed, trying reset.

     

    [   11.903915] adis16400 spi0.2: Power supply below 4.75V.

     

    [   11.910324] adis16400 spi0.2: Power supply above 5.25V.

     

    [   11.916906] adis16400 spi0.2: Flash update failed.

     

    [   11.923031] adis16400 spi0.2: SPI failure.

     

    [   11.928404] adis16400 spi0.2: Sensor overrange.

     

    [   11.934373] adis16400 spi0.2: Self test error.

     

    [   11.940068] adis16400 spi0.2: Flash checksum error.

     

    [   11.946195] adis16400 spi0.2: Alarm 1 active.

     

    [   11.951822] adis16400 spi0.2: Alarm 2 active.

     

    [   11.951825] adis16400 spi0.2: Z-axis gyroscope self-test failure.

     

    [   11.951827] adis16400 spi0.2: Y-axis gyroscope self-test failure.

     

    [   11.951829] adis16400 spi0.2: X-axis gyroscope self-test failure.

     

    [   11.951832] adis16400 spi0.2: X-axis accelerometer self-test failure.

     

    [   11.951835] adis16400 spi0.2: Y-axis accelerometer self-test failure.

     

    [   11.951838] adis16400 spi0.2: Z-axis accelerometer self-test failure.

     

    [   11.951841] adis16400 spi0.2: Second self-test failed, giving up.

     

    [   11.951867] adis16400: probe of spi0.2 failed with error -5

    As indicated SPI is failing .  Not clear how to configure the  /cs  for this slave.

    Have trouble compiling  .dts  file with  "cs-gpios"  option for  SPI0 master device.

    Any thoughts on using gpios ( pin 164 - PU4?) for ADIS16445 /CS? .

    thanks

    ...ravi

     

  • There is some weird stuff going on in Grinch 21.x if you enable spi debugging (via make menuconfig) and view the dmesg, it mentions chip select is already in use.

    If you're just trying to get SPI up and running, I recommend following this documentation verbatim: Using the Jetson TK1 SPI - Part 1 (Why is SPI important)

    You should get SPI up and running on Grinch 19.3.8 via spidev by the end of part 3.  Then you can add the IMU to the DTS in the same way you put the spidev device (see my DTS for the spi0_1 device) and it should respond nominally, so long as you don't need a clock slower than 3.2MHz

    Also, make sure to follow the recommendations of larc, "Try using "adi,adis16448" for the compatible string.", in your case "adi,adis16445"