xref: /openwifi/user_space/side_ch_ctl_src/iq_capture.py (revision a6085186d94dfe08b0e09c18c8d4b1b4fe38ea35)
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(iq_capture, agc_gain, rssi_half_db):
12
13    fig_iq_capture = plt.figure(0)
14    fig_iq_capture.clf()
15    plt.xlabel("sample")
16    plt.ylabel("I/Q")
17    plt.title("I (blue) and Q (red) capture")
18    plt.plot(iq_capture.real, 'b')
19    plt.plot(iq_capture.imag, 'r')
20    plt.ylim(-32767, 32767)
21    fig_iq_capture.show()
22    plt.pause(0.0001)
23
24    agc_gain_lock = np.copy(agc_gain)
25    agc_gain_lock[agc_gain>127] = 80 # agc lock
26    agc_gain_lock[agc_gain<=127] = 0 # agc not lock
27
28    agc_gain_value = np.copy(agc_gain)
29    agc_gain_value[agc_gain>127] = agc_gain[agc_gain>127] - 128
30
31    fig_agc_gain = plt.figure(1)
32    fig_agc_gain.clf()
33    plt.xlabel("sample")
34    plt.ylabel("gain/lock")
35    plt.title("AGC gain (blue) and lock status (red)")
36    plt.plot(agc_gain_value, 'b')
37    plt.plot(agc_gain_lock, 'r')
38    plt.ylim(0, 82)
39    fig_agc_gain.show()
40    plt.pause(0.0001)
41
42    fig_rssi_half_db = plt.figure(2)
43    fig_rssi_half_db.clf()
44    plt.xlabel("sample")
45    plt.ylabel("dB")
46    plt.title("RSSI half dB (uncalibrated)")
47    plt.plot(rssi_half_db)
48    plt.ylim(100, 270)
49    fig_rssi_half_db.show()
50    plt.pause(0.0001)
51
52def parse_iq(iq, iq_len):
53    # print(len(iq), iq_len)
54    num_dma_symbol_per_trans = 1 + iq_len
55    num_int16_per_trans = num_dma_symbol_per_trans*4 # 64bit per dma symbol
56    num_trans = round(len(iq)/num_int16_per_trans)
57    # print(len(iq), iq.dtype, num_trans)
58    iq = iq.reshape([num_trans, num_int16_per_trans])
59
60    timestamp = iq[:,0] + pow(2,16)*iq[:,1] + pow(2,32)*iq[:,2] + pow(2,48)*iq[:,3]
61    iq_capture = iq[:,4::4] + iq[:,5::4]*1j
62    agc_gain = iq[:,6::4]
63    rssi_half_db = iq[:,7::4]
64    # print(num_trans, iq_len, iq_capture.shape, agc_gain.shape, rssi_half_db.shape)
65
66    iq_capture = iq_capture.reshape([num_trans*iq_len,])
67    agc_gain = agc_gain.reshape([num_trans*iq_len,])
68    rssi_half_db = rssi_half_db.reshape([num_trans*iq_len,])
69
70    return timestamp, iq_capture, agc_gain, rssi_half_db
71
72UDP_IP = "192.168.10.1" #Local IP to listen
73UDP_PORT = 4000         #Local port to listen
74
75sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
76sock.bind((UDP_IP, UDP_PORT))
77
78# align with side_ch_control.v and all related user space, remote files
79MAX_NUM_DMA_SYMBOL = 8192
80
81if len(sys.argv)<2:
82    print("Assume iq_len = 8187! (Max UDP 65507 bytes; (65507/8)-1 = 8187)")
83    iq_len = 8187
84else:
85    iq_len = int(sys.argv[1])
86    print(iq_len)
87    # print(type(num_eq))
88
89if iq_len>8187:
90    iq_len = 8187
91    print('Limit iq_len to 8187! (Max UDP 65507 bytes; (65507/8)-1 = 8187)')
92
93num_dma_symbol_per_trans = 1 + iq_len
94num_byte_per_trans = 8*num_dma_symbol_per_trans
95
96if os.path.exists("iq.txt"):
97    os.remove("iq.txt")
98iq_fd=open('iq.txt','a')
99
100while True:
101    try:
102        data, addr = sock.recvfrom(MAX_NUM_DMA_SYMBOL*8) # buffer size
103        # print(addr)
104        test_residual = len(data)%num_byte_per_trans
105        # print(len(data)/8, num_dma_symbol_per_trans, test_residual)
106        if (test_residual != 0):
107            print("Abnormal length")
108
109        iq = np.frombuffer(data, dtype='int16')
110        np.savetxt(iq_fd, iq)
111
112        timestamp, iq_capture, agc_gain, rssi_half_db = parse_iq(iq, iq_len)
113        print(timestamp)
114        display_iq(iq_capture, agc_gain, rssi_half_db)
115
116    except KeyboardInterrupt:
117        print('User quit')
118        break
119
120print('close()')
121side_info_fd.close()
122sock.close()
123