Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
oai
openairinterface5G
Commits
8717057c
Commit
8717057c
authored
Sep 18, 2014
by
knopp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
git-svn-id:
http://svn.eurecom.fr/openair4G/trunk@5796
818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent
36114b84
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
545 additions
and
283 deletions
+545
-283
targets/RT/USER/lte-softmodem.c
targets/RT/USER/lte-softmodem.c
+545
-283
No files found.
targets/RT/USER/lte-softmodem.c
View file @
8717057c
...
...
@@ -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
]
=
{{
5
0
,
0
,
0
,
0
}};
double
rx_gain
[
MAX_NUM_CCs
][
4
]
=
{{
4
0
,
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,
×tamp,
&rxdata[rx_cnt*samples_per_packets],
(samples_per_packets>>2));
×tamp,
&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,
×tamp,
&rxdata[(rx_cnt*samples_per_packets)+(samples_per_packets>>2)],
3*((samples_per_packets>>2)));
×tamp,
&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
)
{