def testAD9361ADC(self): # See if we can get non-zero data from AD9361 global URI sdr = ad9361(uri=URI) data = sdr.rx() s = np.sum(np.abs(data)) del sdr self.assertGreater(s, 0, "check non-zero data")
def testAD9361GainControlCheck(self): # See if we can get non-zero data from AD9361 global URI sdr = ad9361(uri=URI) sdr.gain_control_mode_chan0 = "manual" current_gain = sdr.rx_hardwaregain_chan0 if current_gain == 73: next_gain = 70 else: next_gain = current_gain + 1 sdr.rx_hardwaregain_chan0 = next_gain updated_gain = sdr.rx_hardwaregain_chan0 del sdr self.assertNotEqual(current_gain, next_gain, "Gain not updating") self.assertNotEqual(current_gain, updated_gain, "Gain not updating") self.assertEqual(next_gain, updated_gain, "Gain not updating")
def testAD9361DAC(self): # See if we can tone from AD9361 using DMAs global URI sdr = ad9361(uri=URI) sdr.tx_lo = 1000000000 sdr.rx_lo = 1000000000 sdr.tx_cyclic_buffer = True sdr.tx_hardwaregain_chan0 = -30 sdr.gain_control_mode_chan0 = "slow_attack" sdr.rx_buffer_size = 2 ** 20 sdr.sample_rate = 4000000 # Create a sinewave waveform RXFS = int(sdr.sample_rate) fc = RXFS * 0.1 N = 2 ** 14 ts = 1 / float(RXFS) t = np.arange(0, N * ts, ts) i = np.cos(2 * np.pi * t * fc) * 2 ** 15 * 0.5 q = np.sin(2 * np.pi * t * fc) * 2 ** 15 * 0.5 iq = i + 1j * q # Pass through SDR sdr.tx([iq, iq * 0.0]) for _ in range(30): # Wait for IQ correction to stabilize data = sdr.rx() tone_freq = self.freq_est(data[0], RXFS) # if self.do_plots: # import matplotlib.pyplot as plt # # reals = np.real(data) # plt.plot(reals) # imags = np.imag(data) # plt.plot(imags) # plt.xlabel("Samples") # plt.ylabel("Amplitude [dbFS]") # plt.show() diff = np.abs(tone_freq - fc) del sdr self.assertGreater(fc * 0.01, diff, "Frequency offset")
# re = np.zeros(dat.shape, dtype = np.int16) # im = re.copy() # split into real and imag # for i in range(dat.shape[0]): # re[i] = 0xffff & (dat[i] >> 16) # im[i] = 0xffff & (dat[i]) # print("Split data into re and im") # recombine into complex datastream # data = re + 1j*im # print("Created complex IQ stream") data = np.load('bb_out.npy') print("Loaded data") # sys.exit(0) # initialize radio sdr = adi.ad9361('local:') print("Started radio") sdr.filter = '/home/sunip/modem_filter.ftr' print("Loaded filter") sdr.sample_rate = int(10e6) # 20 MHz sdr.tx_rf_bandwidth = int(10e6) sdr.tx_lo = int(2.5e9) # 2.4 GHz sdr.rx_lo = int(2.4e9) sdr.tx_cyclic_buffer = True sdr.tx_hardwaregain = 0 sdr.tx([data, data]) print("Transmission started, press Ctrl + C to exit") signal.pause() # wait for release sdr.tx_destroy_buffer()
def __init__(self, IP=[192, 168, 0, 3], LO_freq=2400000000, TX_freq=5810000000, SampleRate=3000000, Rx_gain=30, Averages=1, Taper=1, SymTaper=0, PhaseCal=0, ScanMaxAngle=0, Error_Threshold=0.1, SignalFreq=10525000000, RxGain1=127, RxGain2=127, RxGain3=127, RxGain4=127, Rx1_cal=0, Rx2_cal=0, Rx3_cal=0, Rx4_cal=0, RxGain5=127, RxGain6=127, RxGain7=127, RxGain8=127, Rx5_cal=0, Rx6_cal=0, Rx7_cal=0, Rx8_cal=0): """arguments to this function show up as parameters in GRC""" gr.sync_block.__init__( self, name='ADAR1000 Sweeper', # will show up in GRC in_sig=[], #out_sig=[np.complex64, np.complex64, np.complex64, np.complex64, np.float32] out_sig=[np.float32, np.float32]) # if an attribute with the same name as a parameter is found, # a callback is registered (properties work, too). #sdr_address = 'ip:192.168.0.4' sdr_address = "ip:" + str(IP[0]) + "." + str(IP[1]) + "." + str( IP[2] ) + "." + str( IP[3] ) # I couldn't get GNUradio to import the IP address from the flowgraph block as a string.... Not sure why. So I broke it up into integers self.LO_freq = LO_freq # RX LO freq self.TX_freq = TX_freq # TX LO freq self.SampleRate = SampleRate self.Rx_gain = Rx_gain self.Averages = Averages self.Taper = Taper self.SymTaper = SymTaper self.PhaseCal = PhaseCal self.RxGain1 = RxGain1 self.RxGain2 = RxGain2 self.RxGain3 = RxGain3 self.RxGain4 = RxGain4 self.RxGain5 = RxGain5 self.RxGain6 = RxGain6 self.RxGain7 = RxGain7 self.RxGain8 = RxGain8 self.Rx1_cal = Rx1_cal self.Rx2_cal = Rx2_cal self.Rx3_cal = Rx3_cal self.Rx4_cal = Rx4_cal self.Rx5_cal = Rx5_cal self.Rx6_cal = Rx6_cal self.Rx7_cal = Rx7_cal self.Rx8_cal = Rx8_cal self.spi = spidev.SpiDev() self.spi.open(0, 0) #set bus=0 and device=0 self.spi.max_speed_hz = 500000 self.spi.mode = 0 # The ADDR is set by the address pins on the ADAR1000. This is set by P10 on the eval board. self.ADDR1 = 0x20 # ADDR 0x20 is set by jumpering pins 4 and 6 on P10 #self.ADDR1=0x00 # ADDR 0x00 is set by leaving all jumpers off of P10 self.ADDR2 = 0x40 ADAR_init(self.spi, self.ADDR1) ADAR_init(self.spi, self.ADDR2) self.c = 299792458 # speed of light in m/s self.d = 0.015 # element to element spacing of the antenna self.SignalFreq = SignalFreq self.ScanMaxAngle = ScanMaxAngle self.PeakPhaseDelta = 0 self.Error_Threshold = Error_Threshold self.loop_count = 0 self.buffer_array = [] for i in range(0, 4000): self.buffer_array.append(0) # array of zeros '''Setup SDR Context and Configure Settings''' #self.sdr=adi.ad9361(uri='ip:192.168.0.3') self.sdr = adi.ad9361(uri=sdr_address) self.sdr._ctrl.debug_attrs[ "adi,frequency-division-duplex-mode-enable"].value = "1" # move to fdd mode. see https://github.com/analogdevicesinc/pyadi-iio/blob/ensm-example/examples/ad9361_advanced_ensm.py self.sdr._ctrl.debug_attrs[ "adi,ensm-enable-txnrx-control-enable"].value = "0" # Disable pin control so spi can move the states self.sdr._ctrl.debug_attrs["initialize"].value = "1" self.sdr._rxadc.set_kernel_buffers_count( 1 ) #Default is 4 Rx buffers are stored, but we want to change and immediately measure the result, so buffers=1 rx = self.sdr._ctrl.find_channel('voltage0') rx.attrs[ 'quadrature_tracking_en'].value = '0' # set to '1' to enable quadrature tracking self.sdr.rx_enabled_channels = [ 0, 1 ] # enable both Rx1 (voltage0) and Rx2 (voltage1) self.sdr.sample_rate = int(self.SampleRate) #self.sdr.filter = "/home/pi/Documents/PlutoFilters/samprate_40p0.ftr" #pyadi-iio auto applies filters based on sample rate #self.sdr.rx_rf_bandwidth = int(1000000) #self.sdr.tx_rf_bandwidth = int(500000) self.sdr.gain_control_mode_chan0 = 'manual' #We must be in manual gain control mode (otherwise we won't see the peaks and nulls!) self.sdr.gain_control_mode_chan1 = 'manual' #We must be in manual gain control mode (otherwise we won't see the peaks and nulls!) self.sdr.rx_buffer_size = int( 1024 ) # We only need a few samples to get the gain. And a small buffer will greatly speed up the sweep self.sdr.tx_hardwaregain_chan0 = -80 # Make sure the Tx channels are attenuated (or off) and their freq is far away from Rx self.sdr.tx_hardwaregain_chan1 = -80 self.sdr.tx_lo = int(1000000000) print(self.sdr)
import adi # This example shows how to navigate between FDD and TDD modes using debug attributes for AD936X devices sdr = adi.ad9361(uri="ip:analog") # Initial stage print("Initial ensm_mode:", sdr._ctrl.attrs["ensm_mode"].value) # Get to TDD mode sdr._ctrl.debug_attrs["adi,frequency-division-duplex-mode-enable"].value = "0" sdr._ctrl.debug_attrs["initialize"].value = "1" print("ensm_mode_available:", sdr._ctrl.attrs["ensm_mode_available"].value) print("Current ensm:", sdr._ctrl.attrs["ensm_mode"].value) # Get to FDD mode sdr._ctrl.debug_attrs["adi,frequency-division-duplex-mode-enable"].value = "1" # Disable pin control so spi can move the states sdr._ctrl.debug_attrs["adi,ensm-enable-txnrx-control-enable"].value = "0" sdr._ctrl.debug_attrs["initialize"].value = "1" print("ensm_mode_available:", sdr._ctrl.attrs["ensm_mode_available"].value) print("Current ensm:", sdr._ctrl.attrs["ensm_mode"].value)
def test_ad9361(iio_uri): dev = adi.ad9361(iio_uri) assert dev del dev
# IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY # RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import time import adi import matplotlib.pyplot as plt import numpy as np from scipy import signal # Create radio sdr = adi.ad9361(uri="ip:analog.local") # Configure properties sdr.rx_rf_bandwidth = 4000000 sdr.sample_rate = 6000000 sdr.rx_lo = 2000000000 sdr.tx_lo = 2000000000 sdr.tx_cyclic_buffer = True sdr.tx_hardwaregain_chan0 = -30 sdr.gain_control_mode_chan0 = "slow_attack" # Configuration data channels sdr.rx_enabled_channels = [0] sdr.tx_enabled_channels = [0] # Read properties