示例#1
0
def set_python_log_handler(exception_level=None):
    """Replace the default SoapySDR log handler with a Python one.

    The python handler sends the log text to stderr.

    If the log_level is at exception_level or worse then a SoapyException
    is thrown.
    """

    log_level_text = {
        SOAPY_SDR_FATAL: "FATAL",
        SOAPY_SDR_CRITICAL: "CRITICAL",
        SOAPY_SDR_ERROR: "ERROR",
        SOAPY_SDR_WARNING: "WARNING",
        SOAPY_SDR_NOTICE: "NOTICE",
        SOAPY_SDR_INFO: "INFO",
        SOAPY_SDR_DEBUG: "DEBUG",
        SOAPY_SDR_TRACE: "TRACE",
        SOAPY_SDR_SSI: "SSI"}

    def log_handler(log_level, message):
        level_text = log_level_text[log_level]
        log_text = "[{}] {}".format(level_text, message)
        print(log_text, file=sys.stderr)
        if exception_level is not None and log_level <= exception_level:
            raise SoapyException(log_text)

    SoapySDR.registerLogHandler(log_handler)
示例#2
0
import SoapySDR
from SoapySDR import *  #SOAPY_SDR_* constants

import numpy as np

import time

if __name__ == '__main__':
    streamBoardSDR = SoapySDR.Device({"driver": "lime"})

    print("Pick sample rates")
    streamBoardSDR.setSampleRate(SOAPY_SDR_RX, 0, 13e6 / 48)
    streamBoardSDR.setSampleRate(SOAPY_SDR_TX, 0, 13e6 / 12)

    print 'Results...'
    print 'Rx', streamBoardSDR.getSampleRate(SOAPY_SDR_RX, 0) / 1e6, "MHz"
    print 'Tx', streamBoardSDR.getSampleRate(SOAPY_SDR_TX, 0) / 1e6, "MHz"
    print 'CGEN', streamBoardSDR.getMasterClockRate() / 1e6, "MHz"
示例#3
0
def main(args):
    # Create an SDR device instance
    try:
        sdr = SoapySDR.Device(dict(driver="lime"))
    except:
        sys.stderr.write("Failed to create an SDR device instance.\n")
        return False

    if not sdr:
        sys.stderr.write("Could not find any SDR devices.\n")
        return False

    # Setup the Rx channel 0
    sdr.setSampleRate(SoapySDR.SOAPY_SDR_RX, 0, args.sample_rate)
    sdr.setBandwidth(SoapySDR.SOAPY_SDR_RX, 0, args.bandwidth)
    sdr.setAntenna(SoapySDR.SOAPY_SDR_RX, 0, "LNAW")
    sdr.setGain(SoapySDR.SOAPY_SDR_RX, 0, 30.0)
    sdr.setFrequency(SoapySDR.SOAPY_SDR_RX, 0, args.rf)

    # Setup an Rx stream
    rxStream = sdr.setupStream(SoapySDR.SOAPY_SDR_RX, SoapySDR.SOAPY_SDR_CF32,
                               [0])
    # Activate the stream
    sdr.activateStream(rxStream)

    # Check the maximum transmit unit
    mtu = sdr.getStreamMTU(rxStream)

    # Prepare a receive buffer
    rxBuffer = np.zeros(mtu, np.complex64)

    prevSamples = np.array([], dtype=np.complex64)
    while True:
        # Receive samples
        status = sdr.readStream(rxStream, [rxBuffer], rxBuffer.size)
        if status.ret != rxBuffer.size:
            sys.stderr.write(
                "Failed to receive samples in readStream(): {}\n".format(
                    status.ret))
            return False
        # Concatenate the previous samples and the current samples
        samples = np.concatenate([prevSamples, rxBuffer])
        # Calculate angles from previous symbols
        cur = samples[args.samples_per_symbol:]  # current symbols
        prev = samples[0:-args.samples_per_symbol]  # previous symbols
        prev = np.where(prev == 0, prev + 1e-9, prev)  # to avoid zero division
        x = cur / prev
        diffAngles = np.arctan2(x.imag, x.real)
        # Check if the preamble is included
        if np.sum(np.absolute(diffAngles) > math.pi /
                  2) >= 8 * args.samples_per_symbol:
            # Concatenate two sample buffers
            samples = np.copy(rxBuffer)
            status = sdr.readStream(rxStream, [rxBuffer], rxBuffer.size)
            if status.ret != rxBuffer.size:
                sys.stderr.write(
                    "Failed to receive samples in readStream(): {}\n".format(
                        status.ret))
                return False
            samples = np.concatenate([samples, rxBuffer])
            if demodulate(samples, args.samples_per_symbol):
                break
        prevSamples = np.copy(rxBuffer)

    # Deactivate and close the stream
    sdr.deactivateStream(rxStream)
    sdr.closeStream(rxStream)
示例#4
0
    def __init__(
        self,
        serial_id=None,
        tx_freq=None,
        rx_freq=None,
        tx_gain=None,
        rx_gain=None,
        bw=None,
        sample_rate=None,
        n_samp=None,  # Total number of samples, including zero-pads
        n_zpad_samp=150,  # Total number of samples used for zero-padding in prefix and postfix
        max_frames=1,  # Number of frames TXed: How many times the schedule will be repeated
        both_channels=False,
        agc_en=False,
    ):

        if serial_id is not None:
            self.sdr = SoapySDR.Device(dict(driver="iris", serial=serial_id))
            self.serial_id = serial_id
        else:
            self.sdr = None

        self.sample_rate = sample_rate

        if n_samp is not None: self.n_samp = int(n_samp)

        self.agc_en = agc_en
        self.both_channels = both_channels
        self.n_zpad_samp = int(n_zpad_samp)
        self.max_frames = int(max_frames)

        # PACKET DETECT SETUP
        self.sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_THRESH, 0)
        self.sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_NUM_SAMPS, 5)
        self.sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_ENABLE, 0)
        self.sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_NEW_FRAME, 0)

        ### Setup channel rates, ports, gains, and filters ###
        info = self.sdr.getHardwareInfo()
        for chan in [0, 1]:

            #Tx:
            if sample_rate is not None:
                self.sdr.setSampleRate(SOAPY_SDR_TX, chan, sample_rate)
            if bw is not None:
                self.sdr.setBandwidth(SOAPY_SDR_TX, chan, bw)
            else:
                self.sdr.setBandwidth(SOAPY_SDR_TX, chan, 2.5 * sample_rate)
            if tx_gain is not None:
                self.sdr.setGain(SOAPY_SDR_TX, chan, tx_gain)
            if tx_freq is not None:
                self.sdr.setFrequency(SOAPY_SDR_TX, chan, 'RF',
                                      tx_freq - .75 * sample_rate)
                self.sdr.setFrequency(SOAPY_SDR_TX, chan, 'BB',
                                      .75 * sample_rate)

            #print("Set TX frequency to %f" % self.sdr.getFrequency(SOAPY_SDR_TX, chan))
            #self.sdr.setAntenna(SOAPY_SDR_TX, chan, "TRX")
            self.sdr.setGain(SOAPY_SDR_TX, chan, 'IAMP', 12)  #[0,12]
            self.sdr.setGain(SOAPY_SDR_TX, chan, 'PAD', tx_gain)  #[-52,0]

            #Rx:
            if sample_rate is not None:
                self.sdr.setSampleRate(SOAPY_SDR_RX, chan, sample_rate)
            if bw is not None:
                self.sdr.setBandwidth(SOAPY_SDR_RX, chan, bw)
            else:
                self.sdr.setBandwidth(SOAPY_SDR_RX, chan, 2.5 * sample_rate)
            if rx_gain is not None:
                self.sdr.setGain(SOAPY_SDR_RX, chan, rx_gain)
            if rx_freq is not None:
                self.sdr.setFrequency(SOAPY_SDR_RX, chan, 'RF',
                                      rx_freq - .75 * sample_rate)
                self.sdr.setFrequency(SOAPY_SDR_RX, chan, 'BB',
                                      .75 * sample_rate)

            self.sdr.setAntenna(SOAPY_SDR_RX, chan, "TRX")

            if self.agc_en:
                self.sdr.setGain(SOAPY_SDR_RX, chan, 'LNA', 30)  # [0,30]
                self.sdr.setGain(SOAPY_SDR_RX, chan, 'TIA', 12)  # [0,12]
                self.sdr.setGain(SOAPY_SDR_RX, chan, 'PGA', 19)  # [-12,19]
            else:
                self.sdr.setGain(SOAPY_SDR_RX, chan, 'LNA', rx_gain)  #[0,30]
                self.sdr.setGain(SOAPY_SDR_RX, chan, 'TIA', 0)  #[0,12]
                self.sdr.setGain(SOAPY_SDR_RX, chan, 'PGA', 0)  #[-12,19]

            self.sdr.setDCOffsetMode(SOAPY_SDR_RX, chan, True)

            if ("CBRS" in info["frontend"]):
                #Tx:
                self.sdr.setGain(SOAPY_SDR_TX, chan, 'ATTN', 0)  #[-18,0] by 3
                self.sdr.setGain(SOAPY_SDR_TX, chan, 'PA1', 15)  #[0|15]
                self.sdr.setGain(SOAPY_SDR_TX, chan, 'PA2', 0)  #[0|15]
                self.sdr.setGain(SOAPY_SDR_TX, chan, 'PA3', 30)  #[0|30]
                #Rx:
                self.sdr.setGain(SOAPY_SDR_RX, chan, 'ATTN', -18)  #[-18,0]
                self.sdr.setGain(SOAPY_SDR_RX, chan, 'LNA1', 30)  #[0,33]
                self.sdr.setGain(SOAPY_SDR_RX, chan, 'LNA2', 17)  #[0,17]

        self.tx_stream = None  # Burst mode

        self.sdr.writeRegister("IRIS30", RF_RST_REG, (1 << 29) | 0x1)
        self.sdr.writeRegister("IRIS30", RF_RST_REG, (1 << 29))
        self.sdr.writeRegister("IRIS30", RF_RST_REG, 0)

        if not self.both_channels:
            self.sdr.writeSetting(SOAPY_SDR_RX, 1, 'ENABLE_CHANNEL', 'false')
            self.sdr.writeSetting(SOAPY_SDR_TX, 1, 'ENABLE_CHANNEL', 'false')
示例#5
0
import numpy as np
import os

import SoapySDR
from SoapySDR import *

from util import simulation

# soapysdr is not on pip, it is a python binding to a c++ library

soapy1 = SoapySDR.Device_enumerate()[-1]

#class Simulated:
#    def __init__(self, name='receiver'):
#        self.name = name
#        self.sim = simulation(name)
#        self.tuner = Simulated.Tuner(self, name + '_tuner')
#    def enable(self):
#    def disable(self):
#        self.sim = None
#    def read(self):
#        return self.sim.read()
#    class Tuner:
#        def __init__(self, fn):
#            self.sim = simulation(name)
#            self.last = self.sim.read()


class Receiver:
    def __init__(self,
                 soapy_device_data=soapy1,
示例#6
0
def siso_tdd_burst(serial1, serial2, rate, freq, txgain, rxgain, numSamps, prefix_pad, postfix_pad):
    bsdr = SoapySDR.Device(dict(driver='iris', serial=serial1))
    msdr = SoapySDR.Device(dict(driver='iris', 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.setBandwidth(SOAPY_SDR_TX, ch, 2.5*rate)
            sdr.setBandwidth(SOAPY_SDR_RX, ch, 2.5*rate)
            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)
            sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
            sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)

            if "CBRS" in info["frontend"]:
                # Set gains to high val (initially)
                # sdr.setGain(SOAPY_SDR_TX, ch, txgain)  # txgain: at 2.5GHz [16:1:93], at 3.6GHz [15:1:102]
                # sdr.setGain(SOAPY_SDR_RX, ch, rxgain)  # rxgain: at 2.5GHz [3:1:105], at 3.6GHz [3:1:102]
            # else:
                # No CBRS board gains, only changing LMS7 gains
                sdr.setGain(SOAPY_SDR_TX, ch, "PAD", txgain) # [0:1:42] txgain
                sdr.setGain(SOAPY_SDR_TX, ch, "ATTN", -6)
                sdr.setGain(SOAPY_SDR_RX, ch, "LNA", rxgain) # [0:1:30] rxgain
                sdr.setGain(SOAPY_SDR_RX, ch, "LNA2", 14)
                sdr.setGain(SOAPY_SDR_RX, ch, "ATTN", 0 if freq > 3e9 else -18)

    # SYNC_DELAYS
    bsdr.writeSetting("SYNC_DELAYS", "")

    # Packet size
    symSamp = numSamps + prefix_pad + postfix_pad
    print("numSamps = %d" % numSamps)
    print("symSamps = %d" % symSamp)

    # Generate sinusoid to be TX
    Ts = 1 / rate
    s_freq = 1e5
    s_time_vals = np.array(np.arange(0, numSamps)).transpose()*Ts
    pilot = np.exp(s_time_vals*1j*2*np.pi*s_freq).astype(np.complex64)*1
    pad1 = np.array([0]*prefix_pad, np.complex64)
    pad2 = np.array([0]*postfix_pad, np.complex64)
    wbz = np.array([0]*symSamp, np.complex64)
    pilot1 = np.concatenate([pad1, pilot, pad2])
    pilot2 = wbz

    # Initialize RX arrays
    waveRxA1 = np.array([0]*symSamp, np.uint32)
    waveRxB1 = np.array([0]*symSamp, np.uint32)
    waveRxA2 = np.array([0]*symSamp, np.uint32)
    waveRxB2 = np.array([0]*symSamp, np.uint32)

    # Create RX streams
    # CS16 makes sure the 4-bit lsb are samples are being sent
    rxStreamB = bsdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0, 1])
    rxStreamM = msdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0, 1])

    # Set Schedule
    bsched = "PGRG"
    msched = "RGPG"
    print("Node 1 schedule %s " % bsched)
    print("Node 2 schedule %s " % msched)
    # Send one frame (set mamx_frame to 1)
    bconf = {"tdd_enabled": True,
             "frame_mode": "free_running",
             "symbol_size": symSamp,
             "frames": [bsched],
             "max_frame": 1}
    mconf = {"tdd_enabled": True,
             "frame_mode": "free_running",
             "dual_pilot": False,
             "symbol_size": symSamp,
             "frames": [msched],
             "max_frame": 1}
    bsdr.writeSetting("TDD_CONFIG", json.dumps(bconf))
    msdr.writeSetting("TDD_CONFIG", json.dumps(mconf))

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

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

    for sdr in [bsdr, msdr]:
        sdr.writeRegisters("TX_RAM_A", 0, cfloat2uint32(pilot1, order='QI').tolist())
        sdr.writeRegisters("TX_RAM_B", 0, cfloat2uint32(pilot2, order='QI').tolist())

    flags = 0
    r1 = bsdr.activateStream(rxStreamB, flags, 0)
    r2 = msdr.activateStream(rxStreamM, flags, 0)
    if r1 < 0:
        print("Problem activating stream #1")
    if r2 < 0:
        print("Problem activating stream #2")

    bsdr.writeSetting("TRIGGER_GEN", "")

    r1 = msdr.readStream(rxStreamM, [waveRxA1, waveRxB1], symSamp)
    print("reading stream #1 ({})".format(r1))
    r2 = bsdr.readStream(rxStreamB, [waveRxA2, waveRxB2], symSamp)
    print("reading stream #2 ({})".format(r2))
 
    # ADC_rst, stops the tdd time counters, makes sure next time runs in a clean slate
    tdd_conf = {"tdd_enabled" : False}
    for sdr in [bsdr, msdr]:
        sdr.writeSetting("RESET_DATA_LOGIC", "")
        sdr.writeSetting("TDD_CONFIG", json.dumps(tdd_conf))
        sdr.writeSetting("TDD_MODE", "false")

    msdr.deactivateStream(rxStreamM)
    bsdr.deactivateStream(rxStreamB)
    msdr.closeStream(rxStreamM)
    bsdr.closeStream(rxStreamB)
    msdr = None
    bsdr = None

    fig = plt.figure(figsize=(20, 8), dpi=120)
    fig.subplots_adjust(hspace=.5, top=.85)
    ax1 = fig.add_subplot(2, 1, 1)
    ax1.grid(True)
    ax1.set_title('Serials: (%s, %s)' % (serial1, serial2))
    ax1.set_ylabel('Signal (units)')
    ax1.set_xlabel('Sample index')
    ax1.plot(range(len(waveRxA1)), np.real(uint32tocfloat(waveRxA1)), label='ChA I Node 1')
    ax1.plot(range(len(waveRxB1)), np.real(uint32tocfloat(waveRxB1)), label='ChB I Node 1')
    ax1.set_ylim(-1, 1)
    ax1.set_xlim(0, symSamp)
    ax1.legend(fontsize=10)
    ax2 = fig.add_subplot(2, 1, 2)
    ax2.grid(True)
    ax2.set_ylabel('Signal (units)')
    ax2.set_xlabel('Sample index')
    ax2.plot(range(len(waveRxA2)), np.real(uint32tocfloat(waveRxA2)), label='ChA I Node 2')
    ax2.plot(range(len(waveRxB2)), np.real(uint32tocfloat(waveRxB2)), label='ChB I Node 2')
    ax2.set_ylim(-1, 1)
    ax2.set_xlim(0, symSamp)
    ax2.legend(fontsize=10)
    plt.show()
示例#7
0
    def __init__(
        self,
        serial_id=None,
        tx_freq=None,
        rx_freq=None,
        tx_gain=None,
        rx_gain=None,
        bw=None,
        sample_rate=None,
        n_samp=None,  # Total number of samples, including zero-pads
        both_channels=False,
        agc_en=False,
    ):

        if serial_id is not None:
            self.sdr = SoapySDR.Device(
                dict(driver="iris", timeout="1000000", serial=serial_id))
            self.serial_id = serial_id
        else:
            self.sdr = None

        self.sample_rate = sample_rate

        if n_samp is not None:
            self.n_samp = int(n_samp)

        self.agc_en = agc_en
        self.both_channels = both_channels
        self.max_frames = 1

        ### Setup channel rates, ports, gains, and filters ###
        info = self.sdr.getHardwareInfo()
        for chan in [0, 1]:

            #Tx:
            if sample_rate is not None:
                self.sdr.setSampleRate(SOAPY_SDR_TX, chan, sample_rate)
            if bw is not None:
                self.sdr.setBandwidth(SOAPY_SDR_TX, chan, bw)
            else:
                self.sdr.setBandwidth(SOAPY_SDR_TX, chan, 2.5 * sample_rate)
            if tx_gain is not None:
                self.sdr.setGain(SOAPY_SDR_TX, chan, min(tx_gain, 81.0))
            if tx_freq is not None:
                self.sdr.setFrequency(SOAPY_SDR_TX, chan, 'RF',
                                      tx_freq - .75 * sample_rate)
                self.sdr.setFrequency(SOAPY_SDR_TX, chan, 'BB',
                                      .75 * sample_rate)

            #print("Set TX frequency to %f" % self.sdr.getFrequency(SOAPY_SDR_TX, chan))
            #self.sdr.setAntenna(SOAPY_SDR_TX, chan, "TRX")
            #self.sdr.setGain(SOAPY_SDR_TX, chan, 'ATTN', -6)

            #Rx:
            if sample_rate is not None:
                self.sdr.setSampleRate(SOAPY_SDR_RX, chan, sample_rate)
            if bw is not None:
                self.sdr.setBandwidth(SOAPY_SDR_RX, chan, bw)
            else:
                self.sdr.setBandwidth(SOAPY_SDR_RX, chan, 2.5 * sample_rate)
            if rx_gain is not None:
                self.sdr.setGain(SOAPY_SDR_RX, chan, rx_gain)
            if rx_freq is not None:
                self.sdr.setFrequency(SOAPY_SDR_RX, chan, 'RF',
                                      rx_freq - .75 * sample_rate)
                self.sdr.setFrequency(SOAPY_SDR_RX, chan, 'BB',
                                      .75 * sample_rate)

            self.sdr.setAntenna(SOAPY_SDR_RX, chan, "TRX")

            if self.agc_en:
                self.sdr.setGain(SOAPY_SDR_RX, chan, 100)  # high gain value
            else:
                self.sdr.setGain(SOAPY_SDR_RX, chan, rx_gain)

            self.sdr.setDCOffsetMode(SOAPY_SDR_RX, chan, True)

        self.tx_stream = None  # Burst mode

        self.sdr.writeSetting("RESET_DATA_LOGIC", "")

        if not self.both_channels:
            self.sdr.writeSetting(SOAPY_SDR_RX, 1, 'ENABLE_CHANNEL', 'false')
            self.sdr.writeSetting(SOAPY_SDR_TX, 1, 'ENABLE_CHANNEL', 'false')
示例#8
0
if __name__ == '__main__':
    app = QApplication(sys.argv)

    parser = argparse.ArgumentParser()
    parser.add_argument("--args",
                        help="Device arguments (or none for selection dialog)")
    parser.add_argument("--file", help="Load saved config when specified")
    args = parser.parse_args()
    handle = args.args

    settings = QSettings(QSettings.IniFormat, QSettings.UserScope, "Skylark",
                         "IrisControlGUI")

    if not handle:
        dialog = DeviceSelectionDialog(settings=settings)
        dialog.exec()
        handle = dialog.deviceHandle()
    else:
        handle = SoapySDR.Device.enumerate(handle)[0]
    if not handle:
        print('No device selected!')
        sys.exit(-1)

    iris = SoapySDR.Device(handle)

    w = MainWindow(iris=iris, settings=settings, handle=handle)
    w.show()
    if args.file: w.loadFile(args.file)
    sys.exit(app.exec_())
示例#9
0
文件: siggen.py 项目: ADayn/sdradar
def siggen_app(
    args,
    rate,
    waves,
    ampl=0.7,
    freq=None,
    txBw=None,
    txChan=0,
    rxChan=0,
    txGain=None,
    txAnt=None,
    clockRate=None,
    waveFreq=None,
):
    if waveFreq is None: waveFreq = rate / 10

    sdr = SoapySDR.Device(args)
    #set clock rate first
    if clockRate is not None: sdr.setMasterClockRate(clockRate)

    #set sample rate
    sdr.setSampleRate(SOAPY_SDR_TX, txChan, rate)
    print("Actual Tx Rate %f Msps" %
          (sdr.getSampleRate(SOAPY_SDR_TX, txChan) / 1e6))

    #set bandwidth
    if txBw is not None: sdr.setBandwidth(SOAPY_SDR_TX, txChan, txBw)

    #set antenna
    print("Set the antenna")
    if txAnt is not None: sdr.setAntenna(SOAPY_SDR_TX, txChan, txAnt)

    #set overall gain
    print("Set the gain")
    if txGain is not None: sdr.setGain(SOAPY_SDR_TX, txChan, txGain)

    #tune frontends
    print("Tune the frontend")
    if freq is not None: sdr.setFrequency(SOAPY_SDR_TX, txChan, freq)

    print("Waveform:" + waves)

    #tx loop
    #create tx stream
    print("Create Tx stream")
    txStream = sdr.setupStream(SOAPY_SDR_TX, "CF32", [txChan])
    print("Activate Tx Stream")
    sdr.activateStream(txStream)
    phaseAcc = 0
    #phaseInc = 2*math.pi*waveFreq/rate
    phaseInc = math.pi / 4 * waveFreq / rate
    streamMTU = sdr.getStreamMTU(txStream)
    sampsCh0 = np.array([ampl] * streamMTU, np.complex64)
    print streamMTU
    timeLastPrint = time.time()
    totalSamps = 0
    #phaseAccNext = streamMTU*phaseInc
    #phaseAcc = phaseAccNext
    #testSpace = np.pi/4*np.linspace(0,streamMTU-1)
    while True:
        phaseAccNext = phaseAcc + streamMTU * phaseInc
        if waves == "sine":
            sampsCh0 = ampl * np.exp(1j * np.linspace(
                phaseAcc, phaseAccNext, streamMTU)).astype(np.complex64)

#sampsCh0 = ampl*np.exp(1j*testSpace).astype(np.complex64)
        elif waves == "pulse":
            n = len(sampsCh0)
            a = np.zeros(n)
            l = .25
            a[:int(l * n)] = 1
            a[-int(l * n):] = 1
            sampsCh0 = np.fft.ifft(a)
        elif waves == "zeros":
            sampsCh0 = np.zeros(len(sampsCh0))

        phaseAcc = phaseAccNext
        while phaseAcc > math.pi * 2:
            phaseAcc -= math.pi * 2
        #while phaseAcc > math.pi*2: phaseAcc -= math.pi
        #phaseAcc %= math.pi*2
        #	plt.plot(sampsCh0)
        #	plt.show()
        sr = sdr.writeStream(txStream, [sampsCh0], len(sampsCh0))
        if sr.ret != sampsCh0.size:
            raise Exception(
                "Expected writeStream() to consume all samples! %d" % sr.ret)
        totalSamps += sr.ret

        if time.time() > timeLastPrint + 5.0:
            print("Python siggen rate: %f Msps" %
                  (totalSamps / (time.time() - timeLastPrint) / 1e6))
            totalSamps = 0
            timeLastPrint = time.time()

    #cleanup streams
    print("Cleanup stream")
    sdr.deactivateStream(txStream)
    sdr.closeStream(txStream)
    print("Done!")
示例#10
0
# Read transmit buffer from stdin
pulseFile = open("skylark_transmit.txt", 'r')
for line in pulseFile:
	input_interleaved = np.fromstring(line, dtype=np.float32, count=-1, sep=' ')
	sigLength = int(len(input_interleaved) / 2)
	interleavedValues = input_interleaved.reshape((sigLength, 2))
	realSamples = interleavedValues[:, 0]
	imagSamples = interleavedValues[:, 1]
	inputbuffer = realSamples + 1j * imagSamples

num_samps = num_pulses*len(inputbuffer)
print(num_samps)

from pulseDopplerTxRx import MIMO_SDR

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

tx_sdrs = sdrs[0:len(sdrs)//2]
rx_sdrs = sdrs[len(sdrs)//2:]
trig_sdr = sdrs[0]


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

#override default settings
for sdr in sdrs:
	for chan in [0]:
		sdr.setSampleRate(SOAPY_SDR_RX, chan, rate)
示例#11
0
def siso_sounder(serial1, serial2, rate, freq, txgain, rxgain, numSamps, numSyms, txSymNum, threshold, tx_advance,
                 prefix_length, postfix_length, both_channels, wait_trigger, calibrate, record, use_trig, tx_power_loop, agc_en):
    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.setBandwidth(SOAPY_SDR_TX, ch, 2.5*rate)
            sdr.setBandwidth(SOAPY_SDR_RX, ch, 2.5*rate)
            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)
            sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
            sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)

            if "CBRS" in info["frontend"]:
                # Set gains to high val (initially)
                if agc_en: rxgain = 100
                sdr.setGain(SOAPY_SDR_TX, ch, txgain)
                sdr.setGain(SOAPY_SDR_RX, ch, rxgain)
            else:
                # No CBRS board gains, only changing LMS7 gains
                # AGC only supported for CBRS boards
                agc_en = False
                sdr.setGain(SOAPY_SDR_TX, ch, "PAD", txgain)    # [0:1:42]
                sdr.setGain(SOAPY_SDR_TX, ch, "IAMP", 0)        # [-12:1:3]
                sdr.setGain(SOAPY_SDR_RX, ch, "LNA", rxgain)    # [0:1:30]
                sdr.setGain(SOAPY_SDR_RX, ch, "TIA", 0)         # [0, 3, 9, 12]
                sdr.setGain(SOAPY_SDR_RX, ch, "PGA", -10)       # [-12:1:19]

            # Read initial gain settings
            readLNA = sdr.getGain(SOAPY_SDR_RX, 0, 'LNA')
            readTIA = sdr.getGain(SOAPY_SDR_RX, 0, 'TIA')
            readPGA = sdr.getGain(SOAPY_SDR_RX, 0, 'PGA')
            print("INITIAL GAIN - LNA: {}, \t TIA:{}, \t PGA:{}".format(readLNA, readTIA, readPGA))

        for ch in [0, 1]:
            if calibrate:
                sdr.writeSetting(SOAPY_SDR_RX, ch, "CALIBRATE", 'SKLK')

        sdr.writeSetting("RESET_DATA_LOGIC", "")

    # pdb.set_trace()
    if use_trig:
        bsdr.writeSetting("SYNC_DELAYS", "")

    # 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])

    tpc_conf = {"tpc_enabled" : False}
    msdr.writeSetting("TPC_CONFIG", json.dumps(tpc_conf))
    agc_conf = {"agc_enabled" : agc_en}
    msdr.writeSetting("AGC_CONFIG", json.dumps(agc_conf))

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

    ampl = 0.5
    beacon = preambles[0, :]
    coe = cfloat2uint32(np.conj(beacon), order='QI')     # FPGA correlator takes coefficients in QI order
    ltsSym, lts_f = generate_training_seq(preamble_type='lts', cp=32, upsample=1)
    # 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)*ampl
    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)

    if both_channels:
        beacon_weights = hadamard(2)
    else:
        beacon_weights = np.eye(2, dtype=np.uint32)
    beacon_weights = beacon_weights.astype(np.uint32)

    bsched = "BGR"+''.join("G"*(numSyms-txSymNum-4))+''.join("R"*txSymNum)+"G"
    msched = "GGP"+''.join("G"*(numSyms-txSymNum-4))+''.join("T"*txSymNum)+"G"
    if both_channels:
        bsched = "BGRR"+''.join("G"*(numSyms-txSymNum-5))+''.join("R"*txSymNum)+"G"
        msched = "GGPP"+''.join("G"*(numSyms-txSymNum-5))+''.join("T"*txSymNum)+"G"

    print("Iris 1 schedule %s " % bsched) 
    print("Iris 2 schedule %s " % msched)

    bconf = {"tdd_enabled": True,
             "frame_mode": "free_running",
             "symbol_size": symSamp,
             "frames": [bsched],
             "beacon_start" : prefix_length,
             "beacon_stop" : prefix_length+len(beacon),
             "max_frame" : 0}
    mconf = {"tdd_enabled": True,
             "frame_mode": "free_running" if use_trig else "triggered" if wait_trigger else "continuous_resync",
             "dual_pilot": both_channels,
             "symbol_size" : symSamp,
             "frames": [msched],
             "max_frame" : 0}

    bsdr.writeSetting("TDD_CONFIG", json.dumps(bconf))
    msdr.writeSetting("TDD_CONFIG", json.dumps(mconf))

    bsdr.writeRegisters("BEACON_RAM", 0, cfloat2uint32(beacon, order='QI').tolist())
    bsdr.writeRegisters("BEACON_RAM_WGT_A", 0, beacon_weights[0].tolist())
    bsdr.writeRegisters("BEACON_RAM_WGT_B", 0, beacon_weights[1].tolist())
    numAnt = 2 if both_channels else 1
    bsdr.writeSetting("BEACON_START", str(numAnt))

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

    if not use_trig:
        corr_conf = {"corr_enabled" : True, "corr_threshold" : threshold}
        msdr.writeSetting("CORR_CONFIG", json.dumps(corr_conf))
        msdr.writeRegisters("CORR_COE", 0, coe.tolist())

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

    if tx_power_loop:
        tcp_conf = {"tpc_enabled" : True,
                    "max_gain" : int(tx_gain),
                    "min_gain" : max(0, max_gain-12)}
        msdr.writeSetting("TPC_CONFIG", json.dumps(tpc_conf))

    msdr.writeRegisters("TX_RAM_A", 0, cfloat2uint32(wb_pilot1, order='QI').tolist())
    if both_channels:
        msdr.writeRegisters("TX_RAM_B", 0, cfloat2uint32(wb_pilot2, order='QI').tolist())

    if not use_trig:
        msdr.writeSetting("CORR_START", "A")

    signal.signal(signal.SIGINT, partial(signal_handler, rate, numSyms, use_trig))
    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()
    num_trig = 0
    while True:
        time.sleep(1)
        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
示例#12
0
    def __init__(self, cent_freq, meas_time, rx_bw, fs,
                 channel):  #rx_bw - bandwidth, fs - sampling rate
        self.channel = channel
        use_agc = True  # Use or don't use the AGC
        self.freq = cent_freq  # LO tuning frequency in Hz
        self.timeout_us = int(5e6)
        self.N = int(fs * meas_time)  # Number of complex samples per transfer
        self.rx_bits = 12  # The Lime's ADC is 12 bits
        RX1 = 0  # RX1 = 0, RX2 = 1
        RX2 = 1
        self.sdr = SoapySDR.Device(
            dict(driver="lime"))  # Create AIR-T instance

        if (len(self.channel) == 2):
            self.sdr.setSampleRate(SOAPY_SDR_RX, RX1, fs)  # Set sample rate
            self.sdr.setSampleRate(SOAPY_SDR_RX, RX2, fs)
            self.sdr.setGainMode(SOAPY_SDR_RX, RX1, True)  # Set the gain mode
            self.sdr.setGainMode(SOAPY_SDR_RX, RX2, True)
            self.sdr.setGain(SOAPY_SDR_RX, RX1, "TIA",
                             0)  # Set TransImpedance Amplifier gain
            self.sdr.setGain(SOAPY_SDR_RX, RX2, "TIA", 0)
            self.sdr.setGain(SOAPY_SDR_RX, RX1, "LNA",
                             0)  # Set Low-Noise Amplifier gain
            self.sdr.setGain(SOAPY_SDR_RX, RX2, "LNA", 0)
            self.sdr.setGain(SOAPY_SDR_RX, RX1, "PGA",
                             0)  # programmable-gain amplifier (PGA)
            self.sdr.setGain(SOAPY_SDR_RX, RX2, "PGA", 0)
            self.sdr.setGain(SOAPY_SDR_RX, RX1, 0)
            self.sdr.setGain(SOAPY_SDR_RX, RX2, 0)
            self.sdr.setDCOffsetMode(SOAPY_SDR_RX, 0, False)
            self.sdr.setDCOffsetMode(SOAPY_SDR_RX, 1, False)
            self.sdr.setFrequency(SOAPY_SDR_RX, RX1, self.freq)  # Tune the LO
            self.sdr.setFrequency(SOAPY_SDR_RX, RX2, self.freq)  # Tune the LO
            self.RX1_buff = np.empty(
                2 * self.N, np.int16)  # Create memory buffer for data stream
            self.RX2_buff = np.empty(
                2 * self.N, np.int16)  # Create memory buffer for data stream
            self.sdr.setBandwidth(SOAPY_SDR_RX, RX1, rx_bw)
            self.sdr.setBandwidth(SOAPY_SDR_RX, RX2, rx_bw)
            self.sdr.setAntenna(SOAPY_SDR_RX, RX1, "LNAL")
            self.sdr.setAntenna(SOAPY_SDR_RX, RX2, "LNAL")
            # Create data buffer and start streaming samples to it
            self.rx_stream = self.sdr.setupStream(
                SOAPY_SDR_RX, SOAPY_SDR_CS16, [RX1, RX2])  # Setup data stream

        elif (self.channel[0] == 1):
            self.sdr.setSampleRate(SOAPY_SDR_RX, RX1, fs)  # Set sample rate
            self.sdr.setGainMode(SOAPY_SDR_RX, RX1, True)  # Set the gain mode
            self.sdr.setGain(SOAPY_SDR_RX, RX1, "TIA", 0)
            self.sdr.setGain(SOAPY_SDR_RX, RX1, "LNA", 0)
            self.sdr.setGain(SOAPY_SDR_RX, RX1, "PGA",
                             0)  # programmable-gain amplifier (PGA)
            self.sdr.setFrequency(SOAPY_SDR_RX, RX1, self.freq)  # Tune the LO
            self.RX1_buff = np.empty(
                2 * self.N, np.int16)  # Create memory buffer for data stream
            self.sdr.setBandwidth(SOAPY_SDR_RX, RX1, rx_bw)
            self.sdr.setAntenna(SOAPY_SDR_RX, RX1, "LNAL")
            self.rx_stream = self.sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16,
                                                  [RX1])  # Setup data stream

        elif (self.channel[0] == 2):
            self.sdr.setSampleRate(SOAPY_SDR_RX, RX2, fs)  # Set sample rate
            self.sdr.setGainMode(SOAPY_SDR_RX, RX2, True)  # Set the gain mode
            self.sdr.setGain(SOAPY_SDR_RX, RX2, "TIA", 0)
            self.sdr.setGain(SOAPY_SDR_RX, RX2, "LNA", 0)
            self.sdr.setGain(SOAPY_SDR_RX, RX2, "PGA",
                             0)  # programmable-gain amplifier (PGA)
            self.sdr.setFrequency(SOAPY_SDR_RX, RX2, self.freq)  # Tune the LO
            self.RX2_buff = np.empty(
                2 * self.N, np.int16)  # Create memory buffer for data stream
            self.sdr.setBandwidth(SOAPY_SDR_RX, RX2, rx_bw)
            self.sdr.setAntenna(SOAPY_SDR_RX, RX2, "LNAL")
            self.rx_stream = self.sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16,
                                                  [RX2])  # Setup data stream

        else:
            print("Channel amount has to be 1 or 2")
示例#13
0
def signal_handler(rate, numSyms, signal, frame):
    global bsdr, msdr, running, txStreamM, rxStreamB
    msdr.writeRegister(
        "IRIS30", CORR_CONF, 0
    )  # stop mobile correlator first, to prevent from the tdd manager going
    msdr.writeRegister("IRIS30", TX_GAIN_CTRL, 0)
    # stop tx/rx threads
    running = False

    print("printing number of frames")
    print("NB 0x%X" % SoapySDR.timeNsToTicks(bsdr.getHardwareTime(""), rate))
    print("UE 0x%X" % SoapySDR.timeNsToTicks(msdr.getHardwareTime(""), rate))
    # print("UE SCNT: 0x%X" % msdr.readRegister("ARGCOR", CORR_SCNT))
    # ADC_rst, stops the tdd time counters
    for sdr in [bsdr, msdr]:
        sdr.writeRegister("IRIS30", RF_RST_REG, (1 << 29) | 0x1)
        sdr.writeRegister("IRIS30", RF_RST_REG, (1 << 29))
        sdr.writeRegister("IRIS30", RF_RST_REG, 0)
    for i in range(numSyms):
        msdr.writeRegister("RFCORE", SCH_ADDR_REG, i)  # subframe 0
        msdr.writeRegister("RFCORE", SCH_MODE_REG, 0)  # 01 replay
        bsdr.writeRegister("RFCORE", SCH_ADDR_REG, i)  # subframe 0
        bsdr.writeRegister("RFCORE", SCH_MODE_REG, 0)  # 01 replay
    bsdr.writeRegister("RFCORE", TDD_CONF_REG, 0)
    msdr.writeRegister("RFCORE", TDD_CONF_REG, 0)
    msdr.writeSetting("TDD_MODE", "false")
    bsdr.writeSetting("TDD_MODE", "false")

    for i, sdr in enumerate([bsdr, msdr]):
        # Reset
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_ENABLE_FLAG, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_RESET_FLAG, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_RESET_FLAG, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_IQ_THRESH, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_NUM_SAMPS_SAT, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_MAX_NUM_SAMPS_AGC, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_WAIT_COUNT_THRESH, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_RSSI_TARGET, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_SMALL_JUMP, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_BIG_JUMP, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_TEST_GAIN_SETTINGS, 0)

        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_THRESH, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_NUM_SAMPS, 5)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_ENABLE, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_NEW_FRAME, 0)

    bsdr = None
    msdr = None

    if exit_plot:
        fig = plt.figure(figsize=(20, 8), dpi=100)
        ax1 = fig.add_subplot(2, 1, 1)
        ax2 = fig.add_subplot(2, 1, 2)
        pilot = uint32tocfloat(
            read_from_file("data_out/rxpilot_sounder", leng=256, offset=0))
        rxdata = uint32tocfloat(
            read_from_file("data_out/rxdata_sounder", leng=256, offset=0))
        ax1.plot(np.real(pilot), label='pilot i')
        ax1.plot(np.imag(pilot), label='pilot q')
        ax2.plot(np.real(rxdata), label='rx data i')
        ax2.plot(np.imag(rxdata), label='rx data q')
        plt.show()
    sys.exit(0)
示例#14
0
def siso_sounder(serial1, serial2, rate, freq, txgain, rxgain, numSamps,
                 numSyms, txSymNum, threshold, tx_advance, prefix_length,
                 postfix_length, both_channels, wait_trigger, calibrate,
                 record, use_trig, auto_tx_gain, agc_en):
    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))

    for i, sdr in enumerate([bsdr, msdr]):
        # AGC SETUP (Init)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_ENABLE_FLAG, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_RESET_FLAG, 1)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_RESET_FLAG, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_IQ_THRESH,
                          10300)  # 10300 about -6dBm
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_NUM_SAMPS_SAT, 3)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_MAX_NUM_SAMPS_AGC, 20)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_WAIT_COUNT_THRESH,
                          160)  # gain settle takes about 20 samps (val=20)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_RSSI_TARGET,
                          14)  # ideally around 14
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_SMALL_JUMP, 5)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_BIG_JUMP, 15)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_TEST_GAIN_SETTINGS, 0)

        # PACKET DETECT SETUP
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_THRESH, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_NUM_SAMPS, 5)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_ENABLE, 0)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_NEW_FRAME, 0)

    # 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]

            # LMS gains
            if agc_en:
                # Set gains to max (initially)
                sdr.setGain(SOAPY_SDR_RX, ch, 'LNA', 30)  # [0,30]
                sdr.setGain(SOAPY_SDR_RX, ch, 'TIA', 12)  # [0,12]
                sdr.setGain(SOAPY_SDR_RX, ch, 'PGA', 19)  # [-12,19]
            else:
                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', -10)  # [-12,19]

            sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
            sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)

            # Read initial gain settings
            readLNA = sdr.getGain(SOAPY_SDR_RX, 0, 'LNA')
            readTIA = sdr.getGain(SOAPY_SDR_RX, 0, 'TIA')
            readPGA = sdr.getGain(SOAPY_SDR_RX, 0, 'PGA')
            print("INITIAL GAIN - LNA: {}, \t TIA:{}, \t PGA:{}".format(
                readLNA, readTIA, readPGA))

        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:
        #GM
        #msdr.writeRegister("ARGCOR", CORR_RST, 0x1)  # reset corr
        msdr.writeRegister("RFCORE", 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])

    for i, sdr in enumerate([bsdr, msdr]):
        # ENABLE PKT DETECT AND AGC
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_ENABLE, agc_en)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_AGC_ENABLE_FLAG, agc_en)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_NEW_FRAME, 1)
        sdr.writeRegister("IRIS30", FPGA_IRIS030_WR_PKT_DET_NEW_FRAME, 0)

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

    ampl = 1
    beacon = preambles[0, :] * ampl
    coe = cfloat2uint32(
        np.conj(beacon),
        order='QI')  # FPGA correlator takes coefficients in QI order
    ltsSym, lts_f = generate_training_seq(preamble_type='lts',
                                          cp=32,
                                          upsample=1)
    # 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) * ampl
    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 = "GRP" + ''.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)
            # [15] en, [14] mode, [13:12] step, [11:6] stop, [5:0] start
            msdr.writeRegister("IRIS30", TX_GAIN_CTRL, gain_reg)

        # 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))
        # make sure to set this after TDD mode is enabled "writeSetting("TDD_CONFIG", ..."
        msdr.setHardwareTime(
            SoapySDR.ticksToTimeNs((sf_start << 16) | sp_start, rate),
            "TRIGGER")

    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()
示例#15
0
def rxsamples_app(args, srl, freq, bw, rxgain, clockRate, out):
    global sdr, rxStream, timeScale, sampsRx, freqScale, rate, num_samps, fft_size, threadT, agc_fsm
    sdr = SoapySDR.Device(dict(serial=srl))
    info = sdr.getHardwareInfo()
    ch = rxChan

    # RSSI read setup
    setUpDigitalRssiMode(sdr)

    # Instantiate AGC FSM and enable
    agc_fsm = AutomaticGainControl(sdr, ch)
    # Enable AGC and trigger AGC state machine
    threadT = threading.Thread(target=agc_thread)  # , args=(sampsRx,))

    # set clock rate first
    if clockRate is None:
        sdr.setMasterClockRate(rate * 8)
    else:
        sdr.setMasterClockRate(clockRate)
    if bw is not None:
        sdr.setBandwidth(SOAPY_SDR_RX, ch, bw)
    # set params on both channels

    # sdr.setBandwidth(SOAPY_SDR_RX, ch, 10e6)
    sdr.setSampleRate(SOAPY_SDR_RX, ch, rate)
    sdr.setFrequency(SOAPY_SDR_RX, ch, "RF", freq)
    sdr.setFrequency(SOAPY_SDR_RX, ch, "BB", 0)  # don't use cordic
    sdr.setGain(SOAPY_SDR_RX, ch,
                rxgain)  # w/CBRS 3.6GHz [0:105], 2.5GHZ [0:108]
    sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
    sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)
    sdr.setHardwareTime(0)
    print("Set Frequency to %f" % sdr.getFrequency(SOAPY_SDR_RX, 0))

    # setup rxStreaming
    # request an rx burst as an example
    # repeat activateStream and readStream() for each burst needed
    sdr.writeSetting(SOAPY_SDR_RX, 0, 'CALIBRATE', 'SKLK')
    rxStream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32, [0], {})

    # cleanup rxStream
    # print("Cleanup rxStreams")
    # sdr.deactivateStream(rxStream)
    # sdr.closeStream(rxStream)
    step = 1
    print("numSamps %d " % num_samps)
    timeScale = np.arange(0, num_samps * step, num_samps)
    sampsRx = [
        np.zeros(num_samps, np.complex64),
        np.zeros(num_samps, np.complex64)
    ]

    # Start AGC thread
    threadT.start()

    #anim = animation.FuncAnimation(fig, animate, init_func=init,
    #                           frames=100, interval=100, blit=True)
    anim = MyFuncAnimation(fig,
                           animate,
                           init_func=init,
                           frames=100,
                           interval=100,
                           blit=True)

    plt.show()
    if out is not None:
        fig.savefig(out)
        plt.close(fig)
示例#16
0
def siggen_app(args, rate, ampl, ant, gain, freq, bbfreq, waveFreq, numSamps,
               serial1, serial2, sigType, lo_tone):
    """
    Generate signal and write stream to RAM for TX
    """
    global sdr

    # Device information
    sdr = SoapySDR.Device(dict(serial=serial))
    info = sdr.getHardwareInfo()
    amplFixed = int(ampl * (1 << 13))
    if ant == 'A':
        txChannel = [0]
    elif ant == 'B':
        txChannel = [1]
    elif ant == 'AB':
        txChannel = [0, 1]
    else:
        txChannel = []

    # Settings
    for c in txChannel:
        print("Writing settings for channel {}".format(c))
        sdr.setBandwidth(SOAPY_SDR_TX, c, 2.5 * rate)
        sdr.setSampleRate(SOAPY_SDR_TX, c, rate)
        sdr.setFrequency(SOAPY_SDR_TX, c, "RF", freq - .75 * rate)
        sdr.setFrequency(SOAPY_SDR_TX, c, "BB", .75 * rate)
        #sdr.setFrequency(SOAPY_SDR_TX, c, "RF", freq+bbfreq)
        #sdr.setFrequency(SOAPY_SDR_TX, c, "BB", bbfreq)
        sdr.setAntenna(SOAPY_SDR_TX, c, "TRX")

        if lo_tone:
            sdr.writeSetting(SOAPY_SDR_TX, c, 'TSP_TSG_CONST', str(amplFixed))
            sdr.writeSetting(SOAPY_SDR_TX, c, 'TX_ENB_OVERRIDE', 'true')

        if "CBRS" in info["frontend"]:
            sdr.setGain(SOAPY_SDR_TX, c, gain)
        else:
            # No CBRS board gains, only changing LMS7 gains
            sdr.setGain(SOAPY_SDR_TX, c, "PAD", gain)  # [0:1:42]
            sdr.setGain(SOAPY_SDR_TX, c, "IAMP", 0)  # [-12:1:3]

    # Generate TX signal
    txSignal = np.empty(numSamps).astype(np.complex64)
    wbz = txSignal
    if sigType == "LTE":
        # LTE signal
        for i in range(numSamps):
            txSignal[i] = np.complex(LTE5_re.lte5i[i] / 32768.0,
                                     LTE5_im.lte5q[i] / 32768.0)
    elif sigType == "LTS":
        # WiFi LTS Signal
        ltsSym, lts_f = generate_training_seq(preamble_type='lts',
                                              cp=32,
                                              upsample=1)
        txSignal = np.tile(ltsSym, numSamps // len(ltsSym)).astype(
            np.complex64) * ampl
    elif sigType == "STS":
        # WiFi STS Signal
        stsSym = generate_training_seq(preamble_type='sts', reps=10)
        txSignal = np.tile(stsSym, numSamps // len(stsSym)).astype(
            np.complex64) * 5
    elif sigType == "SINE":
        # Sine Waveform
        Ts = 1 / rate
        if waveFreq is None:
            waveFreq = rate / 20
        x = 20
        numSamps = int(x * rate / waveFreq)  # x period worth of samples
        s_freq = waveFreq
        s_time_vals = np.array(np.arange(0, numSamps)).transpose() * Ts
        txSignal = np.exp(s_time_vals * 1j * 2 * np.pi * s_freq).astype(
            np.complex64) * ampl
        if bbfreq > 0:
            txSignal = np.array([0] * numSamps,
                                np.complex64)  # use with cordic
            txSignal += .1
    else:
        raise Exception(
            "Signal type not supported. Valid entries: LTE/LTS/STS/SINE")

    # Float to fixed point
    pilot1_ui32 = cfloat2uint32(txSignal, order='QI')
    pilot2_ui32 = cfloat2uint32(wbz)

    if not lo_tone:
        replay_addr = 0
        if ant == 'A':
            sdr.writeRegisters("TX_RAM_A", replay_addr, pilot1_ui32.tolist())
        elif ant == 'B':
            sdr.writeRegisters("TX_RAM_B", replay_addr, pilot1_ui32.tolist())
        elif ant == 'AB':
            sdr.writeRegisters("TX_RAM_A", replay_addr, pilot1_ui32.tolist())
            sdr.writeRegisters("TX_RAM_B", replay_addr, pilot1_ui32.tolist())
        sdr.writeSetting("TX_REPLAY",
                         str(numSamps))  # this starts transmission

    # Show current gains
    if "CBRS" in info["frontend"]:
        IAMP = sdr.getGain(SOAPY_SDR_TX, 0, "IAMP")
        PAD = sdr.getGain(SOAPY_SDR_TX, 0, "PAD")
        PA1 = sdr.getGain(SOAPY_SDR_TX, 0, "PA1")
        PA2 = sdr.getGain(SOAPY_SDR_TX, 0, "PA2")
        PA3 = sdr.getGain(SOAPY_SDR_TX, 0, "PA3")
        ATTN = sdr.getGain(SOAPY_SDR_TX, 0, "ATTN")
        print("GAINS CHAN0: PA1 {}, PA3 {}, PA2 {}, ATTN {}, PAD {}, IAMP {}".
              format(PA1, PA3, PA2, ATTN, PAD, IAMP))
    else:
        IAMP = sdr.getGain(SOAPY_SDR_TX, 0, "IAMP")
        PAD = sdr.getGain(SOAPY_SDR_TX, 0, "PAD")
        print("GAINS CHAN0: PAD {}, IAMP {}".format(PAD, IAMP))

    # Plot signal
    debug = 0
    if debug:
        fig = plt.figure(figsize=(20, 8), dpi=100)
        ax1 = fig.add_subplot(2, 1, 1)
        ax1.plot(np.real(txSignal), label='pilot i')
        ax1.plot(np.imag(txSignal), label='pilot q')
        ax2 = fig.add_subplot(2, 1, 2)
        ax2.plot(np.abs(txSignal), label='abs(signal)')
        plt.show(block=False)

    # Stop/Close/Cleanup
    signal.signal(signal.SIGINT, signal_handler)
    pth = threading.Thread(target=print_thread, args=(sdr, info))
    pth.start()
    print("ctrl-c to stop ...")
    signal.pause()
示例#17
0
def txrx_app(serials, ref_node_idx, hub_serial, rate, freq, txgain, rxgain, numSamps, prefix_pad, postfix_pad, debug):
    """
    Function to configure Iris boards, generate pilot to be transmitted,
    write pilots to RAM, set up schedule (frame), transmit, and receive.
    """
    serials_all = serials.copy()
    ref_serial = serials[ref_node_idx]
    serials.remove(ref_serial)

    # Get SDR objects (msdr: master SDR, ssdr: slave SDRs)
    ssdr = [SoapySDR.Device(dict(driver="iris", serial=serial)) for serial in serials]
    msdr = SoapySDR.Device(dict(driver="iris", serial=ref_serial))

    if hub_serial != "":
        hub = SoapySDR.Device(dict(driver='faros', serial=hub_serial))

    # eror flag
    flag = 0

    # Some default sample rates
    for i, sdr in enumerate(ssdr + [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, '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)
            sdr.setGain(SOAPY_SDR_TX, ch, txgain)
            sdr.setGain(SOAPY_SDR_RX, ch, rxgain)
            sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
            sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)
        # ADC_rst, stops the tdd time counters, makes sure next time runs in a clean slate
        sdr.writeRegister("IRIS30", RF_RST_REG, (1 << 29) | 0x1)
        sdr.writeRegister("IRIS30", RF_RST_REG, (1 << 29))
        sdr.writeRegister("IRIS30", RF_RST_REG, 0)

    # Generate pilot to be TX
    # WiFi LTS Signal - Cyclic prefix of 32
    lts_sym, lts_freq = generate_training_seq(preamble_type='lts', cp=32, upsample=1)
    pilot = np.tile(lts_sym, numSamps // len(lts_sym)).astype(complex)
    pilot = pilot / max(pilot)  # Normalize amplitude
    pad1 = np.array([0] * prefix_pad, np.complex64)
    pad2 = np.array([0] * postfix_pad, np.complex64)
    pilot1 = np.concatenate([pad1, pilot, pad2])
    pilot2 = np.array([0] * len(pilot1), np.complex64)
    # Packet size
    symSamp = len(pilot) + prefix_pad + postfix_pad
    print("num pilot samps = %d" % len(pilot))
    print("num total samps = %d" % symSamp)

    # Synchronization delays
    if hub_serial != "":
        hub.writeSetting("SYNC_DELAYS", "")
    else:
        msdr.writeSetting("SYNC_DELAYS", "")

    # SW Delays
    [sdr.writeSetting("TX_SW_DELAY", str(30)) for sdr in (ssdr + [msdr])]

    # TDD Mode
    [sdr.writeSetting("TDD_MODE", "true") for sdr in (ssdr + [msdr])]

    # Write Pilot to RAM
    replay_addr = 0
    [sdr.writeRegisters("TX_RAM_A", replay_addr, cfloat2uint32(pilot1, order='IQ').tolist()) for sdr in (ssdr + [msdr])]
    [sdr.writeRegisters("TX_RAM_B", replay_addr, cfloat2uint32(pilot2, order='IQ').tolist()) for sdr in (ssdr + [msdr])]

    # Set Schedule
    ref_sched = "PG"
    other_sched = "RG"
    frame_len = len(ref_sched)                  # Number of subframes (e.g., 3 if PGP, 4 if PGPG)
    num_rx_pilots = other_sched.count('R')      # Two R's for "other" base station radios
    print("Ref node schedule %s " % ref_sched)
    print("Other nodes schedule %s " % other_sched)
    # Send one frame (set max_frame to 1)
    ref_conf = {"tdd_enabled": True, "trigger_out": False, "dual_pilot": False, "symbol_size": symSamp,
                "frames": [ref_sched], "max_frame": 1}
    other_conf = {"tdd_enabled": True, "trigger_out": False, "dual_pilot": False, "symbol_size": symSamp,
                  "frames": [other_sched], "max_frame": 1}

    # Create RX streams
    # CS16 makes sure the 4-bit lsb are samples are being sent
    m_rxStream = msdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0, 1], dict(WIRE=SOAPY_SDR_CS16))
    s_rxStream = [sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0, 1], dict(WIRE=SOAPY_SDR_CS16)) for sdr in ssdr]

    # Write TDD settings (schedule and parameters)
    msdr.writeSetting("TDD_CONFIG", json.dumps(ref_conf))
    for i, sdr in enumerate(ssdr):
        sdr.writeSetting("TDD_CONFIG", json.dumps(other_conf))

    # Begin pilot+calibration process: Send multiple pilots and pick the correlation index that occurs more frequently
    num_cal_tx = 100
    num_ver_tx = 100
    pass_thresh = 0.8*num_cal_tx
    # Aggregate over iterations (for calibration and for verification)
    waveRxA_agg = np.zeros((num_cal_tx, num_rx_pilots*(len(serials_all)-1), symSamp))
    waveRxB_agg = np.zeros((num_cal_tx, num_rx_pilots*(len(serials_all)-1), symSamp))
    waveRxA_ver = np.zeros((num_ver_tx, num_rx_pilots*(len(serials_all)-1), symSamp))
    waveRxB_ver = np.zeros((num_ver_tx, num_rx_pilots*(len(serials_all)-1), symSamp))

    for idx in range(num_cal_tx+num_ver_tx):
        # Initialize RX arrays
        # All nodes except ref. Assume num_rx_pilots entries for each node, regardless of whether we use them or not
        waveRxA = [np.array([0] * symSamp, np.uint32) for i in range(num_rx_pilots) for j in range(len(ssdr))]
        waveRxB = [np.array([0] * symSamp, np.uint32) for i in range(num_rx_pilots) for j in range(len(ssdr))]

        dummyA = np.array([0] * symSamp, np.uint32)
        dummyB = np.array([0] * symSamp, np.uint32)

        # Activate streams
        flags = 0
        r1 = msdr.activateStream(m_rxStream, flags, 0)
        if r1 < 0:
            print("Problem activating RefNode stream (Node0)")
        for i, sdr in enumerate(ssdr):
            r2 = sdr.activateStream(s_rxStream[i], flags, 0)
            if r2 < 0:
                print("Problem activating stream at RxNode #{}".format(i+1))

        # Drain buffers
        for i, sdr in enumerate([msdr] + ssdr):
            valid = 0
            while valid is not -1:
                if i == 0:
                    r0 = sdr.readStream(m_rxStream, [dummyA, dummyB], symSamp)
                else:
                    r0 = sdr.readStream(s_rxStream[i-1], [dummyA, dummyB], symSamp)
                valid = r0.ret
                if debug:
                    print("draining buffers: ({}). Board: {}".format(r0, i))

        # Generate trigger
        if hub_serial != "":
            hub.writeSetting("TRIGGER_GEN", "")
        else:
            msdr.writeSetting("TRIGGER_GEN", "")

        # Read Streams
        # B0 <-- B1 (NOT REALLY NEEDED WITH THE CURRENT SCHEDULE)
        # curr_rx_idx = 0
        # r1 = msdr.readStream(m_rxStream, [waveRxA[curr_rx_idx], waveRxB[curr_rx_idx]], symSamp)
        # print("reading stream ref antenna: ({})".format(r1))

        curr_rx_idx = 0
        for i, sdr in enumerate(ssdr):
            for j in range(num_rx_pilots):
                r1 = sdr.readStream(s_rxStream[i], [waveRxA[curr_rx_idx], waveRxB[curr_rx_idx]], symSamp)
                curr_rx_idx = curr_rx_idx + 1
                if debug:
                    print("reading stream non-reference nodes: ({})".format(r1))

        # Timestamps
        if debug:
            print("Timestamps:")
            for sdr in ([msdr] + ssdr):
                print(hex(SoapySDR.timeNsToTicks(sdr.getHardwareTime(""), rate)))

        waveRxA = uint32tocfloat(waveRxA)
        waveRxB = uint32tocfloat(waveRxB)

        if idx < num_cal_tx:
            waveRxA_agg[idx, :, :] = waveRxA
            waveRxB_agg[idx, :, :] = waveRxB

            if idx == num_cal_tx-1:
                # Find correlation indexes
                idx_mat_cal = find_corr_idx(waveRxA_agg, waveRxB_agg)

                # Find most common value at each board
                most_freq = np.zeros(idx_mat_cal.shape[1])
                num_occurr = np.zeros(idx_mat_cal.shape[1])
                for colIdx in range(idx_mat_cal.shape[1]):
                    occurr_cnt = Counter(idx_mat_cal[:, colIdx])
                    most_freq[colIdx] = (occurr_cnt.most_common(1))[0][0]
                    num_occurr[colIdx] = (occurr_cnt.most_common(1))[0][1]

                # Re-assign
                corr_idx_vec_cal = most_freq

                # Check if we didn't meet "PASSING" threshold (i.e., confidence on rx pilots)
                if any(num_occurr < pass_thresh):
                    cleanup([msdr] + ssdr, frame_len, m_rxStream, s_rxStream)
                    flag = -1
                    return flag, corr_idx_vec_cal, idx_mat_cal, num_occurr

                # Perform calibration
                cal_coeff = calibrate(most_freq, ssdr)

        elif idx >= num_cal_tx:
            waveRxA_ver[idx-num_cal_tx, :, :] = waveRxA
            waveRxB_ver[idx-num_cal_tx, :, :] = waveRxB

            if idx == num_cal_tx + num_ver_tx - 1:
                # Find correlation indexes
                idx_mat = find_corr_idx(waveRxA_ver, waveRxB_ver)
                idx_mat_ver = idx_mat

                # Find most common value at each board
                most_freq = np.zeros(idx_mat_ver.shape[1])
                num_occurr = np.zeros(idx_mat_ver.shape[1])
                for colIdx in range(idx_mat_ver.shape[1]):
                    occurr_cnt = Counter(idx_mat_ver[:, colIdx])
                    most_freq[colIdx] = (occurr_cnt.most_common(1))[0][0]
                    num_occurr[colIdx] = (occurr_cnt.most_common(1))[0][1]

                # Re-assign
                corr_idx_vec_ver = most_freq

    cleanup([msdr] + ssdr, frame_len, m_rxStream, s_rxStream)
    return flag, corr_idx_vec_cal, corr_idx_vec_ver, cal_coeff
示例#18
0
def init(hub, bnodes, cnodes, ref_ant, ampl, rate, freq, txgain, rxgain, cp, plotter, numSamps, prefix_length, postfix_length, tx_advance, mod_order, threshold, use_trig):
    if hub != "": hub_dev = SoapySDR.Device(dict(driver="remote", serial = hub)) # device that triggers bnodes and ref_node
    bsdrs = [SoapySDR.Device(dict(driver="iris", serial = serial)) for serial in bnodes] # base station sdrs
    csdrs = [SoapySDR.Device(dict(driver="iris", serial = serial)) for serial in cnodes] # client sdrs
    # assume trig_sdr is part of the master nodes
    trig_dev = None
    if hub != "":
        trig_dev = hub_dev
    else:
        trig_dev = bsdrs[0]

    #set params on both channels
    for sdr in bsdrs+csdrs:
        info = sdr.getHardwareInfo()
        print("%s settings on device" % (info["frontend"]))
        for ch in [0, 1]:
            sdr.setBandwidth(SOAPY_SDR_TX, ch, 2.5*rate)
            sdr.setBandwidth(SOAPY_SDR_RX, ch, 2.5*rate)
            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)
            sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
            sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)

            sdr.setGain(SOAPY_SDR_TX, ch, 'PAD', txgain)
            sdr.setGain(SOAPY_SDR_RX, ch, 'LNA', rxgain)

            if "CBRS" in info["frontend"]:
                sdr.setGain(SOAPY_SDR_TX, ch, 'ATTN', -6)
                sdr.setGain(SOAPY_SDR_RX, ch, 'LNA2', 14)
                if freq < 3e9:
                    sdr.setGain(SOAPY_SDR_RX, ch, 'ATTN', -12)
                else:
                    sdr.setGain(SOAPY_SDR_RX, ch, 'ATTN', 0)

            # Read initial gain settings
            readLNA = sdr.getGain(SOAPY_SDR_RX, 0, 'LNA')
            readTIA = sdr.getGain(SOAPY_SDR_RX, 0, 'TIA')
            readPGA = sdr.getGain(SOAPY_SDR_RX, 0, 'PGA')
            print("INITIAL GAIN - LNA: {}, \t TIA:{}, \t PGA:{}".format(readLNA, readTIA, readPGA))

        sdr.writeSetting("RESET_DATA_LOGIC", "")
        sdr.writeSetting(SOAPY_SDR_RX, 1, 'ENABLE_CHANNEL', 'false')
        sdr.writeSetting(SOAPY_SDR_TX, 1, 'ENABLE_CHANNEL', 'false')

    trig_dev.writeSetting("SYNC_DELAYS", "")

    sym_samps = numSamps + prefix_length + postfix_length
    print("numSamps = %d"%sym_samps)
    M = len(bsdrs)
    K = len(csdrs)
    N = 64
    D = 1 # number of downlink symbols

    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
    wbz = np.array([0]*(sym_samps), np.complex64)
    # OFDM object
    ofdm_obj = ofdmTxRx()


    #### Generate Pilot
    cp_len = 32 if cp else 0
    ofdm_len = 2*N + cp_len
    lts_rep = numSamps//(ofdm_len)
    zeros = np.array([0]*(numSamps-ofdm_len))
    lts_sym, lts_f = generate_training_seq(preamble_type='lts', cp=cp_len, upsample=1)
    pilot = np.concatenate((lts_sym, zeros))
    wb_pilot = ampl * pilot
    wb_pilot1 = np.concatenate([pad1, wb_pilot, pad2])
    lts_t = lts_sym[-64:]
    lts_t_cp = np.concatenate((lts_t[len(lts_t) - 16:], lts_t))

    #### Generate Beacon and hadamard weights
    upsample = 1
    preambles_bs = generate_training_seq(preamble_type='gold_ifft', seq_length=128, cp=0, upsample=upsample)
    preambles = preambles_bs[:,::upsample]
    beacon = preambles[0,:]
    coe = cfloat2uint32(np.conj(beacon), order='QI')
    bcnz = np.array([0]*(sym_samps-prefix_length-len(beacon)), np.complex64)  
    beacon1 = np.concatenate([pad1,beacon*.5,bcnz])
    beacon2 = wbz  

    possible_dim = []
    possible_dim.append(2**(np.ceil(np.log2(M))))
    h_dim = min(possible_dim)
    hadamard_matrix = hadamard(h_dim)
    beacon_weights = hadamard_matrix[0:M, 0:M]
    beacon_weights = beacon_weights.astype(np.uint32)

    #### Generate Data
    data_cp_len = 16 if cp else 0
    data_ofdm_len = N + data_cp_len
    n_ofdm_syms = (numSamps // data_ofdm_len)
    sig_t, data_const, tx_data, sc_idx_all, pilots_matrix = \
        ofdm_obj.generate_data(n_ofdm_syms - 2, mod_order, cp_length=data_cp_len)
    data_sc = sc_idx_all[0]
    pilot_sc = sc_idx_all[1]
    tx_dl_data = np.zeros((N, n_ofdm_syms, K)).astype(complex)
    for k in range(K):
        tx_dl_data[data_sc, 2:, k] = data_const
        tx_dl_data[pilot_sc, 2:, k] = pilots_matrix
        tx_dl_data[:, 0, k] = lts_f
        tx_dl_data[:, 1, k] = lts_f
    tx_dl_ifft = np.zeros((M, n_ofdm_syms, N)).astype(complex)
    print("n_ofdm_syms %d, data_ofdm_len %d"%(n_ofdm_syms, data_ofdm_len))

    # received data params 
    lts_thresh = 0.8
    n_data_ofdm_syms = n_ofdm_syms - 2
    payload_len = n_data_ofdm_syms * data_ofdm_len
    lts_len = 2 * data_ofdm_len
    fft_offset = 0

    #### Configure tdd mode
    guardSize = (len(csdrs)) % 2 + 1
    frameLen = len(csdrs) + len(bsdrs)*2 + 4 + guardSize

    # BS frame config
    for i,sdr in enumerate(bsdrs):
        beacon_sch = "BG"
        if i == ref_ant:
            ref_ul_pilot_sch = "PG"
            ref_dl_pilot_sch = ''.join("RG" * (M - 1))
            ul_pilot_sch = ''.join("R" * K)
        else:
            ref_ul_pilot_sch = "RG"
            new_i = i - (i > ref_ant)
            ref_dl_pilot_sch = ''.join("GG" * new_i) + "PG" + ''.join("GG" * (M-(new_i+2)))
            ul_pilot_sch = ''.join("R" * K)

        frame_sch1 = beacon_sch + ref_ul_pilot_sch + ref_dl_pilot_sch + ul_pilot_sch + 'G' 

        dl_data_sch = "PG" + ''.join("G" * (2 * M + K - (2 * D)))
        frame_sch2 = beacon_sch + dl_data_sch + 'G'

        print("BS node %d frame schedule (%s, %s)" % (i, frame_sch1, frame_sch2))
        bconf = {"tdd_enabled": True, 
                "frame_mode": "triggered", 
                "symbol_size" : sym_samps, 
                "frames": [frame_sch1, frame_sch2],
                "beacon_start" : prefix_length,
                "beacon_stop" : prefix_length+len(beacon),
                "max_frame" : 2}
        sdr.writeSetting("TDD_CONFIG", json.dumps(bconf))
        sdr.writeSetting("TDD_MODE", "true")

    # Client frame config
    for i, sdr in enumerate(csdrs):
        det_sch = "GG"
        ref_pilot_sch = ''.join("GG" * M)
        ul_pilot_sch = ''.join("G" * i) + "P" + ''.join("G" * (K-(i+1)))
        frame_sch1 = det_sch + ref_pilot_sch + ul_pilot_sch + 'G'

        dl_data_sch = "RG" * D + ''.join("G" * (2 * M + K - (2 * D)))
        frame_sch2 = det_sch + dl_data_sch + 'G'

        print("Client %d frame schedule  (%s, %s)"%(i, frame_sch1, frame_sch2))
        cconf = {"tdd_enabled": True,
                 "frame_mode": "triggered",
                 "symbol_size" : sym_samps,
                 "frames": [frame_sch1, frame_sch2],
                 "max_frame" : 0}
        sdr.writeSetting("TDD_CONFIG", json.dumps(cconf))
        sdr.writeSetting("TDD_MODE", "true")

    for sdr in bsdrs+csdrs:
        sdr.writeSetting("TX_SW_DELAY", str(30))

    if not use_trig:
        for sdr in csdrs:
            # enable the correlator, with zeros as inputs
            corr_conf = {"corr_enabled" : True,
                        "corr_threshold" : 1}
            sdr.writeSetting("CORR_CONFIG", json.dumps(corr_conf))
            sdr.writeRegisters("CORR_COE", 0, coe.tolist())

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

    for i,sdr in enumerate(bsdrs):
        sdr.setHardwareTime(0, "TRIGGER")

    replay_addr = 0
    pilot_uint = cfloat2uint32(wb_pilot1, order='QI').tolist()
    beacon_uint = cfloat2uint32(beacon1, order='QI').tolist()
    zero_uint = cfloat2uint32(wbz, order='QI').tolist() 
    for i, sdr in enumerate(bsdrs):
        sdr.writeRegisters("BEACON_RAM", 0, beacon_uint)
        sdr.writeRegisters("BEACON_RAM_WGT_A", 0, beacon_weights[i].tolist())
        sdr.writeSetting("BEACON_START", str(M))

    for sdr in csdrs:
        sdr.writeRegisters("TX_RAM_A", replay_addr, pilot_uint)
        sdr.writeRegisters("TX_RAM_B", replay_addr, zero_uint)

    # Create and activate streams
    rx_stream_ul = [sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32, [0, 1]) for sdr in bsdrs]
    rx_stream_dl = [sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32, [0, 1]) for sdr in csdrs]
    flags = 0
    for i, sdr in enumerate(bsdrs):
        sdr.activateStream(rx_stream_ul[i], flags, 0)
    for i, sdr in enumerate(csdrs):
        sdr.activateStream(rx_stream_dl[i], flags, 0)

    #############
    #initialize array and matrixes to hold rx and processed data
    #############
    calib_rx_dl = [np.array([1]*sym_samps).astype(np.complex64) for m in range(M)]
    calib_rx_ul = [np.array([1]*sym_samps).astype(np.complex64) for m in range(M)]
    data_rx_dl = [[np.array([0]*sym_samps).astype(np.complex64) for k in range(K)] for m in range(D)]
    pilot_rx_ul = [[np.array([0]*sym_samps).astype(np.complex64) for m in range(M)] for k in range(K)]
    dummy_rx = np.array([0]*sym_samps).astype(np.complex64)

    ul_cal_offset = np.array([0]*M, np.int32)
    dl_cal_offset = np.array([0]*M, np.int32)

    ul_offset = [np.array([0]*K, np.int32) for m in range(M)] 
    dl_offset = [np.array([0]*K, np.int32) for m in range(M)] 

    ul_csi_mat = np.empty([K, M, N], dtype=np.complex64)
    rx_f_cal_dl = np.empty([M, N], dtype=np.complex64)
    rx_f_cal_ul = np.empty([M, N], dtype=np.complex64)

    w_zf_dl = np.empty([M, K, N], dtype=np.complex64)
    w_conj_dl = np.empty([M, K, N], dtype=np.complex64)

    calib = np.empty((M, N)).astype(np.complex64)

    rxSymbols_mat = np.empty([len(data_sc), D * n_data_ofdm_syms, K], dtype=np.complex64)

    cont_plotter = plotter

    if cont_plotter:
        fig1, axes1 = plt.subplots(nrows=M, ncols=2, figsize=(9, 12))
        axes1[0, 0].set_title('Pilot Uplink (Re)')
        axes1[0, 1].set_title('Pilot Uplink (Im)')
        for m in range(M):
            axes1[m, 0].set_xlim(0, sym_samps)
            axes1[m, 0].set_ylim(-1, 1)
            if m == ref_ant:
                axes1[m, 0].set_ylabel('Ant %d (ref)'%m)
            else:
                axes1[m, 0].set_ylabel('Ant %d'%m)
            axes1[m, 0].legend(fontsize=10)
            axes1[m, 1].set_xlim(0, sym_samps)
            axes1[m, 1].set_ylim(-1, 1)
            axes1[m, 1].legend(fontsize=10)
        lines11 = [[axes1[m, 0].plot(range(sym_samps), np.real(pilot_rx_ul[k][m]), label="User %d (real)"%k)[0] for k in range(K)] for m in range(M)]
        lines12 = [[axes1[m, 1].plot(range(sym_samps), np.imag(pilot_rx_ul[k][m]), label="User %d (imag)"%k)[0] for k in range(K)] for m in range(M)]
        fig1.show()

        fig2, axes2 = plt.subplots(nrows=M, ncols=2, figsize=(9, 12))
        axes2[0, 0].set_title('Calibration Downlink')
        axes2[0, 1].set_title('Calibration Uplink')
        for m in range(M):
            axes2[m, 0].set_xlim(0, sym_samps)
            axes2[m, 0].set_ylim(-1, 1)
            if m == ref_ant:
                axes2[m, 0].set_ylabel('Ant %d (ref)'%m)
            else:
                axes2[m, 0].set_ylabel('Ant %d'%m)
            axes2[m, 0].legend(fontsize=10)
            axes2[m, 1].set_xlim(0, sym_samps)
            axes2[m, 1].set_ylim(-1, 1)
            axes2[m, 1].legend(fontsize=10)
        lines20 = [axes2[m, 0].plot(range(sym_samps), calib_rx_dl[m][:sym_samps])[0] for m in range(M)]
        lines21 = [axes2[m, 1].plot(range(sym_samps), calib_rx_ul[m][:sym_samps])[0] for m in range(M)]
        lines24 = [axes2[m, 0].plot(range(sym_samps), calib_rx_dl[m][:sym_samps])[0] for m in range(M)]
        lines25 = [axes2[m, 1].plot(range(sym_samps), calib_rx_ul[m][:sym_samps])[0] for m in range(M)]
        fig2.show()

        fig3, axes3 = plt.subplots(nrows=K, ncols=1, figsize=(6, 6))
        for k in range(K):
            if K == 1:
                ax3 = axes3
            else:
                ax3 = axes3[k]
            ax3.grid(True)
            ax3.set_title('TX/RX Constellation')
            ax3.set_xlabel('')
            ax3.set_ylabel('')
            ax3.set_ylim(-5.5, 5.5)
            ax3.set_xlim(-5.8, 5.8)
            ax3.legend(fontsize=10)

        if K == 1:
            line31, = axes3.plot([], [], 'ro', label='TXSym')
            line32, = axes3.plot([], [], 'bx', label='RXSym')
        else:
            line31 = [axes3[k].plot([], [], 'ro', label='TXSym')[0] for k in range(K)]
            line32 = [axes3[k].plot([], [], 'bx', label='RXSym')[0] for k in range(K)]

        fig3.show()

        fig4, axes4 = plt.subplots(nrows=K, ncols=1, figsize=(6, 6))
        for k in range(K):
            if K == 1:
                ax4 = axes4
            else:
                ax4 = axes4[k]
            ax4.grid(True)
            ax4.set_title('Received Downlink')
            ax4.set_xlabel('')
            ax4.set_ylabel('')
            ax4.set_ylim(-1, 1)
            ax4.set_xlim(0, sym_samps)
            ax4.legend(fontsize=10)

        if K == 1:
            line41, = axes4.plot(range(sym_samps), data_rx_dl[0][0], label='RX Downlink')
            line42, = axes4.plot(range(sym_samps), data_rx_dl[0][0])
        else:
            line41 = [axes4[k].plot(range(sym_samps), data_rx_dl[0][k], label='RX Downlink')[0] for k in range(K)]
            line42 = [axes4[k].plot(range(sym_samps), data_rx_dl[0][k])[0] for k in range(K)]

        fig4.show()


    cur_frame = 0
    signal.signal(signal.SIGINT, signal_handler)
    tstart = datetime.datetime.now()

    while(RUNNING):

        ## disarm correlator in the clients
        if not use_trig:    
            for i, sdr in enumerate(csdrs):
                sdr.writeSetting("CORR_CONFIG", json.dumps({"corr_enabled": False}))

        bad_recip_read = False
        bad_frame = False
        ## arm correlator in the clients, inputs from adc
        if not use_trig:    
            for i, sdr in enumerate(csdrs):
                sdr.writeSetting("CORR_START", "A")

        for i, sdr in enumerate(bsdrs):
            sdr.writeRegisters("TX_RAM_A", 0, pilot_uint)
            sdr.writeRegisters("TX_RAM_B", 0, zero_uint)

        trig_dev.writeSetting("TRIGGER_GEN", "")

        ## collect reciprocity pilots from antenna m
        for m in range(M):
            if bad_recip_read: break
            if m != ref_ant:
                sr = bsdrs[m].readStream(rx_stream_ul[m], [calib_rx_ul[m], dummy_rx], sym_samps)
                if sr.ret < sym_samps:
                    print("Calib: m %d ret %d"%(m,sr.ret))
                    bad_recip_read = True

        for m in range(M):
            if bad_recip_read: break
            if m != ref_ant:
                sr = bsdrs[ref_ant].readStream(rx_stream_ul[ref_ant], [calib_rx_dl[m], dummy_rx], sym_samps)
                if sr.ret < sym_samps:
                    print("Calib: m %d ret %d"%(m,sr.ret))
                    bad_recip_read = True

        if bad_recip_read: 
            print("BAD RECIPROCAL PILOT READ... CONTINUE! ")
            continue

        ## collect uplink pilots
        bad_pilot_read = False
        for k in range(K):
            if bad_pilot_read: break
            for m in range(M):
                sr = bsdrs[m].readStream(rx_stream_ul[m], [pilot_rx_ul[k][m], dummy_rx], sym_samps)
                if sr.ret < sym_samps:
                    print("PilotUP: k: %d, m %d ret %d"%(k,m,sr.ret))
                    bad_pilot_read = True

        if bad_pilot_read: 
            print("BAD PILOT READ... CONTINUE! ")
            continue


        ## process downlink signal 
        # processing the received calibration samples
        print("frame %d"%(cur_frame))
        for m in range(M):
            if ref_ant == m: 
                calib[m,:] = np.array([1]*N, np.complex64) #continue
                rx_f_cal_dl[m,:] = np.array([0]*N, np.complex64) 
                rx_f_cal_ul[m,:] = np.array([0]*N, np.complex64) 
                continue 
            calib_rx_dl[m] -= np.mean(calib_rx_dl[m])
            calib_rx_ul[m] -= np.mean(calib_rx_ul[m])
             
            best_peak_dl, _, _ = find_lts(calib_rx_dl[m], thresh=LTS_THRESH)
            best_peak_ul, _, _ = find_lts(calib_rx_ul[m], thresh=LTS_THRESH)
            dl_cal_offset[m] = 0 if not best_peak_dl else best_peak_dl - len(lts_sym) + cp_len 
            ul_cal_offset[m] = 0 if not best_peak_ul else best_peak_ul - len(lts_sym) + cp_len 
            if (dl_cal_offset[m] < 150 or ul_cal_offset[m] < 150):
                bad_frame = True
            lts_dn_1 = calib_rx_dl[m][dl_cal_offset[m]:dl_cal_offset[m]+N]
            lts_dn_2 = calib_rx_dl[m][dl_cal_offset[m]+N:dl_cal_offset[m]+2*N]
            lts_up_1 = calib_rx_ul[m][ul_cal_offset[m]:ul_cal_offset[m]+N]
            lts_up_2 = calib_rx_ul[m][ul_cal_offset[m]+N:ul_cal_offset[m]+2*N]

            rx_f_cal_dl1 = np.fft.fftshift(np.fft.fft(lts_dn_1, N, 0), 0)
            rx_f_cal_dl2 = np.fft.fftshift(np.fft.fft(lts_dn_2, N, 0), 0)
            rx_f_cal_ul1 = np.fft.fftshift(np.fft.fft(lts_up_1, N, 0), 0)
            rx_f_cal_ul2 = np.fft.fftshift(np.fft.fft(lts_up_2, N, 0), 0)
            rx_f_cal_dl[m, :] = (rx_f_cal_dl1 + rx_f_cal_dl2)/2
            rx_f_cal_ul[m, :] = (rx_f_cal_ul1 + rx_f_cal_ul2)/2
            calib[m,:] = np.divide(rx_f_cal_dl[m,:], rx_f_cal_ul[m,:])
 
        # processing uplink pilot received samples
        for k in range(K):
            for m in range(M):
                pilot_rx_ul[k][m] -= np.mean(pilot_rx_ul[k][m]) 
                best_peak, _, _ = find_lts(pilot_rx_ul[k][m], thresh=LTS_THRESH)
                ul_offset[m][k] = 0 if not best_peak else (best_peak - len(lts_sym) + cp_len) 
                if ul_offset[m][k] < 150:
                    bad_frame = True 
                lts_ul_1 = pilot_rx_ul[k][m][ul_offset[m][k]:ul_offset[m][k]+N]
                lts_ul_2 = pilot_rx_ul[k][m][ul_offset[m][k]+N:ul_offset[m][k]+2*N]
                rx_f_ul1 = np.fft.fftshift(np.fft.fft(lts_ul_1, N, 0), 0)
                rx_f_ul2 = np.fft.fftshift(np.fft.fft(lts_ul_2, N, 0), 0)
                ul_csi_mat[k,m,:] = (rx_f_cal_ul1 + rx_f_cal_ul2) * lts_f / 2 

        # processing beamforming vectors and downlink transmit data
        for l in range(n_ofdm_syms):
            for n in range(N):
                dl_csi = np.matmul(ul_csi_mat[:, :, n], np.diag(calib[:, n]))
                w_zf_dl[:, :, n] = np.linalg.pinv(dl_csi)
                tx_dl_ifft[:, l, n] = np.matmul(w_zf_dl[:, :, n], tx_dl_data[n, l, :])

        tx_sym = np.fft.ifft(tx_dl_ifft, axis=2)
        tx_sym = np.concatenate((tx_sym[:,:,-data_cp_len:], tx_sym), axis=2)

        # send downlink signal
        for i, sdr in enumerate(bsdrs):
            tx_sig = np.reshape(tx_sym[i, :, :], (1, n_ofdm_syms * data_ofdm_len)) 
            tx_sig = np.concatenate([pad1, tx_sig[0, :], pad2])
            sdr.writeRegisters("TX_RAM_A", 0, cfloat2uint32(tx_sig, order='QI').tolist())
            sdr.writeRegisters("TX_RAM_B", 0, zero_uint)

        trig_dev.writeSetting("TRIGGER_GEN", "")

        # collect downlink data from antenna k
        bad_dl_read = False
        for d in range(D):
            if bad_dl_read: break
            for k in range(K):
                sr = csdrs[k].readStream(rx_stream_dl[k], [data_rx_dl[d][k], dummy_rx], sym_samps)
                if sr.ret < sym_samps:
                    print("DL DATA: symbol %d, k %d, ret %d"%(d, k, sr.ret))
                    bad_dl_read = True

        if bad_dl_read: 
            print("BAD DL READ... CONTINUE! ")
            continue

        # DC removal
        # Find LTS peaks (in case LTSs were sent)
        bad_dl_data = False
        for k in range(K):
            if bad_dl_data: break
            for d in range(D):
                data_rx_dl[d][k] -= np.mean(data_rx_dl[d][k])
                best_peak_dl, b, peaks0 = find_lts(data_rx_dl[d][k], thresh=lts_thresh, flip=True, lts_seq=lts_t_cp)
                if use_trig:
                    dl_offset[k] = 163 + 160 #0 if not best_peak_dl else best_peak_dl
                else:
                    dl_offset[k] = 0 if not best_peak_dl else best_peak_dl
                if dl_offset[k] < lts_len:
                    bad_dl_data = True
                    print("NO VALID DOWNLINK... CONTINUE! ")
                    break
                payload_start = dl_offset[k]
                payload_end = payload_start + payload_len  # Payload_len == (n_ofdm_syms * (num_sc + data_cp_len))
                lts_start = payload_start - lts_len  # where LTS-CP start
                lts = data_rx_dl[d][k][lts_start: payload_start]
                if len(lts) < lts_len:
                    print("BAD DOWNLINK PILOT... CONTINUE!  ")
                    bad_dl_data = True
                    break
                lts_1 = lts[16 + -fft_offset + np.array(range(0, 64))]
                lts_2 = lts[96 + -fft_offset + np.array(range(0, 64))]

                # Average 2 LTS symbols to compute channel estimate
                tmp = np.fft.ifftshift(lts_f)
                chan_est = np.fft.ifftshift(lts_f) * (np.fft.fft(lts_1) + np.fft.fft(lts_2))/2
                if len(data_rx_dl[d][k]) >= payload_end:
                    # Retrieve payload symbols
                    payload_samples = data_rx_dl[d][k][payload_start: payload_end]
                else:
                    bad_dl_data = True
                    print("TOO LATE (payload_end %d)... CONTINUE! "%payload_end)
                    break
                payload_samples_mat_cp = np.reshape(payload_samples, (data_ofdm_len, n_data_ofdm_syms), order="F")

                # Remove cyclic prefix
                payload_samples_mat = payload_samples_mat_cp[data_cp_len - fft_offset + np.array(range(0, N)), :]

                # FFT
                rxSig_freq = np.fft.fft(payload_samples_mat, n=N, axis=0)

                # Equalizer
                chan_est_tmp = chan_est.reshape(len(chan_est), 1, order="F")
                rxSig_freq_eq = rxSig_freq / np.matlib.repmat(chan_est_tmp, 1, n_data_ofdm_syms)
                phase_error = ofdm_obj.phase_correction(rxSig_freq_eq, pilot_sc, pilots_matrix)

                phase_corr_tmp = np.matlib.repmat(phase_error, N, 1)
                phase_corr = np.exp(-1j * phase_corr_tmp)
                rxSig_freq_eq_phase = rxSig_freq_eq * phase_corr
                rxSymbols_mat[:, d * n_data_ofdm_syms : (d + 1) * n_data_ofdm_syms, k] = rxSig_freq_eq_phase[data_sc, :]

        if bad_dl_data:
            continue

        evm_mat = np.power(np.abs(rxSymbols_mat - np.tile(tx_dl_data[data_sc, 2:, :], (1, D, 1))), 2)
        evm_per_user = np.mean(np.reshape(evm_mat, (len(data_sc) * n_data_ofdm_syms * D, K)), axis=0)
        evm_per_user_db = 10 * np.log10(evm_per_user)
        print('EVM (dB) per user')
        print([ "{:2.2f}".format(x) for x in evm_per_user_db ])
        print('')

        cur_frame += 1
        if cur_frame >= TOT_FRAMES: break
        if cont_plotter:

            for m in range(M):
                if m == ref_ant:
                    lines20[m].set_ydata(np.real(wb_pilot1))
                    lines21[m].set_ydata(np.real(wb_pilot1))
                    continue
                lines20[m].set_ydata(np.real(calib_rx_dl[m]))
                lines21[m].set_ydata(np.real(calib_rx_ul[m]))
                lines24[m].set_data(dl_cal_offset[m], np.linspace(-1.0, 1.0, num=100))
                lines25[m].set_data(ul_cal_offset[m], np.linspace(-1.0, 1.0, num=100))

            for m in range(M):
                for k in range(K):
                    lines11[m][k].set_ydata(np.real(pilot_rx_ul[k][m]))
                    lines12[m][k].set_ydata(np.imag(pilot_rx_ul[k][m]))

            if K == 1:
                txSyms_all = tx_dl_data[data_sc, 2:, 0].flatten()
                rxSyms_all = rxSymbols_mat[:, :, 0].flatten()
                line31.set_data(np.real(txSyms_all), np.imag(txSyms_all))
                line32.set_data(np.real(rxSyms_all), np.imag(rxSyms_all))
                line41.set_data(range(sym_samps), np.real(data_rx_dl[0][0]))
                line42.set_data(dl_offset[0], np.linspace(-1.0, 1.0, num=100))
            else:
                for k in range(K):
                    txSyms_all = tx_dl_data[data_sc, 2:, k].flatten()
                    rxSyms_all = rxSymbols_mat[:, :, k].flatten()
                    line31[k].set_data(np.real(txSyms_all), np.imag(txSyms_all))
                    line32[k].set_data(np.real(rxSyms_all), np.imag(rxSyms_all))
                    line41[k].set_data(range(sym_samps), np.real(data_rx_dl[0][k]))
                    line42[k].set_data(dl_offset[k], np.linspace(-1.0, 1.0, num=100))

            fig1.canvas.draw()
            fig1.show()

            fig2.canvas.draw()
            fig2.show()

            fig3.canvas.draw()
            fig3.show()

            fig4.canvas.draw()
            fig4.show()

    tend = datetime.datetime.now()
    c = tend - tstart
    print("Elapsed %d (secs)"%c.total_seconds())

    # clear up fpga states 
    tdd_conf = {"tdd_enabled" : False}
    corr_conf = {"corr_enabled" : False}
    for sdr in csdrs:
        if not use_trig:
            sdr.writeSetting("CORR_CONFIG", json.dumps(corr_conf))
    for sdr in bsdrs+csdrs:
        sdr.writeSetting("TDD_CONFIG", json.dumps(tdd_conf))
        sdr.writeSetting("TDD_MODE", "false")
        sdr.writeSetting("RESET_DATA_LOGIC", "")

    # close streams and exit
    for i, sdr in enumerate(bsdrs):
        sdr.closeStream(rx_stream_ul[i])
    for i, sdr in enumerate(csdrs):
        sdr.closeStream(rx_stream_dl[i])
示例#19
0
def beamsweeper(hub, serials, rate, freq, txgain, rxgain, numSamps, numSyms,
                prefix_length, postfix_length, calibrate, both_channels):
    global sdrs, hub_dev
    if hub != "": hub_dev = SoapySDR.Device(dict(serial=hub))
    print("setting %s as eNB" % (serials))
    sdrs = [
        SoapySDR.Device(dict(serial=serial1)) for serial1 in serials.split(',')
    ]

    #some default sample rates
    for sdr in sdrs:
        info = sdr.getHardwareInfo()
        print("%s settings on device" % (info["frontend"]))
        for ch in [0, 1]:
            sdr.setBandwidth(SOAPY_SDR_RX, ch, 2.5 * rate)
            sdr.setBandwidth(SOAPY_SDR_TX, ch, 2.5 * rate)
            sdr.setSampleRate(SOAPY_SDR_TX, ch, rate)
            sdr.setSampleRate(SOAPY_SDR_RX, ch, rate)
            sdr.setFrequency(SOAPY_SDR_TX, ch, "BB", 0.75 * rate)
            sdr.setFrequency(SOAPY_SDR_RX, ch, "BB", 0.75 * rate)
            sdr.setFrequency(SOAPY_SDR_TX, ch, "RF", freq - 0.75 * rate)
            sdr.setFrequency(SOAPY_SDR_RX, ch, "RF", freq - 0.75 * rate)
            sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
            sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)

            if calibrate:
                sdr.writeSetting(SOAPY_SDR_RX, ch, "CALIBRATE", 'SKLK')
                sdr.writeSetting(SOAPY_SDR_TX, ch, "CALIBRATE", '')

            if "CBRS" in info["frontend"]:
                # Set gains to high val (initially)
                sdr.setGain(
                    SOAPY_SDR_TX, ch, txgain
                )  # txgain: at 2.5GHz [16:1:93], at 3.6GHz [15:1:102]
                sdr.setGain(
                    SOAPY_SDR_RX, ch,
                    rxgain)  # rxgain: at 2.5GHz [3:1:105], at 3.6GHz [3:1:102]
            else:
                # No CBRS board gains, only changing LMS7 gains
                sdr.setGain(SOAPY_SDR_TX, ch, "PAD", txgain)  # [0:1:42]
                sdr.setGain(SOAPY_SDR_TX, ch, "IAMP", 0)  # [-12:1:3]
                sdr.setGain(SOAPY_SDR_RX, ch, "LNA", rxgain)  # [0:1:30]
                sdr.setGain(SOAPY_SDR_RX, ch, "TIA", 0)  # [0, 3, 9, 12]
                sdr.setGain(SOAPY_SDR_RX, ch, "PGA", -10)  # [-12:1:19]

        if not both_channels:
            sdr.writeSetting(SOAPY_SDR_RX, 1, 'ENABLE_CHANNEL', 'false')
            sdr.writeSetting(SOAPY_SDR_TX, 1, 'ENABLE_CHANNEL', 'false')
        sdr.writeSetting("RESET_DATA_LOGIC", "")

    if hub == "":
        sdrs[0].writeSetting("SYNC_DELAYS", "")
    else:
        hub_dev.writeSetting("SYNC_DELAYS", "")

    #packet size
    symSamp = numSamps + prefix_length + postfix_length
    print("numSamps = %d" % symSamp)

    # preambles to be sent from BS and correlated against in UE
    upsample = 1
    preambles_bs = generate_training_seq(preamble_type='gold_ifft',
                                         seq_length=128,
                                         cp=0,
                                         upsample=1)
    preambles = preambles_bs[:, ::
                             upsample]  #the correlators can run at lower rates, so we only need the downsampled signal.
    beacon = preambles[0, :] * .25

    possible_dim = []
    nRadios = len(sdrs)
    nChannels = 2 if both_channels else 1
    numAnt = nRadios * nChannels
    possible_dim.append(2**(np.ceil(np.log2(numAnt))))
    h_dim = min(possible_dim)
    hadamard_matrix = hadamard(
        h_dim
    )  #hadamard matrix : http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html
    beacon_weights = hadamard_matrix[0:numAnt, 0:numAnt]
    print(beacon_weights)
    beacon_weights = beacon_weights.astype(np.uint32)
    bzeros = np.array([0] * numAnt, np.uint32)

    bsched = "BG"  #+''.join("G"*(numSyms-1))
    print("Schedule %s " % bsched)
    bconf = {
        "tdd_enabled": True,
        "frame_mode": "free_running",
        "symbol_size": symSamp,
        "frames": [bsched],
        "beacon_start": prefix_length,
        "beacon_stop": prefix_length + len(beacon)
    }
    for i, sdr in enumerate(sdrs):
        sdr.writeSetting("TDD_CONFIG", json.dumps(bconf))
        sdr.writeSetting("TX_SW_DELAY", str(30))
        sdr.writeSetting("TDD_MODE", "true")

    for i, sdr in enumerate(sdrs):
        sdr.writeRegisters("BEACON_RAM", 0,
                           cfloat2uint32(beacon, order='QI').tolist())
        sdr.writeRegisters("BEACON_RAM_WGT_A", 0,
                           beacon_weights[i * nChannels].tolist())
        sdr.writeRegisters(
            "BEACON_RAM_WGT_B", 0,
            beacon_weights[2 * i +
                           1].tolist() if both_channels else bzeros.tolist())
        sdr.writeSetting("BEACON_START", str(numAnt))

    signal.signal(signal.SIGINT, partial(signal_handler, rate, numSyms))
    if hub == "":
        sdrs[0].writeSetting("TRIGGER_GEN", "")
    else:
        hub_dev.writeSetting("TRIGGER_GEN", "")
    signal.pause()
示例#20
0
# Settings
############################################################################################
# Data transfer settings
rx_chan = 0  # RX1 = 0, RX2 = 1
N = 16384  # Number of complex samples per transfer
fs = 31.25e6  # Radio sample Rate
freq = 2.4e9  # LO tuning frequency in Hz
use_agc = True  # Use or don't use the AGC
timeout_us = int(5e6)
rx_bits = 16  # The AIR-T's ADC is 16 bits

############################################################################################
# Receive Signal
############################################################################################
#  Initialize the AIR-T receiver using SoapyAIRT
sdr = SoapySDR.Device(dict(driver="SoapyAIRT"))  # Create AIR-T instance
sdr.setSampleRate(SOAPY_SDR_RX, 0, fs)  # Set sample rate
sdr.setGainMode(SOAPY_SDR_RX, 0, use_agc)  # Set the gain mode
sdr.setFrequency(SOAPY_SDR_RX, 0, freq)  # Tune the LO

# Create data buffer and start streaming samples to it
rx_buff = np.empty(2 * N, np.int16)  # Create memory buffer for data stream
rx_stream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16,
                            [rx_chan])  # Setup data stream
sdr.activateStream(rx_stream)  # this turns the radio on

# Read the samples from the data buffer
sr = sdr.readStream(rx_stream, [rx_buff], N, timeoutUs=timeout_us)
rc = sr.ret  # number of samples read or the error code
assert rc == N, 'Error {}: {}'.format(rc.ret, errToStr(rc.ret))
示例#21
0
#prin dir(dev.getDeviceDescription()['frequencies']['rx'][0])
#print dev.getDeviceDescription()['frequencies']['rx'][0]
#print dev.getDeviceDescription()['frequencies']['rx'].index
#for a in dir(dev.sdr):
#   if 'list' in a or 'get' in a:
#       print a
#print dev.bbdev.values()
#print dev.bbdev.items()

#exit(0)
#print(reSult)

#create device instance
#args can be user defined or from the enumeration result
#args = dict(driver="hackrf")
sdr = SoapySDR.Device({'driver': 'hackrf'})

#query device info
#print(sdr.listAntennas(SOAPY_SDR_RX, 0))
#print(sdr.listGains(SOAPY_SDR_RX, 0))
#freqs = sdr.getFrequencyRange(SOAPY_SDR_RX, 0)
#for freqRange in freqs: print("F"+str(freqRange))

print("Setting up rtx")
#apply settings
sdr.setSampleRate(SOAPY_SDR_RX, 0, 1e6)
sdr.setFrequency(SOAPY_SDR_RX, 0, 99.4e7)
#sdr.setSampleRate(SOAPY_SDR_TX, 0, 1e6)
#sdr.setFrequency(SOAPY_SDR_TX, 0, 99.4e7)

print("Setting up streams")
示例#22
0
def LimeSuiteCalibrate(
    args,
    freqStart,
    freqStop,
    freqStep,
    dumpDir,
    validate,
):
    if freqStart is None: raise Exception("No start frequency specified")
    if freqStop is None: freqStop = freqStart

    #open device
    print('#' * 40)
    print('## Open device with "%s"' % (args))
    print('#' * 40)
    limeSDR = SoapySDR.Device(args)
    print(str(limeSDR))
    info = limeSDR.getHardwareInfo()
    for k in info.keys():
        print("%s:%s" % (k, info[k]))

    #initialize parameters
    print('#' * 40)
    print('## Initialize "%s"' % (str(limeSDR)))
    print('#' * 40)
    limeSDR.setMasterClockRate(CLOCK_RATE)
    for channel in [0, 1]:
        limeSDR.setSampleRate(SOAPY_SDR_TX, channel, SAMPLE_RATE)
        limeSDR.setSampleRate(SOAPY_SDR_RX, channel, SAMPLE_RATE)
        limeSDR.setAntenna(SOAPY_SDR_RX, channel, RX_ANTENNA)
        limeSDR.setAntenna(SOAPY_SDR_TX, channel, TX_ANTENNA)
        limeSDR.setGain(SOAPY_SDR_TX, channel, "PAD", PAD_GAIN)
        limeSDR.setGain(SOAPY_SDR_TX, channel, "LB_PAD", LB_PAD_GAIN)
        limeSDR.setGain(SOAPY_SDR_RX, channel, "PGA", PGA_GAIN)
        limeSDR.setGain(SOAPY_SDR_RX, channel, "TIA", TIA_GAIN)
        limeSDR.setGain(SOAPY_SDR_RX, channel, "LNA", LNA_GAIN)
        limeSDR.setGain(SOAPY_SDR_RX, channel, "LB_LNA", LB_LNA_GAIN)
        limeSDR.setDCOffsetMode(SOAPY_SDR_RX, channel, False)

    #open the rx stream
    rxStream = limeSDR.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32, [0, 1])

    #sweep for each frequency
    for freq in np.arange(freqStart, freqStop + freqStep, freqStep):
        t0 = time.time()
        try:
            CalibrateAtFreq(limeSDR=limeSDR,
                            rxStream=rxStream,
                            freq=freq,
                            dumpDir=dumpDir,
                            validate=validate)
        except Exception as ex:
            print("Failed at %g MHz, skipping...\n    %s" %
                  (freq / 1e6, str(ex)))
        if not validate: print("Cal took %s seconds" % (time.time() - t0))

    #close the rx stream
    limeSDR.closeStream(rxStream)

    #close the device
    limeSDR = None
    print("Done")
示例#23
0
    def setup(self):

        # BS
        for i, sdr in enumerate(self.bsdrs):
            sched_main = "PG" + ''.join(
                "G" * i * self.sdr_ant) + "T" * self.sdr_ant + ''.join(
                    "G" * (self.num_ants -
                           (i + 1) * self.sdr_ant)) + "G" + ''.join(
                               "R" * (len(self.csdrs))) + "G"
            #print("BS node %d"%i)
            #print("sched_main   %s"%(sched_main))
            bconf = {
                "tdd_enabled": True,
                "frame_mode": "free_running",
                "symbol_size": self.symSamp,
                "frames": [sched_main],
                "max_frame": 1
            }
            sdr.writeSetting("TDD_CONFIG", json.dumps(bconf))
            sdr.writeSetting("TDD_MODE", "true")

        # Client
        for i, sdr in enumerate(self.csdrs):
            sched_main = "GG" + ''.join("R" * self.num_bsdrs) + "G" + ''.join(
                "G" * i) + "P" + ''.join("G" * (self.num_csdrs -
                                                (i + 1))) + "G"
            #print("Client node %d"%i)
            #print("sched_main   %s"%(sched_main))
            cconf = {
                "tdd_enabled": True,
                "frame_mode": "triggered",
                "symbol_size": self.symSamp,
                "frames": [sched_main],
                "max_frame": 0
            }
            sdr.writeSetting("TDD_CONFIG", json.dumps(cconf))
            sdr.writeSetting("TDD_MODE", "true")

        for sdr in self.bsdrs + self.csdrs:
            sdr.writeSetting("TX_SW_DELAY", str(30))

        z = np.empty(self.symSamp).astype(np.complex64)
        if self.ota_trig:
            coe = cfloat2uint32(
                np.conj(self.coeffs),
                order='IQ')  # FPGA correlator takes coefficients in QI order
            for sdr in self.csdrs:
                sdr.writeRegister("IRIS30", CORR_CONF, int(
                    "00004001",
                    16))  # enable the correlator, with zeros as inputs
                for i in range(128):
                    sdr.writeRegister("ARGCOE", i * 4, 0)
                time.sleep(0.1)
                sdr.writeRegister("IRIS30", CORR_RST, 0x1)  # reset corr
                sdr.writeRegister("IRIS30", CORR_RST, 0x0)  # unrst corr
                sdr.writeRegister("IRIS30", CORR_THRESHOLD, 1)
                for i in range(128):
                    sdr.writeRegister("ARGCOE", i * 4, int(coe[i]))

                sf_start = self.rf_roundtrip // self.symSamp
                sp_start = self.rf_roundtrip % self.symSamp
                #print("UE starting symbol and sample count (%d, %d)" % (sf_start, sp_start))
                # make sure to set this after TDD mode is enabled "writeSetting("TDD_CONFIG", ..."
                sdr.setHardwareTime(
                    SoapySDR.ticksToTimeNs((sf_start << 16) | sp_start,
                                           self.rate), "TRIGGER")
        else:
            for sdr in self.csdrs:
                sdr.setHardwareTime(0, "TRIGGER")

        replay_addr = 0
        for i, sdr in enumerate(self.bsdrs):
            sdr.writeRegisters("TX_RAM_A", replay_addr,
                               cfloat2uint32(self.beacon, order='IQ').tolist())
            if self.beacon_weights is not None:
                sdr.writeRegisters(
                    "TX_RAM_B", replay_addr,
                    cfloat2uint32(self.beacon, order='IQ').tolist())
                sdr.writeRegisters(
                    "TX_RAM_WGT_A", replay_addr,
                    self.beacon_weights[self.sdr_ant * i].tolist())
                if self.sdr_ant == 2:
                    sdr.writeRegisters(
                        "TX_RAM_WGT_B", replay_addr,
                        self.beacon_weights[self.sdr_ant * i + 1].tolist())

                sdr.writeRegister("RFCORE", 156, int(self.num_ants))
                sdr.writeRegister("RFCORE", 160, 1)  # enable beamsweeping
            else:
                break  # if beamsweep is not active, only send pilot from the first antenna
            sdr.setHardwareTime(0, "TRIGGER")

        for sdr in self.csdrs:
            sdr.writeRegisters("TX_RAM_A", replay_addr,
                               cfloat2uint32(self.pilot, order='IQ').tolist())
            sdr.writeRegisters("TX_RAM_B", replay_addr,
                               cfloat2uint32(z, order='IQ').tolist())

        ret = 0
        dummy = np.empty(self.symSamp).astype(np.complex64)
        dummy2 = np.empty(self.symSamp).astype(np.complex64)
        for r, sdr in enumerate(self.bsdrs):
            #if r != m:
            while ret >= 0:
                sr = sdr.readStream(self.rxBsStream[r], [dummy, dummy2],
                                    self.symSamp,
                                    timeoutUs=0)
                ret = sr.ret
            ret = 0

        for r, sdr in enumerate(self.csdrs):
            #if r != m:
            while ret >= 0:
                sr = sdr.readStream(self.rxBsStream[r], [dummy, dummy2],
                                    self.symSamp,
                                    timeoutUs=0)
                ret = sr.ret
            ret = 0

        # arm correlator in the clients
        if self.ota_trig:
            for i, sdr in enumerate(self.csdrs):
                sdr.writeRegister("IRIS30", CORR_CONF, int(
                    "00004011",
                    16))  # enable the correlator, with inputs from adc
示例#24
0
    siso_bs.burn_data(beacon1_r, beacon1_i)
    #siso_bs.burn_beacon()
    siso_ue.burn_data(wb_pilot1_r, wb_pilot1_i)

    siso_bs.activate_stream_rx()

    siso_ue.set_corr()
    siso_bs.set_trigger(True)

    wave_rx_a_bs_mn = siso_bs.recv_stream_tdd()

    freq = 2.5e9
    print("printing number of frames")
    print("BS 0x%X" %
          SoapySDR.timeNsToTicks(siso_bs.sdr.getHardwareTime(""), freq))
    print("UE 0x%X" %
          SoapySDR.timeNsToTicks(siso_ue.sdr.getHardwareTime(""), freq))

    siso_ue.close()
    siso_bs.close()

    #Test:
    plt.close('all')
    fig = plt.figure(figsize=(20, 8), dpi=100)
    ax1 = fig.add_subplot(2, 1, 1)
    ax2 = fig.add_subplot(2, 1, 2)
    ax1.plot(np.real(wb_pilot), label='pilot i')
    ax1.plot(np.imag(wb_pilot), label='pilot q')
    ax2.plot(np.real(wave_rx_a_bs_mn), label='rx data i')
    ax2.plot(np.imag(wave_rx_a_bs_mn), label='rx data q')
示例#25
0
pwr_circ_buff = np.zeros(num_samps_circ_buff)

########################################
#               LOGGER                 #
########################################
# SOAPY_SDR_FATAL    = 1, //!< A fatal error. The application will most likely terminate. This is the highest priority.
# SOAPY_SDR_CRITICAL = 2, //!< A critical error. The application might not be able to continue running successfully.
# SOAPY_SDR_ERROR    = 3, //!< Error.An operation didn't complete successfully, but application as a whole not affected.
# SOAPY_SDR_WARNING  = 4, //!< A warning. An operation completed with an unexpected result.
# SOAPY_SDR_NOTICE   = 5, //!< A notice, which is an information with just a higher priority.
# SOAPY_SDR_INFO     = 6, //!< An informational message, usually denoting the successful completion of an operation.
# SOAPY_SDR_DEBUG    = 7, //!< A debugging message.
# SOAPY_SDR_TRACE    = 8, //!< A tracing message. This is the lowest priority.
# SOAPY_SDR_SSI      = 9, //!< Streaming status indicators such as "U" (underflow) and "O" (overflow).
logLevel = 3  # 4:WARNING, 6:WARNING+INFO, 7:WARNING+INFO+DEBUG...
SoapySDR.SoapySDR_setLogLevel(logLevel)
logging.basicConfig(
    filename='./data_out/debug_SISO_RX.log',
    level=logging.DEBUG,
    format='[%(levelname)s] (%(threadName)-10s) %(asctime)s %(message)s',
)

#########################################
#             Create Plots              #
#########################################
matplotlib.rcParams.update({'font.size': 10})
fig = plt.figure(figsize=(20, 8), dpi=120)
fig.subplots_adjust(hspace=.5, top=.85)

ax1 = fig.add_subplot(6, 1, 1)
ax1.grid(True)
示例#26
0
    def config_sdr_tdd(self, tdd_sched=None, is_bs=True):
        '''Configure the TDD schedule and functionality when unchained. Set up the correlator.'''
        global tx_advance, corr_threshold, beacon
        len_beacon_zpad = len(beacon) + self.n_zpad_samp
        coe = cfloat2uint32(np.conj(beacon), order='QI')
        if tdd_sched is not None:
            self.tdd_sched = tdd_sched
        else:
            self.tdd_sched = "G"
        max_frames = self.max_frames
        if bool(is_bs):
            conf_str = {
                "tdd_enabled": True,
                "frame_mode": "free_running",
                "symbol_size": self.n_samp,
                "max_frame": max_frames,
                "frames": [self.tdd_sched]
            }
            self.sdr.writeSetting("TDD_CONFIG", json.dumps(conf_str))
            print("TDD schedule of BS node {}: {}".format(
                self.serial_id, tdd_sched))
        else:
            conf_str = {
                "tdd_enabled": True,
                "frame_mode": "triggered",
                "symbol_size": self.n_samp,
                "frames": [self.tdd_sched]
            }
            self.sdr.writeSetting("TDD_CONFIG", json.dumps(conf_str))

            #Correlator stuff:
            self.sdr.writeRegister("IRIS30", CORR_CONF, int(
                "00004001", 16))  # enable the correlator, with zeros as inputs
            for i in range(128):
                self.sdr.writeRegister("ARGCOE", i * 4, 0)
            time.sleep(0.1)
            self.sdr.writeRegister("IRIS30", CORR_RST, 0x1)  # reset corr
            self.sdr.writeRegister("IRIS30", CORR_RST, 0x0)  # unrst corr
            self.sdr.writeRegister("IRIS30", CORR_THRESHOLD,
                                   int(corr_threshold))
            if coe is not None:
                for i in range(128):
                    self.sdr.writeRegister("ARGCOE", i * 4, int(coe[i]))
            else:
                print("No coe was passed into config_sdr_tdd() \n")

            # DEV: ueTrigTime = 153 (prefix_length=0), CBRS: ueTrigTime = 235 (prefix_length=82), tx_advance=prefix_length, corr delay is 17 cycles
            ueTrigTime = 17 + tx_advance + len_beacon_zpad
            sf_start = int(ueTrigTime // (self.n_samp))
            sp_start = int(ueTrigTime % (self.n_samp))
            print(
                "config_sdr_tdd: UE starting symbol and sample count (%d, %d)"
                % (sf_start, sp_start))
            self.sdr.setHardwareTime(
                SoapySDR.ticksToTimeNs((sf_start << 16) | sp_start,
                                       self.sample_rate), "TRIGGER"
            )  # make sure to set this after TDD mode is enabled "writeSetting("TDD_CONFIG", ..."
            print("TDD schedule of UE node {}: {}".format(
                self.serial_id, tdd_sched))

        self.sdr.writeSetting("TX_SW_DELAY", str(30))
        self.sdr.writeSetting("TDD_MODE", "true")
示例#27
0
def rxsamples_app(srl, freq, gain, num_samps, recorder, agc_en, wait_trigger):
    """
    Initialize IRIS parameters and animation kick-off
    """

    # Global declarations
    global sdr, rxStream, freqScale, Rate

    # Instantiate device
    sdr = SoapySDR.Device(dict(serial=srl))
    info = sdr.getHardwareInfo()
    print(info)

    # Set gains to very high value if AGC enabled (AGC only supports CBRS RF frontend at the moment).
    if agc_en and "CBRS" in info["frontend"]:
        gain = 100
        rssi_target_idx = 20
        agc_init(sdr, rssi_target_idx)
    else:
        # Make sure AGC is disabled if any of the previous checks fails
        agc_en = 0

    # Set params on both channels (both RF chains)
    for ch in [0, 1]:
        sdr.setBandwidth(SOAPY_SDR_RX, ch, 2.5 * Rate)
        sdr.setBandwidth(SOAPY_SDR_TX, ch, 2.5 * Rate)
        sdr.setFrequency(SOAPY_SDR_RX, ch, freq)
        sdr.setSampleRate(SOAPY_SDR_RX, ch, Rate)
        sdr.setFrequency(SOAPY_SDR_TX, ch, freq)
        sdr.setSampleRate(SOAPY_SDR_TX, ch, Rate)
        sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
        sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)

        if "CBRS" in info["frontend"]:
            sdr.setGain(SOAPY_SDR_RX, ch, gain)
        else:
            # No CBRS board gains, only changing LMS7 gains
            sdr.setGain(SOAPY_SDR_RX, ch, "LNA", gain)  # [0:1:30]
            sdr.setGain(SOAPY_SDR_RX, ch, "TIA", 0)  # [0, 3, 9, 12]
            sdr.setGain(SOAPY_SDR_RX, ch, "PGA", -10)  # [-12:1:19]

    print("Number of Samples %d " % num_samps)
    print("Frequency has been set to %f" % sdr.getFrequency(SOAPY_SDR_RX, 0))
    sdr.writeRegister("RFCORE", 120, 0)

    # Setup RX stream
    rxStream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32, [0, 1])

    # RSSI read setup
    setUpDigitalRssiMode(sdr)

    # There's a bug in the FuncAnimation function, we replaced it with a fixed version
    # anim = animation.FuncAnimation(fig, animate, init_func=init, fargs=(num_samps, recorder, agc_en, wait_trigger),
    # frames=100, interval=100, blit=True)
    anim = MyFuncAnimation(fig,
                           animate,
                           init_func=init,
                           fargs=(num_samps, recorder, agc_en, wait_trigger,
                                  info),
                           frames=100,
                           interval=100,
                           blit=True)
    plt.show()
示例#28
0
def siggen_app(args,
               rate,
               ampl=0.7,
               freq=None,
               txBw=None,
               txChan=0,
               rxChan=0,
               txGain=None,
               txAnt=None,
               clockRate=None,
               waveFreq=None):
    if waveFreq is None: waveFreq = rate / 10

    sdr = SoapySDR.Device(args)
    #set clock rate first
    if clockRate is not None: sdr.setMasterClockRate(clockRate)

    #set sample rate
    sdr.setSampleRate(SOAPY_SDR_TX, txChan, rate)
    print("Actual Tx Rate %f Msps" %
          (sdr.getSampleRate(SOAPY_SDR_TX, txChan) / 1e6))

    #set bandwidth
    if txBw is not None: sdr.setBandwidth(SOAPY_SDR_TX, txChan, txBw)

    #set antenna
    print("Set the antenna")
    if txAnt is not None: sdr.setAntenna(SOAPY_SDR_TX, txChan, txAnt)

    #set overall gain
    print("Set the gain")
    if txGain is not None: sdr.setGain(SOAPY_SDR_TX, txChan, txGain)

    #tune frontends
    print("Tune the frontend")
    if freq is not None: sdr.setFrequency(SOAPY_SDR_TX, txChan, freq)

    #tx loop
    #create tx stream
    print("Create Tx stream")
    txStream = sdr.setupStream(SOAPY_SDR_TX, "CF32", [txChan])
    print("Activate Tx Stream")
    sdr.activateStream(txStream)
    phaseAcc = 0
    phaseInc = 2 * math.pi * waveFreq / rate
    streamMTU = sdr.getStreamMTU(txStream)
    sampsCh0 = np.array([ampl] * streamMTU, np.complex64)

    timeLastPrint = time.time()
    totalSamps = 0
    while True:
        phaseAccNext = phaseAcc + streamMTU * phaseInc
        sampsCh0 = ampl * np.exp(1j * np.linspace(
            phaseAcc, phaseAccNext, streamMTU)).astype(np.complex64)
        phaseAcc = phaseAccNext
        while phaseAcc > math.pi * 2:
            phaseAcc -= math.pi * 2

        sr = sdr.writeStream(txStream, [sampsCh0], sampsCh0.size)
        if sr.ret != sampsCh0.size:
            raise Exception(
                "Expected writeStream() to consume all samples! %d" % sr.ret)
        totalSamps += sr.ret

        if time.time() > timeLastPrint + 5.0:
            print("Python siggen rate: %f Msps" %
                  (totalSamps / (time.time() - timeLastPrint) / 1e6))
            totalSamps = 0
            timeLastPrint = time.time()

    #cleanup streams
    print("Cleanup stream")
    sdr.deactivateStream(txStream)
    sdr.closeStream(txStream)
    print("Done!")
示例#29
0
import SoapySDR
from SoapySDR import *  #SOAPY_SDR_ constants
import numpy  #use numpy for buffers
import matplotlib.pyplot as plt
from scipy.signal import decimate, hilbert
from scipy import sqrt

#create device instance
#args can be user defined or from the enumeration result
args = dict(driver="rtlsdr")
sdr = SoapySDR.Device(args)

#apply settings
sdr.setSampleRate(SOAPY_SDR_RX, 0, 1e6)
sdr.setFrequency(SOAPY_SDR_RX, 0, 434e6)
# sdr.setGain('auto')
sdr.setBandwidth(SOAPY_SDR_RX, 0, 1e6)

#setup a stream (complex floats)
rxStream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32)
sdr.activateStream(rxStream)  #start streaming

#create a re-usable buffer for rx samples
buff = numpy.array([0] * 1024 * 256, numpy.complex64)

#receive some samples
sr = sdr.readStream(rxStream, [buff], len(buff))
print(buff[0], buff[100], buff[200], buff[2000])
samples_sq = [sqrt(i.real * i.real + i.imag * i.imag) for i in buff]
samples_sq = decimate(samples_sq, 50)
示例#30
0
def simo_fdx_burst(hub, bserials, rate, freq, txgain, rxgain, numSamps,
                   prefix_pad, postfix_pad, both_channels) -> np.array:
    # ## hub and multi-sdr integration copied from WB_CAL_DEMO.py
    if hub != "":
        hub_dev = SoapySDR.Device(dict(driver="remote", serial=hub))
    sdrs = [
        SoapySDR.Device(dict(driver="iris", serial=serial))
        for serial in bserials
    ]

    ant = 2 if both_channels else 1
    num_sdrs = len(sdrs)
    num_ants = num_sdrs * ant

    # assume trig_dev is part of the sdr nodes if no hub given
    trig_dev = None
    if hub != "":
        trig_dev = hub_dev
    else:
        trig_dev = sdrs[0]

    # set params on both channels
    for sdr in sdrs:
        info = sdr.getHardwareInfo()
        print("%s settings on device" % (info["frontend"]))
        for ch in [0, 1]:
            sdr.setBandwidth(SOAPY_SDR_TX, ch, 2.5 * rate)
            sdr.setBandwidth(SOAPY_SDR_RX, ch, 2.5 * rate)
            sdr.setSampleRate(SOAPY_SDR_TX, ch, rate)
            sdr.setSampleRate(SOAPY_SDR_RX, ch, rate)
            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)

            sdr.setGain(SOAPY_SDR_TX, ch, txgain)
            sdr.setGain(SOAPY_SDR_RX, ch, rxgain)

            sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
            sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)

            # Read initial gain settings
            read_lna = sdr.getGain(SOAPY_SDR_RX, 0, 'LNA')
            read_tia = sdr.getGain(SOAPY_SDR_RX, 0, 'TIA')
            read_pga = sdr.getGain(SOAPY_SDR_RX, 0, 'PGA')
            print("INITIAL GAIN - LNA: {}, \t TIA:{}, \t PGA:{}".format(
                read_lna, read_tia, read_pga))

            # gain setting from SISO_TXRX_TDD.py
            if "CBRS" in info["frontend"]:
                # Set gains to high val (initially)
                # sdr.setGain(SOAPY_SDR_TX, ch, txgain)  # txgain: at 2.5GHz [16:1:93], at 3.6GHz [15:1:102]
                # sdr.setGain(SOAPY_SDR_RX, ch, rxgain)  # rxgain: at 2.5GHz [3:1:105], at 3.6GHz [3:1:102]
                # else:
                # No CBRS board gains, only changing LMS7 gains
                sdr.setGain(SOAPY_SDR_TX, ch, "PAD", txgain)  # [0:1:42] txgain
                sdr.setGain(SOAPY_SDR_TX, ch, "ATTN", -6)
                sdr.setGain(SOAPY_SDR_RX, ch, "LNA", rxgain)  # [0:1:30] rxgain
                sdr.setGain(SOAPY_SDR_RX, ch, "LNA2", 14)
                sdr.setGain(SOAPY_SDR_RX, ch, "ATTN", 0 if freq > 3e9 else -18)

        # for ch in [0, 1]:
        #    if calibrate:
        #        sdr.writeSetting(SOAPY_SDR_RX, ch, "CALIBRATE", 'SKLK')
        #        sdr.writeSetting(SOAPY_SDR_TX, ch, "CALIBRATE", '')

        sdr.writeSetting("RESET_DATA_LOGIC", "")
        if not both_channels:
            sdr.writeSetting(SOAPY_SDR_RX, 1, 'ENABLE_CHANNEL', 'false')
            sdr.writeSetting(SOAPY_SDR_TX, 1, 'ENABLE_CHANNEL', 'false')

    trig_dev.writeSetting("SYNC_DELAYS", "")

    # Packet size
    symSamp = numSamps + prefix_pad + postfix_pad
    print("numSamps = %d" % numSamps)
    print("symSamps = %d" % symSamp)

    # Generate sinusoid to be TX
    Ts = 1 / rate
    s_freq = 1e5
    s_time_vals = np.array(np.arange(0, numSamps)).transpose() * Ts
    pilot = np.exp(s_time_vals * 1j * 2 * np.pi * s_freq).astype(
        np.complex64) * 1
    pad1 = np.array([0] * prefix_pad, np.complex64)
    pad2 = np.array([0] * postfix_pad, np.complex64)
    wbz = np.array([0] * symSamp, np.complex64)
    pilot1 = np.concatenate([pad1, pilot, pad2])
    pilot2 = wbz

    # pilot1_energy = np.sum(np.abs(cfloat2uint32(pilot1, order='QI')**2))/len(pilot1)

    # Initialize RX Matrix | num_sdrs x num_sdrs filled with None, to be filled with np.ndarray of np.ndarray of np.ndarray of np.uint32
    # The layers ought to be: array of each iteration (distinct TX board), each of which is an array of each board's RX,
    # each of which is an array of two arrays (one per antenna), each antenna having an array of values

    # this initializes all values to be None, might cause problems if something isn't overwritten for some reason
    rxMatrix = np.empty([num_ants, num_sdrs, ant], np.ndarray)

    # Create RX streams
    # CS16 makes sure the 4-bit lsb are samples are being sent

    rxStreams = [
        sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32, [0, 1]) for sdr in sdrs
    ]

    # Set Schedule #NOTE: this config is still unchanged from SISO_TXRX_TDD.py, needs to be fixed

    txsched = "PG"
    rxsched = "RG"
    print("Node 1 schedule %s " % txsched)
    print("Node 2 schedule %s " % rxsched)
    # Send one frame (set mamx_frame to 1)
    txconf = {
        "tdd_enabled": True,
        "frame_mode": "free_running",
        "symbol_size": symSamp,
        "frames": [txsched],
        "max_frame": 1
    }
    rxconf = {
        "tdd_enabled": True,
        "frame_mode": "free_running",
        "dual_pilot": False,
        "symbol_size": symSamp,
        "frames": [rxsched],
        "max_frame": 1
    }

    # SW Delays
    for sdr in sdrs:
        sdr.writeSetting("TX_SW_DELAY", str(30))

        # TDD_MODE Setting
        sdr.writeSetting("TDD_MODE", "true")

    #for sdr in sdrs:
    #    sdr.writeRegisters("TX_RAM_B", 0, cfloat2uint32(pilot2, order='QI').tolist())

    # Average Energy in signal
    energy_func = lambda x: np.sum(np.abs(x)**2) / len(x)
    dB_func = lambda x: 10 * np.log10(x)

    # implement loop logic here to make each board the TX board once per antenna, run num_ant times
    for i, txsdr in enumerate(sdrs):
        # repeat twice if both channels active
        for tx_ant in range(ant):
            activate_B = tx_ant % 2
            if activate_B:
                # if second time through, activate channel B
                txsdr.writeRegisters(
                    "TX_RAM_B", 0,
                    cfloat2uint32(pilot1, order='QI').tolist())
                txsdr.writeRegisters(
                    "TX_RAM_A", 0,
                    cfloat2uint32(pilot2, order='QI').tolist())
            else:
                # activate channel A first time through
                txsdr.writeRegisters(
                    "TX_RAM_A", 0,
                    cfloat2uint32(pilot1, order='QI').tolist())
                txsdr.writeRegisters(
                    "TX_RAM_B", 0,
                    cfloat2uint32(pilot2, order='QI').tolist())

            txsdr.writeSetting("TDD_CONFIG", json.dumps(txconf))

            # list comp. here makes sure we loop over every other board
            for j, rxsdr in enumerate(
                [board for board in sdrs if board != txsdr]):
                rxsdr.writeSetting("TDD_CONFIG", json.dumps(rxconf))

            # build rx Arrays
            rxArray_single_channel = np.array([0] * symSamp, np.complex64)
            rxArray_both_channels = np.array([rxArray_single_channel] * 2)
            rxArrays = np.array([rxArray_both_channels] * num_sdrs)

            flags = 0
            rList = np.empty(num_sdrs, object)

            # activate streams
            for r, sdr in enumerate(sdrs):
                rList[r] = sdr.activateStream(rxStreams[r], flags, 0)
                if rList[r] < 0:
                    print("Problem activating stream # %d" % i)
            trig_dev.writeSetting("TRIGGER_GEN", "")

            dBArrays = np.zeros(
                [num_sdrs, ant]
            )  #NOTE: this will initialize it to be 0s, which might be problematic

            # read Streams
            for r, sdr in enumerate(sdrs):
                rList[r] = sdrs[r].readStream(rxStreams[r], rxArrays[r],
                                              symSamp)
                print("reading stream #{} ({})".format(r, rList[r]))

                # read num_ant stream (either A or B depending) on which one sent
                for rx_ant in range(ant):
                    dBArrays[r][rx_ant] = dB_func(
                        energy_func(rxArrays[r][rx_ant]))
                    amp = np.max(abs(rxArrays[r][rx_ant]))
                    if amp > 0.1:
                        print("Board {0} with board {1}, max amp:{2}".format(
                            i * 2 + tx_ant, r * 2 + rx_ant, amp))

            for r, sdr in enumerate(sdrs):
                sdr.deactivateStream(rxStreams[r])
    #        print("\n ================ \n ")
    #        print(dBArrays.shape)
    #        print(dBArrays)
    #        print("\n =============== \n")
            rxMatrix[i * ant + tx_ant] = dBArrays
#    print(np.transpose(rxMatrix))

# End of data collection loops #

# ADC_rst, stops the tdd time counters, makes sure next time runs in a clean slate
    tdd_conf = {"tdd_enabled": False}
    for sdr in sdrs:
        sdr.writeSetting("RESET_DATA_LOGIC", "")
        sdr.writeSetting("TDD_CONFIG", json.dumps(tdd_conf))
        sdr.writeSetting("TDD_MODE", "false")

    for r, sdr in enumerate(sdrs):
        sdr.deactivateStream(rxStreams[r])
        sdr.closeStream(rxStreams[r])
        sdrs[r] = None
    print("3D dB Matrix: \n", rxMatrix)
    retMatrix = extract_ant(rxMatrix, both_channels)
    retMatrix = np.transpose(retMatrix)
    print("2D dB Matrix: \n", retMatrix)
    return (retMatrix)
示例#31
0
def calibrate_array(hub_serial, serials, ref_serial, rate, freq, txgain,
                    rxgain, numSamps, prefix_pad, postfix_pad, second_channel):
    global running
    bsdr = [
        SoapySDR.Device(dict(driver='iris', serial=serial))
        for serial in serials
    ]
    ref_sdr = SoapySDR.Device(dict(driver='iris', serial=ref_serial))
    if hub_serial != "":
        hub = SoapySDR.Device(dict(driver='remote', serial=hub_serial))
    sdrs = [ref_sdr] + bsdr
    #some default sample rates
    for i, sdr in enumerate(sdrs):
        info = sdr.getHardwareInfo()
        print("%s settings on device %d" % (info["frontend"], i))
        channel = [1] if second_channel else [0]
        for ch in channel:
            sdr.setFrequency(SOAPY_SDR_TX, ch, freq)
            sdr.setFrequency(SOAPY_SDR_RX, ch, freq)
            sdr.setSampleRate(SOAPY_SDR_TX, ch, rate)
            sdr.setSampleRate(SOAPY_SDR_RX, ch, rate)

            sdr.setGain(SOAPY_SDR_TX, ch, txgain)
            sdr.setGain(SOAPY_SDR_RX, ch, rxgain)

            sdr.setAntenna(SOAPY_SDR_RX, ch, "TRX")
            sdr.setDCOffsetMode(SOAPY_SDR_RX, ch, True)

        sdr.writeSetting("RESET_DATA_LOGIC", "")

    if hub_serial != "":
        hub.writeSetting("SYNC_DELAYS", "")
    else:
        bsdr[0].writeSetting("SYNC_DELAYS", "")
    num_bs_ant = len(bsdr)
    symSamp = numSamps + prefix_pad + postfix_pad
    print("numSamps = %d" % numSamps)
    print("symSamps = %d" % symSamp)

    DnA = [np.array([0] * symSamp, np.uint32) for i in range(num_bs_ant)]
    DnB = [np.array([0] * symSamp, np.uint32) for i in range(num_bs_ant)]
    UpA = [np.array([0] * symSamp, np.uint32) for i in range(num_bs_ant)]
    UpB = [np.array([0] * symSamp, np.uint32) for i in range(num_bs_ant)]

    #phaseDeltaDn = np.empty(num_bs_ant).astype(np.float)
    #phaseDeltaUp = np.empty(num_bs_ant).astype(np.float)
    #calibPhase = np.empty(num_bs_ant).astype(np.float)
    #ampDn = np.empty(num_bs_ant).astype(np.float)
    #ampUp = np.empty(num_bs_ant).astype(np.float)
    #calibAmp = np.empty(num_bs_ant).astype(np.float)

    # CS16 makes sure the 4-bit lsb are samples are being sent
    bs_rx_stream = [
        sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0, 1],
                        dict(WIRE=SOAPY_SDR_CS16)) for sdr in bsdr
    ]
    ref_rx_stream = ref_sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0, 1],
                                        dict(WIRE=SOAPY_SDR_CS16))

    Ts = 1 / rate
    s_freq = 1e5
    s_time_vals = np.array(np.arange(0, numSamps)).transpose() * Ts
    pilot = np.exp(s_time_vals * 1j * 2 * np.pi * s_freq).astype(
        np.complex64) * .2
    pad1 = np.array([0] * prefix_pad, np.complex64)
    pad2 = np.array([0] * postfix_pad, np.complex64)
    wbz = np.array([0] * (symSamp), np.complex64)
    pilot1 = np.concatenate([pad1, pilot, pad2]) if not second_channel else wbz
    pilot2 = np.concatenate([pad1, pilot, pad2]) if second_channel else wbz

    # configure tdd mode
    frameLen = len(bsdr) + 1 + 1 + 1
    for i, sdr in enumerate(bsdr):
        bsched = "RG" + ''.join("G" * i) + "P" + ''.join("G" *
                                                         (frameLen - i - 3))
        print("node %d schedule: %s" % (i, bsched))
        bconf = {
            "tdd_enabled": True,
            "frame_mode": "triggered",
            "symbol_size": symSamp,
            "frames": [bsched],
            "max_frame": 0
        }
        sdr.writeSetting("TDD_CONFIG", json.dumps(bconf))

    msched = "PG" + ''.join("R" * len(bsdr)) + "G"
    print("ref node schedule: %s" % (msched))
    mconf = {
        "tdd_enabled": True,
        "frame_mode": "triggered",
        "symbol_size": symSamp,
        "frames": [msched],
        "max_frame": 0
    }
    ref_sdr.writeSetting("TDD_CONFIG", json.dumps(mconf))

    for sdr in sdrs:
        sdr.writeSetting("TDD_MODE", "true")

    for sdr in sdrs:
        sdr.writeSetting("TX_SW_DELAY", str(30))

    replay_addr = 0
    for sdr in sdrs:
        sdr.writeRegisters("TX_RAM_A", replay_addr,
                           cfloat2uint32(pilot1, order='QI').tolist())
        sdr.writeRegisters("TX_RAM_B", replay_addr,
                           cfloat2uint32(pilot2, order='QI').tolist())

    flags = 0
    [
        sdr.activateStream(bs_rx_stream[i], flags, 0)
        for i, sdr in enumerate(bsdr)
    ]
    ref_sdr.activateStream(ref_rx_stream, flags, 0)

    fig, axes = plt.subplots(nrows=len(serials), ncols=2)  # figsize=(16,16))
    axes[0, 0].set_title('Downlink')
    axes[0, 1].set_title('Uplink')
    for i in range(len(serials)):
        #axes[i, 0].set_ylabel('Amplitude')
        axes[i, 0].set_ylim(-.1, .1)
        axes[i, 0].set_xlim(0, symSamp)
        axes[i, 0].legend(fontsize=10)
        #axes[i, 1].set_ylabel('Amplitude')
        axes[i, 1].set_ylim(-.1, .1)
        axes[i, 1].set_xlim(0, symSamp)
        axes[i, 1].legend(fontsize=10)

    interval = range(100, symSamp)
    lineI0 = [
        axes[i, 0].plot(np.real(uint32tocfloat(UpA[i][interval])),
                        label='ChA(I) Ref->Node %d' % i)[0]
        for i in range(num_bs_ant)
    ]
    lineQ0 = [
        axes[i, 0].plot(np.imag(uint32tocfloat(UpA[i][interval])),
                        label='ChA(Q) Ref->Node %d' % i)[0]
        for i in range(num_bs_ant)
    ]
    lineI1 = [
        axes[i, 1].plot(np.real(uint32tocfloat(DnA[i][interval])),
                        label='ChA(I) Node %d->Ref' % i)[0]
        for i in range(num_bs_ant)
    ]
    lineQ1 = [
        axes[i, 1].plot(np.imag(uint32tocfloat(DnA[i][interval])),
                        label='ChA(Q) Node %d->Ref' % i)[0]
        for i in range(num_bs_ant)
    ]

    fig.show()
    #print("Timestamps:")
    #for sdr in sdrs:
    #    print(hex(SoapySDR.timeNsToTicks(sdr.getHardwareTime(""), rate)))
    plot_size = len(interval)
    H1 = [np.empty(plot_size).astype(np.complex64) for r in range(num_bs_ant)]
    H2 = [np.empty(plot_size).astype(np.complex64) for r in range(num_bs_ant)]
    calib = [
        np.empty(plot_size).astype(np.complex64) for r in range(num_bs_ant)
    ]

    fg, ax = plt.subplots(nrows=2, ncols=1)  #, figsize=(16,8))
    ax[0].set_ylabel('calibration amplitude')
    ax[0].set_xlim(interval[0], interval[-1])
    ax[0].set_ylim(-.1, .1)
    ax[1].set_ylabel('calibration phase')
    ax[1].set_xlim(interval[0], interval[-1])
    ax[1].set_ylim(-np.pi, np.pi)
    line0 = [
        ax[0].plot([0] * plot_size, label='Amplitude %d' % i)[0]
        for i in range(num_bs_ant)
    ]
    line1 = [
        ax[1].plot([0] * plot_size, label='Phase %d' % i)[0]
        for i in range(num_bs_ant)
    ]
    fg.show()

    signal.signal(signal.SIGINT, signal_handler)
    #def animate(i):
    while (running):
        if hub_serial != "":
            hub.writeSetting("TRIGGER_GEN", "")
        else:
            bsdr[0].writeSetting("TRIGGER_GEN", "")

        for i, sdr in enumerate(bsdr):
            sdr.readStream(bs_rx_stream[i], [UpA[i], UpB[i]], symSamp)
        for i in range(len(bsdr)):
            ref_sdr.readStream(ref_rx_stream, [DnA[i], DnB[i]], symSamp)
        for i in range(num_bs_ant):
            H1[i] = uint32tocfloat(
                DnA[i][interval] if not second_channel else DnB[i][interval])
            H2[i] = uint32tocfloat(
                UpA[i][interval] if not second_channel else UpB[i][interval])
            calib[i] = H1[i] * np.conj(H2[i])
            #phaseDeltaDn[i] = np.mean(np.angle(DnA[i][interval] * np.conj(pilot[interval])))
            #phaseDeltaUp[i] = np.mean(np.angle(UpA[i][interval] * np.conj(pilot[interval])))
            #calibPhase[i]   = np.mean(np.angle(DnA[i][interval] * np.conj(UpA[i][interval])))
            #ampDn[i]        = np.sum(np.abs(DnA[i][interval]))/np.sum(np.abs(pilot[interval]))
            #ampUp[i]        = np.sum(np.abs(UpA[i][interval]))/np.sum(np.abs(pilot[interval]))
            #calibAmp[i]     = np.sum(np.abs(UpA[i][interval]))/np.sum(np.abs(DnA[interval]))
            #np.set_printoptions(precision=2)
            lineI0[i].set_ydata(np.real(H1[i]))
            lineQ0[i].set_ydata(np.imag(H1[i]))
            lineI1[i].set_ydata(np.real(H2[i]))
            lineQ1[i].set_ydata(np.imag(H2[i]))
            line0[i].set_ydata(np.abs(calib[i]))
            line1[i].set_ydata((np.angle(calib[i])))
        fig.canvas.draw()
        fg.canvas.draw()
        fg.show()
        fig.show()
        #return line0, line1,
    #anim = animation.FuncAnimation(fig, animate, init_func=None,
    #                           frames=100, interval=100, blit=True)

    #plt.show()

    tdd_conf = {"tdd_enabled": False}
    for sdr in sdrs:
        sdr.writeSetting("RESET_DATA_LOGIC", "")
        sdr.writeSetting("TDD_CONFIG", json.dumps(tdd_conf))
        sdr.writeSetting("TDD_MODE", "false")

    ref_sdr.closeStream(ref_rx_stream)
    for i, sdr in enumerate(bsdr):
        sdr.closeStream(bs_rx_stream[i])
    ref_sdr = None
    bsdr = None