xref: /openwifi/user_space/side_ch_ctl_src/iq_capture_2ant.py (revision e556af35c696ecef552192823e107caf37eb6af9)
1#
2# openwifi side info receive and display program
3# Xianjun jiao. [email protected]; [email protected]
4#
5import os
6import sys
7import socket
8import numpy as np
9import matplotlib.pyplot as plt
10
11def display_iq(iq0_capture, iq1_capture):
12    fig_iq_capture = plt.figure(0)
13    fig_iq_capture.clf()
14
15    ax_iq0 = fig_iq_capture.add_subplot(211)
16    # ax_iq0.set_xlabel("sample")
17    ax_iq0.set_ylabel("I/Q")
18    ax_iq0.set_title("rx0 I/Q")
19    plt.plot(iq0_capture.real, 'b')
20    plt.plot(iq0_capture.imag, 'r')
21    plt.ylim(-32767, 32767)
22
23    ax_iq1 = fig_iq_capture.add_subplot(212)
24    ax_iq1.set_xlabel("sample")
25    ax_iq1.set_ylabel("I/Q")
26    ax_iq1.set_title("rx1 I/Q")
27    plt.plot(iq1_capture.real, 'b')
28    plt.plot(iq1_capture.imag, 'r')
29    plt.ylim(-32767, 32767)
30    fig_iq_capture.canvas.flush_events()
31
32def parse_iq(iq, iq_len):
33    # print(len(iq), iq_len)
34    num_dma_symbol_per_trans = 1 + iq_len
35    num_int16_per_trans = num_dma_symbol_per_trans*4 # 64bit per dma symbol
36    num_trans = round(len(iq)/num_int16_per_trans)
37    # print(len(iq), iq.dtype, num_trans)
38    iq = iq.reshape([num_trans, num_int16_per_trans])
39
40    timestamp = iq[:,0] + pow(2,16)*iq[:,1] + pow(2,32)*iq[:,2] + pow(2,48)*iq[:,3]
41    iq0_capture = np.int16(iq[:,4::4]) + np.int16(iq[:,5::4])*1j
42    iq1_capture = np.int16(iq[:,6::4]) + np.int16(iq[:,7::4])*1j
43    # print(num_trans, iq_len, iq0_capture.shape, iq1_capture.shape)
44
45    iq0_capture = iq0_capture.reshape([num_trans*iq_len,])
46    iq1_capture = iq1_capture.reshape([num_trans*iq_len,])
47
48    return timestamp, iq0_capture, iq1_capture
49
50UDP_IP = "192.168.10.1" #Local IP to listen
51UDP_PORT = 4000         #Local port to listen
52
53sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
54sock.bind((UDP_IP, UDP_PORT))
55sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 464) # for low latency. 464 is the minimum udp length in our case (CSI only)
56
57# align with side_ch_control.v and all related user space, remote files
58MAX_NUM_DMA_SYMBOL = 8192
59
60if len(sys.argv)<2:
61    print("Assume iq_len = 8187! (Max UDP 65507 bytes; (65507/8)-1 = 8187)")
62    iq_len = 8187
63else:
64    iq_len = int(sys.argv[1])
65    print(iq_len)
66    # print(type(num_eq))
67
68if iq_len>8187:
69    iq_len = 8187
70    print('Limit iq_len to 8187! (Max UDP 65507 bytes; (65507/8)-1 = 8187)')
71
72num_dma_symbol_per_trans = 1 + iq_len
73num_byte_per_trans = 8*num_dma_symbol_per_trans
74
75if os.path.exists("iq_2ant.txt"):
76    os.remove("iq_2ant.txt")
77iq_fd=open('iq_2ant.txt','a')
78
79plt.ion()
80
81while True:
82    try:
83        data, addr = sock.recvfrom(MAX_NUM_DMA_SYMBOL*8) # buffer size
84        # print(addr)
85        test_residual = len(data)%num_byte_per_trans
86        # print(len(data)/8, num_dma_symbol_per_trans, test_residual)
87        if (test_residual != 0):
88            print("Abnormal length")
89
90        iq = np.frombuffer(data, dtype='uint16')
91        np.savetxt(iq_fd, iq)
92
93        timestamp, iq0_capture, iq1_capture = parse_iq(iq, iq_len)
94        print(timestamp, max(iq0_capture.real), max(iq1_capture.real))
95        display_iq(iq0_capture, iq1_capture)
96
97    except KeyboardInterrupt:
98        print('User quit')
99        break
100
101print('close()')
102iq_fd.close()
103sock.close()
104