xref: /openwifi/user_space/side_ch_ctl_src/iq_capture_2ant.py (revision e556af35c696ecef552192823e107caf37eb6af9)
15deb8d18SXianjun Jiao#
25deb8d18SXianjun Jiao# openwifi side info receive and display program
35deb8d18SXianjun Jiao# Xianjun jiao. [email protected]; [email protected]
45deb8d18SXianjun Jiao#
55deb8d18SXianjun Jiaoimport os
65deb8d18SXianjun Jiaoimport sys
75deb8d18SXianjun Jiaoimport socket
85deb8d18SXianjun Jiaoimport numpy as np
95deb8d18SXianjun Jiaoimport matplotlib.pyplot as plt
105deb8d18SXianjun Jiao
115deb8d18SXianjun Jiaodef display_iq(iq0_capture, iq1_capture):
125deb8d18SXianjun Jiao    fig_iq_capture = plt.figure(0)
135deb8d18SXianjun Jiao    fig_iq_capture.clf()
145deb8d18SXianjun Jiao
155deb8d18SXianjun Jiao    ax_iq0 = fig_iq_capture.add_subplot(211)
165deb8d18SXianjun Jiao    # ax_iq0.set_xlabel("sample")
175deb8d18SXianjun Jiao    ax_iq0.set_ylabel("I/Q")
185deb8d18SXianjun Jiao    ax_iq0.set_title("rx0 I/Q")
195deb8d18SXianjun Jiao    plt.plot(iq0_capture.real, 'b')
205deb8d18SXianjun Jiao    plt.plot(iq0_capture.imag, 'r')
215deb8d18SXianjun Jiao    plt.ylim(-32767, 32767)
225deb8d18SXianjun Jiao
235deb8d18SXianjun Jiao    ax_iq1 = fig_iq_capture.add_subplot(212)
245deb8d18SXianjun Jiao    ax_iq1.set_xlabel("sample")
255deb8d18SXianjun Jiao    ax_iq1.set_ylabel("I/Q")
265deb8d18SXianjun Jiao    ax_iq1.set_title("rx1 I/Q")
275deb8d18SXianjun Jiao    plt.plot(iq1_capture.real, 'b')
285deb8d18SXianjun Jiao    plt.plot(iq1_capture.imag, 'r')
295deb8d18SXianjun Jiao    plt.ylim(-32767, 32767)
309fde3bffSthavinga    fig_iq_capture.canvas.flush_events()
315deb8d18SXianjun Jiao
325deb8d18SXianjun Jiaodef parse_iq(iq, iq_len):
335deb8d18SXianjun Jiao    # print(len(iq), iq_len)
345deb8d18SXianjun Jiao    num_dma_symbol_per_trans = 1 + iq_len
355deb8d18SXianjun Jiao    num_int16_per_trans = num_dma_symbol_per_trans*4 # 64bit per dma symbol
365deb8d18SXianjun Jiao    num_trans = round(len(iq)/num_int16_per_trans)
375deb8d18SXianjun Jiao    # print(len(iq), iq.dtype, num_trans)
385deb8d18SXianjun Jiao    iq = iq.reshape([num_trans, num_int16_per_trans])
395deb8d18SXianjun Jiao
405deb8d18SXianjun Jiao    timestamp = iq[:,0] + pow(2,16)*iq[:,1] + pow(2,32)*iq[:,2] + pow(2,48)*iq[:,3]
41*e556af35SXianjun Jiao    iq0_capture = np.int16(iq[:,4::4]) + np.int16(iq[:,5::4])*1j
42*e556af35SXianjun Jiao    iq1_capture = np.int16(iq[:,6::4]) + np.int16(iq[:,7::4])*1j
435deb8d18SXianjun Jiao    # print(num_trans, iq_len, iq0_capture.shape, iq1_capture.shape)
445deb8d18SXianjun Jiao
455deb8d18SXianjun Jiao    iq0_capture = iq0_capture.reshape([num_trans*iq_len,])
465deb8d18SXianjun Jiao    iq1_capture = iq1_capture.reshape([num_trans*iq_len,])
475deb8d18SXianjun Jiao
485deb8d18SXianjun Jiao    return timestamp, iq0_capture, iq1_capture
495deb8d18SXianjun Jiao
505deb8d18SXianjun JiaoUDP_IP = "192.168.10.1" #Local IP to listen
515deb8d18SXianjun JiaoUDP_PORT = 4000         #Local port to listen
525deb8d18SXianjun Jiao
535deb8d18SXianjun Jiaosock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
545deb8d18SXianjun Jiaosock.bind((UDP_IP, UDP_PORT))
55a4eb2001SXianjun Jiaosock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 464) # for low latency. 464 is the minimum udp length in our case (CSI only)
565deb8d18SXianjun Jiao
575deb8d18SXianjun Jiao# align with side_ch_control.v and all related user space, remote files
585deb8d18SXianjun JiaoMAX_NUM_DMA_SYMBOL = 8192
595deb8d18SXianjun Jiao
605deb8d18SXianjun Jiaoif len(sys.argv)<2:
615deb8d18SXianjun Jiao    print("Assume iq_len = 8187! (Max UDP 65507 bytes; (65507/8)-1 = 8187)")
625deb8d18SXianjun Jiao    iq_len = 8187
635deb8d18SXianjun Jiaoelse:
645deb8d18SXianjun Jiao    iq_len = int(sys.argv[1])
655deb8d18SXianjun Jiao    print(iq_len)
665deb8d18SXianjun Jiao    # print(type(num_eq))
675deb8d18SXianjun Jiao
685deb8d18SXianjun Jiaoif iq_len>8187:
695deb8d18SXianjun Jiao    iq_len = 8187
705deb8d18SXianjun Jiao    print('Limit iq_len to 8187! (Max UDP 65507 bytes; (65507/8)-1 = 8187)')
715deb8d18SXianjun Jiao
725deb8d18SXianjun Jiaonum_dma_symbol_per_trans = 1 + iq_len
735deb8d18SXianjun Jiaonum_byte_per_trans = 8*num_dma_symbol_per_trans
745deb8d18SXianjun Jiao
755deb8d18SXianjun Jiaoif os.path.exists("iq_2ant.txt"):
765deb8d18SXianjun Jiao    os.remove("iq_2ant.txt")
775deb8d18SXianjun Jiaoiq_fd=open('iq_2ant.txt','a')
785deb8d18SXianjun Jiao
799fde3bffSthavingaplt.ion()
809fde3bffSthavinga
815deb8d18SXianjun Jiaowhile True:
825deb8d18SXianjun Jiao    try:
835deb8d18SXianjun Jiao        data, addr = sock.recvfrom(MAX_NUM_DMA_SYMBOL*8) # buffer size
845deb8d18SXianjun Jiao        # print(addr)
855deb8d18SXianjun Jiao        test_residual = len(data)%num_byte_per_trans
865deb8d18SXianjun Jiao        # print(len(data)/8, num_dma_symbol_per_trans, test_residual)
875deb8d18SXianjun Jiao        if (test_residual != 0):
885deb8d18SXianjun Jiao            print("Abnormal length")
895deb8d18SXianjun Jiao
90*e556af35SXianjun Jiao        iq = np.frombuffer(data, dtype='uint16')
915deb8d18SXianjun Jiao        np.savetxt(iq_fd, iq)
925deb8d18SXianjun Jiao
935deb8d18SXianjun Jiao        timestamp, iq0_capture, iq1_capture = parse_iq(iq, iq_len)
945deb8d18SXianjun Jiao        print(timestamp, max(iq0_capture.real), max(iq1_capture.real))
955deb8d18SXianjun Jiao        display_iq(iq0_capture, iq1_capture)
965deb8d18SXianjun Jiao
975deb8d18SXianjun Jiao    except KeyboardInterrupt:
985deb8d18SXianjun Jiao        print('User quit')
995deb8d18SXianjun Jiao        break
1005deb8d18SXianjun Jiao
1015deb8d18SXianjun Jiaoprint('close()')
1029fde3bffSthavingaiq_fd.close()
1035deb8d18SXianjun Jiaosock.close()
104