Commit af6a6ef3 authored by Oscar Bejarano's avatar Oscar Bejarano

Minor bug fixes/additions


Former-commit-id: 5b24901671539c03887cea4575125fffdcdd9b9c
parent 4d50572c
from matplotlib import animation
class MyFuncAnimation(animation.FuncAnimation):
"""
Unfortunately, it seems that the _blit_clear method of the Animation
class contains an error in several matplotlib verions
That's why, I fork it here and insert the latest git version of
the function.
"""
def _blit_clear(self, artists, bg_cache):
# Get a list of the axes that need clearing from the artists that
# have been drawn. Grab the appropriate saved background from the
# cache and restore.
axes = set(a.axes for a in artists)
for a in axes:
if a in bg_cache: # this is the previously missing line
a.figure.canvas.restore_region(bg_cache[a])
\ No newline at end of file
......@@ -155,6 +155,7 @@ def tx_thread(sdr, rate, txStream, rxStream, waveTx, numSamps, numSyms, txSymNum
if txSymNum == 0:
continue
sr = sdr.readStream(rxStream, [waveRxA, waveRxB], numSamps)
print("CL: readStream returned %d" % sr.ret)
if sr.ret > 0:
txTime = sr.timeNs & 0xFFFFFFFF00000000
txTime += (0x000000000 + (startSymbol << 16))
......@@ -178,11 +179,12 @@ def tx_thread(sdr, rate, txStream, rxStream, waveTx, numSamps, numSyms, txSymNum
def rx_thread(sdr, rxStream, numSamps, txSymNum, both_channels):
global running
fip = open('data_out/rxpilot_sounder.bin', 'wb')
fid = open('data_out/rxdata_sounder.bin', 'wb')
cwd = os.getcwd()
fip = open(cwd + '/data_out/rxpilot_sounder.bin', 'wb')
fid = open(cwd + '/data_out/rxdata_sounder.bin', 'wb')
if both_channels:
fip2 = open('data_out/rxpilotB_sounder.bin', 'wb')
fid2 = open('data_out/rxdataB_sounder.bin', 'wb')
fip2 = open(cwd + '/data_out/rxpilotB_sounder.bin', 'wb')
fid2 = open(cwd + '/data_out/rxdataB_sounder.bin', 'wb')
rxFrNum = 0
pilotSymNum = 2 if both_channels else 1
waveRxA = np.array([0]*numSamps, np.uint32)
......@@ -198,15 +200,16 @@ def rx_thread(sdr, rxStream, numSamps, txSymNum, both_channels):
# print("LNA: {}, \t TIA:{}, \t PGA:{}".format(readLNA, readTIA, readPGA))
for j in range(pilotSymNum):
sr = sdr.readStream(rxStream, [waveRxA, waveRxB], numSamps)
print("BS: readStream returned %d" % sr.ret)
if sr.ret < 0 or sr.ret > numSamps:
print("readStream returned %d"%sr.ret)
print("BS - BAD: readStream returned %d"%sr.ret)
for i, a in enumerate(waveRxA):
pickle.dump(a, fip)
if both_channels: pickle.dump(waveRxB[i], fip2)
for j in range(txSymNum):
sr = sdr.readStream(rxStream, [waveRxA, waveRxB], numSamps)
if sr.ret < 0 or sr.ret > numSamps:
print("readStream returned %d"%sr.ret)
print("BS: readStream returned %d"%sr.ret)
for i, a in enumerate(waveRxA):
pickle.dump(a, fid)
if both_channels: pickle.dump(waveRxB[i], fid2)
......@@ -512,8 +515,8 @@ def main():
parser.add_option("--serial1", type="string", dest="serial1", help="serial number of the master device", default="RF3C000042")
parser.add_option("--serial2", type="string", dest="serial2", help="serial number of the slave device", default="RF3C000025")
parser.add_option("--rate", type="float", dest="rate", help="Tx sample rate", default=5e6)
parser.add_option("--txgain", type="float", dest="txgain", help="Optional Tx gain (dB)", default=20.0)
parser.add_option("--rxgain", type="float", dest="rxgain", help="Optional Rx gain (dB) - only used if agc disabled", default=28.0)
parser.add_option("--txgain", type="float", dest="txgain", help="Optional Tx gain (dB)", default=25.0)
parser.add_option("--rxgain", type="float", dest="rxgain", help="Optional Rx gain (dB) - only used if agc disabled", default=30.0)
parser.add_option("--freq", type="float", dest="freq", help="Optional Tx freq (Hz)", default=3.6e9)
parser.add_option("--numSamps", type="int", dest="numSamps", help="Num samples to receive", default=512)
parser.add_option("--prefix-length", type="int", dest="prefix_length", help="prefix padding length for beacon and pilot", default=82) # to comprensate for front-end group delay
......@@ -524,7 +527,7 @@ def main():
parser.add_option("--ue-tx-advance", type="int", dest="tx_advance", help="sample advance for tx vs rx", default=68)
parser.add_option("--both-channels", action="store_true", dest="both_channels", help="transmit from both channels", default=False)
parser.add_option("--calibrate", action="store_true", dest="calibrate", help="transmit from both channels", default=False)
parser.add_option("--use-trig", action="store_true", dest="use_trig", help="uses chain triggers for synchronization", default=False)
parser.add_option("--use-trig", action="store_true", dest="use_trig", help="uses chain triggers for synchronization", default=True)
parser.add_option("--wait-trigger", action="store_true", dest="wait_trigger", help="wait for a trigger to start a frame", default=False)
parser.add_option("--auto-tx-gain", action="store_true", dest="auto_tx_gain", help="automatically go over tx gains", default=False)
parser.add_option("--record", action="store_true", dest="record", help="record received pilots and data", default=True)
......
aa25b4fba59249680b1b03170a96bd49ca4765b6
\ No newline at end of file
......@@ -21,50 +21,56 @@ def setUpDigitalRssiMode(sdr):
# Select chain to read from (A or B)
# Enable SPI read/write chain A
# write(name, address, value)
sdr.writeRegister("LMS7IC", 0x0020, sdr.readRegister("LMS7IC", 0x0020) & 0xFFFE) # clear
sdr.writeRegister("LMS7IC", 0x0020, sdr.readRegister("LMS7IC", 0x0020) & 0xFFFC) # clear
sdr.writeRegister("LMS7IC", 0x0020, sdr.readRegister("LMS7IC", 0x0020) | 0x0001) # write
# Don't bypass AGC module - 0x040C[6] = 0
sdr.writeRegister("LMS7IC", 0x040C, sdr.readRegister("LMS7IC", 0x040C) & 0xFFBF)
# Set AGC mode to RSSI - 0x040A[13:12] = 1
sdr.writeRegister("LMS7IC", 0x040A, sdr.readRegister("LMS7IC", 0x040A) & 0xCFFF) # clear
sdr.writeRegister("LMS7IC", 0x040A, sdr.readRegister("LMS7IC", 0x040A) | 0x1000) # write
def getDigitalRSSI(sdr, agc_avg):
"""
Read the digital RSSI registers (18-bits total)
agc_avg: Should be a value between 0 and 7. The system takes a window of 2^(agc_avg+7) samples
Return: digital RSSI value and Power in dBm
"""
# Set RSSI Mode to Normal operation (default) - 0x040A[15:14] = 0
sdr.writeRegister("LMS7IC", 0x040A, sdr.readRegister("LMS7IC", 0x040A) & 0x3FFF) # clear
# Select RSSI value to be captured into 0x040E, 0x040F registers - 0x0400[14:13] = 0
sdr.writeRegister("LMS7IC", 0x0400, sdr.readRegister("LMS7IC", 0x0400) & 0x9FFF)
# Select how many samples will be used to calculate RSSI - 0x040A[2:0] = any value from 0 to 7
# Set to 3: Clear:0xFFF8 Write:0x0003
# Set to 1: Clear:0xFFF8 Write:0x0001
# Set to 0: Clear:0xFFF8 Write:0x0000
# from 2^7 to 2^14 samples
sdr.writeRegister("LMS7IC", 0x040A, sdr.readRegister("LMS7IC", 0x040A) & 0xFFF8) # clear
sdr.writeRegister("LMS7IC", 0x040A, sdr.readRegister("LMS7IC", 0x040A) | agc_avg) # write
sdr.writeRegister("LMS7IC", 0x040A, sdr.readRegister("LMS7IC", 0x040A) | 0x0003) # write
def getDigitalRSSI(sdr, agc_avg):
"""
Read the digital RSSI registers (18-bits total)
agc_avg: NO LONGER NEEDED - Should be a value between 0 and 7. The system takes a window of 2^(agc_avg+7) samples
Return: digital RSSI value and Power in dBm
"""
# Trigger read (trigger rising edge of CAPTURE) - 0x0400[15] = 0 then 0x0400[15] = 1 1100
sdr.writeRegister("LMS7IC", 0x0400, sdr.readRegister("LMS7IC", 0x0400) & 0x7FFF) # clear
time.sleep(.1)
time.sleep(.01)
sdr.writeRegister("LMS7IC", 0x0400, sdr.readRegister("LMS7IC", 0x0400) | 0x8000) # write
# Read Digital RSSI samples (peak voltage: sqrt(I^2 + Q^2))
rssi = (sdr.readRegister("LMS7IC", 0x040F) << 2) | (
sdr.readRegister("LMS7IC", 0x040E) & 0x3)
rssi = ((sdr.readRegister("LMS7IC", 0x040F) << 2) | (
sdr.readRegister("LMS7IC", 0x040E) & 0x3)) & 0x3FFFF
Vrms = (rssi / 2.0 ** 18) * (1 / np.sqrt(2.0)) # Vrms = Vpeak/sqrt(2) (In Volts)
PWRrms = (Vrms ** 2.0) / 50.0 # 50 Ohms load (PWRrms in Watts)
PWRdBm = 10.0 * np.log10(PWRrms) + 30 # P(dBm)=10*log10(Prms/1mW) OR P(dBm)=10*log10(Prms)+30
# Vrms = (rssi / 2.0 ** 18) * (1 / np.sqrt(2.0)) # Vrms = Vpeak/sqrt(2) (In Volts)
# PWRrms = (Vrms ** 2.0) / 50.0 # 50 Ohms load (PWRrms in Watts) UNKNOWN!!!
# PWRdBm = 10.0 * np.log10(PWRrms) + 30 # P(dBm)=10*log10(Prms/1mW) OR P(dBm)=10*log10(Prms)+30
# PWRdBm = 20*np.log10(rssi / 90100.0) ## NOTE: in dBFs (max RSSI according to LimeSuite)
return rssi, PWRdBm
maxRSSI = 0x15FF4
if rssi == 0:
rssi = 1
rssi_pwr_dBFs = 20 * np.log10(float(rssi)/maxRSSI) # NOTE: in dBFs (max RSSI according to LimeSuite)
return rssi, rssi_pwr_dBFs
def main():
setUpDigitalRssiMode()
agc_avg = 3
rssi, PWRdBm = getDigitalRSSI(agc_avg)
print("RSSI: " + str(rssi) + " PWRdBm: " + str(PWRdBm))
rssi, PWRdBFS = getDigitalRSSI(agc_avg)
print("RSSI: " + str(rssi) + " PWRdBm: " + str(PWRdBFS))
if __name__ == '__main__':
......
......@@ -159,7 +159,7 @@ class ofdmTxRx:
(1 * ((abs(np.imag(iq)) < 0.9258) and (abs(np.imag(iq)) > 0.3086)))
return val
def generate_data(self, n_ofdm_syms=100, mod_order=4, cp_length=16):
def generate_data(self, n_ofdm_syms=100, mod_order=4, cp_length=16, datastream=[]):
"""
Generate random data stream of n_ofdm_syms number of symbols,
and modulate according to mod_order.
......@@ -187,7 +187,14 @@ class ofdmTxRx:
list(range(38, 43)) + list(range(44, 57)) + list(range(58, 64))
pilot_subcarriers = [7, 21, 43, 57]
n_data_syms = n_ofdm_syms * len(data_subcarriers) # One data sym per data-subcarrier per ofdm symbol
data_i = [random.randint(0, mod_order-1) for i in range(n_data_syms)] # includes end-points
if not datastream:
data_i = [random.randint(0, mod_order-1) for i in range(n_data_syms)] # includes end-points
else:
# Prepend datastream to rest of randomly generated data symbols
data_i_tmp = [random.randint(0, mod_order-1) for i in range(n_data_syms-len(datastream))]
data_i = np.concatenate((datastream, data_i_tmp))
data = np.zeros(len(data_i), dtype=complex)
for x in range(len(data_i)):
......
......@@ -23,6 +23,9 @@
import pickle
import sys
sys.path.append('../DEMOS/data_out/')
import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt
......
......@@ -46,4 +46,25 @@ def cfloat2uint32(arr, order='IQ'):
if order == 'IQ':
return np.bitwise_or(arr_q, np.left_shift(arr_i.astype(np.uint32), 16))
else:
return np.bitwise_or(arr_i, np.left_shift(arr_q.astype(np.uint32), 16))
\ No newline at end of file
return np.bitwise_or(arr_i, np.left_shift(arr_q.astype(np.uint32), 16))
def bin_to_int(val, nbits):
"""
Compute the two's complement of integer value
"""
# If sign bit is 1 => negative value
if (val & (1 << (nbits - 1))) != 0:
val = val - (1 << nbits)
# If positive, do nothing
return val
def int_to_bin(val, nbits):
"""
Convert int to a binary string
"""
# Mask value to 'nbits' number of bits and remove '0b' prefix
s = bin(val & int("1"*nbits, 2))[2:]
binstr = ("{0:0>%s}" % nbits).format(s)
return binstr
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment