Compare commits

...

13 Commits

Author SHA1 Message Date
magounak
b6d217ee40 added gsl function to compute calibration coefficients in real-time, compute beam weights and do precoding 2020-06-10 14:58:09 +02:00
magounak
efbee833d8 fixed some warnings 2020-03-13 11:30:19 +01:00
magounak
89772f565e fix build issues 2020-03-12 19:31:50 +01:00
magounak
fe28f8e482 Merge remote-tracking branch 'origin/develop' into inter-RRU-nr 2020-03-12 13:47:37 +01:00
magounak
4a87791a74 changes to increase the number of antenna ports 2020-03-10 13:45:21 +01:00
magounak
74b1850cde improve hack multi-rru-clean.c 2019-10-08 12:27:01 +02:00
magounak
06bae02383 merged with "moving mask check to wakeup_rxtx" 2019-08-30 15:58:58 +02:00
magounak
7d0c9393ae added NB_PUSCH_ANT_PORTS and modified extract.c 2019-08-30 15:46:27 +02:00
Wang Tsu-Han
6c6e54f851 moving mask check to wakeup_rxtx 2019-07-31 15:25:29 +02:00
magounak
bbaec98c6a received DMRS at RCC side from 2 RRUs 2019-07-09 17:43:28 +02:00
magounak
2cb279d633 minor change at RU_mask_tx 2019-07-08 13:14:24 +02:00
Theoni Magounaki
06c4da479b changes to add calibration symbol 10 2019-06-27 16:46:56 +02:00
magounak
401549af59 modify develop branch to enable multi-RRUs functionalities 2019-06-26 10:31:18 +02:00
24 changed files with 964 additions and 215 deletions

View File

@@ -36,6 +36,7 @@ set (OPENAIR_TARGETS ${OPENAIR_DIR}/targets)
set (OPENAIR3_DIR ${OPENAIR_DIR}/openair3)
set (OPENAIR_CMAKE ${OPENAIR_DIR}/cmake_targets)
set (OPENAIR_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY})
set (GSL_DIR /home/eurecom/gsl)
project (OpenAirInterface)
@@ -127,7 +128,7 @@ endfunction()
#set(CMAKE_BUILD_TYPE "Debug")
if (CMAKE_BUILD_TYPE STREQUAL "")
set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
endif()
message("CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}")
add_list_string_option(CMAKE_BUILD_TYPE "RelWithDebInfo" "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." Debug Release RelWithDebInfo MinSizeRel)
@@ -2298,6 +2299,8 @@ if(EXISTS "/usr/include/atlas/cblas.h" OR EXISTS "/usr/include/cblas.h")
LINK_DIRECTORIES("/usr/lib64")
LINK_DIRECTORIES("/usr/lib64/atlas") #Added because atlas libraries in CentOS 7 are here!
include_directories("${GSL_DIR}/include/gsl")
if(EXISTS "/usr/lib64/libblas.so" OR EXISTS "/usr/lib/libblas.so") #Case for CentOS7
list(APPEND ATLAS_LIBRARIES blas)
@@ -2433,6 +2436,7 @@ target_link_libraries (measurement_display minimal_lib)
# lte-softmodem is both eNB and UE implementation
###################################################
LINK_DIRECTORIES("${GSL_DIR}/lib")
add_executable(lte-softmodem
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/RT/USER/lte-enb.c
@@ -2473,6 +2477,7 @@ target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES})
target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES})
target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES})
target_link_libraries (lte-softmodem ${T_LIB})
target_link_libraries(lte-softmodem gsl gslcblas)
add_executable(cu_test
${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/cu_test.c

View File

@@ -89,6 +89,8 @@ typedef struct {
int *nb_nr_L1_CC;
/// Number of RU instances in this node
int nb_RU;
/// Flag to start collecting channel estimates sent from the RRUs
int collect;
/// FlexRAN context variables
flexran_agent_info_t **flexran;
/// eNB context variables

View File

@@ -45,6 +45,22 @@ ID = ENB_PHY_INPUT_SIGNAL
DESC = eNodeB received signal in the time domain for a duration of 1ms
GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
FORMAT = int,eNB_ID : int,frame : int,subframe : int,antenna : buffer,rxdata
ID = RAU_INPUT_SIGNAL
DESC = RAU received data from the RRUs
GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
FORMAT = int,tag : int,frame : int,subframe : buffer,rxdataF
ID = RAU_INPUT_DMRS
DESC = RAU received DMRS from the RRUs
GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
FORMAT = int,tag : int,frame : int,subframe : buffer,rxdataF_ext
ID = CALIBRATION_CHANNEL_ESTIMATES
DESC = RAU received DMRS estimates from the RRUs
GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
FORMAT = int,tag : int,frame : int,subframe : int,symbol : buffer,calib_ch
ID = CALIBRATION_CHANNEL_ESTIMATES_TIME
DESC = RAU received DMRS estimates in the time domain from the RRUs
GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
FORMAT = int,tag : int,frame : int,subframe : buffer,calib_ch_time
ID = ENB_PHY_OUTPUT_SIGNAL
DESC = eNodeB sent signal in the time domain for a duration of 1ms
GROUP = ALL:PHY:HEAVY:ENB

View File

@@ -18,6 +18,8 @@ void usage(void)
" (you can use several -f options)\n"
" -after <raw time> <nsec> 'event' time has to be greater than this\n"
" -count <n> dump 'n' matching events (less if EOF reached)\n"
" -modulo <n> dump frame which modulo <rru-count> is <n>\n"
" -rru-count <n> set rru count\n"
);
exit(1);
}
@@ -51,10 +53,13 @@ int main(int n, char **v)
int filter_arg[n];
int filter_value[n];
int filter_count = 0;
int filter_frame;
int buffer_arg;
int found;
int count = 1;
int check_time = 0;
int modulo = 0;
int rru_count = 1;
time_t sec;
long nsec;
@@ -77,6 +82,10 @@ int main(int n, char **v)
}
if (!strcmp(v[i], "-count"))
{ if (i > n-2) usage(); count = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-modulo"))
{ if (i > n-2) usage(); modulo = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-rru-count"))
{ if (i > n-2) usage(); rru_count = atoi(v[++i]); continue; }
if (file == NULL) { file = v[i]; continue; }
if (event_name == NULL) { event_name = v[i]; continue; }
if (buffer_name == NULL) { buffer_name = v[i]; continue; }
@@ -108,6 +117,8 @@ int main(int n, char **v)
for (i = 0; i < filter_count; i++)
filter_arg[i] = get_filter_arg(&f, filter[i], "int");
filter_frame = get_filter_arg(&f, "frame", "int");
fd = open(file, O_RDONLY);
if (fd == -1) { perror(file); exit(1); }
@@ -125,6 +136,8 @@ int main(int n, char **v)
break;
if (i != filter_count)
continue;
if (e.e[filter_frame].i % rru_count != modulo)
continue;
if (check_time &&
!(e.sending_time.tv_sec > sec ||
(e.sending_time.tv_sec == sec && e.sending_time.tv_nsec >= nsec)))

View File

@@ -400,8 +400,14 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
common_vars->rxdata = (int32_t **)NULL;
common_vars->txdataF = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t *));
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t *));
common_vars->calib_coeffs = (int32_t **)malloc16(2*sizeof(int32_t *));
LOG_I(PHY,"[INIT] NB_ANTENNA_PORTS_ENB:%d fp->nb_antenna_ports_eNB:%d\n", NB_ANTENNA_PORTS_ENB, fp->nb_antenna_ports_eNB);
for (i=0; i<2; i++) {
common_vars->calib_coeffs[i] = (int32_t *)malloc16_clear(sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); // 2 RRUs
LOG_I(PHY,"[INIT] common_vars->calib_coeffs[%d] = %p (%lu bytes)\n", i,common_vars->calib_coeffs[i], fp->N_RB_UL*12*fp->symbols_per_tti*sizeof(int32_t));
}
for (i=0; i<NB_ANTENNA_PORTS_ENB; i++) {
if (i<fp->nb_antenna_ports_eNB || i==5) {
common_vars->txdataF[i] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) );
@@ -452,42 +458,54 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
prach_vars->rxsigF[ce_level] = (int16_t **) malloc16_clear (64 * sizeof (int16_t *));
}
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0])
AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]),
"nb_antennas_rx too large");
for (i=0; i<fp->nb_antennas_rx; i++) {
prach_vars->rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]);
}*/
// assume maximum of 64 RX antennas for PRACH receiver
for (int ce_level = 0; ce_level < 4; ce_level++) {
prach_vars_br->prach_ifft[ce_level] = (int32_t **) malloc16_clear (64 * sizeof (int32_t *));
for (i = 0; i < 64; i++)
prach_vars_br->prach_ifft[ce_level][i] = (int32_t *) malloc16_clear (1024 * 2 * sizeof (int32_t));
prach_vars->rxsigF[ce_level] = (int16_t **) malloc16_clear (64 * sizeof (int16_t *));
}
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
//FIXME
pusch_vars[UE_id] = (LTE_eNB_PUSCH *) malloc16_clear (NUMBER_OF_UE_MAX * sizeof (LTE_eNB_PUSCH));
pusch_vars[UE_id]->rxdataF_ext = (int32_t **) malloc16 (2 * sizeof (int32_t *));
pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **) malloc16 (2 * sizeof (int32_t *));
pusch_vars[UE_id]->drs_ch_estimates = (int32_t **) malloc16 (2 * sizeof (int32_t *));
pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t **) malloc16 (2 * sizeof (int32_t *));
pusch_vars[UE_id]->rxdataF_comp = (int32_t **) malloc16 (2 * sizeof (int32_t *));
pusch_vars[UE_id]->ul_ch_mag = (int32_t **) malloc16 (2 * sizeof (int32_t *));
pusch_vars[UE_id]->ul_ch_magb = (int32_t **) malloc16 (2 * sizeof (int32_t *));
AssertFatal (fp->ofdm_symbol_size > 127, "fp->ofdm_symbol_size %d<128\n", fp->ofdm_symbol_size);
AssertFatal (fp->symbols_per_tti > 11, "fp->symbols_per_tti %d < 12\n", fp->symbols_per_tti);
AssertFatal (fp->N_RB_UL > 5, "fp->N_RB_UL %d < 6\n", fp->N_RB_UL);
for (i = 0; i < 2; i++) {
// RK 2 times because of output format of FFT!
// FIXME We should get rid of this
pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0])
AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]),
"nb_antennas_rx too large");
for (i=0; i<fp->nb_antennas_rx; i++) {
prach_vars->rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]);
}*/
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
//FIXME
pusch_vars[UE_id] = (LTE_eNB_PUSCH *) malloc16_clear (NUMBER_OF_UE_MAX * sizeof (LTE_eNB_PUSCH));
pusch_vars[UE_id]->rxdataF_ext = (int32_t **) malloc16 (NB_PUSCH_ANT_PORTS * sizeof (int32_t *));
pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **) malloc16 (NB_PUSCH_ANT_PORTS * sizeof (int32_t *));
pusch_vars[UE_id]->drs_ch_estimates = (int32_t **) malloc16 (NB_PUSCH_ANT_PORTS * sizeof (int32_t *));
pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t **) malloc16 (NB_PUSCH_ANT_PORTS * sizeof (int32_t *));
pusch_vars[UE_id]->rxdataF_comp = (int32_t **) malloc16 (NB_PUSCH_ANT_PORTS * sizeof (int32_t *));
pusch_vars[UE_id]->ul_ch_mag = (int32_t **) malloc16 (NB_PUSCH_ANT_PORTS * sizeof (int32_t *));
pusch_vars[UE_id]->ul_ch_magb = (int32_t **) malloc16 (NB_PUSCH_ANT_PORTS * sizeof (int32_t *));
AssertFatal (fp->ofdm_symbol_size > 127, "fp->ofdm_symbol_size %d<128\n", fp->ofdm_symbol_size);
AssertFatal (fp->symbols_per_tti > 11, "fp->symbols_per_tti %d < 12\n", fp->symbols_per_tti);
AssertFatal (fp->N_RB_UL > 5, "fp->N_RB_UL %d < 6\n", fp->N_RB_UL);
for (i = 0; i < NB_PUSCH_ANT_PORTS; i++) {
// RK 2 times because of output format of FFT!
// FIXME We should get rid of this
pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear( NB_PUSCH_ANT_PORTS*sizeof(int32_t)*fp->ofdm_symbol_size );
pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
}
pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
} //UE_id
pusch_vars[UE_id]->llr = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
//LOG_I(PHY,"llr[0] %p\n",pusch_vars[UE_id]->llr);
} //UE_id
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++)
eNB->UE_stats_ptr[UE_id] = &eNB->UE_stats[UE_id];
@@ -516,6 +534,12 @@ void phy_free_lte_eNB(PHY_VARS_eNB *eNB) {
free_and_zero(common_vars->txdataF);
free_and_zero(common_vars->rxdataF);
for (i=0; i<2; i++) {
free_and_zero(common_vars->calib_coeffs[i]);
}
free_and_zero(common_vars->calib_coeffs);
// Channel estimates for SRS
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
for (i=0; i<64; i++) {
@@ -548,7 +572,7 @@ void phy_free_lte_eNB(PHY_VARS_eNB *eNB) {
free_and_zero(prach_vars->rxsigF[0]);
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
for (i = 0; i < 2; i++) {
for (i = 0; i < NB_PUSCH_ANT_PORTS; i++) {
free_and_zero(pusch_vars[UE_id]->rxdataF_ext[i]);
free_and_zero(pusch_vars[UE_id]->rxdataF_ext2[i]);
free_and_zero(pusch_vars[UE_id]->drs_ch_estimates[i]);

View File

@@ -41,9 +41,7 @@ int phy_init_RU(RU_t *ru) {
init_dfts();
LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx);
if (ru->is_slave == 1) {
generate_ul_ref_sigs_rx();
}
generate_ul_ref_sigs_rx();
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals
// Time-domain signals
@@ -57,13 +55,10 @@ int phy_init_RU(RU_t *ru) {
fp->samples_per_tti*10*sizeof(int32_t));
}
if (ru->is_slave == 1) {
calibration->drs_ch_estimates_time = (int32_t **)malloc16_clear(ru->nb_rx*sizeof(int32_t *));
for (i=0; i<ru->nb_rx; i++) {
calibration->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear(2*sizeof(int32_t)*fp->ofdm_symbol_size);
}
}
calibration->drs_ch_estimates_time = (int32_t**)malloc16_clear(ru->nb_rx*sizeof(int32_t*));
for (i=0; i<ru->nb_rx; i++) {
calibration->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear(2*sizeof(int32_t)*fp->ofdm_symbol_size);
}
for (i=0; i<ru->nb_rx; i++) {
ru->common.rxdata[i] = (int32_t *)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
@@ -104,19 +99,29 @@ int phy_init_RU(RU_t *ru) {
ru->common.rxdataF[i] = (int32_t *)malloc16_clear(sizeof(int32_t)*(2*fp->ofdm_symbol_size*fp->symbols_per_tti) );
LOG_I(PHY,"rxdataF[%d] %p for RU %d\n",i,ru->common.rxdataF[i],ru->idx);
}
if (ru->is_slave == 1) {
// allocate FFT output buffers after extraction (RX)
calibration->rxdataF_ext = (int32_t **)malloc16(2*sizeof(int32_t *));
calibration->drs_ch_estimates = (int32_t **)malloc16(2*sizeof(int32_t *));
for (i=0; i<ru->nb_rx; i++) {
// allocate 2 subframes of I/Q signal data (frequency)
calibration->rxdataF_ext[i] = (int32_t *)malloc16_clear(sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
LOG_I(PHY,"rxdataF_ext[%d] %p for RU %d\n",i,calibration->rxdataF_ext[i],ru->idx);
calibration->drs_ch_estimates[i] = (int32_t *)malloc16_clear(sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti);
}
}
// allocate FFT output buffers after extraction (RX)
calibration->rxdataF_ext = (int32_t**)malloc16(2*sizeof(int32_t*));
calibration->drs_ch_estimates = (int32_t**)malloc16(2*sizeof(int32_t*));
calibration->rxdataF_calib = (int32_t****)malloc16(2*sizeof(int32_t***));
//calibration->rxdataF_calib = (int32_t***)malloc16(2*sizeof(int32_t**)); // 2 frames to collect calibration data
//calibration->rxdataF_calib = (int32_t**)malloc16(2*sizeof(int32_t*)); // 2 RRUs
for (i=0; i<ru->nb_rx; i++) {
calibration->rxdataF_calib[i] = (int32_t***)malloc16(2*sizeof(int32_t**)); // 2 frames to collect calibration data
for (j=0; j<2; j++) {
calibration->rxdataF_calib[i][j] = (int32_t**)malloc16(2*sizeof(int32_t*)); // 2 RRUs
for (int k=0; k<2; k++) {
calibration->rxdataF_calib[i][j][k] = (int32_t*)malloc16_clear(sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
}
}
}
for (i=0; i<ru->nb_rx; i++) {
// allocate 2 subframes of I/Q signal data (frequency)
calibration->rxdataF_ext[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
LOG_I(PHY,"rxdataF_ext[%d] %p for RU %d\n",i,calibration->rxdataF_ext[i],ru->idx);
calibration->drs_ch_estimates[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti);
//calibration->rxdataF_calib[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
}
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
//AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
@@ -146,7 +151,7 @@ int phy_init_RU(RU_t *ru) {
for (p=0; p<15; p++) {
LOG_D(PHY,"[INIT] %s() nb_antenna_ports_eNB:%d \n", __FUNCTION__, ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB);
if (p<ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB || p==5) {
if (p<ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB || p==5 || p==7 || p==8) {
LOG_D(PHY,"[INIT] %s() DO BEAM WEIGHTS nb_antenna_ports_eNB:%d nb_tx:%d\n", __FUNCTION__, ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB, ru->nb_tx);
ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t *));
@@ -192,15 +197,10 @@ void phy_free_RU(RU_t *ru) {
for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdata[i]);
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata[i]);
if (ru->is_slave == 1) {
for (i = 0; i < ru->nb_rx; i++) {
free_and_zero(calibration->drs_ch_estimates_time[i]);
}
free_and_zero(calibration->drs_ch_estimates_time);
for (i = 0; i < ru->nb_rx; i++) {
free_and_zero(calibration->drs_ch_estimates_time[i]);
}
free_and_zero(calibration->drs_ch_estimates_time);
free_and_zero(ru->common.txdata);
free_and_zero(ru->common.rxdata);
} // else: IF5 or local RF -> nothing to free()
@@ -219,16 +219,14 @@ void phy_free_RU(RU_t *ru) {
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdataF[i]);
free_and_zero(ru->common.rxdataF);
if (ru->is_slave == 1) {
for (i = 0; i < ru->nb_rx; i++) {
for (i = 0; i < ru->nb_rx; i++) {
free_and_zero(calibration->rxdataF_ext[i]);
free_and_zero(calibration->drs_ch_estimates[i]);
}
free_and_zero(calibration->rxdataF_ext);
free_and_zero(calibration->drs_ch_estimates);
free_and_zero(calibration->drs_ch_estimates[i]);
free_and_zero(calibration->rxdataF_calib[i]);
}
free_and_zero(calibration->rxdataF_ext);
free_and_zero(calibration->drs_ch_estimates);
free_and_zero(calibration->rxdataF_calib);
for (i = 0; i < ru->nb_rx; i++) {
free_and_zero(ru->prach_rxsigF[i]);

View File

@@ -128,7 +128,7 @@ int lte_est_timing_advance_pusch(PHY_VARS_eNB *eNB,
int sync_pos = (frame_parms->ofdm_symbol_size-cyclic_shift*frame_parms->ofdm_symbol_size/12)%(frame_parms->ofdm_symbol_size);
AssertFatal(frame_parms->ofdm_symbol_size > 127,"frame_parms->ofdm_symbol_size %d<128\n",frame_parms->ofdm_symbol_size);
AssertFatal(frame_parms->nb_antennas_rx >0 && frame_parms->nb_antennas_rx<3,"frame_parms->nb_antennas_rx %d not in [0,1]\n",
AssertFatal(frame_parms->nb_antennas_rx >0 && frame_parms->nb_antennas_rx<NB_PUSCH_ANT_PORTS+1,"frame_parms->nb_antennas_rx %d not in [0,1,2]\n",
frame_parms->nb_antennas_rx);
for (i = 0; i < frame_parms->ofdm_symbol_size; i++) {
temp = 0;

View File

@@ -116,6 +116,57 @@ void send_IF4p5(RU_t *ru,
slotoffsetF += fp->ofdm_symbol_size;
blockoffsetF += fp->ofdm_symbol_size;
}
} else if (packet_type == IF4p5_PULCALIB) {
LOG_D(PHY,"send PULCALIB_IF4p5: RU %d frame %d, subframe %d\n",ru->idx,frame,subframe);
AssertFatal(subframe_select(fp,subframe)==SF_S, "calling PULCALIB in non-S subframe\n");
db_fulllength = 12*fp->N_RB_UL;
db_halflength = (db_fulllength)>>1;
slotoffsetF = 0;
blockoffsetF = (fp->ofdm_symbol_size)-db_halflength;
if (eth->flags == ETH_RAW_IF4p5_MODE) {
packet_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t);
} else {
packet_header = (IF4p5_header_t *)(tx_buffer);
data_block = (uint16_t*)(tx_buffer + sizeof_IF4p5_header_t);
}
gen_IF4p5_ul_header(packet_header, packet_type, frame, subframe);
AssertFatal(rxdataF[0]!=NULL,"rxdataF[0] is null\n");
for (symbol_id=0; symbol_id<11; symbol_id++) {
if (symbol_id==3 || symbol_id==10) {
for (int antenna_id=0; antenna_id<ru->nb_tx; antenna_id++) {
for (element_id=0; element_id<db_halflength; element_id++) {
i = (uint16_t*) &rxdataF[antenna_id][blockoffsetF+element_id];
data_block[element_id] = ((uint16_t) lin2alaw_if4p5[*i]) | (lin2alaw_if4p5[*(i+1)]<<8);
i = (uint16_t*) &rxdataF[antenna_id][slotoffsetF+element_id];
data_block[element_id+db_halflength] = ((uint16_t) lin2alaw_if4p5[*i]) | (lin2alaw_if4p5[*(i+1)]<<8);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 );
packet_header->frame_status &= ~(0x7);
packet_header->frame_status |= (ru->nb_rx-1);
packet_header->frame_status &= ~(0x000f<<26);
packet_header->frame_status |= (symbol_id&0x000f)<<26;
if (ru->idx<=1) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0+ru->idx, 1 );
if ((ru->ifdevice.trx_write_func(&ru->ifdevice,
symbol_id,
&tx_buffer,
db_fulllength*ru->nb_rx,
1,
IF4p5_PULCALIB)) < 0) {
perror("ETHERNET write for IF4p5_PULCALIB\n");
}
if (ru->idx<=1) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0+ru->idx, 0 );
}
slotoffsetF += fp->ofdm_symbol_size;
blockoffsetF += fp->ofdm_symbol_size;
}
} else if ((packet_type == IF4p5_PULFFT)||
(packet_type == IF4p5_PULTICK)) {
db_fulllength = 12*fp->N_RB_UL;
@@ -383,6 +434,38 @@ void recv_IF4p5(RU_t *ru,
signal_energy((int *)&rxdataF[antenna_id][blockoffsetF],db_halflength)));
data_block+=db_fulllength;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
} else if (*packet_type == IF4p5_PULCALIB) {
db_fulllength/=ru->nb_rx;
db_halflength/=ru->nb_rx;
*symbol_number = ((packet_header->frame_status)>>26)&0x000f;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF4_SYMBOL, *symbol_number );
if (ru->idx==0) LOG_D(PHY,"UL_IF4p5: RU %d : frame %d, subframe %d, symbol %d\n",ru->idx,*frame,*subframe,*symbol_number);
slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size);
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 );
for (int antenna_id=0;antenna_id<ru->nb_rx;antenna_id++) {
for (element_id=0; element_id<db_halflength; element_id++) {
i = (uint16_t*) &rxdataF[antenna_id][blockoffsetF+element_id];
*i = alaw2lin_if4p5[ (data_block[element_id] & 0xff) ];
*(i+1) = alaw2lin_if4p5[ (data_block[element_id]>>8) ];
i = (uint16_t*) &rxdataF[antenna_id][slotoffsetF+element_id];
*i = alaw2lin_if4p5[ (data_block[element_id+db_halflength] & 0xff) ];
*(i+1) = alaw2lin_if4p5[ (data_block[element_id+db_halflength]>>8) ];
//if (element_id==0) LOG_I(PHY,"recv_if4p5: symbol %d rxdata0 = (%u,%u)\n",*symbol_number,*i,*(i+1));
}
LOG_D(PHY,"PULCALIB_IF4p5: CC_id %d : frame %d, subframe %d (symbol %d)=> %d dB\n",ru->idx,*frame,*subframe,*symbol_number,
dB_fixed(signal_energy((int*)&rxdataF[antenna_id][slotoffsetF],db_halflength)+
signal_energy((int*)&rxdataF[antenna_id][blockoffsetF],db_halflength)));
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
} else if (*packet_type >= IF4p5_PRACH &&
*packet_type <= IF4p5_PRACH + 4) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
} else if (*packet_type >= IF4p5_PRACH &&

View File

@@ -44,6 +44,7 @@
#define IF4p5_PRACH_BR_CE2 0x0024
#define IF4p5_PRACH_BR_CE3 0x0025
#define IF4p5_PULTICK 0x0026
#define IF4p5_PULCALIB 0x0027
struct IF4p5_header {
/// Type

View File

@@ -689,8 +689,9 @@ void ulsch_extract_rbs_single(int32_t **rxdataF,
int32_t *rxF,*rxF_ext;
//uint8_t symbol = l+Ns*frame_parms->symbols_per_tti/2;
uint8_t symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
AssertFatal((frame_parms->nb_antennas_rx>0) && (frame_parms->nb_antennas_rx<5),
"nb_antennas_rx not in (1-4)\n");
AssertFatal((frame_parms->nb_antennas_rx>0) && (frame_parms->nb_antennas_rx<7),
"nb_antennas_rx not in (1-6)\n");
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
nb_rb1 = cmin(cmax((int)(frame_parms->N_RB_UL) - (int)(2*first_rb),(int)0),(int)(2*nb_rb)); // 2 times no. RBs before the DC

View File

@@ -2,6 +2,7 @@
#include <stdint.h>
#include <stdlib.h>
#include "PHY/defs_common.h"
#include "PHY/defs_eNB.h"
int f_read(char *calibF_fname, int nb_ant, int nb_freq, int32_t **tdd_calib_coeffs){
@@ -52,6 +53,24 @@ int compute_BF_weights(int32_t **beam_weights, int32_t **calib_dl_ch_estimates,
}
/* TODO: what to return? is this code used at all? */
return 0;
}
int compute_beam_weights(int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15], int32_t **calib_coeffs, int32_t **ul_ch_estimates, PHY_VARS_eNB *eNB, int l1_id, int p, int aa, int ru_id) {
//PHY_VARS_eNB *eNB = RC.eNB[0][0];
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
int d_f = 597;
//LOG_I(PHY,"compute_beam_weights : l1_id %d, p %d, aa %d, ru_id %d \n",l1_id,p,aa,ru_id);
//LOG_I(PHY,"(int16_t*)&beam_weights[%d][%d][%d][0] %p\n", l1_id,p,aa,(int16_t*)&beam_weights[l1_id][p][aa][0]);
//LOG_I(PHY,"[compute_beam_weights] : calib_coeffs[1][%d] : %d %d i\n",d_f,calib_coeffs[1][d_f],calib_coeffs[1][d_f+1]);
mult_cpx_vector((int16_t *)calib_coeffs[ru_id],
(int16_t*)&ul_ch_estimates[aa][0],
(int16_t*)&beam_weights[l1_id][p][aa][0],
fp->N_RB_UL*12,
15);
return 0;
}
// temporal test function

View File

@@ -84,7 +84,7 @@ int estimate_DLCSI_from_ULCSI(int32_t **calib_dl_ch_estimates, int32_t **ul_ch_e
int compute_BF_weights(int32_t **beam_weights, int32_t **calib_dl_ch_estimates, PRECODE_TYPE_t precode_type, int nb_ant, int nb_freq);
int compute_beam_weights(int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15], int32_t **calib_coeffs, int32_t **ul_ch_estimates, PHY_VARS_eNB *eNB, int l1_id, int p, int aa, int ru_id);
/** @}*/
#endif

View File

@@ -154,7 +154,19 @@ void remove_7_5_kHz(RU_t *ru,uint8_t slot)
(2*frame_parms->nb_prefix_samples)+
frame_parms->nb_prefix_samples0],
(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples)*sizeof(int32_t));
}
}
// undo 7.5 kHz offset for symbol 10 (for calibration)
if (slot == 3){
memcpy((void*)&rxdata_7_5kHz[aa][(10*frame_parms->ofdm_symbol_size)+
(8*frame_parms->nb_prefix_samples)+
2*frame_parms->nb_prefix_samples0],
(void*)&rxdata[aa][slot_offset+ru->N_TA_offset+
(3*frame_parms->ofdm_symbol_size)+
(2*frame_parms->nb_prefix_samples)+
frame_parms->nb_prefix_samples0],
(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples)*sizeof(int32_t));
}
}
}

View File

@@ -273,7 +273,6 @@ int32_t signal_energy_nodc(int32_t *input,uint32_t length)
register int32x4_t tmpE;
int32x2_t tmpE2;
int16x4_t *in = (int16x4_t *)input;
tmpE = vdupq_n_s32(0);
for (i=0; i<length>>1; i++) {

View File

@@ -138,16 +138,41 @@ typedef struct {
typedef struct {
/// \brief Received frequency-domain signal after extraction.
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - second index: ? [0..168*N_RB_DL[
/// - second index: ? [0..168*N_RB_DL]
int32_t **rxdataF_ext;
/// \brief Hold the channel estimates in time domain based on DRS.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..4*ofdm_symbol_size[
/// - first index: rx antenna id [0..nb_antennas_rx]
/// - second index: ? [0..4*ofdm_symbol_size]
int32_t **drs_ch_estimates_time;
/// \brief Hold the channel estimates in frequency domain based on DRS.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
/// - first index: rx antenna id [0..nb_antennas_rx]
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti]
int32_t **drs_ch_estimates;
/// \brief Holds all the received data required for one calibration round in the frequency domain at calibration symbol 10/SSF1
/// \brief calibration round = required frames to collect calibration symbols from all active RRUs = number of RRUs
/// e.x. if we need to calibrate 3 RRUs, the calibration round consists of 3 frames
/// - first index: frame number
/// - second index: RRU tag
/// - third index: rx antenna id [0..nb_antennas_rx]
/// - fourth index: [0..168*N_RB_DL]
int32_t ****rxdataF_calib;
/// \brief Holds the tdd reciprocity calibration coefficients
/// - first index: tx antenna [0..nb_antennas_tx]
/// - second index: number of RRUs
/// - third index: subcarriers [0..168*N_RB_DL]
int32_t ***calib_coeffs;
/// mutex for calibration thread
pthread_mutex_t mutex_calib;
/// condition variable for calibration processing thread
pthread_cond_t cond_calib;
/// This variable is protected by mutex_calib.
int instance_cnt_calib;
// pthread structure for calibration processing thread
pthread_t pthread_calib;
// pthread attributes for calibration processing thread
pthread_attr_t attr_calib;
// calibration frame counter
int calib_frame;
} RU_CALIBRATION;
@@ -422,6 +447,10 @@ typedef enum {
typedef struct RU_t_s {
/// tag of this ru
uint32_t tag;
/// number of RRUs
uint32_t p;
/// index of this ru
uint32_t idx;
/// Pointer to configuration file
@@ -458,6 +487,8 @@ typedef struct RU_t_s {
int wait_cnt;
/// counter to delay start of slave RUs until stable synchronization
int wait_check;
/// counter to count missed synch events during synchronization of RU
int missed_synch_events;
/// Total gain of receive chain
uint32_t rx_total_gain_dB;
/// number of bands that this device can support
@@ -664,6 +695,10 @@ typedef struct RRU_capabilities_s {
typedef struct RRU_config_s {
/// tag of an RU
uint32_t tag;
/// number of slave RRUs
uint32_t p;
/// Fronthaul format
RU_if_south_t FH_fmt;
/// number of EUTRA bands (<=4) configured in RRU

View File

@@ -86,6 +86,11 @@ typedef struct {
/// - first index: tx antenna [0..14[ where 14 is the total supported antenna ports.
/// - second index: sample [0..]
int32_t **txdataF;
/// \brief Holds the tdd reciprocity calibration coefficients
/// - first index: tx antenna [0..nb_antennas_tx]
/// - second index: number of RRUs
/// - third index: subcarriers [0..168*N_RB_DL]
int32_t **calib_coeffs;
} LTE_eNB_COMMON;
typedef struct {
@@ -165,7 +170,7 @@ typedef struct {
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **ul_ch_magb;
/// measured RX power based on DRS
int ulsch_power[2];
int ulsch_power[6];
/// \brief llr values.
/// - first index: ? [0..1179743] (hard coded)
int16_t *llr;
@@ -574,6 +579,8 @@ typedef struct PHY_VARS_eNB_s {
/// if ==0 enables phy only test mode
int mac_enabled;
/// enable precoding with calibration coefficients
int calib_prec_enabled;
// PDSCH Varaibles
PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_UE_MAX];

View File

@@ -175,6 +175,7 @@
#define SLOT_TIME_NS (SLOT_LENGTH_SAMPLES*(1e3)/7.68) // slot time in ns
#define NB_ANTENNA_PORTS_ENB 6 // total number of eNB antenna ports
#define NB_PUSCH_ANT_PORTS 6 // total number of eNB pusch antenna ports
#ifdef EXMIMO
#define TARGET_RX_POWER 55 // Target digital power for the AGC

View File

@@ -117,11 +117,11 @@ void feptx0(RU_t *ru,
fp->frame_type,ru->is_slave);
*/
int num_symb = 7;
/*
if (subframe_select(fp,subframe) == SF_S)
num_symb = fp->dl_symbols_in_S_subframe+1;
if (ru->generate_dmrs_sync == 1 && slot == 0 && subframe == 1 && aa==0) {
*/
if (ru->generate_dmrs_sync == 1 && /*slot == 2 &&*/ subframe == 1 && aa==0) {
//int32_t dmrs[ru->frame_parms.ofdm_symbol_size*14] __attribute__((aligned(32)));
//int32_t *dmrsp[2] ={dmrs,NULL}; //{&dmrs[(3-ru->frame_parms.Ncp)*ru->frame_parms.ofdm_symbol_size],NULL};
@@ -237,7 +237,9 @@ void feptx_ofdm_2thread(RU_t *ru,
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 );
if (subframe_select(fp,subframe)==SF_DL) {
//The 2nd check is to force the RRUs to send DMRS at symbol 10-subframe 1-slot 1 (for calibration)
if (subframe_select(fp,subframe)==SF_DL || ((subframe_select(fp,subframe)==SF_DL || subframe==1))) {
//if (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);
@@ -441,12 +443,16 @@ void feptx_prec(RU_t *ru,
int l,i,aa;
PHY_VARS_eNB **eNB_list = ru->eNB_list, *eNB;
LTE_DL_FRAME_PARMS *fp;
RU_CALIBRATION *calibration = &ru->calibration;
if (ru->num_eNB == 1)
{
eNB = eNB_list[0];
//PHY_VARS_eNB *eNB = RC.eNB[0][0];
LTE_eNB_COMMON *const common_vars = &eNB->common_vars;
fp = &eNB->frame_parms;
LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[subframe&1];
LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[subframe&1];
LTE_eNB_SRS *srs_vars = eNB->srs_vars;
if (subframe_select(fp,subframe) == SF_UL) return;
@@ -455,6 +461,22 @@ void feptx_prec(RU_t *ru,
for (aa=0;aa<ru->nb_tx;aa++) {
memset(ru->common.txdataF_BF[aa],0,sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_tti);
for (int p=0;p<NB_ANTENNA_PORTS_ENB;p++) {
if (eNB->calib_prec_enabled==1 && (p==0 || p==5 || p==7 || p==8)) {
//LOG_I(PHY,"[feptx_prec] common_vars->calib_coeffs[%d] = %p \n",ru->idx,common_vars->calib_coeffs[ru->idx]);
//LOG_I(PHY,"feptx_prec : calib_coeffs[%d][597] : %d %d i\n",ru->idx,((int16_t*)&RC.eNB[0][0]->common_vars.calib_coeffs[ru->idx])[597], ((int16_t*)&RC.eNB[0][0]->common_vars.calib_coeffs[ru->idx])[597+1]);
compute_beam_weights(ru->beam_weights, common_vars->calib_coeffs, srs_vars->srs_ch_estimates, eNB, eNB->Mod_id, p, aa, ru->idx);
for (l=pdcch_vars->num_pdcch_symbols;l<fp->symbols_per_tti;l++) {
beam_precoding(eNB->common_vars.txdataF,
ru->common.txdataF_BF,
subframe,
fp,
ru->beam_weights,
l,
aa,
p,
eNB->Mod_id);
}
}
if (ru->do_precoding == 0) {
if (p==0)
memcpy((void*)ru->common.txdataF_BF[aa],
@@ -633,11 +655,16 @@ void ru_fep_full_2thread(RU_t *ru,
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
RU_CALIBRATION *calibration = &ru->calibration;
RRU_CONFIG_msg_t rru_config_msg;
int check_sync_pos;
int check_sync_pos,Ns,l;
struct timespec wait;
if (subframe==1){
if ((fp->frame_type == TDD) && (subframe_select(fp,subframe) != SF_UL)) return;
}
else if ((fp->frame_type == TDD) && (subframe_select(fp,subframe) != SF_UL)) {
return;
}
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
@@ -682,43 +709,92 @@ void ru_fep_full_2thread(RU_t *ru,
printf("delay in fep wait on condition in frame_rx: %d subframe_rx: %d \n", proc->frame_rx, proc->tti_rx);
}
if (proc->tti_rx/*proc->subframe_rx*/==1 && ru->is_slave==1/* && ru->state == RU_CHECK_SYNC*/)
{
//LOG_I(PHY,"Running check synchronization procedure for frame %d\n", proc->frame_rx);
if (proc->tti_rx==1 && ru->is_slave==0) {
Ns = 1;
l = 10;
ulsch_extract_rbs_single(ru->common.rxdataF,
calibration->rxdataF_ext,
0,
fp->N_RB_DL,
3%(fp->symbols_per_tti/2),// l = symbol within slot
3/(fp->symbols_per_tti/2),// Ns = slot number
fp);
calibration->rxdataF_ext,
0,
fp->N_RB_DL,
3%(fp->symbols_per_tti/2),// l = symbol within slot
Ns,// Ns = slot number
fp);
lte_ul_channel_estimation_RRU(fp,
calibration->drs_ch_estimates,
calibration->drs_ch_estimates_time,
calibration->rxdataF_ext,
fp->N_RB_DL,
proc->frame_rx,
proc->tti_rx,
0,
0,
0,
l,
0,
0);
T(T_CALIBRATION_CHANNEL_ESTIMATES, T_INT(ru->idx), T_INT(proc->frame_rx), T_INT(proc->tti_rx),
T_INT(l),T_BUFFER(&calibration->drs_ch_estimates[0][l*12*fp->N_RB_UL],
12*fp->N_RB_UL*sizeof(int32_t)));
}
if (proc->tti_rx==1 && ru->is_slave==1/* && ru->state == RU_CHECK_SYNC*/) {
Ns = 0;
l = 3;
//LOG_I(PHY,"Running check synchronization procedure for frame %d\n", proc->frame_rx);
ulsch_extract_rbs_single(ru->common.rxdataF,
calibration->rxdataF_ext,
0,
fp->N_RB_DL,
3%(fp->symbols_per_tti/2),// l = symbol within slot
Ns,// Ns = slot number
fp);
/*lte_ul_channel_estimation((PHY_VARS_eNB *)NULL,
proc,
ru->idx,
3%(fp->symbols_per_tti/2),
3/(fp->symbols_per_tti/2));
*/
lte_ul_channel_estimation_RRU(fp,
calibration->drs_ch_estimates,
calibration->drs_ch_estimates_time,
calibration->rxdataF_ext,
fp->N_RB_DL, //N_rb_alloc,
proc->frame_rx,
proc->tti_rx,//proc->subframe_rx,
0,//u = 0..29
0,//v = 0,1
/*eNB->ulsch[ru->idx]->cyclicShift,cyclic_shift,0..7*/0,
3,//l,
0,//interpolate,
0 /*eNB->ulsch[ru->idx]->rnti rnti or ru->ulsch[eNB_id]->rnti*/);
proc->frame_rx,
proc->tti_rx,
0,//u = 0..29
0,//v = 0,1
/*eNB->ulsch[ru->idx]->cyclicShift,cyclic_shift,0..7*/0,
l,//l
0,//interpolate,
0 /*eNB->ulsch[ru->idx]->rnti rnti or ru->ulsch[eNB_id]->rnti*/);
check_sync_pos = lte_est_timing_advance_pusch((PHY_VARS_eNB *)NULL, ru->idx);
check_sync_pos = lte_est_timing_advance_pusch((PHY_VARS_eNB *)NULL, ru->idx);
if (ru->state == RU_CHECK_SYNC) {
if ((check_sync_pos >= 0 && check_sync_pos<8) || (check_sync_pos < 0 && check_sync_pos>-8)) {
LOG_I(PHY,"~~~~~~~~~~~ check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check);
ru->wait_check++;
}
else {
ru->missed_synch_events++;
LOG_I(PHY,"!!!!!!!!!!!! check_sync_pos %d, frame %d, cnt %d, missed %d\n",check_sync_pos,proc->frame_rx,ru->wait_check,ru->missed_synch_events);
}
if (ru->missed_synch_events > 2) {
ru->in_synch = 0;
if (ru->stop_rf) {
ru->stop_rf(ru);
ru->state = RU_SYNC;
ru->cmd = EMPTY;
LOG_I(PHY,"RU %d rf device stopped\n",ru->idx);
LOG_M("rxdata.m","rxdata",&ru->common.rxdata[0][0], fp->samples_per_tti*2,1,1);
exit(-1);
} else AssertFatal(1==0,"ru->stop_rf doesn't exist\n");
}
if (ru->wait_check==20) {
ru->state = RU_RUN;

View File

@@ -215,7 +215,9 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam
} else if (flags == IF4p5_PULFFT) {
packet_size = RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks);
} else if (flags == IF4p5_PULTICK) {
packet_size = RAW_IF4p5_PULTICK_SIZE_BYTES;
packet_size = RAW_IF4p5_PULTICK_SIZE_BYTES;
} else if (flags == IF4p5_PULCALIB) {
packet_size = RAW_IF4p5_PULCALIB_SIZE_BYTES(nblocks);
} else if (flags == IF5_MOBIPASS) {
packet_size = RAW_IF5_MOBIPASS_SIZE_BYTES;
} else {

View File

@@ -235,7 +235,9 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam
} else if (flags == IF4p5_PULFFT) {
packet_size = UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks);
} else if (flags == IF4p5_PULTICK) {
packet_size = UDP_IF4p5_PULTICK_SIZE_BYTES;
packet_size = UDP_IF4p5_PULTICK_SIZE_BYTES;
} else if (flags == IF4p5_PULCALIB) {
packet_size = UDP_IF4p5_PULCALIB_SIZE_BYTES(nblocks);
} else if ((flags >= IF4p5_PRACH)&&
(flags <= (IF4p5_PRACH+4))) {
packet_size = UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + (nsamps<<1);

View File

@@ -75,10 +75,12 @@
#define RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define RAW_IF4p5_PULTICK_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t)
#define RAW_IF4p5_PRACH_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + PRACH_BLOCK_SIZE_BYTES)
#define RAW_IF4p5_PULCALIB_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks) (UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks) (UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
#define UDP_IF4p5_PULTICK_SIZE_BYTES (UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t)
#define UDP_IF4p5_PRACH_SIZE_BYTES (UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + PRACH_BLOCK_SIZE_BYTES)
#define UDP_IF4p5_PULCALIB_SIZE_BYTES(nblocks) (UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
// Mobipass packet sizes
#define RAW_IF5_MOBIPASS_BLOCK_SIZE_BYTES 1280

View File

@@ -140,6 +140,7 @@ static struct {
} sync_phy_proc;
extern double cpuf;
extern char ru_states[6][9];
void init_eNB(int,int);
@@ -153,6 +154,7 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru, int frame, int subframe);
extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
extern int check_sync(RU_t *ru, RU_t *ru_master, int subframe);
//#define TICK_TO_US(ts) (ts.diff)
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)

View File

@@ -45,11 +45,21 @@
#include <getopt.h>
#include <sys/sysinfo.h>
#include "rt_wrapper.h"
#include </home/eurecom/gsl/include/gsl/gsl_vector.h>
#include </home/eurecom/gsl/include/gsl/gsl_complex.h>
#include </home/eurecom/gsl/include/gsl/gsl_complex_math.h>
#include </home/eurecom/gsl/include/gsl/gsl_inline.h>
#include </home/eurecom/gsl/include/gsl/gsl_eigen.h>
#include </home/eurecom/gsl/include/gsl/gsl_matrix.h>
#include </home/eurecom/gsl/include/gsl/gsl_blas.h>
#include </home/eurecom/gsl/include/gsl/gsl_linalg.h>
#define GSL_EXPORT
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
#include "assertions.h"
#include "msc.h"
#include "PHY/defs_eNB.h"
#include "PHY/defs_common.h"
#include "PHY/phy_extern.h"
#include "PHY/types.h"
@@ -110,6 +120,7 @@ extern void phy_init_RU(RU_t *);
void stop_RU(int nb_ru);
void do_ru_synch(RU_t *ru);
int check_sync(RU_t *ru, RU_t *ru_master, int subframe);
void configure_ru(int idx,
void *arg);
@@ -122,6 +133,11 @@ int connect_rau(RU_t *ru);
const char ru_states[6][9] = {"RU_IDLE","RU_CONFIG","RU_READY","RU_RUN","RU_ERROR","RU_SYNC"};
#define FRACT_BITS 15
#define FLOAT2FIXED(x) (int16_t)(round(x * (1 << FRACT_BITS)))
int32_t calib_data[1][2][2][600];
extern uint16_t sf_ahead;
#if defined(PRE_SCD_THREAD)
@@ -216,46 +232,59 @@ void fh_if4p5_south_in(RU_t *ru,
int *subframe) {
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
RU_proc_t *proc = &ru->proc;
int f,sf;
int f,sf,Ns,l,u;
RU_CALIBRATION *calibration = &ru->calibration;
PHY_VARS_eNB *eNB;
eNB = RC.eNB[0][0];
LTE_eNB_COMMON *const common_vars = &eNB->common_vars;
uint16_t packet_type;
uint32_t symbol_number=0;
uint32_t symbol_mask_full;
int pultick_received=0;
int pultick_received=0;
if ((fp->frame_type == TDD) && (subframe_select(fp,*subframe)==SF_S))
symbol_mask_full = (1<<fp->ul_symbols_in_S_subframe)-1;
else
symbol_mask_full = (1<<fp->symbols_per_tti)-1;
if (ru->is_slave==1 && ru->wait_cnt!=0) RC.collect = 0;
if ((fp->frame_type == TDD) && (subframe_select(fp,*subframe)==SF_S)) {
if (*subframe == 1) {
symbol_mask_full = (1<<11)-1;
} else {
symbol_mask_full = (1<<fp->ul_symbols_in_S_subframe)-1;
}
} else {
symbol_mask_full = (1<<fp->symbols_per_tti)-1;
}
LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, ru %d, mask %x\n",ru->idx,*frame,*subframe,ru->idx,proc->symbol_mask[*subframe]);
if (proc->symbol_mask[*subframe] == symbol_mask_full) proc->symbol_mask[*subframe] = 0;
AssertFatal(proc->symbol_mask[*subframe]==0 || proc->symbol_mask[*subframe]==symbol_mask_full,"rx_fh_if4p5: proc->symbol_mask[%d] = %x\n",*subframe,proc->symbol_mask[*subframe]);
if (proc->symbol_mask[*subframe]==0) { // this is normal case, if not true then we received a PULTICK before the previous subframe was finished
do {
recv_IF4p5(ru, &f, &sf, &packet_type, &symbol_number);
LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, f %d, sf %d\n",ru->idx,*frame,*subframe,f,sf);
if (oai_exit == 1 || ru->cmd== STOP_RU) break;
if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sf] = proc->symbol_mask[sf] | (1<<symbol_number);
else if (packet_type == IF4p5_PULTICK) {
proc->symbol_mask[sf] = symbol_mask_full;
pultick_received++;
/*
if ((proc->first_rx==0) && (f!=*frame)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received frame %d != expected %d (RU %d) \n",f,*frame, ru->idx);
else if ((proc->first_rx==0) && (sf!=*subframe)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n",sf,*subframe,proc->first_rx);
else break; */
if (f==*frame || sf==*subframe) break;
} else if (packet_type == IF4p5_PRACH) {
// nothing in RU for RAU
}
LOG_D(PHY,"rx_fh_if4p5 for RU %d: subframe %d, sf %d, symbol mask %x\n",ru->idx,*subframe,sf,proc->symbol_mask[sf]);
} while(proc->symbol_mask[sf] != symbol_mask_full);
} else {
f = *frame;
sf = *subframe;
if (proc->symbol_mask[*subframe]==0) { // this is normal case, if not true then we received a PULTICK before the previous subframe was finished
do {
recv_IF4p5(ru, &f, &sf, &packet_type, &symbol_number);
LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, f %d, sf %d\n",ru->idx,*frame,*subframe,f,sf);
if (oai_exit == 1 || ru->cmd== STOP_RU) break;
if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sf] = proc->symbol_mask[sf] | (1<<symbol_number);
else if (packet_type == IF4p5_PULCALIB) {
proc->symbol_mask[sf] = (2<<symbol_number)-1;
LOG_D(PHY,"symbol_mask[%d] %d\n",sf,proc->symbol_mask[sf]);
}
else if (packet_type == IF4p5_PULTICK) {
proc->symbol_mask[sf] = symbol_mask_full;
pultick_received++;
/*
if ((proc->first_rx==0) && (f!=*frame)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received frame %d != expected %d (RU %d) \n",f,*frame, ru->idx);
else if ((proc->first_rx==0) && (sf!=*subframe)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n",sf,*subframe,proc->first_rx);
else break; */
if (f==*frame || sf==*subframe) break;
} else if (packet_type == IF4p5_PRACH) {
// nothing in RU for RAU
}
LOG_D(PHY,"rx_fh_if4p5 for RU %d: subframe %d, sf %d, symbol mask %x, pulticks %d\n",ru->idx,*subframe,sf,proc->symbol_mask[sf],pultick_received);
} while(proc->symbol_mask[sf] != symbol_mask_full);
}
else {
f = *frame;
sf = *subframe;
}
//calculate timestamp_rx, timestamp_tx based on frame and subframe
@@ -302,6 +331,136 @@ void fh_if4p5_south_in(RU_t *ru,
}*/
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_IN_RU+ru->idx,f);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_IN_RU+ru->idx,sf);
/*
// prepei kapws na thesw to cnt = 1 mono mia fora
if (ru->wait_cnt==5){
calib_frame = 0;
temp_frame = f;
LOG_I(PHY,"1) calib_frame %d, temp_frame %d, RRU %d\n",calib_frame,temp_frame,ru->idx);
}
*/
if (ru->is_slave==1 && ru->wait_cnt==0) RC.collect = 1;
if (ru->wait_cnt==0 && packet_type == IF4p5_PULCALIB && RC.collect==1 && f>199 && ( (f%2==0 && ru->idx==1) || (f%2==1 && ru->idx==0) ) ) {
if (f%2==0) {
calibration->calib_frame = 0;
calibration->calib_frame++;
} else {
calibration->calib_frame+=2;
}
T(T_RAU_INPUT_SIGNAL, T_INT(ru->idx), T_INT(f), T_INT(sf),
T_BUFFER(&ru->common.rxdataF[0][0],
fp->symbols_per_tti*fp->ofdm_symbol_size*sizeof(int32_t)));
// Estimate calibration channel estimates:
Ns = (ru->is_slave==0 ? 1 : 1);
l = (ru->is_slave==0 ? 10 : 10);
u = (ru->is_slave==0 ? 0 : 0);
ru->frame_parms->nb_antennas_rx = ru->nb_rx;
ulsch_extract_rbs_single(ru->common.rxdataF,
calibration->rxdataF_ext,
0,
fp->N_RB_DL,
3%(fp->symbols_per_tti/2),// l = symbol within slot
Ns,
fp);
//mutex lock for wakeup signal
pthread_mutex_lock(&calibration->mutex_calib);
//check instance ==-1 then memcpy else nthing
if (calibration->instance_cnt_calib < 0) {
memcpy((void*)calib_data[0][calibration->calib_frame-1][ru->idx],
(void*)&calibration->rxdataF_ext[0][l*12*fp->N_RB_UL],
12*fp->N_RB_UL*sizeof(int32_t));
}
//wakeup calib_thread only if I have collected all the required data for calibration
if (calibration->calib_frame==2) {
calibration->calib_frame = 0;
// the thread can now be woken up
//LOG_I(PHY,"calib_thread is woken up, RU %d\n", ru->idx);
//LOG_I(PHY,"[fh_if4p5_south_in] common_vars->calib_coeffs[%d] = %p \n",ru->idx,common_vars->calib_coeffs[ru->idx]);
RC.eNB[0][0]->calib_prec_enabled = 0;
calibration->instance_cnt_calib = 0;
pthread_cond_signal(&calibration->cond_calib);
}
//mutex unlock for wakeup signal
pthread_mutex_unlock(&calibration->mutex_calib);
// OR should I call just: lte_ul_channel_estimation();
/*lte_ul_channel_estimation((PHY_VARS_eNB *)NULL,
proc,
ru->idx,
3%(fp->symbols_per_tti/2),
Ns);
*/
/* lte_ul_channel_estimation_RRU(fp,
calibration->drs_ch_estimates,
calibration->drs_ch_estimates_time,
calibration->rxdataF_ext,
fp->N_RB_DL,
f,
sf,
u,
0,
0,
l,
0,
0);
T(T_CALIBRATION_CHANNEL_ESTIMATES, T_INT(ru->idx), T_INT(f), T_INT(sf),
T_INT(l),T_BUFFER(&calibration->drs_ch_estimates[0][l*12*fp->N_RB_UL],
12*fp->N_RB_UL*sizeof(int32_t)));
T(T_CALIBRATION_CHANNEL_ESTIMATES_TIME, T_INT(ru->idx), T_INT(f), T_INT(sf),
T_BUFFER(calibration->drs_ch_estimates_time[0],
fp->ofdm_symbol_size*sizeof(int32_t)));
*/
T(T_RAU_INPUT_DMRS, T_INT(ru->idx), T_INT(f), T_INT(sf),
T_BUFFER(&calibration->rxdataF_ext[0][l*12*fp->N_RB_UL],
12*fp->N_RB_UL*sizeof(int32_t)));
}
/* if (ru->wait_cnt==0 && packet_type == IF4p5_PULCALIB && RC.collect==1 && ru->is_slave==1) {
Ns = 0;
l = 3;
u = 0;
ru->frame_parms.nb_antennas_rx = ru->nb_rx;
ulsch_extract_rbs_single(ru->common.rxdataF,
calibration->rxdataF_ext,
0,
fp->N_RB_DL,
3%(fp->symbols_per_tti/2),// l = symbol within slot
Ns,
fp);
lte_ul_channel_estimation_RRU(fp,
calibration->drs_ch_estimates,
calibration->drs_ch_estimates_time,
calibration->rxdataF_ext,
fp->N_RB_DL,
f,
sf,
u,
0,
0,
l,
0,
0);
T(T_CALIBRATION_CHANNEL_ESTIMATES, T_INT(ru->idx), T_INT(f), T_INT(sf),
T_INT(l),T_BUFFER(&calibration->drs_ch_estimates[0][l*12*fp->N_RB_UL],
12*fp->N_RB_UL*sizeof(int32_t)));
}*/
proc->symbol_mask[sf] = 0;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff);
LOG_D(PHY,"RU %d: fh_if4p5_south_in returning ...\n",ru->idx);
@@ -573,7 +732,17 @@ void fh_if4p5_north_out(RU_t *ru) {
if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) {
/// **** in TDD during DL send_IF4 of ULTICK to RCC **** ///
send_IF4p5(ru, proc->frame_rx, proc->tti_rx, IF4p5_PULTICK);
if (subframe_select(fp,subframe)==SF_S && subframe==1 /*&& ru->state==RU_RUN*/) {
send_IF4p5(ru, proc->frame_rx, proc->tti_rx, IF4p5_PULCALIB);
LOG_D(PHY,"~~~~~~******* Sending PULCALIB frame %d, subframe %d\n",proc->frame_rx,proc->tti_rx);
T(T_RAU_INPUT_DMRS, T_INT(ru->idx), T_INT(proc->frame_rx), T_INT(proc->tti_rx),
T_BUFFER(&ru->common.rxdataF[0][proc->tti_rx*fp->symbols_per_tti*fp->ofdm_symbol_size],
fp->symbols_per_tti*fp->ofdm_symbol_size*sizeof(int32_t)));
} else {
send_IF4p5(ru, proc->frame_rx, proc->tti_rx, IF4p5_PULTICK);
LOG_D(PHY,"~~~~~~******* Sending PULTICK frame %d, subframe %d\n",proc->frame_rx,proc->tti_rx);
}
LOG_D(PHY,"fh_if4p5_north_out: Sending IF4p5_PULCALIB SFN.SF %d.%d\n",proc->frame_rx,proc->tti_rx);
ru->north_out_cnt++;
return;
}
@@ -777,8 +946,8 @@ void tx_rf(RU_t *ru,
uint64_t timestamp) {
RU_proc_t *proc = &ru->proc;
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
void *txp[ru->nb_tx];
unsigned int txs;
void *txp[ru->nb_tx],*txp1[ru->nb_tx];
unsigned int txs,txs1;
int i;
T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(subframe),
T_INT(0), T_BUFFER(&ru->common.txdata[0][subframe * fp->samples_per_tti], fp->samples_per_tti * 4));
@@ -789,30 +958,37 @@ void tx_rf(RU_t *ru,
if ((SF_type == SF_DL) ||
(SF_type == SF_S)) {
int siglen=fp->samples_per_tti,flags=1;
if (SF_type == SF_S) {
int txsymb = fp->dl_symbols_in_S_subframe+(ru->is_slave==0 ? 1 : 0);
AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb);
/* end_of_burst_delay is used to stop TX only "after a while".
* If we stop right after effective signal, with USRP B210 and
* B200mini, we observe a high EVM on the S subframe (on the
* PSS).
* A value of 400 (for 30.72MHz) solves this issue. This is
* the default.
*/
siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0)
+ (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples)
+ ru->end_of_burst_delay;
flags=3; // end of burst
}
int siglen=fp->samples_per_tti,flags=1;
int siglen2=fp->samples_per_tti+fp->nb_prefix_samples;
int sigoff2=2*fp->nb_prefix_samples0+8*fp->nb_prefix_samples+10*fp->ofdm_symbol_size;
if (fp->frame_type == TDD &&
SF_type == SF_DL &&
prevSF_type == SF_UL) {
flags = 2; // start of burst
sf_extension = ru->sf_extension;
}
if (SF_type == SF_S) {
int txsymb = fp->dl_symbols_in_S_subframe+(ru->is_slave==0 ? 1 : -1);
AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb);
/* end_of_burst_delay is used to stop TX only "after a while".
* If we stop right after effective signal, with USRP B210 and
* B200mini, we observe a high EVM on the S subframe (on the
* PSS).
* A value of 400 (for 30.72MHz) solves this issue. This is
* the default.
*/
siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0)
+ (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples)
+ ru->end_of_burst_delay;
if (ru->state==RU_RUN && proc->frame_tx%ru->p==ru->tag) {
siglen2 = fp->ofdm_symbol_size + fp->nb_prefix_samples + ru->end_of_burst_delay; // length of symbol 10
}
flags=3; // end of burst
}
if (fp->frame_type == TDD &&
SF_type == SF_DL &&
prevSF_type == SF_UL) {
flags = 2; // start of burst
sf_extension = ru->sf_extension;
}
#if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__
@@ -824,8 +1000,10 @@ void tx_rf(RU_t *ru,
sf_extension = (sf_extension)&0xfffffffc;
#endif
for (i=0; i<ru->nb_tx; i++)
txp[i] = (void *)&ru->common.txdata[i][(subframe*fp->samples_per_tti)-sf_extension];
for (i=0; i<ru->nb_tx; i++) {
txp[i] = (void *)&ru->common.txdata[i][(proc->tti_tx*fp->samples_per_tti)-sf_extension];
txp1[i] = (void*)&ru->common.txdata[i][(proc->tti_tx*fp->samples_per_tti)+(sigoff2)-sf_extension]; // pointer to 1st sample of 10th symbol
}
/* add fail safe for late command */
if(late_control!=STATE_BURST_NORMAL) { //stop burst
@@ -865,11 +1043,25 @@ void tx_rf(RU_t *ru,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers
txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
txp,
siglen+sf_extension,
ru->nb_tx,
flags);
proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
txp,
siglen+sf_extension,
ru->nb_tx,
flags);
if (ru->state==RU_RUN && proc->frame_tx%ru->p==ru->tag && proc->tti_tx==1) {
txs1 = ru->rfdevice.trx_write_func(&ru->rfdevice,
proc->timestamp_tx+(ru->ts_offset+sigoff2)-ru->openair0_cfg.tx_sample_advance-sf_extension,
txp1,
siglen2+sf_extension,
ru->nb_tx,
flags);
//LOG_M("txdata.m","txdata",&ru->common.txdata[0][0], fp->samples_per_tti*10,1,1); // save 1 frame
//exit(-1);
int se1 = dB_fixed(signal_energy(txp1[0],siglen2+sf_extension));
LOG_D(PHY,"******** frame %d subframe %d RRU sends DMRS of energy10 %d, energy3 %d\n",proc->frame_tx,proc->tti_tx,se1,dB_fixed(signal_energy(txp[0],siglen+sf_extension)));
LOG_D(PHY,"txs1 %d, siglen2 %d, sf_extension %d\n",txs1,siglen2,sf_extension);
}
ru->south_out_cnt++;
LOG_D(PHY,"south_out_cnt %d\n",ru->south_out_cnt);
int se = dB_fixed(signal_energy(txp[0],siglen+sf_extension));
@@ -879,7 +1071,13 @@ void tx_rf(RU_t *ru,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
// AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen);
if (ru->state==RU_RUN && proc->frame_tx%ru->p==ru->tag && proc->tti_tx==1) {
if( (txs1!=siglen2+sf_extension) && (late_control==STATE_BURST_NORMAL) ){ /* add fail safe for late command */
late_control=STATE_BURST_TERMINATE;
LOG_E(PHY,"TX : Timeout (sent %d/%d) state =%d\n",txs1, siglen2,late_control);
}
}
if( (txs != siglen+sf_extension) && (late_control==STATE_BURST_NORMAL) ) { /* add fail safe for late command */
late_control=STATE_BURST_TERMINATE;
LOG_E(PHY,"TX : Timeout (sent %d/%d) state =%d\n",txs, siglen,late_control);
@@ -1606,7 +1804,7 @@ static void *ru_thread_tx( void *param ) {
AssertFatal((ret=pthread_mutex_lock(&eNB_proc->mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
for (int j=0; j<eNB->num_RU; j++) {
if (ru == eNB->RU_list[j]) {
if (ru == eNB->RU_list[j] && eNB->RU_list[j]->wait_cnt == 0) {
if ((eNB_proc->RU_mask_tx&(1<<j)) > 0)
LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n",
eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx);
@@ -1641,8 +1839,8 @@ static void *ru_thread_tx( void *param ) {
}
}
//printf("ru_thread_tx: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask_tx %d\n",
//eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,ru->wait_cnt,eNB_proc->RU_mask_tx);
/* printf("ru_thread_tx: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask_tx %d\n",
eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,ru->wait_cnt,eNB_proc->RU_mask_tx);*/
}
release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
@@ -1650,6 +1848,235 @@ static void *ru_thread_tx( void *param ) {
}
//int calib_thread( void *param ) {
void *calib_thread(void *param) {
RU_t *ru = (RU_t *)param;
RU_CALIBRATION *calibration = &ru->calibration;
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
PHY_VARS_eNB *eNB;
eNB = RC.eNB[0][0];
LTE_eNB_COMMON *const common_vars = &eNB->common_vars;
//PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param;
//PHY_VARS_eNB *eNB = RC.eNB[0][0];
//PHY_VARS_eNB **eNB_list = *eNB;
//eNB = eNB_list[0];
//LTE_eNB_COMMON *common_vars = &eNB->common_vars;
int G = 2; // number of groups of RRUs
int N_RRUs = RC.nb_RU; // number of active RRUs
int M_i = N_RRUs/G; // number of RRUs per group
int d_f;
uint32_t N_f = 12*fp->N_RB_UL; // number of subcarriers
double y = -1; // scaled by -1
double x = 32768; // scaled by 1/pow2(15)
/*
gsl_vector_complex *drsseq0 = gsl_vector_complex_alloc(N_f);
gsl_complex Z,Z_scaled,val;
gsl_matrix_complex *P = gsl_matrix_complex_alloc(M_i,M_i);
gsl_matrix_complex *Y2_1 = gsl_matrix_complex_alloc(M_i,M_i); // y1_0
gsl_matrix_complex *Y1_2 = gsl_matrix_complex_alloc(M_i,M_i); // y0_1
gsl_vector_complex *y0_1 = gsl_vector_complex_alloc(N_f);
gsl_vector_complex *y1_0 = gsl_vector_complex_alloc(N_f);
gsl_matrix_complex *Y_P_res = gsl_matrix_complex_alloc(N_RRUs,N_RRUs);
gsl_eigen_hermv_workspace *w = gsl_eigen_hermv_alloc(N_RRUs);
gsl_vector *Y_P_eigenvalues = gsl_vector_alloc(N_RRUs);
gsl_matrix_complex *Y_P_eigenvectors = gsl_matrix_complex_alloc(N_RRUs,N_RRUs);
gsl_vector_complex *F_inv_est = gsl_vector_complex_alloc(N_RRUs);
gsl_matrix_complex *F = gsl_matrix_complex_alloc(N_RRUs,N_f);
*/
while (!oai_exit) {
if (oai_exit) break;
wait_on_condition(&calibration->mutex_calib,&calibration->cond_calib,&calibration->instance_cnt_calib,"calib_thread");
//LOG_I(PHY,"START of calib_thread : instance_cnt_calib %d\n",calibration->instance_cnt_calib);
//if (gsl_vector_complex_isnull(y1_0)==1) return;
gsl_vector_complex *drsseq0 = gsl_vector_complex_alloc(N_f);
gsl_complex Z,Z_scaled,val;
gsl_matrix_complex *P = gsl_matrix_complex_alloc(M_i,M_i);
gsl_matrix_complex *Y2_1 = gsl_matrix_complex_alloc(M_i,M_i); // y1_0
gsl_matrix_complex *Y1_2 = gsl_matrix_complex_alloc(M_i,M_i); // y0_1
gsl_vector_complex *y0_1 = gsl_vector_complex_alloc(N_f);
gsl_vector_complex *y1_0 = gsl_vector_complex_alloc(N_f);
gsl_matrix_complex *Y_P_res = gsl_matrix_complex_alloc(N_RRUs,N_RRUs);
gsl_eigen_hermv_workspace *w = gsl_eigen_hermv_alloc(N_RRUs);
gsl_vector *Y_P_eigenvalues = gsl_vector_alloc(N_RRUs);
gsl_matrix_complex *Y_P_eigenvectors = gsl_matrix_complex_alloc(N_RRUs,N_RRUs);
gsl_vector_complex *F_inv_est = gsl_vector_complex_alloc(N_RRUs);
gsl_matrix_complex *F = gsl_matrix_complex_alloc(N_RRUs,N_f);
for (d_f=0; d_f<N_f; d_f++) {
GSL_SET_COMPLEX(&Z,ul_ref_sigs_rx[0][0][23][d_f<<1],ul_ref_sigs_rx[0][0][23][1+(d_f<<1)]);
Z_scaled = gsl_complex_div_real(Z,x);
gsl_vector_complex_set(drsseq0,d_f,Z_scaled);
//printf(" pilots(%d) : %g %gi \n", d_f, GSL_REAL(gsl_vector_complex_get(drsseq0,d_f)), GSL_IMAG(gsl_vector_complex_get(drsseq0,d_f)));
/*
GSL_SET_COMPLEX(&Z,calibration->rxdataF_calib[0][0][1][d_f<<1], calibration->rxdataF_calib[0][0][1][1+(d_f<<1)]);
gsl_vector_complex_set(y0_1,d_f,Z);
//printf(" y0_1(%d) : %g %gi \n", d_f, GSL_REAL(gsl_vector_complex_get(y0_1,d_f)), GSL_IMAG(gsl_vector_complex_get(y0_1,d_f)));
GSL_SET_COMPLEX(&Z,calibration->rxdataF_calib[0][1][0][d_f<<1], calibration->rxdataF_calib[0][1][0][1+(d_f<<1)]);
gsl_vector_complex_set(y1_0,d_f,Z);
*/
//GSL_SET_COMPLEX(&Z,calib_data[0][0][1][d_f<<1], calib_data[0][0][1][1+(d_f<<1)]);
GSL_SET_COMPLEX(&Z,((int16_t*)&calib_data[0][0][1])[d_f],((int16_t*)&calib_data[0][0][1])[d_f+1]);
gsl_vector_complex_set(y0_1,d_f,Z);
//printf(" y0_1(%d) : %g %gi \n", d_f, GSL_REAL(gsl_vector_complex_get(y0_1,d_f)), GSL_IMAG(gsl_vector_complex_get(y0_1,d_f)));
//GSL_SET_COMPLEX(&Z,calib_data[0][1][0][d_f<<1], calib_data[0][1][0][1+(d_f<<1)]);
GSL_SET_COMPLEX(&Z,((int16_t*)&calib_data[0][1][0])[d_f],((int16_t*)&calib_data[0][1][0])[d_f+1]);
gsl_vector_complex_set(y1_0,d_f,Z);
//printf(" y1_0(%d) : %g %gi \n", d_f, GSL_REAL(gsl_vector_complex_get(y1_0,d_f)), GSL_IMAG(gsl_vector_complex_get(y1_0,d_f)));
}
//printf("RRU %d, y0_1(10) : %g %gi \n", ru->idx, GSL_REAL(gsl_vector_complex_get(y0_1,10)), GSL_IMAG(gsl_vector_complex_get(y0_1,10)));
//printf("RRU %d, y1_0(10) : %g %gi \n", ru->idx, GSL_REAL(gsl_vector_complex_get(y1_0,10)), GSL_IMAG(gsl_vector_complex_get(y1_0,10)));
for (int d_f=0; d_f<N_f; d_f++){
gsl_matrix_complex_set(P,0,0,gsl_vector_complex_get(drsseq0,d_f));
gsl_matrix_complex_set(Y2_1,0,0,gsl_vector_complex_get(y1_0,d_f));
gsl_matrix_complex_set(Y1_2,0,0,gsl_vector_complex_get(y0_1,d_f));
//LOG_I(PHY,"M_i %d, d_f %d, Y2_1->size1 %lu\n",M_i,d_f,Y2_1->size1);
gsl_matrix_complex *AB = gsl_matrix_complex_alloc(Y2_1->size2*P->size2,Y2_1->size1); // result from first khatri rao
gsl_matrix_complex *AB1 = gsl_matrix_complex_alloc(Y1_2->size2*P->size2,Y1_2->size1); // // result from second khatri rao
gsl_matrix_complex *Y_P = gsl_matrix_complex_alloc(AB->size1,N_RRUs);
gsl_vector_complex *P_trans_col_vec = gsl_vector_complex_alloc(P->size2);
gsl_matrix_complex *P_trans_col = gsl_matrix_complex_alloc(P->size2,1);
gsl_vector_complex *Y2_1_trans_col_vec = gsl_vector_complex_alloc(Y2_1->size2);
gsl_matrix_complex *Y2_1_trans_col = gsl_matrix_complex_alloc(Y2_1->size2,1);
gsl_vector_complex *Y1_2_trans_col_vec = gsl_vector_complex_alloc(Y1_2->size2);
gsl_matrix_complex *Y1_2_trans_col = gsl_matrix_complex_alloc(Y1_2->size2,1);
gsl_matrix_complex *ab = gsl_matrix_complex_alloc(P_trans_col->size1, Y2_1_trans_col->size1);
gsl_matrix_complex *ab1 = gsl_matrix_complex_alloc(Y1_2_trans_col->size1, P_trans_col->size1);
gsl_vector_complex *AB_col = gsl_vector_complex_alloc(AB->size1);
gsl_vector_complex *AB1_col = gsl_vector_complex_alloc(AB1->size1);
for (int i=0; i<Y2_1->size1; i++){
gsl_matrix_complex_get_row (P_trans_col_vec,P,i);
gsl_matrix_complex_set_col(P_trans_col,0,P_trans_col_vec);
gsl_matrix_complex_get_row (Y2_1_trans_col_vec,Y2_1,i);
gsl_matrix_complex_set_col(Y2_1_trans_col,0,Y2_1_trans_col_vec);
gsl_blas_zgemm(CblasNoTrans, CblasTrans, GSL_COMPLEX_ONE, P_trans_col, Y2_1_trans_col, GSL_COMPLEX_ZERO, ab);
int k = 0;
int m = 0;
while(k<AB->size1){
int l = 0;
while(l<ab->size1){
gsl_matrix_complex_set(AB,k,i,gsl_matrix_complex_get(ab,l,m));
k++;
l++;
}
m++;
}
gsl_matrix_complex_get_row (Y1_2_trans_col_vec,Y1_2,i);
gsl_matrix_complex_set_col(Y1_2_trans_col,0,Y1_2_trans_col_vec);
gsl_blas_zgemm(CblasNoTrans, CblasTrans, GSL_COMPLEX_ONE, Y1_2_trans_col, P_trans_col, GSL_COMPLEX_ZERO, ab1);
k = 0;
m = 0;
while(k<AB1->size1){
int l = 0;
while(l<ab1->size1){
gsl_matrix_complex_set(AB1,k,i,gsl_complex_mul_real(gsl_matrix_complex_get(ab1,l,m),y));
k++;
l++;
}
m++;
}
} // end for i
gsl_matrix_complex_get_col (AB_col,AB,0);
gsl_matrix_complex_set_col(Y_P,0,AB_col);
gsl_matrix_complex_get_col (AB1_col,AB1,0);
gsl_matrix_complex_set_col(Y_P,1,AB1_col);
gsl_blas_zgemm(CblasConjTrans, CblasNoTrans,
GSL_COMPLEX_ONE, Y_P, Y_P,
GSL_COMPLEX_ZERO, Y_P_res);
//printf("\n \n Y_P_res for d_f %d is: \n",d_f);
//display_mat(Y_P_res);
gsl_eigen_hermv(Y_P_res, Y_P_eigenvalues, Y_P_eigenvectors, w);
//printf("\n eigenvalues are : %f, %f\n",gsl_vector_get(Y_P_eigenvalues,0),gsl_vector_get(Y_P_eigenvalues,1));
//printf("\n \n eigenvector for d_f %d is: \n",d_f);
//display_mat(Y_P_eigenvectors);
int min_eigenindex = gsl_vector_min_index(Y_P_eigenvalues); // returns the index of the minimum value in the vector Y_P_eigenvalues
//printf(" Minimum eigenindex is %d\n",min_eigenindex);
gsl_matrix_complex_get_col (F_inv_est,Y_P_eigenvectors,min_eigenindex);
gsl_complex set_to_unit;
GSL_SET_COMPLEX(&set_to_unit,1,0);
gsl_vector_complex_set(F_inv_est,0,set_to_unit);
//for (int i=0;i<N_RRUs;i++) {
//printf(" F_inv_est(%d) : %g %gi \n",i, GSL_REAL(gsl_vector_complex_get(F_inv_est,i)), GSL_IMAG(gsl_vector_complex_get(F_inv_est,i)));
//}
gsl_matrix_complex_set_col(F,d_f,F_inv_est);
//printf("\n \n Calibration matrix(%d) : \n",d_f);
//display_mat(F);
//calibration->calib_coeffs[0][0][d_f] = gsl_matrix_complex_get(F,0,d_f);
//convert it back to fixed point
for (int k=0; k<F->size1; k++) {
if (k==0) {
//LOG_I(PHY,"[1) calib_thread[%d]] common_vars->calib_coeffs[%d] = %p \n",d_f,k,common_vars->calib_coeffs[k]);
// ((int16_t*)&RC.eNB[0][0]->common_vars.calib_coeffs[k])[d_f] = FLOAT2FIXED(1);
// ((int16_t*)&RC.eNB[0][0]->common_vars.calib_coeffs[k])[d_f+1] = FLOAT2FIXED(0);
common_vars->calib_coeffs[k][d_f] = FLOAT2FIXED(1);
common_vars->calib_coeffs[k][d_f+1] = FLOAT2FIXED(0);
//LOG_I(PHY,"[2) calib_thread[%d]] common_vars->calib_coeffs[%d] = %p \n",d_f,k,common_vars->calib_coeffs[k]);
//((int16_t*)&calib_coeffs[0][k])[d_f] = FLOAT2FIXED(1);
//((int16_t*)&calib_coeffs[0][k])[d_f+1] = FLOAT2FIXED(0);
} else {
//LOG_I(PHY,"[3) calib_thread[%d]] common_vars->calib_coeffs[%d] = %p \n",d_f,k,common_vars->calib_coeffs[k]);
val = gsl_matrix_complex_get(F,k,d_f);
//((int16_t*)&RC.eNB[0][0]->common_vars.calib_coeffs[k])[d_f] = FLOAT2FIXED(GSL_REAL(val));
//((int16_t*)&RC.eNB[0][0]->common_vars.calib_coeffs[k])[d_f+1] = FLOAT2FIXED(GSL_IMAG(val));
common_vars->calib_coeffs[k][d_f] = FLOAT2FIXED(GSL_REAL(val));
common_vars->calib_coeffs[k][d_f+1] = FLOAT2FIXED(GSL_IMAG(val));
//LOG_I(PHY,"[4) calib_thread[%d]] common_vars->calib_coeffs[%d] = %p \n",d_f,k,common_vars->calib_coeffs[k]);
//((int16_t*)calib_coeffs[0][k])[d_f] = FLOAT2FIXED(GSL_REAL(val));
//((int16_t*)calib_coeffs[0][k])[d_f+1] = FLOAT2FIXED(GSL_IMAG(val));
}
//LOG_I(PHY," gsl F[%d][%d] : %g %gi \n", k,d_f,GSL_REAL(val), GSL_IMAG(val));
/*
if (d_f==597 || d_f==598){
LOG_I(PHY,"calib_thread : calib_coeffs[%d][%d] : %d %d i\n",k,d_f,common_vars->calib_coeffs[k][d_f],common_vars->calib_coeffs[k][d_f+1]);
}
*/
}
gsl_matrix_complex_free(AB);
gsl_matrix_complex_free(AB1);
gsl_matrix_complex_free(Y_P);
gsl_vector_complex_free(P_trans_col_vec);
gsl_matrix_complex_free(P_trans_col);
gsl_vector_complex_free(Y2_1_trans_col_vec);
gsl_matrix_complex_free(Y2_1_trans_col);
gsl_vector_complex_free(Y1_2_trans_col_vec);
gsl_matrix_complex_free(Y1_2_trans_col);
gsl_matrix_complex_free(ab);
gsl_matrix_complex_free(ab1);
gsl_vector_complex_free(AB_col);
gsl_vector_complex_free(AB1_col);
} // end for d_f
//LOG_I(PHY,"[calib_thread] common_vars->calib_coeffs[%d] = %p \n",ru->idx,common_vars->calib_coeffs[ru->idx]);
calibration->instance_cnt_calib = -2;
RC.eNB[0][0]->calib_prec_enabled = 1;
gsl_vector_complex_free(drsseq0);
gsl_matrix_complex_free(P);
gsl_matrix_complex_free(Y2_1);
gsl_matrix_complex_free(Y1_2);
gsl_vector_complex_free(y0_1);
gsl_vector_complex_free(y1_0);
gsl_matrix_complex_free(Y_P_res);
gsl_eigen_hermv_free(w);
gsl_vector_free(Y_P_eigenvalues);
gsl_matrix_complex_free(Y_P_eigenvectors);
gsl_vector_complex_free(F_inv_est);
gsl_matrix_complex_free(F);
} // end while
printf( "Exiting calib_thread \n");
return NULL;
//return(0);
}
static void *ru_thread( void *param ) {
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
@@ -1757,7 +2184,6 @@ static void *ru_thread( void *param ) {
pthread_cond_signal(&proc->cond_asynch_rxtx);
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_asynch_rxtx))==0,"mutex_unlock returns %d\n",ret);
} else LOG_D(PHY,"RU %d no asynch_south interface\n",ru->idx);
// if this is a slave RRU, try to synchronize on the DL frequency
if ((ru->is_slave == 1) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
@@ -1975,23 +2401,22 @@ void *ru_thread_synch(void *arg) {
// if we're not in synch, then run initial synch
if (ru->in_synch == 0) {
// run intial synch like UE
LOG_I(PHY,"Running initial synchronization\n");
LOG_D(PHY,"Running initial synchronization\n");
ru->rx_offset = ru_sync_time(ru,
&peak_val,
&avg);
LOG_I(PHY,"RU synch cnt %d: %d, val %llu (%d dB,%d dB)\n",cnt,ru->rx_offset,(unsigned long long)peak_val,dB_fixed64(peak_val),dB_fixed64(avg));
cnt++;
//if (/*ru->rx_offset >= 0*/dB_fixed(peak_val)>=85 && cnt>10) {
if (ru->rx_offset >= 0 && avg>0 && dB_fixed(peak_val/avg)>=15 && cnt>10) {
LOG_I(PHY,"Estimated peak_val %d dB, avg %d => timing offset %llu\n",dB_fixed(peak_val),dB_fixed(avg),(unsigned long long int)ru->rx_offset);
ru->in_synch = 1;
/*
LOG_M("ru_sync_rx.m","rurx",&ru->common.rxdata[0][0],LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,1);
LOG_M("ru_sync_corr.m","sync_corr",ru->dmrs_corr,LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,6);
LOG_M("ru_dmrs.m","rudmrs",&ru->dmrssync[0],fp->ofdm_symbol_size,1,1);
*/
//exit(-1);
LOG_I(PHY,"Estimated peak_val %d dB, avg %d => timing offset %llu\n",dB_fixed(peak_val),dB_fixed(avg),(unsigned long long int)ru->rx_offset);
ru->in_synch = 1;
/*
LOG_M("ru_sync_rx.m","rurx",&ru->common.rxdata[0][0],LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,1);
LOG_M("ru_sync_corr.m","sync_corr",ru->dmrs_corr,LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,6);
LOG_M("ru_dmrs.m","rudmrs",&ru->dmrssync[0],fp->ofdm_symbol_size,1,1);
exit(-1);
*/
} // sync_pos > 0
else { //AssertFatal(cnt<1000,"Cannot find synch reference\n");
if (cnt>200) {
@@ -2230,14 +2655,17 @@ void reset_proc(RU_t *ru) {
void init_RU_proc(RU_t *ru) {
int i=0, ret;
RU_proc_t *proc;
pthread_attr_t *attr_FH=NULL, *attr_FH1=NULL, *attr_prach=NULL, *attr_asynch=NULL, *attr_synch=NULL, *attr_emulateRF=NULL, *attr_ctrl=NULL, *attr_prach_br=NULL;
RU_CALIBRATION *calibration;
pthread_attr_t *attr_FH=NULL, *attr_FH1=NULL, *attr_prach=NULL, *attr_asynch=NULL, *attr_synch=NULL, *attr_emulateRF=NULL, *attr_ctrl=NULL, *attr_prach_br=NULL, *attr_calib=NULL;
//pthread_attr_t *attr_fep=NULL;
#ifndef OCP_FRAMEWORK
LOG_I(PHY,"Initializing RU proc %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]);
#endif
proc = &ru->proc;
calibration = &ru->calibration;
memset((void *)proc,0,sizeof(RU_proc_t));
proc->ru = ru;
calibration->instance_cnt_calib = -1;
proc->instance_cnt_prach = -1;
proc->instance_cnt_synch = -1;
proc->instance_cnt_FH = -1;
@@ -2254,6 +2682,7 @@ void init_RU_proc(RU_t *ru) {
for (i=0; i<10; i++) proc->symbol_mask[i]=0;
pthread_mutex_init( &calibration->mutex_calib, NULL);
pthread_mutex_init( &proc->mutex_prach, NULL);
pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
pthread_mutex_init( &proc->mutex_synch,NULL);
@@ -2290,6 +2719,7 @@ void init_RU_proc(RU_t *ru) {
pthread_cond_init( &proc->cond_rf_tx, NULL);
#endif
#ifndef DEADLINE_SCHEDULER
attr_calib = &calibration->attr_calib;
attr_FH = &proc->attr_FH;
attr_FH1 = &proc->attr_FH1;
attr_prach = &proc->attr_prach;
@@ -2301,6 +2731,7 @@ void init_RU_proc(RU_t *ru) {
if (ru->function!=eNodeB_3GPP) pthread_create( &proc->pthread_ctrl, attr_ctrl, ru_thread_control, (void *)ru );
pthread_create( &calibration->pthread_calib, attr_calib, calib_thread, (void *)ru );
pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void *)ru );
#if defined(PRE_SCD_THREAD)
proc->instance_pre_scd = -1;
@@ -2330,8 +2761,6 @@ void init_RU_proc(RU_t *ru) {
if ((ru->if_timing == synch_to_other) || (ru->function == NGFI_RRU_IF5) || (ru->function == NGFI_RRU_IF4p5)) {
LOG_I(PHY,"Starting ru_thread_asynch_rxtx, ru->is_slave %d, ru->generate_dmrs_sync %d\n",
ru->is_slave,ru->generate_dmrs_sync);
//generate_ul_ref_sigs();
//ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms.ofdm_symbol_size*2*sizeof(int16_t));
pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, ru_thread_asynch_rxtx, (void *)ru );
}
} else if (ru->function == eNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF
@@ -2371,6 +2800,7 @@ void init_RU_proc(RU_t *ru) {
void kill_RU_proc(RU_t *ru) {
int ret;
RU_proc_t *proc = &ru->proc;
RU_CALIBRATION *calibration = &ru->calibration;
#if defined(PRE_SCD_THREAD)
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_pre_scd))==0,"mutex_lock returns %d\n",ret);
ru->proc.instance_pre_scd = 0;
@@ -2408,6 +2838,10 @@ void kill_RU_proc(RU_t *ru) {
proc->instance_cnt_FH = 0;
pthread_cond_signal(&proc->cond_FH);
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_FH))==0,"mutex_unlock returns %d\n",ret);
AssertFatal((ret=pthread_mutex_lock(&calibration->mutex_calib))==0,"mutex_lock returns %d\n",ret);
calibration->instance_cnt_calib = 0;
pthread_cond_signal(&calibration->cond_calib);
AssertFatal((ret=pthread_mutex_unlock(&calibration->mutex_calib))==0,"mutex_unlock returns %d\n",ret);
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_FH1))==0,"mutex_lock returns %d\n",ret);
proc->instance_cnt_FH1 = 0;
pthread_cond_signal(&proc->cond_FH1);
@@ -2714,12 +3148,16 @@ void init_RU(char *rf_config_file, clock_source_t clock_source, clock_source_t t
// NOTE: multiple CC_id are not handled here yet!
ru->openair0_cfg.clock_source = clock_source;
ru->openair0_cfg.time_source = time_source;
//ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0;
if ((ru->is_slave == 0) && (ru->ota_sync_enable == 1))
ru->generate_dmrs_sync = 1;
else
ru->generate_dmrs_sync = 0;
//if ((ru->is_slave == 0) && (ru->ota_sync_enable == 1)) {
ru->generate_dmrs_sync = 1;
generate_ul_ref_sigs();
//ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms.ofdm_symbol_size*2*sizeof(int16_t));
//}
//else{
// ru->generate_dmrs_sync = 0;
//}
ru->wakeup_L1_sleeptime = 2000;
ru->wakeup_L1_sleep_cnt_max = 3;

View File

@@ -121,8 +121,9 @@ int send_config(RU_t *ru,
rru_config_msg.type = RRU_config;
rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t);
LOG_I(PHY,"Sending Configuration to RRU %d (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d\n",
ru->idx,
LOG_I(PHY,"Sending Configuration to RRU %d (RRU p %d,RRU tag %d,num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d\n",ru->idx,
((RRU_config_t *)&rru_config_msg.msg[0])->p,
((RRU_config_t *)&rru_config_msg.msg[0])->tag,
((RRU_config_t *)&rru_config_msg.msg[0])->num_bands,
((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0],
((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0],
@@ -229,7 +230,9 @@ int attach_rru(RU_t *ru)
rru_config_msg.type = RRU_config;
rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t);
LOG_I(PHY,"Sending Configuration to RRU %d (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n",ru->idx,
LOG_I(PHY,"Sending Configuration to RRU %d (RRU p %d,RRU tag %d,num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n",ru->idx,
((RRU_config_t *)&rru_config_msg.msg[0])->p,
((RRU_config_t *)&rru_config_msg.msg[0])->tag,
((RRU_config_t *)&rru_config_msg.msg[0])->num_bands,
((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0],
((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0],
@@ -322,7 +325,9 @@ int connect_rau(RU_t *ru)
LOG_I(PHY,"Waiting for configuration from RAU\n");
}
else {
LOG_I(PHY,"Configuration received from RAU (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n",
LOG_I(PHY,"Configuration received from RAU (RRU p %d,RRU tag %d,num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n",
((RRU_config_t *)&rru_config_msg.msg[0])->p,
((RRU_config_t *)&rru_config_msg.msg[0])->tag,
((RRU_config_t *)&rru_config_msg.msg[0])->num_bands,
((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0],
((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0],
@@ -422,6 +427,8 @@ void configure_ru(int idx,
config->N_RB_DL[0] = ru->frame_parms->N_RB_DL;
config->N_RB_UL[0] = ru->frame_parms->N_RB_UL;
config->threequarter_fs[0] = ru->frame_parms->threequarter_fs;
config->tag = idx;
config->p = RC.nb_RU;
if (ru->if_south==REMOTE_IF4p5) {
config->prach_FreqOffset[0] = ru->frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset;
config->prach_ConfigIndex[0] = ru->frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
@@ -444,16 +451,18 @@ void configure_rru(int idx,
void *arg)
{
RRU_config_t *config = (RRU_config_t *)arg;
RU_t *ru = RC.ru[idx];
RU_t *ru = RC.ru[idx];
ru->tag = config->tag;
ru->p = config->p;
ru->frame_parms->eutra_band = config->band_list[0];
ru->frame_parms->dl_CarrierFreq = config->tx_freq[0];
ru->frame_parms->ul_CarrierFreq = config->rx_freq[0];
if (ru->frame_parms->dl_CarrierFreq == ru->frame_parms->ul_CarrierFreq) {
LOG_I(PHY,"Setting RRU to TDD frame type\n");
LOG_I(PHY,"Setting RRU to TDD frame type\n");
ru->frame_parms->frame_type = TDD;
ru->frame_parms->tdd_config = config->tdd_config[0];
ru->frame_parms->tdd_config_S = config->tdd_config_S[0];
ru->frame_parms->tdd_config_S = config->tdd_config_S[0];
}
else ru->frame_parms->frame_type = FDD;
@@ -589,7 +598,9 @@ void* ru_thread_control( void* param )
case RRU_config: // RRU
if (ru->if_south == LOCAL_RF){
LOG_I(PHY,"Configuration received from RAU (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n",
LOG_I(PHY,"Configuration received from RAU (p %d, tag %d, num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n",
((RRU_config_t *)&rru_config_msg.msg[0])->p,
((RRU_config_t *)&rru_config_msg.msg[0])->tag,
((RRU_config_t *)&rru_config_msg.msg[0])->num_bands,
((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0],
((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0],