Commit 8717057c authored by Raymond Knopp's avatar Raymond Knopp

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5796 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 36114b84
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/ *******************************************************************************/
/*! \file lte-softmodem.c /*! \file lte-softmodem.c
* \brief main program to control HW and scheduling * \brief main program to control HW and scheduling
...@@ -69,7 +69,7 @@ static int hw_subframe; ...@@ -69,7 +69,7 @@ static int hw_subframe;
#include "PHY/defs.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 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 //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
#ifndef USRP #ifndef USRP
#include "openair0_lib.h" #include "openair0_lib.h"
...@@ -77,7 +77,7 @@ static int hw_subframe; ...@@ -77,7 +77,7 @@ static int hw_subframe;
#include "../../ARCH/COMMON/common_lib.h" #include "../../ARCH/COMMON/common_lib.h"
#endif #endif
#undef FRAME_LENGTH_COMPLEX_SAMPLES //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
#include "PHY/vars.h" #include "PHY/vars.h"
#include "MAC_INTERFACE/vars.h" #include "MAC_INTERFACE/vars.h"
...@@ -131,6 +131,8 @@ unsigned short config_frames[4] = {2,9,11,13}; ...@@ -131,6 +131,8 @@ unsigned short config_frames[4] = {2,9,11,13};
#define DEBUG_THREADS 1 #define DEBUG_THREADS 1
//#define USRP_DEBUG 1
struct timing_info_t { struct timing_info_t {
//unsigned int frame, hw_slot, last_slot, next_slot; //unsigned int frame, hw_slot, last_slot, next_slot;
RTIME time_min, time_max, time_avg, time_last, time_now; RTIME time_min, time_max, time_avg, time_last, time_now;
...@@ -182,8 +184,10 @@ struct sched_param sched_param_dlsch; ...@@ -182,8 +184,10 @@ struct sched_param sched_param_dlsch;
#ifdef USRP #ifdef USRP
pthread_cond_t sync_cond; pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex; pthread_mutex_t sync_mutex;
#endif #endif
#endif #endif
RTIME T0;
pthread_attr_t attr_UE_init_synch; pthread_attr_t attr_UE_init_synch;
pthread_attr_t attr_UE_thread_tx; pthread_attr_t attr_UE_thread_tx;
...@@ -265,7 +269,7 @@ static unsigned int nf_byp[4] = {15,20,29,23}; ...@@ -265,7 +269,7 @@ static unsigned int nf_byp[4] = {15,20,29,23};
static rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}}; static rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}};
#else #else
double tx_gain[MAX_NUM_CCs][4] = {{120,0,0,0}}; double tx_gain[MAX_NUM_CCs][4] = {{120,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{50,0,0,0}}; double rx_gain[MAX_NUM_CCs][4] = {{40,0,0,0}};
#endif #endif
double sample_rate=30.72e6; double sample_rate=30.72e6;
...@@ -282,9 +286,17 @@ unsigned int samples_per_packets = 2048; // samples got every recv or send ...@@ -282,9 +286,17 @@ unsigned int samples_per_packets = 2048; // samples got every recv or send
unsigned int tx_forward_nsamps; unsigned int tx_forward_nsamps;
int sf_bounds_5[10] = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75}; int sf_bounds_5[10] = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75};
int sf_bounds_5_tx[10] = {4, 11, 19, 26, 34, 41, 49, 56, 64, 71};
int sf_bounds_10[10] = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75}; int sf_bounds_10[10] = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75};
int sf_bounds_10_tx[10] = {4, 11, 19, 26, 34, 41, 49, 56, 64, 71};
int sf_bounds_20[10] = {15, 30, 45, 60, 75, 90, 105, 120, 135, 150}; int sf_bounds_20[10] = {15, 30, 45, 60, 75, 90, 105, 120, 135, 150};
int sf_bounds_20_tx[10] = {7, 22, 37, 52, 67, 82, 97, 112, 127, 142};
int *sf_bounds; int *sf_bounds;
int *sf_bounds_tx;
int max_cnt; int max_cnt;
int tx_delay; int tx_delay;
...@@ -392,15 +404,15 @@ void exit_fun(const char* s) ...@@ -392,15 +404,15 @@ void exit_fun(const char* s)
static int latency_target_fd = -1; static int latency_target_fd = -1;
static int32_t latency_target_value = 0; static int32_t latency_target_value = 0;
/* Latency trick - taken from cyclictest.c /* Latency trick - taken from cyclictest.c
* if the file /dev/cpu_dma_latency exists, * if the file /dev/cpu_dma_latency exists,
* open it and write a zero into it. This will tell * open it and write a zero into it. This will tell
* the power management system not to transition to * the power management system not to transition to
* a high cstate (in fact, the system acts like idle=poll) * a high cstate (in fact, the system acts like idle=poll)
* When the fd to /dev/cpu_dma_latency is closed, the behavior * When the fd to /dev/cpu_dma_latency is closed, the behavior
* goes back to the system default. * goes back to the system default.
* *
* Documentation/power/pm_qos_interface.txt * Documentation/power/pm_qos_interface.txt
*/ */
static void set_latency_target(void) static void set_latency_target(void)
{ {
struct stat s; struct stat s;
...@@ -915,8 +927,7 @@ static void * eNB_thread_tx(void *param) { ...@@ -915,8 +927,7 @@ static void * eNB_thread_tx(void *param) {
} }
} }
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe),1); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe),1);
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_ENB, proc->frame_tx); vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx);
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_ENB, proc->subframe*2);
if (oai_exit) break; if (oai_exit) break;
...@@ -1019,7 +1030,6 @@ static void * eNB_thread_rx(void *param) { ...@@ -1019,7 +1030,6 @@ static void * eNB_thread_rx(void *param) {
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe),0); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe),0);
// LOG_I(PHY,"Locking mutex for eNB proc %d (IC %d,mutex %p)\n",proc->subframe,proc->instance_cnt,&proc->mutex); // LOG_I(PHY,"Locking mutex for eNB proc %d (IC %d,mutex %p)\n",proc->subframe,proc->instance_cnt,&proc->mutex);
if (pthread_mutex_lock(&proc->mutex_rx) != 0) { if (pthread_mutex_lock(&proc->mutex_rx) != 0) {
LOG_E(PHY,"[SCHED][eNB] error locking mutex for eNB RX proc %d\n",proc->subframe); LOG_E(PHY,"[SCHED][eNB] error locking mutex for eNB RX proc %d\n",proc->subframe);
...@@ -1037,6 +1047,7 @@ static void * eNB_thread_rx(void *param) { ...@@ -1037,6 +1047,7 @@ static void * eNB_thread_rx(void *param) {
} }
} }
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe),1); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe),1);
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx);
if (oai_exit) break; if (oai_exit) break;
...@@ -1141,9 +1152,10 @@ void init_eNB_proc(void) { ...@@ -1141,9 +1152,10 @@ void init_eNB_proc(void) {
#else #else
// TX processes subframe +2, RX subframe // TX processes subframe +2, RX subframe
// Note this inialization is because the first process awoken for frame 0 is number 1 and so processes 8,9 and 0 have to start with frame 1 // Note this inialization is because the first process awoken for frame 0 is number 1 and so processes 8,9 and 0 have to start with frame 1
// PHY_vars_eNB_g[0][CC_id]->proc[7].frame_tx = 1;
PHY_vars_eNB_g[0][CC_id]->proc[8].frame_tx = 1; PHY_vars_eNB_g[0][CC_id]->proc[8].frame_tx = 1;
PHY_vars_eNB_g[0][CC_id]->proc[9].frame_tx = 1; PHY_vars_eNB_g[0][CC_id]->proc[9].frame_tx = 1;
PHY_vars_eNB_g[0][CC_id]->proc[0].frame_tx = 1; // PHY_vars_eNB_g[0][CC_id]->proc[0].frame_tx = 1;
#endif #endif
} }
} }
...@@ -1261,13 +1273,13 @@ static void *eNB_thread(void *arg) ...@@ -1261,13 +1273,13 @@ static void *eNB_thread(void *arg)
timing_info.n_samples = 0; timing_info.n_samples = 0;
#ifdef USRP #ifdef USRP
printf("waiting for USRP sync \n"); printf("waiting for USRP sync (eNB_thread)\n");
#ifdef RTAI #ifdef RTAI
rt_sem_wait(sync_sem); rt_sem_wait(sync_sem);
#else #else
//pthread_mutex_lock(&sync_mutex); pthread_mutex_lock(&sync_mutex);
pthread_cond_wait(&sync_cond, &sync_mutex); pthread_cond_wait(&sync_cond, &sync_mutex);
//pthread_mutex_unlock(&sync_mutex); pthread_mutex_unlock(&sync_mutex);
#endif #endif
// printf("starting eNB thread @ %llu\n",get_usrp_time(&openair0)); // printf("starting eNB thread @ %llu\n",get_usrp_time(&openair0));
#endif #endif
...@@ -1344,6 +1356,7 @@ static void *eNB_thread(void *arg) ...@@ -1344,6 +1356,7 @@ static void *eNB_thread(void *arg)
openair0_timestamp time0,time1; openair0_timestamp time0,time1;
unsigned int rxs; unsigned int rxs;
#ifndef USRP_DEBUG
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);
/* /*
// Grab 1/4 of RX buffer and get timestamp // Grab 1/4 of RX buffer and get timestamp
...@@ -1357,6 +1370,8 @@ static void *eNB_thread(void *arg) ...@@ -1357,6 +1370,8 @@ static void *eNB_thread(void *arg)
*/ */
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_TXCNT,tx_cnt);
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_RXCNT,rx_cnt*samples_per_packets);
rxs = openair0.trx_read_func(&openair0, rxs = openair0.trx_read_func(&openair0,
&timestamp, &timestamp,
&rxdata[rx_cnt*samples_per_packets], &rxdata[rx_cnt*samples_per_packets],
...@@ -1385,7 +1400,30 @@ static void *eNB_thread(void *arg) ...@@ -1385,7 +1400,30 @@ static void *eNB_thread(void *arg)
if (rxs != (3*(samples_per_packets>>2))) if (rxs != (3*(samples_per_packets>>2)))
oai_exit=1; oai_exit=1;
*/ */
#else
rt_sleep_ns(1000000);
#endif
if (rx_cnt == sf_bounds_tx[hw_subframe]) {
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].mutex_tx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",hw_subframe,PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx);
}
else {
// LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d)\n",hw_subframe,PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt);
PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx++;
pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].mutex_tx);
if (PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx == 0) {
if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].cond_tx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB TX thread %d\n",hw_subframe);
}
}
else {
LOG_W(PHY,"[eNB] Frame %d, eNB TX thread %d busy!!\n",PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].frame_tx,hw_subframe);
oai_exit=1;
}
}
}
}
rx_cnt++; rx_cnt++;
tx_cnt++; tx_cnt++;
...@@ -1401,7 +1439,7 @@ static void *eNB_thread(void *arg) ...@@ -1401,7 +1439,7 @@ static void *eNB_thread(void *arg)
if (oai_exit) break; if (oai_exit) break;
if (frame>99) {
timing_info.time_last = timing_info.time_now; timing_info.time_last = timing_info.time_now;
timing_info.time_now = rt_get_time_ns(); timing_info.time_now = rt_get_time_ns();
...@@ -1427,20 +1465,16 @@ static void *eNB_thread(void *arg) ...@@ -1427,20 +1465,16 @@ static void *eNB_thread(void *arg)
*/ */
//} //}
if (multi_thread == 0) {
if ((slot&1) == 0) {
LOG_I(PHY,"[eNB] Single thread slot %d\n",slot);
phy_procedures_eNB_lte ((2+(slot>>1))%10, PHY_vars_eNB_g[0], 0, no_relay,NULL);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
do_OFDM_mod_rt((2+(slot>>1))%10,PHY_vars_eNB_g[0][CC_id]);
}
}
}
else { // multi-thread > 0
if ((slot&1) == 1) { if ((slot&1) == 1) {
#ifndef USRP
sf = ((slot>>1)+1)%10; sf = ((slot>>1)+1)%10;
#else
sf = hw_subframe;
#endif
// LOG_I(PHY,"[eNB] Multithread slot %d (IC %d)\n",slot,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt); // LOG_I(PHY,"[eNB] Multithread slot %d (IC %d)\n",slot,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
#ifndef USRP
if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx) != 0) { if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx); LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx);
} }
...@@ -1458,7 +1492,7 @@ static void *eNB_thread(void *arg) ...@@ -1458,7 +1492,7 @@ static void *eNB_thread(void *arg)
oai_exit=1; oai_exit=1;
} }
} }
#endif
if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx) != 0) { if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB RX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx); LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB RX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx);
} }
...@@ -1479,8 +1513,8 @@ static void *eNB_thread(void *arg) ...@@ -1479,8 +1513,8 @@ static void *eNB_thread(void *arg)
} }
} }
}
}
#ifndef RTAI #ifndef RTAI
//pthread_mutex_lock(&tti_mutex); //pthread_mutex_lock(&tti_mutex);
#endif #endif
...@@ -1502,7 +1536,7 @@ static void *eNB_thread(void *arg) ...@@ -1502,7 +1536,7 @@ static void *eNB_thread(void *arg)
frame++; frame++;
slot = 1; slot = 1;
} }
#endif #endif
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
...@@ -1535,23 +1569,31 @@ static void *eNB_thread(void *arg) ...@@ -1535,23 +1569,31 @@ static void *eNB_thread(void *arg)
return 0; return 0;
} }
#ifdef USRP_DEBUG
int is_synchronized=1;
#else
int is_synchronized=0; int is_synchronized=0;
#endif
static void *UE_thread_synch(void *arg) { static void *UE_thread_synch(void *arg) {
int i,hw_slot_offset,CC_id; int i,hw_slot_offset,CC_id;
PHY_VARS_UE *UE = arg; PHY_VARS_UE *UE = arg;
printf("UE_thread_sync in with PHY_vars_UE %p\n",arg);
#ifdef USRP #ifdef USRP
printf("waiting for USRP sync \n"); printf("waiting for USRP sync (UE_thread_synch) \n");
#ifdef RTAI #ifdef RTAI
rt_sem_wait(sync_sem); rt_sem_wait(sync_sem);
#else #else
//pthread_mutex_lock(&sync_mutex);
pthread_mutex_lock(&sync_mutex);
printf("Locked sync_mutex, waiting (UE_sync_thread)\n");
pthread_cond_wait(&sync_cond, &sync_mutex); pthread_cond_wait(&sync_cond, &sync_mutex);
//pthread_mutex_unlock(&sync_mutex); pthread_mutex_unlock(&sync_mutex);
printf("unlocked sync_mutex (UE_sync_thread)\n");
#endif #endif
// printf("starting eNB thread @ %llu\n",get_usrp_time(&openair0)); printf("starting UE synch thread\n");
#endif #endif
while (!oai_exit) { while (!oai_exit) {
...@@ -1569,7 +1611,8 @@ static void *UE_thread_synch(void *arg) { ...@@ -1569,7 +1611,8 @@ static void *UE_thread_synch(void *arg) {
oai_exit=1; oai_exit=1;
} }
} // mutex_lock
// LOG_I(PHY,"[SCHED][UE] Running UE intial synch\n");
if (initial_sync(PHY_vars_UE_g[0][0],mode)==0) { if (initial_sync(PHY_vars_UE_g[0][0],mode)==0) {
/* /*
lte_adjust_synch(&PHY_vars_UE_g[0]->lte_frame_parms, lte_adjust_synch(&PHY_vars_UE_g[0]->lte_frame_parms,
...@@ -1584,19 +1627,19 @@ static void *UE_thread_synch(void *arg) { ...@@ -1584,19 +1627,19 @@ static void *UE_thread_synch(void *arg) {
memset(PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata[aa],0, memset(PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata[aa],0,
PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)); PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int));
*/ */
if (mode == rx_calib_ue) {
exit_fun("[HW][UE] UE in RX calibration mode"); T0 = rt_get_time_ns();
}
else {
is_synchronized = 1; is_synchronized = 1;
oai_exit=1; PHY_vars_UE_g[0][0]->slot_rx = 0;
//oai_exit=1;
//start the DMA transfers //start the DMA transfers
//LOG_D(HW,"Before openair0_start_rt_acquisition \n"); //LOG_D(HW,"Before openair0_start_rt_acquisition \n");
//openair0_start_rt_acquisition(0); //openair0_start_rt_acquisition(0);
hw_slot_offset = (PHY_vars_UE_g[0][0]->rx_offset<<1) / PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti; hw_slot_offset = (PHY_vars_UE_g[0][0]->rx_offset<<1) / PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti;
LOG_D(HW,"Got synch: hw_slot_offset %d\n",hw_slot_offset); LOG_I(HW,"Got synch: hw_slot_offset %d\n",hw_slot_offset);
}
} }
else { else {
if (openair_daq_vars.freq_offset >= 0) { if (openair_daq_vars.freq_offset >= 0) {
...@@ -1611,19 +1654,33 @@ static void *UE_thread_synch(void *arg) { ...@@ -1611,19 +1654,33 @@ static void *UE_thread_synch(void *arg) {
mac_xface->macphy_exit("No cell synchronization found, abondoning"); mac_xface->macphy_exit("No cell synchronization found, abondoning");
} }
else { else {
LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",openair_daq_vars.freq_offset); // LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",openair_daq_vars.freq_offset);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { for (card=0;card<MAX_CARDS;card++) {
for (i=0; i<openair0_cfg[rf_map[CC_id].card].rx_num_channels; i++) for (i=0; i<openair0_cfg[card].rx_num_channels; i++) {
openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+openair_daq_vars.freq_offset; openair0_cfg[card].rx_freq[i] = downlink_frequency[card][i]+openair_daq_vars.freq_offset;
for (i=0; i<openair0_cfg[rf_map[CC_id].card].tx_num_channels; i++) openair0_cfg[card].tx_freq[i] = downlink_frequency[card][i]+uplink_frequency_offset[card][i]+openair_daq_vars.freq_offset;
openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+openair_daq_vars.freq_offset; #ifndef USRP_DEBUG
openair0_set_frequencies(&openair0,&openair0_cfg[0]);
#endif
} }
// openair0_config(&openair0_cfg[0],UE_flag); }
// openair0_dump_config(&openair0_cfg[0],UE_flag);
// rt_sleep_ns(FRAME_PERIOD); // rt_sleep_ns(FRAME_PERIOD);
} // freq_offset } // freq_offset
} // initial_sync=0 } // initial_sync=0
} // mutex_lock
if (pthread_mutex_lock(&PHY_vars_UE_g[0][0]->mutex_synch) != 0) {
printf("[openair][SCHED][eNB] error locking mutex for UE synch\n");
}
else {
PHY_vars_UE_g[0][0]->instance_cnt_synch--;
if (pthread_mutex_unlock(&PHY_vars_UE_g[0][0]->mutex_synch) != 0) {
printf("[openair][SCHED][eNB] error unlocking mutex for UE synch\n");
}
}
} // while !oai_exit } // while !oai_exit
return(0); return(0);
...@@ -1693,27 +1750,48 @@ static void *UE_thread_tx(void *arg) { ...@@ -1693,27 +1750,48 @@ static void *UE_thread_tx(void *arg) {
static void *UE_thread_rx(void *arg) { static void *UE_thread_rx(void *arg) {
PHY_VARS_UE *UE = (PHY_VARS_UE*)arg; PHY_VARS_UE *UE = (PHY_VARS_UE*)arg;
int i;
UE->instance_cnt_rx=-1; UE->instance_cnt_rx=-1;
mlockall(MCL_CURRENT | MCL_FUTURE); mlockall(MCL_CURRENT | MCL_FUTURE);
while (!oai_exit) { #ifdef USRP
printf("waiting for USRP sync (UE_thread_rx)\n");
#ifdef RTAI
rt_sem_wait(sync_sem);
#else
pthread_mutex_lock(&sync_mutex);
printf("Locked sync_mutex, waiting (UE_thread_rx)\n");
pthread_cond_wait(&sync_cond, &sync_mutex);
pthread_mutex_unlock(&sync_mutex);
printf("unlocked sync_mutex, waiting (UE_thread_rx)\n");
#endif
#endif
printf("Starting UE RX thread\n");
while (!oai_exit) {
printf("UE_thread_rx: locking UE RX mutex\n");
if (pthread_mutex_lock(&UE->mutex_rx) != 0) { if (pthread_mutex_lock(&UE->mutex_rx) != 0) {
LOG_E(PHY,"[SCHED][eNB] error locking mutex for UE RX\n"); LOG_E(PHY,"[SCHED][eNB] error locking mutex for UE RX\n");
oai_exit=1; oai_exit=1;
} }
else { else {
printf("UE_thread_rx: unlocking UE RX mutex (IC %d)\n",UE->instance_cnt_rx);
while (UE->instance_cnt_rx < 0) { while (UE->instance_cnt_rx < 0) {
printf("Waiting for cond_rx (%p)\n",(void*)&UE->cond_rx);
pthread_cond_wait(&UE->cond_rx,&UE->mutex_rx); pthread_cond_wait(&UE->cond_rx,&UE->mutex_rx);
printf("Got UE RX condition, IC %d @ %llu\n",UE->instance_cnt_rx,rt_get_time_ns()-T0);
} }
if (pthread_mutex_unlock(&UE->mutex_rx) != 0) { if (pthread_mutex_unlock(&UE->mutex_rx) != 0) {
LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for UE RX\n"); LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for UE RX\n");
oai_exit=1; oai_exit=1;
} }
for (i=0;i<2;i++) {
printf("UE_thread_rx: processing slot %d (slot rx %d) @ %llu\n",i,UE->slot_rx,rt_get_time_ns()-T0);
if ((subframe_select(&UE->lte_frame_parms,UE->slot_rx>>1)==SF_DL) || if ((subframe_select(&UE->lte_frame_parms,UE->slot_rx>>1)==SF_DL) ||
(UE->lte_frame_parms.frame_type == FDD)){ (UE->lte_frame_parms.frame_type == FDD)){
phy_procedures_UE_RX(UE,eNB_id,0,mode,no_relay,NULL); phy_procedures_UE_RX(UE,eNB_id,0,mode,no_relay,NULL);
...@@ -1730,46 +1808,82 @@ static void *UE_thread_rx(void *arg) { ...@@ -1730,46 +1808,82 @@ static void *UE_thread_rx(void *arg) {
} }
} }
} }
if (pthread_mutex_lock(&UE->mutex_rx) != 0) {
printf("[openair][SCHED][eNB] error locking mutex for UE RX\n");
}
else {
UE->instance_cnt_rx--;
if (pthread_mutex_unlock(&UE->mutex_rx) != 0) {
printf("[openair][SCHED][eNB] error unlocking mutex for UE RX\n");
}
}
printf("UE_thread_rx done\n");
}
return(0); return(0);
} }
#ifdef USRP #ifdef USRP
static void *UE_thread_new(void *arg) { #define RX_OFF_MAX 10
#define RX_OFF_MIN 5
#define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2)
static void *UE_thread(void *arg) {
int slot=0,frame=0,hw_slot,last_slot, next_slot,hw_subframe; LTE_DL_FRAME_PARMS *frame_parms=&PHY_vars_UE_g[0][0]->lte_frame_parms;
int slot=1,frame=0,hw_slot,last_slot, next_slot,hw_subframe=0,rx_cnt=0,tx_cnt=0;
// unsigned int aa; // unsigned int aa;
static int is_synchronized = 0; int dummy[samples_per_packets];
int dummy_dump = 0;
int tx_enabled=0;
int start_rx_stream=0;
int rx_off_diff = 0;
int rx_correction_timer = 0;
printf("waiting for USRP sync \n"); openair0_timestamp time0,time1;
unsigned int rxs;
printf("waiting for USRP sync (UE_thread)\n");
#ifdef RTAI #ifdef RTAI
rt_sem_wait(sync_sem); rt_sem_wait(sync_sem);
#else #else
//pthread_mutex_lock(&sync_mutex); pthread_mutex_lock(&sync_mutex);
printf("Locked sync_mutex, waiting (UE_thread)\n");
pthread_cond_wait(&sync_cond, &sync_mutex); pthread_cond_wait(&sync_cond, &sync_mutex);
//pthread_mutex_unlock(&sync_mutex); pthread_mutex_unlock(&sync_mutex);
printf("unlocked sync_mutex, waiting (UE_thread)\n");
#endif #endif
while (!oai_exit) { printf("starting UE thread\n");
T0 = rt_get_time_ns();
while (!oai_exit) {
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_subframe); vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_subframe);
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame); vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame);
while (rx_cnt < sf_bounds[hw_subframe]) { while (rx_cnt < sf_bounds[hw_subframe]) {
openair0_timestamp time0,time1;
unsigned int rxs;
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);
#ifndef USRP_DEBUG
rxs = openair0.trx_read_func(&openair0, rxs = openair0.trx_read_func(&openair0,
&timestamp, &timestamp,
&rxdata[rx_cnt*samples_per_packets], (dummy_dump==0) ? &rxdata[rx_cnt*samples_per_packets] : dummy,
samples_per_packets); samples_per_packets - ((rx_cnt==0) ? rx_off_diff : 0));
if (rxs != samples_per_packets) if (rxs != (samples_per_packets- ((rx_cnt==0) ? rx_off_diff : 0)))
oai_exit=1; oai_exit=1;
rx_off_diff = 0;
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);
// Transmit TX buffer based on timestamp from RX // Transmit TX buffer based on timestamp from RX
if (is_synchronized) { if (tx_enabled) {
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
openair0.trx_write_func(&openair0, openair0.trx_write_func(&openair0,
(timestamp+samples_per_packets*tx_delay-tx_forward_nsamps), (timestamp+samples_per_packets*tx_delay-tx_forward_nsamps),
...@@ -1778,7 +1892,9 @@ static void *UE_thread_new(void *arg) { ...@@ -1778,7 +1892,9 @@ static void *UE_thread_new(void *arg) {
1); 1);
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);
} }
#else
rt_sleep_ns(10000000);
#endif
rx_cnt++; rx_cnt++;
tx_cnt++; tx_cnt++;
...@@ -1789,15 +1905,78 @@ static void *UE_thread_new(void *arg) { ...@@ -1789,15 +1905,78 @@ static void *UE_thread_new(void *arg) {
if(rx_cnt == max_cnt) if(rx_cnt == max_cnt)
rx_cnt = 0; rx_cnt = 0;
if (is_synchronized) {
// phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[0][0], 0, 0,mode,0,NULL);
if (is_synchronized==1) {
// printf("UE_thread: hw_frame %d, hw_subframe %d (time %llu)\n",frame,hw_subframe,rt_get_time_ns()-T0);
if (start_rx_stream==1) {
// printf("UE_thread: locking UE mutex_rx\n");
if (pthread_mutex_lock(&PHY_vars_UE_g[0][0]->mutex_rx) != 0) {
LOG_E(PHY,"[SCHED][UE] error locking mutex for UE RX thread\n");
oai_exit=1;
}
else {
PHY_vars_UE_g[0][0]->instance_cnt_rx++;
// printf("UE_thread: Unlocking UE mutex_rx\n");
pthread_mutex_unlock(&PHY_vars_UE_g[0][0]->mutex_rx);
if (PHY_vars_UE_g[0][0]->instance_cnt_rx == 0) {
// printf("Scheduling UE RX for frame %d (hw frame %d), subframe %d (%d)\n",PHY_vars_UE_g[0][0]->frame_rx,frame,hw_subframe,PHY_vars_UE_g[0][0]->slot_rx>>1);
if (pthread_cond_signal(&PHY_vars_UE_g[0][0]->cond_rx) != 0) {
LOG_E(PHY,"[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n");
oai_exit=1;
}
else {
// printf("UE_thread: cond_signal for RX ok (%p) @ %llu\n",(void*)&PHY_vars_UE_g[0][0]->cond_rx,rt_get_time_ns()-T0);
}
if (mode == rx_calib_ue) {
if (frame == 10) {
LOG_I(PHY,"[SCHED][UE] Found cell with N_RB_DL %d, PHICH CONFIG (%d,%d), Nid_cell %d, NB_ANTENNAS_TX %d, initial frequency offset %d Hz, frequency offset %d Hz, RSSI (digital) %d dB, measured Gain %d dB\n",
PHY_vars_UE_g[0][0]->lte_frame_parms.N_RB_DL,
PHY_vars_UE_g[0][0]->lte_frame_parms.phich_config_common.phich_duration,
PHY_vars_UE_g[0][0]->lte_frame_parms.phich_config_common.phich_resource,
PHY_vars_UE_g[0][0]->lte_frame_parms.Nid_cell,
PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx_eNB,
openair_daq_vars.freq_offset,
PHY_vars_UE_g[0][0]->lte_ue_common_vars.freq_offset,
PHY_vars_UE_g[0][0]->PHY_measurements.rx_power_avg_dB[0],
PHY_vars_UE_g[0][0]->PHY_measurements.rx_power_avg_dB[0] - rx_input_level_dBm
);
exit_fun("[HW][UE] UE in RX calibration mode, exiting");
}
}
}
else {
LOG_E(PHY,"[SCHED][UE] UE RX thread busy!!\n");
oai_exit=1;
}
}
}
} }
else { // we are not yet synchronized else { // we are not yet synchronized
if (slot == 18) { if ((hw_subframe == 9)&&(dummy_dump == 0)) {
// Wake up initial synch thread // Wake up initial synch thread
if (pthread_mutex_lock(&PHY_vars_UE_g[0][0]->mutex_synch) != 0) {
LOG_E(PHY,"[SCHED][UE] error locking mutex for UE initial synch thread\n");
oai_exit=1;
}
else {
PHY_vars_UE_g[0][0]->instance_cnt_synch++;
pthread_mutex_unlock(&PHY_vars_UE_g[0][0]->mutex_synch);
dummy_dump = 1;
if (PHY_vars_UE_g[0][0]->instance_cnt_synch == 0) {
if (pthread_cond_signal(&PHY_vars_UE_g[0][0]->cond_synch) != 0) {
LOG_E(PHY,"[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n");
oai_exit=1;
}
}
else {
LOG_E(PHY,"[SCHED][UE] UE sync thread busy!!\n");
oai_exit=1;
}
}
} }
} }
/* /*
...@@ -1811,6 +1990,38 @@ static void *UE_thread_new(void *arg) { ...@@ -1811,6 +1990,38 @@ static void *UE_thread_new(void *arg) {
hw_subframe = 0; hw_subframe = 0;
frame++; frame++;
slot = 1; slot = 1;
if (PHY_vars_UE_g[0][0]->instance_cnt_synch < 0) {
if (is_synchronized == 1) {
rx_off_diff = 0;
// LOG_D(PHY,"HW RESYNC: hw_frame %d: rx_offset = %d\n",frame,PHY_vars_UE_g[0][0]->rx_offset);
if ((PHY_vars_UE_g[0][0]->rx_offset > RX_OFF_MAX)&&(start_rx_stream==0)) {
start_rx_stream=1;
//LOG_D(PHY,"HW RESYNC: hw_frame %d: Resynchronizing sample stream\n");
frame=0;
// dump ahead in time to start of frame
#ifndef USRP_DEBUG
rxs = openair0.trx_read_func(&openair0,
&timestamp,
&rxdata[0],
PHY_vars_UE_g[0][0]->rx_offset);
#else
rt_sleep_ns(10000000);
#endif
PHY_vars_UE_g[0][0]->rx_offset=0;
}
else if ((PHY_vars_UE_g[0][0]->rx_offset < RX_OFF_MIN)&&(start_rx_stream==1)) {
// rx_off_diff = -PHY_vars_UE_g[0][0]->rx_offset + RX_OFF_MIN;
}
else if ((PHY_vars_UE_g[0][0]->rx_offset > (FRAME_LENGTH_COMPLEX_SAMPLES-RX_OFF_MAX)) &&(start_rx_stream==1) && (rx_correction_timer == 0)) {
rx_off_diff = FRAME_LENGTH_COMPLEX_SAMPLES-PHY_vars_UE_g[0][0]->rx_offset;
rx_correction_timer = 5;
}
if (rx_correction_timer>0)
rx_correction_timer--;
// LOG_D(PHY,"HW RESYNC: hw_frame %d: Correction: rx_off_diff %d (timer %d)\n",frame,rx_off_diff,rx_correction_timer);
}
dummy_dump=0;
}
} }
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
...@@ -2001,7 +2212,8 @@ static void *UE_thread(void *arg) { ...@@ -2001,7 +2212,8 @@ static void *UE_thread(void *arg) {
openair0_start_rt_acquisition(0); openair0_start_rt_acquisition(0);
hw_slot_offset = (PHY_vars_UE_g[0][0]->rx_offset<<1) / PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti; hw_slot_offset = (PHY_vars_UE_g[0][0]->rx_offset<<1) / PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti;
LOG_D(HW,"Got synch: hw_slot_offset %d\n",hw_slot_offset); //LOG_D(HW,"Got synch: hw_slot_offset %d\n",hw_slot_offset);
oai_exit=1;
/*}*/ /*}*/
} }
else { else {
...@@ -2017,7 +2229,7 @@ static void *UE_thread(void *arg) { ...@@ -2017,7 +2229,7 @@ static void *UE_thread(void *arg) {
mac_xface->macphy_exit("No cell synchronization found, abondoning"); mac_xface->macphy_exit("No cell synchronization found, abondoning");
} }
else { else {
LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",openair_daq_vars.freq_offset); // LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",openair_daq_vars.freq_offset);
#ifndef USRP #ifndef USRP
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
for (i=0; i<openair0_cfg[rf_map[CC_id].card].rx_num_channels; i++) for (i=0; i<openair0_cfg[rf_map[CC_id].card].rx_num_channels; i++)
...@@ -2191,6 +2403,7 @@ static void get_options (int argc, char **argv) { ...@@ -2191,6 +2403,7 @@ static void get_options (int argc, char **argv) {
case 'd': case 'd':
#ifdef XFORMS #ifdef XFORMS
do_forms=1; do_forms=1;
printf("Running with XFORMS!\n");
#endif #endif
break; break;
...@@ -2383,7 +2596,7 @@ int main(int argc, char **argv) { ...@@ -2383,7 +2596,7 @@ int main(int argc, char **argv) {
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS)); frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS));
/* Set some default values that may be overwritten while reading options */ /* Set some default values that may be overwritten while reading options */
frame_parms[CC_id]->frame_type = TDD; /* TDD */ frame_parms[CC_id]->frame_type = FDD; /* TDD */
frame_parms[CC_id]->tdd_config = 3; frame_parms[CC_id]->tdd_config = 3;
frame_parms[CC_id]->tdd_config_S = 0; frame_parms[CC_id]->tdd_config_S = 0;
frame_parms[CC_id]->N_RB_DL = 25; frame_parms[CC_id]->N_RB_DL = 25;
...@@ -2391,6 +2604,7 @@ int main(int argc, char **argv) { ...@@ -2391,6 +2604,7 @@ int main(int argc, char **argv) {
frame_parms[CC_id]->Ncp = NORMAL; frame_parms[CC_id]->Ncp = NORMAL;
frame_parms[CC_id]->Ncp_UL = NORMAL; frame_parms[CC_id]->Ncp_UL = NORMAL;
frame_parms[CC_id]->Nid_cell = Nid_cell; frame_parms[CC_id]->Nid_cell = Nid_cell;
frame_parms[CC_id]->num_MBSFN_config = 0;
} }
get_options (argc, argv); //Command-line options get_options (argc, argv); //Command-line options
...@@ -2548,7 +2762,7 @@ int main(int argc, char **argv) { ...@@ -2548,7 +2762,7 @@ int main(int argc, char **argv) {
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs); PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
PHY_vars_UE_g[0][CC_id] = init_lte_UE(frame_parms[CC_id], UE_id,abstraction_flag,transmission_mode); PHY_vars_UE_g[0][CC_id] = init_lte_UE(frame_parms[CC_id], UE_id,abstraction_flag,transmission_mode);
printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,PHY_vars_UE_g[0][CC_id]);
#ifndef OPENAIR2 #ifndef OPENAIR2
for (i=0;i<NUMBER_OF_eNB_MAX;i++) { for (i=0;i<NUMBER_OF_eNB_MAX;i++) {
PHY_vars_UE_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; PHY_vars_UE_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
...@@ -2637,9 +2851,14 @@ int main(int argc, char **argv) { ...@@ -2637,9 +2851,14 @@ int main(int argc, char **argv) {
PHY_vars_eNB_g[0][CC_id]->X_u); PHY_vars_eNB_g[0][CC_id]->X_u);
#ifdef USRP #ifdef USRP
PHY_vars_eNB_g[0][CC_id]->rx_total_gain_eNB_dB = (int)rx_gain[CC_id][0];
PHY_vars_eNB_g[0][CC_id]->rx_total_gain_eNB_dB = (int)rx_gain[CC_id][0] + 96;
#else #else
PHY_vars_eNB_g[0][CC_id]->rx_total_gain_eNB_dB = rxg_max[0] + (int)rx_gain[CC_id][0] - 30; //was measured at rxgain=30; PHY_vars_eNB_g[0][CC_id]->rx_total_gain_eNB_dB = rxg_max[0] + (int)rx_gain[CC_id][0] - 30; //was measured at rxgain=30;
printf("Setting RX total gain to %d\n",PHY_vars_eNB_g[0][CC_id]->rx_total_gain_eNB_dB);
// set eNB to max gain // set eNB to max gain
for (i=0;i<4;i++) for (i=0;i<4;i++)
rx_gain_mode[CC_id][i] = max_gain; rx_gain_mode[CC_id][i] = max_gain;
...@@ -2669,6 +2888,7 @@ int main(int argc, char **argv) { ...@@ -2669,6 +2888,7 @@ int main(int argc, char **argv) {
// from usrp_time_offset // from usrp_time_offset
tx_forward_nsamps = 175; tx_forward_nsamps = 175;
sf_bounds = sf_bounds_20; sf_bounds = sf_bounds_20;
sf_bounds_tx = sf_bounds_20_tx;
max_cnt = 150; max_cnt = 150;
tx_delay = 8; tx_delay = 8;
#endif #endif
...@@ -2680,6 +2900,7 @@ int main(int argc, char **argv) { ...@@ -2680,6 +2900,7 @@ int main(int argc, char **argv) {
samples_per_frame = 153600; samples_per_frame = 153600;
tx_forward_nsamps = 95; tx_forward_nsamps = 95;
sf_bounds = sf_bounds_10; sf_bounds = sf_bounds_10;
sf_bounds_tx = sf_bounds_10_tx;
max_cnt = 75; max_cnt = 75;
tx_delay = 4; tx_delay = 4;
#endif #endif
...@@ -2691,8 +2912,9 @@ int main(int argc, char **argv) { ...@@ -2691,8 +2912,9 @@ int main(int argc, char **argv) {
samples_per_frame = 76800; samples_per_frame = 76800;
tx_forward_nsamps = 70; tx_forward_nsamps = 70;
sf_bounds = sf_bounds_5; sf_bounds = sf_bounds_5;
sf_bounds_tx = sf_bounds_5_tx;
max_cnt = 75; max_cnt = 75;
tx_delay = 8; tx_delay = 5;
#endif #endif
} }
...@@ -2705,6 +2927,8 @@ int main(int argc, char **argv) { ...@@ -2705,6 +2927,8 @@ int main(int argc, char **argv) {
// since the USRP only supports one CC (for the moment), we initialize all the cards with first CC. // since the USRP only supports one CC (for the moment), we initialize all the cards with first CC.
// in the case of EXMIMO2, these values are overwirtten in the function setup_eNB/UE_buffer // in the case of EXMIMO2, these values are overwirtten in the function setup_eNB/UE_buffer
#ifdef USRP #ifdef USRP
openair0_cfg[card].tx_num_channels=1;
openair0_cfg[card].rx_num_channels=1;
for (i=0;i<4;i++) { for (i=0;i<4;i++) {
openair0_cfg[card].tx_gain[i] = tx_gain[0][i]; openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
openair0_cfg[card].rx_gain[i] = rx_gain[0][i]; openair0_cfg[card].rx_gain[i] = rx_gain[0][i];
...@@ -2714,11 +2938,12 @@ int main(int argc, char **argv) { ...@@ -2714,11 +2938,12 @@ int main(int argc, char **argv) {
#endif #endif
} }
#ifndef USRP_DEBUG
if (openair0_device_init(&openair0, &openair0_cfg[0]) <0) { if (openair0_device_init(&openair0, &openair0_cfg[0]) <0) {
printf("Exiting, cannot initialize device\n"); printf("Exiting, cannot initialize device\n");
exit(-1); exit(-1);
} }
#endif
mac_xface = malloc(sizeof(MAC_xface)); mac_xface = malloc(sizeof(MAC_xface));
...@@ -2768,7 +2993,7 @@ int main(int argc, char **argv) { ...@@ -2768,7 +2993,7 @@ int main(int argc, char **argv) {
for(CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { for(CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
rf_map[CC_id].card=0; rf_map[CC_id].card=0;
rf_map[CC_id].chain=CC_id+1; rf_map[CC_id].chain=CC_id;
} }
// connect the TX/RX buffers // connect the TX/RX buffers
...@@ -2948,7 +3173,8 @@ int main(int argc, char **argv) { ...@@ -2948,7 +3173,8 @@ int main(int argc, char **argv) {
// start the main thread // start the main thread
if (UE_flag == 1) { if (UE_flag == 1) {
#ifndef USRP init_UE_threads();
#ifdef RTAI #ifdef RTAI
main_ue_thread = rt_thread_create(UE_thread, NULL, 100000000); main_ue_thread = rt_thread_create(UE_thread, NULL, 100000000);
#else #else
...@@ -2967,9 +3193,6 @@ int main(int argc, char **argv) { ...@@ -2967,9 +3193,6 @@ int main(int argc, char **argv) {
init_dlsch_threads(); init_dlsch_threads();
#endif #endif
printf("UE threads created\n"); printf("UE threads created\n");
#else
printf("UE functionality not yet supported on USRP");
#endif
} }
else { else {
...@@ -2995,15 +3218,19 @@ int main(int argc, char **argv) { ...@@ -2995,15 +3218,19 @@ int main(int argc, char **argv) {
// Sleep to allow all threads to setup // Sleep to allow all threads to setup
sleep(5); sleep(5);
#ifdef USRP #ifdef USRP
#ifndef USRP_DEBUG
openair0.trx_start_func(&openair0); openair0.trx_start_func(&openair0);
// printf("returning from usrp start streaming: %llu\n",get_usrp_time(&openair0)); // printf("returning from usrp start streaming: %llu\n",get_usrp_time(&openair0));
#endif
#ifdef RTAI #ifdef RTAI
rt_sem_signal(sync_sem); rt_sem_signal(sync_sem);
#else #else
//pthread_mutex_lock(&sync_mutex); pthread_mutex_lock(&sync_mutex);
pthread_cond_signal(&sync_cond); printf("Sending sync ...\n");
//pthread_mutex_unlock(&sync_mutex); pthread_cond_broadcast(&sync_cond);
pthread_mutex_unlock(&sync_mutex);
#endif #endif
#endif #endif
// wait for end of program // wait for end of program
...@@ -3123,7 +3350,11 @@ int main(int argc, char **argv) { ...@@ -3123,7 +3350,11 @@ int main(int argc, char **argv) {
int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]) int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs])
{ {
#ifndef USRP
#ifdef USRP
uint16_t N_TA_offset = 0;
#endif
int i, CC_id; int i, CC_id;
LTE_DL_FRAME_PARMS *frame_parms; 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++) {
...@@ -3135,6 +3366,19 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, ...@@ -3135,6 +3366,19 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg,
return(-1); return(-1);
} }
#ifdef USRP
if (frame_parms->frame_type == TDD) {
if (frame_parms->N_RB_DL == 100)
N_TA_offset = 624;
else if (frame_parms->N_RB_DL == 50)
N_TA_offset = 624/2;
else if (frame_parms->N_RB_DL == 25)
N_TA_offset = 580/4;//624/4;
}
#endif
#ifndef USRP
openair0_cfg[CC_id].tx_num_channels = 0; openair0_cfg[CC_id].tx_num_channels = 0;
openair0_cfg[CC_id].rx_num_channels = 0; openair0_cfg[CC_id].rx_num_channels = 0;
...@@ -3172,12 +3416,28 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, ...@@ -3172,12 +3416,28 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg,
printf("txdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]); printf("txdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]);
} }
}
return(0);
#else #else
printf("USRP not supported for UE yet!"); // replace RX signal buffers with mmaped HW versions
return(-1); for (i=0;i<frame_parms->nb_antennas_rx;i++) {
printf("Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i);
free(phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i]);
rxdata = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i] = rxdata-N_TA_offset; // N_TA offset for TDD
}
for (i=0;i<frame_parms->nb_antennas_tx;i++) {
printf("Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i);
free(phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]);
txdata = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i] = txdata;
memset(txdata, 0, samples_per_frame*sizeof(int32_t));
}
#endif #endif
}
return(0);
} }
/* this function maps the phy_vars_eNB tx and rx buffers to the available rf chains. /* this function maps the phy_vars_eNB tx and rx buffers to the available rf chains.
...@@ -3194,9 +3454,11 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -3194,9 +3454,11 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
#endif #endif
LTE_DL_FRAME_PARMS *frame_parms; 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]) { if (phy_vars_eNB[CC_id]) {
frame_parms = &(phy_vars_eNB[CC_id]->lte_frame_parms); frame_parms = &(phy_vars_eNB[CC_id]->lte_frame_parms);
printf("setup_eNB_buffers: frame_parms = %p\n",frame_parms);
} }
else { else {
printf("phy_vars_eNB[%d] not initialized\n", CC_id); printf("phy_vars_eNB[%d] not initialized\n", CC_id);
...@@ -3215,13 +3477,14 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -3215,13 +3477,14 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
#endif #endif
openair0_cfg[CC_id].tx_num_channels = 0;
openair0_cfg[CC_id].rx_num_channels = 0;
// replace RX signal buffers with mmaped HW versions // replace RX signal buffers with mmaped HW versions
#ifndef USRP #ifndef USRP
openair0_cfg[CC_id].tx_num_channels = 0;
openair0_cfg[CC_id].rx_num_channels = 0;
for (i=0;i<frame_parms->nb_antennas_rx;i++) { for (i=0;i<frame_parms->nb_antennas_rx;i++) {
printf("Mapping eNB CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i); printf("Mapping eNB CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i);
free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i]); free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i]);
...@@ -3233,7 +3496,6 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -3233,7 +3496,6 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
else { else {
openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[rf_map[CC_id].card].rx_gain[rf_map[CC_id].chain+i] = rx_gain[CC_id][i]; openair0_cfg[rf_map[CC_id].card].rx_gain[rf_map[CC_id].chain+i] = rx_gain[CC_id][i];
openair0_cfg[rf_map[CC_id].card].rxg_mode[rf_map[CC_id].chain+i] = rx_gain_mode[CC_id][i];
openair0_cfg[rf_map[CC_id].card].rx_num_channels++; openair0_cfg[rf_map[CC_id].card].rx_num_channels++;
} }
printf("rxdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i]); printf("rxdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i]);
......
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