Commit 2c230f83 authored by rdoost's avatar rdoost

working tdd/fdd at 5 and 10 Mhz

parent 36d3e624
......@@ -2017,7 +2017,7 @@ void prach_procedures(PHY_VARS_eNB *eNB) {
eNB->UE_stats[(uint32_t)UE_id].UE_timing_offset = preamble_delay_list[preamble_max]&0x1FFF; //limit to 13 (=11+2) bits
eNB->UE_stats[(uint32_t)UE_id].sector = 0;
LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure (UE_id %d) with preamble %d, energy %d.%d dB, delay %d\n",
LOG_D(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure (UE_id %d) with preamble %d, energy %d.%d dB, delay %d\n",
eNB->Mod_id,
eNB->CC_id,
frame,
......@@ -3042,7 +3042,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
#endif
stop_meas(&eNB->ulsch_decoding_stats);
LOG_G(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
eNB->Mod_id,harq_pid,
frame,subframe,
eNB->ulsch[i]->rnti,
......
......@@ -125,7 +125,7 @@ skb_p->mark = rb_idP;
skb_p->ip_summed = CHECKSUM_UNNECESSARY;
ipv_p = (struct ipversion*)((void*)&(skb_p->data[hard_header_len]));
ipv_p = (ipversion_t *)((void*)&(skb_p->data[hard_header_len]));
switch (ipv_p->version) {
......
......@@ -243,7 +243,12 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP)
// End debug information
netif_stop_queue(dev_pP);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
netif_trans_update(dev_pP);
#else
dev_pP->trans_start = jiffies;
#endif
#ifdef OAI_DRV_DEBUG_DEVICE
printk("[UE_IP_DRV][%s] step 1\n", __FUNCTION__);
#endif
......@@ -315,7 +320,11 @@ void ue_ip_tx_timeout(struct net_device *dev_pP)
printk("[UE_IP_DRV][%s] begin\n", __FUNCTION__);
// (ue_ip_priv_t *)(dev_pP->priv_p)->stats.tx_errors++;
(priv_p->stats).tx_errors++;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
netif_trans_update(dev_pP);
#else
dev_pP->trans_start = jiffies;
#endif
netif_wake_queue(dev_pP);
printk("[UE_IP_DRV][%s] transmit timed out %s\n", __FUNCTION__,dev_pP->name);
}
......
......@@ -20,26 +20,26 @@
#include <limits>
#include "UTIL/LOG/log_extern.h"
#include "common_lib.h"
#include <chrono>
#define SAMPLE_RATE_DOWN 1
/*! \brief Iris Configuration */
typedef struct
{
typedef struct {
// --------------------------------
// variables for Iris configuration
// --------------------------------
//! Iris device pointer
std::vector<SoapySDR::Device*> iris;
std::vector<SoapySDR::Device *> iris;
int device_num;
int rx_num_channels;
int tx_num_channels;
//create a send streamer and a receive streamer
//! Iris TX Stream
std::vector<SoapySDR::Stream*> txStream;
std::vector<SoapySDR::Stream *> txStream;
//! Iris RX Stream
std::vector<SoapySDR::Stream*> rxStream;
std::vector<SoapySDR::Stream *> rxStream;
//! Sampling rate
double sample_rate;
......@@ -73,20 +73,18 @@ typedef struct
/*! \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;
static int trx_iris_start(openair0_device *device) {
iris_state_t *s = (iris_state_t *) device->priv;
long long timeNs = s->iris[0]->getHardwareTime("") + 500000;
int flags = 0;
//flags |= SOAPY_SDR_HAS_TIME;
int r;
for (r = 0; r < s->device_num; r++)
{
for (r = 0; r < s->device_num; r++) {
int ret = s->iris[r]->activateStream(s->rxStream[r], flags, timeNs, 0);
int ret2 = s->iris[r]->activateStream(s->txStream[r]);
if (ret < 0 | ret2 < 0)
return - 1;
return -1;
}
return 0;
}
......@@ -94,28 +92,25 @@ static int trx_iris_start(openair0_device *device)
/*! \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;
int trx_iris_stop(openair0_device *device) {
iris_state_t *s = (iris_state_t *) device->priv;
int r;
for (r = 0; r < s->device_num; r++)
{
for (r = 0; r < s->device_num; r++) {
s->iris[r]->deactivateStream(s->txStream[r]);
s->iris[r]->deactivateStream(s->rxStream[r]);
}
return(0);
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)
{
LOG_I(HW,"Closing Iris device.\n");
static void trx_iris_end(openair0_device *device) {
LOG_I(HW, "Closing Iris device.\n");
trx_iris_stop(device);
iris_state_t *s = (iris_state_t*)device->priv;
iris_state_t *s = (iris_state_t *) device->priv;
int r;
for (r = 0; r < s->device_num; r++)
{
for (r = 0; r < s->device_num; r++) {
s->iris[r]->closeStream(s->txStream[r]);
s->iris[r]->closeStream(s->rxStream[r]);
SoapySDR::Device::unmake(s->iris[r]);
......@@ -130,70 +125,65 @@ static void trx_iris_end(openair0_device *device)
@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;
static int
trx_iris_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
using namespace std::chrono;
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 ret = 0, ret_i = 0;
int flag = 0;
iris_state_t *s = (iris_state_t*)device->priv;
iris_state_t *s = (iris_state_t *) device->priv;
clock_gettime(CLOCK_MONOTONIC_RAW, &tp_start);
// This hack was added by cws to help keep packets flowing
if (flags == 8) {
long long tempHack = s->iris[0]->getHardwareTime("");
return nsamps;
}
if (flags)
flag |= SOAPY_SDR_HAS_TIME;
if (flags == 2 || flags == 1) { // start of burst
}else if (flags == 3 || flags == 4){
} else if (flags == 3 || flags == 4) {
flag |= SOAPY_SDR_END_BURST;
}
long long timeNs = SoapySDR::ticksToTimeNs(timestamp, s->sample_rate/SAMPLE_RATE_DOWN);
long long timeNs = SoapySDR::ticksToTimeNs(timestamp, s->sample_rate / SAMPLE_RATE_DOWN);
uint32_t *samps[2]; //= (uint32_t **)buff;
int r;
int m = s->tx_num_channels;
for (r = 0; r < s->device_num; r++)
{
for (r = 0; r < s->device_num; r++) {
int samples_sent = 0;
samps[0] = (uint32_t *)buff[m*r];
samps[0] = (uint32_t *) buff[m * r];
if (cc % 2 == 0)
samps[1] = (uint32_t *)buff[m*r+1]; //cws: it seems another thread can clobber these, so we need to save them locally.
while (samples_sent < nsamps)
{
ret = s->iris[r]->writeStream(s->txStream[r], (void **)samps, (size_t)(nsamps - samples_sent), flag, timeNs, 1000000);
if (ret < 0) {
samps[1] = (uint32_t *) buff[m * r +
1]; //cws: it seems another thread can clobber these, so we need to save them locally.
//printf("\nHardware time before write: %lld, tx_time_stamp: %lld\n", s->iris[0]->getHardwareTime(""), timeNs);
ret = s->iris[r]->writeStream(s->txStream[r], (void **) samps, (size_t)(nsamps), flag, timeNs, 1000000);
if (ret < 0)
printf("Unable to write stream!\n");
break;
}
flag = 0;
samples_sent += ret;
samps[0] += ret;
if (cc % 2 == 0)
samps[1] += ret;
}
else
samples_sent = ret;
if (samples_sent != nsamps)
printf("[xmit] tx samples %d != %d\n", samples_sent, nsamps);
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;
}
......@@ -208,35 +198,30 @@ static int trx_iris_write(openair0_device *device, openair0_timestamp timestamp,
* \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)
{
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;
iris_state_t *s = (iris_state_t *) device->priv;
bool time_set = false;
long long timeNs = 0;
int flags;
int samples_received;
uint32_t *samps[2]; //= (uint32_t **)buff;
//printf("Reading %d samples from Iris...\n", nsamps);
//fflush(stdout);
int r;
int m = s->rx_num_channels;
for (r = 0; r < s->device_num; r++)
{
for (r = 0; r < s->device_num; r++) {
flags = 0;
samples_received = 0;
samps[0] = (uint32_t *)buff[m*r];
samps[0] = (uint32_t *) buff[m * r];
if (cc % 2 == 0)
samps[1] = (uint32_t *)buff[m*r+1];
//uint32_t *samps[2] = {(uint32_t *)buff[2*r], (uint32_t *)buff[2*r+1]}; //cws: it seems another thread can clobber these, so we need to save them locally.
while (samples_received < nsamps)
{
samps[1] = (uint32_t *) buff[m * r + 1];
flags = 0;
ret = s->iris[r]->readStream(s->rxStream[r], (void **)samps, (size_t)(nsamps-samples_received), flags, timeNs, 1000000);
if (ret < 0)
{
ret = s->iris[r]->readStream(s->rxStream[r], (void **) samps, (size_t)(nsamps - samples_received), flags,
timeNs, 1000000);
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))
......@@ -248,19 +233,15 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp
else if (ret == SOAPY_SDR_CORRUPTION)
printf("[recv] Bad packet occured!\n");
break;
}
} else
samples_received = ret;
samples_received += ret;
samps[0] += ret;
if (cc % 2 == 0)
samps[1] += ret;
if (r == 0)
{
if (r == 0) {
if (samples_received == ret) // first batch
{
if (flags & SOAPY_SDR_HAS_TIME)
{
s->rx_timestamp = SoapySDR::timeNsToTicks(timeNs, s->sample_rate/SAMPLE_RATE_DOWN);
if (flags & SOAPY_SDR_HAS_TIME) {
s->rx_timestamp = SoapySDR::timeNsToTicks(timeNs, s->sample_rate / SAMPLE_RATE_DOWN);
*ptimestamp = s->rx_timestamp;
nextTime = timeNs;
nextTimeValid = true;
......@@ -269,23 +250,29 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp
}
}
}
if (r == 0) {
if (samples_received == nsamps) {
if (flags & SOAPY_SDR_HAS_TIME) {
s->rx_timestamp = SoapySDR::timeNsToTicks(nextTime, s->sample_rate / SAMPLE_RATE_DOWN);
*ptimestamp = s->rx_timestamp;
nextTime = timeNs;
nextTimeValid = true;
time_set = true;
}
if (r == 0)
{
if (samples_received < nsamps)
printf("[recv] received %d samples out of %d\n",samples_received,nsamps);
} else if (samples_received < nsamps)
printf("[recv] received %d samples out of %d\n", samples_received, nsamps);
s->rx_count += samples_received;
if (s->sample_rate != 0 && nextTimeValid)
{
if (!time_set)
{
s->rx_timestamp = SoapySDR::timeNsToTicks(nextTime, s->sample_rate/SAMPLE_RATE_DOWN);
if (s->sample_rate != 0 && nextTimeValid) {
if (!time_set) {
s->rx_timestamp = SoapySDR::timeNsToTicks(nextTime, s->sample_rate / SAMPLE_RATE_DOWN);
*ptimestamp = s->rx_timestamp;
//printf("2) time set %llu, nextTime will be %llu \n", *ptimestamp, nextTime);
}
nextTime += SoapySDR::ticksToTimeNs(samples_received, s->sample_rate/SAMPLE_RATE_DOWN);
nextTime += SoapySDR::ticksToTimeNs(samples_received, s->sample_rate / SAMPLE_RATE_DOWN);
}
}
}
......@@ -295,9 +282,8 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp
/*! \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;
openair0_timestamp get_iris_time(openair0_device *device) {
iris_state_t *s = (iris_state_t *) device->priv;
return SoapySDR::timeNsToTicks(s->iris[0]->getHardwareTime(""), s->sample_rate);
}
......@@ -305,61 +291,58 @@ openair0_timestamp get_iris_time(openair0_device *device)
* \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();
static bool is_equal(double a, double b) {
return std::fabs(a - b) < std::numeric_limits<double>::epsilon();
}
void *set_freq_thread(void *arg) {
openair0_device *device=(openair0_device *)arg;
iris_state_t *s = (iris_state_t*)device->priv;
openair0_device *device = (openair0_device *) arg;
iris_state_t *s = (iris_state_t *) device->priv;
int r, i;
printf("Setting Iris TX Freq %f, RX Freq %f\n",device->openair0_cfg[0].tx_freq[0],device->openair0_cfg[0].rx_freq[0]);
printf("Setting Iris TX Freq %f, RX Freq %f\n", device->openair0_cfg[0].tx_freq[0],
device->openair0_cfg[0].rx_freq[0]);
// add check for the number of channels in the cfg
for (r = 0; r < s->device_num; r++)
{
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
for (r = 0; r < s->device_num; r++) {
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels)
s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", device->openair0_cfg[0].rx_freq[i]);
}
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels)
s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", device->openair0_cfg[0].tx_freq[i]);
}
}
}
/*! \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;
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;
pthread_t f_thread;
if (dont_block)
pthread_create(&f_thread, NULL, set_freq_thread, (void*)device);
else
{
pthread_create(&f_thread, NULL, set_freq_thread, (void *) device);
else {
int r, i;
for (r = 0; r < s->device_num; r++)
{
printf("Setting Iris TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]);
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
for (r = 0; r < s->device_num; r++) {
printf("Setting Iris TX Freq %f, RX Freq %f\n", openair0_cfg[0].tx_freq[0], openair0_cfg[0].rx_freq[0]);
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels) {
s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]);
}
}
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels) {
s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]);
}
}
}
}
return(0);
return (0);
}
......@@ -368,29 +351,28 @@ int trx_iris_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,
* \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success
*/
int trx_iris_set_gains(openair0_device* device,
int trx_iris_set_gains(openair0_device *device,
openair0_config_t *openair0_cfg) {
iris_state_t *s = (iris_state_t*)device->priv;
iris_state_t *s = (iris_state_t *) device->priv;
int r;
for (r = 0; r < s->device_num; r++)
{
for (r = 0; r < s->device_num; r++) {
s->iris[r]->setGain(SOAPY_SDR_RX, 0, openair0_cfg[0].rx_gain[0]);
s->iris[r]->setGain(SOAPY_SDR_TX, 0, openair0_cfg[0].tx_gain[0]);
s->iris[r]->setGain(SOAPY_SDR_RX, 1, openair0_cfg[0].rx_gain[1]);
s->iris[r]->setGain(SOAPY_SDR_TX, 1, openair0_cfg[0].tx_gain[1]);
}
return(0);
return (0);
}
/*! \brief Iris RX calibration table */
rx_gain_calib_table_t calib_table_iris[] = {
{3500000000.0,83},
{2660000000.0,83},
{2580000000.0,83},
{2300000000.0,83},
{1880000000.0,83},
{816000000.0,83},
{-1,0}};
{3500000000.0, 83},
{2660000000.0, 83},
{2580000000.0, 83},
{2300000000.0, 83},
{1880000000.0, 83},
{816000000.0, 83},
{-1, 0}};
/*! \brief Set RX gain offset
......@@ -398,61 +380,60 @@ rx_gain_calib_table_t calib_table_iris[] = {
* \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) {
void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index, int bw_gain_adjust) {
int i=0;
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) {
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;
gain_adj = 1.25;
break;
case 15360000:
gain_adj=3.0;
gain_adj = 3.0;
break;
case 7680000:
gain_adj=6.0;
gain_adj = 6.0;
break;
case 3840000:
gain_adj=9.0;
gain_adj = 9.0;
break;
case 1920000:
gain_adj=12.0;
gain_adj = 12.0;
break;
default:
printf("unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate);
printf("unknown sampling rate %d\n", (int) openair0_cfg[0].sample_rate);
exit(-1);
break;
}
}
if (openair0_cfg[0].gain_calib_val == 0){
while (openair0_cfg->rx_gain_calib_table[i].freq>0) {
if (openair0_cfg[0].gain_calib_val == 0) {
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);
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;
openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset + gain_adj;
}
i++;
}
}
else
openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg[0].gain_calib_val+gain_adj;
} else
openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg[0].gain_calib_val + gain_adj;
}
/*! \brief print the Iris statistics
* \param device the hardware to use
* \returns 0 on success
*/
int trx_iris_get_stats(openair0_device* device) {
int trx_iris_get_stats(openair0_device *device) {
return(0);
return (0);
}
......@@ -460,82 +441,90 @@ int trx_iris_get_stats(openair0_device* device) {
* \param device the hardware to use
* \returns 0 on success
*/
int trx_iris_reset_stats(openair0_device* device) {
int trx_iris_reset_stats(openair0_device *device) {
return(0);
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) {
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
size_t i,r,card;
int bw_gain_adjust=0;
size_t i, r, card;
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));
iris_state_t *s = (iris_state_t *) malloc(sizeof(iris_state_t));
memset(s, 0, sizeof(iris_state_t));
std::string devFE("DEV");
std::string cbrsFE("CBRS");
std::string wireFormat("WIRE");
// Initialize Iris device
device->openair0_cfg = openair0_cfg;
SoapySDR::Kwargs args;
for (card = 0; card < MAX_CARDS; card++)
{
char* remote_addr = device->openair0_cfg[card].remote_addr;
if (remote_addr == NULL) {printf("Opened %d cards...\n", card);break;}
char* drvtype = strtok(remote_addr, ",");
printf("\nMAX_CARDS: %d\n", MAX_CARDS);
for (card = 0; card < 1; card++) {
char *remote_addr = device->openair0_cfg[card].remote_addr;
if (remote_addr == NULL) {
printf("Opened %lu cards...\n", card);
break;
}
char *drvtype = strtok(remote_addr, ",");
char *srl = strtok(NULL, ",");
while (srl != NULL)
{
LOG_I(HW,"Attempting to open Iris device: %s\n", srl);
args["driver"] = drvtype;
args["serial"] = srl;
while (srl != NULL) {
LOG_I(HW, "Attempting to open Iris device\n");//, srl);
args["driver"] = "iris";//drvtype;
args["serial"] = srl; //Ali: Debugging...was "serial"
s->iris.push_back(SoapySDR::Device::make(args));
srl = strtok(NULL, ",");
}
//openair0_cfg[0].iq_txshift = 4;//if radio needs OAI to shift left the tx samples for preserving bit precision
openair0_cfg[0].iq_txshift = 4;//if radio needs OAI to shift left the tx samples for preserving bit precision
openair0_cfg[0].iq_rxrescale = 15;
}
s->device_num = s->iris.size();
device->type=IRIS_DEV;
device->type = IRIS_DEV;
switch ((int)openair0_cfg[0].sample_rate) {
switch ((int) openair0_cfg[0].sample_rate) {
case 30720000:
//openair0_cfg[0].samples_per_packet = 1024;
//openair0_cfg[0].tx_sample_advance = 115;
openair0_cfg[0].tx_sample_advance = 115;
openair0_cfg[0].tx_bw = 20e6;
openair0_cfg[0].rx_bw = 20e6;
break;
case 23040000:
//openair0_cfg[0].samples_per_packet = 1024;
//openair0_cfg[0].tx_sample_advance = 113;
openair0_cfg[0].tx_sample_advance = 113;
openair0_cfg[0].tx_bw = 15e6;
openair0_cfg[0].rx_bw = 15e6;
break;
case 15360000:
//openair0_cfg[0].samples_per_packet = 1024;
//openair0_cfg[0].tx_sample_advance = 103;
openair0_cfg[0].tx_sample_advance = 60;
openair0_cfg[0].tx_bw = 10e6;
openair0_cfg[0].rx_bw = 10e6;
break;
case 7680000:
//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;
openair0_cfg[0].tx_sample_advance = 30;
openair0_cfg[0].tx_bw = 5e6;
openair0_cfg[0].rx_bw = 5e6;
break;
case 1920000:
//openair0_cfg[0].samples_per_packet = 1024;
//openair0_cfg[0].tx_sample_advance = 40;
openair0_cfg[0].tx_bw = 5e6;
openair0_cfg[0].rx_bw = 5e6;
openair0_cfg[0].tx_sample_advance = 40;
openair0_cfg[0].tx_bw = 1.4e6;
openair0_cfg[0].rx_bw = 1.4e6;
break;
default:
printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
printf("Error: unknown sampling rate %f\n", openair0_cfg[0].sample_rate);
exit(-1);
break;
}
......@@ -545,101 +534,232 @@ extern "C" {
s->tx_num_channels = openair0_cfg[0].tx_num_channels;
if ((s->rx_num_channels == 1 || s->rx_num_channels == 2) && (s->tx_num_channels == 1 || s->tx_num_channels == 2))
printf("Enabling %d rx and %d tx channel(s) on each device...\n", s->rx_num_channels, s->tx_num_channels);
else
{
else {
printf("Invalid rx or tx number of channels (%d, %d)\n", s->rx_num_channels, s->tx_num_channels);
exit(-1);
}
for (r = 0; r < s->device_num; r++)
{
s->iris[r]->setMasterClockRate(8*openair0_cfg[0].sample_rate); // sample*8=clock_rate for Soapy
for (r = 0; r < s->device_num; r++) {
switch ((int) openair0_cfg[0].sample_rate) {
case 1920000:
s->iris[r]->setMasterClockRate(256 * openair0_cfg[0].sample_rate);
break;
case 3840000:
s->iris[r]->setMasterClockRate(128 * openair0_cfg[0].sample_rate);
break;
case 7680000:
s->iris[r]->setMasterClockRate(64 * openair0_cfg[0].sample_rate);
break;
case 15360000:
s->iris[r]->setMasterClockRate(32 * openair0_cfg[0].sample_rate);
break;
case 30720000:
s->iris[r]->setMasterClockRate(16 * openair0_cfg[0].sample_rate);
break;
default:
printf("Error: unknown sampling rate %f\n", openair0_cfg[0].sample_rate);
exit(-1);
break;
}
// display Iris settings
printf("Actual master clock: %fMHz...\n", (s->iris[r]->getMasterClockRate()/1e6));
printf("Actual master clock: %fMHz...\n", (s->iris[r]->getMasterClockRate() / 1e6));
/* Setting TX/RX BW after streamers are created due to iris calibration issue */
for(i = 0; i < s->tx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX) ) {
for (i = 0; i < s->tx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) {
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0)
s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, 30e6);
else
s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, openair0_cfg[0].tx_bw);
printf("Setting tx bandwidth on channel %lu/%lu: BW %f (readback %f)\n",i,s->iris[r]->getNumChannels(SOAPY_SDR_TX),openair0_cfg[0].tx_bw/1e6,s->iris[r]->getBandwidth(SOAPY_SDR_TX, i)/1e6);
printf("Setting tx bandwidth on channel %lu/%lu: BW %f (readback %f)\n", i,
s->iris[r]->getNumChannels(SOAPY_SDR_TX), openair0_cfg[0].tx_bw / 1e6,
s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6);
}
}
for(i = 0; i < s->rx_num_channels; i++) {
for (i = 0; i < s->rx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) {
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0)
s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, 30e6);
else
s->iris[r]->setBandwidth(SOAPY_SDR_RX, i, openair0_cfg[0].rx_bw);
printf("Setting rx bandwidth on channel %lu/%lu : BW %f (readback %f)\n",i,s->iris[r]->getNumChannels(SOAPY_SDR_RX),openair0_cfg[0].rx_bw/1e6,s->iris[r]->getBandwidth(SOAPY_SDR_RX, i)/1e6);
printf("Setting rx bandwidth on channel %lu/%lu : BW %f (readback %f)\n", i,
s->iris[r]->getNumChannels(SOAPY_SDR_RX), openair0_cfg[0].rx_bw / 1e6,
s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6);
}
}
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels) {
s->iris[r]->setSampleRate(SOAPY_SDR_RX, i, openair0_cfg[0].sample_rate/SAMPLE_RATE_DOWN);
s->iris[r]->setSampleRate(SOAPY_SDR_RX, i, openair0_cfg[0].sample_rate / SAMPLE_RATE_DOWN);
s->iris[r]->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[r]->setGain(SOAPY_SDR_RX, i, openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i]);
set_rx_gain_offset(&openair0_cfg[0], i, bw_gain_adjust);
//s->iris[r]->setGain(SOAPY_SDR_RX, i, openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]);
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]);
//s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", 0);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA1", 30);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA2", 17);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 0);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 0);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "ATTN", 0);
} else {
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]); // [0,30]
s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 0); // [0,12,6]
s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 0); // [-12,19,1]
//s->iris[r]->setGain(SOAPY_SDR_RX, i, 50); // [-12,19,1]
}
if (openair0_cfg[0].duplex_mode == 1) //duplex_mode_TDD
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "TRX");
else
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "RX");
if (openair0_cfg[0].duplex_mode == 1 ) //duplex_mode_TDD
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, s->iris[r]->listAntennas(SOAPY_SDR_RX, i)[0]);
s->iris[r]->setDCOffsetMode(SOAPY_SDR_RX, i, true); // move somewhere else
}
}
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels) {
s->iris[r]->setSampleRate(SOAPY_SDR_TX, i, openair0_cfg[0].sample_rate/SAMPLE_RATE_DOWN);
s->iris[r]->setSampleRate(SOAPY_SDR_TX, i, openair0_cfg[0].sample_rate / SAMPLE_RATE_DOWN);
s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]);
s->iris[r]->setGain(SOAPY_SDR_TX, i, openair0_cfg[0].tx_gain[i]);
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) == 0) {
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", openair0_cfg[0].tx_gain[i]);
//s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 52);
s->iris[r]->setGain(SOAPY_SDR_TX, i, "IAMP", 0);
//s->iris[r]->writeSetting("TX_ENABLE_DELAY", "0");
//s->iris[r]->writeSetting("TX_DISABLE_DELAY", "100");
} else {
s->iris[r]->setGain(SOAPY_SDR_TX, i, "ATTN", 0); // [-18, 0, 6] dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "IAMP", 0); // [-12, 12, 1] dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", openair0_cfg[0].tx_gain[i]);
//s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 35); // [0, 52, 1] dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA1", 9); // 17 ??? dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA2", 0); // [0, 17, 17] dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA3", 20); // 33 ??? dB
s->iris[r]->writeSetting("TX_ENABLE_DELAY", "0");
s->iris[r]->writeSetting("TX_DISABLE_DELAY", "100");
}
// if (openair0_cfg[0].duplex_mode == 0) {
// printf("\nFDD: Enable TX antenna override\n");
// s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "TX_ENB_OVERRIDE",
// "true"); // From Josh: forces tx switching to be on always transmit regardless of bursts
// }
}
}
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels) {
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
printf("\nUsing SKLK calibration...\n");
s->iris[r]->writeSetting(SOAPY_SDR_RX, i, "CALIBRATE", "SKLK");
} else {
s->iris[r]->writeSetting(SOAPY_SDR_RX, i, "CALIBRATE", "");
printf("\nUsing LMS calibration...\n");
}
}
}
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels) {
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
printf("\nUsing SKLK calibration...\n");
s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "CALIBRATE", "SKLK");
} else {
printf("\nUsing LMS calibration...\n");
s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "CALIBRATE", "");
}
}
}
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (openair0_cfg[0].duplex_mode == 0) {
printf("\nFDD: Setting receive antenna to %s\n", s->iris[r]->listAntennas(SOAPY_SDR_RX, i)[1].c_str());
if (i < s->rx_num_channels)
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "RX");
} else {
printf("\nTDD: Setting receive antenna to %s\n", s->iris[r]->listAntennas(SOAPY_SDR_RX, i)[0].c_str());
if (i < s->rx_num_channels)
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "TRX");
}
}
//s->iris[r]->writeSetting("TX_SW_DELAY", std::to_string(
// -openair0_cfg[0].tx_sample_advance)); //should offset switching to compensate for RF path (Lime) delay -- this will eventually be automated
// create tx & rx streamer
//const SoapySDR::Kwargs &arg = SoapySDR::Kwargs();
std::vector<size_t> channels;
std::map <std::string, std::string> rxStreamArgs;
rxStreamArgs["WIRE"] = SOAPY_SDR_CS16;
std::vector <size_t> channels;
for (i = 0; i < s->rx_num_channels; i++)
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX))
channels.push_back(i);
s->rxStream.push_back(s->iris[r]->setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, channels)); //, arg));
s->rxStream.push_back(s->iris[r]->setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, channels));//, rxStreamArgs));
std::vector<size_t> tx_channels={};
std::vector <size_t> tx_channels = {};
for (i = 0; i < s->tx_num_channels; i++)
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX))
tx_channels.push_back(i);
s->txStream.push_back(s->iris[r]->setupStream(SOAPY_SDR_TX, SOAPY_SDR_CS16, tx_channels)); //, arg));
//s->iris[r]->setHardwareTime(0, "");
std::cout << "Front end detected: " << s->iris[r]->getHardwareInfo()["frontend"] << "\n";
for (i = 0; i < s->rx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) {
printf("RX Channel %lu\n",i);
printf("Actual RX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_RX, i)/1e6) );
printf("Actual RX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_RX, i)/1e9) );
printf("Actual RX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i)) );
printf("Actual RX LNA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA")) );
printf("Actual RX PGA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "PGA")) );
printf("Actual RX TIA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "TIA")) );
printf("Actual RX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_RX, i)/1e6) );
printf("Actual RX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_RX, i).c_str()) );
printf("RX Channel %lu\n", i);
printf("Actual RX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_RX, i) / 1e6));
printf("Actual RX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_RX, i) / 1e9));
printf("Actual RX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i)));
printf("Actual RX LNA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA")));
printf("Actual RX PGA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "PGA")));
printf("Actual RX TIA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "TIA")));
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
printf("Actual RX LNA1 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA1")));
printf("Actual RX LNA2 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA2")));
}
printf("Actual RX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6));
printf("Actual RX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_RX, i).c_str()));
}
}
for (i=0;i < s->tx_num_channels;i++) {
for (i = 0; i < s->tx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) {
printf("TX Channel %lu\n",i);
printf("Actual TX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_TX, i)/1e6) );
printf("Actual TX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_TX, i)/1e9) );
printf("Actual TX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i)) );
printf("Actual TX PAD gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PAD")) );
printf("Actual TX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_TX, i)/1e6) );
printf("Actual TX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_TX, i).c_str()) );
printf("TX Channel %lu\n", i);
printf("Actual TX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_TX, i) / 1e6));
printf("Actual TX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_TX, i) / 1e9));
printf("Actual TX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i)));
printf("Actual TX PAD gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PAD")));
printf("Actual TX IAMP gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "IAMP")));
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
printf("Actual TX PA1 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA1")));
printf("Actual TX PA2 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA2")));
printf("Actual TX PA3 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA3")));
}
printf("Actual TX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6));
printf("Actual TX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_TX, i).c_str()));
}
}
}
s->iris[0]->writeSetting("SYNC_DELAYS","");
s->iris[0]->writeSetting("SYNC_DELAYS", "");
for (r = 0; r < s->device_num; r++)
s->iris[r]->setHardwareTime(0, "TRIGGER");
s->iris[0]->writeSetting("TRIGGER_GEN","");
s->iris[0]->writeSetting("TRIGGER_GEN", "");
for (r = 0; r < s->device_num; r++)
printf("Device timestamp: %f...\n", (s->iris[r]->getHardwareTime("TRIG")/1e9) );
printf("Device timestamp: %f...\n", (s->iris[r]->getHardwareTime("TRIGGER") / 1e9));
device->priv = s;
device->trx_start_func = trx_iris_start;
......@@ -656,16 +776,16 @@ extern "C" {
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))
if (is_equal(s->sample_rate, (double) 30.72e6))
s->tx_forward_nsamps = 176;
if(is_equal(s->sample_rate, (double)15.36e6))
if (is_equal(s->sample_rate, (double) 15.36e6))
s->tx_forward_nsamps = 90;
if(is_equal(s->sample_rate, (double)7.68e6))
if (is_equal(s->sample_rate, (double) 7.68e6))
s->tx_forward_nsamps = 50;
LOG_I(HW,"Finished initializing %d Iris device(s).\n", s->device_num);
LOG_I(HW, "Finished initializing %d Iris device(s).\n", s->device_num);
fflush(stdout);
return 0;
}
}
}
/*@}*/
......@@ -33,14 +33,14 @@ eNBs =
eutra_band = 38;
downlink_frequency = 2580000000L;
uplink_frequency_offset = 0;
Nid_cell = 57;
N_RB_DL = 25;
Nid_cell = 10;
N_RB_DL = 100;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 52;
rx_gain = 110;
tx_gain = 52; # [ ~50 for DEV-FE, ~30 for CBRS-FE ]
rx_gain = 115; # [ ~115 for DEV-FE, ~90 fir CBRS-FE ]
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
......@@ -50,7 +50,7 @@ eNBs =
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -60;
pdsch_referenceSignalPower = -30;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
......@@ -68,7 +68,7 @@ eNBs =
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -90;
pusch_p0_Nominal = -70;
pusch_alpha = "AL1";
pucch_p0_Nominal = -96;
msg3_delta_Preamble = 6;
......@@ -137,7 +137,7 @@ eNBs =
////////// MME parameters:
mme_ip_address = ( { ipv4 = "10.224.20.11";
mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "fe80::6a6:9555:ded:fafa/64";
active = "yes";
preference = "ipv4";
......@@ -145,16 +145,16 @@ eNBs =
);
rrh_gw_config = ({
local_if_name = "eth0";
remote_address = "iris,0205";
local_address = "10.224.20.40";
local_if_name = "eno1";
remote_address = "iris,100.0.0.101";
local_address = "10.0.0.108";
local_port = 50000; #for raw option local port must be the same to remote
remote_port = 50000;
rrh_gw_active = "yes";
tr_preference = "raw";
rf_preference = "iris030";
iq_txshift = 4;
tx_sample_advance = -40;
tx_sample_advance = 60;
tx_scheduling_advance = 9;
if_compression = "alaw";
}
......@@ -162,16 +162,10 @@ rrh_gw_config = ({
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
ENB_INTERFACE_NAME_FOR_S1_MME = "enp1s0f0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "10.224.20.35/26";
ENB_INTERFACE_NAME_FOR_S1U = "enp1s0f0";
ENB_IPV4_ADDRESS_FOR_S1U = "10.224.20.35/26";
ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
......@@ -180,9 +174,9 @@ rrh_gw_config = ({
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
hw_log_verbosity ="high";
phy_log_level ="info";
phy_log_verbosity ="medium";
phy_log_verbosity ="high";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
......
......@@ -17,7 +17,7 @@ eNBs =
mobile_country_code = "208";
mobile_network_code = "94";
mobile_network_code = "92";
////////// Physical parameters:
......@@ -39,7 +39,7 @@ eNBs =
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
tx_gain = 110;
rx_gain = 125;
prach_root = 0;
prach_config_index = 0;
......@@ -137,20 +137,36 @@ eNBs =
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.70";
mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
rrh_gw_config = ({
local_if_name = "eno1";
remote_address = "iris,RF3C000052";
local_address = "10.0.0.108";
local_port = 50000; #for raw option local port must be the same to remote
remote_port = 50000;
rrh_gw_active = "yes";
tr_preference = "raw";
rf_preference = "iris030";
iq_txshift = 4;
tx_sample_advance = -40;
tx_scheduling_advance = 9;
if_compression = "alaw";
}
);
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_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
......@@ -159,9 +175,9 @@ eNBs =
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
hw_log_verbosity ="high";
phy_log_level ="info";
phy_log_verbosity ="medium";
phy_log_verbosity ="high";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
......
......@@ -23,6 +23,11 @@ eNBs =
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;
......@@ -33,9 +38,10 @@ eNBs =
Nid_cell = 0;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
tx_gain = 110;
rx_gain = 115;
prach_root = 0;
prach_config_index = 0;
......@@ -97,6 +103,7 @@ eNBs =
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
}
);
......@@ -132,20 +139,41 @@ eNBs =
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.13.11";
mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
rrh_gw_config = ({
local_if_name = "eno1";
remote_address = "iris,RF3C000052";
local_address = "10.0.0.108";
local_port = 50000; #for raw option local port must be the same to remote
remote_port = 50000;
rrh_gw_active = "yes";
tr_preference = "raw";
rf_preference = "iris030";
iq_txshift = 4;
tx_sample_advance = -40;
tx_scheduling_advance = 9;
if_compression = "alaw";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.13.10/24";
ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "eth0";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.13.10/24";
ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
......
......@@ -39,8 +39,8 @@ eNBs =
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 52;
rx_gain = 110;
tx_gain = 52; # [~50 for DEV-FE, ~30 for CBRS-FE]
rx_gain = 115; # [115 for DEV-FE, 90 for CBRS-FE]
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
......@@ -137,7 +137,7 @@ eNBs =
////////// MME parameters:
mme_ip_address = ( { ipv4 = "10.224.20.11";
mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "fe80::6a6:9555:ded:fafa";
active = "yes";
preference = "ipv4";
......@@ -145,9 +145,9 @@ eNBs =
);
rrh_gw_config = ({
local_if_name = "eth0";
remote_address = "iris,0205";
local_address = "10.224.20.47"
local_if_name = "eno1";
remote_address = "iris,RF3C000052";
local_address = "100.0.0.108"
local_port = 50000; #for raw option local port must be the same to remote
remote_port = 50000;
rrh_gw_active = "yes";
......@@ -161,10 +161,10 @@ rrh_gw_config = ({
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "enp1s0f0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "10.224.20.35/26";
ENB_INTERFACE_NAME_FOR_S1U = "enp1s0f0";
ENB_IPV4_ADDRESS_FOR_S1U = "10.224.20.35/26";
ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
#ENB_INTERFACE_NAME_FOR_S1_MME = "enp1s0f0";
......@@ -183,7 +183,7 @@ rrh_gw_config = ({
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
mac_log_verbosity ="medium";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
......
......@@ -17,7 +17,7 @@ eNBs =
mobile_country_code = "208";
mobile_network_code = "94";
mobile_network_code = "92";
////////// Physical parameters:
......@@ -33,13 +33,13 @@ eNBs =
eutra_band = 7;
downlink_frequency = 2660000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
Nid_cell = 66;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
tx_gain = 110;
rx_gain = 125;
prach_root = 0;
prach_config_index = 0;
......@@ -137,20 +137,40 @@ eNBs =
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.70";
mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
rrh_gw_config = ({
local_if_name = "eno1";
remote_address = "iris,RF3C000052";
local_address = "10.0.0.108";
local_port = 50000; #for raw option local port must be the same to remote
remote_port = 50000;
rrh_gw_active = "yes";
tr_preference = "raw";
rf_preference = "iris030";
iq_txshift = 4;
tx_sample_advance = -40;
tx_scheduling_advance = 9;
if_compression = "alaw";
}
);
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_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
......
......@@ -30,6 +30,7 @@
* \warning
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
......@@ -53,6 +54,7 @@
#include "PHY/types.h"
#include "PHY/defs.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
......@@ -79,6 +81,7 @@
#include "PHY/TOOLS/smbv.h"
unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "UTIL/LOG/log_extern.h"
#include "UTIL/OTG/otg_tx.h"
#include "UTIL/OTG/otg_externs.h"
......@@ -89,7 +92,9 @@ unsigned short config_frames[4] = {2,9,11,13};
//#include "PHY/TOOLS/time_meas.h"
#ifndef OPENAIR2
#include "UTIL/OTG/otg_extern.h"
#endif
#if defined(ENABLE_ITTI)
......@@ -141,7 +146,7 @@ time_stats_t softmodem_stats_rx_sf; // total rx time
uint8_t seqno; //sequence number
static int time_offset[4] = {0,0,0,0};
static int time_offset[4] = {0, 0, 0, 0};
/* mutex, cond and variable to serialize phy proc TX calls
* (this mechanism may be relaxed in the future for better
......@@ -155,9 +160,10 @@ static struct {
extern double cpuf;
void exit_fun(const char* s);
void exit_fun(const char *s);
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[], int nb_inst, eth_params_t *, int);
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *,int);
void stop_eNB(int nb_inst);
......@@ -221,20 +227,20 @@ static inline void thread_top_init(char *thread_name,
/* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) {
perror( "pthread_getaffinity_np");
perror("pthread_getaffinity_np");
exit_fun("Error getting processor affinity ");
}
memset(cpu_affinity,0,sizeof(cpu_affinity));
memset(cpu_affinity, 0, sizeof(cpu_affinity));
for (j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, &cpuset)) {
char temp[1024];
sprintf (temp, " CPU_%d", j);
sprintf(temp, " CPU_%d", j);
strcat(cpu_affinity, temp);
}
memset(&sparam, 0, sizeof(sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
policy = SCHED_FIFO ;
policy = SCHED_FIFO;
s = pthread_setschedparam(pthread_self(), policy, &sparam);
if (s != 0) {
......@@ -248,12 +254,13 @@ static inline void thread_top_init(char *thread_name,
exit_fun("Error getting thread priority");
}
LOG_I(HW, "[SCHED][eNB] %s started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",thread_name,sched_getcpu(),gettid(),
LOG_I(HW, "[SCHED][eNB] %s started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",
thread_name, sched_getcpu(), gettid(),
(policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???",
sparam.sched_priority, cpu_affinity );
sparam.sched_priority, cpu_affinity);
#endif //LOW_LATENCY
......@@ -263,37 +270,36 @@ static inline void thread_top_init(char *thread_name,
static inline void wait_sync(char *thread_name) {
printf( "waiting for sync (%s)\n",thread_name);
pthread_mutex_lock( &sync_mutex );
printf("waiting for sync (%s)\n", thread_name);
pthread_mutex_lock(&sync_mutex);
while (sync_var<0)
pthread_cond_wait( &sync_cond, &sync_mutex );
while (sync_var < 0)
pthread_cond_wait(&sync_cond, &sync_mutex);
pthread_mutex_unlock(&sync_mutex);
printf( "got sync (%s)\n", thread_name);
printf("got sync (%s)\n", thread_name); fflush(stdout);
}
void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
{
void do_OFDM_mod_rt(int subframe, PHY_VARS_eNB *phy_vars_eNB) {
unsigned int aa,slot_offset;
unsigned int aa, slot_offset;
//int dummy_tx_b[7680*4] __attribute__((aligned(32)));
int i, tx_offset;
//int slot_sizeF = (phy_vars_eNB->frame_parms.ofdm_symbol_size)* ((phy_vars_eNB->frame_parms.Ncp==1) ? 6 : 7);
int len;
//int slot_offset_F = (subframe<<1)*slot_sizeF;
slot_offset = subframe*phy_vars_eNB->frame_parms.samples_per_tti;
slot_offset = subframe * phy_vars_eNB->frame_parms.samples_per_tti;
if ((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_DL)||
((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_S))) {
if ((subframe_select(&phy_vars_eNB->frame_parms, subframe) == SF_DL) ||
((subframe_select(&phy_vars_eNB->frame_parms, subframe) == SF_S))) {
// LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION, 1);
/*for (aa=0; aa<phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) {
......@@ -326,18 +332,18 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
}*/
for (aa=0; aa<phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) {
for (aa = 0; aa < phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) {
do_OFDM_mod_symbol(&phy_vars_eNB->common_vars,
0,
subframe<<1,
subframe << 1,
&phy_vars_eNB->frame_parms,
aa);
// if S-subframe generate first slot only
if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL) {
if (subframe_select(&phy_vars_eNB->frame_parms, subframe) == SF_DL) {
do_OFDM_mod_symbol(&phy_vars_eNB->common_vars,
0,
1+(subframe<<1),
1 + (subframe << 1),
&phy_vars_eNB->frame_parms,
aa);
}
......@@ -359,13 +365,13 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
thread_pool_join(phy_vars_eNB->pool);
}
*/
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION, 0);
for (aa=0; aa<phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) {
for (aa = 0; aa < phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) {
// if S-subframe generate first slot only
if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S)
len = phy_vars_eNB->frame_parms.samples_per_tti>>1;
if (subframe_select(&phy_vars_eNB->frame_parms, subframe) == SF_S)
len = phy_vars_eNB->frame_parms.samples_per_tti >> 1;
else
len = phy_vars_eNB->frame_parms.samples_per_tti;
/*
......@@ -375,45 +381,49 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
dummy_tx_b[i+2] = 0xff00;
dummy_tx_b[i+3] = 0xff000000;
}*/
for (i=0; i<len; i++) {
tx_offset = (int)slot_offset+time_offset[aa%4]+i;
for (i = 0; i < len; i++) {
tx_offset = (int) slot_offset + time_offset[aa % 4] + i;
if (tx_offset<0)
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
if (tx_offset < 0)
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME * phy_vars_eNB->frame_parms.samples_per_tti;
if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
if (tx_offset >= (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME * phy_vars_eNB->frame_parms.samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME * phy_vars_eNB->frame_parms.samples_per_tti;
/* ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0] = ((short*)dummy_tx_b)[2*i]<<openair0_cfg[0].iq_txshift;
((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] = ((short*)dummy_tx_b)[2*i+1]<<openair0_cfg[0].iq_txshift; */
((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0] = ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0]<<openair0_cfg[0].iq_txshift;
((short *) &phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0] =
((short *) &phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0]
<< openair0_cfg[0].iq_txshift;
((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] = ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1]<<openair0_cfg[0].iq_txshift;
((short *) &phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] =
((short *) &phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1]
<< openair0_cfg[0].iq_txshift;
}
// if S-subframe switch to RX in second subframe
if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S) {
for (i=0; i<len; i++) {
if (subframe_select(&phy_vars_eNB->frame_parms, subframe) == SF_S) {
for (i = 0; i < len; i++) {
phy_vars_eNB->common_vars.txdata[0][aa][tx_offset++] = 0x00010001;
}
}
if ((((phy_vars_eNB->frame_parms.tdd_config==0) ||
(phy_vars_eNB->frame_parms.tdd_config==1) ||
(phy_vars_eNB->frame_parms.tdd_config==2) ||
(phy_vars_eNB->frame_parms.tdd_config==6)) &&
(subframe==0)) || (subframe==5)) {
if ((((phy_vars_eNB->frame_parms.tdd_config == 0) ||
(phy_vars_eNB->frame_parms.tdd_config == 1) ||
(phy_vars_eNB->frame_parms.tdd_config == 2) ||
(phy_vars_eNB->frame_parms.tdd_config == 6)) &&
(subframe == 0)) || (subframe == 5)) {
// turn on tx switch N_TA_offset before
//LOG_D(HW,"subframe %d, time to switch to tx (N_TA_offset %d, slot_offset %d) \n",subframe,phy_vars_eNB->N_TA_offset,slot_offset);
for (i=0; i<phy_vars_eNB->N_TA_offset; i++) {
tx_offset = (int)slot_offset+time_offset[aa%4]+i-phy_vars_eNB->N_TA_offset;
if (tx_offset<0)
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
for (i = 0; i < phy_vars_eNB->N_TA_offset; i++) {
tx_offset = (int) slot_offset + time_offset[aa % 4] + i - phy_vars_eNB->N_TA_offset;
if (tx_offset < 0)
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME * phy_vars_eNB->frame_parms.samples_per_tti;
if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
if (tx_offset >= (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME * phy_vars_eNB->frame_parms.samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME * phy_vars_eNB->frame_parms.samples_per_tti;
phy_vars_eNB->common_vars.txdata[0][aa][tx_offset] = 0x00000000;
}
......@@ -423,18 +433,18 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
}
void tx_fh_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx&0xffffffff );
void tx_fh_if5(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx & 0xffffffff);
send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_RRH_GW_DL);
}
void tx_fh_if5_mobipass(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx&0xffffffff );
void tx_fh_if5_mobipass(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx & 0xffffffff);
send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_MOBIPASS);
}
void tx_fh_if4p5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
send_IF4p5(eNB,proc->frame_tx, proc->subframe_tx, IF4p5_PDLFFT, 0);
void tx_fh_if4p5(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) {
send_IF4p5(eNB, proc->frame_tx, proc->subframe_tx, IF4p5_PDLFFT, 0);
}
void proc_tx_high0(PHY_VARS_eNB *eNB,
......@@ -444,10 +454,11 @@ void proc_tx_high0(PHY_VARS_eNB *eNB,
int offset = proc == &eNB->proc.proc_rxtx[0] ? 0 : 1;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB+offset, proc->frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB+offset, proc->subframe_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB + offset, proc->frame_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB + offset,
proc->subframe_tx);
phy_procedures_eNB_TX(eNB,proc,r_type,rn,1);
phy_procedures_eNB_TX(eNB, proc, r_type, rn, 1);
/* we're done, let the next one proceed */
if (pthread_mutex_lock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
......@@ -471,10 +482,10 @@ void proc_tx_high(PHY_VARS_eNB *eNB,
// do PHY high
proc_tx_high0(eNB,proc,r_type,rn);
proc_tx_high0(eNB, proc, r_type, rn);
// if TX fronthaul go ahead
if (eNB->tx_fh) eNB->tx_fh(eNB,proc);
if (eNB->tx_fh) eNB->tx_fh(eNB, proc);
}
......@@ -485,11 +496,11 @@ void proc_tx_full(PHY_VARS_eNB *eNB,
// do PHY high
proc_tx_high0(eNB,proc,r_type,rn);
proc_tx_high0(eNB, proc, r_type, rn);
// do OFDM modulation
do_OFDM_mod_rt(proc->subframe_tx,eNB);
do_OFDM_mod_rt(proc->subframe_tx, eNB);
// if TX fronthaul go ahead
if (eNB->tx_fh) eNB->tx_fh(eNB,proc);
if (eNB->tx_fh) eNB->tx_fh(eNB, proc);
/*
if (proc->frame_tx>1000) {
......@@ -509,34 +520,36 @@ void proc_tx_rru_if4p5(PHY_VARS_eNB *eNB,
relaying_type_t r_type,
PHY_VARS_RN *rn) {
uint32_t symbol_number=0;
uint32_t symbol_number = 0;
uint32_t symbol_mask, symbol_mask_full;
uint16_t packet_type;
int offset = proc == &eNB->proc.proc_rxtx[0] ? 0 : 1;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB+offset, proc->frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB+offset, proc->subframe_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB + offset, proc->frame_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB + offset,
proc->subframe_tx);
/// **** recv_IF4 of txdataF from RCC **** ///
symbol_number = 0;
symbol_mask = 0;
symbol_mask_full = (1<<eNB->frame_parms.symbols_per_tti)-1;
symbol_mask_full = (1 << eNB->frame_parms.symbols_per_tti) - 1;
do {
recv_IF4p5(eNB, &proc->frame_tx, &proc->subframe_tx, &packet_type, &symbol_number);
symbol_mask = symbol_mask | (1<<symbol_number);
symbol_mask = symbol_mask | (1 << symbol_number);
} while (symbol_mask != symbol_mask_full);
do_OFDM_mod_rt(proc->subframe_tx, eNB);
}
void proc_tx_rru_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
void proc_tx_rru_if5(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) {
int offset = proc == &eNB->proc.proc_rxtx[0] ? 0 : 1;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB+offset, proc->frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB+offset, proc->subframe_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB + offset, proc->frame_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB + offset,
proc->subframe_tx);
/// **** recv_IF5 of txdata from BBU **** ///
recv_IF5(eNB, &proc->timestamp_tx, proc->subframe_tx, IF5_RRH_GW_DL);
}
......@@ -545,13 +558,13 @@ int wait_CCs(eNB_rxtx_proc_t *proc) {
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
wait.tv_sec = 0;
wait.tv_nsec = 5000000L;
if (pthread_mutex_timedlock(&sync_phy_proc.mutex_phy_proc_tx,&wait) != 0) {
if (pthread_mutex_timedlock(&sync_phy_proc.mutex_phy_proc_tx, &wait) != 0) {
LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX\n");
exit_fun("nothing to add");
return(-1);
return (-1);
}
// wait for our turn or oai_exit
......@@ -563,27 +576,28 @@ int wait_CCs(eNB_rxtx_proc_t *proc) {
if (pthread_mutex_unlock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX\n");
exit_fun("nothing to add");
return(-1);
return (-1);
}
return(0);
return (0);
}
static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) {
static inline int rxtx(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, char *thread_name) {
start_meas(&softmodem_stats_rxtx_sf);
// ****************************************
// TDD workaround for EXMIMO card
if ((eNB->rfdevice.openair0_cfg->duplex_mode == duplex_mode_TDD_workaround) && (eNB->frame_parms.frame_type == TDD) && subframe_select(&eNB->frame_parms,proc->subframe_rx)==SF_UL) {
remove_1_4_fs(eNB,proc->subframe_rx<<1);
remove_1_4_fs(eNB,1+(proc->subframe_rx<<1));
if ((eNB->rfdevice.openair0_cfg->duplex_mode == duplex_mode_TDD_workaround) &&
(eNB->frame_parms.frame_type == TDD) && subframe_select(&eNB->frame_parms, proc->subframe_rx) == SF_UL) {
remove_1_4_fs(eNB, proc->subframe_rx << 1);
remove_1_4_fs(eNB, 1 + (proc->subframe_rx << 1));
}
// Common RX procedures subframe n
phy_procedures_eNB_common_RX(eNB);
// UE-specific RX processing for subframe n
if (eNB->proc_uespec_rx) eNB->proc_uespec_rx(eNB, proc, no_relay );
if (eNB->proc_uespec_rx) eNB->proc_uespec_rx(eNB, proc, no_relay);
// *****************************************
// TX processing for subframe n+4
......@@ -592,15 +606,15 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
// *****************************************
//if (wait_CCs(proc)<0) return(-1);
if (oai_exit) return(-1);
if (oai_exit) return (-1);
if (eNB->proc_tx) eNB->proc_tx(eNB, proc, no_relay, NULL );
if (eNB->proc_tx) eNB->proc_tx(eNB, proc, no_relay, NULL);
if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1);
if (release_thread(&proc->mutex_rxtx, &proc->instance_cnt_rxtx, thread_name) < 0) return (-1);
stop_meas( &softmodem_stats_rxtx_sf );
stop_meas(&softmodem_stats_rxtx_sf);
return(0);
return (0);
}
/*!
......@@ -608,11 +622,11 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
* \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
static void* eNB_thread_rxtx( void* param ) {
static void *eNB_thread_rxtx(void *param) {
static int eNB_thread_rxtx_status;
eNB_rxtx_proc_t *proc = (eNB_rxtx_proc_t*)param;
eNB_rxtx_proc_t *proc = (eNB_rxtx_proc_t *) param;
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
char thread_name[100];
......@@ -622,27 +636,28 @@ static void* eNB_thread_rxtx( void* param ) {
eNB_thread_rxtx_status = 0;
sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
thread_top_init(thread_name,1,850000L,1000000L,2000000L);
sprintf(thread_name, "RXn_TXnp4_%d\n", &eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
thread_top_init(thread_name, 1, 850000L, 1000000L, 2000000L);
while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0 + (proc->subframe_rx & 1),
0);
if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
if (wait_on_condition(&proc->mutex_rxtx, &proc->cond_rxtx, &proc->instance_cnt_rxtx, thread_name) < 0) break;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0 + (proc->subframe_rx & 1),
1);
if (oai_exit) break;
if (rxtx(eNB,proc,thread_name) < 0) break;
if (rxtx(eNB, proc, thread_name) < 0) break;
} // while !oai_exit
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0 + (proc->subframe_rx & 1), 0);
printf( "Exiting eNB thread RXn_TXnp4\n");
printf("Exiting eNB thread RXn_TXnp4\n");
eNB_thread_rxtx_status = 0;
return &eNB_thread_rxtx_status;
......@@ -669,46 +684,45 @@ static void wait_system_ready (char *message, volatile int *start_flag) {
// asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU)
void fh_if5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
void fh_if5_asynch_UL(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
eNB_proc_t *proc = &eNB->proc;
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL);
proc->subframe_rx = (proc->timestamp_rx/fp->samples_per_tti)%10;
proc->frame_rx = (proc->timestamp_rx/(10*fp->samples_per_tti))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti) % 10;
proc->frame_rx = (proc->timestamp_rx / (10 * fp->samples_per_tti)) & 1023;
if (proc->first_rx != 0) {
proc->first_rx = 0;
*subframe = proc->subframe_rx;
*frame = proc->frame_rx;
}
else {
} else {
if (proc->subframe_rx != *subframe) {
LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe);
LOG_E(PHY, "subframe_rx %d is not what we expect %d\n", proc->subframe_rx, *subframe);
exit_fun("Exiting");
}
if (proc->frame_rx != *frame) {
LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->frame_rx,*frame);
LOG_E(PHY, "subframe_rx %d is not what we expect %d\n", proc->frame_rx, *frame);
exit_fun("Exiting");
}
}
} // eNodeB_3GPP_BBU
// asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU)
void fh_if4p5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
void fh_if4p5_asynch_UL(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc;
uint16_t packet_type;
uint32_t symbol_number,symbol_mask,symbol_mask_full,prach_rx;
uint32_t symbol_number, symbol_mask, symbol_mask_full, prach_rx;
symbol_number = 0;
symbol_mask = 0;
symbol_mask_full = (1<<fp->symbols_per_tti)-1;
symbol_mask_full = (1 << fp->symbols_per_tti) - 1;
prach_rx = 0;
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
......@@ -717,71 +731,69 @@ void fh_if4p5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
*frame = proc->frame_rx;
*subframe = proc->subframe_rx;
proc->first_rx = 0;
}
else {
} else {
if (proc->frame_rx != *frame) {
LOG_E(PHY,"frame_rx %d is not what we expect %d\n",proc->frame_rx,*frame);
LOG_E(PHY, "frame_rx %d is not what we expect %d\n", proc->frame_rx, *frame);
exit_fun("Exiting");
}
if (proc->subframe_rx != *subframe) {
LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe);
LOG_E(PHY, "subframe_rx %d is not what we expect %d\n", proc->subframe_rx, *subframe);
exit_fun("Exiting");
}
}
if (packet_type == IF4p5_PULFFT) {
symbol_mask = symbol_mask | (1<<symbol_number);
prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0;
symbol_mask = symbol_mask | (1 << symbol_number);
prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx) > 0) ? 1 : 0;
} else if (packet_type == IF4p5_PRACH) {
prach_rx = 0;
}
} while( (symbol_mask != symbol_mask_full) || (prach_rx == 1));
} while ((symbol_mask != symbol_mask_full) || (prach_rx == 1));
}
void fh_if5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
void fh_if5_asynch_DL(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc;
int subframe_tx,frame_tx;
int subframe_tx, frame_tx;
openair0_timestamp timestamp_tx;
recv_IF5(eNB, &timestamp_tx, *subframe, IF5_RRH_GW_DL);
// printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx);
subframe_tx = (timestamp_tx/fp->samples_per_tti)%10;
frame_tx = (timestamp_tx/(fp->samples_per_tti*10))&1023;
subframe_tx = (timestamp_tx / fp->samples_per_tti) % 10;
frame_tx = (timestamp_tx / (fp->samples_per_tti * 10)) & 1023;
if (proc->first_tx != 0) {
*subframe = subframe_tx;
*frame = frame_tx;
proc->first_tx = 0;
}
else {
} else {
if (subframe_tx != *subframe) {
LOG_E(PHY,"subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe);
LOG_E(PHY, "subframe_tx %d is not what we expect %d\n", subframe_tx, *subframe);
exit_fun("Exiting");
}
if (frame_tx != *frame) {
LOG_E(PHY,"frame_tx %d is not what we expect %d\n",frame_tx,*frame);
LOG_E(PHY, "frame_tx %d is not what we expect %d\n", frame_tx, *frame);
exit_fun("Exiting");
}
}
}
void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc;
uint16_t packet_type;
uint32_t symbol_number,symbol_mask,symbol_mask_full;
int subframe_tx,frame_tx;
uint32_t symbol_number, symbol_mask, symbol_mask_full;
int subframe_tx, frame_tx;
symbol_number = 0;
symbol_mask = 0;
symbol_mask_full = (1<<fp->symbols_per_tti)-1;
symbol_mask_full = (1 << fp->symbols_per_tti) - 1;
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
recv_IF4p5(eNB, &frame_tx, &subframe_tx, &packet_type, &symbol_number);
......@@ -789,22 +801,20 @@ void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
*frame = frame_tx;
*subframe = subframe_tx;
proc->first_tx = 0;
}
else {
} else {
if (frame_tx != *frame) {
LOG_E(PHY,"frame_tx %d is not what we expect %d\n",frame_tx,*frame);
LOG_E(PHY, "frame_tx %d is not what we expect %d\n", frame_tx, *frame);
exit_fun("Exiting");
}
if (subframe_tx != *subframe) {
LOG_E(PHY,"subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe);
LOG_E(PHY, "subframe_tx %d is not what we expect %d\n", subframe_tx, *subframe);
exit_fun("Exiting");
}
}
if (packet_type == IF4p5_PDLFFT) {
symbol_mask = symbol_mask | (1<<symbol_number);
}
else {
LOG_E(PHY,"Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n",packet_type);
symbol_mask = symbol_mask | (1 << symbol_number);
} else {
LOG_E(PHY, "Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n", packet_type);
exit_fun("Exiting");
}
} while (symbol_mask != symbol_mask_full);
......@@ -818,100 +828,110 @@ void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
* \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
static void* eNB_thread_asynch_rxtx( void* param ) {
static void *eNB_thread_asynch_rxtx(void *param) {
static int eNB_thread_asynch_rxtx_status;
eNB_proc_t *proc = (eNB_proc_t*)param;
eNB_proc_t *proc = (eNB_proc_t *) param;
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
int subframe = 0, frame = 0;
int subframe=0, frame=0;
thread_top_init("thread_asynch",1,870000L,1000000L,1000000L);
thread_top_init("thread_asynch", 1, 870000L, 1000000L, 1000000L);
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
wait_sync("thread_asynch");
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
printf( "waiting for devices (eNB_thread_asynch_rx)\n");
printf("waiting for devices (eNB_thread_asynch_rx)\n");
wait_on_condition(&proc->mutex_asynch_rxtx,&proc->cond_asynch_rxtx,&proc->instance_cnt_asynch_rxtx,"thread_asynch");
wait_on_condition(&proc->mutex_asynch_rxtx, &proc->cond_asynch_rxtx, &proc->instance_cnt_asynch_rxtx,
"thread_asynch");
printf( "devices ok (eNB_thread_asynch_rx)\n");
printf("devices ok (eNB_thread_asynch_rx)\n");
while (!oai_exit) {
if (oai_exit) break;
if (subframe==9) {
subframe=0;
if (subframe == 9) {
subframe = 0;
frame++;
frame&=1023;
frame &= 1023;
} else {
subframe++;
}
if (eNB->fh_asynch) eNB->fh_asynch(eNB,&frame,&subframe);
else AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function);
if (eNB->fh_asynch) eNB->fh_asynch(eNB, &frame, &subframe);
else AssertFatal(1 == 0, "Unknown eNB->node_function %d", eNB->node_function);
}
eNB_thread_asynch_rxtx_status=0;
return(&eNB_thread_asynch_rxtx_status);
eNB_thread_asynch_rxtx_status = 0;
return (&eNB_thread_asynch_rxtx_status);
}
void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
void rx_rf(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
eNB_proc_t *proc = &eNB->proc;
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
void *rxp[fp->nb_antennas_rx],*txp[fp->nb_antennas_tx];
unsigned int rxs,txs;
void *rxp[fp->nb_antennas_rx], *txp[fp->nb_antennas_tx];
unsigned int rxs, txs;
int i;
int flag = 1;
int tx_sfoffset = 3;//(eNB->single_thread_flag == 1) ? 3 : 3;
//lte_subframe_t TXSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset)%10);
lte_subframe_t TXSF_type = subframe_select(fp, (proc->subframe_rx + tx_sfoffset) % 10);
//if (proc->first_rx==0 && TXSF_type != SF_UL) {
if (proc->first_rx==0) {
if (proc->first_rx == 0) {
// Transmit TX buffer based on timestamp from RX
// printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST,
(proc->timestamp_rx + (tx_sfoffset * fp->samples_per_tti) -
openair0_cfg[0].tx_sample_advance) & 0xffffffff);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1);
// prepare tx buffer pointers
for (i=0; i<fp->nb_antennas_tx; i++)
txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+tx_sfoffset)%10)*fp->samples_per_tti];
//lte_subframe_t SFnext_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+1)%10);
//if (SFnext_type == SF_UL) flag = 3;
for (i = 0; i < fp->nb_antennas_tx; i++)
txp[i] = (void *) &eNB->common_vars.txdata[0][i][((proc->subframe_rx + tx_sfoffset) % 10) *
fp->samples_per_tti];
lte_subframe_t SFnext_type = subframe_select(fp, (proc->subframe_rx + tx_sfoffset + 1) % 10);
if (SFnext_type == SF_UL) flag = 3;
if (TXSF_type != SF_UL) {
txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice,
proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance,
proc->timestamp_rx + (tx_sfoffset * fp->samples_per_tti) -
openair0_cfg[0].tx_sample_advance,
txp,
fp->samples_per_tti,
fp->nb_antennas_tx,
flag);
} else {
txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice,
proc->timestamp_rx + (tx_sfoffset * fp->samples_per_tti) -
openair0_cfg[0].tx_sample_advance,
txp,
fp->samples_per_tti,
fp->nb_antennas_tx,
8);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0);
if (txs != fp->samples_per_tti) {
LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti);
exit_fun( "problem transmitting samples" );
LOG_E(PHY, "TX : Timeout (sent %d/%d)\n", txs, fp->samples_per_tti);
exit_fun("problem transmitting samples");
}
}
for (i=0; i<fp->nb_antennas_rx; i++)
rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][*subframe*fp->samples_per_tti];
for (i = 0; i < fp->nb_antennas_rx; i++)
rxp[i] = (void *) &eNB->common_vars.rxdata[0][i][*subframe * fp->samples_per_tti];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1);
rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
&(proc->timestamp_rx),
......@@ -919,21 +939,25 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
fp->samples_per_tti,
fp->nb_antennas_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0);
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
proc->timestamp_tx = proc->timestamp_rx+(4*fp->samples_per_tti);
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti * 10)) & 1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti) % 10;
proc->timestamp_tx = proc->timestamp_rx + (4 * fp->samples_per_tti);
// printf("trx_read <- USRP TS %llu (sf %d, first_rx %d)\n", proc->timestamp_rx,proc->subframe_rx,proc->first_rx);
if (proc->first_rx == 0) {
if (proc->subframe_rx != *subframe){
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe);
if (proc->subframe_rx != *subframe) {
LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",
proc->subframe_rx, *subframe);
exit_fun("Exiting");
}
if (proc->frame_rx != *frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,*frame);
LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",
proc->frame_rx, *frame);
exit_fun("Exiting");
}
} else {
......@@ -944,33 +968,36 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
//printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx & 0xffffffff);
if (rxs != fp->samples_per_tti)
exit_fun( "problem receiving samples" );
exit_fun("problem receiving samples");
}
void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) {
void rx_fh_if5(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc;
recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL);
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti * 10)) & 1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti) % 10;
if (proc->first_rx == 0) {
if (proc->subframe_rx != *subframe){
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe);
if (proc->subframe_rx != *subframe) {
LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",
proc->subframe_rx, subframe);
exit_fun("Exiting");
}
if (proc->frame_rx != *frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame);
LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",
proc->frame_rx, frame);
exit_fun("Exiting");
}
} else {
......@@ -979,12 +1006,12 @@ void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) {
*subframe = proc->subframe_rx;
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx & 0xffffffff);
}
void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
void rx_fh_if4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc;
......@@ -992,37 +1019,41 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
int prach_rx;
uint16_t packet_type;
uint32_t symbol_number=0;
uint32_t symbol_number = 0;
uint32_t symbol_mask, symbol_mask_full;
symbol_mask = 0;
symbol_mask_full = (1<<fp->symbols_per_tti)-1;
symbol_mask_full = (1 << fp->symbols_per_tti) - 1;
prach_rx = 0;
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
recv_IF4p5(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number);
if (packet_type == IF4p5_PULFFT) {
symbol_mask = symbol_mask | (1<<symbol_number);
prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0;
symbol_mask = symbol_mask | (1 << symbol_number);
prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx) > 0) ? 1 : 0;
} else if (packet_type == IF4p5_PRACH) {
prach_rx = 0;
}
} while( (symbol_mask != symbol_mask_full) || (prach_rx == 1));
} while ((symbol_mask != symbol_mask_full) || (prach_rx == 1));
//caculate timestamp_rx, timestamp_tx based on frame and subframe
proc->timestamp_rx = ((proc->frame_rx * 10) + proc->subframe_rx ) * fp->samples_per_tti ;
proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
proc->timestamp_rx = ((proc->frame_rx * 10) + proc->subframe_rx) * fp->samples_per_tti;
proc->timestamp_tx = proc->timestamp_rx + (4 * fp->samples_per_tti);
if (proc->first_rx == 0) {
if (proc->subframe_rx != *subframe){
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe);
if (proc->subframe_rx != *subframe) {
LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",
proc->subframe_rx, *subframe);
exit_fun("Exiting");
}
if (proc->frame_rx != *frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,*frame);
LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",
proc->frame_rx, *frame);
exit_fun("Exiting");
}
} else {
......@@ -1031,48 +1062,50 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
*subframe = proc->subframe_rx;
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx & 0xffffffff);
}
void rx_fh_slave(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
void rx_fh_slave(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
// This case is for synchronization to another thread
// it just waits for an external event. The actual rx_fh is handle by the asynchronous RX thread
eNB_proc_t *proc=&eNB->proc;
eNB_proc_t *proc = &eNB->proc;
if (wait_on_condition(&proc->mutex_FH,&proc->cond_FH,&proc->instance_cnt_FH,"rx_fh_slave") < 0)
if (wait_on_condition(&proc->mutex_FH, &proc->cond_FH, &proc->instance_cnt_FH, "rx_fh_slave") < 0)
return;
release_thread(&proc->mutex_FH,&proc->instance_cnt_FH,"rx_fh_slave");
release_thread(&proc->mutex_FH, &proc->instance_cnt_FH, "rx_fh_slave");
}
int wakeup_rxtx(eNB_proc_t *proc,eNB_rxtx_proc_t *proc_rxtx,LTE_DL_FRAME_PARMS *fp) {
int wakeup_rxtx(eNB_proc_t *proc, eNB_rxtx_proc_t *proc_rxtx, LTE_DL_FRAME_PARMS *fp) {
int i;
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
wait.tv_sec = 0;
wait.tv_nsec = 5000000L;
/* accept some delay in processing - up to 5ms */
for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) {
LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->instance_cnt_rxtx);
LOG_W(PHY, "[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx,
proc_rxtx->instance_cnt_rxtx);
usleep(500);
}
if (proc_rxtx->instance_cnt_rxtx == 0) {
exit_fun( "TX thread busy" );
return(-1);
exit_fun("TX thread busy");
return (-1);
}
// wake up TX for subframe n+4
// lock the TX mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx );
exit_fun( "error locking mutex_rxtx" );
return(-1);
if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx, &wait) != 0) {
LOG_E(PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx & 1,
proc_rxtx->instance_cnt_rxtx);
exit_fun("error locking mutex_rxtx");
return (-1);
}
++proc_rxtx->instance_cnt_rxtx;
......@@ -1083,22 +1116,22 @@ int wakeup_rxtx(eNB_proc_t *proc,eNB_rxtx_proc_t *proc_rxtx,LTE_DL_FRAME_PARMS *
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
// we want to generate subframe (n+4), so TS_tx = TX_rx+4*samples_per_tti,
// and proc->subframe_tx = proc->subframe_rx+4
proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
proc_rxtx->timestamp_tx = proc->timestamp_rx + (4 * fp->samples_per_tti);
proc_rxtx->frame_rx = proc->frame_rx;
proc_rxtx->subframe_rx = proc->subframe_rx;
proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10;
proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx + 1) & 1023 : proc_rxtx->frame_rx;
proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4) % 10;
// the thread can now be woken up
if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" );
return(-1);
LOG_E(PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
exit_fun("ERROR pthread_cond_signal");
return (-1);
}
pthread_mutex_unlock( &proc_rxtx->mutex_rxtx );
pthread_mutex_unlock(&proc_rxtx->mutex_rxtx);
return(0);
return (0);
}
void wakeup_slaves(eNB_proc_t *proc) {
......@@ -1106,16 +1139,17 @@ void wakeup_slaves(eNB_proc_t *proc) {
int i;
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
wait.tv_sec = 0;
wait.tv_nsec = 5000000L;
for (i=0;i<proc->num_slaves;i++) {
for (i = 0; i < proc->num_slaves; i++) {
eNB_proc_t *slave_proc = proc->slave_proc[i];
// wake up slave FH thread
// lock the FH mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB CCid %d slave CCid %d (IC %d)\n",proc->CC_id,slave_proc->CC_id);
exit_fun( "error locking mutex_rxtx" );
if (pthread_mutex_timedlock(&slave_proc->mutex_FH, &wait) != 0) {
LOG_E(PHY, "[eNB] ERROR pthread_mutex_lock for eNB CCid %d slave CCid %d (IC %d)\n", proc->CC_id,
slave_proc->CC_id);
exit_fun("error locking mutex_rxtx");
break;
}
......@@ -1125,18 +1159,20 @@ void wakeup_slaves(eNB_proc_t *proc) {
slave_proc->timestamp_rx = proc->timestamp_rx;
slave_proc->timestamp_tx = proc->timestamp_tx;
pthread_mutex_unlock( &slave_proc->mutex_FH );
pthread_mutex_unlock(&slave_proc->mutex_FH);
if (cnt_slave == 0) {
// the thread was presumably waiting where it should and can now be woken up
if (pthread_cond_signal(&slave_proc->cond_FH) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB CCid %d, slave CCid %d\n",proc->CC_id,slave_proc->CC_id);
exit_fun( "ERROR pthread_cond_signal" );
LOG_E(PHY, "[eNB] ERROR pthread_cond_signal for eNB CCid %d, slave CCid %d\n", proc->CC_id,
slave_proc->CC_id);
exit_fun("ERROR pthread_cond_signal");
break;
}
} else {
LOG_W( PHY,"[eNB] Frame %d, slave CC_id %d thread busy!! (cnt_FH %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave);
exit_fun( "FH thread busy" );
LOG_W(PHY, "[eNB] Frame %d, slave CC_id %d thread busy!! (cnt_FH %i)\n", slave_proc->frame_rx,
slave_proc->CC_id, cnt_slave);
exit_fun("FH thread busy");
break;
}
}
......@@ -1150,20 +1186,20 @@ void wakeup_slaves(eNB_proc_t *proc) {
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
static void* eNB_thread_FH( void* param ) {
static void *eNB_thread_FH(void *param) {
static int eNB_thread_FH_status;
eNB_proc_t *proc = (eNB_proc_t*)param;
eNB_proc_t *proc = (eNB_proc_t *) param;
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
int subframe=0, frame=0;
int subframe = 0, frame = 0;
// set default return value
eNB_thread_FH_status = 0;
thread_top_init("eNB_thread_FH",0,870000,1000000,1000000);
thread_top_init("eNB_thread_FH", 0, 870000, 1000000, 1000000);
wait_sync("eNB_thread_FH");
......@@ -1175,16 +1211,16 @@ static void* eNB_thread_FH( void* param ) {
// Start IF device if any
if (eNB->start_if)
if (eNB->start_if(eNB) != 0)
LOG_E(HW,"Could not start the IF device\n");
LOG_E(HW, "Could not start the IF device\n");
// Start RF device if any
if (eNB->start_rf)
if (eNB->start_rf(eNB) != 0)
LOG_E(HW,"Could not start the RF device\n");
LOG_E(HW, "Could not start the RF device\n");
// wakeup asnych_rxtx thread because the devices are ready at this point
pthread_mutex_lock(&proc->mutex_asynch_rxtx);
proc->instance_cnt_asynch_rxtx=0;
proc->instance_cnt_asynch_rxtx = 0;
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
pthread_cond_signal(&proc->cond_asynch_rxtx);
......@@ -1193,18 +1229,18 @@ static void* eNB_thread_FH( void* param ) {
// these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
// They are set on the first rx/tx in the underly FH routines.
if (subframe==9) {
subframe=0;
if (subframe == 9) {
subframe = 0;
frame++;
frame&=1023;
frame &= 1023;
} else {
subframe++;
}
// synchronization on FH interface, acquire signals/data and block
if (eNB->rx_fh) eNB->rx_fh(eNB,&frame,&subframe);
else AssertFatal(1==0, "No fronthaul interface : eNB->node_function %d",eNB->node_function);
if (eNB->rx_fh) eNB->rx_fh(eNB, &frame, &subframe);
else AssertFatal(1 == 0, "No fronthaul interface : eNB->node_function %d", eNB->node_function);
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
......@@ -1214,15 +1250,15 @@ static void* eNB_thread_FH( void* param ) {
// wake up RXn_TXnp4 thread for the subframe
// choose even or odd thread for RXn-TXnp4 processing
if (wakeup_rxtx(proc,&proc->proc_rxtx[proc->subframe_rx&1],fp) < 0)
if (wakeup_rxtx(proc, &proc->proc_rxtx[proc->subframe_rx & 1], fp) < 0)
break;
// artifical sleep for very slow fronthaul
if (eNB->frame_parms.N_RB_DL==6)
if (eNB->frame_parms.N_RB_DL == 6)
rt_sleep_ns(800000LL);
}
printf( "Exiting FH thread \n");
printf("Exiting FH thread \n");
eNB_thread_FH_status = 0;
return &eNB_thread_FH_status;
......@@ -1234,48 +1270,50 @@ static void* eNB_thread_FH( void* param ) {
* \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
static void* eNB_thread_prach( void* param ) {
static void *eNB_thread_prach(void *param) {
static int eNB_thread_prach_status;
eNB_proc_t *proc = (eNB_proc_t*)param;
PHY_VARS_eNB *eNB= PHY_vars_eNB_g[0][proc->CC_id];
eNB_proc_t *proc = (eNB_proc_t *) param;
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
// set default return value
eNB_thread_prach_status = 0;
thread_top_init("eNB_thread_prach",1,500000L,1000000L,20000000L);
thread_top_init("eNB_thread_prach", 1, 500000L, 1000000L, 20000000L);
while (!oai_exit) {
if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
if (wait_on_condition(&proc->mutex_prach, &proc->cond_prach, &proc->instance_cnt_prach, "eNB_prach_thread") <
0)
break;
if (oai_exit) break;
prach_procedures(eNB);
if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
if (release_thread(&proc->mutex_prach, &proc->instance_cnt_prach, "eNB_prach_thread") < 0) break;
}
printf( "Exiting eNB thread PRACH\n");
printf("Exiting eNB thread PRACH\n");
eNB_thread_prach_status = 0;
return &eNB_thread_prach_status;
}
static void* eNB_thread_single( void* param ) {
static void *eNB_thread_single(void *param) {
static int eNB_thread_single_status;
eNB_proc_t *proc = (eNB_proc_t*)param;
eNB_proc_t *proc = (eNB_proc_t *) param;
eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0];
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
int subframe=0, frame=0;
int subframe = 0, frame = 0;
// set default return value
eNB_thread_single_status = 0;
thread_top_init("eNB_thread_single",0,870000,1000000,1000000);
thread_top_init("eNB_thread_single", 0, 870000, 1000000, 1000000);
wait_sync("eNB_thread_single");
......@@ -1287,16 +1325,16 @@ static void* eNB_thread_single( void* param ) {
// Start IF device if any
if (eNB->start_if)
if (eNB->start_if(eNB) != 0)
LOG_E(HW,"Could not start the IF device\n");
LOG_E(HW, "Could not start the IF device\n");
// Start RF device if any
if (eNB->start_rf)
if (eNB->start_rf(eNB) != 0)
LOG_E(HW,"Could not start the RF device\n");
LOG_E(HW, "Could not start the RF device\n");
// wakeup asnych_rxtx thread because the devices are ready at this point
pthread_mutex_lock(&proc->mutex_asynch_rxtx);
proc->instance_cnt_asynch_rxtx=0;
proc->instance_cnt_asynch_rxtx = 0;
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
pthread_cond_signal(&proc->cond_asynch_rxtx);
......@@ -1305,37 +1343,37 @@ static void* eNB_thread_single( void* param ) {
// these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
// They are set on the first rx/tx in the underly FH routines.
if (subframe==9) {
subframe=0;
if (subframe == 9) {
subframe = 0;
frame++;
frame&=1023;
frame &= 1023;
} else {
subframe++;
}
LOG_D(PHY,"eNB Fronthaul thread, frame %d, subframe %d\n",frame,subframe);
LOG_D(PHY, "eNB Fronthaul thread, frame %d, subframe %d\n", frame, subframe);
// synchronization on FH interface, acquire signals/data and block
if (eNB->rx_fh) eNB->rx_fh(eNB,&frame,&subframe);
else AssertFatal(1==0, "No fronthaul interface : eNB->node_function %d",eNB->node_function);
if (eNB->rx_fh) eNB->rx_fh(eNB, &frame, &subframe);
else AssertFatal(1 == 0, "No fronthaul interface : eNB->node_function %d", eNB->node_function);
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
proc_rxtx->subframe_rx = proc->subframe_rx;
proc_rxtx->frame_rx = proc->frame_rx;
proc_rxtx->subframe_tx = (proc->subframe_rx+4)%10;
proc_rxtx->frame_tx = (proc->subframe_rx < 6) ? proc->frame_rx : (proc->frame_rx+1)&1023;
proc_rxtx->subframe_tx = (proc->subframe_rx + 4) % 10;
proc_rxtx->frame_tx = (proc->subframe_rx < 6) ? proc->frame_rx : (proc->frame_rx + 1) & 1023;
proc_rxtx->timestamp_tx = proc->timestamp_tx;
// At this point, all information for subframe has been received on FH interface
// If this proc is to provide synchronization, do so
wakeup_slaves(proc);
if (rxtx(eNB,proc_rxtx,"eNB_thread_single") < 0) break;
if (rxtx(eNB, proc_rxtx, "eNB_thread_single") < 0) break;
}
printf( "Exiting eNB_single thread \n");
printf("Exiting eNB_single thread \n");
eNB_thread_single_status = 0;
return &eNB_thread_single_status;
......@@ -1343,22 +1381,25 @@ static void* eNB_thread_single( void* param ) {
}
extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *);
void init_eNB_proc(int inst) {
int i=0;
int i = 0;
int CC_id;
PHY_VARS_eNB *eNB;
eNB_proc_t *proc;
eNB_rxtx_proc_t *proc_rxtx;
pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL,*attr_te;
pthread_attr_t *attr0 = NULL, *attr1 = NULL, *attr_FH = NULL, *attr_prach = NULL, *attr_asynch = NULL, *attr_single = NULL, *attr_fep = NULL, *attr_td = NULL, *attr_te;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
eNB = PHY_vars_eNB_g[inst][CC_id];
#ifndef OCP_FRAMEWORK
LOG_I(PHY,"Initializing eNB %d CC_id %d (%s,%s),\n",inst,CC_id,eNB_functions[eNB->node_function],eNB_timing[eNB->node_timing]);
LOG_I(PHY, "Initializing eNB %d CC_id %d (%s,%s),\n", inst, CC_id, eNB_functions[eNB->node_function],
eNB_timing[eNB->node_timing]);
#endif
proc = &eNB->proc;
......@@ -1370,30 +1411,30 @@ void init_eNB_proc(int inst) {
proc->instance_cnt_asynch_rxtx = -1;
proc->CC_id = CC_id;
proc->first_rx=1;
proc->first_tx=1;
pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL);
pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL);
pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL);
pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL);
pthread_mutex_init( &proc->mutex_prach, NULL);
pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
pthread_cond_init( &proc->cond_prach, NULL);
pthread_cond_init( &proc->cond_FH, NULL);
pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
pthread_attr_init( &proc->attr_FH);
pthread_attr_init( &proc->attr_prach);
pthread_attr_init( &proc->attr_asynch_rxtx);
pthread_attr_init( &proc->attr_single);
pthread_attr_init( &proc->attr_fep);
pthread_attr_init( &proc->attr_td);
pthread_attr_init( &proc->attr_te);
pthread_attr_init( &proc_rxtx[0].attr_rxtx);
pthread_attr_init( &proc_rxtx[1].attr_rxtx);
proc->first_rx = 1;
proc->first_tx = 1;
pthread_mutex_init(&proc_rxtx[0].mutex_rxtx, NULL);
pthread_mutex_init(&proc_rxtx[1].mutex_rxtx, NULL);
pthread_cond_init(&proc_rxtx[0].cond_rxtx, NULL);
pthread_cond_init(&proc_rxtx[1].cond_rxtx, NULL);
pthread_mutex_init(&proc->mutex_prach, NULL);
pthread_mutex_init(&proc->mutex_asynch_rxtx, NULL);
pthread_cond_init(&proc->cond_prach, NULL);
pthread_cond_init(&proc->cond_FH, NULL);
pthread_cond_init(&proc->cond_asynch_rxtx, NULL);
pthread_attr_init(&proc->attr_FH);
pthread_attr_init(&proc->attr_prach);
pthread_attr_init(&proc->attr_asynch_rxtx);
pthread_attr_init(&proc->attr_single);
pthread_attr_init(&proc->attr_fep);
pthread_attr_init(&proc->attr_td);
pthread_attr_init(&proc->attr_te);
pthread_attr_init(&proc_rxtx[0].attr_rxtx);
pthread_attr_init(&proc_rxtx[1].attr_rxtx);
#ifndef DEADLINE_SCHEDULER
attr0 = &proc_rxtx[0].attr_rxtx;
attr1 = &proc_rxtx[1].attr_rxtx;
......@@ -1406,51 +1447,49 @@ void init_eNB_proc(int inst) {
attr_te = &proc->attr_te;
#endif
if (eNB->single_thread_flag==0) {
pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] );
pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] );
pthread_create( &proc->pthread_FH, attr_FH, eNB_thread_FH, &eNB->proc );
}
else {
if (eNB->single_thread_flag == 0) {
pthread_create(&proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0]);
pthread_create(&proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1]);
pthread_create(&proc->pthread_FH, attr_FH, eNB_thread_FH, &eNB->proc);
} else {
pthread_create(&proc->pthread_single, attr_single, eNB_thread_single, &eNB->proc);
init_fep_thread(eNB,attr_fep);
init_td_thread(eNB,attr_td);
init_te_thread(eNB,attr_te);
init_fep_thread(eNB, attr_fep);
init_td_thread(eNB, attr_td);
init_te_thread(eNB, attr_te);
}
pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, &eNB->proc );
pthread_create(&proc->pthread_prach, attr_prach, eNB_thread_prach, &eNB->proc);
if ((eNB->node_timing == synch_to_other) ||
(eNB->node_function == NGFI_RRU_IF5) ||
(eNB->node_function == NGFI_RRU_IF4p5))
pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, eNB_thread_asynch_rxtx, &eNB->proc );
pthread_create(&proc->pthread_asynch_rxtx, attr_asynch, eNB_thread_asynch_rxtx, &eNB->proc);
char name[16];
if (eNB->single_thread_flag == 0) {
snprintf( name, sizeof(name), "RXTX0 %d", i );
pthread_setname_np( proc_rxtx[0].pthread_rxtx, name );
snprintf( name, sizeof(name), "RXTX1 %d", i );
pthread_setname_np( proc_rxtx[1].pthread_rxtx, name );
snprintf( name, sizeof(name), "FH %d", i );
pthread_setname_np( proc->pthread_FH, name );
}
else {
snprintf( name, sizeof(name), " %d", i );
pthread_setname_np( proc->pthread_single, name );
snprintf(name, sizeof(name), "RXTX0 %d", i);
pthread_setname_np(proc_rxtx[0].pthread_rxtx, name);
snprintf(name, sizeof(name), "RXTX1 %d", i);
pthread_setname_np(proc_rxtx[1].pthread_rxtx, name);
snprintf(name, sizeof(name), "FH %d", i);
pthread_setname_np(proc->pthread_FH, name);
} else {
snprintf(name, sizeof(name), " %d", i);
pthread_setname_np(proc->pthread_single, name);
}
}
//for multiple CCs: setup master and slaves
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
eNB = PHY_vars_eNB_g[inst][CC_id];
if (eNB->node_timing == synch_to_ext_device) { //master
eNB->proc.num_slaves = MAX_NUM_CCs-1;
eNB->proc.slave_proc = (eNB_proc_t**)malloc(eNB->proc.num_slaves*sizeof(eNB_proc_t*));
eNB->proc.num_slaves = MAX_NUM_CCs - 1;
eNB->proc.slave_proc = (eNB_proc_t **) malloc(eNB->proc.num_slaves * sizeof(eNB_proc_t * ));
for (i=0; i< eNB->proc.num_slaves; i++) {
for (i = 0; i < eNB->proc.num_slaves; i++) {
if (i < CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc);
if (i >= CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i+1]->proc);
if (i >= CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i + 1]->proc);
}
}
}
......@@ -1463,7 +1502,6 @@ void init_eNB_proc(int inst) {
}
/*!
* \brief Terminate eNB TX and RX threads.
*/
......@@ -1473,8 +1511,8 @@ void kill_eNB_proc(int inst) {
PHY_VARS_eNB *eNB;
eNB_proc_t *proc;
eNB_rxtx_proc_t *proc_rxtx;
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
eNB=PHY_vars_eNB_g[inst][CC_id];
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
eNB = PHY_vars_eNB_g[inst][CC_id];
proc = &eNB->proc;
proc_rxtx = &proc->proc_rxtx[0];
......@@ -1487,25 +1525,25 @@ void kill_eNB_proc(int inst) {
proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race!
proc->instance_cnt_prach = 0;
proc->instance_cnt_FH = 0;
pthread_cond_signal( &proc_rxtx[0].cond_rxtx );
pthread_cond_signal( &proc_rxtx[1].cond_rxtx );
pthread_cond_signal( &proc->cond_prach );
pthread_cond_signal( &proc->cond_FH );
pthread_cond_signal(&proc_rxtx[0].cond_rxtx);
pthread_cond_signal(&proc_rxtx[1].cond_rxtx);
pthread_cond_signal(&proc->cond_prach);
pthread_cond_signal(&proc->cond_FH);
pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
pthread_join( proc->pthread_FH, (void**)&status );
pthread_mutex_destroy( &proc->mutex_FH );
pthread_cond_destroy( &proc->cond_FH );
pthread_join(proc->pthread_FH, (void **) &status);
pthread_mutex_destroy(&proc->mutex_FH);
pthread_cond_destroy(&proc->cond_FH);
pthread_join( proc->pthread_prach, (void**)&status );
pthread_mutex_destroy( &proc->mutex_prach );
pthread_cond_destroy( &proc->cond_prach );
pthread_join(proc->pthread_prach, (void **) &status);
pthread_mutex_destroy(&proc->mutex_prach);
pthread_cond_destroy(&proc->cond_prach);
int i;
for (i=0;i<2;i++) {
pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status );
pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx );
pthread_cond_destroy( &proc_rxtx[i].cond_rxtx );
for (i = 0; i < 2; i++) {
pthread_join(proc_rxtx[i].pthread_rxtx, (void **) &status);
pthread_mutex_destroy(&proc_rxtx[i].mutex_rxtx);
pthread_cond_destroy(&proc_rxtx[i].cond_rxtx);
}
}
}
......@@ -1517,20 +1555,20 @@ void kill_eNB_proc(int inst) {
antennas are mapped to successive RF chains on the same card. */
int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg) {
int i,j;
int CC_id,card,ant;
int i, j;
int CC_id, card, ant;
//uint16_t N_TA_offset = 0;
LTE_DL_FRAME_PARMS *frame_parms;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
if (phy_vars_eNB[CC_id]) {
frame_parms = &(phy_vars_eNB[CC_id]->frame_parms);
printf("setup_eNB_buffers: frame_parms = %p\n",frame_parms);
printf("setup_eNB_buffers: frame_parms = %p\n", frame_parms);
} else {
printf("phy_vars_eNB[%d] not initialized\n", CC_id);
return(-1);
return (-1);
}
/*
......@@ -1548,36 +1586,41 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
if (openair0_cfg[CC_id].mmapped_dma == 1) {
// replace RX signal buffers with mmaped HW versions
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
card = i/4;
ant = i%4;
printf("Mapping eNB CC_id %d, rx_ant %d, on card %d, chain %d\n",CC_id,i,phy_vars_eNB[CC_id]->rf_map.card+card, phy_vars_eNB[CC_id]->rf_map.chain+ant);
for (i = 0; i < frame_parms->nb_antennas_rx; i++) {
card = i / 4;
ant = i % 4;
printf("Mapping eNB CC_id %d, rx_ant %d, on card %d, chain %d\n", CC_id, i,
phy_vars_eNB[CC_id]->rf_map.card + card, phy_vars_eNB[CC_id]->rf_map.chain + ant);
free(phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card+card].rxbase[phy_vars_eNB[CC_id]->rf_map.chain+ant];
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card +
card].rxbase[
phy_vars_eNB[CC_id]->rf_map.chain + ant];
printf("rxdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
for (j=0; j<16; j++) {
printf("rxbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j]);
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j] = 16-j;
printf("rxdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
for (j = 0; j < 16; j++) {
printf("rxbuffer %d: %x\n", j, phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j]);
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j] = 16 - j;
}
}
for (i=0; i<frame_parms->nb_antennas_tx; i++) {
card = i/4;
ant = i%4;
printf("Mapping eNB CC_id %d, tx_ant %d, on card %d, chain %d\n",CC_id,i,phy_vars_eNB[CC_id]->rf_map.card+card, phy_vars_eNB[CC_id]->rf_map.chain+ant);
for (i = 0; i < frame_parms->nb_antennas_tx; i++) {
card = i / 4;
ant = i % 4;
printf("Mapping eNB CC_id %d, tx_ant %d, on card %d, chain %d\n", CC_id, i,
phy_vars_eNB[CC_id]->rf_map.card + card, phy_vars_eNB[CC_id]->rf_map.chain + ant);
free(phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card+card].txbase[phy_vars_eNB[CC_id]->rf_map.chain+ant];
phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card +
card].txbase[
phy_vars_eNB[CC_id]->rf_map.chain + ant];
printf("txdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
for (j=0; j<16; j++) {
printf("txbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j]);
phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j] = 16-j;
}
for (j = 0; j < 16; j++) {
printf("txbuffer %d: %x\n", j, phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j]);
phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j] = 16 - j;
}
}
else { // not memory-mapped DMA
} else { // not memory-mapped DMA
//nothing to do, everything already allocated in lte_init
/*
rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
......@@ -1602,7 +1645,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
}
}
return(0);
return (0);
}
......@@ -1612,7 +1655,7 @@ void reset_opp_meas(void) {
reset_meas(&softmodem_stats_mt);
reset_meas(&softmodem_stats_hw);
for (sfn=0; sfn < 10; sfn++) {
for (sfn = 0; sfn < 10; sfn++) {
reset_meas(&softmodem_stats_rxtx_sf);
reset_meas(&softmodem_stats_rx_sf);
}
......@@ -1621,45 +1664,50 @@ void reset_opp_meas(void) {
void print_opp_meas(void) {
int sfn=0;
int sfn = 0;
print_meas(&softmodem_stats_mt, "Main ENB Thread", NULL, NULL);
print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL);
for (sfn=0; sfn < 10; sfn++) {
print_meas(&softmodem_stats_rxtx_sf,"[eNB][total_phy_proc_rxtx]",NULL, NULL);
print_meas(&softmodem_stats_rx_sf,"[eNB][total_phy_proc_rx]",NULL,NULL);
for (sfn = 0; sfn < 10; sfn++) {
print_meas(&softmodem_stats_rxtx_sf, "[eNB][total_phy_proc_rxtx]", NULL, NULL);
print_meas(&softmodem_stats_rx_sf, "[eNB][total_phy_proc_rx]", NULL, NULL);
}
}
int start_if(PHY_VARS_eNB *eNB) {
return(eNB->ifdevice.trx_start_func(&eNB->ifdevice));
return (eNB->ifdevice.trx_start_func(&eNB->ifdevice));
}
int start_rf(PHY_VARS_eNB *eNB) {
return(eNB->rfdevice.trx_start_func(&eNB->rfdevice));
return (eNB->rfdevice.trx_start_func(&eNB->rfdevice));
}
extern void eNB_fep_rru_if5(PHY_VARS_eNB *eNB);
extern void eNB_fep_full(PHY_VARS_eNB *eNB);
extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB);
extern void do_prach(PHY_VARS_eNB *eNB);
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *eth_params,int single_thread_flag) {
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[], int nb_inst, eth_params_t *eth_params,
int single_thread_flag) {
int CC_id;
int inst;
PHY_VARS_eNB *eNB;
int ret;
for (inst=0;inst<nb_inst;inst++) {
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
for (inst = 0; inst < nb_inst; inst++) {
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
eNB = PHY_vars_eNB_g[inst][CC_id];
eNB->node_function = node_function[CC_id];
eNB->node_timing = node_timing[CC_id];
eNB->abstraction_flag = 0;
eNB->single_thread_flag = single_thread_flag;
#ifndef OCP_FRAMEWORK
LOG_I(PHY,"Initializing eNB %d CC_id %d : (%s,%s)\n",inst,CC_id,eNB_functions[node_function[CC_id]],eNB_timing[node_timing[CC_id]]);
LOG_I(PHY, "Initializing eNB %d CC_id %d : (%s,%s)\n", inst, CC_id, eNB_functions[node_function[CC_id]],
eNB_timing[node_timing[CC_id]]);
#endif
switch (node_function[CC_id]) {
......@@ -1676,15 +1724,15 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->start_if = start_if;
eNB->fh_asynch = fh_if5_asynch_DL;
ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]);
if (ret<0) {
if (ret < 0) {
printf("Exiting, cannot initialize rf device\n");
exit(-1);
}
eNB->rfdevice.host_type = RRH_HOST;
eNB->ifdevice.host_type = RRH_HOST;
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id);
if (ret<0) {
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params + CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n", ret, CC_id);
if (ret < 0) {
printf("Exiting, cannot initialize transport protocol\n");
exit(-1);
}
......@@ -1702,15 +1750,15 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->start_rf = start_rf;
eNB->start_if = start_if;
ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]);
if (ret<0) {
if (ret < 0) {
printf("Exiting, cannot initialize rf device\n");
exit(-1);
}
eNB->rfdevice.host_type = RRH_HOST;
eNB->ifdevice.host_type = RRH_HOST;
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id);
if (ret<0) {
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params + CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n", ret, CC_id);
if (ret < 0) {
printf("Exiting, cannot initialize transport protocol\n");
exit(-1);
}
......@@ -1731,7 +1779,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->start_if = NULL;
eNB->fh_asynch = NULL;
ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]);
if (ret<0) {
if (ret < 0) {
printf("Exiting, cannot initialize rf device\n");
exit(-1);
}
......@@ -1750,8 +1798,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->rx_fh = rx_fh_slave;
eNB->fh_asynch = fh_if5_asynch_UL;
}
else {
} else {
eNB->tx_fh = tx_fh_if5;
eNB->rx_fh = rx_fh_if5;
eNB->fh_asynch = NULL;
......@@ -1763,9 +1810,9 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->ifdevice.host_type = BBU_HOST;
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id);
if (ret<0) {
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params + CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n", ret, CC_id);
if (ret < 0) {
printf("Exiting, cannot initialize transport protocol\n");
exit(-1);
}
......@@ -1784,9 +1831,9 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->fh_asynch = (eNB->node_timing == synch_to_other) ? fh_if4p5_asynch_UL : NULL;
eNB->rfdevice.host_type = BBU_HOST;
eNB->ifdevice.host_type = BBU_HOST;
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id);
if (ret<0) {
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params + CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n", ret, CC_id);
if (ret < 0) {
printf("Exiting, cannot initialize transport protocol\n");
exit(-1);
}
......@@ -1809,9 +1856,9 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->rfdevice.host_type = BBU_HOST;
eNB->ifdevice.host_type = BBU_HOST;
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id);
if (ret<0) {
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params + CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n", ret, CC_id);
if (ret < 0) {
printf("Exiting, cannot initialize transport protocol\n");
exit(-1);
}
......@@ -1821,7 +1868,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
}
}
if (setup_eNB_buffers(PHY_vars_eNB_g[inst],&openair0_cfg[0])!=0) {
if (setup_eNB_buffers(PHY_vars_eNB_g[inst], &openair0_cfg[0]) != 0) {
printf("Exiting, cannot initialize eNodeB Buffers\n");
exit(-1);
}
......@@ -1830,7 +1877,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
}
sleep(1);
LOG_D(HW,"[lte-softmodem.c] eNB threads created\n");
LOG_D(HW, "[lte-softmodem.c] eNB threads created\n");
}
......@@ -1838,8 +1885,8 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
void stop_eNB(int nb_inst) {
for (int inst=0;inst<nb_inst;inst++) {
printf("Killing eNB %d processing threads\n",inst);
for (int inst = 0; inst < nb_inst; inst++) {
printf("Killing eNB %d processing threads\n", inst);
kill_eNB_proc(inst);
}
}
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