...
 
Commits (18)
This diff is collapsed.
{
"BaseStations" : {
"cells" : 1,
"sdr_id" : ["files/iris_serials.txt"],
"hub_id" : "files/hub_serials.txt",
"frequency" : 3.6e9,
"polarization" : "single",
"rxgainA" : 20,
......@@ -7,21 +10,18 @@
"rxgainB" : 20,
"txgainB" : 40,
"rate" : 5e6,
"fft_size" : 64,
"frame_schedule" : [
"BGPPGGGGGGGGGGGGGGGG"
],
"subframe_size" : 400,
"fft_size" : 64,
"cp_size" : 16,
"prefix" : 82,
"postfix" : 68,
"frame_schedule" : [
"BGPPUGGGGGGGGGGGGGGG"
],
"pilot_seq" : "lts",
"beacon_seq" : "gold_ifft",
"beamsweep" : false,
"beacon_antenna" : 0,
"cells" : 1,
"sdr_id" : ["conf/iris_serials.txt"],
"hub_id" : "conf/hub_serials.txt"
"pilot_seq" : "lts"
}
}
......@@ -12,6 +12,7 @@
#define CONFIG_HEADER
#include <algorithm>
#include <stdexcept>
#include <vector>
#include <iostream>
#include <complex.h>
......@@ -77,13 +78,28 @@ public:
int clSdrCh;
bool clAgcEn;
std::string clDataMod;
std::vector<int> data_ind;
std::vector<uint32_t> coeffs;
std::vector<std::complex<int16_t>> coeffs_ci16;
std::vector<uint32_t> beacon;
std::vector<std::complex<int16_t>> beacon_ci16;
std::vector<std::complex<int16_t>> pilot_ci16;
std::vector<uint32_t> pilot;
std::vector<std::vector<int>> pilot_sc;
std::vector<std::vector<double>> pilot_double;
std::vector<std::vector<std::complex<float>>> txdata;
std::vector<std::vector<std::complex<float>>> txdata_freq_dom;
std::vector<std::string> clFrames;
std::vector<std::vector<size_t>> clPilotSymbols;
std::vector<std::vector<size_t>> clULSymbols;
std::vector<std::vector<size_t>> clDLSymbols;
// TODO clients gain can be set for each separately
double clTxgainA;
double clRxgainA;
double clTxgainB;
double clRxgainB;
const int maxFrame = 1 << 31;
const int data_offset = sizeof(int) * 4;
......
......@@ -45,6 +45,11 @@ struct SocketBuffer
std::vector<int> buffer_status;
};
//std::atomic_int thread_count(0);
//std::mutex d_mutex;
//std::condition_variable cond;
class Receiver
{
public:
......@@ -56,6 +61,23 @@ public:
int tid;
};
struct dev_profile
{
int tid;
int nsamps;
int txSyms;
int rxSyms;
int txStartSym;
unsigned txFrameDelta;
double rate;
SoapySDR::Device * device;
SoapySDR::Stream * rxs;
SoapySDR::Stream * txs;
std::string data_file;
int core;
Receiver *ptr;
};
public:
Receiver(int N_THREAD, Config *cfg);
Receiver(int N_THREAD, Config *cfg, moodycamel::ConcurrentQueue<Event_data> * in_queue);
......@@ -63,7 +85,7 @@ public:
std::vector<pthread_t> startRecv(void** in_buffer, int** in_buffer_status, int in_buffer_frame_num, int in_buffer_length, int in_core_id=0);
static void* loopRecv(void *context);
static void* clientTxRx(void *context);
private:
Config *config_;
struct sockaddr_in servaddr_; /* server address */
......
......@@ -20,6 +20,9 @@
#include <math.h>
#include <ctime>
#include <algorithm>
#include <string>
#include <sstream>
#include <complex>
#include "hdf5.h"
#include "H5Cpp.h"
#include "receiver.h"
......
......@@ -27,6 +27,9 @@ public:
void reciprocityCalProcedure(std::vector<void *> &tx, std::vector<void *> &rx);
void sampleDelayCalibrate();
~RadioConfig();
std::vector<SoapySDR::Device *> devs;
std::vector<SoapySDR::Stream *> rxss;
std::vector<SoapySDR::Stream *> txss;
private:
Config *_cfg;
std::vector<SoapySDR::Device *> hubs;
......@@ -41,6 +44,8 @@ private:
std::vector<std::complex<int16_t>> buff;
std::vector<int> nBsSdrs;
std::vector<int> nBsAntennas;
int nClSdrs;
int nClAntennas;
};
This diff is collapsed.
......@@ -11,6 +11,7 @@
#include "include/receiver.h"
static sig_atomic_t loopDone = false;
Receiver::Receiver(int N_THREAD, Config *cfg)
{
......@@ -20,7 +21,7 @@ Receiver::Receiver(int N_THREAD, Config *cfg)
thread_num_ = N_THREAD;
/* initialize random seed: */
srand (time(NULL));
context = new ReceiverContext[thread_num_];
if (thread_num_ > 0) context = new ReceiverContext[thread_num_];
}
......@@ -51,24 +52,60 @@ std::vector<pthread_t> Receiver::startRecv(void** in_buffer, int** in_buffer_sta
core_id_ = in_core_id;
radioconfig_->radioStart();
std::vector<pthread_t> client_threads;
if (config_->clPresent)
{
double frameTime = config_->sampsPerSymbol*config_->clFrames[0].size()*1e3/config_->rate; // miliseconds
unsigned frameTimeDelta = (unsigned)(std::ceil(TIME_DELTA/frameTime));
std::cout << "Frame time delta " << frameTimeDelta << std::endl;
for(int i = 0; i < config_->nClSdrs; i++)
{
pthread_t cl_thread_;
// record the thread id
dev_profile *profile = (dev_profile *)malloc(sizeof(dev_profile));
profile->tid = i;
profile->rate = config_->rate;
profile->nsamps = config_->sampsPerSymbol;
profile->txSyms = config_->clULSymbols[i].size();
profile->rxSyms = config_->clDLSymbols[i].size();
profile->txStartSym = config_->clULSymbols[i].size() > 0 ? config_->clULSymbols[i][0] : 0;
profile->txFrameDelta = frameTimeDelta;
profile->device = radioconfig_->devs[i];
profile->rxs = radioconfig_->rxss[i];
profile->txs = radioconfig_->txss[i];
profile->core = 1+i+1+SOCKET_THREAD_NUM+TASK_THREAD_NUM;
profile->ptr = this;
// start socket thread
if(pthread_create( &cl_thread_, NULL, Receiver::clientTxRx, (void *)(profile) ) != 0)
{
perror("socket client thread create failed");
exit(0);
}
client_threads.push_back(cl_thread_);
}
}
printf("start Recv thread\n");
// new thread
std::vector<pthread_t> created_threads;
for(int i = 0; i < thread_num_; i++)
if (config_->bsPresent)
{
pthread_t recv_thread_;
// record the thread id
context[i].ptr = this;
context[i].tid = i;
// start socket thread
if(pthread_create( &recv_thread_, NULL, Receiver::loopRecv, (void *)(&context[i])) != 0)
for(int i = 0; i < thread_num_; i++)
{
perror("socket recv thread create failed");
exit(0);
pthread_t recv_thread_;
// record the thread id
context[i].ptr = this;
context[i].tid = i;
// start socket thread
if(pthread_create( &recv_thread_, NULL, Receiver::loopRecv, (void *)(&context[i])) != 0)
{
perror("socket recv thread create failed");
exit(0);
}
created_threads.push_back(recv_thread_);
}
created_threads.push_back(recv_thread_);
}
return created_threads;
......@@ -227,3 +264,101 @@ void* Receiver::loopRecv(void *in_context)
}
}
void* Receiver::clientTxRx(void * context)
{
dev_profile *profile = (dev_profile *)context;
SoapySDR::Device * device = profile->device;
SoapySDR::Stream * rxStream = profile->rxs;
SoapySDR::Stream * txStream = profile->txs;
int tid = profile->tid;
int txSyms = profile->txSyms;
int rxSyms = profile->rxSyms;
int txStartSym = profile->txStartSym;
double rate = profile->rate;
unsigned txFrameDelta = profile->txFrameDelta;
int NUM_SAMPS = profile->nsamps;
Receiver* obj_ptr = profile->ptr;
Config *cfg = obj_ptr->config_;
#ifdef ENABLE_CPU_ATTACH
printf("pinning client thread %d to core %d\n", tid, profile->core);
if(pin_to_core(profile->core) != 0)
{
printf("pin client thread %d to core %d failed\n", tid, profile->core);
exit(0);
}
#endif
//while(!d_mutex.try_lock()){}
//thread_count++;
//std::cout << "Thread " << tid << ", txSyms " << txSyms << ", rxSyms " << rxSyms << ", txStartSym " << txStartSym << ", rate " << rate << ", txFrameDelta " << txFrameDelta << ", nsamps " << NUM_SAMPS << std::endl;
//d_mutex.unlock();
std::vector<std::complex<float>> buffs(NUM_SAMPS, 0);
std::vector<void *> rxbuff(2);
rxbuff[0] = buffs.data();
rxbuff[1] = buffs.data();
std::vector<void *> txbuff(2);
if (txSyms > 0)
{
txbuff[0] = cfg->txdata[tid].data();
txbuff[1] = cfg->txdata[tid].data();
}
bool exitLoop = false;
while (true)//(not exitLoop)
{
exitLoop = loopDone;
// receiver loop
long long rxTime(0);
long long txTime(0);
long long firstRxTime (0);
bool receiveErrors = false;
for (int i = 0; i < rxSyms; i++)
{
int flags(0);
int r = device->readStream(rxStream, rxbuff.data(), NUM_SAMPS, flags, rxTime, 1000000);
if (r == NUM_SAMPS)
{
if (i == 0) firstRxTime = rxTime;
}
else
{
std::cerr << "waiting for receive frames... " << std::endl;
receiveErrors = true;
break;
}
}
if (receiveErrors) continue; // just go to the next frame
// transmit loop
int flags = SOAPY_SDR_HAS_TIME;
txTime = firstRxTime & 0xFFFFFFFF00000000;
txTime += ((long long)txFrameDelta << 32);
txTime += ((long long)txStartSym << 16);
//printf("rxTime %llx, txTime %llx \n", firstRxTime, txTime);
if (exitLoop) flags |= SOAPY_SDR_END_BURST; //end burst on last iter
bool transmitErrors = false;
for (int i = 0; i < txSyms; i++)
{
if (i == txSyms - 1) flags |= SOAPY_SDR_END_BURST;
int r = device->writeStream(txStream, txbuff.data(), NUM_SAMPS, flags, txTime, 1000000);
if (r == NUM_SAMPS)
{
txTime += 0x10000;
}
else
{
std::cerr << "unexpected writeStream error " << SoapySDR::errToStr(r) << std::endl;
transmitErrors = true;
//goto cleanup;
}
}
}
}
......@@ -15,7 +15,8 @@ Recorder::Recorder(Config *cfg)
this->cfg = cfg;
unsigned nCores = std::thread::hardware_concurrency();
printf("number of CPU cores %d\n", nCores);
rx_thread_num = nCores >= 2*SOCKET_THREAD_NUM and cfg->nBsSdrs[0] >= SOCKET_THREAD_NUM ? SOCKET_THREAD_NUM : 1; // TODO: read number of cores and assign accordingly
if (cfg->bsPresent) rx_thread_num = nCores >= 2*SOCKET_THREAD_NUM and cfg->nBsSdrs[0] >= SOCKET_THREAD_NUM ? SOCKET_THREAD_NUM : 1; // TODO: read number of cores and assign accordingly
else rx_thread_num = 0;
printf("allocating %d cores to receive threads ... \n", rx_thread_num);
task_queue_ = moodycamel::ConcurrentQueue<Event_data>(SOCKET_BUFFER_FRAME_NUM * cfg->symbolsPerFrame * cfg->getNumAntennas() * 36);
message_queue_ = moodycamel::ConcurrentQueue<Event_data>(SOCKET_BUFFER_FRAME_NUM * cfg->symbolsPerFrame * cfg->getNumAntennas() * 36);
......@@ -67,6 +68,9 @@ herr_t Recorder::initHDF5(std::string hdf5)
hsize_t cdims_data[5] = {1, 1, 1, 1, 2 * cfg->sampsPerSymbol}; // data chunk size, TODO: optimize size
hsize_t max_dims_data[5] = {H5S_UNLIMITED, cfg->nCells, cfg->ulSymsPerFrame, cfg->getNumAntennas(), 2 * cfg->sampsPerSymbol};
// Used to create variable strings
std::ostringstream oss;
try
{
Exception::dontPrint();
......@@ -99,6 +103,10 @@ herr_t Recorder::initHDF5(std::string hdf5)
Attribute att;
std::vector<std::vector<std::string>> att_matrix;
std::vector<const char *> cStrArray;
std::vector<int> attr_data_ind;
std::vector<std::vector<int>> attr_pilot_sc;
std::vector<std::vector<std::complex<float>>> attr_txdata_freq_dom;
std::vector<std::vector<double>> attr_pilot_double;
// ******* COMMON ******** //
// TX/RX Frequency
......@@ -189,7 +197,6 @@ herr_t Recorder::initHDF5(std::string hdf5)
for(int index = 0; index < att_vector.size(); ++index) { cStrArray.push_back(att_vector[index].c_str()); }
if(!att_vector.empty()) { att.write(strdatatype, (void*)&cStrArray[0]); }
// Number of Base Station Cells
attr_data = cfg->nCells;
att = mainGroup.createAttribute("BS_NUM_CELLS", PredType::STD_I32BE, attr_ds);
......@@ -251,6 +258,66 @@ herr_t Recorder::initHDF5(std::string hdf5)
att.write(PredType::NATIVE_INT, &attr_data);
// ******* Clients ******** //
// Data subcarriers
attr_data_ind = cfg->data_ind;
dimsVec[0] = attr_data_ind.size();
attr_vec_ds = DataSpace (1, dimsVec);
att = mainGroup.createAttribute("OFDM_DATA_SC", PredType::STD_I32BE, attr_vec_ds);
att.write(PredType::NATIVE_INT, &attr_data_ind[0]);
// Pilot subcarriers (indexes)
attr_pilot_sc = cfg->pilot_sc;
dimsVec[0] = attr_pilot_sc[0].size();
attr_vec_ds = DataSpace (1, dimsVec);
att = mainGroup.createAttribute("OFDM_PILOT_SC", PredType::STD_I32BE, attr_vec_ds);
att.write(PredType::NATIVE_INT, &attr_pilot_sc[0][0]);
// Pilot subcarriers (values)
dimsVec[0] = attr_pilot_sc[1].size();
attr_vec_ds = DataSpace (1, dimsVec);
att = mainGroup.createAttribute("OFDM_PILOT_SC_VALS", PredType::STD_I32BE, attr_vec_ds);
att.write(PredType::NATIVE_INT, &attr_pilot_sc[1][0]);
// Freq. Domain Data Symbols - OBCH
attr_txdata_freq_dom = cfg->txdata_freq_dom;
std::vector<double> re_im_split_vec; // re-write complex vector. type not supported by hdf5
for (int i = 0; i < attr_txdata_freq_dom.size(); i++){
oss.str("");
oss.clear();
oss << "OFDM_DATA_CL" << i;
std::string var = oss.str();
re_im_split_vec.clear();
for (int j = 0; j < attr_txdata_freq_dom[i].size(); j++){
double re_val = std::real(attr_txdata_freq_dom[i][j]);
double im_val = std::imag(attr_txdata_freq_dom[i][j]);
re_im_split_vec.push_back(re_val);
re_im_split_vec.push_back(im_val);
}
dimsVec[0] = re_im_split_vec.size(); // real and imaginary parts
attr_vec_ds = DataSpace (1, dimsVec);
att = mainGroup.createAttribute(var, PredType::NATIVE_DOUBLE, attr_vec_ds);
att.write(PredType::NATIVE_DOUBLE, &re_im_split_vec[0]);
}
// for (int i = 0; i < attr_txdata_freq_dom.size(); i++)
// {
// for (int j = 0; j < attr_txdata_freq_dom[i].size(); j++){
// std::cout << "OBCH["<< i <<"][" << j << "]: \t " << attr_txdata_freq_dom[i][j] << std::endl;
// }
// }
// Freq. Domain Pilot symbols (real and imaginary parts)
attr_pilot_double = cfg->pilot_double;
std::vector<double> re_im_split_vec_pilot; // re-write complex vector. type not supported by hdf5
for (int j = 0; j < attr_pilot_double[0].size(); j++){
re_im_split_vec_pilot.push_back(attr_pilot_double[0][j]);
re_im_split_vec_pilot.push_back(attr_pilot_double[1][j]);
}
dimsVec[0] = re_im_split_vec_pilot.size();
attr_vec_ds = DataSpace (1, dimsVec);
att = mainGroup.createAttribute("OFDM_PILOT", PredType::NATIVE_DOUBLE, attr_vec_ds);
att.write(PredType::NATIVE_DOUBLE, &re_im_split_vec_pilot[0]);
// Number of Clients
attr_data = cfg->nClSdrs;
att = mainGroup.createAttribute("CL_NUM", PredType::STD_I32BE, attr_ds);
......
This diff is collapsed.
......@@ -363,7 +363,8 @@ def animate(i, num_samps, recorder, agc_en):
sigPwr_dBm = 10 * np.log10(sigPwr / 1e-3)
# Compute Power of Frequency Domain Signal (FFT)
f1, powerBins, noiseFloor, pks = fft_power(sampsRx[0], Rate, num_bins=fft_size, peak=1.0, scaling='density', peak_thresh=20)
f1, powerBins, noiseFloor, pks = fft_power(sampsRx[0], Rate, num_bins=fft_size, peak=1.0,
scaling='density', peak_thresh=20)
fftPower = bandpower(sampsRx[0], Rate, 0, Rate / 2)
fftPower_dB = 10 * np.log10(fftPower)
fftPower_dBm = 10 * np.log10(fftPower / 1e-3)
......@@ -437,14 +438,14 @@ def main():
parser.add_option("--label", type="string", dest="label", help="label for recorded file name", default="rx2.600GHz_TEST.hdf5")
parser.add_option("--lna", type="float", dest="lna", help="Lime Chip Rx LNA gain [0:30](dB)", default=30.0)
parser.add_option("--tia", type="float", dest="tia", help="Lime Chip Rx TIA gain [0,3,9,12] (dB)", default=0.0)
parser.add_option("--pga", type="float", dest="pga", help="Lime Chip Rx PGA gain [-12:19] (dB)", default=-5.0)
parser.add_option("--pga", type="float", dest="pga", help="Lime Chip Rx PGA gain [-12:19] (dB)", default=-10.0)
parser.add_option("--lna1", type="float", dest="lna1", help="BRS/CBRS Front-end LNA1 gain stage [0:33] (dB)", default=10.0)
parser.add_option("--lna2", type="float", dest="lna2", help="BRS/CBRS Front-end LNA2 gain [0:17] (dB)", default=0.0)
parser.add_option("--attn", type="float", dest="rxattn", help="BRS/CBRS Front-end ATTN gain stage [-18:6:0] (dB)", default=0.0)
parser.add_option("--latitude", type="float", dest="latitude", help="Latitude", default=0.0)
parser.add_option("--longitude", type="float", dest="longitude", help="Longitude", default=0.0)
parser.add_option("--elevation", type="float", dest="elevation", help="Elevation", default=0.0)
parser.add_option("--freq", type="float", dest="freq", help="Optional Rx freq (Hz)", default=2.6e9)
parser.add_option("--freq", type="float", dest="freq", help="Optional Rx freq (Hz)", default=3.6e9)
parser.add_option("--numSamps", type="int", dest="numSamps", help="Num samples to receive", default=16384)
parser.add_option("--serial", type="string", dest="serial", help="Serial number of the device", default="")
parser.add_option("--rxMode", type="string", dest="rxMode", help="RX Mode, Options:BASIC/REC/REPLAY", default="REC")
......
......@@ -46,7 +46,7 @@ from generate_sequence import *
#########################################
sdr = None
running = True
txStream = None
#########################################
# Functions #
......@@ -143,21 +143,34 @@ def siggen_app(args, rate, ampl, ant, gain, freq, bbfreq, numSamps, serial, sigT
sdr.writeSetting("TX_REPLAY", str(numSamps)) # this starts transmission
# Plot signal
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)
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()
def signal_handler(signal, frame):
global sdr, txStream, running
running = False
#cleanup txStream
print("Cleanup txStreams")
if txStream is not None:
sdr.deactivateStream(txStream)
sdr.closeStream(txStream)
#########################################
# Main #
#########################################
......@@ -168,7 +181,7 @@ def main():
parser.add_option("--ampl", type="float", dest="ampl", help="Tx digital amplitude scale", default=1)
parser.add_option("--ant", type="string", dest="ant", help="Optional Tx antenna", default="A")
parser.add_option("--gain", type="float", dest="gain", help="Tx gain (dB)", default=-5.0)
parser.add_option("--freq", type="float", dest="freq", help="Tx RF freq (Hz)", default=2.6e9)
parser.add_option("--freq", type="float", dest="freq", help="Tx RF freq (Hz)", default=3.6e9)
parser.add_option("--bbfreq", type="float", dest="bbfreq", help="Lime chip Baseband frequency (Hz)", default=0)
parser.add_option("--numSamps", type="int", dest="numSamps", help="Num samples to receive", default=1024)
parser.add_option("--serial", type="string", dest="serial", help="serial number of the device", default="")
......
......@@ -28,13 +28,15 @@ def find_lts(iq, thresh=0.8, us=1, cp=32):
cp: cyclic prefix
Returns:
best: highest LTS peak,
best_pk: highest LTS peak,
lts_pks: the list of all detected LTSs, and
lts_corr: the correlated signal, multiplied by itself delayed by 1/2 an LTS
"""
debug = False
lts, lts_f = generate_training_seq(preamble_type='lts', cp=cp, upsample=us)
lts_flip = np.flip(lts[-64:]) # lts contains 2.5 64-sample-LTS sequences, we need only one symbol
lts_tmp = lts[-64:]
lts_flip = lts_tmp[::-1] # lts contains 2.5 64-sample-LTS sequences, we need only one symbol
lts_flip_conj = np.conjugate(lts_flip)
lts_corr = np.abs(np.convolve(lts_flip_conj, np.sign(iq)))
lts_pks = np.where(lts_corr > (thresh * np.max(lts_corr)))
......@@ -44,11 +46,23 @@ def find_lts(iq, thresh=0.8, us=1, cp=32):
if not second_peak_idx.any():
print("NO LTS FOUND!")
best = []
best_pk = []
else:
best = lts_pks[second_peak_idx[0]] # Grab only the first packet we have received
best_pk = lts_pks[second_peak_idx[0]] # Grab only the first packet we have received
return best, lts_pks, lts_corr
if debug:
print("LTS: {}, BEST: {}".format(lts_pks, lts_pks[second_peak_idx]))
fig = plt.figure()
ax1 = fig.add_subplot(2, 1, 1)
ax1.grid(True)
ax1.plot(np.abs(iq))
ax2 = fig.add_subplot(2, 1, 2)
ax2.grid(True)
ax2.plot(np.abs(lts_corr))
ax2.scatter(lts_pks, 2 * np.ones(len(lts_pks)))
plt.show()
return best_pk, lts_pks, lts_corr
if __name__ == '__main__':
......
......@@ -278,7 +278,7 @@ if __name__ == '__main__':
sequence_sts = generate_training_seq('sts', reps=10)
sequence_lts, lts_f = generate_training_seq('lts', cp=32, upsample=1)
sequence_zadoff = generate_training_seq('lte_zadoffchu_seq', seq_length=63, root=25)
sequence_goldIfft = generate_training_seq('gold_ifft', seq_length=128, cp=32, upsample=1)
sequence_goldIfft = generate_training_seq('gold_ifft', seq_length=128, cp=0, upsample=1)
print("SIZE GOLD SEQ.: {},{}".format(len(sequence_goldIfft), len(sequence_goldIfft[0])))
......
......@@ -45,6 +45,8 @@ class hdfDump:
self.filename = filename
self.h5struct = []
self.data = []
self.metadata = {}
self.samples = {}
def get_hdf5(self):
"""
......@@ -129,6 +131,95 @@ class hdfDump:
return self.data
def get_attributes(self):
# Retrieve attributes, translate into python dictionary
data = self.data
# Data cleanup
# In OFDM_DATA_CLx and OFDM_PILOT, we have stored both real and imaginary in same vector
# (i.e., RE1,IM1,RE2,IM2...REm,IM,)
# OFDM data
num_cl = np.squeeze(data['Attributes']['CL_NUM'])
prefix_len = np.squeeze(data['Attributes']['PREFIX_LEN'])
ofdm_data = np.zeros((num_cl, 320)).astype(complex) # FIXME !!!! REMOVE HARDCODED VALUE
for clIdx in range(num_cl):
this_str = 'OFDM_DATA_CL' + str(clIdx)
data_per_cl = np.squeeze(data['Attributes'][this_str])
# some_list[start:stop:step]
I = np.double(data_per_cl[0::2])
Q = np.double(data_per_cl[1::2])
IQ = I + Q * 1j
ofdm_data[clIdx, :] = IQ[prefix_len::]
#ofdm_data.append(IQ[prefix_len::]) # FIXME - need to remove prefix on main.cc
# Pilots
pilot_vec = np.squeeze(data['Attributes']['OFDM_PILOT'])
# some_list[start:stop:step]
I = pilot_vec[0::2]
Q = pilot_vec[1::2]
pilot_complex = I + Q * 1j
# Populate dictionary
self.metadata = {
'FREQ': np.squeeze(data['Attributes']['FREQ']),
'RATE': np.squeeze(data['Attributes']['RATE']),
'SYM_LEN_NO_PAD': np.squeeze(data['Attributes']['SYMBOL_LEN_NO_PAD']),
'PREFIX_LEN': np.squeeze(data['Attributes']['PREFIX_LEN']),
'POSTFIX_LEN': np.squeeze(data['Attributes']['POSTFIX_LEN']),
'SYM_LEN': np.squeeze(data['Attributes']['SYMBOL_LEN']),
'FFT_SIZE': np.squeeze(data['Attributes']['FFT_SIZE']),
'CP_LEN': np.squeeze(data['Attributes']['CP_LEN']),
'BEACON_SEQ': np.squeeze(data['Attributes']['BEACON_SEQ_TYPE']).astype(str),
'PILOT_SEQ': np.squeeze(data['Attributes']['PILOT_SEQ_TYPE']).astype(str),
'BS_HUB_ID': np.squeeze(data['Attributes']['BS_HUB_ID']).astype(str),
'BS_SDR_NUM_PER_CELL': np.squeeze(data['Attributes']['BS_SDR_NUM_PER_CELL']).astype(int),
'BS_SDR_ID': np.squeeze(data['Attributes']['BS_SDR_ID']).astype(str),
'BS_NUM_CELLS': np.squeeze(data['Attributes']['BS_NUM_CELLS']),
'BS_CH_PER_RADIO': np.squeeze(data['Attributes']['BS_CH_PER_RADIO']),
'BS_FRAME_SCHED': np.squeeze(data['Attributes']['BS_FRAME_SCHED']).astype(str),
'BS_RX_GAIN_A': np.squeeze(data['Attributes']['BS_RX_GAIN_A']),
'BS_TX_GAIN_A': np.squeeze(data['Attributes']['BS_TX_GAIN_A']),
'BS_RX_GAIN_B': np.squeeze(data['Attributes']['BS_RX_GAIN_B']),
'BS_TX_GAIN_B': np.squeeze(data['Attributes']['BS_TX_GAIN_B']),
'BS_BEAMSWEEP': np.squeeze(data['Attributes']['BS_BEAMSWEEP']),
'BS_BEACON_ANT': np.squeeze(data['Attributes']['BS_BEACON_ANT']),
'BS_NUM_ANT': np.squeeze(data['Attributes']['BS_NUM_ANT']),
'BS_FRAME_LEN': np.squeeze(data['Attributes']['BS_FRAME_LEN']),
'NUM_CLIENTS': np.squeeze(data['Attributes']['CL_NUM']),
'CL_CH_PER_RADIO': np.squeeze(data['Attributes']['CL_CH_PER_RADIO']),
'CL_AGC_EN': np.squeeze(data['Attributes']['CL_AGC_EN']),
'CL_RX_GAIN_A': np.squeeze(data['Attributes']['CL_RX_GAIN_A']),
'CL_TX_GAIN_A': np.squeeze(data['Attributes']['CL_TX_GAIN_A']),
'CL_RX_GAIN_B': np.squeeze(data['Attributes']['CL_RX_GAIN_B']),
'CL_TX_GAIN_B': np.squeeze(data['Attributes']['CL_TX_GAIN_B']),
'CL_FRAME_SCHED': np.squeeze(data['Attributes']['CL_FRAME_SCHED']).astype(str),
'CL_SDR_ID': np.squeeze(data['Attributes']['CL_SDR_ID']).astype(str),
'CL_MODULATION': np.squeeze(data['Attributes']['CL_MODULATION']).astype(str),
'UL_SYMS': np.squeeze(data['Attributes']['UL_SYMS']),
'OFDM_DATA_SC': np.squeeze(data['Attributes']['OFDM_DATA_SC']),
'OFDM_PILOT_SC': np.squeeze(data['Attributes']['OFDM_PILOT_SC']),
'OFDM_PILOT_SC_VALS': np.squeeze(data['Attributes']['OFDM_PILOT_SC_VALS']),
'OFDM_PILOT_TIME': pilot_complex,
'OFDM_DATA': ofdm_data,
}
def get_samples(self, data_types_avail):
# Retrieve samples, translate into python dictionary
samples_pilots = []
samples_ulData = []
for idx, ftype in enumerate(data_types_avail):
if ftype == "PILOTS":
samples = self.data['Pilot_Samples']['Samples']
samples_pilots = samples
elif ftype == "UL_DATA":
samples = self.data['UplinkData']['Samples']
samples_ulData = samples
self.samples = {'PILOT_SAMPS': samples_pilots,
'UL_SAMPS': samples_ulData,
}
def verify_hdf5(self, default_frame=100):
"""
Plot data in file to verify contents.
......@@ -210,9 +301,34 @@ if __name__ == '__main__':
filename = sys.argv[1]
# Instantiate
hdf5 = hdfDump(filename)
hdf5.get_hdf5()
hdf5.parse_hdf5()
# Check which data we have available
data_types_avail = []
pilots_avail = bool(hdf5.data['Pilot_Samples'])
ul_data_avail = bool(hdf5.data['UplinkData'])
if pilots_avail:
data_types_avail.append("PILOTS")
print("PILOT Data Available")
if ul_data_avail:
data_types_avail.append("UL_DATA")
print("Uplink Data Available")
# Empty structure
if not data_types_avail:
raise Exception(' **** No pilots or uplink data found **** ')
hdf5.get_attributes()
hdf5.get_samples(data_types_avail)
raw_data = hdf5.data
metadata = hdf5.metadata
samples = hdf5.samples
hdf5.verify_hdf5()
else:
......
This diff is collapsed.
......@@ -280,7 +280,7 @@ class ofdmTxRx:
Apply Sample Frequency Offset
Input:
rxSig_freq_eq - Equalized, time domain received signal
rxSig_freq_eq - Equalized, frequency domain received signal
pilot_sc - Pilot subcarriers (indexes)
pilots_matrix - Pilots in matrix form
n_ofdm_syms - Number of OFDM symbols
......
This diff is collapsed.