Beispiel #1
0
def main():
    read_arguments()

    ctx = create_context(scan_for_context, arg_uri, arg_ip)

    if timeout >= 0:
        ctx.set_timeout(timeout)

    dev = ctx.find_device(device_name)

    if dev is None:
        sys.stderr.write('Device %s not found!' % device_name)
        exit(1)

    if len(channels) == 0:
        for channel in dev.channels:
            channel.enabled = True
    else:
        for channel_idx in channels:
            dev.channels[int(channel_idx)].enabled = True

    buffer = iio.Buffer(dev, buffer_size, cyclic=cyclic)

    if buffer is None:
        sys.stderr.write('Unable to create buffer!')
        exit(1)

    write_data(dev, buffer, num_samples, buffer_size, cyclic)
Beispiel #2
0
 def writeTx(self, samples):  #, raw=False): use samples.dtype
     """write to the Tx buffer and make it cyclic"""
     if self._tx_buff is not None:
         self._tx_buff = None  # turn off any previous signal
     if not (isinstance(samples, np.ndarray)):
         logging.debug('tx: off')  # leave with transmitter off
         self.tx_state = self.TX_OFF
         return
     if samples.dtype == np.int16:
         data = samples << 4  # align 12 bit raw to msb
     else:  # samples can come from some DiscreteSignalSource, if so
         # data is complex IQ and scaled to +/-1.0 float range
         # use 16 **not** self.no_bits to align data to msb
         data = self.complex2raw(samples, 16)
     # samples are 2 bytes each with interleaved I/Q value (no_samples = len/4)
     self.tx_state = self.TX_DMA  # enable the tx channels
     try:  # create a cyclic iio buffer for continuous tx output
         self._tx_buff = iio.Buffer(self.dac, len(data) // 4, True)
         count = self._tx_buff.write(data)
         logging.debug(str(count) + ' samples transmitted')
         self._tx_buff.push()
     except OSError as oserr:
         self.tx_state = self.TX_OFF
         raise OSError('failed to create an iio buffer')
     # buffer retained after a successful call
     return count  # just for now
Beispiel #3
0
            def run(collector_self):
                for name, ch in self.channels.items():
                    ch.iio_channel.enabled = (name in self.active_channels)

                samples_count = self.buffer_samples_count or self.sample_rate_hz

                iio_buffer = iio.Buffer(self.iio_device, samples_count,
                                        self.buffer_is_circular)
                # NB: This buffer creates a communication pipe to the
                #     BeagleBone (or is it between the BBB and the ACME?)
                #     that locks down any configuration. The IIO drivers
                #     do not limit access when a buffer exists so that
                #     configuring the INA226 (i.e. accessing iio.Device.attrs
                #     or iio.Channel.attrs from iio.Device.channels i.e.
                #     assigning to or reading from any property of this class
                #     or calling its setup or reset methods) will screw up the
                #     whole system and will require rebooting the BBB-ACME board!

                self.collector_exception = None
                try:
                    refilled_once = False
                    while not (refilled_once and self.work_done.is_set()):
                        refilled_once = True
                        iio_buffer.refill()
                        for name in self.active_channels:
                            self.channels[name].iio_store_buffer_samples(
                                iio_buffer)
                except Exception as e:
                    self.collector_exception = e
                finally:
                    del iio_buffer
                    for ch in self.channels.values():
                        ch.enabled = False
Beispiel #4
0
 def writeTx(self, samples, raw=False):
     """write to the Tx buffer and make it cyclic"""
     if self._tx_buff is not None:
         self._tx_buff = None               # turn off any previous signal
     if isinstance(samples, bool) or len(samples)==0:          
         logging.debug('tx: off')           # leave with transmitter off
         return
     if raw:
         data = samples<<4         # align 12 bit raw to msb
     else:   # samples some are from some DiscreteSignalSource, so
             # data is complex IQ and scaled to +/-1.0 float range
             # use 16 **not** self.no_bits to align data to msb
         data = self.complex2raw(samples, 16)
     no_samples = len(data)//2
     for ch in self.tx_channels:   # enable the tx channels
         ch.enabled = True
     try:  # create a cyclic iio buffer for continuous tx output
         self._tx_buff = iio.Buffer(self.dac, no_samples//2, True)
         count = self._tx_buff.write(data)
         logging.debug(str(count)+' samples transmitted')
         self._tx_buff.push()
     except OSError:
         for ch in chs:
             ch.enabled = False
         self._tx_buff = None
         raise OSError('failed to create an iio buffer')
     # buffer retained after a successful call
     return count # just for now
Beispiel #5
0
    def create(self):
        """Create the IIO buffer."""
        self._device()
        self._channels()
        buffer = iio.Buffer(self.dev, self.arguments.buffer_size)

        if buffer is None:
            raise Exception("Unable to create buffer!\n")

        return buffer
Beispiel #6
0
    def create_streams(self, blen):

        self.dev_rx = self.iio_ctx.find_device("cf-ad9361-A")

        # configure master streaming devices
        for n in range(8):
            chan = self.dev_rx.find_channel("voltage" + str(n))
            chan.enabled = True

        # create IIO buffer object
        self.buf_rx = iio.Buffer(self.dev_rx, blen)
Beispiel #7
0
 def _rx_init_channels(self):
     if self._complex_data:
         for m in self.rx_enabled_channels:
             v = self._rxadc.find_channel(self._rx_channel_names[m * 2])
             v.enabled = True
             v = self._rxadc.find_channel(self._rx_channel_names[m * 2 + 1])
             v.enabled = True
     else:
         for m in self.rx_enabled_channels:
             v = self._rxadc.find_channel(self._rx_channel_names[m])
             v.enabled = True
     self.__rxbuf = iio.Buffer(self._rxadc, self.__rx_buffer_size, False)
Beispiel #8
0
 def rx(self):
     if not self.rxbuf:
         # Enable all IQ channels
         v0 = self.rxadc.find_channel("voltage0")
         v1 = self.rxadc.find_channel("voltage1")
         v0.enabled = True
         v1.enabled = True
         self.rxbuf = iio.Buffer(self.rxadc, 2**15, False)
     self.rxbuf.refill()
     data = self.rxbuf.read()
     x = np.frombuffer(data, dtype=np.int16)
     sig = x[::2] + 1j * x[1::2]
     return sig
Beispiel #9
0
    def _create_buffer(self, buff_size):

        device = self.context.find_device(DEVICE_TX_NAME)

        # configure master streaming devices
        # 1x1 SDR contains only two channels
        for n in range(2):
            name = "voltage{0}".format(n)
            chan = device.find_channel(name, is_output=True)
            chan.enabled = True

        # create buffer
        self.buffer_tx = iio.Buffer(device, buff_size, cyclic=True)
Beispiel #10
0
 def _tx_init_channels(self):
     if self._complex_data:
         for m in self.tx_enabled_channels:
             v = self._txdac.find_channel(self._tx_channel_names[m * 2], True)
             v.enabled = True
             v = self._txdac.find_channel(self._tx_channel_names[m * 2 + 1], True)
             v.enabled = True
     else:
         for m in self.tx_enabled_channels:
             v = self._txdac.find_channel(self._tx_channel_names[m], True)
             v.enabled = True
     self.__txbuf = iio.Buffer(
         self._txdac, self._tx_buffer_size, self.__tx_cyclic_buffer
     )
Beispiel #11
0
 def readRx(self, no_samples, raw=True):
     # enable the channels
     for ch in self.adc.channels:
         ch.enabled = True
     try:  # create a buffer of the right size to use
         buff = iio.Buffer(self.adc, no_samples)
         buff.refill()
         buffer = buff.read()
         iq = np.frombuffer(buffer, np.int16)
     except OSError:
         for ch in self.adc.channels:
             ch.enabled = True
         raise OSError('failed to create iio buffer')
     if raw:
         return iq
     else:
         return self.raw2complex(iq)
Beispiel #12
0
    def _rx_init_channels(self):
        for m in self._rx_channel_names:
            v = self._rxadc.find_channel(m)
            if not v:
                raise Exception(f"Channel {m} not found")
            v.enabled = False

        if self._complex_data:
            for m in self.rx_enabled_channels:
                v = self._rxadc.find_channel(self._rx_channel_names[m * 2])
                v.enabled = True
                v = self._rxadc.find_channel(self._rx_channel_names[m * 2 + 1])
                v.enabled = True
        else:
            for m in self.rx_enabled_channels:
                v = self._rxadc.find_channel(self._rx_channel_names[m])
                v.enabled = True
        self.__rxbuf = iio.Buffer(self._rxadc, self.__rx_buffer_size, False)
Beispiel #13
0
    def allocate_capture_buffer(self, samples_count, cyclic=False):
        """ Allocate buffer to store captured data.

        Args:
            samples_count (int): amount of samples to hold in buffer (> 0).
            cyclic (bool): True to make the buffer act as a circular buffer,
                           False otherwise.

        Returns:
            bool: True if operation is successful, False otherwise.

        """
        self._iio_buffer = iio.Buffer(self._iio_device, samples_count, cyclic)
        if self._iio_buffer != None:
            self._trace.trace(
                1, "Buffer (count=%d, cyclic=%s) allocated." %
                (samples_count, cyclic))
            return True
        self._trace.trace(
            1, "Failed to allocate buffer! (count=%d, cyclic=%s)" %
            (samples_count, cyclic))
        return False
Beispiel #14
0
# https://ez.analog.com/thread/97117-using-iiopy-with-m2k
# https://mirrors.dotsrc.org/fosdem/2018/AW1.120/plutosdr.webm
# https://wiki.analog.com/resources/tools-software/linux-software/fmcomms2_plugin
import iio, struct, time
import scipy.signal
import numpy as np
import matplotlib.pyplot as plt
ctxs = iio.scan_contexts()
uri = next(iter(ctxs), None)
ctx = iio.Context(uri)
dev = ctx.find_device('cf-ad9361-lpc')
phy = ctx.find_device('ad9361-phy')
phy.channels[0].attrs['frequency'].value = str(int(1575.42e6))
dev.channels[0].enabled = True
dev.channels[1].enabled = True
buf = iio.Buffer(dev, 4096, cyclic=False)
ys = []
for i in range(1024):
    buf.refill()
    ys.append(buf.read())
d = np.frombuffer(np.array([inner for outer in ys for inner in outer]),
                  dtype=np.int16)
q = d[::2] + 1j * d[1::2]
f, t, z = scipy.signal.stft(q[0:32 * 4096])
plt.imshow(np.abs(z))
plt.show()

print(iio.version)

ctxs = iio.scan_contexts()
Beispiel #15
0
def get_plot_data(dev, center_freq, min_hw_gain):

    global fft_rxvals_iq_db
    global fftfreq_rxvals_iq

    ylim = [0, 0]
    # Create IIO RX Buffer
    rxbuf = iio.Buffer(dev[RXADC], BUFLEN, False)

    # Window function, max value = unity
    window = np.blackman(BUFLEN)

    avg_step = 0
    fft_rxvals_iq = np.array([])
    fftfreq_rxvals_iq = np.array([])
    avgband = np.array([])

    while (True):

        #acquire data
        for i in range(0, len(center_freq)):

            RXLO = center_freq[i]
            TXLO = RXLO
            rxLO.attrs["frequency"].value = str(int(RXLO))
            txLO.attrs["frequency"].value = str(int(TXLO))

            time.sleep(0.2)
            root.update_idletasks()
            root.update()

            #Get gain calibration for specific band
            if (gain_calib_set.get() == True):
                for index_gain in range(0, len(gain_freq)):
                    gain_frequency = float(gain_freq[index_gain][0]) * 1e6
                    if ((center_freq[i] - FREQ_BAND / 2) <= gain_frequency <=
                        (center_freq[i] + FREQ_BAND / 2)):
                        gain_calib = float(gain_freq[index_gain][1])
                        break
            else:
                gain_calib = 0

            #generate test tone
            test_tone_freq = str(
                (TXDAC_FREQ) * (i + 1))  # spread test tones for each new band
            dds0.attrs["frequency"].value = test_tone_freq

            #delay before data acquisition
            time.sleep(0.01)

            if (progress_en.get() == False):
                for k in range(0, int(avg_nr.get()) + 1):
                    #flush operations
                    for j in range(5):
                        rxbuf.refill()
                        x = rxbuf.read()

                    buff = np.frombuffer(x, np.int16)

                    #apply window
                    rxvals_i = buff[0::2] * window
                    rxvals_q = buff[1::2] * window

                    #construct complex IQ data
                    rxvals_iq = rxvals_i + (1j * rxvals_q)
                    # apply FFT and get amplitude of the IQ data
                    newband = np.abs(np.fft.fft(rxvals_iq))
                    #apply averaging
                    if (k != 0):
                        avgband = (newband) * 1 / k + avgband * (k - 1) / k
                    else:
                        avgband = newband
            else:
                for j in range(5):
                    rxbuf.refill()
                    x = rxbuf.read()

                #get data from buffer
                buff = np.frombuffer(x, np.int16)

                #apply window
                rxvals_i = buff[0::2] * window
                rxvals_q = buff[1::2] * window

                #construct complex IQ data
                rxvals_iq = rxvals_i + (1j * rxvals_q)

                # apply FFT and get amplitude of the IQ data
                avgband = np.abs(np.fft.fft(rxvals_iq))

            txt1.insert(
                tk.END,
                "Center Frequency set to: " + str(int(RXLO / 1e6)) + ' MHz\n')
            txt1.insert(
                tk.END, "Min / Max i values: " + str(int(np.min(rxvals_i))) +
                ", " + str(int(np.max(rxvals_i))) + "\n")
            txt1.see("end")

            #compute cutoff thresholds
            low_th = int(((RX0FS - FREQ_BAND) / (RX0FS * 2)) * BUFLEN)
            high_th = int(BUFLEN - (((RX0FS - FREQ_BAND) /
                                     (RX0FS * 2)) * BUFLEN))

            #compute frequency bins
            freq_bins = (np.fft.fftfreq(BUFLEN, 1 / RX0FS) +
                         (center_freq[0] + FREQ_BAND * i)) / 1e6

            # Create tuple such that frequencies and corresponding amplitudes can be manipulated together
            tuple1 = zip(freq_bins, avgband)

            # Rearrange such that the center frequency is in the middle.
            tuple1 = sorted(tuple1, key=lambda x: x[0])

            # Extract the passband of the FIR response
            tuple1 = tuple1[low_th:high_th]

            iq = np.array([nr[1] for nr in tuple1]) / (10**(gain_calib / 10))

            if (progress_en.get() == False):
                if (avg_step == 0):
                    # Append amplitudes to collection of bands
                    fft_rxvals_iq = np.append(fft_rxvals_iq, iq)
                    # Append frequency bins to the frequency collection
                    fftfreq_rxvals_iq = np.append(fftfreq_rxvals_iq,
                                                  [nr[0] for nr in tuple1])
                else:
                    #replace older amplitudes per band with newer amplitudes
                    fft_rxvals_iq[i * (high_th - low_th):(i + 1) *
                                  (high_th - low_th)] = iq
            else:
                if (avg_step == 0):
                    # Append amplitudes to collection of bands
                    fft_rxvals_iq = np.append(fft_rxvals_iq, iq)
                    fftfreq_rxvals_iq = np.append(fftfreq_rxvals_iq,
                                                  [nr[0] for nr in tuple1])
                else:
                    #replace older amplitudes per band with newer amplitudes
                    iq = iq * 1 / avg_step + fft_rxvals_iq[
                        i * (high_th - low_th):(i + 1) *
                        (high_th - low_th)] * (avg_step - 1) / avg_step
                    fft_rxvals_iq[i * (high_th - low_th):(i + 1) *
                                  (high_th - low_th)] = iq

            # Compute in dB, subtract hardware gain to normalize to absolute analog signal level at input
            fft_rxvals_iq_db = 20 * np.log10(fft_rxvals_iq * 2 /
                                             (2**11 * BUFLEN)) - min_hw_gain

            #Perform gain calibration per band
            #fft_rxvals_iq_db[i * (high_th - low_th) : (i + 1) * (high_th - low_th)] = fft_rxvals_iq_db[i * (high_th - low_th) : (i + 1) * (high_th - low_th)] - gain_calib

            # Plot data
            a.clear()
            a.grid(True)
            a.set_title('Frequency Spectrum')
            a.set_xlabel('Fequency (MHz)')
            a.set_ylabel('Magnitude')

            a.plot(fftfreq_rxvals_iq, fft_rxvals_iq_db)
            if (fixed_axis.get() == True and avg_step != 0):
                a.set_ylim(ylim)
            if (fixed_axis.get() == False or avg_step == 0):
                ylim = a.get_ylim()
            canvas.draw()
            root.update_idletasks()
            root.update()

            if (btn_text.get() == "Start" and sweep_en.get() == False):
                break

        if (btn_text.get() == "Start" or sweep_en.get() == True):
            break
        avg_step += 1
Beispiel #16
0
ctrl.channels[5].attrs['hardwaregain'].value = '-30'

# Enable all IQ channels
rxadc.channels[0].enabled = True
rxadc.channels[1].enabled = True
txdac.channels[4].enabled = True
txdac.channels[5].enabled = True

# Force DAC to use DMA not DDSs
txdac.channels[0].attrs['raw'].value = str(0)
txdac.channels[1].attrs['raw'].value = str(0)
txdac.channels[2].attrs['raw'].value = str(0)
txdac.channels[3].attrs['raw'].value = str(0)

# Create buffer for RX data
rxbuf = iio.Buffer(rxadc, 2**15, False)

# Create cyclic buffer for TX data
N = 2**15
txbuf = iio.Buffer(txdac, N / 2, True)

# Create a sinewave waveform
fc = 10000
ts = 1 / float(RXFS)
t = np.arange(0, N * ts, ts)
i = np.sin(2 * np.pi * t * fc) * 2**14
q = np.cos(2 * np.pi * t * fc) * 2**14
iq = np.empty((i.size + q.size, ), dtype=i.dtype)
iq[0::2] = i
iq[1::2] = q
iq = np.int16(iq)
def run_hardware_tests(TRXLO, sync, runs, uri):

    # User configurable
    DDS_Freq = 4000000

    # Setup contexts
    try:
        ctx = iio.Context(uri)
    except:
        raise Exception("No device found")

    ctrl_chipA = ctx.find_device("adrv9009-phy")
    ctrl_chipB = ctx.find_device("adrv9009-phy-b")
    txdac = ctx.find_device("axi-adrv9009-tx-hpc")
    rxadc = ctx.find_device("axi-adrv9009-rx-hpc")
    hmc7044 = ctx.find_device("hmc7044")

    # Configure transceiver settings
    LO = ctrl_chipA.find_channel("TRX_LO", True)
    LO.attrs["frequency"].value = str(int(TRXLO))
    LO = ctrl_chipB.find_channel("TRX_LO", True)
    LO.attrs["frequency"].value = str(int(TRXLO))
    #
    rx = ctrl_chipA.find_channel("voltage0")
    rx.attrs['gain_control_mode'].value = 'slow_attack'
    rx = ctrl_chipB.find_channel("voltage0")
    rx.attrs['gain_control_mode'].value = 'slow_attack'

    if sync:
        # Calibrate
        ctrl_chipA.attrs['calibrate_rx_phase_correction_en'] = True
        ctrl_chipA.attrs['calibrate'] = True
        ctrl_chipB.attrs['calibrate_rx_phase_correction_en'] = True
        ctrl_chipB.attrs['calibrate'] = True

        # MCS
        hmc7044.reg_write(0x5a, 0)
        for k in range(12):
            ctrl_chipA.attrs['multichip_sync'] = str(k)
            ctrl_chipB.attrs['multichip_sync'] = str(k)

    # Enable all IQ channels
    v0 = rxadc.find_channel("voltage0_i")
    v1 = rxadc.find_channel("voltage0_q")
    v2 = rxadc.find_channel("voltage1_i")
    v3 = rxadc.find_channel("voltage1_q")
    v0.enabled = True
    v1.enabled = True
    v2.enabled = True
    v3.enabled = True

    # Create buffer for RX data
    rxbuf = iio.Buffer(rxadc, 2**14, False)
    #
    # Enable single tone DDS
    dds0_tx1 = txdac.find_channel('altvoltage0', True)
    dds2_tx1 = txdac.find_channel('altvoltage2', True)
    dds0_tx2 = txdac.find_channel('altvoltage8', True)
    dds2_tx2 = txdac.find_channel('altvoltage10', True)

    # Turn all others off
    dds1 = txdac.find_channel('altvoltage1', True)
    dds1.attrs['raw'].value = str(0)
    dds1.attrs['scale'].value = str(0)
    for r in range(3, 16):
        dds1 = txdac.find_channel('altvoltage' + str(r), True)
        dds1.attrs['scale'].value = str(0)
        dds1.attrs['raw'].value = str(0)

    # Set frequency of enabled DDSs
    dds0_tx1.attrs['raw'].value = str(1)
    dds0_tx1.attrs['frequency'].value = str(DDS_Freq)
    dds0_tx1.attrs['scale'].value = str(0.5)
    dds0_tx1.attrs['phase'].value = str(90000)
    dds2_tx1.attrs['raw'].value = str(1)
    dds2_tx1.attrs['frequency'].value = str(DDS_Freq)
    dds2_tx1.attrs['scale'].value = str(0.5)
    dds2_tx1.attrs['phase'].value = str(0)

    dds0_tx2.attrs['raw'].value = str(1)
    dds0_tx2.attrs['frequency'].value = str(DDS_Freq)
    dds0_tx2.attrs['scale'].value = str(0.5)
    dds0_tx2.attrs['phase'].value = str(90000)
    dds2_tx2.attrs['raw'].value = str(1)
    dds2_tx2.attrs['frequency'].value = str(DDS_Freq)
    dds2_tx2.attrs['scale'].value = str(0.5)
    dds2_tx2.attrs['phase'].value = str(0)

    # Collect data
    # reals0 = np.array([])
    # imags0 = np.array([])
    # reals1 = np.array([])
    # imags1 = np.array([])
    phase_error = np.array([])

    for i in range(runs):
        rxbuf.refill()
        data = rxbuf.read()
        x = np.frombuffer(data, dtype=np.int16)
        # reals0 = np.append(reals0,x[::4])
        # imags0 = np.append(imags0,x[1::4])
        # reals1 = np.append(reals1,x[2::4])
        # imags1 = np.append(imags1,x[3::4])
        chan0 = x[0::4] + 1j * x[1::4]
        chan1 = x[2::4] + 1j * x[3::4]
        phase_error = np.append(phase_error, measure_phase(chan0, chan1))

    # # Plot
    # if do_plots:
    #     plt.plot(phase_error)
    #     # plt.plot(reals0)
    #     # # plt.plot(imags0)
    #     # plt.plot(reals1)
    #     # # plt.plot(imags1)
    #     plt.xlabel("Samples")
    #     plt.ylabel("Amplitude [dbFS]")
    #     plt.show()
    return phase_error
Beispiel #18
0
    def __init__(self, sampling_count=2048, context='ip:192.168.2.1'):
        '''
        Initialization
        Paramters:
            handler: when I/Q data get ready, there requires a callback to send data
            sampling_count: I/Q sampling count, default value: 2048,
            context: device context, there requires ip address,
        '''

        sys.stdout.write('Initialize Adalm-Pluto (based on AD936x) ...\n')

        self.__parameters = {
            'frequency': (0, [101700000,
                              (70000000, 1, 6000000000)]),  # RX frequency
            'rf_bandwidth': (4, [2000000,
                                 (200000, 1, 56000000)]),  # RX bandwidth
            # 'sampling_frequency': (4, [2500000, (2083333, 1, 61440000)]),
            'sampling_frequency':
            (4, [2500000, (521000, 1, 61440000)]),  # Sampling Rate
            'gain_control_mode':
            (4, ['manual',
                 ('manual,fast_attack,slow_attack,hybrid')]),  # Gain control
            'hardwaregain': (4, [-3, (-3, 1, 71)]),  # MGC
            'tx_enabled': (1, ['false', ('true,false')]),  # TX RF out
            'tx_frequency': (1, [101700000,
                                 (70000000, 1, 6000000000)]),  # TX frequency
            'tx_hardwaregain': (5, [0, (-89, 1, 0)])  # TX MGC
        }
        self.__callback = None
        self.__capture = None
        self.__start_sampling = False
        self.__lock = threading.Lock()
        self.__abort_sampling_event = threading.Event()
        self.__abort_sampling_event.clear()

        try:
            # Create device context
            retry = 10
            while retry:
                try:
                    self.__ctx = iio.Context(context)
                    break
                except:
                    time.sleep(2)
                    retry -= 1
                    continue

            sys.stdout.write(('Initialize device context.\n'))

            # Initialize device control
            # channel 0, 4 are manipulated by rx
            # channel 1, 5 are manipulated by tx
            self.__ctrl = self.__ctx.find_device('ad9361-phy')

            # Initialize RX/TX ctrl parameters
            self.__ctrl.channels[0].attrs['powerdown'].value = '1'
            self.__ctrl.channels[0].attrs['frequency'].value = '101700000'
            self.__ctrl.channels[4].attrs['rf_bandwidth'].value = '2000000'
            self.__ctrl.channels[4].attrs[
                'gain_control_mode'].value = 'slow_attack'
            self.__ctrl.channels[4].attrs[
                'rf_port_select'].value = 'A_BALANCED'
            self.__ctrl.channels[1].attrs['powerdown'].value = '1'
            self.__ctrl.channels[1].attrs['frequency'].value = '101700000'
            self.__ctrl.channels[5].attrs['rf_bandwidth'].value = '2000000'
            self.__ctrl.channels[5].attrs['hardwaregain'].value = '0'
            _ad9361_set_bb_rate(self.__ctrl._device, 2560000)
            sys.stdout.write('Initialize CTRL: \"ad9361-phy\".\n')

            # Initialize device receiving channels and enable I/Q data output channels
            self.__rx = self.__ctx.find_device('cf-ad9361-lpc')
            sys.stdout.write('Initialize RX: \"cf-ad9361-lpc\".\n')
            self.__rx.channels[0].enabled = True  # I data channel
            self.__rx.channels[1].enabled = True  # Q data channel
            sys.stdout.write('Enable RX I/Q channels.\n')

            # Initialize buffer
            self.__buffer = iio.Buffer(self.__rx, sampling_count, False)
            sys.stdout.write(
                'Initialize I/Q data buffers (sampling count={0}).\n'.format(
                    sampling_count))
        except:
            traceback.print_exc()
Beispiel #19
0
tx.attrs["sampling_frequency"].value = str(int(RXFS))
tx.attrs['hardwaregain'].value = '-30'

rx = ctrl.find_channel("voltage0")
rx.attrs["rf_bandwidth"].value = str(int(TXBW))
rx.attrs["sampling_frequency"].value = str(int(TXFS))
rx.attrs['gain_control_mode'].value = 'slow_attack'

# Enable all IQ channels
v0 = rxadc.find_channel("voltage0")
v1 = rxadc.find_channel("voltage1")
v0.enabled = True
v1.enabled = True

# Create buffer for RX data
rxbuf = iio.Buffer(rxadc, 2**15, False)

# Enable single tone DDS
dds0 = txdac.find_channel('altvoltage0', True)
dds2 = txdac.find_channel('altvoltage2', True)
dds0.attrs['raw'].value = str(1)
dds0.attrs['frequency'].value = str(100000)
dds0.attrs['scale'].value = str(0.9)
dds0.attrs['phase'].value = str(90000)
dds2.attrs['raw'].value = str(1)
dds2.attrs['frequency'].value = str(100000)
dds2.attrs['scale'].value = str(0.9)
dds2.attrs['phase'].value = str(0)

# Collect data
#reals = np.array([])
ctrl.find_channel('voltage0', True).attrs['hardwaregain'].value = '-30'

# Enable all IQ channels
rxadc.find_channel("voltage0").enabled = True
rxadc.find_channel("voltage1").enabled = True
txdac.find_channel("voltage0", True).enabled = True
txdac.find_channel("voltage1", True).enabled = True

# Force DAC to use DMA not DDS
txdac.find_channel('TX1_I_F1', True).attrs['raw'].value = str(0)
txdac.find_channel('TX1_Q_F1', True).attrs['raw'].value = str(0)
txdac.find_channel('TX1_I_F2', True).attrs['raw'].value = str(0)
txdac.find_channel('TX1_Q_F2', True).attrs['raw'].value = str(0)

# Create buffer for RX data
rxbuf = iio.Buffer(rxadc, 2**15, False)

# Create cyclic buffer for TX data
samples_per_channel = 2**15
txbuf = iio.Buffer(txdac, samples_per_channel, True)

# Create a sinewave waveform
fc = 10000
ts = 1 / float(RXFS)
t = np.arange(0, samples_per_channel * ts, ts)
i = np.sin(2 * np.pi * t * fc) * 2**14
q = np.cos(2 * np.pi * t * fc) * 2**14
iq = np.empty((i.size + q.size, ), dtype=i.dtype)
iq[0::2] = i
iq[1::2] = q
iq = np.int16(iq)
def run_hardware_tests(TRXLO, sync, runs, buf_len, uri1, uri2):

    # User configurable
    DDS_Freq = 4000000

    # Setup contexts
    try:
        ctx1 = iio.Context(uri1)
    except:
        raise Exception("No device1 found")
    try:
        ctx2 = iio.Context(uri2)
    except:
        raise Exception("No device1 found")

    ctrl_chip1A = ctx1.find_device("adrv9009-phy")
    ctrl_chip1B = ctx1.find_device("adrv9009-phy-b")
    ctrl_chip2A = ctx2.find_device("adrv9009-phy")
    ctrl_chip2B = ctx2.find_device("adrv9009-phy-b")

    txdac1 = ctx1.find_device("axi-adrv9009-tx-hpc")
    rxadc1 = ctx1.find_device("axi-adrv9009-rx-hpc")
    txdac2 = ctx2.find_device("axi-adrv9009-tx-hpc")
    rxadc2 = ctx2.find_device("axi-adrv9009-rx-hpc")

    hmc7044_1 = ctx1.find_device("hmc7044")
    hmc7044_1_car = ctx1.find_device("hmc7044-car")
    hmc7044_2 = ctx2.find_device("hmc7044")
    hmc7044_2_car = ctx2.find_device("hmc7044-car")
    hmc7044_1_ext = ctx1.find_device("hmc7044-ext")

    # request sync pulse
    hmc7044_1_ext.attrs["sysref_request"].value = str(1)
    # Check Sync status
    # print(hmc7044_1._debug_attrs["status"].value)

    # Configure transceiver settings
    LO1 = ctrl_chip1A.find_channel("TRX_LO", True)
    LO1.attrs["frequency"].value = str(int(TRXLO))
    LO1 = ctrl_chip1B.find_channel("TRX_LO", True)
    LO1.attrs["frequency"].value = str(int(TRXLO))

    LO2 = ctrl_chip2A.find_channel("TRX_LO", True)
    LO2.attrs["frequency"].value = str(int(TRXLO))
    LO2 = ctrl_chip2B.find_channel("TRX_LO", True)
    LO2.attrs["frequency"].value = str(int(TRXLO))
    #
    rx1 = ctrl_chip1A.find_channel("voltage0")
    rx1.attrs['gain_control_mode'].value = 'slow_attack'
    rx1 = ctrl_chip1B.find_channel("voltage0")
    rx1.attrs['gain_control_mode'].value = 'slow_attack'

    rx2 = ctrl_chip2A.find_channel("voltage0")
    rx2.attrs['gain_control_mode'].value = 'slow_attack'
    rx2 = ctrl_chip2B.find_channel("voltage0")
    rx2.attrs['gain_control_mode'].value = 'slow_attack'

    if sync:
        # Calibrate
        ctrl_chip1A.attrs['calibrate_rx_phase_correction_en'] = True
        ctrl_chip1A.attrs['calibrate'] = True
        ctrl_chip1B.attrs['calibrate_rx_phase_correction_en'] = True
        ctrl_chip1B.attrs['calibrate'] = True

        ctrl_chip2A.attrs['calibrate_rx_phase_correction_en'] = True
        ctrl_chip2A.attrs['calibrate'] = True
        ctrl_chip2B.attrs['calibrate_rx_phase_correction_en'] = True
        ctrl_chip2B.attrs['calibrate'] = True

        # MCS
        #hmc7044_1.reg_write(0x5a,0)
        for k in range(12):
            ctrl_chip1A.attrs['multichip_sync'] = str(k)
            ctrl_chip1B.attrs['multichip_sync'] = str(k)

        #hmc7044_2.reg_write(0x5a,0)
        for k in range(12):
            ctrl_chip2A.attrs['multichip_sync'] = str(k)
            ctrl_chip2B.attrs['multichip_sync'] = str(k)

    # Enable all IQ channels
    v0 = rxadc1.find_channel("voltage0_i")
    v1 = rxadc1.find_channel("voltage0_q")
    v2 = rxadc1.find_channel("voltage1_i")
    v3 = rxadc1.find_channel("voltage1_q")
    v0.enabled = True
    v1.enabled = True
    v2.enabled = True
    v3.enabled = True

    v4 = rxadc2.find_channel("voltage0_i")
    v5 = rxadc2.find_channel("voltage0_q")
    v6 = rxadc2.find_channel("voltage1_i")
    v7 = rxadc2.find_channel("voltage1_q")
    v4.enabled = True
    v5.enabled = True
    v6.enabled = True
    v7.enabled = True

    # Create buffer for RX data
    rxbuf1 = iio.Buffer(rxadc1, buf_len, False)
    rxbuf2 = iio.Buffer(rxadc2, buf_len, False)
    #
    # Enable single tone DDS
    dds0_tx1_1 = txdac1.find_channel('altvoltage0', True)
    dds2_tx1_1 = txdac1.find_channel('altvoltage2', True)
    dds0_tx1_2 = txdac1.find_channel('altvoltage8', True)
    dds2_tx1_2 = txdac1.find_channel('altvoltage10', True)

    dds0_tx2_1 = txdac2.find_channel('altvoltage0', True)
    dds2_tx2_1 = txdac2.find_channel('altvoltage2', True)
    dds0_tx2_2 = txdac2.find_channel('altvoltage8', True)
    dds2_tx2_2 = txdac2.find_channel('altvoltage10', True)

    # Turn all others off
    dds1_1 = txdac1.find_channel('altvoltage1', True)
    dds1_1.attrs['raw'].value = str(0)
    dds1_1.attrs['scale'].value = str(0)
    for r in range(3, 16):
        dds1_1 = txdac1.find_channel('altvoltage' + str(r), True)
        dds1_1.attrs['scale'].value = str(0)
        dds1_1.attrs['raw'].value = str(0)

    dds2_1 = txdac2.find_channel('altvoltage1', True)
    dds2_1.attrs['raw'].value = str(0)
    dds2_1.attrs['scale'].value = str(0)
    for r in range(3, 16):
        dds2_1 = txdac2.find_channel('altvoltage' + str(r), True)
        dds2_1.attrs['scale'].value = str(0)
        dds2_1.attrs['raw'].value = str(0)

    # Set frequency of enabled DDSs
    dds0_tx1_1.attrs['raw'].value = str(1)
    dds0_tx1_1.attrs['frequency'].value = str(DDS_Freq)
    dds0_tx1_1.attrs['scale'].value = str(0.5)
    dds0_tx1_1.attrs['phase'].value = str(90000)
    dds2_tx1_1.attrs['raw'].value = str(1)
    dds2_tx1_1.attrs['frequency'].value = str(DDS_Freq)
    dds2_tx1_1.attrs['scale'].value = str(0.5)
    dds2_tx1_1.attrs['phase'].value = str(0)

    dds0_tx2_1.attrs['raw'].value = str(1)
    dds0_tx2_1.attrs['frequency'].value = str(DDS_Freq)
    dds0_tx2_1.attrs['scale'].value = str(0.5)
    dds0_tx2_1.attrs['phase'].value = str(90000)
    dds2_tx2_1.attrs['raw'].value = str(1)
    dds2_tx2_1.attrs['frequency'].value = str(DDS_Freq)
    dds2_tx2_1.attrs['scale'].value = str(0.5)
    dds2_tx2_1.attrs['phase'].value = str(0)

    dds0_tx1_2.attrs['raw'].value = str(1)
    dds0_tx1_2.attrs['frequency'].value = str(DDS_Freq)
    dds0_tx1_2.attrs['scale'].value = str(0.5)
    dds0_tx1_2.attrs['phase'].value = str(90000)
    dds2_tx1_2.attrs['raw'].value = str(1)
    dds2_tx1_2.attrs['frequency'].value = str(DDS_Freq)
    dds2_tx1_2.attrs['scale'].value = str(0.5)
    dds2_tx1_2.attrs['phase'].value = str(0)

    dds0_tx2_2.attrs['raw'].value = str(1)
    dds0_tx2_2.attrs['frequency'].value = str(DDS_Freq)
    dds0_tx2_2.attrs['scale'].value = str(0.5)
    dds0_tx2_2.attrs['phase'].value = str(90000)
    dds2_tx2_2.attrs['raw'].value = str(1)
    dds2_tx2_2.attrs['frequency'].value = str(DDS_Freq)
    dds2_tx2_2.attrs['scale'].value = str(0.5)
    dds2_tx2_2.attrs['phase'].value = str(0)

    # Stop continuous sysref 1
    hmc7044_1_ext.reg_write(0x5, 0x2)
    hmc7044_1_car.reg_write(0x5, 0x42)
    hmc7044_1_car.reg_write(0x49, 0x0)
    hmc7044_1_car.reg_write(0x5a, 0x1)
    hmc7044_1.reg_write(0x49, 0x0)
    hmc7044_1.reg_write(0x5a, 0x1)
    hmc7044_1.reg_write(0x5, 0x43)
    hmc7044_1.reg_write(0x5, 0x83)

    # Stop continuous sysref 2
    # hmc7044_2_ext.reg_write(0x5, 0x2)
    hmc7044_2_car.reg_write(0x5, 0x42)
    hmc7044_2_car.reg_write(0x49, 0x0)
    hmc7044_2_car.reg_write(0x5a, 0x1)
    hmc7044_2.reg_write(0x49, 0x0)
    hmc7044_2.reg_write(0x5a, 0x1)
    hmc7044_2.reg_write(0x5, 0x43)
    hmc7044_2.reg_write(0x5, 0x83)

    # Collect data
    # reals0 = np.array([])
    # imags0 = np.array([])
    # reals1 = np.array([])
    # imags1 = np.array([])
    phase_error1 = np.array([])
    phase_error2 = np.array([])
    phase_error12 = np.array([])
    #raw_input("asd")
    # k = 0
    # while rxadc1.reg_read(0x80000068) == 0:
    #     rxadc1.reg_write(0x80000044, 0x8)
    #     if (k == 50):
    #         print("no HDL 1 sync")
    #         break
    #     k += 1
    # k = 0
    # while rxadc2.reg_read(0x80000068) == 0:
    #     rxadc2.reg_write(0x80000044, 0x8)
    #     if (k == 50):
    #         print("no HDL 2 sync")
    #         break
    #     k += 1

    for i in range(runs):

        k = 0
        while rxadc1.reg_read(0x80000068) == 0:
            rxadc1.reg_write(0x80000044, 0x8)
            if (k == 50):
                print("no HDL 1 sync")
                break
            k += 1

        k = 0
        while rxadc2.reg_read(0x80000068) == 0:
            rxadc2.reg_write(0x80000044, 0x8)
            if (k == 50):
                print("no HDL 2 sync")
                break
            k += 1

        hmc7044_1_ext.attrs["sysref_request"].value = str(1)
        rxbuf1.refill()
        rxbuf2.refill()

        #raw_input("asd")

        #hmc7044_1_ext.attrs["sysref_request"].value = str(1)

        data1 = rxbuf1.read()
        data2 = rxbuf2.read()

        x1 = np.frombuffer(data1, dtype=np.int16)
        x2 = np.frombuffer(data2, dtype=np.int16)
        # reals0 = np.append(reals0,x[::4])
        # imags0 = np.append(imags0,x[1::4])
        # reals1 = np.append(reals1,x[2::4])
        # imags1 = np.append(imags1,x[3::4])
        chan1 = x1[2::4] + 1j * x1[3::4]
        chan0 = x1[0::4] + 1j * x1[1::4]
        chan3 = x2[2::4] + 1j * x2[3::4]
        chan2 = x2[0::4] + 1j * x2[1::4]
        phase_error1 = np.append(phase_error1, measure_phase(chan0, chan1))
        phase_error2 = np.append(phase_error2, measure_phase(chan2, chan3))
        phase_error12 = np.append(phase_error12, measure_phase(chan0, chan2))
    # # Plot
    # if do_plots:
    #     plt.plot(phase_error)
    #     # plt.plot(reals0)
    #     # # plt.plot(imags0)
    #     # plt.plot(reals1)
    #     # # plt.plot(imags1)
    #     plt.xlabel("Samples")
    #     plt.ylabel("Amplitude [dbFS]")
    #     plt.show()
    return phase_error1, phase_error2, phase_error12