diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 02a6ac5151..1027718d48 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -976,6 +976,7 @@ set(PHY_SRC ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c ${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz.c ${OPENAIR1_DIR}/PHY/MODULATION/beamforming.c + ${OPENAIR1_DIR}/PHY/MODULATION/compute_bf_weights.c ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_time.c ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_timefreq.c diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h index 8bcf312c3e..e0029be318 100644 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/defs.h @@ -242,6 +242,8 @@ typedef struct { int32_t *txdataF[8]; /// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers? int32_t **ue_spec_bf_weights[4]; + /// dl channel estimates (estimated from ul channel estimates) + int32_t **calib_dl_ch_estimates; /// Allocated RNTI (0 means DLSCH_t is not currently used) uint16_t rnti; /// Active flag for baseband transmitter processing diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index 2e38b7cb93..00bb9e5dca 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -120,4 +120,3 @@ int beam_precoding(int32_t **txdataF, } } } - diff --git a/openair1/PHY/MODULATION/compute_bf_weights.c b/openair1/PHY/MODULATION/compute_bf_weights.c new file mode 100644 index 0000000000..32a91c11f5 --- /dev/null +++ b/openair1/PHY/MODULATION/compute_bf_weights.c @@ -0,0 +1,56 @@ +#include +#include +#include "PHY/impl_defs_lte.h" + +int f_read(char *calibF_fname, int nb_ant, int nb_freq, int32_t **tdd_calib_coeffs){ + + FILE *calibF_fd; + int i,j,l,calibF_e; + + calibF_fd = fopen(calibF_fname,"r"); + + if (calibF_fd) { + printf("Loading Calibration matrix from %s\n", calibF_fname); + + for(i=0;irx_vars[a].RX_DMA_BUFFER. @@ -632,18 +641,16 @@ typedef struct { /// - first index: eNB id [0..2] (hard coded) /// - second index: sample [0..samples_per_tti*10[ uint32_t *sync_corr[3]; - // int32_t **beam_weights[3][15]; /// \brief Holds the beamforming weights /// - first index: eNB id [0..2] (hard coded) - /// - second index: eNB antenna port index + /// - second index: eNB antenna port index (hard coded) /// - third index: tx antenna [0..nb_antennas_tx[ /// - fourth index: sample [0..] int32_t **beam_weights[3][15]; /// \brief Holds the tdd reciprocity calibration coefficients /// - first index: eNB id [0..2] (hard coded) - /// - second index: ue specific eNB antenna port index, port5->index0, port7-15->index0-7 - /// - third index: tx antenna [0..nb_antennas_tx[ - /// - forth index: frenquency [0..] + /// - second index: tx antenna [0..nb_antennas_tx[ + /// - third index: frequency [0..] int32_t **tdd_calib_coeffs[3]; } LTE_eNB_COMMON; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index dd535064d1..1a34e59f5a 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -991,6 +991,9 @@ int main(int argc, char **argv) PHY_vars_eNB->eNB_UE_stats[1].DL_pmi_single = 0; } + //TODO: allocate memory for calibration matrix and calib_dl_ch_estimates in init_lte.c + //for first tests initialze calibration matrix with idendity + //read_calibration_matrix(calib_fname, nb_ant, nb_freq, PHY_vars_eNB->lte_eNB_common_vars.tdd_calib_coeffs[0]); if (input_fd==NULL) { @@ -2142,6 +2145,32 @@ int main(int argc, char **argv) PMI_FEEDBACK: + //make sure dlsim is called with perfect channel estimation option (for freq_channel) + //fill drs_ch_estimates with data from eNB2UE->chF + for(aa=0; aanb_antenna_ports_eNB; aa++) { + for (aarx=0; aarxnb_antennas_rx; aarx++) { + for (i=0; iN_RB_DL*12; i++) { + for (l=0; lsymbols_per_tti; l++) { + ((int16_t *) PHY_vars_eNB->lte_eNB_pusch_vars[0]->drs_ch_estimates[0][(aa<<1)+aarx])[2*i+(l*frame_parms->ofdm_symbol_size)*2]=(int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); + //printf("x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP); + ((int16_t *) PHY_vars_eNB->lte_eNB_pusch_vars[0]->drs_ch_estimates[0][(aa<<1)+aarx])[2*i+1+(l*frame_parms->ofdm_symbol_size)*2]=(int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); + } + } + } + } + + estimate_DLCSI_from_ULCSI(PHY_vars_eNB->dlsch_eNB[0][0]->calib_dl_ch_estimates, + &PHY_vars_eNB->lte_eNB_pusch_vars[0]->drs_ch_estimates[0][0/*position of second DMRS*/], + PHY_vars_eNB->lte_eNB_common_vars.tdd_calib_coeffs[0], + frame_parms->nb_antennas_tx, + frame_parms->N_RB_DL*12); + + compute_BF_weights(PHY_vars_eNB->dlsch_eNB[0][0]->ue_spec_bf_weights[0], + PHY_vars_eNB->dlsch_eNB[0][0]->calib_dl_ch_estimates, + MRT, + frame_parms->nb_antennas_tx, + frame_parms->N_RB_DL*12); + //printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); for (aa=0; aalte_eNB_common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); @@ -3088,6 +3117,7 @@ PMI_FEEDBACK: eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); if (transmission_mode == 7){ + //this should include the BF weights! Will not work for a random channel if (PHY_vars_UE->high_speed_flag==0) { ((int16_t *)PHY_vars_UE->lte_ue_pdsch_vars[0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(int16_t)( eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);