AD9361
Recommended for New Designs
The AD9361 is a high performance, highly integrated radio
frequency (RF) Agile Transceiverâ„¢ designed for use in 3G and
4G base station applications....
AD9361 on Analog.com
Hello,
I am porting a current device to a new kernel and am having some issue with the AD9361. I am not seeing any transmits or receives in our software, where it worked before under an older kernel. I suspect it's something with the device tree. Could you double check and make sure this looks alright?
I have a TX DMA and associated dds device commented out, because the kernel panics with it, likely because I don't think we are using a TX DMA, that happens in the FPGA.
Like written, I get a boot error about the cf-ad9361-lpc device not working because TX tune failed. When I disable TX tune, eventually, when running my application, I see RX tune also failing. I also don't see anything being transmitted or received.
Thanks!
File 1:
/ {
amba: amba {
rx_dma: dma@7c400000 {
compatible = "adi,axi-dmac-1.00.a";
reg = <0x7c400000 0x10000>;
#dma-cells = <1>;
interrupt-parent = <&intc>;
interrupts = <0 33 0>;
clocks = <&clkc 16>;
dma-channel {
adi,buswidth = <64>;
adi,type = <0>;
};
};
/*
tx_dma: dma@7c420000 {
compatible = "adi,axi-dmac-1.00.a";
reg = <0x7c420000 0x10000>;
#dma-cells = <1>;
interrupt-parent = <&intc>;
interrupts = <0 56 0>;
clocks = <&clkc 16>;
dma-channel {
adi,buswidth = <64>;
adi,type = <1>;
adi,cyclic;
};
};
*/
cf_ad9361_adc_core_0: cf-ad9361-lpc@79020000 {
compatible = "adi,axi-ad9361-6.00.a";
reg = <0x79020000 0x6000>;
dmas = <&rx_dma 0>;
dma-names = "rx";
spibus-connected = <&adc0_ad9361>;
xlnx,dphase-timeout = <0x8>;
xlnx,num-mem = <0x1>;
xlnx,num-reg = <0x1>;
xlnx,s-axi-min-size = <0x1ff>;
xlnx,slv-awidth = <0x20>;
xlnx,slv-dwidth = <0x20>;
xlnx,use-wstrb = <0x0>;
};
/*
cf_ad9361_dac_core_0: cf-ad9361-dds-core-lpc@79024000 {
compatible = "adi,axi-ad9361-dds-6.00.a";
reg = <0x79024000 0x1000>;
clocks = <&adc0_ad9361 13>;
clock-names = "sampl_clk";
dmas = <&tx_dma 0>;
dma-names = "tx";
dac-sample-frequency = <491520000>;
xlnx,dphase-timeout = <0x8>;
xlnx,num-mem = <0x1>;
xlnx,num-reg = <0x1>;
xlnx,s-axi-min-size = <0x1ff>;
xlnx,slv-awidth = <0x20>;
xlnx,slv-dwidth = <0x20>;
xlnx,use-wstrb = <0x0>;
};
*/
};
};
and:
&spi0 {
adc0_ad9361: ad9361-phy@0 {
#address-cells = <1>;
#size-cells = <0>;
#clock-cells = <1>;
compatible = "ad9361";
/* SPI Setup */
reg = <0>;
spi-cpha;
spi-max-frequency = <10000000>;
/* Clocks */
clocks = <&ad9361_clkin 0>;
clock-names = "ad9361_ext_refclk";
clock-output-names = "rx_sampl_clk", "tx_sampl_clk";
//adi,debug-mode-enable;
/* Digital Interface Control */
/* adi,digital-interface-tune-skip-mode:
* 0 = TUNE RX&TX
* 1 = SKIP TX
* 2 = SKIP ALL
*/
adi,digital-interface-tune-skip-mode = <0>;
adi,pp-tx-swap-enable;
adi,pp-rx-swap-enable;
adi,rx-frame-pulse-mode-enable;
adi,lvds-mode-enable;
adi,lvds-bias-mV = <150>;
adi,lvds-rx-onchip-termination-enable;
adi,rx-data-delay = <10>;
adi,tx-fb-clock-delay = <7>;
//adi,fdd-rx-rate-2tx-enable;
adi,dcxo-coarse-and-fine-tune = <8 5920>;
//adi,xo-disable-use-ext-refclk-enable;
/* Mode Setup */
adi,2rx-2tx-mode-enable;
//adi,split-gain-table-mode-enable;
/* ENSM Mode */
adi,frequency-division-duplex-mode-enable;
//adi,ensm-pin-pulse-mode-enable;
//adi,ensm-enable-txnrx-control-enable;
/* adi,rx-rf-port-input-select:
* 0 = (RX1A_N & RX1A_P) and (RX2A_N & RX2A_P) enabled; balanced
* 1 = (RX1B_N & RX1B_P) and (RX2B_N & RX2B_P) enabled; balanced
* 2 = (RX1C_N & RX1C_P) and (RX2C_N & RX2C_P) enabled; balanced
*
* 3 = RX1A_N and RX2A_N enabled; unbalanced
* 4 = RX1A_P and RX2A_P enabled; unbalanced
* 5 = RX1B_N and RX2B_N enabled; unbalanced
* 6 = RX1B_P and RX2B_P enabled; unbalanced
* 7 = RX1C_N and RX2C_N enabled; unbalanced
* 8 = RX1C_P and RX2C_P enabled; unbalanced
*/
adi,rx-rf-port-input-select = <0>; /* (RX1A_N & RX1A_P) and (RX2A_N & RX2A_P) enabled; balanced */
/* adi,tx-rf-port-input-select:
* 0 TX1A, TX2A
* 1 TX1B, TX2B
*/
adi,tx-rf-port-input-select = <0>; /* TX1A, TX2A */
//adi,update-tx-gain-in-alert-enable;
adi,tx-attenuation-mdB = <10000>;
adi,rf-rx-bandwidth-hz = <1000000>;
adi,rf-tx-bandwidth-hz = <1000000>;
adi,rx-synthesizer-frequency-hz = /bits/ 64 <402795000>;
adi,tx-synthesizer-frequency-hz = /bits/ 64 <402795000>;
/* BBPLL ADC R2CLK R1CLK CLKRF RSAMPL */
adi,rx-path-clock-frequencies = <819200000 12800000 12800000 6400000 3200000 1600000>;
/* BBPLL DAC T2CLK T1CLK CLKTF TSAMPL */
adi,tx-path-clock-frequencies = <819200000 12800000 12800000 6400000 3200000 1600000>;
/* Gain Control */
/* adi,gc-rx[1|2]-mode:
* 0 = RF_GAIN_MGC
* 1 = RF_GAIN_FASTATTACK_AGC
* 2 = RF_GAIN_SLOWATTACK_AGC
* 3 = RF_GAIN_HYBRID_AGC
*/
adi,gc-rx1-mode = <0>;
adi,gc-rx2-mode = <0>;
adi,gc-adc-ovr-sample-size = <4>; /* sum 4 samples */
adi,gc-adc-small-overload-thresh = <47>; /* sum of squares */
adi,gc-adc-large-overload-thresh = <58>; /* sum of squares */
adi,gc-lmt-overload-high-thresh = <800>; /* mV */
adi,gc-lmt-overload-low-thresh = <704>; /* mV */
adi,gc-dec-pow-measurement-duration = <8192>; /* 0..524288 Samples */
adi,gc-low-power-thresh = <24>; /* 0..-64 dBFS vals are set pos */
//adi,gc-dig-gain-enable;
//adi,gc-max-dig-gain = <15>;
/* Manual Gain Control Setup */
//adi,mgc-rx1-ctrl-inp-enable; /* uncomment to use ctrl inputs */
//adi,mgc-rx2-ctrl-inp-enable; /* uncomment to use ctrl inputs */
adi,mgc-inc-gain-step = <2>;
adi,mgc-dec-gain-step = <2>;
/* adi,mgc-split-table-ctrl-inp-gain-mode:
* (relevant if adi,split-gain-table-mode-enable is set)
* 0 = AGC determine this
* 1 = only in LPF
* 2 = only in LMT
*/
adi,mgc-split-table-ctrl-inp-gain-mode = <0>;
/* Automatic Gain Control Setup */
adi,agc-attack-delay-extra-margin-us= <1>; /* us */
adi,agc-outer-thresh-high = <5>; /* -dBFS */
adi,agc-outer-thresh-high-dec-steps = <2>; /* 0..15 */
adi,agc-inner-thresh-high = <10>; /* -dBFS */
adi,agc-inner-thresh-high-dec-steps = <1>; /* 0..7 */
adi,agc-inner-thresh-low = <12>; /* -dBFS */
adi,agc-inner-thresh-low-inc-steps = <1>; /* 0..7 */
adi,agc-outer-thresh-low = <18>; /* -dBFS */
adi,agc-outer-thresh-low-inc-steps = <2>; /* 0..15 */
adi,agc-adc-small-overload-exceed-counter = <10>; /* 0..15 */
adi,agc-adc-large-overload-exceed-counter = <10>; /* 0..15 */
adi,agc-adc-large-overload-inc-steps = <2>; /* 0..15 */
//adi,agc-adc-lmt-small-overload-prevent-gain-inc-enable;
adi,agc-lmt-overload-large-exceed-counter = <10>; /* 0..15 */
adi,agc-lmt-overload-small-exceed-counter = <10>; /* 0..15 */
adi,agc-lmt-overload-large-inc-steps = <2>; /* 0..7 */
//adi,agc-dig-saturation-exceed-counter = <3>; /* 0..15 */
//adi,agc-dig-gain-step-size = <4>; /* 1..8 */
//adi,agc-sync-for-gain-counter-enable;
adi,agc-gain-update-interval-us = <1000>; /* 1ms */
//adi,agc-immed-gain-change-if-large-adc-overload-enable;
//adi,agc-immed-gain-change-if-large-lmt-overload-enable;
/* Fast AGC */
adi,fagc-dec-pow-measurement-duration = <64>; /* 64 Samples */
//adi,fagc-allow-agc-gain-increase-enable;
adi,fagc-lp-thresh-increment-steps = <1>;
adi,fagc-lp-thresh-increment-time = <5>;
adi,fagc-energy-lost-stronger-sig-gain-lock-exit-cnt = <8>;
adi,fagc-final-overrange-count = <3>;
//adi,fagc-gain-increase-after-gain-lock-enable;
adi,fagc-gain-index-type-after-exit-rx-mode = <0>;
adi,fagc-lmt-final-settling-steps = <1>;
adi,fagc-lock-level = <10>;
adi,fagc-lock-level-gain-increase-upper-limit = <5>;
adi,fagc-lock-level-lmt-gain-increase-enable;
adi,fagc-lpf-final-settling-steps = <1>;
adi,fagc-optimized-gain-offset = <5>;
adi,fagc-power-measurement-duration-in-state5 = <64>;
adi,fagc-rst-gla-engergy-lost-goto-optim-gain-enable;
adi,fagc-rst-gla-engergy-lost-sig-thresh-below-ll = <10>;
adi,fagc-rst-gla-engergy-lost-sig-thresh-exceeded-enable;
adi,fagc-rst-gla-if-en-agc-pulled-high-mode = <0>;
adi,fagc-rst-gla-large-adc-overload-enable;
adi,fagc-rst-gla-large-lmt-overload-enable;
adi,fagc-rst-gla-stronger-sig-thresh-above-ll = <10>;
adi,fagc-rst-gla-stronger-sig-thresh-exceeded-enable;
adi,fagc-state-wait-time-ns = <260>;
adi,fagc-use-last-lock-level-for-set-gain-enable;
/* RSSI */
/* adi,rssi-restart-mode:
* 0 = AGC_IN_FAST_ATTACK_MODE_LOCKS_THE_GAIN,
* 1 = EN_AGC_PIN_IS_PULLED_HIGH,
* 2 = ENTERS_RX_MODE,
* 3 = GAIN_CHANGE_OCCURS,
* 4 = SPI_WRITE_TO_REGISTER,
* 5 = GAIN_CHANGE_OCCURS_OR_EN_AGC_PIN_PULLED_HIGH,
*/
adi,rssi-restart-mode = <3>;
//adi,rssi-unit-is-rx-samples-enable;
adi,rssi-delay = <1>; /* 1us */
adi,rssi-wait = <1>; /* 1us */
adi,rssi-duration = <1000>; /* 1ms */
/* Control Outputs */
adi,ctrl-outs-index = <0>;
adi,ctrl-outs-enable-mask = <0xFF>;
/* AuxADC Temp Sense Control */
adi,temp-sense-measurement-interval-ms = <1000>;
adi,temp-sense-offset-signed = <0xCE>;
adi,temp-sense-periodic-measurement-enable;
/* AuxDAC Control */
adi,aux-dac-manual-mode-enable;
adi,aux-dac1-default-value-mV = <0>;
//adi,aux-dac1-active-in-rx-enable;
//adi,aux-dac1-active-in-tx-enable;
//adi,aux-dac1-active-in-alert-enable;
adi,aux-dac1-rx-delay-us = <0>;
adi,aux-dac1-tx-delay-us = <0>;
adi,aux-dac2-default-value-mV = <0>;
//adi,aux-dac2-active-in-rx-enable;
//adi,aux-dac2-active-in-tx-enable;
//adi,aux-dac2-active-in-alert-enable;
adi,aux-dac2-rx-delay-us = <0>;
adi,aux-dac2-tx-delay-us = <0>;
};
};
&adc0_ad9361 {
reset-gpios = <&gpio0 100 0>;
};
Please see here: https://wiki.analog.com/resources/eval/user-guides/ad-fmcomms2-ebz/interface_timing_validation
If tuning fails, it's most likely an issue with your HW or HDL design.
You could use skip mode = 2, to get the device probed and then further test your system.
adi,digital-interface-tune-skip-mode = <0>;
After you have probed the ad9361-phy you can use BIST to test the transceiver.
Then try to use the digital tune runtime API to test different interface speeds.
-Michael
I think I ignored a fairly important bit: We are using the axi_ad9361 IP core, but it's old (2011). I assume a new driver would require an up-to-date IP core as well, so let me try and update that.
With the new IP core, TX tuning seems to work (I get no error with the ad9361-lpc device), but RX tuning still fails when I run my application. Ideas?
Hi,
You are saying that both HDL and HW have been tested - how did you test them? If the digital tuning doesn't work, most likely the issue is caused by HDL or HW.
Dragos
Hi,
You are saying that both HDL and HW have been tested - how did you test them? If the digital tuning doesn't work, most likely the issue is caused by HDL or HW.
Dragos
Good question. The hardware has existed for a while, running an older Linux OS, and works just fine, so I think hardware can be ruled out.
As for HDL, I've been using the same bitfile we use with the legacy OS. Then I realized that we are using an old axi_ad9361 IP core in the HDL, so I just updated that to the 2018_R2_pack2 branch of the ADI HDL, along with axi_dmac and others.
My assumption is that a 2018_R2 HDL core plus the 2018_R2 branch of the ADI Linux fork as the OS should work.
Tuning was enabled in 2014/15 in our device tree, so I assume it worked then (no error messages about tuning with legacy OS).