Commit 7f8e8b96 authored by Rahman's avatar Rahman

Merge branch 'develop' into 'master'

Develop

See merge request renew/renew-software!9
parents fd4174dc 7635d56d
Pipeline #66 failed with stage
in 0 seconds
......@@ -31,8 +31,7 @@ BaseRadioSet::BaseRadioSet(Config* cfg)
int radioNum = _cfg->nBsSdrs[c];
nBsAntennas[c] = radioNum * _cfg->bsChannel.length();
std::cout << radioNum << " radios in cell " << c << std::endl;
if (!_cfg->hub_ids.empty()) {
if (!kUseUHD && !_cfg->hub_ids.empty()) {
SoapySDR::Kwargs args;
args["driver"] = "remote";
args["timeout"] = "1000000";
......@@ -111,7 +110,8 @@ BaseRadioSet::BaseRadioSet(Config* cfg)
while (threadCount > 0)
;
// Measure Sync Delays now!
sync_delays(c);
if (!kUseUHD)
sync_delays(c);
}
if (radioNotFound) {
......@@ -173,37 +173,46 @@ BaseRadioSet::BaseRadioSet(Config* cfg)
tddConfStr += "]}";
std::cout << tddConfStr << std::endl;
#endif
for (size_t i = 0; i < bsRadios[0].size(); i++) {
SoapySDR::Device* dev = bsRadios[0][i]->dev;
dev->writeSetting("TX_SW_DELAY", "30"); // experimentally good value for dev front-end
dev->writeSetting("TDD_MODE", "true");
dev->writeSetting("TDD_CONFIG", tddConfStr);
}
// write TDD schedule and beacons to FPFA buffers only for Iris
if (!kUseUHD) {
for (size_t i = 0; i < bsRadios[0].size(); i++) {
SoapySDR::Device* dev = bsRadios[0][i]->dev;
dev->writeSetting("TX_SW_DELAY", "30"); // experimentally good value for dev front-end
dev->writeSetting("TDD_MODE", "true");
dev->writeSetting("TDD_CONFIG", tddConfStr);
}
// write beacons to FPGA buffers
size_t ndx = 0;
for (size_t i = 0; i < bsRadios[0].size(); i++) {
SoapySDR::Device* dev = bsRadios[0][i]->dev;
dev->writeRegisters("BEACON_RAM", 0, _cfg->beacon);
for (char const& c : _cfg->bsChannel) {
bool isBeaconAntenna = !_cfg->beamsweep && ndx == _cfg->beacon_ant;
std::vector<unsigned> beacon_weights(nBsAntennas[0], isBeaconAntenna ? 1 : 0);
std::string tx_ram_wgt = "BEACON_RAM_WGT_";
if (_cfg->beamsweep) {
for (int j = 0; j < nBsAntennas[0]; j++)
beacon_weights[j] = CommsLib::hadamard2(ndx, j);
// write beacons to FPGA buffers
size_t ndx = 0;
for (size_t i = 0; i < bsRadios[0].size(); i++) {
SoapySDR::Device* dev = bsRadios[0][i]->dev;
dev->writeRegisters("BEACON_RAM", 0, _cfg->beacon);
for (char const& c : _cfg->bsChannel) {
bool isBeaconAntenna = !_cfg->beamsweep && ndx == _cfg->beacon_ant;
std::vector<unsigned> beacon_weights(nBsAntennas[0], isBeaconAntenna ? 1 : 0);
std::string tx_ram_wgt = "BEACON_RAM_WGT_";
if (_cfg->beamsweep) {
for (int j = 0; j < nBsAntennas[0]; j++)
beacon_weights[j] = CommsLib::hadamard2(ndx, j);
}
dev->writeRegisters(tx_ram_wgt + c, 0, beacon_weights);
++ndx;
}
dev->writeRegisters(tx_ram_wgt + c, 0, beacon_weights);
++ndx;
dev->writeSetting("BEACON_START", std::to_string(bsRadios[0].size()));
}
dev->writeSetting("BEACON_START", std::to_string(bsRadios[0].size()));
}
for (size_t i = 0; i < bsRadios[0].size(); i++) {
SoapySDR::Device* dev = bsRadios[0][i]->dev;
bsRadios[0][i]->activateRecv();
bsRadios[0][i]->activateXmit();
dev->setHardwareTime(0, "TRIGGER");
if (!kUseUHD) {
bsRadios[0][i]->activateRecv();
bsRadios[0][i]->activateXmit();
dev->setHardwareTime(0, "TRIGGER");
} else {
dev->setHardwareTime(0.0); // "CMD"
bsRadios[0][i]->activateRecv();
bsRadios[0][i]->activateXmit();
}
}
std::cout << __func__ << " done!" << std::endl;
}
......@@ -237,13 +246,22 @@ void BaseRadioSet::init(BaseRadioContext* context)
auto channels = Utils::strToChannels(_cfg->bsChannel);
SoapySDR::Kwargs args;
args["driver"] = "iris";
if (!kUseUHD) {
args["driver"] = "iris";
args["serial"] = _cfg->bs_sdr_ids[c][i];
} else {
args["driver"] = "uhd";
args["addr"] = _cfg->bs_sdr_ids[c][i];
std::cout << "Init bsRadios: " << args["addr"] << std::endl;
}
args["timeout"] = "1000000";
args["serial"] = _cfg->bs_sdr_ids[c][i];
try {
bsRadios[c][i] = new Radio(args, SOAPY_SDR_CS16, channels, _cfg->rate);
} catch (std::runtime_error) {
std::cerr << "Ignoring iris " << _cfg->bs_sdr_ids[c][i] << std::endl;
if (!kUseUHD)
std::cerr << "Ignoring iris " << _cfg->bs_sdr_ids[c][i] << std::endl;
else
std::cerr << "Ignoring uhd device " << _cfg->bs_sdr_ids[c][i] << std::endl;
bsRadios[c][i] = NULL;
}
......@@ -309,7 +327,8 @@ void BaseRadioSet::radioTrigger(void)
void BaseRadioSet::radioStart()
{
radioTrigger();
if (!kUseUHD)
radioTrigger();
}
void BaseRadioSet::readSensors()
......@@ -332,9 +351,11 @@ void BaseRadioSet::radioStop(void)
{
std::string tddConfStr = "{\"tdd_enabled\":false}";
for (size_t i = 0; i < bsRadios[0].size(); i++) {
SoapySDR::Device* dev = bsRadios[0][i]->dev;
dev->writeSetting("TDD_CONFIG", tddConfStr);
dev->writeSetting("TDD_MODE", "false");
if (!kUseUHD) {
SoapySDR::Device* dev = bsRadios[0][i]->dev;
dev->writeSetting("TDD_CONFIG", tddConfStr);
dev->writeSetting("TDD_MODE", "false");
}
bsRadios[0][i]->reset_DATA_clk_domain();
}
}
......@@ -349,11 +370,20 @@ void BaseRadioSet::radioTx(const void* const* buffs)
int BaseRadioSet::radioTx(size_t radio_id, const void* const* buffs, int flags, long long& frameTime)
{
int w = bsRadios[0][radio_id]->xmit(buffs, _cfg->sampsPerSymbol, flags, frameTime);
int w;
// for UHD device xmit from host using frameTimeNs
if (!kUseUHD) {
w = bsRadios[0][radio_id]->xmit(buffs, _cfg->sampsPerSymbol, flags, frameTime);
} else {
long long frameTimeNs = SoapySDR::ticksToTimeNs(frameTime, _cfg->rate);
w = bsRadios[0][radio_id]->xmit(buffs, _cfg->sampsPerSymbol, flags, frameTimeNs);
}
#if DEBUG_RADIO
size_t chanMask;
long timeoutUs(0);
SoapySDR::Device* dev = bsRadios[0][radio_id]->dev;
int s = dev->readStreamStatus(bsRadio->txs, chanMask, flags, frameTime, timeoutUs);
int s = dev->readStreamStatus(SOAPY_SDR_TX, chanMask, flags, frameTime, timeoutUs);
std::cout << "radio " << radio_id << " tx returned " << w << " and status " << s << std::endl;
#endif
return w;
......@@ -372,18 +402,33 @@ int BaseRadioSet::radioRx(size_t radio_id, void* const* buffs, long long& frameT
{
if (radio_id < bsRadios[0].size()) {
long long frameTimeNs = 0;
int ret = bsRadios[0][radio_id]->recv(buffs, _cfg->sampsPerSymbol, frameTimeNs);
frameTime = frameTimeNs; //SoapySDR::timeNsToTicks(frameTimeNs, _rate);
// for UHD device recv using ticks
if (!kUseUHD)
frameTime = frameTimeNs; //SoapySDR::timeNsToTicks(frameTimeNs, _rate);
else
frameTime = SoapySDR::timeNsToTicks(frameTimeNs, _cfg->rate);
#if DEBUG_RADIO
if (ret != _cfg->sampsPerSymbol)
std::cout << "recv returned " << ret << " from radio " << radio_id << ", Expected "
<< _cfg->sampsPerSymbol << std::endl;
else
std::cout << "radio " << radio_id << "received " << ret << std::endl;
std::cout << "radio " << radio_id << "received " << ret << " at " << frameTime << std::endl;
#endif
return ret;
}
std::cout << "invalid radio id " << radio_id << std::endl;
return 0;
}
int BaseRadioSet::radioRx(size_t radio_id, void* const* buffs, int numSamps, long long& frameTime)
{
if (radio_id < bsRadios[0].size()) {
long long frameTimeNs = 0;
int ret = bsRadios[0][radio_id]->recv(buffs, numSamps, frameTimeNs);
frameTime = SoapySDR::timeNsToTicks(frameTimeNs, _cfg->rate);
return ret;
}
std::cout << "invalid radio id " << radio_id << std::endl;
return 0;
}
......@@ -6,6 +6,14 @@ set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -g -O3 -mavx2 -mavx")
find_package(nlohmann_json 3.2.0 REQUIRED)
set(USE_UHD False CACHE STRING "USE_UHD defaulting to 'False'")
message(STATUS "USE_UHD: ${USE_UHD}")
if(${USE_UHD})
message(STATUS "Enabled USE_UHD: ${USE_UHD}")
add_definitions(-DUSE_UHD)
endif()
########################################################################
# SoapySDR dependency
########################################################################
......@@ -33,5 +41,40 @@ message(STATUS "HDF5_INCLUDE_DIRS: ${HDF5_INCLUDE_DIRS}")
message(STATUS "HDF5_LIBRARIES: ${HDF5_LIBRARIES}")
include_directories(${SoapySDR_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS})
add_executable(sounder main.cc ClientRadioSet.cc config.cc Radio.cc receiver.cc recorder.cc BaseRadioSet.cc BaseRadioSet-calibrate.cc comms-lib.cc comms-lib-avx.cc utils.cc signalHandler.cpp)
target_link_libraries(sounder -lpthread -lhdf5_cpp --enable-threadsafe ${SoapySDR_LIBRARIES} ${HDF5_LIBRARIES} ${CMAKE_SOURCE_DIR}/mufft/libmuFFT.a ${CMAKE_SOURCE_DIR}/mufft/libmuFFT-sse.a ${CMAKE_SOURCE_DIR}/mufft/libmuFFT-sse3.a ${CMAKE_SOURCE_DIR}/mufft/libmuFFT-avx.a)
set(SOUNDER_SOURCES
ClientRadioSet.cc
config.cc
Radio.cc
receiver.cc
recorder.cc
BaseRadioSet.cc
BaseRadioSet-calibrate.cc
comms-lib.cc
comms-lib-avx.cc
utils.cc
signalHandler.cpp)
add_executable(sounder
main.cc
${SOUNDER_SOURCES})
target_link_libraries(sounder -lpthread -lhdf5_cpp --enable-threadsafe
${SoapySDR_LIBRARIES}
${HDF5_LIBRARIES}
${CMAKE_SOURCE_DIR}/mufft/libmuFFT.a
${CMAKE_SOURCE_DIR}/mufft/libmuFFT-sse.a
${CMAKE_SOURCE_DIR}/mufft/libmuFFT-sse3.a
${CMAKE_SOURCE_DIR}/mufft/libmuFFT-avx.a)
add_library(sounder_module MODULE
${SOUNDER_SOURCES})
target_link_libraries(sounder_module -lpthread -lhdf5_cpp --enable-threadsafe
-Wl,--whole-archive
${CMAKE_SOURCE_DIR}/mufft/libmuFFT.a
${CMAKE_SOURCE_DIR}/mufft/libmuFFT-sse.a
${CMAKE_SOURCE_DIR}/mufft/libmuFFT-sse3.a
${CMAKE_SOURCE_DIR}/mufft/libmuFFT-avx.a
-Wl,--no-whole-archive
${HDF5_LIBRARIES}
${SoapySDR_LIBRARIES})
......@@ -36,7 +36,10 @@ ClientRadioSet::ClientRadioSet(Config* cfg)
for (size_t i = 0; i < _cfg->nClSdrs; i++) {
SoapySDR::Kwargs args;
args["timeout"] = "1000000";
args["serial"] = _cfg->cl_sdr_ids.at(i);
if (!kUseUHD)
args["serial"] = _cfg->cl_sdr_ids.at(i);
else
args["addr"] = _cfg->cl_sdr_ids.at(i);
try {
radios.push_back(new Radio(args, SOAPY_SDR_CF32, channels, _cfg->rate));
} catch (std::runtime_error) {
......@@ -48,14 +51,16 @@ ClientRadioSet::ClientRadioSet(Config* cfg)
auto dev = radios.back()->dev;
SoapySDR::Kwargs info = dev->getHardwareInfo();
for (auto ch : { 0, 1 }) //channels)
{
// for (auto ch : { 0, 1 }) //channels)
for (auto ch : channels) {
double rxgain = _cfg->clRxgain_vec[ch][i]; // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:108]
double txgain = _cfg->clTxgain_vec[ch][i]; // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:105]
radios.back()->dev_init(_cfg, ch, rxgain, txgain);
}
initAGC(dev, _cfg);
// TODO: add uhd_cal
if (!kUseUHD)
initAGC(dev, _cfg);
}
radios.shrink_to_fit();
......@@ -71,6 +76,8 @@ ClientRadioSet::ClientRadioSet(Config* cfg)
for (size_t i = 0; i < radios.size(); i++) {
auto dev = radios[i]->dev;
// hw_frame is only for Iris
if (_cfg->hw_framer) {
std::string corrConfString = "{\"corr_enabled\":true,\"corr_threshold\":" + std::to_string(1) + "}";
dev->writeSetting("CORR_CONFIG", corrConfString);
......@@ -125,10 +132,16 @@ ClientRadioSet::ClientRadioSet(Config* cfg)
else
dev->writeSetting("CORR_START", (_cfg->clChannel == "B") ? "B" : "A");
} else {
dev->setHardwareTime(0, "TRIGGER");
radios[i]->activateRecv();
radios[i]->activateXmit();
dev->writeSetting("TRIGGER_GEN", "");
if (!kUseUHD) {
dev->setHardwareTime(0, "TRIGGER");
radios[i]->activateRecv();
radios[i]->activateXmit();
dev->writeSetting("TRIGGER_GEN", "");
} else {
dev->setHardwareTime(0.0); // "CMD"
radios[i]->activateRecv();
radios[i]->activateXmit();
}
}
}
std::cout << __func__ << " done!" << std::endl;
......@@ -169,15 +182,19 @@ int ClientRadioSet::triggers(int i)
int ClientRadioSet::radioRx(size_t radio_id, void* const* buffs, int numSamps, long long& frameTime)
{
if (radio_id < radios.size()) {
int ret(0);
int ret(0);
if (_cfg->hw_framer) {
ret = radios[radio_id]->recv(buffs, numSamps, frameTime);
} else {
} else {
long long frameTimeNs(0);
ret = radios[radio_id]->recv(buffs, numSamps, frameTimeNs);
frameTime = SoapySDR::timeNsToTicks(frameTimeNs, _cfg->rate);
}
return ret;
#if DEBUG_RADIO
if (frameTimeNs < 2e9)
std::cout << "client " << radio_id << " received " << ret << " at " << frameTimeNs << std::endl;
#endif
}
return ret;
}
std::cout << "invalid radio id " << radio_id << std::endl;
return 0;
......@@ -187,7 +204,7 @@ int ClientRadioSet::radioTx(size_t radio_id, const void* const* buffs, int numSa
{
if (_cfg->hw_framer) {
return radios[radio_id]->xmit(buffs, numSamps, flags, frameTime);
} else {
} else {
long long frameTimeNs = SoapySDR::ticksToTimeNs(frameTime, _cfg->rate);
return radios[radio_id]->xmit(buffs, numSamps, flags, frameTimeNs);
}
......
......@@ -7,7 +7,7 @@ experiments with an RENEW base station hardware. To run, follow steps below:
```shell
cd mufft
git submodule update --init
cmake ./
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON ./
make -j
cd ../
cmake ./
......
......@@ -6,33 +6,50 @@
void Radio::dev_init(Config* _cfg, int ch, double rxgain, double txgain)
{
// these params are sufficient to set before DC offset and IQ imbalance calibration
dev->setAntenna(SOAPY_SDR_RX, ch, "TRX");
dev->setBandwidth(SOAPY_SDR_RX, ch, _cfg->bwFilter);
dev->setBandwidth(SOAPY_SDR_TX, ch, _cfg->bwFilter);
if (!kUseUHD) {
dev->setAntenna(SOAPY_SDR_RX, ch, "TRX");
dev->setBandwidth(SOAPY_SDR_RX, ch, _cfg->bwFilter);
dev->setBandwidth(SOAPY_SDR_TX, ch, _cfg->bwFilter);
dev->setFrequency(SOAPY_SDR_RX, ch, "BB", _cfg->nco);
dev->setFrequency(SOAPY_SDR_TX, ch, "BB", _cfg->nco);
} else {
std::cout << "Init USRP channel: " << ch << std::endl;
dev->setAntenna(SOAPY_SDR_TX, ch, "TX/RX");
dev->setAntenna(SOAPY_SDR_RX, ch, "RX2"); // or "TX/RX"
dev->setFrequency(SOAPY_SDR_RX, ch, "BB", 0);
dev->setFrequency(SOAPY_SDR_TX, ch, "BB", 0);
}
dev->setFrequency(SOAPY_SDR_RX, ch, "RF", _cfg->radioRfFreq);
dev->setFrequency(SOAPY_SDR_RX, ch, "BB", _cfg->nco);
dev->setFrequency(SOAPY_SDR_TX, ch, "RF", _cfg->radioRfFreq);
dev->setFrequency(SOAPY_SDR_TX, ch, "BB", _cfg->nco);
// Unified gains for both lime and frontend
if (_cfg->single_gain) {
dev->setGain(SOAPY_SDR_RX, ch, rxgain); // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:108]
dev->setGain(SOAPY_SDR_TX, ch, txgain); // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:105]
std::cout << "Tx gain: " << dev->getGain(SOAPY_SDR_TX, ch)
<< ", Rx gain: " << dev->getGain(SOAPY_SDR_RX, ch) << std::endl;
} else {
dev->setGain(SOAPY_SDR_RX, ch, "LNA", std::min(30.0, rxgain)); // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:108]
dev->setGain(SOAPY_SDR_RX, ch, "TIA", 0);
dev->setGain(SOAPY_SDR_RX, ch, "PGA", 0);
dev->setGain(SOAPY_SDR_RX, ch, "LNA2", 17); // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:108]
dev->setGain(SOAPY_SDR_RX, ch, "ATTN", _cfg->radioRfFreq < 3e9 ? -12 : 0);
dev->setGain(SOAPY_SDR_TX, ch, "PAD", std::min(42.0, txgain)); // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:105]
dev->setGain(SOAPY_SDR_TX, ch, "IAMP", 0);
dev->setGain(SOAPY_SDR_TX, ch, "PA2", 0);
dev->setGain(SOAPY_SDR_TX, ch, "ATTN", -6);
if (!kUseUHD) {
dev->setGain(SOAPY_SDR_RX, ch, "LNA", std::min(30.0, rxgain)); // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:108]
dev->setGain(SOAPY_SDR_RX, ch, "TIA", 0);
dev->setGain(SOAPY_SDR_RX, ch, "PGA", 0);
dev->setGain(SOAPY_SDR_RX, ch, "LNA2", 17); // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:108]
dev->setGain(SOAPY_SDR_RX, ch, "ATTN", _cfg->radioRfFreq < 3e9 ? -12 : 0);
dev->setGain(SOAPY_SDR_TX, ch, "PAD", std::min(42.0, txgain)); // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:105]
dev->setGain(SOAPY_SDR_TX, ch, "IAMP", 0);
dev->setGain(SOAPY_SDR_TX, ch, "PA2", 0);
dev->setGain(SOAPY_SDR_TX, ch, "ATTN", -6);
} else {
dev->setGain(SOAPY_SDR_RX, ch, "PGA0", std::min(31.5, rxgain));
dev->setGain(SOAPY_SDR_TX, ch, "PGA0", std::min(31.5, txgain));
}
}
// DC Offset
dev->setDCOffsetMode(SOAPY_SDR_RX, ch, true);
// TODO: add uhd_cal
if (!kUseUHD)
dev->setDCOffsetMode(SOAPY_SDR_RX, ch, true);
}
void Radio::drain_buffers(std::vector<void*> buffs, int symSamp)
......@@ -82,7 +99,10 @@ Radio::~Radio(void)
int Radio::recv(void* const* buffs, int samples, long long& frameTime)
{
int flags(0);
return dev->readStream(rxs, buffs, samples, flags, frameTime, 1000000);
int r = dev->readStream(rxs, buffs, samples, flags, frameTime, 1000000);
if (r != samples)
std::cerr << "time: " << frameTime << ", unexpected readStream error " << SoapySDR::errToStr(r) << ", flag: " << flags << std::endl;
return r;
}
int Radio::activateRecv(const long long rxTime, const size_t numSamps, int flags)
......@@ -94,7 +114,11 @@ int Radio::activateRecv(const long long rxTime, const size_t numSamps, int flags
SOAPY_SDR_WAIT_TRIGGER | SOAPY_SDR_END_BURST
};
int flag_args = soapyFlags[flags];
return dev->activateStream(rxs, flag_args, rxTime, numSamps);
// for USRP device start rx stream 1 sec in the future
if (!kUseUHD)
return dev->activateStream(rxs, flag_args, rxTime, numSamps);
else
return dev->activateStream(rxs, SOAPY_SDR_HAS_TIME, 1e9, 0);
}
void Radio::deactivateRecv(void)
......@@ -119,7 +143,11 @@ int Radio::xmit(const void* const* buffs, int samples, int flags, long long& fra
void Radio::activateXmit(void)
{
dev->activateStream(txs);
// for USRP device start tx stream 1 sec in the future
if (!kUseUHD)
dev->activateStream(txs);
else
dev->activateStream(txs, SOAPY_SDR_HAS_TIME, 1e9, 0);
}
void Radio::deactivateXmit(void)
......
......@@ -53,7 +53,8 @@ Config::Config(const std::string& jsonfile)
pilot_seq = tddConf.value("pilot_seq", "lts-half");
// BS
hub_file = tddConf.value("hub_id", "hub_serials.txt");
if (!kUseUHD)
hub_file = tddConf.value("hub_id", "hub_serials.txt");
json sdr_id_files = tddConf.value("sdr_id", json::array());
nCells = sdr_id_files.size();
bs_sdr_file.assign(sdr_id_files.begin(), sdr_id_files.end());
......@@ -62,7 +63,7 @@ Config::Config(const std::string& jsonfile)
throw std::invalid_argument("error channel config: not any of A/B/AB!\n");
auto jBsFrames = tddConf.value("frame_schedule", json::array());
frames.assign(jBsFrames.begin(), jBsFrames.end());
single_gain = tddConf.value("single_gain", true);
single_gain = tddConf.value("single_gain", true);
txgain[0] = tddConf.value("txgainA", 20);
rxgain[0] = tddConf.value("rxgainA", 20);
txgain[1] = tddConf.value("txgainB", 20);
......@@ -83,7 +84,8 @@ Config::Config(const std::string& jsonfile)
nBsSdrs[i] = bs_sdr_ids[i].size();
nBsAntennas[i] = bsChannel.length() * nBsSdrs[i];
}
Utils::loadDevices(hub_file, hub_ids);
if (!kUseUHD)
Utils::loadDevices(hub_file, hub_ids);
symbolsPerFrame = frames.at(0).size();
//std::vector<std::vector<size_t>> pilotSymbols = Utils::loadSymbols(frames, 'P');
......@@ -124,8 +126,10 @@ Config::Config(const std::string& jsonfile)
// Clients
if (clPresent) {
auto jClSdrs = tddConfCl.value("sdr_id", json::array());
// auto jClSdrs = tddConfCl.value("sdr_ip", json::array());
nClSdrs = jClSdrs.size();
cl_sdr_ids.assign(jClSdrs.begin(), jClSdrs.end());
// cl_sdr_ips.assign(jClSdrs.begin(), jClSdrs.end());
clChannel = tddConfCl.value("channel", "A");
if (clChannel != "A" && clChannel != "B" && clChannel != "AB")
throw std::invalid_argument("error channel config: not any of A/B/AB!\n");
......@@ -136,7 +140,7 @@ Config::Config(const std::string& jsonfile)
clDataMod = tddConfCl.value("modulation", "QPSK");
frame_mode = tddConfCl.value("frame_mode", "continuous_resync");
hw_framer = tddConfCl.value("hw_framer", true);
txAdvance = tddConfCl.value("tx_advance", 250);
txAdvance = tddConfCl.value("tx_advance", 250); // 250
auto jClTxgainA_vec = tddConfCl.value("txgainA", json::array());
clTxgain_vec[0].assign(jClTxgainA_vec.begin(), jClTxgainA_vec.end());
......@@ -171,7 +175,7 @@ Config::Config(const std::string& jsonfile)
beacon_seq = tddConfCl.value("beacon_seq", "gold_ifft");
pilot_seq = tddConfCl.value("pilot_seq", "lts-half");
symbolsPerFrame = clFrames.at(0).size();
single_gain = tddConfCl.value("single_gain", true);
single_gain = tddConfCl.value("single_gain", true);
}
}
......@@ -215,6 +219,13 @@ Config::Config(const std::string& jsonfile)
beacon = Utils::cint16_to_uint32(beacon_ci16, false, "QI");
coeffs = Utils::cint16_to_uint32(gold_ifft_ci16, true, "QI");
int fracBeacon = subframeSize % beaconSize;
std::vector<std::complex<int16_t>> preBeacon(prefix, 0);
std::vector<std::complex<int16_t>> postBeacon(postfix + fracBeacon, 0);
beacon_ci16.insert(beacon_ci16.begin(), preBeacon.begin(), preBeacon.end());
beacon_ci16.insert(beacon_ci16.end(), postBeacon.begin(), postBeacon.end());
beacon = Utils::cint16_to_uint32(beacon_ci16, false, "QI");
// compose pilot subframe
if (fftSize != 64) {
fftSize = 64;
......@@ -430,3 +441,13 @@ unsigned Config::getCoreCount()
#endif
return nCores;
}
extern "C"
{
__attribute__((visibility("default"))) Config* Config_new(char *filename) {
Config *cfg = new Config(filename);
return cfg;
}
}
{
"BaseStations" : {
"cells" : 1,
"sdr_id" : ["files/usrp-bs-serials.txt"],
"frequency" : 3.6e9,
"channel" : "A",
"rxgainA" : 20,
"txgainA" : 15,
"rxgainB" : 20,
"txgainB" : 15,
"rate" : 50e6,
"frame_schedule" : [
"BGPGGGGGGGGGGGGGGGGG"
],
"max_frame" : 0,
"subframe_size" : 640,
"fft_size" : 64,
"cp_size" : 16,
"prefix" : 82,
"postfix" : 68,
"beacon_seq" : "gold_ifft",
"beamsweep" : true,
"sample_calibrate" : false,
"beacon_antenna" : 0,
"pilot_seq" : "lts-half"
}
}
{
"Clients" : {
"frequency" : 3.6e9,
"channel" : "A",
"agc_en" : false,
"rxgainA" : [20],
"txgainA" : [15],
"rxgainB" : [20],
"txgainB" : [15],
"rate" : 20e6,
"fft_size" : 64,
"subframe_size" : 640,
"cp_size" : 16,
"prefix" : 82,
"postfix" : 68,
"frame_schedule" : [
"GGPGGGGGGGGGGGGGGGGG"
],
"frame_mode" : "free_running",
"hw_framer" : false,
"beacon_type" : "gold_ifft",
"modulation" : "QPSK",
"pilot_seq" : "lts-half",
"sdr_id" : [
"10.118.3.2"
]
}
}
{
"BaseStations" : {
"cells" : 1,
"sdr_id" : ["files/usrp-bs-serials.txt"],
"frequency" : 3.6e9,
"channel" : "B",
"rxgainA" : 20,
"txgainA" : 15,
"rxgainB" : 20,
"txgainB" : 15,
"rate" : 50e6,
"frame_schedule" : [
"BGPGGGGGGGGGGGGGGGGG"
],
"max_frame" : 0,
"subframe_size" : 640,
"fft_size" : 64,
"cp_size" : 16,
"prefix" : 82,
"postfix" : 68,
"beacon_seq" : "gold_ifft",
"beamsweep" : true,
"sample_calibrate" : false,
"beacon_antenna" : 0,
"pilot_seq" : "lts-half",
"single_gain" : true
},
"Clients" : {
"frequency" : 3.6e9,
"channel" : "A",
"agc_en" : false,
"rxgainA" : [20],
"txgainA" : [15],
"rxgainB" : [20],
"txgainB" : [15],
"rate" : 50e6,
"frame_schedule" : [
"GGPGGGGGGGGGGGGGGGGG"
],
"frame_mode" : "free_running",
"hw_framer" : false,
"subframe_size" : 640,
"fft_size" : 64,
"cp_size" : 16,
"prefix" : 82,
"postfix" : 68,
"beacon_seq" : "gold_ifft",
"pilot_seq" : "lts-half",
"modulation" : "QPSK",
"sdr_id" : [
"10.118.3.2"
]
}
}
......@@ -20,6 +20,7 @@ public:
void radioRx(void* const* buffs);
int radioTx(size_t radio_id, const void* const* buffs, int flags, long long& frameTime);
int radioRx(size_t radio_id, void* const* buffs, long long& frameTime);
int radioRx(size_t radio_id, void* const* buffs, int numSamps, long long& frameTime);
void radioStart(void);
void radioStop(void);
bool getRadioNotFound() { return radioNotFound; }
......
#ifndef MACROS_H
#define MACROS_H
#ifdef USE_UHD
static constexpr bool kUseUHD = true;
#else
static constexpr bool kUseUHD = false;
#endif
#define DEBUG_PRINT 0
#define DEBUG_RADIO 0
#define DEBUG_PLOT 0
......
......@@ -52,6 +52,7 @@ struct Package {
}
};
// each thread has a SampleBuffer
struct SampleBuffer {
std::vector<char> buffer;
std::atomic_int* pkg_buf_inuse;
......
......@@ -21,6 +21,8 @@ public:
~Recorder();
void do_it();
int getRecordedFrameNum();
std::string getTraceFileName() {return cfg->trace_file;}