Commit 1309358b authored by Raymond Knopp's avatar Raymond Knopp

changes for oaisim to function with new threading architecture and...

changes for oaisim to function with new threading architecture and trx_read/trx_write emulation. Tested for 5/10 MHz TM1. Multiple-antenna mode fails.
parent 8d057b80
......@@ -179,7 +179,7 @@ install_nettle_from_source() {
cd /tmp
echo "Downloading nettle archive"
$SUDO rm -rf /tmp/nettle-2.5.tar.gz* /tmp/nettle-2.5
wget https://ftp.gnu.org/gnu/nettle/nettle-2.5.tar.gz
wget http://ftp.nluug.nl/gnu/nettle/nettle-2.5.tar.gz
if [ $? -ne 0 ]; then
wget ftp://ftp.lysator.liu.se/pub/security/lsh/nettle-2.5.tar.gz
fi
......
......@@ -988,7 +988,8 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
ue->total_received_bits[eNB_id] = 0;
}
ue->tx_power_dBm=-127;
for (i=0;i<10;i++)
ue->tx_power_dBm[i]=-127;
if (abstraction_flag == 0) {
......
......@@ -30,6 +30,8 @@
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#define DEBUG_PHY
// Adjust location synchronization point to account for drift
......@@ -48,6 +50,8 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
int diff;
short Re,Im,ncoef;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
ncoef = 32767 - coef;
#ifdef DEBUG_PHY
......@@ -98,6 +102,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
ue->proc.proc_rxtx[0].frame_rx,ue->rx_offset,max_pos,max_pos_fil,temp);
#endif //DEBUG_PHY
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
}
......
......@@ -296,10 +296,10 @@ int32_t subcarrier_energy(int32_t *,uint32_t, int32_t* subcarrier_energy, uint16
*/
int32_t signal_energy_nodc(int32_t *,uint32_t);
/*!\fn double signal_energy_fp(double **, double **,uint32_t, uint32_t,uint32_t);
/*!\fn double signal_energy_fp(double s_re[2][30720], double s_im[2][30720],uint32_t, uint32_t,uint32_t);
\brief Computes the signal energy per subcarrier
*/
double signal_energy_fp(double **s_re, double **s_im, uint32_t nb_antennas, uint32_t length,uint32_t offset);
double signal_energy_fp(double s_re[2][30720], double s_im[2][30720], uint32_t nb_antennas, uint32_t length,uint32_t offset);
/*!\fn double signal_energy_fp2(struct complex *, uint32_t);
\brief Computes the signal energy per subcarrier
......
......@@ -255,7 +255,7 @@ int32_t signal_energy_nodc(int32_t *input,uint32_t length)
}
#endif
double signal_energy_fp(double **s_re,double **s_im,uint32_t nb_antennas,uint32_t length,uint32_t offset)
double signal_energy_fp(double s_re[2][30720],double s_im[2][30720],uint32_t nb_antennas,uint32_t length,uint32_t offset)
{
int32_t aa,i;
......
......@@ -612,6 +612,8 @@ typedef struct {
int is_synchronized;
/// Data structure for UE process scheduling
UE_proc_t proc;
/// Flag to indicate the UE shouldn't do timing correction at all
int no_timing_correction;
/// \brief Total gain of the TX chain (16-bit baseband I/Q to antenna)
uint32_t tx_total_gain_dB;
/// \brief Total gain of the RX chain (antenna to baseband I/Q) This is a function of rx_gain_mode (and the corresponding gain) and the rx_gain of the card.
......@@ -623,9 +625,9 @@ typedef struct {
/// \brief Total gains with bypassed RF gain stage (ExpressMIMO2/Lime)
uint32_t rx_gain_byp[4];
/// \brief Current transmit power
int8_t tx_power_dBm;
int8_t tx_power_dBm[10];
/// \brief Total number of REs in current transmission
int tx_total_RE;
int tx_total_RE[10];
/// \brief Maximum transmit power
int8_t tx_power_max_dBm;
/// \brief Number of eNB seen by UE
......
......@@ -111,7 +111,7 @@ extern double p_qam64[8];
extern double beta1_dlsch[6][MCS_COUNT];
extern double beta2_dlsch[6][MCS_COUNT];
extern char eNB_functions[5][20];
extern char eNB_functions[6][20];
extern char eNB_timing[2][20];
......
......@@ -718,7 +718,7 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
frame_tx,
eNB_id,
subframe_tx);
// LOG_I(PHY,"Got prach_resources for eNB %d address %d, RRCCommon %d\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[Mod_id].radioResourceConfigCommon);
LOG_D(PHY,"Got prach_resources for eNB %d address %d, RRCCommon %d\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon);
}
}
......@@ -744,17 +744,17 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
ue->prach_resources[eNB_id]->ra_RNTI);
if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
ue->tx_power_dBm = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id);
ue->tx_power_dBm[subframe_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id);
}
else {
ue->tx_power_dBm = ue->tx_power_max_dBm;
ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
}
ue->tx_total_RE = 96;
ue->tx_total_RE[subframe_tx] = 96;
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm,
ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
ue->tx_power_max_dBm,
ue->frame_parms.N_RB_UL,
6);
......@@ -766,7 +766,7 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
ue->Mod_id,
proc->frame_rx,
proc->subframe_tx,
ue->tx_power_dBm,
ue->tx_power_dBm[subframe_tx],
ue->prach_vars[eNB_id]->amp);
......@@ -778,7 +778,7 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
ue->Mod_id,
get_PL(ue->Mod_id,ue->CC_id,eNB_id),
ue->tx_power_dBm,
ue->tx_power_dBm[subframe_tx],
dB_fixed(prach_power),
ue->prach_vars[eNB_id]->amp);
} else {
......@@ -1036,15 +1036,15 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
if (abstraction_flag == 0) {
if (ue->mac_enabled==1) {
pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag);
ue->tx_power_dBm = ue->ulsch[eNB_id]->Po_PUSCH;
ue->tx_power_dBm[subframe_tx] = ue->ulsch[eNB_id]->Po_PUSCH;
}
else {
ue->tx_power_dBm = ue->tx_power_max_dBm;
ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
}
ue->tx_total_RE = nb_rb*12;
ue->tx_total_RE[subframe_tx] = nb_rb*12;
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
tx_amp = get_tx_amp(ue->tx_power_dBm,
tx_amp = get_tx_amp(ue->tx_power_dBm[,
ue->tx_power_max_dBm,
ue->frame_parms.N_RB_UL,
nb_rb);
......@@ -1052,7 +1052,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
tx_amp = AMP;
#endif
LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
Mod_id,harq_pid,frame_tx,subframe_tx,ue->tx_power_dBm,ue->tx_power_max_dBm, tx_amp);
Mod_id,harq_pid,frame_tx,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp);
start_meas(&ue->ulsch_modulation_stats);
ulsch_modulation(ue->common_vars.txdataF,
tx_amp,
......@@ -1156,8 +1156,8 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
else {
Po_PUCCH = ue->tx_power_max_dBm;
}
ue->tx_power_dBm = Po_PUCCH;
ue->tx_total_RE = 12;
ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
ue->tx_total_RE[subframe_tx] = 12;
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
tx_amp = get_tx_amp(Po_PUCCH,
......@@ -1220,8 +1220,8 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
else {
Po_PUCCH = ue->tx_power_max_dBm;
}
ue->tx_power_dBm = Po_PUCCH;
ue->tx_total_RE = 12;
ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
ue->tx_total_RE[subframe_tx] = 12;
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
tx_amp = get_tx_amp(Po_PUCCH,
......@@ -1286,7 +1286,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
//phy_procedures_emos_UE_TX(next_slot);
#endif
ue->tx_power_dBm=-127;
ue->tx_power_dBm[subframe_tx]=-127;
if (abstraction_flag==0) {
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
......@@ -1391,6 +1391,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
(ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
// check if we have PRACH opportunity
if (is_prach_subframe(&ue->frame_parms,frame_tx,subframe_tx)) {
ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
......@@ -1484,17 +1485,17 @@ void ue_measurement_procedures(uint16_t l, PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
eNB_id = 0;
if (abstraction_flag == 0)
if (abstraction_flag == 0) {
if (ue->no_timing_correction==0)
lte_adjust_synch(&ue->frame_parms,
ue,
eNB_id,
0,
16384);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
}
}
......
......@@ -26,8 +26,8 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
void adc(double **r_re,
double **r_im,
void adc(double r_re[2][30720],
double r_im[2][30720],
unsigned int input_offset,
unsigned int output_offset,
unsigned int **output,
......
......@@ -31,8 +31,8 @@
#include <stdio.h>
#include "PHY/TOOLS/defs.h"
void dac(double **s_re,
double **s_im,
void dac(double s_re[2][30720],
double s_im[2][30720],
uint32_t **input,
uint32_t input_offset,
uint32_t nb_tx_antennas,
......@@ -81,8 +81,8 @@ void dac(double **s_re,
}
}
double dac_fixed_gain(double **s_re,
double **s_im,
double dac_fixed_gain(double s_re[2][30720],
double s_im[2][30720],
uint32_t **input,
uint32_t input_offset,
uint32_t nb_tx_antennas,
......
......@@ -64,16 +64,16 @@ void rf_rx(double **r_re,
double IQ_imb_dB,
double IQ_phase);
void rf_rx_simple(double **r_re,
double **r_im,
void rf_rx_simple(double r_re[2][30720],
double r_im[2][30720],
unsigned int nb_rx_antennas,
unsigned int length,
double s_time,
double rx_gain_dB);
void adc(double **r_re,
double **r_im,
void adc(double r_re[2][30720],
double r_im[2][30720],
unsigned int input_offset,
unsigned int output_offset,
int **output,
......@@ -81,8 +81,8 @@ void adc(double **r_re,
unsigned int length,
unsigned char B);
void dac(double **s_re,
double **s_im,
void dac(double s_re[2][30720],
double s_im[2][30720],
int **input,
unsigned int input_offset,
unsigned int nb_tx_antennas,
......@@ -92,8 +92,8 @@ void dac(double **s_re,
unsigned int meas_length,
unsigned int meas_offset);
double dac_fixed_gain(double **s_re,
double **s_im,
double dac_fixed_gain(double s_re[2][30720],
double s_im[2][30720],
int **input,
unsigned int input_offset,
unsigned int nb_tx_antennas,
......
......@@ -206,8 +206,8 @@ void rf_rx(double **r_re,
}
}
void rf_rx_simple(double **r_re,
double **r_im,
void rf_rx_simple(double r_re[2][30720],
double r_im[2][30720],
unsigned int nb_rx_antennas,
unsigned int length,
double s_time,
......
......@@ -219,10 +219,10 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag);
/**\fn void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
double tx_sig_re[2][30720],
double tx_sig_im[2][30720],
double rx_sig_re[2][30720],
double rx_sig_im[2][30720],
uint32_t length,
uint8_t keep_channel)
......@@ -237,10 +237,10 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag);
*/
void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
double tx_sig_re[2][30720],
double tx_sig_im[2][30720],
double rx_sig_re[2][30720],
double rx_sig_im[2][30720],
uint32_t length,
uint8_t keep_channel);
/*
......
......@@ -44,10 +44,10 @@ uint8_t multipath_channel_nosigconv(channel_desc_t *desc)
//#define CHANNEL_SSE
#ifdef CHANNEL_SSE
void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
double tx_sig_re[2][30720],
double tx_sig_im[2][30720],
double rx_sig_re[2][30720],
double rx_sig_im[2][30720],
uint32_t length,
uint8_t keep_channel)
{
......@@ -150,10 +150,10 @@ void multipath_channel(channel_desc_t *desc,
#else
void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
double tx_sig_re[2][30720],
double tx_sig_im[2][30720],
double rx_sig_re[2][30720],
double rx_sig_im[2][30720],
uint32_t length,
uint8_t keep_channel)
{
......
......@@ -24,7 +24,7 @@ eNBs =
component_carriers = (
{
node_function = "eNodeB_3GPP";
node_timing = "synch_to_other";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
......
......@@ -191,7 +191,7 @@ static inline void thread_top_init(char *thread_name,
return &eNB_thread_rxtx_status;
}
LOG_I( HW, "[SCHED] eNB RXn-TXnp4 deadline thread (TID %ld) started on CPU %d\n", gettid(), sched_getcpu() );
LOG_I( HW, "[SCHED] eNB %s deadline thread (TID %ld) started on CPU %d\n", gettid(), thread_name,sched_getcpu() );
#else //LOW_LATENCY
int policy, s, j;
......@@ -654,7 +654,7 @@ static void* eNB_thread_rxtx( void* param ) {
return &eNB_thread_rxtx_status;
}
#if defined(ENABLE_ITTI)
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
/* Wait for eNB application initialization to be complete (eNB registration to MME) */
static void wait_system_ready (char *message, volatile int *start_flag) {
......@@ -1032,7 +1032,7 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
void rx_fh_slave(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
// This case is for synchronization to another thread
// it just waits for an external event. The actual rx_rh is handle by the asynchronous RX thread
// it just waits for an external event. The actual rx_fh is handle by the asynchronous RX thread
eNB_proc_t *proc=&eNB->proc;
if (wait_on_condition(&proc->mutex_FH,&proc->cond_FH,&proc->instance_cnt_FH,"rx_fh_slave") < 0)
......@@ -1129,7 +1129,7 @@ void wakeup_slaves(eNB_proc_t *proc) {
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);
LOG_W( PHY,"[eNB] Frame %d, slave CC_id %d thread busy!! (cnt_FH %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave);
exit_fun( "FH thread busy" );
break;
}
......@@ -1161,7 +1161,7 @@ static void* eNB_thread_FH( void* param ) {
wait_sync("eNB_thread_FH");
#if defined(ENABLE_ITTI)
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
if (eNB->node_function < NGFI_RRU_IF5)
wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
#endif
......@@ -1273,7 +1273,7 @@ static void* eNB_thread_single( void* param ) {
wait_sync("eNB_thread_single");
#if defined(ENABLE_ITTI)
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
if (eNB->node_function < NGFI_RRU_IF5)
wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
#endif
......@@ -1307,6 +1307,7 @@ static void* eNB_thread_single( void* param ) {
subframe++;
}
LOG_D(PHY,"eNB Fronthaul thread, frame %d, subframe %d\n",frame,subframe);
// synchronization on FH interface, acquire signals/data and block
if (eNB->rx_fh) eNB->rx_fh(eNB,&frame,&subframe);
......@@ -1314,6 +1315,7 @@ static void* eNB_thread_single( void* param ) {
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
// At this point, all information for subframe has been received on FH interface
// If this proc is to provide synchronization, do so
wakeup_slaves(proc);
......@@ -1546,17 +1548,17 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
free(phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
rxdata[i] = (int32_t*)(32 + malloc16(32+openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card].samples_per_frame*sizeof(int32_t))); // FIXME broken memory allocation
rxdata[i] = (int32_t*)(32 + malloc16(32+frame_parms->samples_per_tti*10*sizeof(int32_t))); // FIXME broken memory allocation
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD FIXME! N_TA_offset > 16 => access of unallocated memory
memset(rxdata[i], 0, openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card].samples_per_frame*sizeof(int32_t));
memset(rxdata[i], 0, frame_parms->samples_per_tti*10*sizeof(int32_t));
printf("rxdata[%d] @ %p (%p) (N_TA_OFFSET %d)\n", i, phy_vars_eNB[CC_id]->common_vars.rxdata[0][i],rxdata[i],N_TA_offset);
}
for (i=0; i<frame_parms->nb_antennas_tx; i++) {
free(phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
txdata[i] = (int32_t*)(32 + malloc16(32 + openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card].samples_per_frame*sizeof(int32_t))); // FIXME broken memory allocation
txdata[i] = (int32_t*)(32 + malloc16(32 + frame_parms->samples_per_tti*10*sizeof(int32_t))); // FIXME broken memory allocation
phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = txdata[i];
memset(txdata[i],0, openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card].samples_per_frame*sizeof(int32_t));
memset(txdata[i],0, frame_parms->samples_per_tti*10*sizeof(int32_t));
printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
}
}
......
......@@ -793,6 +793,16 @@ static void *UE_thread_rxn_txnp4(void *arg)
UE->UE_mode[0] = PRACH;
}
}
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
(UE->frame_parms.frame_type == FDD) ||
(subframe_select( &UE->frame_parms, proc->subframe_tx ) == SF_S)) {
if (UE->mode != loop_through_memory) {
phy_procedures_UE_TX(UE,proc,0,0,normal_txrx,no_relay);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RXTX0+(proc->subframe_rx&1), 0 );
......@@ -967,6 +977,8 @@ void *UE_thread(void *arg) {
if (start_rx_stream==0) {
start_rx_stream=1;
if (UE->mode != loop_through_memory) {
if (UE->no_timing_correction==0) {
LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset);
rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
......@@ -977,6 +989,7 @@ void *UE_thread(void *arg) {
exit_fun("problem in rx");
return &UE_thread_retval;
}
}
UE->rx_offset=0;
UE->proc.proc_rxtx[0].frame_rx++;
UE->proc.proc_rxtx[1].frame_rx++;
......@@ -1049,10 +1062,15 @@ void *UE_thread(void *arg) {
int instance_cnt_rxtx = ++proc->instance_cnt_rxtx;
proc->subframe_rx=sf;
proc->subframe_tx=(sf+4)%10;
proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5)?1:0;
proc->frame_tx = proc->frame_rx + ((proc->subframe_rx>5)?1:0);
proc->timestamp_tx = timestamp+(4*UE->frame_parms.samples_per_tti)-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
if (sf != (timestamp/UE->frame_parms.samples_per_tti)%10) {
LOG_E(PHY,"steady-state UE_thread error : frame_rx %d, subframe_rx %d, frame_tx %d, subframe_tx %d, rx subframe %d\n",proc->frame_rx,proc->subframe_rx,proc->frame_tx,proc->subframe_tx,(timestamp/UE->frame_parms.samples_per_tti)%10);
exit(-1);
}
if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX\n" );
exit_fun("nothing to add");
......
......@@ -437,9 +437,14 @@ void do_UL_sig(channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_N
txdata = PHY_vars_UE_g[UE_id][CC_id]->common_vars.txdata;
sf_offset = subframe*frame_parms->samples_per_tti;
if (((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm +
if (((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe] +
UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB) <= -125.0) {
// don't simulate a UE that is too weak
LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %d dBm (num_RE %d) for subframe %d (sf_offset %d)\n",
UE_id,
PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe],
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe],
subframe,sf_offset);
} else {
tx_pwr = dac_fixed_gain((double**)s_re,
......@@ -451,13 +456,13 @@ void do_UL_sig(channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_N
sf_offset,
frame_parms->ofdm_symbol_size,
14,
(double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm-10*log10((double)PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE),
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE); // This make the previous argument the total power
(double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe]-10*log10((double)PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]),
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]); // This make the previous argument the total power
LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %f dBm (target %d dBm, num_RE %d) for subframe %d (sf_offset %d)\n",
UE_id,
10*log10(tx_pwr),
PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm,
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE,
PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe],
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe],
subframe,sf_offset);
......
......@@ -139,8 +139,10 @@ node_desc_t *ue_data[NUMBER_OF_UE_MAX];
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
int sync_var;
int sync_var=-1;
pthread_mutex_t subframe_mutex;
int subframe_eNB_mask=0,subframe_UE_mask=0;
openair0_config_t openair0_cfg[MAX_CARDS];
uint32_t downlink_frequency[MAX_NUM_CCs][4];
......@@ -451,6 +453,10 @@ typedef enum l2l1_task_state_e {
l2l1_task_state_t l2l1_state = L2L1_WAITTING;
extern openair0_timestamp current_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
extern openair0_timestamp current_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
/*------------------------------------------------------------------------------*/
void *
l2l1_task (void *args_p)
......@@ -719,6 +725,40 @@ l2l1_task (void *args_p)
clear_eNB_transport_info (oai_emulation.info.nb_enb_local);
CC_id=0;
int all_done=0;
while (all_done==0) {
pthread_mutex_lock(&subframe_mutex);
int subframe_eNB_mask_local = subframe_eNB_mask;
int subframe_UE_mask_local = subframe_UE_mask;
pthread_mutex_unlock(&subframe_mutex);
LOG_D(EMU,"Frame %d, Subframe %d: Checking masks %x,%x\n",frame,sf,subframe_eNB_mask,subframe_UE_mask);
if ((subframe_eNB_mask_local == ((1<<NB_eNB_INST)-1)) &&
(subframe_UE_mask_local == ((1<<NB_UE_INST)-1)))
all_done=1;
else
usleep(500);
}
//clear subframe masks for next round
pthread_mutex_lock(&subframe_mutex);
subframe_eNB_mask=0;
subframe_UE_mask=0;
pthread_mutex_unlock(&subframe_mutex);
// increment timestamps
for (eNB_inst = oai_emulation.info.first_enb_local;
(eNB_inst
< (oai_emulation.info.first_enb_local
+ oai_emulation.info.nb_enb_local));
eNB_inst++) {
current_eNB_rx_timestamp[eNB_inst][CC_id] += PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.samples_per_tti;
}
for (UE_inst = 0; UE_inst<NB_UE_INST;UE_inst++) {
current_UE_rx_timestamp[UE_inst][CC_id] += PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.samples_per_tti;
}
for (eNB_inst = oai_emulation.info.first_enb_local;
(eNB_inst
< (oai_emulation.info.first_enb_local
......@@ -727,6 +767,7 @@ l2l1_task (void *args_p)
if (oai_emulation.info.cli_start_enb[eNB_inst] != 0) {
T(T_ENB_MASTER_TICK, T_INT(eNB_inst), T_INT(frame % 1024), T_INT(sf));
/*
LOG_D(EMU,
"PHY procedures eNB %d for frame %d, subframe %d TDD %d/%d Nid_cell %d\n",
eNB_inst,
......@@ -736,7 +777,7 @@ l2l1_task (void *args_p)
PHY_vars_eNB_g[eNB_inst][0]->frame_parms.tdd_config,
PHY_vars_eNB_g[eNB_inst][0]->frame_parms.Nid_cell);
*/
#ifdef OPENAIR2
//Application: traffic gen
update_otg_eNB (eNB_inst, oai_emulation.info.time_ms);
......@@ -745,34 +786,7 @@ l2l1_task (void *args_p)
// pdcp_run (frame, 1, 0, eNB_inst); //PHY_vars_eNB_g[eNB_id]->Mod_id
#endif
CC_id=0;
// trigger synch event to RAN FH thread for CC_id
eNB_proc_t *proc = &PHY_vars_eNB_g[eNB_inst][CC_id]->proc;
if (pthread_mutex_lock(&proc->mutex_FH) != 0) {
LOG_E( PHY, "error locking mutex for FH\n");
exit_fun( "error locking mutex" );
break;
}
int cnt_FH = ++proc->instance_cnt_FH;
proc->frame_rx = frame;
proc->subframe_rx = sf;
proc->timestamp_rx += PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.samples_per_tti;
pthread_mutex_unlock( &proc->mutex_FH );
if (cnt_FH == 0) {
if (pthread_cond_signal(&proc->cond_FH) != 0) {
LOG_E(PHY,"ERROR pthread_cond_signal for eNB FH CCid %d\n",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 %d)\n",proc->instance_cnt_FH);
exit_fun("FH thread busy");
break;
}
#ifdef PRINT_STATS
if((sf==9) && frame%10==0)
......@@ -1099,6 +1113,10 @@ main (int argc, char **argv)
sinr_dB = -20;
}
pthread_cond_init(&sync_cond,NULL);
pthread_mutex_init(&sync_mutex, NULL);
pthread_mutex_init(&subframe_mutex, NULL);
#ifdef OPENAIR2
init_omv ();
#endif
......@@ -1117,6 +1135,15 @@ main (int argc, char **argv)
init_ocm ();
// wait for all threads to startup
sleep(3);
printf("Sending sync to all threads\n");
pthread_mutex_lock(&sync_mutex);
sync_var=0;
pthread_cond_broadcast(&sync_cond);
pthread_mutex_unlock(&sync_mutex);
#ifdef SMBV
// Rohde&Schwarz SMBV100A vector signal generator
smbv_init_config(smbv_fname, smbv_nframes);
......
......@@ -456,7 +456,7 @@ int olg_config(void)
set_comp_log(PHY, LOG_TRACE, 0x15, 1);
set_comp_log(PDCP, LOG_DEBUG, 0x15,1);
set_comp_log(RRC, LOG_DEBUG, 0x15,1);
set_comp_log(OCM, LOG_ERR, 0x15,20);
set_comp_log(OCM, LOG_DEBUG, 0x15,20);
set_comp_log(OTG, LOG_DEBUG, 0x15,1);
set_comp_log(OMG, LOG_NOTICE, 0x15,1);
set_comp_log(OPT, LOG_ERR, 0x15,1);
......
......@@ -957,6 +957,11 @@ void init_seed(uint8_t set_seed)
}
}
openair0_timestamp current_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
openair0_timestamp current_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
openair0_timestamp last_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
openair0_timestamp last_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
int eNB_trx_start(openair0_device *device) {
return(0);
}
......@@ -990,53 +995,134 @@ int UE_trx_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
return(0);
}
int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
return(0);
}
extern pthread_mutex_t subframe_mutex;
extern int subframe_eNB_mask,subframe_UE_mask;
int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
return(0);
}
int eNB_trx_write(openair0_device *device,openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
int eNB_id = device->Mod_id;
int CC_id = device->CC_id;
int UE_id;
int subframe = (timestamp/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10;
for (UE_id=0;UE_id<=NB_UE_INST;UE_id++) {
do_DL_sig(eNB2UE,
int subframe;
int ready_for_new_subframe=0;
int subframe_eNB_mask_local;
int sample_count=0;
*ptimestamp = last_eNB_rx_timestamp[eNB_id][CC_id];
LOG_D(PHY,"eNB_trx_read nsamps %d TS(%llu,%llu) => subframe %d\n",nsamps,
(unsigned long long)current_eNB_rx_timestamp[eNB_id][CC_id],
(unsigned long long)last_eNB_rx_timestamp[eNB_id][CC_id],
(*ptimestamp/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10);
// if we're at a subframe boundary generate UL signals for this eNB
while (sample_count<nsamps) {
while (current_eNB_rx_timestamp[eNB_id][CC_id]<
(nsamps+last_eNB_rx_timestamp[eNB_id][CC_id])) {
LOG_D(EMU,"eNB: current TS %llu, last TS %llu, sleeping\n",current_eNB_rx_timestamp[eNB_id][CC_id],last_eNB_rx_timestamp[eNB_id][CC_id]);
usleep(500);
}
// tell top-level we are busy
pthread_mutex_lock(&subframe_mutex);
subframe_eNB_mask|=(1<<eNB_id);
pthread_mutex_unlock(&subframe_mutex);
subframe = (last_eNB_rx_timestamp[eNB_id][CC_id]/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10;
LOG_D(PHY,"eNB_trx_read generating UL subframe %d (Ts %llu, current TS %llu)\n",
subframe,(unsigned long long)*ptimestamp,
(unsigned long long)current_eNB_rx_timestamp[eNB_id][CC_id]);
do_UL_sig(UE2eNB,
enb_data,
ue_data,
subframe,
0, //abstraction_flag,
0, // abstraction_flag
&PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms,
UE_id,
0, // frame is only used for abstraction
eNB_id,
CC_id);
last_eNB_rx_timestamp[eNB_id][CC_id] += PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti;
sample_count += PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti;
}
return(0);
return(nsamps);
}
int UE_trx_write(openair0_device *device,openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
int UE_id = device->Mod_id;
int CC_id = device->CC_id;
int eNB_id;
int subframe = (timestamp/PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)%10;
int subframe;
int ready_for_new_subframe=0;
int subframe_UE_mask_local;
int sample_count=0;
int read_size;
for (eNB_id=0;eNB_id<=NB_eNB_INST;eNB_id++) {
do_UL_sig(UE2eNB,
*ptimestamp = last_UE_rx_timestamp[UE_id][CC_id];
LOG_D(PHY,"UE_trx_read nsamps %d TS(%llu,%llu)\n",nsamps,
(unsigned long long)current_UE_rx_timestamp[UE_id][CC_id],
(unsigned long long)last_UE_rx_timestamp[UE_id][CC_id]);
if (nsamps < PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)
read_size = nsamps;
else
read_size = PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti;
while (sample_count<nsamps) {
while (current_UE_rx_timestamp[UE_id][CC_id] <
(last_UE_rx_timestamp[UE_id][CC_id]+read_size)) {
LOG_D(EMU,"UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]);
usleep(500);
}
LOG_D(EMU,"UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]);
// tell top-level we are busy
pthread_mutex_lock(&subframe_mutex);
subframe_UE_mask|=(1<<UE_id);
pthread_mutex_unlock(&subframe_mutex);
// if we didn't ask for at least a subframe's worth of samples return
// otherwise we have one subframe here so generate the received signal
subframe = (last_UE_rx_timestamp[UE_id][CC_id]/PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)%10;
if ((last_UE_rx_timestamp[UE_id][CC_id]%PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti) > 0)
subframe++;
last_UE_rx_timestamp[UE_id][CC_id] += read_size;
sample_count += read_size;
if (subframe > 9)
return(nsamps);
LOG_D(PHY,"UE_trx_read generating DL subframe %d (Ts %llu, current TS %llu)\n",
subframe,(unsigned long long)*ptimestamp,
(unsigned long long)current_UE_rx_timestamp[UE_id][CC_id]);
do_DL_sig(eNB2UE,
enb_data,
ue_data,
subframe,
0, // abstraction_flag
&PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms,
0, // frame is only used for abstraction
eNB_id,
0, //abstraction_flag,
&PHY_vars_UE_g[UE_id][CC_id]->frame_parms,
UE_id,
CC_id);
}
return(0);
return(nsamps);
}
int eNB_trx_write(openair0_device *device,openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
return(nsamps);
}
int UE_trx_write(openair0_device *device,openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
return(nsamps);
}
void init_devices(void){
......@@ -1055,8 +1141,10 @@ void init_devices(void){
PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_stop_func = eNB_trx_stop;
PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_set_freq_func = eNB_trx_set_freq;
PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_set_gains_func = eNB_trx_set_gains;
current_eNB_rx_timestamp[eNB_id][CC_id] = PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti;
last_eNB_rx_timestamp[eNB_id][CC_id] = 0;
}
for (UE_id=0;UE_id<NB_eNB_INST;UE_id++) {
for (UE_id=0;UE_id<NB_UE_INST;UE_id++) {
PHY_vars_UE_g[UE_id][CC_id]->rfdevice.Mod_id = UE_id;
PHY_vars_UE_g[UE_id][CC_id]->rfdevice.CC_id = CC_id;
PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_start_func = UE_trx_start;
......@@ -1066,6 +1154,9 @@ void init_devices(void){
PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_stop_func = UE_trx_stop;
PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_set_freq_func = UE_trx_set_freq;
PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_set_gains_func = UE_trx_set_gains;
current_UE_rx_timestamp[UE_id][CC_id] = PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti;
last_UE_rx_timestamp[UE_id][CC_id] = 0;
}
}
}
......@@ -1123,7 +1214,11 @@ void init_openair1(void)
//N_TA_offset
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
PHY_vars_UE_g[UE_id][CC_id]->use_ia_receiver = 0;
PHY_vars_UE_g[UE_id][CC_id]->mode = normal_txrx;
PHY_vars_UE_g[UE_id][CC_id]->mac_enabled = 1;
PHY_vars_UE_g[UE_id][CC_id]->no_timing_correction = 1;
if (PHY_vars_UE_g[UE_id][CC_id]->frame_parms.frame_type == TDD) {
if (PHY_vars_UE_g[UE_id][CC_id]->frame_parms.N_RB_DL == 100)
......@@ -1396,7 +1491,7 @@ void update_ocm()
enb_data[eNB_id]->tx_power_dBm = PHY_vars_eNB_g[eNB_id][0]->frame_parms.pdsch_config_common.referenceSignalPower;
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++)
ue_data[UE_id]->tx_power_dBm = PHY_vars_UE_g[UE_id][0]->tx_power_dBm;
ue_data[UE_id]->tx_power_dBm = PHY_vars_UE_g[UE_id][0]->tx_power_dBm[0];
/* check if the openair channel model is activated used for PHY abstraction : path loss*/
......@@ -1450,10 +1545,10 @@ void update_ocm()
UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB = -132.24 + sinr_dB - PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.pdsch_config_common.referenceSignalPower;
}
LOG_I(OCM,"Path loss from eNB %d to UE %d (CCid %d)=> %f dB (eNB TX %d, SNR %f)\n",eNB_id,UE_id,CC_id,
LOG_D(OCM,"Path loss from eNB %d to UE %d (CCid %d)=> %f dB (eNB TX %d, SNR %f)\n",eNB_id,UE_id,CC_id,
eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB,
PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.pdsch_config_common.referenceSignalPower,snr_dB);
// printf("[SIM] Path loss from UE %d to eNB %d => %f dB\n",UE_id,eNB_id,UE2eNB[UE_id][eNB_id]->path_loss_dB);
}
}
}
......@@ -1721,3 +1816,14 @@ void init_time()
td_avg = TARGET_SF_TIME_NS;
}
int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params) {
return(0);
}
int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) {
return(0);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment