コード例 #1
0
    def setupTxReplay(self, name):
        self._txReplayWaveform = name

        #empty string to disable
        if not name:
            return [
                iris.writeSetting("TX_REPLAY", "")
                for iris in self._writeIrises
            ][0]

        if name == "LTS":
            import lts
            samps = lts.genLTS()

        #TODO others

        def cfloat2uint32(arr):
            import numpy as np
            arr_i = (np.real(arr) * 32767).astype(np.uint16)
            arr_q = (np.imag(arr) * 32767).astype(np.uint16)
            return np.bitwise_or(arr_q,
                                 np.left_shift(arr_i.astype(np.uint32), 16))

        samps = cfloat2uint32(samps)
        for iris in self._writeIrises:
            iris.writeRegisters('TX_RAM_A', 0, cfloat2uint32(samps).tolist())
        for iris in self._writeIrises:
            iris.writeRegisters('TX_RAM_B', 0, cfloat2uint32(samps).tolist())
        for iris in self._writeIrises:
            iris.writeSetting("TX_REPLAY", str(len(samps)))
コード例 #2
0
def setupUE(args, serial, rate, freq, txgain, rxgain, numSamps, numSyms, pilotSymbol, txSymbol, txSymNum, threshold, tx_advance, prefix_length, postfix_length, cp, calibrate, both_channels, wait_trigger, auto_tx_gain):
    global msdr, txStreamM, rxStreamM
    msdr = SoapySDR.Device(dict(serial=serial))

    #some default sample rates
    for sdr in [msdr]:
        info = sdr.getHardwareInfo();
        print("%s settings" % info["frontend"])
        for ch in [0,1]:
            sdr.setSampleRate(SOAPY_SDR_TX, ch, rate)
            sdr.setSampleRate(SOAPY_SDR_RX, ch, rate)
            #sdr.setFrequency(SOAPY_SDR_TX, ch, freq)
            #sdr.setFrequency(SOAPY_SDR_RX, ch, freq)
            sdr.setFrequency(SOAPY_SDR_TX, ch, 'RF', freq-.75*rate)
            sdr.setFrequency(SOAPY_SDR_RX, ch, 'RF', freq-.75*rate)
            sdr.setFrequency(SOAPY_SDR_TX, ch, 'BB', .75*rate)
            sdr.setFrequency(SOAPY_SDR_RX, ch, 'BB', .75*rate)
            if ("CBRS" in info["frontend"]):
                sdr.setGain(SOAPY_SDR_TX, ch, 'ATTN', 0) #[-18,0] by 3
                sdr.setGain(SOAPY_SDR_TX, ch, 'PA1', 15) #[0|15]
                sdr.setGain(SOAPY_SDR_TX, ch, 'PA2', 0) #[0|15]
                sdr.setGain(SOAPY_SDR_TX, ch, 'PA3', 30) #[0|30]
            if ("UHF" in info["frontend"]):
                sdr.setGain(SOAPY_SDR_TX, ch, 'ATTN', 0) #[-18,0] by 3
            sdr.setGain(SOAPY_SDR_TX, ch, 'IAMP', 0) #[0,12]
            sdr.setGain(SOAPY_SDR_TX, ch, 'PAD', txgain) #[0,52]

            if ("CBRS" in info["frontend"]):
                sdr.setGain(SOAPY_SDR_RX, ch, 'ATTN', 0) #[-18,0]
                sdr.setGain(SOAPY_SDR_RX, ch, 'LNA1', 30) #[0,33]
                sdr.setGain(SOAPY_SDR_RX, ch, 'LNA2', 17) #[0,17]
            if ("UHF" in info["frontend"]):
                sdr.setGain(SOAPY_SDR_RX, ch, 'ATTN1', -6) #[-18,0]
                sdr.setGain(SOAPY_SDR_RX, ch, 'ATTN2', -12) #[-18,0]
            sdr.setGain(SOAPY_SDR_RX, ch, 'LNA', rxgain) #[0,30]
            sdr.setGain(SOAPY_SDR_RX, ch, 'TIA', 0) #[0,12]
            sdr.setGain(SOAPY_SDR_RX, ch, 'PGA', 0) #[-12,19]
            sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
            #sdr.setBandwidth(SOAPY_SDR_TX, ch, 30e6)
            #sdr.setBandwidth(SOAPY_SDR_RX, ch, 30e6)
            sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)
        if calibrate:
            for ch in [0,1]:
                sdr.writeSetting(SOAPY_SDR_RX, ch, "CALIBRATE", 'SKLK')
                sdr.writeSetting(SOAPY_SDR_TX, ch, "CALIBRATE", 'SKLK')
        #if not both_channels:
        #    sdr.writeSetting("SPI_TDD_MODE", "SISO")
        #    sdr.writeSetting(SOAPY_SDR_RX, 1, 'ENABLE_CHANNEL', 'false')
        #    sdr.writeSetting(SOAPY_SDR_TX, 1, 'ENABLE_CHANNEL', 'false')
        #else:
        #    sdr.writeSetting("SPI_TDD_MODE", "MIMO")

        sdr.writeRegister("IRIS30", RF_RST_REG, (1<<29) | 0x1)
        sdr.writeRegister("IRIS30", RF_RST_REG, (1<<29))
        sdr.writeRegister("IRIS30", RF_RST_REG, 0)
    msdr.writeRegister("ARGCOR", CORR_RST, 0x1) # reset corr
    msdr.writeRegister("IRIS30", TX_GAIN_CTRL, 0) 
    minfo = msdr.getHardwareInfo()
    #packet size
    symSamp = numSamps + prefix_length + postfix_length
    print("symSamp = %d"%symSamp)
    print("txSymNum = %d"%txSymNum)

    upsample = 1
    # preambles to be sent from BS and correlated against in UE
    preambles_bs, highest_peak_to_second_ratio_bs = Preambles.getPreambles('gold_ifft', 128, 0, upsample=1) #the base station may upsample, but the mobiles won't
    preambles = preambles_bs[:,::upsample] #the correlators can run at lower rates, so we only need the downsampled signal.
    
    beacon = preambles[0,:]*.25
    coe = cfloat2uint32(np.conj(beacon), order='QI') # FPGA correlator takes coefficients in QI order
    ltsSym = lts.genLTS(upsample=upsample,cp=1 if cp else 0)  
    pad1 = np.array([0]*(prefix_length), np.complex64) # to comprensate for front-end group delay
    pad2 = np.array([0]*(postfix_length), np.complex64) # to comprensate for rf path delay
    wb_pilot = np.tile(ltsSym,numSamps/len(ltsSym)).astype(np.complex64)*.5
    wbz = np.array([0]*(symSamp), np.complex64)
    wb_pilot1 = np.concatenate([pad1,wb_pilot,pad2]) 
    wb_pilot2 = wb_pilot1 if both_channels else wbz
    
    Ts = 1/rate
    s_freq = 1e6
    s_time_vals = np.array(np.arange(0,symSamp)).transpose()*Ts
    nb_data = np.exp(s_time_vals*1j*2*np.pi*s_freq).astype(np.complex64)*.25

    rand_data = [1,0,1,1,0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, \
				0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, \
				0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0 ,1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, \
				0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1 ,0, 1, 0, 0, \
				0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, \
				0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, \
				0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1]
    #data_16qam = genDATA(np.random.randint(2, size=64*4),0)
    data_16qam = ofdm.genDATAQPSK(rand_data,0)
    if not cp: data_16qam[16:]
    wb_data = np.tile(data_16qam,numSamps/len(data_16qam)).astype(np.complex64)*.5
    wb_data = np.concatenate([pad1,wb_data,pad2])

    if txSymNum > 0:
        txStreamM = msdr.setupStream(SOAPY_SDR_TX, SOAPY_SDR_CF32, [0, 1])  
        rxStreamM = msdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0, 1]) 
 
    msdr.writeRegister("IRIS30", CORR_CONF, int("00004001", 16)) # enable the correlator, with zeros as inputs 
    for i in range(128):
        msdr.writeRegister("ARGCOE", i*4, 0)
    time.sleep(0.1)
    msdr.writeRegister("ARGCOR", CORR_THRESHOLD, int(threshold))
    msdr.writeRegister("ARGCOR", CORR_RST, 0x1) # reset corr
    msdr.writeRegister("ARGCOR", CORR_RST, 0x0) # unrst corr 
    for i in range(128):
        msdr.writeRegister( "ARGCOE", i*4, int(coe[i]))
    if auto_tx_gain:
        max_gain = int(txgain)
        min_gain = max(0, max_gain-15)
        gain_reg = 0xF000 | (max_gain & 0x3F) << 6 | (min_gain & 0x3F)
        print("gain reg 0x%X" % gain_reg)
        msdr.writeRegister("IRIS30", TX_GAIN_CTRL, gain_reg) # [15] en, [14] mode, [13:12] step, [11:6] stop, [5:0] start 
    
    if both_channels:
        pilotSymNum = 2
        msched = ''.join("G"*(pilotSymbol-2))+"PP"
    else:
        pilotSymNum = 1
        msched = ''.join("G"*(pilotSymbol-2))+"P"
    if txSymNum > 0:
        msched += ''.join("G"*(txSymbol-pilotSymbol-pilotSymNum))+''.join("T"*txSymNum)+''.join("G"*(numSyms-txSymNum-txSymbol))
        msched = "GR" + msched
    else:
        msched += ''.join("G"*(numSyms-pilotSymbol-pilotSymNum))
        msched = "GG" + msched
    print("Client schedule %s " % msched)
    mconf = {"tdd_enabled": True, "trigger_out": True, "wait_trigger": True, "dual_pilot": both_channels, "symbol_size" : symSamp, "frames": [msched]}
    msdr.writeSetting("TDD_CONFIG", json.dumps(mconf))

    # DEV: ueTrigTime = 153 (prefix_length=0), CBRS: ueTrigTime = 235 (prefix_length=82), tx_advance=prefix_length
    ueTrigTime = prefix_length + len(beacon) + postfix_length + 17 + tx_advance 
    sf_start = ueTrigTime/symSamp
    sp_start = ueTrigTime%symSamp
    print("UE starting symbol and sample count (%d, %d)" % (sf_start, sp_start))
    msdr.setHardwareTime(SoapySDR.ticksToTimeNs((sf_start<<16) | sp_start, rate),"TRIGGER") # make sure to set this after TDD mode is enabled "writeSetting("TDD_CONFIG", ..."

    for sdr in [msdr]:
        sdr.writeSetting("TX_SW_DELAY", str(30))
    msdr.writeSetting("TDD_MODE", "true")

    replay_addr = 0
    if both_channels:
        msdr.writeRegisters("TX_RAM_A", replay_addr+(pilotSymbol%2)*2048, cfloat2uint32(wb_pilot1, order='QI').tolist())
        msdr.writeRegisters("TX_RAM_B", replay_addr+((pilotSymbol+1)%2)*2048, cfloat2uint32(wb_pilot1, order='QI').tolist())
    else:
        msdr.writeRegisters("TX_RAM_A", replay_addr, cfloat2uint32(wb_pilot1, order='QI').tolist())
        msdr.writeRegisters("TX_RAM_B", replay_addr, cfloat2uint32(wb_pilot2, order='QI').tolist())

    #pdb.set_trace()
    msdr.writeRegister("IRIS30", CORR_CONF, int("00004011", 16)) # enable the correlator, with inputs from adc
    signal.signal(signal.SIGINT, partial(signal_handler, rate, numSyms, txSymNum))
    if txSymNum>0:
        txth = threading.Thread(target=tx_thread, args=(msdr, rate, txStreamM, rxStreamM, wb_data, symSamp, numSyms, txSymNum, txSymbol))
        txth.start()
    #signal.pause()
    num_trig = 0
    while True:
        time.sleep(0.25)
        t = SoapySDR.timeNsToTicks(msdr.getHardwareTime(""),rate) >> 32 #trigger count is top 32 bits.
        print("%d new triggers, %d total" % (t - num_trig, t))
        num_trig = t
コード例 #3
0
def siso_sounder(serial1, serial2, rate, freq, txgain, rxgain, bw, numSamps,
                 numSyms, txSymNum, threshold, tx_advance, prefix_length,
                 postfix_length, both_channels, wait_trigger, calibrate,
                 record, use_trig, auto_tx_gain):
    global bsdr, msdr, txStreamM, rxStreamB
    print("setting %s as eNB and %s as UE" % (serial1, serial2))
    bsdr = SoapySDR.Device(dict(serial=serial1))
    msdr = SoapySDR.Device(dict(serial=serial2))

    #some default sample rates
    for i, sdr in enumerate([bsdr, msdr]):
        info = sdr.getHardwareInfo()
        print("%s settings on device %d" % (info["frontend"], i))
        for ch in [0, 1]:
            sdr.setSampleRate(SOAPY_SDR_TX, ch, rate)
            sdr.setSampleRate(SOAPY_SDR_RX, ch, rate)
            #sdr.setFrequency(SOAPY_SDR_TX, ch, freq)
            #sdr.setFrequency(SOAPY_SDR_RX, ch, freq)
            sdr.setFrequency(SOAPY_SDR_TX, ch, 'RF', freq - .75 * rate)
            sdr.setFrequency(SOAPY_SDR_RX, ch, 'RF', freq - .75 * rate)
            sdr.setFrequency(SOAPY_SDR_TX, ch, 'BB', .75 * rate)
            sdr.setFrequency(SOAPY_SDR_RX, ch, 'BB', .75 * rate)
            if ("CBRS" in info["frontend"]):
                sdr.setGain(SOAPY_SDR_TX, ch, 'ATTN', 0)  #[-18,0] by 3
                sdr.setGain(SOAPY_SDR_TX, ch, 'PA1', 15)  #[0,15]
                sdr.setGain(SOAPY_SDR_TX, ch, 'PA2', 0)  #[0,15]
                sdr.setGain(SOAPY_SDR_TX, ch, 'PA3', 30)  #[0,30]
            sdr.setGain(SOAPY_SDR_TX, ch, 'IAMP', 12)  #[0,12]
            sdr.setGain(SOAPY_SDR_TX, ch, 'PAD', txgain)  #[-52,0]

            if ("CBRS" in info["frontend"]):
                sdr.setGain(SOAPY_SDR_RX, ch, 'ATTN', 0)  #[-18,0]
                sdr.setGain(SOAPY_SDR_RX, ch, 'LNA1', 30)  #[0,33]
                sdr.setGain(SOAPY_SDR_RX, ch, 'LNA2', 17)  #[0,17]
            sdr.setGain(SOAPY_SDR_RX, ch, 'LNA', rxgain)  #[0,30]
            sdr.setGain(SOAPY_SDR_RX, ch, 'TIA', 0)  #[0,12]
            sdr.setGain(SOAPY_SDR_RX, ch, 'PGA', 0)  #[-12,19]
            sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
            #sdr.setBandwidth(SOAPY_SDR_RX, ch, bw)
            #sdr.setBandwidth(SOAPY_SDR_TX, ch, bw)
            sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)
        for ch in [0, 1]:
            if calibrate:
                sdr.writeSetting(SOAPY_SDR_RX, ch, "CALIBRATE", 'SKLK')
                sdr.writeSetting(SOAPY_SDR_TX, ch, "CALIBRATE", '')

        sdr.writeRegister("IRIS30", RF_RST_REG, (1 << 29) | 0x1)
        sdr.writeRegister("IRIS30", RF_RST_REG, (1 << 29))
        sdr.writeRegister("IRIS30", RF_RST_REG, 0)
        if not both_channels:
            sdr.writeSetting("SPI_TDD_MODE", "SISO")
            sdr.writeSetting(SOAPY_SDR_RX, 1, 'ENABLE_CHANNEL', 'false')
            sdr.writeSetting(SOAPY_SDR_TX, 1, 'ENABLE_CHANNEL', 'false')
        else:
            sdr.writeSetting("SPI_TDD_MODE", "MIMO")
    #pdb.set_trace()
    msdr.writeRegister("IRIS30", TX_GAIN_CTRL, 0)
    if use_trig:
        bsdr.writeSetting("SYNC_DELAYS", "")
        #bsdr.writeSetting("FPGA_DIQ_MODE", "PATTERN")
    else:
        msdr.writeRegister("ARGCOR", CORR_RST, 0x1)  # reset corr
    #packet size
    symSamp = numSamps + prefix_length + postfix_length
    print("numSamps = %d" % symSamp)
    print("txSymNum = %d" % txSymNum)
    upsample = 1
    Ts = 1 / rate
    s_freq = 1e6
    s_time_vals = np.array(np.arange(0, numSamps)).transpose() * Ts
    nb_data = np.exp(s_time_vals * 1j * 2 * np.pi * s_freq).astype(
        np.complex64) * .25

    #create streams
    rxStreamM = msdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0, 1])
    txStreamM = msdr.setupStream(SOAPY_SDR_TX, SOAPY_SDR_CF32, [0, 1])
    if record:
        rxStreamB = bsdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0, 1])

    # preambles to be sent from BS and correlated against in UE
    preambles_bs, highest_peak_to_second_ratio_bs = Preambles.getPreambles(
        'gold_ifft', 128, 0,
        upsample=1)  #the base station may upsample, but the mobiles won't
    preambles = preambles_bs[:, ::
                             upsample]  #the correlators can run at lower rates, so we only need the downsampled signal.

    beacon = preambles[0, :] * .25
    coe = cfloat2uint32(
        np.conj(beacon),
        order='QI')  # FPGA correlator takes coefficients in QI order
    ltsSym = lts.genLTS(upsample=1, cp=0)
    pad1 = np.array([0] * (prefix_length),
                    np.complex64)  # to comprensate for front-end group delay
    pad2 = np.array([0] * (postfix_length),
                    np.complex64)  # to comprensate for rf path delay
    wb_pilot = np.tile(ltsSym, numSamps / len(ltsSym)).astype(
        np.complex64) * .5
    wbz = np.array([0] * (symSamp), np.complex64)
    wb_pilot1 = np.concatenate([pad1, wb_pilot, pad2])
    wb_pilot2 = wbz  #wb_pilot1 if both_channels else wbz
    bcnz = np.array([0] * (symSamp - prefix_length - len(beacon)),
                    np.complex64)
    beacon1 = np.concatenate([pad1, beacon, bcnz])
    beacon2 = wbz  #beacon1 if both_channels else wbz

    bsched = "PGR" + ''.join("G" * (numSyms - txSymNum - 4)) + ''.join(
        "R" * txSymNum) + "G"
    msched = "GGP" + ''.join("G" * (numSyms - txSymNum - 4)) + ''.join(
        "T" * txSymNum) + "G"
    if both_channels:
        bsched = "PGRR" + ''.join("G" * (numSyms - txSymNum - 5)) + ''.join(
            "R" * txSymNum) + "G"
        msched = "GGPP" + ''.join("G" * (numSyms - txSymNum - 5)) + ''.join(
            "T" * txSymNum) + "G"
    print("Node 1 schedule %s " % bsched)
    print("Node 2 schedule %s " % msched)
    bconf = {
        "tdd_enabled": True,
        "trigger_out": False,
        "symbol_size": symSamp,
        "frames": [bsched]
    }
    mconf = {
        "tdd_enabled": True,
        "trigger_out": not use_trig,
        "wait_trigger": wait_trigger,
        "dual_pilot": both_channels,
        "symbol_size": symSamp,
        "frames": [msched]
    }
    #mconf = {"tdd_enabled": True, "trigger_out": not use_trig, "wait_trigger": True, "symbol_size" : symSamp, "frames": [msched]}
    bsdr.writeSetting("TDD_CONFIG", json.dumps(bconf))
    msdr.writeSetting("TDD_CONFIG", json.dumps(mconf))

    for sdr in [bsdr, msdr]:
        sdr.writeSetting("TX_SW_DELAY", str(30))

    if not use_trig:
        msdr.writeRegister("IRIS30", CORR_CONF, int(
            "00004001", 16))  # enable the correlator, with zeros as inputs
        for i in range(128):
            msdr.writeRegister("ARGCOE", i * 4, 0)
        time.sleep(0.1)
        msdr.writeRegister("ARGCOR", CORR_THRESHOLD, int(threshold))
        msdr.writeRegister("ARGCOR", CORR_RST, 0x1)  # reset corr
        msdr.writeRegister("ARGCOR", CORR_RST, 0x0)  # unrst corr
        for i in range(128):
            msdr.writeRegister("ARGCOE", i * 4, int(coe[i]))
        if auto_tx_gain:
            max_gain = int(txgain)
            min_gain = max(0, max_gain - 15)
            gain_reg = 0xF000 | (max_gain & 0x3F) << 6 | (min_gain & 0x3F)
            print("gain reg 0x%X" % gain_reg)
            msdr.writeRegister(
                "IRIS30", TX_GAIN_CTRL, gain_reg
            )  # [15] en, [14] mode, [13:12] step, [11:6] stop, [5:0] start

        # DEV: ueTrigTime = 153 (prefix_length=0), CBRS: ueTrigTime = 235 (prefix_length=82), tx_advance=prefix_length, corr delay is 17 cycles
        ueTrigTime = prefix_length + len(
            beacon) + postfix_length + 17 + tx_advance
        sf_start = ueTrigTime / symSamp
        sp_start = ueTrigTime % symSamp
        print("UE starting symbol and sample count (%d, %d)" %
              (sf_start, sp_start))
        msdr.setHardwareTime(
            SoapySDR.ticksToTimeNs((sf_start << 16) | sp_start,
                                   rate), "TRIGGER"
        )  # make sure to set this after TDD mode is enabled "writeSetting("TDD_CONFIG", ..."

    msdr.writeSetting("TDD_MODE", "true")
    bsdr.writeSetting("TDD_MODE", "true")

    replay_addr = 0
    bsdr.writeRegisters("TX_RAM_A", replay_addr,
                        cfloat2uint32(beacon1, order='IQ').tolist())
    bsdr.writeRegisters("TX_RAM_B", replay_addr,
                        cfloat2uint32(beacon2, order='IQ').tolist())

    msdr.writeRegisters("TX_RAM_A", replay_addr,
                        cfloat2uint32(wb_pilot1, order='IQ').tolist())
    msdr.writeRegisters("TX_RAM_B", replay_addr,
                        cfloat2uint32(wbz, order='IQ').tolist())
    if both_channels:
        msdr.writeRegisters("TX_RAM_A", replay_addr + 2048,
                            cfloat2uint32(wbz, order='IQ').tolist())
        msdr.writeRegisters("TX_RAM_B", replay_addr + 2048,
                            cfloat2uint32(wb_pilot2, order='IQ').tolist())

    if not use_trig:
        msdr.writeRegister("IRIS30", CORR_CONF, int(
            "00004011", 16))  # enable the correlator, with inputs from adc
    signal.signal(signal.SIGINT, partial(signal_handler, rate, numSyms))
    bsdr.writeSetting("TRIGGER_GEN", "")
    txth = threading.Thread(target=tx_thread,
                            args=(msdr, rate, txStreamM, rxStreamM, nb_data,
                                  symSamp, numSyms, txSymNum,
                                  numSyms - txSymNum - 1))
    txth.start()
    if record:
        rxth = threading.Thread(target=rx_thread,
                                args=(bsdr, rxStreamB, symSamp, txSymNum,
                                      both_channels))
        rxth.start()
    signal.pause()
コード例 #4
0
	def __init__(self,
		args,
		rate,
		freq=None,
		bw=None,
		txGain=None,
		rxGain=None,
		rxAnt=None,
		txAnt=None,
		serials=None,
		num_samps=None,
		LTSMode=False,
		ShowConst=False,
	):

		self.sdrs = [SoapySDR.Device(dict(driver="iris", serial = serial)) for serial in serials]
		#for serial in serials:
		#	print(serial)
		#	SoapySDR.Device(dict(driver="iris", serial = serial))

		#split array in half for normal mode, use last SDR for tx if LTSMode
		if LTSMode:
						self.tx_sdrs = [self.sdrs[-1]]
						self.rx_sdrs = self.sdrs[:-1]
		else:
			self.tx_sdrs = self.sdrs[0:len(self.sdrs)//2]
			self.rx_sdrs = self.sdrs[len(self.sdrs)//2:]
		self.trig_sdr = self.sdrs[0]
		self.num_samps = num_samps
		self.LTSMode = LTSMode
		self.ShowConst = ShowConst

		print("Using %i tx Irises and %i rx Irises." % (len(self.tx_sdrs), len(self.rx_sdrs)) )

		#initialize in parallel
		self.sdrs = SoapySDR.Device([dict(driver='iris',serial=s) for s in serials])
		threads = [threading.Thread(target=self.initSDR, args=[sdr, rate, freq, bw, txGain, rxGain, rxAnt, txAnt]) for sdr in self.sdrs]
		for t in threads: t.start()
		for t in threads: t.join()
		
		#Sync timestamps with trigger
		self.trig_sdr.writeSetting('SYNC_DELAYS', "")
		for sdr in self.sdrs: sdr.setHardwareTime(0, "TRIGGER")


		#create rx streams
		self.rxStreams = [sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32, [0, 1], {"remote:prot":"tcp", "remote:mtu":"1024"}) for sdr in self.rx_sdrs]
		num_rx_r = len(self.rx_sdrs)*2
		self.sampsRecv = [np.empty(num_samps+int(num_samps*self.LTSMode*1.5)).astype(np.complex64) for r in range(num_rx_r)]
		print("Receiving chunks of %i" % len(self.sampsRecv[0]))

		#create tx stream
		self.txStreams = []
		for sdr in self.tx_sdrs:
			if not self.LTSMode:
				txStream = sdr.setupStream(SOAPY_SDR_TX, SOAPY_SDR_CF32, [0, 1], {})
				sdr.activateStream(txStream)
				self.txStreams.append(txStream)
			print("Activate Tx Stream, replay = " + str(self.LTSMode))
	

		#create our own sinusoid
		Ts = 1/rate
		s_length = 768
		s_freq = 1e6
		s_time_vals = np.array(np.arange(0,s_length)).transpose()*Ts
		s = np.exp(s_time_vals*1j*2*np.pi*s_freq).astype(np.complex64)*.25
		num_tx_r = len(self.tx_sdrs)*2
		self.sampsToSend = [np.zeros(num_samps).astype(np.complex64) for r in range(num_tx_r)]

		if LTSMode:
			if self.ShowConst:
				num_syms = 22
				num_const = 52*num_syms
				syms = np.random.randint(2, size=num_const)*2-1 + np.random.randint(2, size=num_const)*2j-1j
				syms = np.reshape(syms,(num_syms,52))
				syms_z = np.append(np.insert(np.insert(syms,0,np.zeros((6,num_syms)),axis=1),32,np.zeros((1,num_syms)),axis=1),np.zeros((num_syms,5)),axis=1)
				syms_time = np.fft.ifft(np.fft.ifftshift(syms_z,axes=(1)),axis=1)
				syms_time_cp = np.insert(syms_time,0,np.transpose(syms_time[:,-16:]),axis=1)
				samps = syms_time_cp.flatten()
				lts_samps = lts.genLTS()
				self.sampsToSend = [[], []]
				self.sampsToSend[0] = np.concatenate((lts_samps,samps,np.zeros(256))).astype(np.complex64)
				self.sampsToSend[1] = np.concatenate((lts_samps,samps,np.zeros(256))).astype(np.complex64)
			else:
				l = np.concatenate((lts.genLTS(),np.zeros(64),s))
				self.sampsToSend[0][:len(l)] = l
				self.sampsToSend[1][len(l)+64:len(l)+len(s)+64] = s

			usetrig = False
			for r,sdr in enumerate(self.tx_sdrs):
				replay_addr = 0
				max_replay = 4096  #todo: read from hardware
				if(len(self.sampsToSend[0]) > max_replay):
					print("Warning: Continuous mode signal must be less than %d samples. Using first %d samples." % (max_replay, max_replay) )
					self.sampsToSend[0] = self.sampsToSend[0][:max_replay]
					self.sampsToSend[1] = self.sampsToSend[1][:max_replay]
					
				sdr.writeRegisters('TX_RAM_A', replay_addr, cfloat2uint32(self.sampsToSend[0]).tolist())
				sdr.writeRegisters('TX_RAM_B', replay_addr, cfloat2uint32(self.sampsToSend[1]).tolist())
				sdr.writeSetting("TX_REPLAY", str(len(self.sampsToSend[0])))
				
				if False:
					timeNowNs = sdr.getHardwareTime()
					txTime = timeNowNs + int(1e8)# 100 ms in the future
					flags = SOAPY_SDR_WAIT_TRIGGER | SOAPY_SDR_END_BURST if usetrig else SOAPY_SDR_END_BURST | SOAPY_SDR_HAS_TIME
					txStream = self.txStreams[r]
					sdr.activateStream(txStream)
					numSent = 0
					while numSent < len(self.sampsToSend[0]):
						if usetrig:
							sr = sdr.writeStream(txStream, [self.sampsToSend[r*2][numSent:], self.sampsToSend[r*2+1][numSent:]], len(self.sampsToSend[0])-numSent, flags)
						else:
							sr = sdr.writeStream(txStream, [self.sampsToSend[r*2][numSent:], self.sampsToSend[r*2+1][numSent:]], len(self.sampsToSend[0])-numSent, flags, timeNs=txTime)
							flags = SOAPY_SDR_END_BURST #clear has time for next call
						print(sr) 
						#assertGreater(sr.ret, 0)
						numSent += sr.ret
						if sr.ret == -1:
							print('Bad Write!')
					
					if usetrig: 
						time.sleep(0.1) #seems that the tx data may not have gone through both IP stacks and DMA yet, so we need to wait a bit to avoid a race.
						sdr.writeSetting("TRIGGER_GEN", "")		

		# GM (not lts mode)
		else:

			#scaler = (np.arange(s_length/2)).astype(np.complex64)/(s_length/2)
			#scaler_tri = np.concatenate((scaler,scaler[::-1]))
			#s = np.multiply(s,scaler_tri)
			g_length = 256 #guard length

			#samples to send is a two channel array of complex floats
			for r in range(num_tx_r):
				self.sampsToSend[r][r*(s_length+g_length):(r+1)*(s_length+g_length)-g_length] = s #staggered sinusoids

		print("Done initializing MIMOGui.")
コード例 #5
0
	def update(self):
		'''Get new samples (from mimo_sdr) and plot them.'''
		sps = 80
		num_syms = 24
		spp = 1920//sps
		fft_len = int(sps*.8)
		#delay = int(sps*.1)
		delay = 16
		leadtime = 128

		samps = self.mimo_sdr.getSamples()
		if samps == -1: 
			return #don't die -- just try again on the next update

		if self.LTSMode:
			(lts_start, ltss, peaks) = lts.findLTS(samps[0][leadtime*2:2048+leadtime*2])
			packet_start = lts_start - 32 + leadtime*2 #(sps-fft_len)
			packet_start = 0 if packet_start < 0 else packet_start
			#print((lts_start,ltss))

		for plt in range(self.num_plots):
			#if we're in LTSMode we align the samples by detecting the LTS
			if self.LTSMode:
				packet_samps = samps[0][packet_start:packet_start+num_syms*sps]
				#print((packet_start,packet_start+num_syms*sps))
	
				spec = np.log10(np.fft.fftshift(np.square(np.fft.fft(samps[0][:128]))))*10

				if False:  #highlight packet, but don't adjust viewing window.
					corr1 = np.correlate(samps[plt],lts.genLTS()[32:64+32])/12
					corr2 = corr1[:-64]*corr1[64:]
					self.Corr_plots[plt].setData(np.abs(corr2[:self.num_samps]))
					self.I_plots[plt].setData(samps[plt][128:128+self.num_samps].real) # - np.mean(samps[plt][:self.num_samps].real))
					self.Q_plots[plt].setData(samps[plt][128:128+self.num_samps].imag) # - np.mean(samps[plt][:self.num_samps].imag))
					#self.LR[plt].setRegion([packet_start-128,packet_start+num_syms*sps-128]) #if we plot raw samps, this will track
					self.LR[plt].setRegion([packet_start-128,packet_start+160+768+64-128]) #if we plot raw samps, this will track

				else:
					
					packet_samps = samps[plt][packet_start-leadtime*2:packet_start+self.num_samps-leadtime]
					corr1 = np.correlate(packet_samps,lts.genLTS()[32:64+32])/10
					corr2 = corr1[:-64]*corr1[64:]
					packet_samps = packet_samps[leadtime:] #realign correlation
					self.Corr_plots[plt].setData(np.abs(corr2))
					self.I_plots[plt].setData(packet_samps.real) # - np.mean(samps[plt][:self.num_samps].real))
					self.Q_plots[plt].setData(packet_samps.imag) # - np.mean(samps[plt][:self.num_samps].imag))

				if self.ShowConst:
					syms = np.reshape(packet_samps, (num_syms,sps) )
					#syms_freq = np.fft.fft(np.fft.fftshift(syms[:,delay:delay+fft_len],axes=(1)),axis=1)
					syms_freq = np.fft.fftshift(np.fft.fft(syms[2:,delay:delay+fft_len],axis=1),axes=(1))
					sl = list(range(6,32))+list(range(33,59))
					#chan_est = 1/(np.mean(syms_freq[:2,:],axis=0)*lts.lts_freq)[sl]
					chan_est = 1/(np.mean(np.fft.fftshift(np.fft.fft(np.reshape(packet_samps[16+delay:16+delay+fft_len*2], (2,fft_len) ),axis=1),axes=(1)),axis=0)*lts.lts_freq)
					chan_est = chan_est[sl]
					syms_freq = syms_freq[:,sl]
					syms_freq_eq = syms_freq*chan_est
					#print(np.abs(chan_est))
					syms_freq_flat = syms_freq_eq.flatten()			
					#self.LR[plt].setRegion([0,num_syms*sps])
					self.Const_data[plt].setPoints(x=syms_freq_flat.real, y=syms_freq_flat.imag)
			
				#let's calculate some power figures for other purposes (e.g. antenna testing)
				if True:
					amp = np.mean(np.abs(packet_samps))
					pwr = amp**2
					print("start: %i  end: %i  amp: %f  pwr: %f  pwr_dB: %f" % (packet_start, packet_start+num_syms*sps, amp, pwr, 10*np.log10(pwr)) )
			#if we're not in LTSMode, the triggers align everything, so we can just display it.		
			else:
				self.I_plots[plt].setData(samps[plt][:self.num_samps].real) # - np.mean(samps[plt][:self.num_samps].real))
				self.Q_plots[plt].setData(samps[plt][:self.num_samps].imag) # - np.mean(samps[plt][:self.num_samps].imag))