Commit 1a6c0287 authored by rubuntun's avatar rubuntun

driver for Iris boards and proper changes in the makefiles

parent 31413ac5
...@@ -480,7 +480,7 @@ add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4 ...@@ -480,7 +480,7 @@ add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4
add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4") add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4")
add_list1_option(NB_ANTENNAS_TXRX "2" "Number of antennas in ????" "1" "2" "4") add_list1_option(NB_ANTENNAS_TXRX "2" "Number of antennas in ????" "1" "2" "4")
add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR") add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR" "IRIS")
add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET") add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET")
...@@ -526,6 +526,12 @@ set(TPLIB_ETHERNET_SOURCE ...@@ -526,6 +526,12 @@ set(TPLIB_ETHERNET_SOURCE
) )
add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} ) add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/")
set (option_HWIRISLIB_lib "-l SoapySDR")
set(HWLIB_IRIS_SOURCE
${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp
)
add_library(oai_irisdevif MODULE ${HWLIB_IRIS_SOURCE} )
# RF devices / transport protocols settings # RF devices / transport protocols settings
###################################################################### ######################################################################
...@@ -570,6 +576,15 @@ elseif (${RF_BOARD} STREQUAL "OAI_LMSSDR") ...@@ -570,6 +576,15 @@ elseif (${RF_BOARD} STREQUAL "OAI_LMSSDR")
set(HW_SOURCE ${HW_SOURCE} ${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp) set(HW_SOURCE ${HW_SOURCE} ${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp)
set(option_HW_lib "-lLMS_SDR -lLMS7002M -lSi5351C -rdynamic -ldl") set(option_HW_lib "-lLMS_SDR -lLMS7002M -lSi5351C -rdynamic -ldl")
elseif (${RF_BOARD} STREQUAL "OAI_IRIS")
include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/")
include_directories("/usr/local/include/")
set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp)
LINK_DIRECTORIES("/usr/local/lib")
set(option_HW_lib "-lSoapySDR -rdynamic -ldl")
elseif (${RF_BOARD} STREQUAL "CPRIGW") elseif (${RF_BOARD} STREQUAL "CPRIGW")
set(HW_SOURCE ${HW_SOURCE} set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/CPRIGW/USERSPACE/LIB/cprigw_lib.c ${OPENAIR_TARGETS}/ARCH/CPRIGW/USERSPACE/LIB/cprigw_lib.c
......
...@@ -91,7 +91,7 @@ Options ...@@ -91,7 +91,7 @@ Options
default is Rel10, default is Rel10,
Rel8 limits the implementation to 3GPP Release 8 version Rel8 limits the implementation to 3GPP Release 8 version
-w | --hardware -w | --hardware
EXMIMO, USRP, BLADERF, ETHERNET, LMSSDR, None (Default) EXMIMO, USRP, BLADERF, ETHERNET, LMSSDR, IRIS, None (Default)
Adds this RF board support (in external packages installation and in compilation) Adds this RF board support (in external packages installation and in compilation)
-t | --transport protocol -t | --transport protocol
ETHERNET , None ETHERNET , None
...@@ -194,7 +194,7 @@ function main() { ...@@ -194,7 +194,7 @@ function main() {
-w | --hardware) -w | --hardware)
HW="$2" #"${i#*=}" HW="$2" #"${i#*=}"
# Use OAI_USRP as the key word USRP is used inside UHD driver # Use OAI_USRP as the key word USRP is used inside UHD driver
if [ "$HW" != "BLADERF" -a "$HW" != "USRP" -a "$HW" != "LMSSDR" -a "$HW" != "None" -a "$HW" != "EXMIMO" ] ; then if [ "$HW" != "BLADERF" -a "$HW" != "USRP" -a "$HW" != "LMSSDR" -a "$HW" != "None" -a "$HW" != "EXMIMO" -a "$HW" != "IRIS" ] ; then
echo_fatal "Unknown HW type $HW will exit..." echo_fatal "Unknown HW type $HW will exit..."
else else
if [ "$HW" == "USRP" ] ; then if [ "$HW" == "USRP" ] ; then
...@@ -206,6 +206,9 @@ function main() { ...@@ -206,6 +206,9 @@ function main() {
if [ "$HW" == "LMSSDR" ] ; then if [ "$HW" == "LMSSDR" ] ; then
HW="OAI_LMSSDR" HW="OAI_LMSSDR"
fi fi
if [ "$HW" == "IRIS" ] ; then
HW="OAI_IRIS"
fi
echo_info "Setting hardware to: $HW" echo_info "Setting hardware to: $HW"
fi fi
shift 2;; shift 2;;
...@@ -344,6 +347,8 @@ function main() { ...@@ -344,6 +347,8 @@ function main() {
DEADLINE_SCHEDULER_FLAG_USER="False" DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "OAI_LMSSDR" ] ; then elif [ "$HW" = "OAI_LMSSDR" ] ; then
DEADLINE_SCHEDULER_FLAG_USER="False" DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "OAI_IRIS" ] ; then
DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "None" ] ; then elif [ "$HW" = "None" ] ; then
DEADLINE_SCHEDULER_FLAG_USER="False" DEADLINE_SCHEDULER_FLAG_USER="False"
else else
...@@ -772,6 +777,14 @@ function main() { ...@@ -772,6 +777,14 @@ function main() {
ln -s liboai_lmssdrdevif.so liboai_device.so ln -s liboai_lmssdrdevif.so liboai_device.so
ln -s $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so ln -s $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so
echo_info "liboai_device.so is linked to LMSSDR device library" echo_info "liboai_device.so is linked to LMSSDR device library"
elif [ "$HW" == "OAI_IRIS" ] ; then
compilations \
$build_dir oai_irisdevif \
liboai_irisdevif.so $dbin/liboai_irisdevif.so.$REL
ln -s liboai_irisdevif.so liboai_device.so
ln -s $dbin/liboai_irisdevif.so.$REL $dbin/liboai_device.so
echo_info "liboai_device.so is linked to IRIS device library"
else else
echo_info "liboai_device.so is not linked to any device library" echo_info "liboai_device.so is not linked to any device library"
fi fi
......
...@@ -56,6 +56,9 @@ case USRP_X300_DEV: ...@@ -56,6 +56,9 @@ case USRP_X300_DEV:
case LMSSDR_DEV: case LMSSDR_DEV:
printf("[%s] has loaded LMSSDR device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); printf("[%s] has loaded LMSSDR device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
break; break;
case IRIS_DEV:
printf("[%s] has loaded Iris device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
break;
case NONE_DEV: case NONE_DEV:
printf("[%s] has not loaded a HW device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); printf("[%s] has not loaded a HW device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
break; break;
......
...@@ -95,6 +95,8 @@ typedef enum { ...@@ -95,6 +95,8 @@ typedef enum {
BLADERF_DEV, BLADERF_DEV,
/*!\brief device is LMSSDR (SoDeRa)*/ /*!\brief device is LMSSDR (SoDeRa)*/
LMSSDR_DEV, LMSSDR_DEV,
/*!\brief device is Iris */
IRIS_DEV,
/*!\brief device is NONE*/ /*!\brief device is NONE*/
NONE_DEV, NONE_DEV,
MAX_RF_DEV_TYPE MAX_RF_DEV_TYPE
......
IRIS_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.o
IRIS_FILE_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp
IRIS_CFLAGS += -I$(OPENAIR_TARGETS)/ARCH/COMMON -I$(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/COMMON
/** iris_lib.cpp
*
* \author: Rahman Doost-Mohammady : doost@rice.edu
*/
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <SoapySDR/Device.hpp>
#include <SoapySDR/Formats.hpp>
#include <SoapySDR/Time.hpp>
#include <boost/format.hpp>
#include <iostream>
#include <complex>
#include <fstream>
#include <cmath>
#include <time.h>
#include <limits>
#include "UTIL/LOG/log_extern.h"
#include "common_lib.h"
/*! \brief Iris Configuration */
typedef struct
{
// --------------------------------
// variables for Iris configuration
// --------------------------------
//! Iris device pointer
SoapySDR::Device *iris;
//create a send streamer and a receive streamer
//! Iris TX Stream
SoapySDR::Stream *txStream;
//! Iris RX Stream
SoapySDR::Stream *rxStream;
//! Sampling rate
double sample_rate;
//! time offset between transmiter timestamp and receiver timestamp;
double tdiff;
//! TX forward samples.
int tx_forward_nsamps; //166 for 20Mhz
// --------------------------------
// Debug and output control
// --------------------------------
//! Number of underflows
int num_underflows;
//! Number of overflows
int num_overflows;
//! Number of sequential errors
int num_seq_errors;
//! tx count
int64_t tx_count;
//! rx count
int64_t rx_count;
//! timestamp of RX packet
openair0_timestamp rx_timestamp;
} iris_state_t;
/*! \brief Called to start the Iris lime transceiver. Return 0 if OK, < 0 if error
@param device pointer to the device structure specific to the RF hardware target
*/
static int trx_iris_start(openair0_device *device)
{
iris_state_t *s = (iris_state_t*)device->priv;
long long timeNs = s->iris->getHardwareTime("") + 500000;
int flags = 0;
flags |= SOAPY_SDR_HAS_TIME;
int ret = s->iris->activateStream(s->rxStream, flags, timeNs, 0);
int ret2 = s->iris->activateStream(s->txStream);
if (ret < 0 | ret2 < 0)
return - 1;
return 0;
}
/*! \brief Terminate operation of the Iris lime transceiver -- free all associated resources
* \param device the hardware to use
*/
static void trx_iris_end(openair0_device *device)
{
iris_state_t *s = (iris_state_t*)device->priv;
s->iris->closeStream(s->txStream);
s->iris->closeStream(s->rxStream);
SoapySDR::Device::unmake(s->iris);
}
/*! \brief Called to send samples to the Iris RF target
@param device pointer to the device structure specific to the RF hardware target
@param timestamp The timestamp at whicch the first sample MUST be sent
@param buff Buffer which holds the samples
@param nsamps number of samples to be sent
@param antenna_id index of the antenna if the device has multiple anteannas
@param flags flags must be set to TRUE if timestamp parameter needs to be applied
*/
static int trx_iris_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags)
{
static long long int loop=0;
static long time_min=0, time_max=0, time_avg=0;
struct timespec tp_start, tp_end;
long time_diff;
int ret=0, ret_i=0;
int flag = 0;
iris_state_t *s = (iris_state_t*)device->priv;
clock_gettime(CLOCK_MONOTONIC_RAW, &tp_start);
if (flags)
flag |= SOAPY_SDR_HAS_TIME;
long long timeNs = SoapySDR::ticksToTimeNs(timestamp, s->sample_rate);
int samples_sent = 0;
uint32_t **samps = (uint32_t **)buff;
while (samples_sent < nsamps)
{
ret = s->iris->writeStream(s->txStream, (void **)samps, (size_t)(nsamps - samples_sent), flag, timeNs, 100000);
if (ret < 0) {
printf("Unable to write stream!\n");
break;
}
samples_sent += ret;
samps[0] += ret;
if (cc > 1)
samps[1] += ret;
}
if (samples_sent != nsamps) {
printf("[xmit] tx samples %d != %d\n",samples_sent,nsamps);
}
/*
flag = 0;
size_t channel = 0;
ret = s->iris->readStreamStatus(s->txStream, channel, flag, timeNs, 0);
if (ret == SOAPY_SDR_TIME_ERROR)
printf("[xmit] Time Error in tx stream!\n");
else if (ret == SOAPY_SDR_UNDERFLOW)
printf("[xmit] Underflow occured!\n");
else if (ret == SOAPY_SDR_TIMEOUT)
printf("[xmit] Timeout occured!\n");
else if (ret == SOAPY_SDR_STREAM_ERROR)
printf("[xmit] Stream (tx) error occured!\n");
*/
return nsamps;
}
/*! \brief Receive samples from hardware.
* Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
* the first channel. *ptimestamp is the time at which the first sample
* was received.
* \param device the hardware to use
* \param[out] ptimestamp the time at which the first sample was received.
* \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
* \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
* \param antenna_id Index of antenna for which to receive samples
* \returns the number of sample read
*/
static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc)
{
int ret = 0;
static long long nextTime;
static bool nextTimeValid = false;
iris_state_t *s = (iris_state_t*)device->priv;
long long timeNs = 0;
int flags = 0;
int samples_received = 0;
uint32_t **samps = (uint32_t **)buff;
while (samples_received < nsamps)
{
flags = 0;
ret = s->iris->readStream(s->rxStream, (void **)samps, (size_t)(nsamps-samples_received), flags, timeNs, 100000);
if (ret < 0)
{
if (ret == SOAPY_SDR_TIME_ERROR)
printf("[recv] Time Error in tx stream!\n");
else if (ret == SOAPY_SDR_OVERFLOW | (flags & SOAPY_SDR_END_ABRUPT))
printf("[recv] Overflow occured!\n");
else if (ret == SOAPY_SDR_TIMEOUT)
printf("[recv] Timeout occured!\n");
else if (ret == SOAPY_SDR_STREAM_ERROR)
printf("[recv] Stream (tx) error occured!\n");
else if (ret == SOAPY_SDR_CORRUPTION)
printf("[recv] Bad packet occured!\n");
break;
}
samples_received += ret;
samps[0] += ret;
if (cc > 1)
samps[1] += ret;
if (samples_received == ret) // first batch
{
if (flags & SOAPY_SDR_HAS_TIME)
{
nextTime = timeNs;
nextTimeValid = true;
}
}
}
if (samples_received < nsamps)
printf("[recv] received %d samples out of %d\n",samples_received,nsamps);
if (s->sample_rate != 0 && nextTimeValid)
{
s->rx_count += samples_received;
s->rx_timestamp = SoapySDR::timeNsToTicks(nextTime, s->sample_rate);
*ptimestamp = s->rx_timestamp;
nextTime += SoapySDR::ticksToTimeNs(samples_received, s->sample_rate);
}
return samples_received;
}
/*! \brief Get current timestamp of Iris
* \param device the hardware to use
*/
openair0_timestamp get_iris_time(openair0_device *device)
{
iris_state_t *s = (iris_state_t*)device->priv;
return SoapySDR::timeNsToTicks(s->iris->getHardwareTime(""), s->sample_rate);
}
/*! \brief Compares two variables within precision
* \param a first variable
* \param b second variable
*/
static bool is_equal(double a, double b)
{
return std::fabs(a-b) < std::numeric_limits<double>::epsilon();
}
/*! \brief Set frequencies (TX/RX)
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \param dummy dummy variable not used
* \returns 0 in success
*/
int trx_iris_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dont_block) {
iris_state_t *s = (iris_state_t*)device->priv;
printf("Setting Iris TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]);
s->iris->setFrequency(SOAPY_SDR_RX, 0, "RF", openair0_cfg[0].rx_freq[0]);
s->iris->setFrequency(SOAPY_SDR_TX, 0, "RF", openair0_cfg[0].tx_freq[0]);
s->iris->setFrequency(SOAPY_SDR_RX, 1, "RF", openair0_cfg[0].rx_freq[1]);
s->iris->setFrequency(SOAPY_SDR_TX, 1, "RF", openair0_cfg[0].tx_freq[1]);
return(0);
}
/*! \brief Set Gains (TX/RX)
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success
*/
int trx_iris_set_gains(openair0_device* device,
openair0_config_t *openair0_cfg) {
iris_state_t *s = (iris_state_t*)device->priv;
s->iris->setGain(SOAPY_SDR_RX, 0, openair0_cfg[0].rx_gain[0]);
s->iris->setGain(SOAPY_SDR_TX, 0, openair0_cfg[0].tx_gain[0]);
s->iris->setGain(SOAPY_SDR_RX, 1, openair0_cfg[0].rx_gain[1]);
s->iris->setGain(SOAPY_SDR_TX, 1, openair0_cfg[0].tx_gain[1]);
return(0);
}
/*! \brief Stop Iris
* \param card refers to the hardware index to use
*/
int trx_iris_stop(openair0_device* device) {
iris_state_t *s = (iris_state_t*)device->priv;
s->iris->deactivateStream(s->txStream);
s->iris->deactivateStream(s->rxStream);
return(0);
}
/*! \brief Iris RX calibration table */
rx_gain_calib_table_t calib_table_iris[] = {
{3500000000.0,0},
{2660000000.0,0},
{2300000000.0,0},
{1880000000.0,0},
{816000000.0,0},
{-1,0}};
/*! \brief Set RX gain offset
* \param openair0_cfg RF frontend parameters set by application
* \param chain_index RF chain to apply settings to
* \returns 0 in success
*/
void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_gain_adjust) {
int i=0;
// loop through calibration table to find best adjustment factor for RX frequency
double min_diff = 6e9,diff,gain_adj=0.0;
if (bw_gain_adjust==1) {
switch ((int)openair0_cfg[0].sample_rate) {
case 30720000:
break;
case 23040000:
gain_adj=1.25;
break;
case 15360000:
gain_adj=3.0;
break;
case 7680000:
gain_adj=6.0;
break;
case 3840000:
gain_adj=9.0;
break;
case 1920000:
gain_adj=12.0;
break;
default:
printf("unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate);
exit(-1);
break;
}
}
while (openair0_cfg->rx_gain_calib_table[i].freq>0) {
diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq);
printf("cal %d: freq %f, offset %f, diff %f\n",
i,
openair0_cfg->rx_gain_calib_table[i].freq,
openair0_cfg->rx_gain_calib_table[i].offset,diff);
if (min_diff > diff) {
min_diff = diff;
openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj;
}
i++;
}
}
/*! \brief print the Iris statistics
* \param device the hardware to use
* \returns 0 on success
*/
int trx_iris_get_stats(openair0_device* device) {
return(0);
}
/*! \brief Reset the Iris statistics
* \param device the hardware to use
* \returns 0 on success
*/
int trx_iris_reset_stats(openair0_device* device) {
return(0);
}
extern "C" {
/*! \brief Initialize Openair Iris target. It returns 0 if OK
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
*/
int device_init(openair0_device* device, openair0_config_t *openair0_cfg) {
size_t i;
int bw_gain_adjust=0;
openair0_cfg[0].rx_gain_calib_table = calib_table_iris;
iris_state_t *s = (iris_state_t*)malloc(sizeof(iris_state_t));
memset(s, 0, sizeof(iris_state_t));
// Initialize Iris device
device->openair0_cfg = openair0_cfg;
// add ip to cfg so that we can add to args
std::string args = "driver=remote,remote:prot=tcp";
s->iris = SoapySDR::Device::make(args);
device->type=IRIS_DEV;
switch ((int)openair0_cfg[0].sample_rate) {
case 30720000:
s->iris->setMasterClockRate(8*30.72e6);
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].tx_sample_advance = 115;
openair0_cfg[0].tx_bw = 30e6;
openair0_cfg[0].rx_bw = 30e6;
break;
case 23040000:
s->iris->setMasterClockRate(8*23.04e6);
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].tx_sample_advance = 113;
openair0_cfg[0].tx_bw = 30e6;
openair0_cfg[0].rx_bw = 30e6;
break;
case 15360000:
s->iris->setMasterClockRate(8*15.36e6);
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].tx_sample_advance = 103;
openair0_cfg[0].tx_bw = 30e6;
openair0_cfg[0].rx_bw = 30e6;
break;
case 7680000:
s->iris->setMasterClockRate(8*7.68e6); // sample*8=clock_rate for Soapy
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].tx_sample_advance = 80;
openair0_cfg[0].tx_bw = 30e6;
openair0_cfg[0].rx_bw = 30e6;
break;
case 1920000:
s->iris->setMasterClockRate(8*1.92e6);
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].tx_sample_advance = 40;
openair0_cfg[0].tx_bw = 30e6;
openair0_cfg[0].rx_bw = 30e6;
break;
default:
printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
exit(-1);
break;
}
for(i=0; i < s->iris->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < openair0_cfg[0].rx_num_channels) {
s->iris->setSampleRate(SOAPY_SDR_RX, i, openair0_cfg[0].sample_rate);
s->iris->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]);
set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust);
s->iris->setGain(SOAPY_SDR_RX, i, openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i]);
s->iris->setDCOffsetMode(SOAPY_SDR_RX, i, true); // move somewhere else
}
}
for(i=0; i < s->iris->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < openair0_cfg[0].tx_num_channels) {
s->iris->setSampleRate(SOAPY_SDR_TX, i, openair0_cfg[0].sample_rate);
s->iris->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]);
s->iris->setGain(SOAPY_SDR_TX, i, openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i]);
}
}
// display Iris settings
std::cout << boost::format("Actual master clock: %fMHz...") % (s->iris->getMasterClockRate()/1e6) << std::endl;
sleep(1);
int samples=openair0_cfg[0].sample_rate;
samples/=24000;
// create tx & rx streamer
const SoapySDR::Kwargs &arg = SoapySDR::Kwargs();
std::vector<size_t> channels={};
for (i = 0; i<openair0_cfg[0].rx_num_channels; i++)
if (i < s->iris->getNumChannels(SOAPY_SDR_RX))
channels.push_back(i);
s->rxStream = s->iris->setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, channels, arg);
std::vector<size_t> tx_channels={};
for (i = 0; i<openair0_cfg[0].tx_num_channels; i++)
if (i < s->iris->getNumChannels(SOAPY_SDR_TX))
tx_channels.push_back(i);
s->txStream = s->iris->setupStream(SOAPY_SDR_TX, SOAPY_SDR_CS16, tx_channels, arg);
/* Setting TX/RX BW after streamers are created due to iris calibration issue */
for(i = 0; i < openair0_cfg[0].tx_num_channels; i++) {
if (i < s->iris->getNumChannels(SOAPY_SDR_TX) ) {
s->iris->setBandwidth(SOAPY_SDR_TX, i, openair0_cfg[0].tx_bw);
printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->iris->getNumChannels(SOAPY_SDR_TX),openair0_cfg[0].tx_bw/1e6,s->iris->getBandwidth(SOAPY_SDR_TX, i)/1e6);
}
}
for(i = 0; i < openair0_cfg[0].rx_num_channels; i++) {
if (i < s->iris->getNumChannels(SOAPY_SDR_RX)) {
s->iris->setBandwidth(SOAPY_SDR_RX, i, openair0_cfg[0].rx_bw);
printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->iris->getNumChannels(SOAPY_SDR_RX),openair0_cfg[0].rx_bw/1e6,s->iris->getBandwidth(SOAPY_SDR_RX, i)/1e6);
}
}
s->iris->setHardwareTime(0, "");
for (i = 0; i < openair0_cfg[0].rx_num_channels; i++) {
if (i < s->iris->getNumChannels(SOAPY_SDR_RX)) {
printf("RX Channel %lu\n",i);
std::cout << boost::format("Actual RX sample rate: %fMSps...") % (s->iris->getSampleRate(SOAPY_SDR_RX, i)/1e6) << std::endl;
std::cout << boost::format("Actual RX frequency: %fGHz...") % (s->iris->getFrequency(SOAPY_SDR_RX, i)/1e9) << std::endl;
std::cout << boost::format("Actual RX gain: %f...") % (s->iris->getGain(SOAPY_SDR_RX, i)) << std::endl;
std::cout << boost::format("Actual RX bandwidth: %fM...") % (s->iris->getBandwidth(SOAPY_SDR_RX, i)/1e6) << std::endl;
std::cout << boost::format("Actual RX antenna: %s...") % (s->iris->getAntenna(SOAPY_SDR_RX, i)) << std::endl;
}
}
for (i=0;i<openair0_cfg[0].tx_num_channels;i++) {
if (i < s->iris->getNumChannels(SOAPY_SDR_TX)) {
printf("TX Channel %lu\n",i);
std::cout << std::endl<<boost::format("Actual TX sample rate: %fMSps...") % (s->iris->getSampleRate(SOAPY_SDR_TX, i)/1e6) << std::endl;
std::cout << boost::format("Actual TX frequency: %fGHz...") % (s->iris->getFrequency(SOAPY_SDR_TX, i)/1e9) << std::endl;
std::cout << boost::format("Actual TX gain: %f...") % (s->iris->getGain(SOAPY_SDR_TX, i)) << std::endl;
std::cout << boost::format("Actual TX bandwidth: %fM...") % (s->iris->getBandwidth(SOAPY_SDR_TX, i)/1e6) << std::endl;
std::cout << boost::format("Actual TX antenna: %s...") % (s->iris->getAntenna(SOAPY_SDR_TX, i)) << std::endl;
}
}
std::cout << boost::format("Device timestamp: %f...") % (s->iris->getHardwareTime()/1e9) << std::endl;
device->priv = s;
device->trx_start_func = trx_iris_start;
device->trx_write_func = trx_iris_write;
device->trx_read_func = trx_iris_read;
device->trx_get_stats_func = trx_iris_get_stats;
device->trx_reset_stats_func = trx_iris_reset_stats;
device->trx_end_func = trx_iris_end;
device->trx_stop_func = trx_iris_stop;
device->trx_set_freq_func = trx_iris_set_freq;
device->trx_set_gains_func = trx_iris_set_gains;
device->openair0_cfg = openair0_cfg;
s->sample_rate = openair0_cfg[0].sample_rate;
// TODO:
// init tx_forward_nsamps based iris_time_offset ex
if(is_equal(s->sample_rate, (double)30.72e6))
s->tx_forward_nsamps = 176;
if(is_equal(s->sample_rate, (double)15.36e6))
s->tx_forward_nsamps = 90;
if(is_equal(s->sample_rate, (double)7.68e6))
s->tx_forward_nsamps = 50;
return 0;
}
}
/*@}*/
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1";
mobile_country_code = "208";
mobile_network_code = "94";
////////// Physical parameters:
component_carriers = (
{
node_function = "eNodeB_3GPP";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2660000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 57;
N_RB_DL = 6;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 2;
nb_antennas_rx = 2;
tx_gain = 52;
rx_gain = 40;
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -24;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -90;
pusch_alpha = "AL1";
pucch_p0_Nominal = -96;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -104;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.70";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth1";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.146/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth1";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.146/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
}
);
...@@ -120,6 +120,13 @@ CFLAGS += -DOAI_USRP ...@@ -120,6 +120,13 @@ CFLAGS += -DOAI_USRP
LDFLAGS += -L/usr/lib/ -luhd -lpthread -lstdc++ LDFLAGS += -L/usr/lib/ -luhd -lpthread -lstdc++
endif endif
ifeq ($(IRIS),1)
include $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/Makefile.inc
CFLAGS += -I/usr/local/include/ -L/usr/local/lib -lSoapySDR -lpthread -lstdc++
CFLAGS += -DOAI_IRIS
LDFLAGS += -L/usr/local/lib/ -lSoapySDR -lpthread -lstdc++
endif
ifeq ($(ETHERNET),1) ifeq ($(ETHERNET),1)
include $(OPENAIR_TARGETS)/ARCH/ETHERNET/USERSPACE/LIB/Makefile.inc include $(OPENAIR_TARGETS)/ARCH/ETHERNET/USERSPACE/LIB/Makefile.inc
LDFLAGS += -lpthread LDFLAGS += -lpthread
......
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