xref: /openwifi/doc/app_notes/iq_2ant.md (revision 9634f24ef2e854c6502c52dc539ea21733f33671)
15deb8d18SXianjun JiaoInstead of [**normal IQ sample capture**](iq.md), this app note introduce how to enable the I/Q capture for dual antenna. In this dual antenna mode, the RSSI and AGC status won't be captured as in the normal mode. Instead, they are replaced by the I/Q samples from the other antenna. But you are suggested to read the [**normal IQ sample capture**](iq.md) to understand how do we use the side channel to capture I/Q sample by different trigger conditions.
25deb8d18SXianjun Jiao
35deb8d18SXianjun JiaoIn this app note, we show how to use the dual antenna I/Q capture to capture the collision.
45deb8d18SXianjun Jiao
55deb8d18SXianjun Jiao## Quick start
65deb8d18SXianjun Jiao  The currently selected antenna (rx0 by default if you do not select explicitly by set_ant.sh) is always used for communication and I/Q capture. Meanwhile, the other antenna (rx1) will be also avaliable 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.
75deb8d18SXianjun Jiao
85deb8d18SXianjun Jiao  The collision capture steps:
95deb8d18SXianjun Jiao  - Change rx1 AGC to manual mode instead of fast_attack in rf_init.sh by:
105deb8d18SXianjun Jiao  ```
115deb8d18SXianjun Jiao  echo manual > in_voltage1_gain_control_mode
125deb8d18SXianjun Jiao  ```
135deb8d18SXianjun Jiao  - Change rx1 gain to a low level, such as 20, by:
145deb8d18SXianjun Jiao  ```
155deb8d18SXianjun Jiao  echo 20 > in_voltage1_hardwaregain
165deb8d18SXianjun Jiao  ```
175deb8d18SXianjun Jiao  - Use the new rf_init.sh script to boot up the SDR board, and setup the working scenario.
185deb8d18SXianjun Jiao  - Setup the side channel:
195deb8d18SXianjun Jiao  ```
205deb8d18SXianjun Jiao  insmod side_ch.ko iq_len_init=8187
21*9634f24eSXianjun Jiao  (iq_len_init should be <4096, like 4095, if smaller FPGA, like z7020, is used)
225deb8d18SXianjun Jiao  ./side_ch_ctl wh11d2000
235deb8d18SXianjun 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)
245deb8d18SXianjun Jiao  ```
255deb8d18SXianjun Jiao  - Put the other antenna (rx1) close to the peer WiFi node, set trigger condition to 23 (baseband tx done)
265deb8d18SXianjun Jiao  ```
275deb8d18SXianjun Jiao  ./side_ch_ctl wh8d23
285deb8d18SXianjun Jiao  ```
295deb8d18SXianjun Jiao  - Enable the **dual antenna capture** mode
305deb8d18SXianjun Jiao  ```
315deb8d18SXianjun Jiao  ./side_ch_ctl wh3h11
325deb8d18SXianjun Jiao  ```
335deb8d18SXianjun Jiao  - Run some traffic between the SDR board and the peer WiFi node, and start the user space I/Q capture program
345deb8d18SXianjun Jiao  ```
355deb8d18SXianjun Jiao  ./side_ch_ctl g
365deb8d18SXianjun Jiao  ```
375deb8d18SXianjun Jiao  If the printed "**side info count**" is increasing, it means the trigger condition is met from time to time.
385deb8d18SXianjun Jiao  - On remote computer, run
395deb8d18SXianjun Jiao  ```
405deb8d18SXianjun Jiao  python3 iq_capture_2ant.py
4101754872SXianjun Jiao  (if smaller FPGA, like z7020, is used, add a argument that equals to iq_len_init, like 4095)
425deb8d18SXianjun Jiao  ```
435deb8d18SXianjun Jiao  Above script will plot the real-time rx0 and rx1 I/Q captured each time trigger condition met. Meanwhile the script also prints the maximum amplitutde 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 indicate 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).
445deb8d18SXianjun 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).
455deb8d18SXianjun Jiao  ```
465deb8d18SXianjun Jiao  (Quit side_ch_ctl by Ctrl+C)
475deb8d18SXianjun Jiao  ./side_ch_ctl wh8d29
485deb8d18SXianjun Jiao  ./side_ch_ctl wh9d2500
495deb8d18SXianjun Jiao  ./side_ch_ctl g
505deb8d18SXianjun Jiao  ```
515deb8d18SXianjun 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.
525deb8d18SXianjun Jiao  - You can also see it via iq_capture_2ant.py or do offline analysis by test_iq_2ant_file_display.m
535deb8d18SXianjun 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.
54