Commit 8717057c authored by knopp's avatar knopp

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5796 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 36114b84
......@@ -25,7 +25,7 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
*******************************************************************************/
/*! \file lte-softmodem.c
* \brief main program to control HW and scheduling
......@@ -69,7 +69,7 @@ static int hw_subframe;
#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
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
#ifndef USRP
#include "openair0_lib.h"
......@@ -77,7 +77,7 @@ static int hw_subframe;
#include "../../ARCH/COMMON/common_lib.h"
#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 "MAC_INTERFACE/vars.h"
......@@ -131,6 +131,8 @@ unsigned short config_frames[4] = {2,9,11,13};
#define DEBUG_THREADS 1
//#define USRP_DEBUG 1
struct timing_info_t {
//unsigned int frame, hw_slot, last_slot, next_slot;
RTIME time_min, time_max, time_avg, time_last, time_now;
......@@ -182,8 +184,10 @@ struct sched_param sched_param_dlsch;
#ifdef USRP
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
#endif
#endif
RTIME T0;
pthread_attr_t attr_UE_init_synch;
pthread_attr_t attr_UE_thread_tx;
......@@ -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}};
#else
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
double sample_rate=30.72e6;
......@@ -281,10 +285,18 @@ unsigned int samples_per_frame = 307200;
unsigned int samples_per_packets = 2048; // samples got every recv or send
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_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_tx[10] = {7, 22, 37, 52, 67, 82, 97, 112, 127, 142};
int *sf_bounds;
int *sf_bounds_tx;
int max_cnt;
int tx_delay;
......@@ -392,15 +404,15 @@ void exit_fun(const char* s)
static int latency_target_fd = -1;
static int32_t latency_target_value = 0;
/* Latency trick - taken from cyclictest.c
* if the file /dev/cpu_dma_latency exists,
* open it and write a zero into it. This will tell
* the power management system not to transition to
* a high cstate (in fact, the system acts like idle=poll)
* When the fd to /dev/cpu_dma_latency is closed, the behavior
* goes back to the system default.
*
* Documentation/power/pm_qos_interface.txt
*/
* if the file /dev/cpu_dma_latency exists,
* open it and write a zero into it. This will tell
* the power management system not to transition to
* a high cstate (in fact, the system acts like idle=poll)
* When the fd to /dev/cpu_dma_latency is closed, the behavior
* goes back to the system default.
*
* Documentation/power/pm_qos_interface.txt
*/
static void set_latency_target(void)
{
struct stat s;
......@@ -875,8 +887,8 @@ static void * eNB_thread_tx(void *param) {
}
#else
// LOG_I(PHY,
printf("[SCHED][eNB] eNB TX thread %d started on CPU %d\n",
proc->subframe,sched_getcpu());
printf("[SCHED][eNB] eNB TX thread %d started on CPU %d\n",
proc->subframe,sched_getcpu());
#endif
mlockall(MCL_CURRENT | MCL_FUTURE);
......@@ -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_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_ENB, proc->frame_tx);
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_ENB, proc->subframe*2);
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx);
if (oai_exit) break;
......@@ -1018,8 +1029,7 @@ static void * eNB_thread_rx(void *param) {
while (!oai_exit){
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);
if (pthread_mutex_lock(&proc->mutex_rx) != 0) {
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) {
}
}
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;
......@@ -1109,41 +1120,42 @@ void init_eNB_proc(void) {
pthread_attr_setschedparam (&attr_eNB_proc_rx[CC_id][i], &sched_param_eNB_proc_rx[CC_id][i]);
pthread_attr_setschedpolicy (&attr_eNB_proc_rx[CC_id][i], SCHED_FIFO);
PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_tx=-1;
PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_rx=-1;
PHY_vars_eNB_g[0][CC_id]->proc[i].subframe=i;
PHY_vars_eNB_g[0][CC_id]->proc[i].CC_id = CC_id;
pthread_mutex_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_tx,NULL);
pthread_mutex_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_rx,NULL);
pthread_cond_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_tx,NULL);
pthread_cond_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_rx,NULL);
pthread_create(&PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_tx,NULL,eNB_thread_tx,(void*)&PHY_vars_eNB_g[0][CC_id]->proc[i]);
pthread_create(&PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_rx,NULL,eNB_thread_rx,(void*)&PHY_vars_eNB_g[0][CC_id]->proc[i]);
PHY_vars_eNB_g[0][CC_id]->proc[i].frame_tx = 0;
PHY_vars_eNB_g[0][CC_id]->proc[i].frame_rx = 0;
PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_tx=-1;
PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_rx=-1;
PHY_vars_eNB_g[0][CC_id]->proc[i].subframe=i;
PHY_vars_eNB_g[0][CC_id]->proc[i].CC_id = CC_id;
pthread_mutex_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_tx,NULL);
pthread_mutex_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_rx,NULL);
pthread_cond_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_tx,NULL);
pthread_cond_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_rx,NULL);
pthread_create(&PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_tx,NULL,eNB_thread_tx,(void*)&PHY_vars_eNB_g[0][CC_id]->proc[i]);
pthread_create(&PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_rx,NULL,eNB_thread_rx,(void*)&PHY_vars_eNB_g[0][CC_id]->proc[i]);
PHY_vars_eNB_g[0][CC_id]->proc[i].frame_tx = 0;
PHY_vars_eNB_g[0][CC_id]->proc[i].frame_rx = 0;
#ifndef USRP
PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_rx = (i+9)%10;
PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_tx = (i+1)%10;
PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_rx = (i+9)%10;
PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_tx = (i+1)%10;
#else
PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_rx = i;
PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_tx = (i+2)%10;
PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_rx = i;
PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_tx = (i+2)%10;
#endif
}
#ifndef USRP
// TX processes subframe + 1, RX subframe -1
// Note this inialization is because the first process awoken for frame 0 is number 1 and so processes 9 and 0 have to start with frame 1
// TX processes subframe + 1, RX subframe -1
// Note this inialization is because the first process awoken for frame 0 is number 1 and so processes 9 and 0 have to start with frame 1
//PHY_vars_eNB_g[0][CC_id]->proc[0].frame_rx = 1023;
//PHY_vars_eNB_g[0][CC_id]->proc[0].frame_rx = 1023;
PHY_vars_eNB_g[0][CC_id]->proc[9].frame_tx = 1;
PHY_vars_eNB_g[0][CC_id]->proc[0].frame_tx = 1;
#else
// 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
// 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[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
}
}
......@@ -1261,18 +1273,18 @@ static void *eNB_thread(void *arg)
timing_info.n_samples = 0;
#ifdef USRP
printf("waiting for USRP sync \n");
printf("waiting for USRP sync (eNB_thread)\n");
#ifdef RTAI
rt_sem_wait(sync_sem);
#else
//pthread_mutex_lock(&sync_mutex);
pthread_mutex_lock(&sync_mutex);
pthread_cond_wait(&sync_cond, &sync_mutex);
//pthread_mutex_unlock(&sync_mutex);
pthread_mutex_unlock(&sync_mutex);
#endif
// printf("starting eNB thread @ %llu\n",get_usrp_time(&openair0));
#endif
while (!oai_exit) {
while (!oai_exit) {
#ifndef USRP
hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15;
......@@ -1344,19 +1356,22 @@ static void *eNB_thread(void *arg)
openair0_timestamp time0,time1;
unsigned int rxs;
#ifndef USRP_DEBUG
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
/*
// Grab 1/4 of RX buffer and get timestamp
rxs = openair0.trx_read_func(&openair0,
&timestamp,
&rxdata[rx_cnt*samples_per_packets],
(samples_per_packets>>2));
&timestamp,
&rxdata[rx_cnt*samples_per_packets],
(samples_per_packets>>2));
if (rxs != (samples_per_packets>>2))
oai_exit=1;
oai_exit=1;
*/
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,
&timestamp,
&rxdata[rx_cnt*samples_per_packets],
......@@ -1378,14 +1393,37 @@ static void *eNB_thread(void *arg)
// Grab remaining 3/4 of RX buffer
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
rxs = openair0.trx_read_func(&openair0,
&timestamp,
&rxdata[(rx_cnt*samples_per_packets)+(samples_per_packets>>2)],
3*((samples_per_packets>>2)));
&timestamp,
&rxdata[(rx_cnt*samples_per_packets)+(samples_per_packets>>2)],
3*((samples_per_packets>>2)));
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,0);
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++;
tx_cnt++;
......@@ -1401,86 +1439,82 @@ static void *eNB_thread(void *arg)
if (oai_exit) break;
if (frame>99) {
timing_info.time_last = timing_info.time_now;
timing_info.time_now = rt_get_time_ns();
if (timing_info.n_samples>0) {
time_diff = timing_info.time_now - timing_info.time_last;
if (time_diff < timing_info.time_min)
timing_info.time_min = time_diff;
if (time_diff > timing_info.time_max)
timing_info.time_max = time_diff;
timing_info.time_avg += time_diff;
timing_info.time_last = timing_info.time_now;
timing_info.time_now = rt_get_time_ns();
if (timing_info.n_samples>0) {
time_diff = timing_info.time_now - timing_info.time_last;
if (time_diff < timing_info.time_min)
timing_info.time_min = time_diff;
if (time_diff > timing_info.time_max)
timing_info.time_max = time_diff;
timing_info.time_avg += time_diff;
}
timing_info.n_samples++;
/*
if ((timing_info.n_samples%2000)==0) {
LOG_D(HW,"frame %d (%d), slot %d, hw_slot %d: diff=%llu, min=%llu, max=%llu, avg=%llu (n_samples %d)\n",
frame, PHY_vars_eNB_g[0]->frame, slot, hw_slot,time_diff,
timing_info.time_min,timing_info.time_max,timing_info.time_avg/timing_info.n_samples,timing_info.n_samples);
timing_info.n_samples = 0;
timing_info.time_avg = 0;
}
*/
//}
if ((slot&1) == 1) {
#ifndef USRP
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);
timing_info.n_samples++;
/*
if ((timing_info.n_samples%2000)==0) {
LOG_D(HW,"frame %d (%d), slot %d, hw_slot %d: diff=%llu, min=%llu, max=%llu, avg=%llu (n_samples %d)\n",
frame, PHY_vars_eNB_g[0]->frame, slot, hw_slot,time_diff,
timing_info.time_min,timing_info.time_max,timing_info.time_avg/timing_info.n_samples,timing_info.n_samples);
timing_info.n_samples = 0;
timing_info.time_avg = 0;
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) {
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);
}
*/
//}
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 {
// LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt);
PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx++;
pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx);
if (PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx == 0) {
if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_tx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB TX thread %d\n",sf);
}
}
else {
LOG_W(PHY,"[eNB] Frame %d, eNB TX thread %d busy!!\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_tx,sf);
oai_exit=1;
}
}
}
else { // multi-thread > 0
if ((slot&1) == 1) {
sf = ((slot>>1)+1)%10;
// 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++) {
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);
}
else {
// LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt);
PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx++;
pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx);
if (PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx == 0) {
if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_tx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB TX thread %d\n",sf);
}
}
else {
LOG_W(PHY,"[eNB] Frame %d, eNB TX thread %d busy!!\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_tx,sf);
oai_exit=1;
}
}
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);
}
else {
// LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt);
PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx++;
pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx);
if (PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx == 0) {
if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_rx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB RX thread %d\n",sf);
}
}
else {
LOG_W(PHY,"[eNB] Frame %d, eNB RX thread %d busy!!\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_rx,sf);
oai_exit=1;
}
#endif
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);
}
else {
// LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt);
PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx++;
pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx);
if (PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx == 0) {
if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_rx) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB RX thread %d\n",sf);
}
}
else {
LOG_W(PHY,"[eNB] Frame %d, eNB RX thread %d busy!!\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_rx,sf);
oai_exit=1;
}
}
}
}
#ifndef RTAI
//pthread_mutex_lock(&tti_mutex);
#endif
......@@ -1498,11 +1532,11 @@ static void *eNB_thread(void *arg)
hw_subframe++;
slot+=2;
if(hw_subframe==10) {
hw_subframe = 0;
hw_subframe = 0;
frame++;
slot = 1;
}
#endif
#endif
#if defined(ENABLE_ITTI)
......@@ -1535,23 +1569,31 @@ static void *eNB_thread(void *arg)
return 0;
}
#ifdef USRP_DEBUG
int is_synchronized=1;
#else
int is_synchronized=0;
#endif
static void *UE_thread_synch(void *arg) {
int i,hw_slot_offset,CC_id;
PHY_VARS_UE *UE = arg;
printf("UE_thread_sync in with PHY_vars_UE %p\n",arg);
#ifdef USRP
printf("waiting for USRP sync \n");
printf("waiting for USRP sync (UE_thread_synch) \n");
#ifdef RTAI
rt_sem_wait(sync_sem);
#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_mutex_unlock(&sync_mutex);
pthread_mutex_unlock(&sync_mutex);
printf("unlocked sync_mutex (UE_sync_thread)\n");
#endif
// printf("starting eNB thread @ %llu\n",get_usrp_time(&openair0));
printf("starting UE synch thread\n");
#endif
while (!oai_exit) {
......@@ -1569,61 +1611,76 @@ static void *UE_thread_synch(void *arg) {
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) {
/*
lte_adjust_synch(&PHY_vars_UE_g[0]->lte_frame_parms,
PHY_vars_UE_g[0],
0,
1,
16384);
*/
//for better visualization afterwards
/*
for (aa=0; aa<PHY_vars_UE_g[0]->lte_frame_parms.nb_antennas_rx; aa++)
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));
*/
if (initial_sync(PHY_vars_UE_g[0][0],mode)==0) {
/*
lte_adjust_synch(&PHY_vars_UE_g[0]->lte_frame_parms,
PHY_vars_UE_g[0],
0,
1,
16384);
*/
//for better visualization afterwards
/*
for (aa=0; aa<PHY_vars_UE_g[0]->lte_frame_parms.nb_antennas_rx; aa++)
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));
*/
if (mode == rx_calib_ue) {
exit_fun("[HW][UE] UE in RX calibration mode");
}
else {
is_synchronized = 1;
oai_exit=1;
//start the DMA transfers
//LOG_D(HW,"Before openair0_start_rt_acquisition \n");
//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;
LOG_D(HW,"Got synch: hw_slot_offset %d\n",hw_slot_offset);
}
T0 = rt_get_time_ns();
is_synchronized = 1;
PHY_vars_UE_g[0][0]->slot_rx = 0;
//oai_exit=1;
//start the DMA transfers
//LOG_D(HW,"Before openair0_start_rt_acquisition \n");
//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;
LOG_I(HW,"Got synch: hw_slot_offset %d\n",hw_slot_offset);
}
else {
if (openair_daq_vars.freq_offset >= 0) {
openair_daq_vars.freq_offset += 100;
openair_daq_vars.freq_offset *= -1;
}
else {
if (openair_daq_vars.freq_offset >= 0) {
openair_daq_vars.freq_offset += 100;
openair_daq_vars.freq_offset *= -1;
}
else {
openair_daq_vars.freq_offset *= -1;
}
if (abs(openair_daq_vars.freq_offset) > 7500) {
LOG_I(PHY,"[initial_sync] No cell synchronization found, abondoning\n");
mac_xface->macphy_exit("No cell synchronization found, abondoning");
}
else {
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 (i=0; i<openair0_cfg[rf_map[CC_id].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;
for (i=0; i<openair0_cfg[rf_map[CC_id].card].tx_num_channels; i++)
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;
openair_daq_vars.freq_offset *= -1;
}
if (abs(openair_daq_vars.freq_offset) > 7500) {
LOG_I(PHY,"[initial_sync] No cell synchronization found, abondoning\n");
mac_xface->macphy_exit("No cell synchronization found, abondoning");
}
else {
// LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",openair_daq_vars.freq_offset);
for (card=0;card<MAX_CARDS;card++) {
for (i=0; i<openair0_cfg[card].rx_num_channels; i++) {
openair0_cfg[card].rx_freq[i] = downlink_frequency[card][i]+openair_daq_vars.freq_offset;
openair0_cfg[card].tx_freq[i] = downlink_frequency[card][i]+uplink_frequency_offset[card][i]+openair_daq_vars.freq_offset;
#ifndef USRP_DEBUG
openair0_set_frequencies(&openair0,&openair0_cfg[0]);
#endif
}
// openair0_config(&openair0_cfg[0],UE_flag);
// rt_sleep_ns(FRAME_PERIOD);
} // freq_offset
} // initial_sync=0
} // mutex_lock
}
// openair0_dump_config(&openair0_cfg[0],UE_flag);
// rt_sleep_ns(FRAME_PERIOD);
} // freq_offset
} // initial_sync=0
if (pthread_mutex_lock(&PHY_vars_UE_g[0][0]->mutex_synch) != 0) {