Unable to read data written by AXI ADI DMA from Petalinux

Hello,

I have a setup where an AD9652 evaluation board is connected to a Microzed running Petalinux. The Petalinux I've built uses the ADI Kernel with the AXI ADI DMA and AD9467 drivers enabled. The PL side includes an AD9652 front end IP and an AD9467 AXI DMA block to write the data from the AD9652 block to microzed memory (high OCM addresses 0xFFFC0000 to 0xFFFFFFFF.) This PL design is the example AD9467 Vivado project for the ZedBoard modified to work with the AD9652 and ported to the Microzed. When I boot petalinux, my bootlog includes statements like:

DCO 0x0 CLK 250000000 Hz

cf_axi_adc 43c10000.axi_ad9652: ADI AIM (9.00.b) at 0x43C10000 mapped to 0xf09c0000, probed ADC AD9652 as MASTER

which tell me that the Microzed is successfully probing the AD9652 over the SPI bus.

The problem I am unable to solve is that I cannot see the data that the DMA is supposedly saving to the OCM. I have a python script that runs the following:

payload_size = 0x40000
ADC_DMA_OFFST_ADDR = 0x43C00000
f = os.open("/dev/mem", os.O_SYNC | os.O_RDWR)
mapf_dma = mmap.mmap(f, 0x10000, access=mmap.ACCESS_WRITE, offset=ADC_DMA_OFFST_ADDR)

# Init once
# Enable DMA channel
mapf_dma[0x400:0x404] = struct.pack("I", 1)
# Set TLAST, PARTIAL_REPORTING_EN and CYCLE
mapf_dma[0x40c:0x410] = struct.pack("I", 6)
# Set transfer size of payload_size bytes
mapf_dma[0x418:0x41c] = struct.pack("I", payload_size)
# Set destination address (0xfffc0000)
mapf_dma[0x410:0x414] = struct.pack("I", 0xfffc0000)
# Send start signal
mapf_dma[0x408:0x40c] = struct.pack("I", 1)

while(1):
    addr = struct.unpack("I", mapf_dma[0x434:0x438])[0]
    print(format(addr, '08x'))
    if(addr == 0xfffc0000):
        break

If I run this code, I get a few printouts which tell me that the DMA runs once and saves the data to the correct location:

fffc0b80
fffd8b80
fffe5200
fffefd80
ffffa480
fffc0000

This tells me that the DMA runs once and is writing to the correct range and while it does so, the while loop in the python script above grabs a few of the target addresses, which look correct.

Then, I use another script to grab the data from the OCM addresses between 0xFFFC0000 and 0xFFFFFFFF and send them to a PC and plot them. However, I am unable to see the data that the ADC is producing . I verify this by writing something of my own to the OCM addresses using mmap, then running the above script, and then reading it out. The above script does not change the values written manually by me, thus telling me that the DMA is, for whatever reason, not writing to the above addresses or the changes are not visible to Linux.

I thought that this may be a caching issue so I removed the cache-controller entry in the device tree when building petalinux. However it did not change the result at all, even though the bootlog no longer includes any statements about L2 cache (telling me that the cache is indeed disabled.)

can you please suggest any potential reasons why I can't see the data written by the DMA? in the zedboard implementation of the IIO oscilloscope, do you do any sort of cache manipulations before reading the data? I have successfully used mmap to read and plot the data on the zedboard implementation so it should also work here as well.

Please advise what I may be doing wrong.

Thank you,

svv9

  • 0
    •  Analog Employees 
    on Oct 29, 2020 12:19 PM 25 days ago

    Hi,

    Can you post the devicetree?

    Thanks,

    Alexandru Tachici

  • Hi, here's the devicetree:

    /dts-v1/;
    
    /memreserve/	0x00000000076c0000 0x0000000000003000;
    /memreserve/	0x00000000076c6000 0x0000000000939680;
    / {
    	#address-cells = <0x1>;
    	#size-cells = <0x1>;
    	compatible = "xlnx,zynq-7000";
    
    	cpus {
    		#address-cells = <0x1>;
    		#size-cells = <0x0>;
    
    		cpu@0 {
    			compatible = "arm,cortex-a9";
    			device_type = "cpu";
    			reg = <0x0>;
    			clocks = <0x1 0x3>;
    			clock-latency = <0x3e8>;
    			cpu0-supply = <0x2>;
    			operating-points = <0xa2c2a 0xf4240 0x51615 0xf4240>;
    		};
    
    		cpu@1 {
    			compatible = "arm,cortex-a9";
    			device_type = "cpu";
    			reg = <0x1>;
    			clocks = <0x1 0x3>;
    		};
    	};
    
    	fpga-full {
    		compatible = "fpga-region";
    		fpga-mgr = <0x3>;
    		#address-cells = <0x1>;
    		#size-cells = <0x1>;
    		ranges;
    	};
    
    	pmu@f8891000 {
    		compatible = "arm,cortex-a9-pmu";
    		interrupts = <0x0 0x5 0x4 0x0 0x6 0x4>;
    		interrupt-parent = <0x4>;
    		reg = <0xf8891000 0x1000 0xf8893000 0x1000>;
    	};
    
    	fixedregulator {
    		compatible = "regulator-fixed";
    		regulator-name = "VCCPINT";
    		regulator-min-microvolt = <0xf4240>;
    		regulator-max-microvolt = <0xf4240>;
    		regulator-boot-on;
    		regulator-always-on;
    		linux,phandle = <0x2>;
    		phandle = <0x2>;
    	};
    
    	amba {
    		u-boot,dm-pre-reloc;
    		compatible = "simple-bus";
    		#address-cells = <0x1>;
    		#size-cells = <0x1>;
    		interrupt-parent = <0x4>;
    		ranges;
    
    		adc@f8007100 {
    			compatible = "xlnx,zynq-xadc-1.00.a";
    			reg = <0xf8007100 0x20>;
    			interrupts = <0x0 0x7 0x4>;
    			interrupt-parent = <0x4>;
    			clocks = <0x1 0xc>;
    		};
    
    		can@e0008000 {
    			compatible = "xlnx,zynq-can-1.0";
    			status = "disabled";
    			clocks = <0x1 0x13 0x1 0x24>;
    			clock-names = "can_clk", "pclk";
    			reg = <0xe0008000 0x1000>;
    			interrupts = <0x0 0x1c 0x4>;
    			interrupt-parent = <0x4>;
    			tx-fifo-depth = <0x40>;
    			rx-fifo-depth = <0x40>;
    		};
    
    		can@e0009000 {
    			compatible = "xlnx,zynq-can-1.0";
    			status = "disabled";
    			clocks = <0x1 0x14 0x1 0x25>;
    			clock-names = "can_clk", "pclk";
    			reg = <0xe0009000 0x1000>;
    			interrupts = <0x0 0x33 0x4>;
    			interrupt-parent = <0x4>;
    			tx-fifo-depth = <0x40>;
    			rx-fifo-depth = <0x40>;
    		};
    
    		gpio@e000a000 {
    			compatible = "xlnx,zynq-gpio-1.0";
    			#gpio-cells = <0x2>;
    			clocks = <0x1 0x2a>;
    			gpio-controller;
    			interrupt-controller;
    			#interrupt-cells = <0x2>;
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x14 0x4>;
    			reg = <0xe000a000 0x1000>;
    			emio-gpio-width = <0x40>;
    			gpio-mask-high = <0x0>;
    			gpio-mask-low = <0x5600>;
    		};
    
    		i2c@e0004000 {
    			compatible = "cdns,i2c-r1p10";
    			status = "disabled";
    			clocks = <0x1 0x26>;
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x19 0x4>;
    			reg = <0xe0004000 0x1000>;
    			#address-cells = <0x1>;
    			#size-cells = <0x0>;
    		};
    
    		i2c@e0005000 {
    			compatible = "cdns,i2c-r1p10";
    			status = "disabled";
    			clocks = <0x1 0x27>;
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x30 0x4>;
    			reg = <0xe0005000 0x1000>;
    			#address-cells = <0x1>;
    			#size-cells = <0x0>;
    		};
    
    		interrupt-controller@f8f01000 {
    			compatible = "arm,cortex-a9-gic";
    			#interrupt-cells = <0x3>;
    			interrupt-controller;
    			reg = <0xf8f01000 0x1000 0xf8f00100 0x100>;
    			num_cpus = <0x2>;
    			num_interrupts = <0x60>;
    			linux,phandle = <0x4>;
    			phandle = <0x4>;
    		};
    
    		memory-controller@f8006000 {
    			compatible = "xlnx,zynq-ddrc-a05";
    			reg = <0xf8006000 0x1000>;
    		};
    
    		ocmc@f800c000 {
    			compatible = "xlnx,zynq-ocmc-1.0";
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x3 0x4>;
    			reg = <0xf800c000 0x1000>;
    		};
    
    		serial@e0000000 {
    			compatible = "xlnx,xuartps", "cdns,uart-r1p8";
    			status = "disabled";
    			clocks = <0x1 0x17 0x1 0x28>;
    			clock-names = "uart_clk", "pclk";
    			reg = <0xe0000000 0x1000>;
    			interrupts = <0x0 0x1b 0x4>;
    		};
    
    		serial@e0001000 {
    			compatible = "xlnx,xuartps", "cdns,uart-r1p8";
    			status = "okay";
    			clocks = <0x1 0x18 0x1 0x29>;
    			clock-names = "uart_clk", "pclk";
    			reg = <0xe0001000 0x1000>;
    			interrupts = <0x0 0x32 0x4>;
    			device_type = "serial";
    			port-number = <0x0>;
    		};
    
    		spi@e0006000 {
    			compatible = "xlnx,zynq-spi-r1p6";
    			reg = <0xe0006000 0x1000>;
    			status = "okay";
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x1a 0x4>;
    			clocks = <0x1 0x19 0x1 0x22>;
    			clock-names = "ref_clk", "pclk";
    			#address-cells = <0x1>;
    			#size-cells = <0x0>;
    			is-decoded-cs = <0x0>;
    			num-cs = <0x1>;
    
    			ad9652@0 {
    				compatible = "adi,ad9652";
    				reg = <0x0>;
    				spi-max-frequency = <0xf4240>;
    				adi,spi-3wire-enable;
    				clocks = <0x16 0x0>;
    				clock-names = "adc_clk";
    				linux,phandle = <0x11>;
    				phandle = <0x11>;
    			};
    		};
    
    		spi@e0007000 {
    			compatible = "xlnx,zynq-spi-r1p6";
    			reg = <0xe0007000 0x1000>;
    			status = "okay";
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x31 0x4>;
    			clocks = <0x1 0x1a 0x1 0x23>;
    			clock-names = "ref_clk", "pclk";
    			#address-cells = <0x1>;
    			#size-cells = <0x0>;
    			is-decoded-cs = <0x0>;
    			num-cs = <0x3>;
    		};
    
    		spi@e000d000 {
    			clock-names = "ref_clk", "pclk";
    			clocks = <0x1 0xa 0x1 0x2b>;
    			compatible = "xlnx,zynq-qspi-1.0";
    			status = "okay";
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x13 0x4>;
    			reg = <0xe000d000 0x1000>;
    			#address-cells = <0x1>;
    			#size-cells = <0x0>;
    			is-dual = <0x0>;
    			num-cs = <0x1>;
    			spi-rx-bus-width = <0x4>;
    			spi-tx-bus-width = <0x4>;
    
    			flash@0 {
    				compatible = "n25q512a", "micron,m25p80";
    				reg = <0x0>;
    				#address-cells = <0x1>;
    				#size-cells = <0x1>;
    				spi-max-frequency = <0x2faf080>;
    
    				partition@0x00000000 {
    					label = "boot";
    					reg = <0x0 0x500000>;
    				};
    
    				partition@0x00500000 {
    					label = "bootenv";
    					reg = <0x500000 0x20000>;
    				};
    
    				partition@0x00520000 {
    					label = "kernel";
    					reg = <0x520000 0xae0000>;
    				};
    
    				partition@0x01000000 {
    					label = "spare";
    					reg = <0x1000000 0x0>;
    				};
    			};
    		};
    
    		memory-controller@e000e000 {
    			#address-cells = <0x1>;
    			#size-cells = <0x1>;
    			status = "disabled";
    			clock-names = "memclk", "aclk";
    			clocks = <0x1 0xb 0x1 0x2c>;
    			compatible = "arm,pl353-smc-r2p1";
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x12 0x4>;
    			ranges;
    			reg = <0xe000e000 0x1000>;
    
    			flash@e1000000 {
    				status = "disabled";
    				compatible = "arm,pl353-nand-r2p1";
    				reg = <0xe1000000 0x1000000>;
    				#address-cells = <0x1>;
    				#size-cells = <0x1>;
    			};
    
    			flash@e2000000 {
    				status = "disabled";
    				compatible = "cfi-flash";
    				reg = <0xe2000000 0x2000000>;
    				#address-cells = <0x1>;
    				#size-cells = <0x1>;
    			};
    		};
    
    		ethernet@e000b000 {
    			compatible = "cdns,zynq-gem", "cdns,gem";
    			reg = <0xe000b000 0x1000>;
    			status = "okay";
    			interrupts = <0x0 0x16 0x4>;
    			clocks = <0x1 0x1e 0x1 0x1e 0x1 0xd>;
    			clock-names = "pclk", "hclk", "tx_clk";
    			#address-cells = <0x1>;
    			#size-cells = <0x0>;
    			phy-mode = "rgmii-id";
    			xlnx,ptp-enet-clock = <0x69f6bcb>;
    			local-mac-address = [00 0a 35 00 1e 53];
    		};
    
    		ethernet@e000c000 {
    			compatible = "cdns,zynq-gem", "cdns,gem";
    			reg = <0xe000c000 0x1000>;
    			status = "disabled";
    			interrupts = <0x0 0x2d 0x4>;
    			clocks = <0x1 0x1f 0x1 0x1f 0x1 0xe>;
    			clock-names = "pclk", "hclk", "tx_clk";
    			#address-cells = <0x1>;
    			#size-cells = <0x0>;
    		};
    
    		sdhci@e0100000 {
    			compatible = "arasan,sdhci-8.9a";
    			status = "okay";
    			clock-names = "clk_xin", "clk_ahb";
    			clocks = <0x1 0x15 0x1 0x20>;
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x18 0x4>;
    			reg = <0xe0100000 0x1000>;
    			xlnx,has-cd = <0x1>;
    			xlnx,has-power = <0x0>;
    			xlnx,has-wp = <0x1>;
    		};
    
    		sdhci@e0101000 {
    			compatible = "arasan,sdhci-8.9a";
    			status = "disabled";
    			clock-names = "clk_xin", "clk_ahb";
    			clocks = <0x1 0x16 0x1 0x21>;
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x2f 0x4>;
    			reg = <0xe0101000 0x1000>;
    		};
    
    		slcr@f8000000 {
    			u-boot,dm-pre-reloc;
    			#address-cells = <0x1>;
    			#size-cells = <0x1>;
    			compatible = "xlnx,zynq-slcr", "syscon", "simple-mfd";
    			reg = <0xf8000000 0x1000>;
    			ranges;
    			linux,phandle = <0x5>;
    			phandle = <0x5>;
    
    			clkc@100 {
    				u-boot,dm-pre-reloc;
    				#clock-cells = <0x1>;
    				compatible = "xlnx,ps7-clkc";
    				fclk-enable = <0x3>;
    				clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci", "lqspi", "smc", "pcap", "gem0", "gem1", "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper", "swdt", "dbg_trc", "dbg_apb";
    				reg = <0x100 0x100>;
    				ps-clk-frequency = <0x1fca055>;
    				linux,phandle = <0x1>;
    				phandle = <0x1>;
    			};
    
    			rstc@200 {
    				compatible = "xlnx,zynq-reset";
    				reg = <0x200 0x48>;
    				#reset-cells = <0x1>;
    				syscon = <0x5>;
    			};
    
    			pinctrl@700 {
    				compatible = "xlnx,pinctrl-zynq";
    				reg = <0x700 0x200>;
    				syscon = <0x5>;
    			};
    		};
    
    		dmac@f8003000 {
    			compatible = "arm,pl330", "arm,primecell";
    			reg = <0xf8003000 0x1000>;
    			interrupt-parent = <0x4>;
    			interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3", "dma4", "dma5", "dma6", "dma7";
    			interrupts = <0x0 0xd 0x4 0x0 0xe 0x4 0x0 0xf 0x4 0x0 0x10 0x4 0x0 0x11 0x4 0x0 0x28 0x4 0x0 0x29 0x4 0x0 0x2a 0x4 0x0 0x2b 0x4>;
    			#dma-cells = <0x1>;
    			#dma-channels = <0x8>;
    			#dma-requests = <0x4>;
    			clocks = <0x1 0x1b>;
    			clock-names = "apb_pclk";
    		};
    
    		devcfg@f8007000 {
    			compatible = "xlnx,zynq-devcfg-1.0";
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x8 0x4>;
    			reg = <0xf8007000 0x100>;
    			clocks = <0x1 0xc 0x1 0xf 0x1 0x10 0x1 0x11 0x1 0x12>;
    			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
    			syscon = <0x5>;
    			linux,phandle = <0x3>;
    			phandle = <0x3>;
    		};
    
    		efuse@f800d000 {
    			compatible = "xlnx,zynq-efuse";
    			reg = <0xf800d000 0x20>;
    		};
    
    		timer@f8f00200 {
    			compatible = "arm,cortex-a9-global-timer";
    			reg = <0xf8f00200 0x20>;
    			interrupts = <0x1 0xb 0x301>;
    			interrupt-parent = <0x4>;
    			clocks = <0x1 0x4>;
    		};
    
    		timer@f8001000 {
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0xa 0x4 0x0 0xb 0x4 0x0 0xc 0x4>;
    			compatible = "cdns,ttc";
    			clocks = <0x1 0x6>;
    			reg = <0xf8001000 0x1000>;
    		};
    
    		timer@f8002000 {
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x25 0x4 0x0 0x26 0x4 0x0 0x27 0x4>;
    			compatible = "cdns,ttc";
    			clocks = <0x1 0x6>;
    			reg = <0xf8002000 0x1000>;
    		};
    
    		timer@f8f00600 {
    			interrupt-parent = <0x4>;
    			interrupts = <0x1 0xd 0x301>;
    			compatible = "arm,cortex-a9-twd-timer";
    			reg = <0xf8f00600 0x20>;
    			clocks = <0x1 0x4>;
    		};
    
    		usb@e0002000 {
    			compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
    			status = "okay";
    			clocks = <0x1 0x1c>;
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x15 0x4>;
    			reg = <0xe0002000 0x1000>;
    			phy_type = "ulpi";
    		};
    
    		usb@e0003000 {
    			compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
    			status = "disabled";
    			clocks = <0x1 0x1d>;
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x2c 0x4>;
    			reg = <0xe0003000 0x1000>;
    			phy_type = "ulpi";
    		};
    
    		watchdog@f8005000 {
    			clocks = <0x1 0x2d>;
    			compatible = "cdns,wdt-r1p2";
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x9 0x1>;
    			reg = <0xf8005000 0x1000>;
    			timeout-sec = <0xa>;
    		};
    	};
    
    	amba_pl {
    		#address-cells = <0x1>;
    		#size-cells = <0x1>;
    		compatible = "simple-bus";
    		ranges;
    
    		axi_dmac@43c00000 {
    			compatible = "adi,axi-dmac-1.00.a";
    			interrupt-names = "irq";
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x1f 0x0>;
    			reg = <0x43c00000 0x10000>;
    			#dma-cells = <0x1>;
    			clocks = <0x1 0x10>;
    			linux,phandle = <0x10>;
    			phandle = <0x10>;
    
    			adi,channels {
    				#size-cells = <0x0>;
    				#address-cells = <0x1>;
    
    				dma-channel@0 {
    					reg = <0x0>;
    					adi,source-bus-width = <0x10>;
    					adi,source-bus-type = <0x2>;
    					adi,destination-bus-width = <0x40>;
    					adi,destination-bus-type = <0x0>;
    				};
    			};
    		};
    
    		axi_ad9652@43c10000 {
    			compatible = "xlnx,cf-ad9467-core-1.00.a";
    			reg = <0x43c10000 0x10000>;
    			dmas = <0x10 0x0>;
    			dma-names = "rx";
    			spibus-connected = <0x11>;
    		};
    
    		gpio@41200000 {
    			#gpio-cells = <0x3>;
    			clock-names = "s_axi_aclk";
    			clocks = <0x1 0xf>;
    			compatible = "xlnx,xps-gpio-1.00.a";
    			gpio-controller;
    			reg = <0x41200000 0x10000>;
    			xlnx,all-inputs = <0x0>;
    			xlnx,all-inputs-2 = <0x0>;
    			xlnx,all-outputs = <0x1>;
    			xlnx,all-outputs-2 = <0x0>;
    			xlnx,dout-default = <0x0>;
    			xlnx,dout-default-2 = <0x0>;
    			xlnx,gpio-width = <0x20>;
    			xlnx,gpio2-width = <0x20>;
    			xlnx,interrupt-present = <0x0>;
    			xlnx,is-dual = <0x0>;
    			xlnx,tri-default = <0xffffffff>;
    			xlnx,tri-default-2 = <0xffffffff>;
    		};
    	};
    
    	chosen {
    		linux,initrd-end = <0x7fff680>;
    		linux,initrd-start = "\al`";
    		bootargs = "console=ttyPS0,115200 earlyprintk";
    		stdout-path = "serial0:115200n8";
    	};
    
    	aliases {
    		ethernet0 = "/amba/ethernet@e000b000";
    		serial0 = "/amba/serial@e0001000";
    		spi0 = "/amba/spi@e000d000";
    		spi1 = "/amba/spi@e0006000";
    		spi2 = "/amba/spi@e0007000";
    	};
    
    	memory {
    		device_type = "memory";
    		reg = <0x0 0x40000000>;
    	};
    
    	clocks {
    
    		clock_1@0 {
    			compatible = "fixed-clock";
    			clock-frequency = <0xee6b280>;
    			clock-output-names = "adc_clk";
    			#clock-cells = <0x0>;
    			linux,phandle = <0x16>;
    			phandle = <0x16>;
    		};
    	};
    };
    

    Thanks,

    svv9

  • +1
    •  Analog Employees 
    on Oct 30, 2020 3:23 PM 24 days ago in reply to svv9

    Hi,

    Here:

    # Set TLAST, PARTIAL_REPORTING_EN and CYCLE
    mapf_dma[0x40c:0x410] = struct.pack("I", 6)

    Can you try enabling cyclic transfers "("I", 7)" and see if it works. In this way dma should not rely on interrupts.

    Thanks,

    Alexandru Tachici