diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 8cc7926d4571158f210eb976dd3df102f4d2a510..6f118094b59da5a67e70be81fd5c0ffc76a327d1 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -60,6 +60,11 @@ typedef enum { max_gain=0,med_gain,byp_gain } rx_gain_t; +typedef enum { + duplex_mode_TDD=1,duplex_mode_FDD=0 +} duplex_mode_t; + + /** @addtogroup _PHY_RF_INTERFACE_ * @{ */ @@ -76,6 +81,8 @@ typedef struct { int Mod_id; // device log level int log_level; + //! duplexing mode + duplex_mode_t duplex_mode; //! number of downlink resource blocks int num_rb_dl; //! number of samples per frame diff --git a/targets/ARCH/EXMIMO/DEFS/pcie_interface.h b/targets/ARCH/EXMIMO/DEFS/pcie_interface.h index 925787cabfbb955e1cb20d17b0d73ecb0c5a5694..42380f1322314996b95d2af8b56e6ea6665da0e5 100644 --- a/targets/ARCH/EXMIMO/DEFS/pcie_interface.h +++ b/targets/ARCH/EXMIMO/DEFS/pcie_interface.h @@ -316,7 +316,9 @@ typedef struct { // // In TDD mode, there are two ways to control the RX/TX switch: // 1. using the LSB from the TX data (TXRXSWITCH_LSB) +// only the LSB from RF chain set in the ACTIVE_RF register controls the switch on all the chains // 2. using FPGA logic, based on switch_offset[0..3] +// this mode is not tested well and should be used with care #define DUPLEXMODE_MASK (1<<0) #define DUPLEXMODE_FDD 0 #define DUPLEXMODE_TDD (1<<0) @@ -330,6 +332,11 @@ typedef struct { #define SWITCHSTATE_1 (1<<3) #define TEST_ADACLOOP_MASK (1<<4) #define TEST_ADACLOOP_EN (1<<4) +#define ACTIVE_RF_MASK (15<<5) +#define ACTIVE_RF_1 (1<<5) +#define ACTIVE_RF_2 (2<<5) +#define ACTIVE_RF_3 (4<<5) +#define ACTIVE_RF_4 (8<<5) typedef enum { BW5, diff --git a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c index df9900d3bc98720090143b73c2989a30ad0868ea..238c94bd7e97a6ce6d6330f260ca99c38e83e5b5 100644 --- a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c +++ b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c @@ -296,6 +296,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag) int ant, card; int resampling_factor=2; int rx_filter=RXLPF25, tx_filter=TXLPF25; + int ACTIVE_RF=0; exmimo_config_t *p_exmimo_config; exmimo_id_t *p_exmimo_id; @@ -315,8 +316,6 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag) else p_exmimo_config->framing.eNB_flag = !UE_flag; - p_exmimo_config->framing.tdd_config = DUPLEXMODE_FDD + TXRXSWITCH_LSB; - if (openair0_num_detected_cards==1) p_exmimo_config->framing.multicard_syncmode=SYNCMODE_FREE; else if (card==0) @@ -355,6 +354,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag) for (ant=0; ant<4; ant++) { if (openair0_cfg[card].rx_freq[ant] || openair0_cfg[card].tx_freq[ant]) { + ACTIVE_RF += (1<<ant)<<5; p_exmimo_config->rf.rf_mode[ant] = RF_MODE_BASE; p_exmimo_config->rf.do_autocal[ant] = 1;//openair0_cfg[card].autocal[ant]; printf("card %d, antenna %d, autocal %d\n",card,ant,openair0_cfg[card].autocal[ant]); @@ -408,6 +408,15 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag) } } + if (openair0_cfg[card].duplex_mode==duplex_mode_FDD) { + p_exmimo_config->framing.tdd_config = DUPLEXMODE_FDD; + printf("!!!!!setting FDD (tdd_config=%d)\n",p_exmimo_config->framing.tdd_config); + } + else { + p_exmimo_config->framing.tdd_config = DUPLEXMODE_TDD + TXRXSWITCH_LSB + ACTIVE_RF; + printf("!!!!!setting TDD (tdd_config=%d)\n",p_exmimo_config->framing.tdd_config); + } + ret = ioctl(openair0_fd, openair_DUMP_CONFIG, card); if (ret!=0) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index b96a7ae5292099fd5bc964e57b2a89e2502699be..30e81995821b8baf4e83a1145967e009b1ae4959 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -970,6 +970,25 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset++] = 0x00010001; } } + + if ((((phy_vars_eNB->lte_frame_parms.tdd_config==0) || + (phy_vars_eNB->lte_frame_parms.tdd_config==1) || + (phy_vars_eNB->lte_frame_parms.tdd_config==2) || + (phy_vars_eNB->lte_frame_parms.tdd_config==6)) && + (subframe==0)) || (subframe==5)) { + // turn on tx switch N_TA_offset before + //LOG_D(HW,"subframe %d, time to switch to tx (N_TA_offset %d, slot_offset %d) \n",subframe,phy_vars_eNB->N_TA_offset,slot_offset); + for (i=0; i<phy_vars_eNB->N_TA_offset; i++) { + tx_offset = (int)slot_offset+time_offset[aa]+i-phy_vars_eNB->N_TA_offset/2; + if (tx_offset<0) + tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti; + + if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti)) + tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti; + + phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset] = 0x00000000; + } + } } } } @@ -2821,7 +2840,7 @@ int main( int argc, char **argv ) } #else - //already taken care of in lte-softmodem + //already taken care of in lte-softmodem.c PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0; #endif @@ -2901,7 +2920,12 @@ int main( int argc, char **argv ) openair0_cfg[card].tx_delay = 8; #endif } - + + if (frame_parms[0]->frame_type==TDD) + openair0_cfg[card].duplex_mode = duplex_mode_TDD; + else //FDD + openair0_cfg[card].duplex_mode = duplex_mode_FDD; + #ifdef ETHERNET //calib needed @@ -2935,7 +2959,7 @@ int main( int argc, char **argv ) openair0_cfg[card].remote_ip = &rrh_eNB_ip[0]; openair0_cfg[card].remote_port = rrh_eNB_port; } -openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; + openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; #endif openair0_cfg[card].sample_rate = sample_rate; openair0_cfg[card].tx_bw = bw; @@ -3064,7 +3088,7 @@ openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { rf_map[CC_id].card=0; - rf_map[CC_id].chain=CC_id; + rf_map[CC_id].chain=CC_id+1; } // connect the TX/RX buffers