def dds_loopback(classname, devicename, param_set, channel, frequency, scale, peak_min): bi = BoardInterface(classname, devicename) # See if we can tone using DMAs sdr = eval(bi.classname + "(uri='" + bi.uri + "')") # Set custom device parameters for p in param_set.keys(): setattr(sdr, p, param_set[p]) # Set common buffer settings sdr.tx_cyclic_buffer = True N = 2 ** 14 # Create a sinewave waveform if hasattr(sdr, "sample_rate"): RXFS = int(sdr.sample_rate) else: RXFS = int(sdr.rx_sample_rate) sdr.rx_enabled_channels = [channel] sdr.rx_buffer_size = N * 2 * len(sdr.rx_enabled_channels) sdr.dds_single_tone(frequency, scale, channel) # Pass through SDR try: for _ in range(10): # Wait data = sdr.rx() except Exception as e: del sdr raise Exception(e) del sdr tone_peaks, tone_freqs = spec.spec_est(data, fs=RXFS, ref=2 ** 15) indx = np.argmax(tone_peaks) diff = np.abs(tone_freqs[indx] - frequency) print("Peak: " + str(tone_peaks[indx]) + "@" + str(tone_freqs[indx])) assert (frequency * 0.01) > diff assert tone_peaks[indx] > peak_min
def dds_loopback(uri, classname, param_set, channel, frequency, scale, peak_min): """ dds_loopback: Test DDS loopback with connected loopback cables. This test requires a devices with TX and RX onboard where the transmit signal can be recovered. TX FPGA DDSs are used to generate a sinusoid which is then estimated on the RX side. The receive tone must be within 1% of its expected frequency with a specified peak parameters: uri: type=string URI of IIO context of target board/system classname: type=string Name of pyadi interface class which contain attribute param_set: type=dict Dictionary of attribute and values to be set before tone is generated and received channel: type=list List of integers or list of list of integers of channels to enable through tx_enabled_channels frequency: type=integer Frequency in Hz of transmitted tone scale: type=float Scale of DDS tone. Range [0,1] peak_min: type=float Minimum acceptable value of maximum peak in dBFS of received tone """ # See if we can tone using DMAs sdr = eval(classname + "(uri='" + uri + "')") # Set custom device parameters for p in param_set.keys(): setattr(sdr, p, param_set[p]) # Set common buffer settings sdr.tx_cyclic_buffer = True N = 2**14 # Create a sinewave waveform if hasattr(sdr, "sample_rate"): RXFS = int(sdr.sample_rate) else: RXFS = int(sdr.rx_sample_rate) sdr.rx_enabled_channels = [channel] sdr.rx_buffer_size = N * 2 * len(sdr.rx_enabled_channels) sdr.dds_single_tone(frequency, scale, channel) # Pass through SDR try: for _ in range(10): # Wait data = sdr.rx() except Exception as e: del sdr raise Exception(e) del sdr tone_peaks, tone_freqs = spec.spec_est(data, fs=RXFS, ref=2**15) indx = np.argmax(tone_peaks) diff = np.abs(tone_freqs[indx] - frequency) print("Peak: " + str(tone_peaks[indx]) + "@" + str(tone_freqs[indx])) assert (frequency * 0.01) > diff assert tone_peaks[indx] > peak_min
def cw_loopback(classname, devicename, channel, param_set): bi = BoardInterface(classname, devicename) # See if we can tone using DMAs sdr = eval(bi.classname + "(uri='" + bi.uri + "')") # Set custom device parameters for p in param_set.keys(): setattr(sdr, p, param_set[p]) # Set common buffer settings sdr.tx_cyclic_buffer = True N = 2 ** 14 sdr.tx_enabled_channels = [channel] sdr.tx_buffer_size = N * 2 * len(sdr.tx_enabled_channels) sdr.rx_enabled_channels = [channel] sdr.rx_buffer_size = N * 2 * len(sdr.rx_enabled_channels) # Create a sinewave waveform if hasattr(sdr, "sample_rate"): RXFS = int(sdr.sample_rate) else: RXFS = int(sdr.rx_sample_rate) A = 2 ** 15 fc = RXFS * 0.1 ts = 1 / float(RXFS) t = np.arange(0, N * ts, ts) if sdr._complex_data: i = np.cos(2 * np.pi * t * fc) * A * 0.5 q = np.sin(2 * np.pi * t * fc) * A * 0.5 cw = i + 1j * q else: cw = np.cos(2 * np.pi * t * fc) * A * 1 # Pass through SDR try: sdr.tx(cw) for _ in range(30): # Wait to stabilize data = sdr.rx() except Exception as e: del sdr raise Exception(e) del sdr # tone_freq = freq_est(data, RXFS) # diff = np.abs(tone_freq - fc) # print("Peak: @"+str(tone_freq) ) # assert (fc * 0.01) > diff tone_peaks, tone_freqs = spec.spec_est(data, fs=RXFS, ref=A) indx = np.argmax(tone_peaks) diff = np.abs(tone_freqs[indx] - fc) print("Peak: " + str(tone_peaks[indx]) + "@" + str(tone_freqs[indx])) assert (fc * 0.01) > diff
def cw_loopback(uri, classname, channel, param_set, use_tx2=False, use_rx2=False): """cw_loopback: Test CW loopback with connected loopback cables. This test requires a devices with TX and RX onboard where the transmit signal can be recovered. Sinuoidal data is passed to DMAs which is then estimated on the RX side. The receive tone must be within 1% of its expected frequency at the max peak found parameters: uri: type=string URI of IIO context of target board/system classname: type=string Name of pyadi interface class which contain attribute channel: type=list List of integers or list of list of integers of channels to enable through tx_enabled_channels param_set: type=dict Dictionary of attribute and values to be set before tone is generated and received use_tx2: type=bool Boolean if set will use tx2() as tx method use_rx2: type=bool Boolean if set will use rx2() as rx method """ # See if we can tone using DMAs sdr = eval(classname + "(uri='" + uri + "')") # Set custom device parameters for p in param_set.keys(): setattr(sdr, p, param_set[p]) time.sleep(1) # Verify still set for p in param_set.keys(): if isinstance(param_set[p], str): assert getattr(sdr, p) == param_set[p] else: assert (np.argmax( np.abs(np.array(getattr(sdr, p)) - np.array(param_set[p]))) < 4) # Set common buffer settings N = 2**14 if use_tx2: sdr.tx2_cyclic_buffer = True sdr.tx2_enabled_channels = [channel] sdr.tx2_buffer_size = N * 2 * len(sdr.tx2_enabled_channels) else: sdr.tx_cyclic_buffer = True sdr.tx_enabled_channels = [channel] sdr.tx_buffer_size = N * 2 * len(sdr.tx_enabled_channels) if use_rx2: sdr.rx2_enabled_channels = [channel] sdr.rx2_buffer_size = N * 2 * len(sdr.rx2_enabled_channels) else: sdr.rx_enabled_channels = [channel] sdr.rx_buffer_size = N * 2 * len(sdr.rx_enabled_channels) # Create a sinewave waveform if hasattr(sdr, "sample_rate"): RXFS = int(sdr.sample_rate) elif hasattr(sdr, "rx_sample_rate"): RXFS = int(sdr.rx_sample_rate) else: """no sample_rate nor rx_sample_rate. Let's try something like rx($channel)_sample_rate""" attr = "rx" + str(channel) + "_sample_rate" RXFS = int(getattr(sdr, attr)) A = 2**15 fc = RXFS * 0.1 fc = int(fc / (RXFS / N)) * (RXFS / N) ts = 1 / float(RXFS) t = np.arange(0, N * ts, ts) if sdr._complex_data: i = np.cos(2 * np.pi * t * fc) * A * 0.5 q = np.sin(2 * np.pi * t * fc) * A * 0.5 cw = i + 1j * q else: cw = np.cos(2 * np.pi * t * fc) * A * 1 # Pass through SDR try: if use_tx2: sdr.tx2(cw) else: sdr.tx(cw) for _ in range(30): # Wait to stabilize data = sdr.rx2() if use_rx2 else sdr.rx() except Exception as e: del sdr raise Exception(e) del sdr # tone_freq = freq_est(data, RXFS) # diff = np.abs(tone_freq - fc) # print("Peak: @"+str(tone_freq) ) # assert (fc * 0.01) > diff tone_peaks, tone_freqs = spec.spec_est(data, fs=RXFS, ref=A) indx = np.argmax(tone_peaks) diff = np.abs(tone_freqs[indx] - fc) print("Peak: " + str(tone_peaks[indx]) + "@" + str(tone_freqs[indx])) assert (fc * 0.01) > diff
def nco_loopback(uri, classname, param_set, channel, frequency, peak_min): """nco_loopback: TX/DAC Test tone loopback with connected loopback cables. This test requires a devices with TX and RX onboard where the transmit signal can be recovered. TX/DAC internal NCOs are used to generate a sinusoid which is then estimated on the RX side. The receive tone must be within 1% of its expected frequency with a specified peak parameters: uri: type=string URI of IIO context of target board/system classname: type=string Name of pyadi interface class which contain attribute param_set: type=dict Dictionary of attribute and values to be set before tone is generated and received channel: type=list List of integers or list of list of integers of channels to enable through tx_enabled_channels frequency: type=integer Frequency in Hz of transmitted tone peak_min: type=float Minimum acceptable value of maximum peak in dBFS of received tone """ # See if we can tone using DMAs sdr = eval(classname + "(uri='" + uri + "')") # Set custom device parameters for p in param_set.keys(): setattr(sdr, p, param_set[p]) N = 2**14 sdr.rx_enabled_channels = [channel] sdr.rx_buffer_size = N * 2 * len(sdr.rx_enabled_channels) # Create a sinewave waveform if hasattr(sdr, "sample_rate"): RXFS = int(sdr.sample_rate) elif hasattr(sdr, "rx_sample_rate"): RXFS = int(sdr.rx_sample_rate) else: """no sample_rate nor rx_sample_rate. Let's try something like rx($channel)_sample_rate""" attr = "rx" + str(channel) + "_sample_rate" RXFS = int(getattr(sdr, attr)) # Pass through SDR try: for _ in range(10): # Wait data = sdr.rx() except Exception as e: del sdr raise Exception(e) del sdr tone_peaks, tone_freqs = spec.spec_est(data, fs=RXFS, ref=2**15) indx = np.argmax(tone_peaks) diff = np.abs(tone_freqs[indx] - frequency) s = "Peak: " + str(tone_peaks[indx]) + "@" + str(tone_freqs[indx]) print(s) if do_html_log: pytest.data_log = { "html": gen_line_plot_html( tone_freqs, tone_peaks, "Frequency (Hz)", "Amplitude (dBFS)", "{} ({})".format(s, classname), ) } assert (frequency * 0.01) > diff assert tone_peaks[indx] > peak_min
def dds_two_tone( uri, classname, channel, param_set, frequency1, scale1, peak_min1, frequency2, scale2, peak_min2, ): """ dds_two_tone: Test DDS loopback with connected loopback cables. This test requires a devices with TX and RX onboard where the transmit signal can be recovered. TX FPGA DDSs are used to generate two sinusoids which are then estimated on the RX side. The receive tones must be within 1% of its respective expected frequency with a specified peak. parameters: uri: type=string URI of IIO context of target board/system classname: type=string Name of pyadi interface class which contain attribute param_set: type=dict Dictionary of attribute and values to be set before tone is generated and received channel: type=list List of integers or list of list of integers of channels to enable through tx_enabled_channels frequency1: type=integer Frequency in Hz of the first transmitted tone scale1: type=float Scale of the first DDS tone. Range [0,1] peak_min1: type=float Minimum acceptable value of maximum peak in dBFS of the received first tone frequency2: type=integer Frequency in Hz of the second transmitted tone scale2: type=float Scale of the second DDS tone. Range [0,1] peak_min2: type=float Minimum acceptable value of maximum peak in dBFS of the received second tone """ # See if we can tone using DMAs sdr = eval(classname + "(uri='" + uri + "')") # Set custom device parameters for p in param_set.keys(): setattr(sdr, p, param_set[p]) # Set common buffer settings sdr.tx_cyclic_buffer = True N = 2**14 # Create a sinewave waveform if hasattr(sdr, "sample_rate"): RXFS = int(sdr.sample_rate) else: RXFS = int(sdr.rx_sample_rate) sdr.rx_enabled_channels = [channel] sdr.rx_buffer_size = N * 2 * len(sdr.rx_enabled_channels) sdr.dds_dual_tone(frequency1, scale1, frequency2, scale2, channel) # Pass through SDR try: for _ in range(10): # Wait data = sdr.rx() except Exception as e: del sdr raise Exception(e) del sdr tone_peaks, tone_freqs = spec.spec_est(data, fs=RXFS, ref=2**15) indx = heapq.nlargest(2, range(len(tone_peaks)), tone_peaks.__getitem__) s1 = "Peak 1: " + str(tone_peaks[indx[0]]) + " @ " + str( tone_freqs[indx[0]]) s2 = "Peak 2: " + str(tone_peaks[indx[1]]) + " @ " + str( tone_freqs[indx[1]]) print(s1) print(s2) if do_html_log: pytest.data_log = { "html": gen_line_plot_html( tone_freqs, tone_peaks, "Frequency (Hz)", "Amplitude (dBFS)", "{}\n{} ({})".format(s1, s2, classname), ) } if (abs(frequency1 - tone_freqs[indx[0]]) <= (frequency1 * 0.01)) and (abs(frequency2 - tone_freqs[indx[1]]) <= (frequency2 * 0.01)): diff1 = np.abs(tone_freqs[indx[0]] - frequency1) diff2 = np.abs(tone_freqs[indx[1]] - frequency2) # print(frequency1, frequency2) # print(tone_freqs[indx[0]], tone_freqs[indx[1]]) # print(tone_peaks[indx[0]], tone_peaks[indx[1]]) # print(diff1, diff2) assert (frequency1 * 0.01) > diff1 assert (frequency2 * 0.01) > diff2 assert tone_peaks[indx[0]] > peak_min1 assert tone_peaks[indx[1]] > peak_min2 elif (abs(frequency2 - tone_freqs[indx[0]]) <= (frequency2 * 0.01)) and (abs(frequency1 - tone_freqs[indx[1]]) <= (frequency1 * 0.01)): diff1 = np.abs(tone_freqs[indx[0]] - frequency2) diff2 = np.abs(tone_freqs[indx[1]] - frequency1) assert (frequency2 * 0.01) > diff1 assert (frequency1 * 0.01) > diff2 assert tone_peaks[indx[1]] > peak_min1 assert tone_peaks[indx[0]] > peak_min2
def cw_loopback(uri, classname, channel, param_set): # See if we can tone using DMAs sdr = eval(classname + "(uri='" + uri + "')") # Set custom device parameters for p in param_set.keys(): setattr(sdr, p, param_set[p]) time.sleep(1) # Verify still set for p in param_set.keys(): if isinstance(param_set[p], str): assert getattr(sdr, p) == param_set[p] else: assert np.abs(getattr(sdr, p) - param_set[p]) < 4 # Set common buffer settings sdr.tx_cyclic_buffer = True N = 2**14 sdr.tx_enabled_channels = [channel] sdr.tx_buffer_size = N * 2 * len(sdr.tx_enabled_channels) sdr.rx_enabled_channels = [channel] sdr.rx_buffer_size = N * 2 * len(sdr.rx_enabled_channels) # Create a sinewave waveform if hasattr(sdr, "sample_rate"): RXFS = int(sdr.sample_rate) elif hasattr(sdr, "rx_sample_rate"): RXFS = int(sdr.rx_sample_rate) else: """ no sample_rate nor rx_sample_rate. Let's try something like rx($channel)_sample_rate""" attr = "rx" + str(channel) + "_sample_rate" RXFS = int(getattr(sdr, attr)) A = 2**15 fc = RXFS * 0.1 ts = 1 / float(RXFS) t = np.arange(0, N * ts, ts) if sdr._complex_data: i = np.cos(2 * np.pi * t * fc) * A * 0.5 q = np.sin(2 * np.pi * t * fc) * A * 0.5 cw = i + 1j * q else: cw = np.cos(2 * np.pi * t * fc) * A * 1 # Pass through SDR try: sdr.tx(cw) for _ in range(30): # Wait to stabilize data = sdr.rx() except Exception as e: del sdr raise Exception(e) del sdr # tone_freq = freq_est(data, RXFS) # diff = np.abs(tone_freq - fc) # print("Peak: @"+str(tone_freq) ) # assert (fc * 0.01) > diff tone_peaks, tone_freqs = spec.spec_est(data, fs=RXFS, ref=A) indx = np.argmax(tone_peaks) diff = np.abs(tone_freqs[indx] - fc) print("Peak: " + str(tone_peaks[indx]) + "@" + str(tone_freqs[indx])) assert (fc * 0.01) > diff