xref: /openwifi/doc/app_notes/iq_2ant.md (revision 23ba65e4fa367dd754c10f174b8714c19f936261)
1a6085186SLina Ceballos<!--
2b57ee357SJiao XianjunAuthor: Xianjun jiao
3b57ee357SJiao XianjunSPDX-FileCopyrightText: 2019 UGent
4a6085186SLina CeballosSPDX-License-Identifier: AGPL-3.0-or-later
5a6085186SLina Ceballos-->
6a6085186SLina Ceballos
7a6085186SLina Ceballos
819acf08cSJiao XianjunInstead of [**normal IQ sample capture**](iq.md), this app note introduces how to enable the I/Q capture for dual antennas. Besides the I/Q from the main antenna (that is selected by baseband), the I/Q samples from the other antenna (monitoring antenna) is captured as well (coherently synchronized) in this dual antenna mode. You are suggested to read the [**normal IQ sample capture**](iq.md) to understand how we use the side channel to capture I/Q samples by different trigger conditions.
95deb8d18SXianjun Jiao
10*23ba65e4SXianjun JiaoThis feature also support capturing TX I/Q (loopback) to test the baseband transmitter.
11*23ba65e4SXianjun Jiao
12*23ba65e4SXianjun Jiao- [[Quick start for collision capture](#Quick-start-for-collision-capture)]
13*23ba65e4SXianjun Jiao- [[Quick start for TX IQ capture in trigger mode](#Quick-start-for-TX-IQ-capture-in-trigger-mode)]
14*23ba65e4SXianjun Jiao- [[Quick start for TX IQ capture in free running mode](#Quick-start-for-TX-IQ-capture-in-free-running-mode)]
15*23ba65e4SXianjun Jiao
16*23ba65e4SXianjun Jiao## Quick start for collision capture
178a71401fSJiao Xianjun![](./iq_2ant-setup.png)
185deb8d18SXianjun Jiao
1919acf08cSJiao Xianjun  The main antenna rx0 (by default selected by baseband if you do not select explicitly by set_ant.sh) is always used for communication and I/Q capture. Meanwhile, the other antenna (rx1 -- monitoring antenna) will be also available for capturing rx I/Q if you are using AD9361 based RF board, such as fmcomms2/3 and adrv9361z7035, by turning on the **dual antenna capture** mode. In this case, you can place the other antenna (rx1) close to the communication peer (for example, the other WiFi node) to capture the potential collision by monitoring rx1 I/Q. The nature of collision is that both sides of a communication link are trying to do transmission at the same time.
205deb8d18SXianjun Jiao
215deb8d18SXianjun Jiao  The collision capture steps:
225deb8d18SXianjun Jiao  - Change rx1 AGC to manual mode instead of fast_attack in rf_init.sh by:
235deb8d18SXianjun Jiao  ```
245deb8d18SXianjun Jiao  echo manual > in_voltage1_gain_control_mode
255deb8d18SXianjun Jiao  ```
265deb8d18SXianjun Jiao  - Change rx1 gain to a low level, such as 20, by:
275deb8d18SXianjun Jiao  ```
285deb8d18SXianjun Jiao  echo 20 > in_voltage1_hardwaregain
295deb8d18SXianjun Jiao  ```
305deb8d18SXianjun Jiao  - Use the new rf_init.sh script to boot up the SDR board, and setup the working scenario.
315deb8d18SXianjun Jiao  - Setup the side channel:
325deb8d18SXianjun Jiao  ```
335deb8d18SXianjun Jiao  insmod side_ch.ko iq_len_init=8187
349634f24eSXianjun Jiao  (iq_len_init should be <4096, like 4095, if smaller FPGA, like z7020, is used)
355deb8d18SXianjun Jiao  ./side_ch_ctl wh11d2000
365deb8d18SXianjun Jiao  (Set a smaller pre_trigger_len 2000, because we want to see what happens after the trigger instead of long period stored before the trigger)
375deb8d18SXianjun Jiao  ```
385deb8d18SXianjun Jiao  - Put the other antenna (rx1) close to the peer WiFi node, set trigger condition to 23 (baseband tx done)
395deb8d18SXianjun Jiao  ```
405deb8d18SXianjun Jiao  ./side_ch_ctl wh8d23
415deb8d18SXianjun Jiao  ```
425deb8d18SXianjun Jiao  - Enable the **dual antenna capture** mode
435deb8d18SXianjun Jiao  ```
445deb8d18SXianjun Jiao  ./side_ch_ctl wh3h11
455deb8d18SXianjun Jiao  ```
465deb8d18SXianjun Jiao  - Run some traffic between the SDR board and the peer WiFi node, and start the user space I/Q capture program
475deb8d18SXianjun Jiao  ```
485deb8d18SXianjun Jiao  ./side_ch_ctl g
495deb8d18SXianjun Jiao  ```
505deb8d18SXianjun Jiao  If the printed "**side info count**" is increasing, it means the trigger condition is met from time to time.
515deb8d18SXianjun Jiao  - On remote computer, run
525deb8d18SXianjun Jiao  ```
535deb8d18SXianjun Jiao  python3 iq_capture_2ant.py
5401754872SXianjun Jiao  (if smaller FPGA, like z7020, is used, add a argument that equals to iq_len_init, like 4095)
555deb8d18SXianjun Jiao  ```
5619acf08cSJiao Xianjun  Above script will plot the real-time rx0 and rx1 I/Q captured each time the trigger condition is met. .
578421731bSJiao Xianjun  ![](./iq_2ant-screen-shot.jpg)
5819acf08cSJiao Xianjun  In the above example, the upper half shows the signal received from the main antenna (self tx is not seen because of self muting in FPGA), the lower half shows not only the rx signal from the monitoring antenna but also the tx signal from the main antenna due to coupling.
5919acf08cSJiao Xianjun  Meanwhile the script also prints the maximum amplitude of the rx0 and rx1 I/Q samples. Check the 3rd column that is displayed by the script: Those small value printing indicate noise (most probably, because the rx1 gain is very low). The big value printing indicates a packet from rx1 (although rx1 has very low gain, rx1 is very close to the peer WiFi node). Go through the noise and the packet max I/Q amplitude numbers from rx1 printing (the 3rd column), and decide a threshold value that is significantly higher than the noise but less than those big values (packets).
605deb8d18SXianjun Jiao  - Set trigger condition to 29, which means that rx1 I/Q is found larger than a threshold while SDR is transmitting -- this means a collision condition is captured because rx1 I/Q implies the transmitting from the peer WiFi node. The threshold value is decided in the previous step (2500 is assumed here).
615deb8d18SXianjun Jiao  ```
625deb8d18SXianjun Jiao  (Quit side_ch_ctl by Ctrl+C)
635deb8d18SXianjun Jiao  ./side_ch_ctl wh8d29
645deb8d18SXianjun Jiao  ./side_ch_ctl wh9d2500
655deb8d18SXianjun Jiao  ./side_ch_ctl g
665deb8d18SXianjun Jiao  ```
675deb8d18SXianjun Jiao  - Now the trigger condition can capture the case where both sides happen to transmit in an overlapped duration. If the  printed "**side info count**" is increasing, it means the collision happens from time to time.
685deb8d18SXianjun Jiao  - You can also see it via iq_capture_2ant.py or do offline analysis by test_iq_2ant_file_display.m
695deb8d18SXianjun Jiao  - Check the **iq1** signal in FPGA ILA/probe (triggered by signal "iq_trigger") for further debug if you want to know what exactly happened when collision is captured.
70*23ba65e4SXianjun Jiao
71*23ba65e4SXianjun Jiao## Quick start for TX IQ capture in trigger mode
72*23ba65e4SXianjun Jiao
73*23ba65e4SXianjun JiaoTo capture the TX I/Q (baseband loopback), a scenario where openwifi will do TX needs to be set up. Such as beacon TX when openwifi act as AP, or [packet injection](inject_80211.md).
74*23ba65e4SXianjun Jiao
75*23ba65e4SXianjun JiaoThe example command sequence on board and explanations are as follows.
76*23ba65e4SXianjun Jiao```
77*23ba65e4SXianjun Jiaocd openwifi
78*23ba65e4SXianjun Jiao./fosdem.sh
79*23ba65e4SXianjun Jiaoinsmod side_ch.ko iq_len_init=511
80*23ba65e4SXianjun Jiao(511 I/Q samples cover the short, long preamble and some OFDM symbols. Change it according to your case)
81*23ba65e4SXianjun Jiao./side_ch_ctl wh11d1
82*23ba65e4SXianjun Jiao(1 sample before the trigger met will be captured. So most of the I/Q will be captured after trigger met)
83*23ba65e4SXianjun Jiao./side_ch_ctl wh8d16
84*23ba65e4SXianjun Jiao(trigger condition 16: phy_tx_started signal from openofdm tx core)
85*23ba65e4SXianjun Jiao./side_ch_ctl wh5h2
86*23ba65e4SXianjun Jiao(I/Q source selection: 2--openofdm_tx core; 4--tx_intf)
87*23ba65e4SXianjun Jiao./side_ch_ctl wh3h11
88*23ba65e4SXianjun Jiao./side_ch_ctl g1
89*23ba65e4SXianjun Jiao```
90*23ba65e4SXianjun JiaoOn computer:
91*23ba65e4SXianjun Jiao```
92*23ba65e4SXianjun Jiaoopenwifi/user_space/side_ch_ctl_src/python3 iq_capture_2ant.py 511
93*23ba65e4SXianjun Jiao
94*23ba65e4SXianjun Jiao```
95*23ba65e4SXianjun Jiao
96*23ba65e4SXianjun Jiao## Quick start for TX IQ capture in free running mode
97*23ba65e4SXianjun Jiao
98*23ba65e4SXianjun Jiao```
99*23ba65e4SXianjun Jiaocd openwifi
100*23ba65e4SXianjun Jiao./fosdem.sh
101*23ba65e4SXianjun Jiaoinsmod side_ch.ko iq_len_init=511
102*23ba65e4SXianjun Jiao(511 I/Q samples cover the short, long preamble and some OFDM symbols. Change it according to your case)
103*23ba65e4SXianjun Jiao./side_ch_ctl wh11d1
104*23ba65e4SXianjun Jiao(1 sample before the trigger met will be captured. So most of the I/Q will be captured after trigger met)
105*23ba65e4SXianjun Jiao./side_ch_ctl wh8d0
106*23ba65e4SXianjun Jiao(trigger condition 0 is needed for free running mode)
107*23ba65e4SXianjun Jiao./side_ch_ctl wh5h3
108*23ba65e4SXianjun Jiao(I/Q source selection: 3--openofdm_tx core; 5--tx_intf)
109*23ba65e4SXianjun Jiao./side_ch_ctl wh3h11
110*23ba65e4SXianjun Jiao./side_ch_ctl g1
111*23ba65e4SXianjun Jiao```
112*23ba65e4SXianjun JiaoOn computer:
113*23ba65e4SXianjun Jiao```
114*23ba65e4SXianjun Jiaoopenwifi/user_space/side_ch_ctl_src/python3 iq_capture_2ant.py 511
115*23ba65e4SXianjun Jiao
116*23ba65e4SXianjun Jiao```
117