Setting AD9371 for 80MHz sampling clk

Hello All,

I’m using AD9371 for advanced Wi-Fi prototyping. Hence I had to change 122.88MHz VCXO on evaluation board to 80MHz so I can achieve integer multiples of 20MHz sampling required for 802.11 signal processing.

By  doing so, I discover a number of issues, particularly with initial calibration routine in AD9371 firmware and driver. Below are details of my discovery and workaround I find to make it work. Could you please review it and subject the better way to make AD9371 work for 80MHz sampling clk, Thanks, Mikhail.

Here are details:

1.By enabling  ad9371 evaluation board to run at 80MHz clk I discover a multiple issues with Filter Designer for AD9371, AD9371 calibration firmware routine and a driver. While I found a workaround, we asking to address this issue as it preventing us to use AD9371 in normal operation mode.

2.Attached are word document and supporting files (.m file, profile & .dts) with necessary information to make ad9371 work 80MHz clk so I&Q sampling rate is integer multiplier of 20MHz (as it used for 802.11/WI-FI).

ad9371_80MHz_profileMTG.txt
<profile AD9371 version=0 name=Rx 40, IQrate 80.000>
 <clocks>
  <deviceClock_kHz=320000>
  <clkPllVcoFreq_kHz=9600000>
  <clkPllVcoDiv=3>
  <clkPllHsDiv=4>
 </clocks>

 <rx>
  <adcDiv=1>
  <rxFirDecimation=2>
  <rxDec5Decimation=5>
  <enHighRejDec5=1>
  <rhb1Decimation=1>
  <iqRate_kHz=80000>
  <rfBandwidth_Hz=40000000>
  <rxBbf3dBCorner_kHz=40000>

  <filter FIR gain=-6 num=48>
  1
  7
  3
  -20
  -38
  10
  107
  100
  -122
  -334
  -113
  506
  718
  -166
  -1391
  -1095
  1231
  3033
  981
  -4224
  -6482
  219
  14325
  26107
  26107
  14325
  219
  -6482
  -4224
  981
  3033
  1231
  -1095
  -1391
  -166
  718
  506
  -113
  -334
  -122
  100
  107
  10
  -38
  -20
  3
  7
  1
  </filter>

  <adc-profile num=16>
  900
  559
  201
  98
  1280
  199
  1522
  98
  860
  25
  529
  37
  48
  26
  15
  196
  </adc-profile>
 </rx>

 <obs>
  <adcDiv=1>
  <rxFirDecimation=2>
  <rxDec5Decimation=5>
  <enHighRejDec5=1>
  <rhb1Decimation=1>
  <iqRate_kHz=80000>
  <rfBandwidth_Hz=40000000>
  <rxBbf3dBCorner_kHz=20000>

  <filter FIR gain=-6 num=48>
  -1
  10
  10
  -22
  -60
  -6
  143
  171
  -129
  -485
  -245
  660
  1099
  -74
  -1954
  -1784
  1506
  4443
  1920
  -5737
  -10210
  -2631
  15550
  31189
  31189
  15550
  -2631
  -10210
  -5737
  1920
  4443
  1506
  -1784
  -1954
  -74
  1099
  660
  -245
  -485
  -129
  171
  143
  -6
  -60
  -22
  10
  10
  -1
  </filter>

  <adc-profile num=16>
  900
  559
  201
  98
  1280
  199
  1522
  98
  860
  25
  529
  37
  48
  26
  15
  196
  </adc-profile>

  <lpbk-adc-profile num=16>
  922
  550
  201
  98
  1280
  112
  1505
  53
  864
  14
  533
  40
  48
  26
  15
  197
  </lpbk-adc-profile>
 </obs>

 <sniffer>
  <adcDiv=1>
  <rxFirDecimation=2>
  <rxDec5Decimation=5>
  <enHighRejDec5=1>
  <rhb1Decimation=2>
  <iqRate_kHz=40000>
  <rfBandwidth_Hz=20000000>
  <rxBbf3dBCorner_kHz=20000>

  <filter FIR gain=-6 num=72>
  -9
  12
  18
  17
  -17
  -49
  -45
  21
  99
  105
  -11
  -171
  -215
  -36
  258
  390
  149
  -343
  -648
  -371
  394
  1003
  763
  -357
  -1476
  -1425
  138
  2113
  2589
  489
  -3082
  -5079
  -2537
  4990
  14500
  21095
  21095
  14500
  4990
  -2537
  -5079
  -3082
  489
  2589
  2113
  138
  -1425
  -1476
  -357
  763
  1003
  394
  -371
  -648
  -343
  149
  390
  258
  -36
  -215
  -171
  -11
  105
  99
  21
  -45
  -49
  -17
  17
  18
  12
  -9
  </filter>

  <adc-profile num=16>
  922
  550
  201
  98
  1280
  112
  1505
  53
  864
  14
  533
  40
  48
  26
  15
  197
  </adc-profile>
 </sniffer>

 <tx>
  <dacDiv=2.5>
  <txFirInterpolation=1>
  <thb1Interpolation=2>
  <thb2Interpolation=2>
  <txInputHbInterpolation=1>
  <iqRate_kHz=80000>
  <primarySigBandwidth_Hz=20000000>
  <rfBandwidth_Hz=40000000>
  <txDac3dBCorner_kHz=92000>
  <txBbf3dBCorner_kHz=20000>

  <filter FIR gain=6 num=16>
  26
  -292
  -75
  333
  339
  -659
  -2192
  21034
  -2192
  -659
  339
  333
  -75
  -292
  26
  0
  </filter>
 </tx>
</profile>

DOCX

3.The main issue addressed by outlined work around:

3.1. Even with correct modification to Linux Device Tree, initial initialization of AD9371 at boot up is failing due to a time out of driver waiting for calibration routine execution in AD9371 firmware.

[    3.560034] random: crng init done

[   84.532030] ERROR: 283: MYKONOS_waitInitCals() returned an ARM error

[   84.557234] ERROR: 258: Device not in radioOff/IDLE state. Error in MYKONOS_enableTrackingCals()

[   84.591936] ERROR: 364: MYKONOS_waitArmCmdStatus() exited due to ARM error for the desired ARM opcode

[   84.601111] ERROR: 145: ARM command to move to radioOn state failed.

[   84.608698] ERROR: 364: MYKONOS_waitArmCmdStatus() exited due to ARM error for the desired ARM opcode

[   84.617880] ERROR: 257: ARM Command Error in MYKONOS_setObsRxPathSource()

3.2. It was discovered that if TX_QEC_INIT calibration flag is disabled, Driver is not failing anymore. TX is operate fine after that but RX still not working. 

% Dis TX_QEC_INIT Calibration using command line

cd /sys/kernel/debug/iio/iio:device1

echo 31231 > /sys/kernel/debug/iio/iio:device1/adi,default-initial-calibrations-mask

echo 1 > /sys/kernel/debug/iio/iio:device1/initialize

3.3. It was discovered that the profile, exactly the same as AD9371 configuration in Linux Device Tree has to be reload as the net step to make RX chain working (the MATLAB script is used).

h = intelsoc;

ProfileFile = 'ad9371_80MHz_profileMTG.txt';

h.putFile(ProfileFile,'/tmp') % FTP the configuration file over

ProfileConfigLocation = h.system('ls /sys/bus/iio/devices/iio:device*/*profile_config*');

ProfileConfigWrite = sprintf('cat /tmp/%s > %s',ProfileFile,ProfileConfigLocation);

msg = h.system(ProfileConfigWrite);