Post Go back to editing

How to add two adrv9002 with one zcu102 board

Category: Software
Product Number: adrv9002
Software Version: 2022_R2

Hi

    I'm using the open linux + HDL development platform with zcu102 and adrv9002, the default system provided by adi is one zcu102 to one adrv9002.We now want to connect another adrv9002 on FMC1 of zcu102. Which modules should be added or modified(software and hardware)?

Thanks

  • Now I changed the HDL and device tree, added another adrv9002, the two adrv9002 are under same spi0, the adrv9002_1 use spi_cs[0] and adrv9002_2 use spi_cs[1], but the second adrv9002 can't be found when system boot.

  • Hi,

    Could you share your devicetree and boot log?

    - Nuno Sá

  • Hi

        The previous problem of unable to find second board is that I removed the RX2 of second board, because the vivado compiles fail for can't use same IO DELAY GROUP in same bank since FMC0 RX1 and FMC1 RX2 both connected to bank 66. Now I disabled the IO DELAY control and enabled the RX2 of second board and so I can find two devices both.

        Belows are my device tree and boot log.

    /delete-node/ &adrv1_axi_adrv9001;
    /delete-node/ &adrv1_axi_adrv9001_rx1_dma;
    /delete-node/ &adrv1_axi_adrv9001_rx2_dma;
    /delete-node/ &adrv1_axi_adrv9001_tx1_dma;
    /delete-node/ &adrv1_axi_adrv9001_tx2_dma;
    /delete-node/ &misc_clk_0;
    /delete-node/ &adrv2_axi_adrv9001;
    /delete-node/ &adrv2_axi_adrv9001_rx1_dma;
    /delete-node/ &adrv2_axi_adrv9001_rx2_dma;
    /delete-node/ &adrv2_axi_adrv9001_tx1_dma;
    /delete-node/ &adrv2_axi_adrv9001_tx2_dma;
    /delete-node/ &axi_sysid_0;
    
    // SPDX-License-Identifier: GPL-2.0
    #include <dt-bindings/iio/adc/adi,adrv9002.h>
    
    / {
    	clocks {
    		adrv9002_clkin_0: clock@0 {
    			compatible = "fixed-clock";
    
    			clock-frequency = <38400000>;
    			clock-output-names = "adrv9002_ext_refclk";
    			#clock-cells = <0>;
    		};
    		adrv9002_clkin_1: clock@1 {
    			compatible = "fixed-clock";
    
    			clock-frequency = <38400000>;
    			clock-output-names = "adrv9002_ext_refclk2";
    			#clock-cells = <0>;
    		};
    
    	};
    
    };
    
    &fmc_spi {
    	status = "okay";
            /* HPC0 */
    	adc0_adrv9002_0: adrv9002-phy-0@0 {
    
    		compatible = "adi,adrv9002";
    		reg = <0>;
    
    		interrupt-parent = <&gpio>;
    		interrupts = <122 IRQ_TYPE_EDGE_RISING>;
    
    		spi-max-frequency = <20000000>;
    		/* Clocks */
    		clocks = <&adrv9002_clkin_0>;
    		clock-names = "adrv9002_ext_refclk";
    		clock-output-names = "rx1_sampl_clk", "tx1_sampl_clk", "tdd1_intf_clk",
    				"rx2_sampl_clk", "tx2_sampl_clk", "tdd2_intf_clk";
    		#clock-cells = <1>;
    
    		adi,channels {
    			#address-cells = <1>;
    			#size-cells = <0>;
    
    			rx@0 {
    				reg = <0>;
    				adi,port = <0>;
    				orx-gpios = <&gpio 110 GPIO_ACTIVE_HIGH>; /* dgpio0 */
    			};
    
    			rx@1 {
    				reg = <1>;
    				adi,port = <0>;
    				orx-gpios = <&gpio 111 GPIO_ACTIVE_HIGH>; /* dgpio1 */
    			};
    
    			tx@0 {
    				reg = <0>;
    				adi,port = <1>;
    				adi,dpd;
    			};
    
    			tx@1 {
    				reg = <1>;
    				adi,port = <1>;
    				adi,dpd;
    			};
    
    		};
    
    		adi,gpios {
    			#address-cells = <1>;
    			#size-cells = <0>;
    
    			gpio@0 {
    				reg = <ADRV9002_DGPIO_0>;
    				adi,signal = <ADRV9002_GPIO_SIGNAL_ORX_ENABLE_1>;
    			};
    
    			gpio@1 {
    				reg = <ADRV9002_DGPIO_1>;
    				adi,signal = <ADRV9002_GPIO_SIGNAL_ORX_ENABLE_2>;
    			};
    		};
    
    		/* Frequency hopping properties */
    		adi,frequency-hopping {
    			adi,fh-mode = <ADRV9002_FH_LO_RETUNE_REALTIME_PROCESS_DUAL_HOP>;
    			adi-fh-rx-zero-if-en;
    
    			/* Depends on @adi,fh-mode being set to dual hop */
    			adi,fh-hop-signal-2 {
    				adi,fh-hop-rx-ports = <ADRV9002_RX_2>;
    				adi,fh-hop-tx-ports = <ADRV9002_TX_2>;
    			};
    		};
    	};
    	/* HPC1 */
    	adc0_adrv9002_1: adrv9002-phy-1@1 {
    
    		compatible = "adi,adrv9002";
    		reg = <2>;
    
    		interrupt-parent = <&gpio>;
    		interrupts = <150 IRQ_TYPE_EDGE_RISING>;
    
    		spi-max-frequency = <20000000>;
    		/* Clocks */
    		clocks = <&adrv9002_clkin_1>;
    		clock-names = "adrv9002_ext_refclk";
    		clock-output-names = "rx1_sampl_clk", "tx1_sampl_clk", "tdd1_intf_clk",
    				"rx2_sampl_clk", "tx2_sampl_clk", "tdd2_intf_clk";
    		#clock-cells = <1>;
    
    		adi,channels {
    			#address-cells = <1>;
    			#size-cells = <0>;
    
    			rx@0 {
    				reg = <0>;
    				adi,port = <0>;
    				orx-gpios = <&gpio 138 GPIO_ACTIVE_HIGH>; /* dgpio0 */
    			};
    
    			rx@1 {
    				reg = <1>;
    				adi,port = <0>;
    				orx-gpios = <&gpio 139 GPIO_ACTIVE_HIGH>; /* dgpio1 */
    			};
    
    			tx@0 {
    				reg = <0>;
    				adi,port = <1>;
    				adi,dpd;
    			};
    
    			tx@1 {
    				reg = <1>;
    				adi,port = <1>;
    				adi,dpd;
    			};
    
    		};
    
    		adi,gpios {
    			#address-cells = <1>;
    			#size-cells = <0>;
    
    			gpio@0 {
    				reg = <ADRV9002_DGPIO_0>;
    				adi,signal = <ADRV9002_GPIO_SIGNAL_ORX_ENABLE_1>;
    			};
    
    			gpio@1 {
    				reg = <ADRV9002_DGPIO_1>;
    				adi,signal = <ADRV9002_GPIO_SIGNAL_ORX_ENABLE_2>;
    			};
    		};
    
    		/* Frequency hopping properties */
    		adi,frequency-hopping {
    			adi,fh-mode = <ADRV9002_FH_LO_RETUNE_REALTIME_PROCESS_DUAL_HOP>;
    			adi-fh-rx-zero-if-en;
    
    			/* Depends on @adi,fh-mode being set to dual hop */
    			adi,fh-hop-signal-2 {
    				adi,fh-hop-rx-ports = <ADRV9002_RX_2>;
    				adi,fh-hop-tx-ports = <ADRV9002_TX_2>;
    			};
    		};
    	};
    };
    
    // SPDX-License-Identifier: GPL-2.0
    /*
     * Analog Devices ADRV9002
     *
     * hdl_project: <adrv9001/zcu102>
     * board_revision: <>
     *
     * Copyright (C) 2020 Analog Devices Inc.
     */
    #include "zynqmp-zcu102-rev1.0.dts"
    #include <dt-bindings/interrupt-controller/irq.h>
    #include <dt-bindings/gpio/gpio.h>
    
    
    &i2c1 {
    	i2c-mux@75 {
    		i2c@0 { /* HPC0 */
    			#address-cells = <1>;
    			#size-cells = <0>;
    			reg = <0>;
    			/* HPC0_IIC */
    			eeprom@50 {
    				compatible = "at24,24c02";
    				reg = <0x50>;
    			};
    
    		};
    	};
    };
    
    / {
    	fpga_axi  {
    		interrupt-parent = <&gic>;
    		compatible = "simple-bus";
    		#address-cells = <0x1>;
    		#size-cells = <0x1>;
    		ranges = <0 0 0 0xffffffff>;
    		
    		/* HPC0 */
    		rx_dma_0: dma_0@84a30000 {
    			compatible = "adi,axi-dmac-1.00.a";
    			reg = <0x84a30000 0x10000>;
    			#dma-cells = <1>;
    			interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
    			clocks = <&zynqmp_clk 71>;
    
    			adi,channels {
    				#size-cells = <0>;
    				#address-cells = <1>;
    
    				dma-channel@0 {
    					reg = <0>;
    					adi,source-bus-width = <64>;
    					adi,source-bus-type = <2>;
    					adi,destination-bus-width = <64>;
    					adi,destination-bus-type = <0>;
    				};
    			};
    		};
    
    		tx_dma_0: dma_0@84a50000 {
    			compatible = "adi,axi-dmac-1.00.a";
    			reg = <0x84a50000 0x10000>;
    			#dma-cells = <1>;
    			interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
    			clocks = <&zynqmp_clk 71>;
    
    			adi,channels {
    				#size-cells = <0>;
    				#address-cells = <1>;
    
    				dma-channel@0 {
    					reg = <0>;
    					adi,source-bus-width = <64>;
    					adi,source-bus-type = <0>;
    					adi,destination-bus-width = <64>;
    					adi,destination-bus-type = <2>;
    				};
    			};
    		};
    
    		axi_adrv9002_core_rx_0: axi-adrv9002-rx-lpc_0@84a00000 {
    			compatible = "adi,axi-adrv9002-rx-1.0";
    			reg = <0x84a00000 0x6000>;
    			clocks = <&adc0_adrv9002_0 0>;
    			dmas = <&rx_dma_0 0>;
    			dma-names = "rx";
    			spibus-connected = <&adc0_adrv9002_0>;
    		};
    
    		axi_adrv9002_core_tx_0: axi-adrv9002-tx-lpc_0@84a04000 {
    			compatible = "adi,axi-adrv9002-rx2tx2-1.0";
    			reg = <0x84a02000 0x2000>;
    			clocks = <&adc0_adrv9002_0 1>;
    			clock-names = "sampl_clk";
    			dmas = <&tx_dma_0 0>;
    			dma-names = "tx";
    			adi,axi-dds-default-scale = <0x800>;
    			adi,axi-dds-default-frequency = <2000000>;
    		};
    
    		axi_adrv9002_core_tdd_0: axi-adrv9002-core-tdd-lpc_0@84a0C800 {
    			compatible = "adi,axi-tdd-1.00";
    			reg = <0x84a0C800 0x400>;
    			clocks = <&zynqmp_clk 71>, <&adc0_adrv9002_0 2>;
    			clock-names = "s_axi_aclk", "intf_clk";
    		};
    
    		/* HPC1  */
    		rx_dma_1: dma_1@80010000 {
    			compatible = "adi,axi-dmac-1.00.a";
    			reg = <0x80010000 0x10000>;
    			#dma-cells = <1>;
    			interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
    			clocks = <&zynqmp_clk 71>;
    
    			adi,channels {
    				#size-cells = <0>;
    				#address-cells = <1>;
    
    				dma-channel@0 {
    					reg = <0>;
    					adi,source-bus-width = <64>;
    					adi,source-bus-type = <2>;
    					adi,destination-bus-width = <64>;
    					adi,destination-bus-type = <0>;
    				};
    			};
    		};
    
    		tx_dma_1: dma_1@80030000 {
    			compatible = "adi,axi-dmac-1.00.a";
    			reg = <0x80030000 0x10000>;
    			#dma-cells = <1>;
    			interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>;
    			clocks = <&zynqmp_clk 71>;
    
    			adi,channels {
    				#size-cells = <0>;
    				#address-cells = <1>;
    
    				dma-channel@0 {
    					reg = <0>;
    					adi,source-bus-width = <64>;
    					adi,source-bus-type = <0>;
    					adi,destination-bus-width = <64>;
    					adi,destination-bus-type = <2>;
    				};
    			};
    		};
    
    		axi_adrv9002_core_rx_1: axi-adrv9002-rx-lpc_1@80000000 {
    			compatible = "adi,axi-adrv9002-rx-1.0";
    			reg = <0x80000000 0x6000>;
    			clocks = <&adc0_adrv9002_1 0>;
    			dmas = <&rx_dma_1 0>;
    			dma-names = "rx";
    			spibus-connected = <&adc0_adrv9002_1>;
    		};
    
    		axi_adrv9002_core_tx_1: axi-adrv9002-tx-lpc_1@80004000 {
    			compatible = "adi,axi-adrv9002-rx2tx2-1.0";
    			reg = <0x80002000 0x2000>;
    			clocks = <&adc0_adrv9002_1 1>;
    			clock-names = "sampl_clk";
    			dmas = <&tx_dma_1 0>;
    			dma-names = "tx";
    			adi,axi-dds-default-scale = <0x800>;
    			adi,axi-dds-default-frequency = <2000000>;
    		};
    
    		axi_adrv9002_core_tdd_1: axi-adrv9002-core-tdd-lpc_1@8000C800 {
    			compatible = "adi,axi-tdd-1.00";
    			reg = <0x8000C800 0x400>;
    			clocks = <&zynqmp_clk 71>, <&adc0_adrv9002_1 2>;
    			clock-names = "s_axi_aclk", "intf_clk";
    		};
    
    		axi_sysid_0: axi-sysid-0@85000000 {
    			compatible = "adi,axi-sysid-1.00.a";
    			reg = <0x85000000 0x10000>;
    		};
    
        };
    };
    
    &spi0 {
    	status = "okay";
    };
    
    #define fmc_spi spi0
    
    #include "pml-adi-dual-adrv9002.dtsi"
    
    /* HPC0
    Name		HDL	Linux
    ssi_sync	54	132
    mcs		53	131
    output_enable	52	130
    tx2_enable	51	129
    tx1_enable	50	128
    rx2_enable	49	127
    rx1_enable	48	126
    sm_fan_tach	47	125
    reset_trx	46	124
    mode		45	123
    gp_int		44	122
    dgpio_11	43	121
    dgpio_10	42	120
    dgpio_9		41	119
    dgpio_8		40	118
    dgpio_7		39	117
    dgpio_6		38	116
    dgpio_5		37	115
    dgpio_4		36	114
    dgpio_3		35	113
    dgpio_2		34	112
    dgpio_1		33	111
    dgpio_0		32	110
    */
    
    /* HPC1
    Name		HDL	Linux
    ssi_sync	82	160
    mcs		81	159
    output_enable	80	158
    tx2_enable	79	157
    tx1_enable	78	156
    rx2_enable	77	155
    rx1_enable	76	154
    sm_fan_tach	75	153
    reset_trx	74	152
    mode		73	151
    gp_int		72	150
    dgpio_11	71	149
    dgpio_10	70	148
    dgpio_9		69	147
    dgpio_8		68	146
    dgpio_7		67	145
    dgpio_6		66	144
    dgpio_5		65	143
    dgpio_4		64	142
    dgpio_3		63	141
    dgpio_2		62	140
    dgpio_1		61	139
    dgpio_0		60	138
    */
    
    &adc0_adrv9002_0 {
    	compatible = "adi,adrv9002-rx2tx2";
    	reset-gpios = <&gpio 124 GPIO_ACTIVE_LOW>;
    	ssi-sync-gpios = <&gpio 132 GPIO_ACTIVE_HIGH>;
    	clock-output-names = "rx1_sampl_clk", "tx1_sampl_clk", "tdd1_intf_clk";
    };
    &adc0_adrv9002_1 {
    	compatible = "adi,adrv9002-rx2tx2";
    	reset-gpios = <&gpio 152 GPIO_ACTIVE_LOW>;
    	ssi-sync-gpios = <&gpio 160 GPIO_ACTIVE_HIGH>;
    	clock-output-names = "rx1_sampl_clk", "tx1_sampl_clk", "tdd1_intf_clk";
    };
    
    zcu102_2024-11-04_17_27_05.log

       My problem now is the second board's txs can't send signals and rxs are all noises. The first board is normal. I added ilas in system_top.v and the adc1_data_valid and adc1_enable are normal, so where would cause this problem?

     Thanks

  • Hi,

    Not seeing anything odd on the DT. Might be HDL related which is not something I can help much. Will ping someone...

    - Nuno Sá

  • Hi,

    Can you add the below define
     

    #define DEBUG
     
    in drivers/iio/adc/navassa/adrv9002.c and rebuild the Image.

    Reboot the system with the new image and attach the UART log. This will give us the digital interface tunning results.

    Have you used the USE_RX_CLK_FOR_TX on the new FMC connector?
    maybe give uss more info about the SSI clocks for RX and TX on the new fmc.
    What hdl branch are you working on?

    Andrei

  • Hi

       I added #define DEBUG in adrv9002.c and rebuit kernel, this is the new boot log

    zcu102_2024-11-05_11_13_00.log

    Have you used the USE_RX_CLK_FOR_TX on the new FMC connector?

    Yes, I confirmed it's value is 1,same as fmc0

    What hdl branch are you working on?

    2022R2

    maybe give uss more info about the SSI clocks for RX and TX on the new fmc.

    My dev clock is internal 38.4MHz, RX1/RX2 and TX1/TX2 Dataport Sample Rate are 15.36MSPS, RF Channel Bandwidth are 10MHz, Interface Rate are 15.36MSPS

  • Hi

        I found that both the adrv9002_1 and adrv9002_2 block in iio-oscilloscope, their ENSM mode both control the board on FMC 0, that's why the second board did not work normal.

        So now the problem is why this two adrv9002 block controlled same adrv9002 board, does it have relation to the iio name ? because i found the name of iio has the same

    Thanks

  • Hi,

    Sorry for the delayed reply.
    I'm looking for this type of message from the driver.

    [ 6.942241] SAMPL CLK: 15360000 tuning: RX1
    [ 6.946446] 0:1:2:3:4:5:6:7
    [ 6.949440] 0:o o o o o o o o
    [ 6.952506] 1:o o o o o o o o
    [ 6.955575] 2:o o o o o o o o
    [ 6.958652] 3:o o o o o o o o
    [ 6.961723] 4:o o o o o o o o
    [ 6.964795] 5:o o o o o o o o
    [ 6.967861] 6:o o o o o o o o
    [ 6.970931] 7:o o o o o o o o
    [ 7.340456] SAMPL CLK: 15360000 tuning: TX1
    [ 7.344641] 0:1:2:3:4:5:6:7
    [ 7.347623] 0:o # # o o o o o
    [ 7.350694] 1:o # # # o o o o
    [ 7.353767] 2:o o # # # o o o
    [ 7.356839] 3:o o o # # # o o
    [ 7.359905] 4:o o o o # # # #
    [ 7.362975] 5:o o o o o # # #
    [ 7.366048] 6:o o o o o o # #
    [ 7.369120] 7:o o o o o o o #


    Couldn't find it in your log.
      the driver has the same functionality for Petalinux?

    Andrei

  • HI

       Thanks for your reply, I have found the reason, because the name of iio core are same, so both my cmds from iio-oscilloscope sent to adrv9002 in FMC0. The solution is adding a label in device tree like label = "axi-adrv9002-phy-1" under adrv9002-phy node to make a distinguish with adrv9002-phy-0.

        up to now, two adrv9002 on one zcu102 can work normal with oscilloscope. But I still have another question, if using pyadi-iio, the function SDR=adi.adrv9002("ip:192.168.1.10") can only find one device, how can pyadi-iio work like iio-oscilloscope which can find both two device?

    Thanks

  •   might be able to help with pyadi-iio. But I'm still not convinced that osc plugin is working as good as you think...

    - Nuno Sá