diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index e4386c8fdfe479d8044b1b0dd31ea2bbc5eb826d..3b3f277894187d06427dc1090b728c1a172c6235 100755 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -170,8 +170,6 @@ typedef enum { synch_to_other // synch to another source (timer, other CC_id) } eNB_timing_t; - - typedef struct UE_SCAN_INFO_s { /// 10 best amplitudes (linear) for each pss signals int32_t amp[3][10]; @@ -810,11 +808,4 @@ typedef struct { #include "SIMULATION/ETH_TRANSPORT/defs.h" #endif //OPENAIR_LTE - #endif // __PHY_DEFS__H__ - - - - - - diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 43edfa807d4a6505643e4d83066b2ed8f2c524d0..8eeaa64a673dd2091f7085733823ebd0c762539a 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -2517,31 +2517,29 @@ void cba_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_p void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_flag) { - int i,l; + int l; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; eNB_proc_t *proc = &eNB->proc; - int subframe = proc->subframe_rx; - int frame = proc->frame_rx; + + const int subframe = proc->subframe_rx; + const int frame = proc->frame_rx; uint8_t seqno=0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 1 ); - - start_meas(&eNB->phy_proc_rx); #ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",eNB->Mod_id,frame, subframe); + LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_common_RX(%d)\n",eNB->Mod_id,frame,subframe); #endif - if (abstraction_flag==0) { // grab signal in chunks of 500 us (1 slot) - + if (abstraction_flag==0) { if ((eNB->node_function == NGFI_RRU_IF4) || - (eNB->node_function == eNodeB_3GPP) || - (eNB->node_function == eNodeB_3GPP_BBU)) { // front-end processing + (eNB->node_function == eNodeB_3GPP) || + (eNB->node_function == eNodeB_3GPP_BBU)) { // front-end processing // now do common RX processing for first slot in subframe VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,1); @@ -2564,7 +2562,6 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl ); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,0); if (eNB->node_function == NGFI_RRU_IF4) { @@ -2572,10 +2569,7 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 ); send_IF4(eNB, proc->frame_rx, proc->subframe_rx, IF4_PULFFT, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 ); - - } - - + } } else if (eNB->node_function == NGFI_RRU_IF5) { /// **** send_IF5 of rxdata to BBU **** /// @@ -2587,12 +2581,12 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl /// **** send_IF4 of prach to RCC **** /// done in prach thread (below) // check if we have to detect PRACH first if ((eNB->node_function != NGFI_RRU_IF5) && - (is_prach_subframe(fp,proc->frame_rx,proc->subframe_rx)>0)) { // any other node must call prach procedure + (is_prach_subframe(fp,proc->frame_rx,proc->subframe_rx)>0)) { // any other node must call prach procedure // wake up thread for PRACH RX if (pthread_mutex_lock(&proc->mutex_prach) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->instance_cnt_prach ); - exit_fun( "error locking mutex_prach" ); - return; + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->instance_cnt_prach ); + exit_fun( "error locking mutex_prach" ); + return; } int cnt_prach = ++proc->instance_cnt_prach; @@ -2603,18 +2597,19 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl pthread_mutex_unlock( &proc->mutex_prach ); if (cnt_prach == 0) { - // the thread was presumably waiting where it should and can now be woken up - if (pthread_cond_signal(&proc->cond_prach) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index); - exit_fun( "ERROR pthread_cond_signal" ); - return; - } + // the thread was presumably waiting where it should and can now be woken up + if (pthread_cond_signal(&proc->cond_prach) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index); + exit_fun( "ERROR pthread_cond_signal" ); + return; + } } else { - LOG_W( PHY,"[eNB] Frame %d Subframe %d, eNB PRACH thread busy (IC %d)!!\n", proc->frame_rx,proc->subframe_rx,cnt_prach); - exit_fun( "PRACH thread busy" ); - return; + LOG_W( PHY,"[eNB] Frame %d Subframe %d, eNB PRACH thread busy (IC %d)!!\n", proc->frame_rx,proc->subframe_rx,cnt_prach); + exit_fun( "PRACH thread busy" ); + return; } } + } else { // grab transport channel information from network interface } @@ -2641,7 +2636,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 1 ); start_meas(&eNB->phy_proc_rx); #ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",eNB->Mod_id,frame, subframe); + LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_uespec_RX(%d)\n",eNB->Mod_id,frame, subframe); #endif T(T_ENB_PHY_UL_TICK, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe)); diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index c1de6a79350a883032edec18984d250d1ba1ce24..35d02f8842e80e4d566198a03759f9c4dd4a1ea1 100755 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -74,7 +74,8 @@ #define ENB_CONFIG_STRING_COMPONENT_CARRIERS "component_carriers" #define ENB_CONFIG_STRING_CC_NODE_FUNCTION "node_function" -#define ENB_CONFIG_STRING_CC_NODE_TIMING "node_timing" +#define ENB_CONFIG_STRING_CC_NODE_TIMING "node_timing" +#define ENB_CONFIG_STRING_CC_NODE_SYNCH_REF "node_synch_ref" #define ENB_CONFIG_STRING_FRAME_TYPE "frame_type" #define ENB_CONFIG_STRING_TDD_CONFIG "tdd_config" @@ -303,25 +304,26 @@ void enb_config_display(void) printf( "\tiq_txshift : \t%d:\n",enb_properties.properties[i]->rrh_gw_config[j].iq_txshift); printf( "\ttransport : \t%s Ethernet:\n",(enb_properties.properties[i]->rrh_gw_config[j].raw == 1)? "RAW" : (enb_properties.properties[i]->rrh_gw_config[j].rawif4 == 1)? "RAW_IF4" : (enb_properties.properties[i]->rrh_gw_config[j].udpif4 == 1)? "UDP_IF4" : (enb_properties.properties[i]->rrh_gw_config[j].rawif5_mobipass == 1)? "RAW_IF5_MOBIPASS" : "UDP"); if (enb_properties.properties[i]->rrh_gw_config[j].exmimo == 1) { - printf( "\tRF target : \tEXMIMO:\n\n"); + printf( "\tRF target : \tEXMIMO:\n"); } else if (enb_properties.properties[i]->rrh_gw_config[j].usrp_b200 == 1) { - printf( "\tRF target : \tUSRP_B200:\n\n"); + printf( "\tRF target : \tUSRP_B200:\n"); } else if (enb_properties.properties[i]->rrh_gw_config[j].usrp_x300 == 1) { - printf( "\tRF target : \tUSRP_X300:\n\n"); + printf( "\tRF target : \tUSRP_X300:\n"); } else if (enb_properties.properties[i]->rrh_gw_config[j].bladerf == 1) { - printf( "\tRF target : \tBLADERF:\n\n"); + printf( "\tRF target : \tBLADERF:\n"); } else if (enb_properties.properties[i]->rrh_gw_config[j].lmssdr == 1) { - printf( "\tRF target : \tLMSSDR:\n\n"); + printf( "\tRF target : \tLMSSDR:\n"); } else { - printf( "\tRF target : \tNONE:\n\n"); + printf( "\tRF target : \tNONE:\n"); } } } for (j=0; j< enb_properties.properties[i]->nb_cc; j++) { // CC_ID node function/timing - printf( "\tnode_function for CC %d:\t%d:\n",j,enb_properties.properties[i]->cc_node_function[j]); - printf( "\tnode_timing for CC %d:\t%d:\n",j,enb_properties.properties[i]->cc_node_timing[j]); + printf( "\n\tnode_function for CC %d: \t%d:\n",j,enb_properties.properties[i]->cc_node_function[j]); + printf( "\tnode_timing for CC %d: \t%d:\n",j,enb_properties.properties[i]->cc_node_timing[j]); + printf( "\tnode_synch_ref for CC %d: \t%d:\n",j,enb_properties.properties[i]->cc_node_synch_ref[j]); printf( "\teutra band for CC %d: \t%"PRId16":\n",j,enb_properties.properties[i]->eutra_band[j]); printf( "\tdownlink freq for CC %d: \t%"PRIu64":\n",j,enb_properties.properties[i]->downlink_frequency[j]); @@ -416,17 +418,17 @@ void enb_config_display(void) printf( "\tue_TimersAndConstants_t310 for CC %d:\t%ld:\n",j,enb_properties.properties[i]->ue_TimersAndConstants_t310[j]); printf( "\tue_TimersAndConstants_n310 for CC %d:\t%ld:\n",j,enb_properties.properties[i]->ue_TimersAndConstants_n310[j]); printf( "\tue_TimersAndConstants_t311 for CC %d:\t%ld:\n",j,enb_properties.properties[i]->ue_TimersAndConstants_t311[j]); - printf( "\tue_TimersAndConstants_n311 for CC %d:\t%ld:\n\n",j,enb_properties.properties[i]->ue_TimersAndConstants_n311[j]); + printf( "\tue_TimersAndConstants_n311 for CC %d:\t%ld:\n",j,enb_properties.properties[i]->ue_TimersAndConstants_n311[j]); } for (j=0; j < enb_properties.properties[i]->num_otg_elements; j++) { - printf( "\tOTG Destination UE ID: \t%"PRIu16, enb_properties.properties[i]->otg_ue_id[j]); + printf( "\n\tOTG Destination UE ID: \t%"PRIu16, enb_properties.properties[i]->otg_ue_id[j]); printf( "\n\tOTG App Type: \t%"PRIu8, enb_properties.properties[i]->otg_app_type[j]); printf( "\n\tOTG Background Traffic: \t%s\n", (enb_properties.properties[i]->otg_bg_traffic[j]==1) ? "Enabled" : "Disabled"); } - printf( "\tGlobal log level: \t%s\n", map_int_to_str(log_level_names,enb_properties.properties[i]->glog_level)); + printf( "\n\tGlobal log level: \t%s\n", map_int_to_str(log_level_names,enb_properties.properties[i]->glog_level)); printf( "\tHW log level: \t%s\n", map_int_to_str(log_level_names,enb_properties.properties[i]->hw_log_level)); printf( "\tPHY log level: \t%s\n", map_int_to_str(log_level_names,enb_properties.properties[i]->phy_log_level)); printf( "\tMAC log level: \t%s\n", map_int_to_str(log_level_names,enb_properties.properties[i]->mac_log_level)); @@ -521,6 +523,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) const char* cc_node_function = NULL; const char* cc_node_timing = NULL; + int cc_node_synch_ref = 0; const char* cell_type = NULL; const char* tac = 0; @@ -800,6 +803,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) //printf("Component carrier %d\n",component_carrier); if (!(config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_CC_NODE_FUNCTION, &cc_node_function) && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_CC_NODE_TIMING, &cc_node_timing) + && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_CC_NODE_SYNCH_REF, &cc_node_synch_ref) && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_FRAME_TYPE, &frame_type) && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_TDD_CONFIG, &tdd_config) && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_TDD_CONFIG_S, &tdd_config_s) @@ -894,9 +898,9 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) lib_config_file_name_pP, i, cc_node_function); } - if (strcmp(cc_node_timing, "SYNCH_TO_DEVICE") == 0) { + if (strcmp(cc_node_timing, "synch_to_ext_device") == 0) { enb_properties.properties[enb_properties_index]->cc_node_timing[j] = synch_to_ext_device; - } else if (strcmp(cc_node_timing, "SYNCH_TO_OTHER") == 0) { + } else if (strcmp(cc_node_timing, "synch_to_other") == 0) { enb_properties.properties[enb_properties_index]->cc_node_timing[j] = synch_to_other; } else { AssertError (0, parse_errors ++, @@ -904,6 +908,14 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) lib_config_file_name_pP, i, cc_node_timing); } + if ((cc_node_synch_ref >= -1) && (cc_node_synch_ref < num_component_carriers)) { + enb_properties.properties[enb_properties_index]->cc_node_synch_ref[j] = (int16_t) cc_node_synch_ref; + } else { + AssertError (0, parse_errors ++, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for node_synch_ref choice: valid CC_id or -1 !\n", + lib_config_file_name_pP, i, cc_node_synch_ref); + } + enb_properties.properties[enb_properties_index]->tdd_config[j] = tdd_config; AssertError (tdd_config <= TDD_Config__subframeAssignment_sa6, parse_errors ++, "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!", diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index 3feeb5e8280d2197579ec244267e6cebf66ae68c..6a8483c3d06ca058f70b75d1b5861b2581783103 100755 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -132,6 +132,7 @@ typedef struct Enb_properties_s { int16_t nb_cc; eNB_func_t cc_node_function[1+MAX_NUM_CCs]; eNB_timing_t cc_node_timing[1+MAX_NUM_CCs]; + int16_t cc_node_synch_ref[1+MAX_NUM_CCs]; lte_frame_type_t frame_type[1+MAX_NUM_CCs]; uint8_t tdd_config[1+MAX_NUM_CCs]; uint8_t tdd_config_s[1+MAX_NUM_CCs]; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index ba7921e4082d678a05c12140b852eb814d25f1ee..2ec507e4c326a1c0542aaa4914f39763e37e2b75 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -157,7 +157,7 @@ static struct { void exit_fun(const char* s); -void init_eNB(eNB_func_t node_function,int nb_inst); +void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[]); void stop_eNB(void); @@ -496,7 +496,7 @@ static void* eNB_thread_rxtx( void* param ) { LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX proc\n"); exit_fun("nothing to add"); break; - } + } } else if (PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF4) { /// **** recv_IF4 of txdataF from RCC **** /// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 ); @@ -604,10 +604,8 @@ static void* eNB_thread_rxtx( void* param ) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); - printf( "Exiting eNB thread RXn_TXnp4\n"); - eNB_thread_rxtx_status = 0; return &eNB_thread_rxtx_status; } @@ -770,7 +768,6 @@ static void* eNB_thread_asynch_rx( void* param ) { prach_rx = 0; do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 ); recv_IF4(eNB, &frame_rx, &subframe_rx, &packet_type, &symbol_number); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 ); @@ -781,10 +778,7 @@ static void* eNB_thread_asynch_rx( void* param ) { } else if (packet_type == IF4_PRACH) { // wake up thread for PRACH RX prach_rx = 1; - } - - - + } } while( (symbol_mask != symbol_mask_full) && (prach_rx == 0)); if (proc->first_rx == 0) { @@ -823,16 +817,12 @@ static void* eNB_thread_FH( void* param ) { int i; int prach_rx; - - uint16_t packet_type; uint32_t symbol_number=0; uint32_t symbol_mask, symbol_mask_full; - int subframe = proc->subframe_rx; - int frame = proc->frame_rx; - - + int subframe=0, frame=0; + wait.tv_sec=0; wait.tv_nsec=5000000L; @@ -983,76 +973,75 @@ static void* eNB_thread_FH( void* param ) { // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices while (!oai_exit) { - if (oai_exit) break; - + if (oai_exit) break; + // This case is for synchronization to another thread if ((eNB->node_timing == synch_to_other) && - ((eNB->node_function == NGFI_RRU_IF4) || - (eNB->node_function == NGFI_RRU_IF5) || - (eNB->node_function == eNodeB_3GPP))) { // This case is for synchronization to another thread + ((eNB->node_function == NGFI_RCC_IF4) || + (eNB->node_function == eNodeB_3GPP_BBU))) { //wait for event // how long should we wait here, for MOBIPASS this could be long // if (pthread_mutex_timedlock(&proc->mutex_FH,&wait) != 0) { if (pthread_mutex_lock(&proc->mutex_FH) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for FH\n"); - exit_fun( "error locking mutex" ); - break; + LOG_E( PHY, "[SCHED][eNB] error locking mutex for FH\n"); + exit_fun( "error locking mutex" ); + break; } while (proc->instance_cnt_FH < 0) { - // most of the time the thread is waiting here - // proc->instance_cnt_prach is -1 - pthread_cond_wait( &proc->cond_FH,&proc->mutex_FH ); // this unlocks mutex_rxtx while waiting and then locks it again - } - + // most of the time the thread is waiting here + // proc->instance_cnt_prach is -1 + pthread_cond_wait( &proc->cond_FH,&proc->mutex_FH ); // this unlocks mutex_rxtx while waiting and then locks it again + } proc->instance_cnt_FH++; - } // Remaining cases are all for synchronization on FH interface else if ((eNB->node_timing == synch_to_ext_device) && - ((eNB->node_function == NGFI_RRU_IF4) || - (eNB->node_function == NGFI_RRU_IF5) || - (eNB->node_function == eNodeB_3GPP))) { // acquisition from RF + ((eNB->node_function == NGFI_RRU_IF4) || + (eNB->node_function == NGFI_RRU_IF5) || + (eNB->node_function == eNodeB_3GPP))) { // acquisition from RF for (i=0; i<fp->nb_antennas_rx; i++) - rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti]; + rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - // sanitycheck if (subframe==9) { - subframe=0; - frame++; - frame&=1023; + subframe=0; + frame++; + frame&=1023; } else { - subframe++; + subframe++; } rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, - &proc->timestamp_rx, - rxp, - fp->samples_per_tti, - fp->nb_antennas_rx); + &proc->timestamp_rx, + rxp, + fp->samples_per_tti, + fp->nb_antennas_rx); + proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - if (proc->first_rx == 0) { - if (proc->subframe_rx != subframe){ + if (proc->subframe_rx != subframe){ LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe); exit_fun("Exiting"); - } + } + if (proc->frame_rx != frame) { - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); - exit_fun("Exiting"); - } + LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); + exit_fun("Exiting"); + } } else { proc->first_rx = 0; + frame = proc->frame_rx; + subframe = proc->subframe_rx; } - // printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); + //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx ); @@ -1065,7 +1054,7 @@ static void* eNB_thread_FH( void* param ) { } // node_timing==synch_to_ext_device && node_function == RRU || eNodeB else if ((eNB->node_timing == synch_to_ext_device) && - (eNB->node_function == eNodeB_3GPP_BBU)) { // acquisition from IF + (eNB->node_function == eNodeB_3GPP_BBU)) { // acquisition from IF /// **** recv_IF5 of rxdata from RRH **** /// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 ); recv_IF5(eNB, &proc->timestamp_rx, proc->subframe_rx, IF5_RRH_GW_UL); @@ -1073,30 +1062,30 @@ static void* eNB_thread_FH( void* param ) { proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - + if (proc->first_rx == 0) { - if (proc->subframe_rx != subframe){ - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe); - //exit_fun("Exiting"); - } - if (proc->frame_rx != frame) { - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); - //exit_fun("Exiting"); - } + if (proc->subframe_rx != subframe){ + LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe); + exit_fun("Exiting"); + } + + if (proc->frame_rx != frame) { + LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); + exit_fun("Exiting"); + } } else { - proc->first_rx = 0; - } + proc->first_rx = 0; + } VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, proc->subframe_rx ); + } // eNodeB_3GPP_BBU && node_timing == synch_to_ext_device - else if ((eNB->node_timing == synch_to_ext_device) && - (eNB->node_function == NGFI_RCC_IF4)) { + (eNB->node_function == NGFI_RCC_IF4)) { /// **** recv_IF4 of rxdataF from RRU **** /// /// **** recv_IF4 of rxsigF from RRU **** /// - // get frame/subframe information from IF4 interface // timed loop (200 us) symbol_number = 0; @@ -1105,7 +1094,6 @@ static void* eNB_thread_FH( void* param ) { prach_rx = 0; do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 ); recv_IF4(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 ); @@ -1116,10 +1104,7 @@ static void* eNB_thread_FH( void* param ) { } else if (packet_type == IF4_PRACH) { // wake up thread for PRACH RX prach_rx = 1; - } - - - + } } while( (symbol_mask != symbol_mask_full) && (prach_rx == 0)); if (proc->first_rx == 0) { @@ -1138,7 +1123,6 @@ static void* eNB_thread_FH( void* param ) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, proc->subframe_rx ); - } // node_timing == synch_to_externs, node_function = NGFI_IF4 else { // should not get here @@ -1152,10 +1136,11 @@ static void* eNB_thread_FH( void* param ) { // wake up slave FH thread // lock the FH mutex and make sure the thread is ready if (pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB CCid %d slave CCid %d (IC %d)\n",proc->CC_id,slave_proc->CC_id); - exit_fun( "error locking mutex_rxtx" ); - break; + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB CCid %d slave CCid %d (IC %d)\n",proc->CC_id,slave_proc->CC_id); + exit_fun( "error locking mutex_rxtx" ); + break; } + int cnt_slave = ++slave_proc->instance_cnt_FH; slave_proc->frame_rx = proc->frame_rx; slave_proc->subframe_rx = proc->subframe_rx; @@ -1164,12 +1149,12 @@ static void* eNB_thread_FH( void* param ) { pthread_mutex_unlock( &slave_proc->mutex_FH ); if (cnt_slave == 0) { - // the thread was presumably waiting where it should and can now be woken up - if (pthread_cond_signal(&slave_proc->cond_FH) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB CCid %d, slave CCid %d\n",proc->CC_id,slave_proc->CC_id); - exit_fun( "ERROR pthread_cond_signal" ); - break; - } + // the thread was presumably waiting where it should and can now be woken up + if (pthread_cond_signal(&slave_proc->cond_FH) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB CCid %d, slave CCid %d\n",proc->CC_id,slave_proc->CC_id); + exit_fun( "ERROR pthread_cond_signal" ); + break; + } } else { LOG_W( PHY,"[eNB] Frame %d, FH CC_id %d thread busy!! (cnt_FH %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave); exit_fun( "FH thread busy" ); @@ -1193,7 +1178,7 @@ static void* eNB_thread_FH( void* param ) { // We have just received and processed the common part of a subframe, say n. // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired // transmitted timestamp of the next TX slot (first). - // The last (TS_rx mod samples_pexr_frame) was n*samples_per_tti, + // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, // we want to generate subframe (n+3), so TS_tx = TX_rx+3*samples_per_tti, // and proc->subframe_tx = proc->subframe_rx+3 proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); @@ -1215,14 +1200,13 @@ static void* eNB_thread_FH( void* param ) { LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, cnt_rxtx ); exit_fun( "TX thread busy" ); break; - } - + } stop_meas( &softmodem_stats_rxtx_sf ); #ifdef DEADLINE_SCHEDULER if (opp_enabled){ - if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime){ - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_RXTX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0); + if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_RXTX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0); } } #endif // DEADLINE_SCHEDULER @@ -1243,7 +1227,6 @@ static void* eNB_thread_FH( void* param ) { } printf( "Exiting FH thread \n"); - eNB_thread_FH_status = 0; return &eNB_thread_FH_status; @@ -1258,8 +1241,6 @@ static void* eNB_thread_FH( void* param ) { static void* eNB_thread_prach( void* param ) { static int eNB_thread_prach_status; - - eNB_proc_t *proc = (eNB_proc_t*)param; PHY_VARS_eNB *eNB= PHY_vars_eNB_g[0][proc->CC_id]; @@ -1406,10 +1387,8 @@ static void* eNB_thread_prach( void* param ) { } } - printf( "Exiting eNB thread PRACH\n"); - eNB_thread_prach_status = 0; return &eNB_thread_prach_status; } @@ -1671,15 +1650,16 @@ void print_opp_meas(void) { } - void init_eNB(eNB_func_t node_function,int nb_inst) { +void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[]) { int CC_id; - int inst; - for (inst=0;inst<nb_inst;inst++) - for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) - PHY_vars_eNB_g[0][CC_id]->node_function = node_function; + + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + PHY_vars_eNB_g[0][CC_id]->node_function = node_function[CC_id]; + PHY_vars_eNB_g[0][CC_id]->node_timing = node_timing[CC_id]; + } - init_eNB_proc(nb_inst); + init_eNB_proc(); sleep(1); LOG_D(HW,"[lte-softmodem.c] eNB threads created\n"); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index d17f7b859941fcdbc2ccd6af19e56771e1c71ca8..297286687eb5977b5869c2689039f524a8d77749 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -119,7 +119,7 @@ unsigned short config_frames[4] = {2,9,11,13}; // In lte-enb.c extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]); -extern void init_eNB(eNB_func_t,int); +extern void init_eNB(eNB_func_t *, eNB_timing_t *); extern void stop_eNB(void); extern void kill_eNB_proc(void); @@ -229,7 +229,9 @@ int otg_enabled; static LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; -eNB_func_t node_function=eNodeB_3GPP; +eNB_func_t node_function[MAX_NUM_CCs]; +eNB_timing_t node_timing[MAX_NUM_CCs]; +int16_t node_synch_ref[MAX_NUM_CCs]; uint32_t target_dl_mcs = 28; //maximum allowed mcs uint32_t target_ul_mcs = 20; @@ -237,8 +239,6 @@ uint32_t timing_advance = 0; uint8_t exit_missed_slots=1; uint64_t num_missed_slots=0; // counter for the number of missed slots - - extern void reset_opp_meas(void); extern void print_opp_meas(void); int transmission_mode=1; @@ -384,11 +384,6 @@ void help (void) { printf(" --ue-scan_carrier set UE to scan around carrier\n"); printf(" --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n"); printf(" --mmapped-dma sets flag for improved EXMIMO UE performance\n"); - printf(" --RCC run using NGFI RCC node function IF4 split\n"); - printf(" --RRU run using NGFI RRU node function IF4 split\n"); - printf(" --eNB run using 3GPP eNB node function\n"); - printf(" --BBU run using 3GPP eNB node function with IF5 split\n"); - printf(" --RRH run using RRH node function with IF5 split\n"); printf(" -C Set the downlink frequency for all component carriers\n"); printf(" -d Enable soft scope and L1 and L2 stats (Xforms)\n"); printf(" -F Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"); @@ -685,12 +680,7 @@ static void get_options (int argc, char **argv) LONG_OPTION_DUMP_FRAME, LONG_OPTION_LOOPMEMORY, LONG_OPTION_PHYTEST, - LONG_OPTION_MMAPPED_DMA, - LONG_OPTION_RCC, - LONG_OPTION_RRU, - LONG_OPTION_ENB, - LONG_OPTION_ENB_BBU, - LONG_OPTION_RRH + LONG_OPTION_MMAPPED_DMA #if T_TRACER , LONG_OPTION_T_PORT, @@ -715,11 +705,6 @@ static void get_options (int argc, char **argv) {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY}, {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST}, {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA}, - {"RCC", no_argument, NULL, LONG_OPTION_RCC}, - {"RRU", no_argument, NULL, LONG_OPTION_RRU}, - {"eNB", no_argument, NULL, LONG_OPTION_ENB}, - {"BBU", no_argument, NULL, LONG_OPTION_ENB_BBU}, - {"RRH", no_argument, NULL, LONG_OPTION_RRH}, #if T_TRACER {"T_port", required_argument, 0, LONG_OPTION_T_PORT}, {"T_nowait", no_argument, 0, LONG_OPTION_T_NOWAIT}, @@ -814,26 +799,6 @@ static void get_options (int argc, char **argv) case LONG_OPTION_MMAPPED_DMA: mmapped_dma = 1; break; - - case LONG_OPTION_RCC: - node_function = NGFI_RCC_IF4; - break; - - case LONG_OPTION_RRU: - node_function = NGFI_RRU_IF4; - break; - - case LONG_OPTION_ENB: - node_function = eNodeB_3GPP; - break; - - case LONG_OPTION_ENB_BBU: - node_function = eNodeB_3GPP_BBU; - break; - - case LONG_OPTION_RRH: - node_function = NGFI_RRU_IF5; - break; #if T_TRACER case LONG_OPTION_T_PORT: { @@ -1113,6 +1078,10 @@ static void get_options (int argc, char **argv) } for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + node_function[CC_id] = enb_properties->properties[i]->cc_node_function[CC_id]; + node_timing[CC_id] = enb_properties->properties[i]->cc_node_timing[CC_id]; + node_synch_ref[CC_id] = enb_properties->properties[i]->cc_node_synch_ref[CC_id]; + frame_parms[CC_id]->frame_type = enb_properties->properties[i]->frame_type[CC_id]; frame_parms[CC_id]->tdd_config = enb_properties->properties[i]->tdd_config[CC_id]; frame_parms[CC_id]->tdd_config_S = enb_properties->properties[i]->tdd_config_s[CC_id]; @@ -1665,7 +1634,7 @@ int main( int argc, char **argv ) if (UE_flag == 0) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - if (node_function == NGFI_RRU_IF4 || node_function == NGFI_RRU_IF5) { + if (node_function[CC_id] == NGFI_RRU_IF4 || node_function[CC_id] == NGFI_RRU_IF5) { PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = RRH_HOST; PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = RRH_HOST; } else { @@ -1685,10 +1654,9 @@ int main( int argc, char **argv ) int returns=-1; - // Handle spatially distributed MIMO antenna ports // Load RF device and initialize - if (node_function == NGFI_RRU_IF5 || node_function == NGFI_RRU_IF4 || node_function == eNodeB_3GPP) { - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + if (node_function[CC_id] == NGFI_RRU_IF5 || node_function[CC_id] == NGFI_RRU_IF4 || node_function[CC_id] == eNodeB_3GPP) { if (mode!=loop_through_memory) { returns= (UE_flag == 0) ? openair0_device_load(&(PHY_vars_eNB_g[0][CC_id]->rfdevice), &openair0_cfg[0]) : @@ -1696,28 +1664,27 @@ int main( int argc, char **argv ) printf("openair0_device_init returns %d for CC_id %d\n",returns,CC_id); if (returns<0) { - printf("Exiting, cannot initialize device\n"); - exit(-1); + printf("Exiting, cannot initialize device\n"); + exit(-1); } - } - else if (mode==loop_through_memory) { + } else if (mode==loop_through_memory) { + } } } // Load transport protocol and initialize - - if ((UE_flag==0) && (node_function != eNodeB_3GPP)){ - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + if ((UE_flag==0) && (node_function[CC_id] != eNodeB_3GPP)) { if (mode!=loop_through_memory) { - returns=openair0_transport_load(&(PHY_vars_eNB_g[0][CC_id]->ifdevice), &openair0_cfg[0], (eth_params+CC_id)); + returns = openair0_transport_load(&(PHY_vars_eNB_g[0][CC_id]->ifdevice), &openair0_cfg[0], (eth_params+CC_id)); printf("openair0_transport_init returns %d for CC_id %d\n",returns,CC_id); if (returns<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); } - } - else if (mode==loop_through_memory) { + } else if (mode==loop_through_memory) { + } } } @@ -1755,7 +1722,6 @@ int main( int argc, char **argv ) number_of_cards = 1; - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { rf_map[CC_id].card=0; rf_map[CC_id].chain=CC_id+chain_offset; @@ -1877,17 +1843,11 @@ int main( int argc, char **argv ) // start the main thread if (UE_flag == 1) init_UE(1); - else init_eNB(node_function,1); - + else init_eNB(node_function,node_timing); // Sleep to allow all threads to setup sleep(3); - - - // *** Handle per CC_id openair0 - - printf("Sending sync to all threads\n"); pthread_mutex_lock(&sync_mutex); @@ -1949,6 +1909,7 @@ int main( int argc, char **argv ) pthread_cond_destroy(&sync_cond); pthread_mutex_destroy(&sync_mutex); + // *** Handle per CC_id openair0 if (UE_flag==1) { if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) @@ -1972,10 +1933,3 @@ int main( int argc, char **argv ) return 0; } - - - - - - - diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index c8f42dfdd89a6bf8dc20639550b33b5a54d28386..8148730a2456d18d5928fd19edb633bb3d02b3fb 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -1132,7 +1132,7 @@ void init_ocm(void) get_beta_map_up(); #endif get_MIESM_param(); - + //load_pbch_desc(); }