Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
alex037yang
OpenXG-RAN
Commits
1440e3c5
Commit
1440e3c5
authored
Apr 16, 2018
by
Guy De Souza
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
NR RU procedures
parent
4aba771c
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
336 additions
and
7 deletions
+336
-7
cmake_targets/CMakeLists.txt
cmake_targets/CMakeLists.txt
+1
-0
openair1/PHY/defs.h
openair1/PHY/defs.h
+2
-2
openair1/SCHED_NR/nr_ru_procedures.c
openair1/SCHED_NR/nr_ru_procedures.c
+328
-0
targets/RT/USER/nr-ru.c
targets/RT/USER/nr-ru.c
+5
-5
No files found.
cmake_targets/CMakeLists.txt
View file @
1440e3c5
...
...
@@ -989,6 +989,7 @@ add_library(SCHED_LIB ${SCHED_SRC})
set
(
SCHED_NR_SRC
${
OPENAIR1_DIR
}
/SCHED_NR/phy_procedures_nr_common.c
${
OPENAIR1_DIR
}
/SCHED_NR/phy_procedures_nr_gNB.c
${
OPENAIR1_DIR
}
/SCHED_NR/nr_ru_procedures.c
)
add_library
(
SCHED_NR_LIB
${
SCHED_NR_SRC
}
)
...
...
openair1/PHY/defs.h
View file @
1440e3c5
...
...
@@ -798,10 +798,10 @@ typedef struct RU_t_s{
void
(
*
feptx_prec
)(
struct
RU_t_s
*
ru
);
/// function pointer to wakeup routine in lte-enb/nr-gnb.
int
(
*
wakeup_rxtx
)(
struct
PHY_VARS_eNB_s
*
eNB
,
struct
RU_t_s
*
ru
);
int
(
*
nr_wakeup_rxtx
)(
struct
PHY_VARS_gNB_s
*
e
NB
,
struct
RU_t_s
*
ru
);
int
(
*
nr_wakeup_rxtx
)(
struct
PHY_VARS_gNB_s
*
g
NB
,
struct
RU_t_s
*
ru
);
/// function pointer to wakeup routine in lte-enb/nr-gnb.
void
(
*
wakeup_prach_eNB
)(
struct
PHY_VARS_eNB_s
*
eNB
,
struct
RU_t_s
*
ru
,
int
frame
,
int
subframe
);
void
(
*
wakeup_prach_gNB
)(
struct
PHY_VARS_gNB_s
*
e
NB
,
struct
RU_t_s
*
ru
,
int
frame
,
int
subframe
);
void
(
*
wakeup_prach_gNB
)(
struct
PHY_VARS_gNB_s
*
g
NB
,
struct
RU_t_s
*
ru
,
int
frame
,
int
subframe
);
#ifdef Rel14
/// function pointer to wakeup routine in lte-enb.
void
(
*
wakeup_prach_eNB_br
)(
struct
PHY_VARS_eNB_s
*
eNB
,
struct
RU_t_s
*
ru
,
int
frame
,
int
subframe
);
...
...
openair1/SCHED_NR/nr_ru_procedures.c
0 → 100644
View file @
1440e3c5
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file ru_procedures.c
* \brief Implementation of RU procedures
* \author R. Knopp, F. Kaltenberger, N. Nikaein, X. Foukas
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr, x.foukas@sms.ed.ac.uk
* \note
* \warning
*/
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "SCHED/extern.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"
#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/defs.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "T.h"
#include "assertions.h"
#include "msc.h"
#include <time.h>
#include "targets/RT/USER/rt_wrapper.h"
// RU OFDM Modulator gNodeB
extern
openair0_config_t
openair0_cfg
[
MAX_CARDS
];
extern
int
oai_exit
;
void
nr_feptx0
(
RU_t
*
ru
,
int
slot
)
{
NR_DL_FRAME_PARMS
*
fp
=
&
ru
->
nr_frame_parms
;
nfapi_config_request_t
*
cfg
=
&
ru
->
gNB_list
[
0
]
->
gNB_config
;
unsigned
int
aa
,
slot_offset
;
int
i
,
tx_offset
;
int
slot_sizeF
=
(
fp
->
ofdm_symbol_size
)
*
((
cfg
->
subframe_config
.
dl_cyclic_prefix_type
.
value
==
1
)
?
12
:
14
);
int
subframe
=
ru
->
proc
.
subframe_tx
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM
+
slot
,
1
);
slot_offset
=
subframe
*
fp
->
samples_per_subframe
+
(
slot
*
(
fp
->
samples_per_subframe
/
fp
->
slots_per_subframe
));
LOG_I
(
PHY
,
"SFN/SF:RU:TX:%d/%d Generating slot %d
\n
"
,
ru
->
proc
.
frame_tx
,
ru
->
proc
.
subframe_tx
,
slot
);
for
(
aa
=
0
;
aa
<
ru
->
nb_tx
;
aa
++
)
{
if
(
cfg
->
subframe_config
.
dl_cyclic_prefix_type
.
value
==
1
)
PHY_ofdm_mod
(
&
ru
->
common
.
txdataF_BF
[
aa
][
slot
*
slot_sizeF
],
(
int
*
)
&
ru
->
common
.
txdata
[
aa
][
slot_offset
],
fp
->
ofdm_symbol_size
,
12
,
fp
->
nb_prefix_samples
,
CYCLIC_PREFIX
);
else
normal_prefix_mod
(
&
ru
->
common
.
txdataF_BF
[
aa
][
slot
*
slot_sizeF
],
(
int
*
)
&
ru
->
common
.
txdata
[
aa
][
slot_offset
],
14
,
fp
);
/*
len = fp->samples_per_subframe / fp->slots_per_subframe;
if ((slot_offset+len)>(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe)) {
tx_offset = (int)slot_offset;
txdata = (int16_t*)&ru->common.txdata[aa][tx_offset];
len2 = -tx_offset+LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
for (i=0; i<(len2<<1); i++) {
txdata[i] = ((int16_t*)dummy_tx_b)[i];
}
txdata = (int16_t*)&ru->common.txdata[aa][0];
for (j=0; i<(len<<1); i++,j++) {
txdata[j++] = ((int16_t*)dummy_tx_b)[i];
}
}
else {
tx_offset = (int)slot_offset;
txdata = (int16_t*)&ru->common.txdata[aa][tx_offset];
memcpy((void*)txdata,(void*)dummy_tx_b,len<<2);
}
*/
// TDD: turn on tx switch N_TA_offset before by setting buffer in these samples to 0
/*if ((slot == 0) &&
(fp->frame_type == TDD) &&
((fp->tdd_config==0) ||
(fp->tdd_config==1) ||
(fp->tdd_config==2) ||
(fp->tdd_config==6)) &&
((subframe==0) || (subframe==5))) {
for (i=0; i<ru->N_TA_offset; i++) {
tx_offset = (int)slot_offset+i-ru->N_TA_offset/2;
if (tx_offset<0)
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
ru->common.txdata[aa][tx_offset] = 0x00000000;
}
}*/
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM
+
slot
,
0
);
}
void
nr_feptx_ofdm_2thread
(
RU_t
*
ru
)
{
NR_DL_FRAME_PARMS
*
fp
=&
ru
->
nr_frame_parms
;
RU_proc_t
*
proc
=
&
ru
->
proc
;
struct
timespec
wait
;
int
subframe
=
ru
->
proc
.
subframe_tx
;
wait
.
tv_sec
=
0
;
wait
.
tv_nsec
=
5000000L
;
start_meas
(
&
ru
->
ofdm_mod_stats
);
if
(
nr_subframe_select
(
fp
,
subframe
)
==
SF_UL
)
return
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM
,
1
);
if
(
nr_subframe_select
(
fp
,
subframe
)
==
SF_DL
)
{
// If this is not an S-subframe
if
(
pthread_mutex_timedlock
(
&
proc
->
mutex_feptx
,
&
wait
)
!=
0
)
{
printf
(
"[RU] ERROR pthread_mutex_lock for feptx thread (IC %d)
\n
"
,
proc
->
instance_cnt_feptx
);
exit_fun
(
"error locking mutex_feptx"
);
return
;
}
if
(
proc
->
instance_cnt_feptx
==
0
)
{
printf
(
"[RU] FEPtx thread busy
\n
"
);
exit_fun
(
"FEPtx thread busy"
);
pthread_mutex_unlock
(
&
proc
->
mutex_feptx
);
return
;
}
++
proc
->
instance_cnt_feptx
;
if
(
pthread_cond_signal
(
&
proc
->
cond_feptx
)
!=
0
)
{
printf
(
"[RU] ERROR pthread_cond_signal for feptx thread
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
;
}
pthread_mutex_unlock
(
&
proc
->
mutex_feptx
);
}
// call first slot in this thread
nr_feptx0
(
ru
,
0
);
wait_on_busy_condition
(
&
proc
->
mutex_feptx
,
&
proc
->
cond_feptx
,
&
proc
->
instance_cnt_feptx
,
"feptx thread"
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM
,
0
);
stop_meas
(
&
ru
->
ofdm_mod_stats
);
}
void
nr_feptx_ofdm
(
RU_t
*
ru
)
{
NR_DL_FRAME_PARMS
*
fp
=&
ru
->
nr_frame_parms
;
nfapi_config_request_t
*
cfg
=
&
ru
->
gNB_list
[
0
]
->
gNB_config
;
unsigned
int
aa
,
slot_offset
,
slot_offset_F
;
int
dummy_tx_b
[
7680
*
4
]
__attribute__
((
aligned
(
32
)));
int
i
,
j
,
tx_offset
;
int
slot_sizeF
=
(
fp
->
ofdm_symbol_size
)
*
((
cfg
->
subframe_config
.
dl_cyclic_prefix_type
.
value
==
1
)
?
12
:
14
);
int
len
,
len2
;
int16_t
*
txdata
;
int
subframe
=
ru
->
proc
.
subframe_tx
;
// int CC_id = ru->proc.CC_id;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM
,
1
);
slot_offset_F
=
0
;
slot_offset
=
subframe
*
fp
->
samples_per_subframe
;
if
((
nr_subframe_select
(
fp
,
subframe
)
==
SF_DL
)
||
((
nr_subframe_select
(
fp
,
subframe
)
==
SF_S
)))
{
// LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
start_meas
(
&
ru
->
ofdm_mod_stats
);
for
(
aa
=
0
;
aa
<
ru
->
nb_tx
;
aa
++
)
{
if
(
cfg
->
subframe_config
.
dl_cyclic_prefix_type
.
value
==
1
)
{
PHY_ofdm_mod
(
&
ru
->
common
.
txdataF_BF
[
aa
][
0
],
dummy_tx_b
,
fp
->
ofdm_symbol_size
,
12
,
fp
->
nb_prefix_samples
,
CYCLIC_PREFIX
);
PHY_ofdm_mod
(
&
ru
->
common
.
txdataF_BF
[
aa
][
slot_sizeF
],
dummy_tx_b
+
(
fp
->
samples_per_subframe
/
fp
->
slots_per_subframe
),
fp
->
ofdm_symbol_size
,
12
,
fp
->
nb_prefix_samples
,
CYCLIC_PREFIX
);
}
else
{
normal_prefix_mod
(
&
ru
->
common
.
txdataF_BF
[
aa
][
slot_offset_F
],
dummy_tx_b
,
14
,
fp
);
// if S-subframe generate first slot only
if
(
subframe_select
(
fp
,
subframe
)
==
SF_DL
)
normal_prefix_mod
(
&
ru
->
common
.
txdataF_BF
[
aa
][
slot_offset_F
+
slot_sizeF
],
dummy_tx_b
+
(
fp
->
samples_per_subframe
/
fp
->
slots_per_subframe
),
14
,
fp
);
}
// if S-subframe generate first slot only
if
(
subframe_select
(
fp
,
subframe
)
==
SF_S
)
len
=
fp
->
samples_per_subframe
/
fp
->
slots_per_subframe
;
else
len
=
fp
->
samples_per_subframe
;
/*
for (i=0;i<len;i+=4) {
dummy_tx_b[i] = 0x100;
dummy_tx_b[i+1] = 0x01000000;
dummy_tx_b[i+2] = 0xff00;
dummy_tx_b[i+3] = 0xff000000;
}*/
if
(
slot_offset
<
0
)
{
txdata
=
(
int16_t
*
)
&
ru
->
common
.
txdata
[
aa
][(
LTE_NUMBER_OF_SUBFRAMES_PER_FRAME
*
fp
->
samples_per_subframe
)
+
tx_offset
];
len2
=
-
(
slot_offset
);
len2
=
(
len2
>
len
)
?
len
:
len2
;
for
(
i
=
0
;
i
<
(
len2
<<
1
);
i
++
)
{
txdata
[
i
]
=
((
int16_t
*
)
dummy_tx_b
)[
i
];
}
if
(
len2
<
len
)
{
txdata
=
(
int16_t
*
)
&
ru
->
common
.
txdata
[
aa
][
0
];
for
(
j
=
0
;
i
<
(
len
<<
1
);
i
++
,
j
++
)
{
txdata
[
j
++
]
=
((
int16_t
*
)
dummy_tx_b
)[
i
];
}
}
}
else
if
((
slot_offset
+
len
)
>
(
fp
->
samples_per_frame
))
{
tx_offset
=
(
int
)
slot_offset
;
txdata
=
(
int16_t
*
)
&
ru
->
common
.
txdata
[
aa
][
tx_offset
];
len2
=
-
tx_offset
+
fp
->
samples_per_frame
;
for
(
i
=
0
;
i
<
(
len2
<<
1
);
i
++
)
{
txdata
[
i
]
=
((
int16_t
*
)
dummy_tx_b
)[
i
];
}
txdata
=
(
int16_t
*
)
&
ru
->
common
.
txdata
[
aa
][
0
];
for
(
j
=
0
;
i
<
(
len
<<
1
);
i
++
,
j
++
)
{
txdata
[
j
++
]
=
((
int16_t
*
)
dummy_tx_b
)[
i
];
}
}
else
{
//LOG_D(PHY,"feptx_ofdm: Writing to position %d\n",slot_offset);
tx_offset
=
(
int
)
slot_offset
;
txdata
=
(
int16_t
*
)
&
ru
->
common
.
txdata
[
aa
][
tx_offset
];
for
(
i
=
0
;
i
<
(
len
<<
1
);
i
++
)
{
txdata
[
i
]
=
((
int16_t
*
)
dummy_tx_b
)[
i
];
}
}
// if S-subframe switch to RX in second subframe
/*
if (subframe_select(fp,subframe) == SF_S) {
for (i=0; i<len; i++) {
ru->common_vars.txdata[0][aa][tx_offset++] = 0x00010001;
}
}
*/
/*if ((fp->frame_type == TDD) &&
((fp->tdd_config==0) ||
(fp->tdd_config==1) ||
(fp->tdd_config==2) ||
(fp->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,ru->N_TA_offset,slot_offset);
for (i=0; i<ru->N_TA_offset; i++) {
tx_offset = (int)slot_offset+i-ru->N_TA_offset/2;
if (tx_offset<0)
tx_offset += fp->samples_per_frame;
if (tx_offset>=(fp->samples_per_frame))
tx_offset -= fp->samples_per_frame;
ru->common.txdata[aa][tx_offset] = 0x00000000;
}
}*/
stop_meas
(
&
ru
->
ofdm_mod_stats
);
LOG_D
(
PHY
,
"feptx_ofdm (TXPATH): frame %d, subframe %d: txp (time %p) %d dB, txp (freq) %d dB
\n
"
,
ru
->
proc
.
frame_tx
,
subframe
,
txdata
,
dB_fixed
(
signal_energy
((
int32_t
*
)
txdata
,
fp
->
samples_per_subframe
)),
dB_fixed
(
signal_energy_nodc
(
ru
->
common
.
txdataF_BF
[
aa
],
2
*
slot_sizeF
)));
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM
,
0
);
}
targets/RT/USER/nr-ru.c
View file @
1440e3c5
...
...
@@ -1587,8 +1587,8 @@ int stop_rf(RU_t *ru)
extern
void
fep_full
(
RU_t
*
ru
);
extern
void
ru_fep_full_2thread
(
RU_t
*
ru
);
extern
void
feptx_ofdm
(
RU_t
*
ru
);
extern
void
feptx_ofdm_2thread
(
RU_t
*
ru
);
extern
void
nr_
feptx_ofdm
(
RU_t
*
ru
);
extern
void
nr_
feptx_ofdm_2thread
(
RU_t
*
ru
);
extern
void
feptx_prec
(
RU_t
*
ru
);
extern
void
init_fep_thread
(
RU_t
*
ru
,
pthread_attr_t
*
attr
);
extern
void
init_feptx_thread
(
RU_t
*
ru
,
pthread_attr_t
*
attr
);
...
...
@@ -1976,7 +1976,7 @@ void set_function_spec_param(RU_t *ru)
ru
->
fh_south_out
=
tx_rf
;
// send output to RF
ru
->
fh_north_asynch_in
=
fh_if4p5_north_asynch_in
;
// TX packets come asynchronously
ru
->
feprx
=
(
get_nprocs
()
<=
2
)
?
fep_full
:
ru_fep_full_2thread
;
// RX DFTs
ru
->
feptx_ofdm
=
(
get_nprocs
()
<=
2
)
?
feptx_ofdm
:
feptx_ofdm_2thread
;
// this is fep with idft only (no precoding in RRU)
ru
->
feptx_ofdm
=
(
get_nprocs
()
<=
2
)
?
nr_feptx_ofdm
:
nr_
feptx_ofdm_2thread
;
// this is fep with idft only (no precoding in RRU)
ru
->
feptx_prec
=
NULL
;
ru
->
start_if
=
start_if
;
// need to start the if interface for if4p5
ru
->
ifdevice
.
host_type
=
RRU_HOST
;
...
...
@@ -1998,7 +1998,7 @@ void set_function_spec_param(RU_t *ru)
else
if
(
ru
->
function
==
gNodeB_3GPP
)
{
ru
->
do_prach
=
0
;
// no prach processing in RU
ru
->
feprx
=
(
get_nprocs
()
<=
2
)
?
fep_full
:
ru_fep_full_2thread
;
// RX DFTs
ru
->
feptx_ofdm
=
(
get_nprocs
()
<=
2
)
?
feptx_ofdm
:
feptx_ofdm_2thread
;
// this is fep with idft and precoding
ru
->
feptx_ofdm
=
(
get_nprocs
()
<=
2
)
?
nr_feptx_ofdm
:
nr_
feptx_ofdm_2thread
;
// this is fep with idft and precoding
ru
->
feptx_prec
=
feptx_prec
;
// this is fep with idft and precoding
ru
->
fh_north_in
=
NULL
;
// no incoming fronthaul from north
ru
->
fh_north_out
=
NULL
;
// no outgoing fronthaul to north
...
...
@@ -2028,7 +2028,7 @@ void set_function_spec_param(RU_t *ru)
ru
->
do_prach
=
0
;
ru
->
feprx
=
(
get_nprocs
()
<=
2
)
?
fep_full
:
fep_full
;
// this is frequency-shift + DFTs
ru
->
feptx_prec
=
feptx_prec
;
// need to do transmit Precoding + IDFTs
ru
->
feptx_ofdm
=
(
get_nprocs
()
<=
2
)
?
feptx_ofdm
:
feptx_ofdm_2thread
;
// need to do transmit Precoding + IDFTs
ru
->
feptx_ofdm
=
(
get_nprocs
()
<=
2
)
?
nr_feptx_ofdm
:
nr_
feptx_ofdm_2thread
;
// need to do transmit Precoding + IDFTs
if
(
ru
->
if_timing
==
synch_to_other
)
{
ru
->
fh_south_in
=
fh_slave_south_in
;
// synchronize to master
ru
->
fh_south_out
=
fh_if5_mobipass_south_out
;
// use send_IF5 for mobipass
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment