Commit 8a88d9b7 authored by Florian Kaltenberger's avatar Florian Kaltenberger

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5053 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 56572a19
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
*******************************************************************************/ *******************************************************************************/
/*! \file synctest.c /*! \file lte-softmodem.c
* \brief main program to control HW and scheduling * \brief main program to control HW and scheduling
* \author R. Knopp, F. Kaltenberger * \author R. Knopp, F. Kaltenberger
* \date 2012 * \date 2012
...@@ -51,119 +51,146 @@ ...@@ -51,119 +51,146 @@
#include <execinfo.h> #include <execinfo.h>
#include <getopt.h> #include <getopt.h>
#include <rtai_lxrt.h> #include "rt_wrapper.h"
#include <rtai_sem.h>
#include <rtai_msg.h>
#include "PHY/types.h" #include "PHY/types.h"
#include "PHY/defs.h" //#include "PHY/defs.h"
#include "openair0_lib.h"
#include "ARCH/COMMON/defs.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/cbmimo1_device.h" #include "UTIL/LOG/log.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/cbmimo1_pci.h" #include "UTIL/LOG/vcd_signal_dumper.h"
#include "SIMULATION/LTE_PHY/openair_hw.h"
#if defined(ENABLE_ITTI)
#include "PHY/vars.h" # include "intertask_interface_init.h"
#include "MAC_INTERFACE/vars.h" # include "timer.h"
#include "SCHED/vars.h" # if defined(ENABLE_USE_MME)
#include "ARCH/CBMIMO1/DEVICE_DRIVER/vars.h" # include "s1ap_eNB.h"
#include "LAYER2/MAC/vars.h" # include "sctp_eNB_task.h"
# endif
#include "../../SIMU/USER/init_lte.h"
#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif #endif
#ifdef OPENAIR2
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/vars.h"
#ifndef CELLULAR
#include "RRC/LITE/vars.h"
#endif
#include "PHY_INTERFACE/vars.h"
#endif
#include "UTIL/LOG/log_extern.h"
#include "UTIL/OTG/otg.h"
#include "UTIL/OTG/otg_vars.h"
#include "UTIL/MATH/oml.h"
#ifdef XFORMS #ifdef XFORMS
#include <forms.h> #include "PHY/TOOLS/lte_phy_scope.h"
#include "lte_scope.h"
//#include "USERSPACE_TOOLS/SCOPE/lte_scope.h"
#include "stats.h" #include "stats.h"
FD_lte_scope *form_dl=NULL; // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
// at eNB 0, an UL scope for every UE
FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX];
FD_lte_phy_scope_enb *form_enb[NUMBER_OF_UE_MAX];
FD_stats_form *form_stats=NULL; FD_stats_form *form_stats=NULL;
char title[255];
unsigned char scope_enb_num_ue = 1;
#endif //XFORMS #endif //XFORMS
#define FRAME_PERIOD 100000000ULL #ifdef EMOS
#define DAQ_PERIOD 66666ULL #include <gps.h>
#include <rtai_fifos.h>
//#define CHANSOUNDER_FIFO_SIZE 10485760 // 10 Mbytes FIFO
#define CHANSOUNDER_FIFO_SIZE 20971520 // 20 Mbytes FIFO
#define CHANSOUNDER_FIFO_MINOR 4 // minor of the FIFO device - this is /dev/rtf3
#define CHANSOUNDER_FIFO_DEV "/dev/rtf4"
#endif
#define TIMER_ONESHOT_MODE
#define FRAME_PERIOD 100000000ULL
#define DAQ_PERIOD 66667ULL
#define LTE_SLOTS_PER_FRAME 20
#define RESAMPLING_FACTOR 2
#define SAMPLES_PER_SLOT (15360/(1<<RESAMPLING_FACTOR))
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
#ifdef RTAI
static SEM *mutex; static SEM *mutex;
//static CND *cond; //static CND *cond;
static int thread0; static long int thread0;
static int thread1; static long int thread1;
static int sync_thread; //static long int sync_thread;
#else
#define OPENAIR_THREAD_STACK_SIZE 8192
#define OPENAIR_THREAD_PRIORITY 255
pthread_t thread0;
//pthread_t thread1;
pthread_attr_t attr_dlsch_threads;
struct sched_param sched_param_dlsch;
#endif
pthread_t thread2; pthread_t thread2; //xforms
pthread_t thread3; //emos
/*
static int instance_cnt=-1; //0 means worker is busy, -1 means its free static int instance_cnt=-1; //0 means worker is busy, -1 means its free
int instance_cnt_ptr_kern,*instance_cnt_ptr_user; int instance_cnt_ptr_kern,*instance_cnt_ptr_user;
int pci_interface_ptr_kern; int pci_interface_ptr_kern;
*/
//extern unsigned int bigphys_top;
//extern unsigned int mem_base;
extern unsigned int bigphys_top; int card = 0;
extern unsigned int mem_base; exmimo_config_t *p_exmimo_config;
exmimo_id_t *p_exmimo_id;
int openair_fd = 0; volatile unsigned int *DAQ_MBOX;
int oai_exit = 0; int oai_exit = 0;
//PCI_interface_t *pci_interface[3];
unsigned int *DAQ_MBOX;
//int time_offset[4] = {-138,-138,-138,-138}; //int time_offset[4] = {-138,-138,-138,-138};
int time_offset[4] = {-145,-145,-145,-145}; //int time_offset[4] = {-145,-145,-145,-145};
//int time_offset[4] = {0,0,0,0}; int time_offset[4] = {0,0,0,0};
int fs4_test=0; int fs4_test=0;
char UE_flag=0; char UE_flag=0;
u8 eNB_id=0,UE_id=0;
u32 carrier_freq[4]= {1907600000,1907600000,1907600000,1907600000};
struct timing_info_t { struct timing_info_t {
unsigned int frame, hw_slot, last_slot, next_slot; //unsigned int frame, hw_slot, last_slot, next_slot;
RTIME time0, time1, time2; RTIME time_min, time_max, time_avg, time_last, time_now;
unsigned int mbox0, mbox1, mbox2, mbox_target; //unsigned int mbox0, mbox1, mbox2, mbox_target;
} timing_info[20]; unsigned int n_samples;
} timing_info;
extern s16* sync_corr_ue0; extern s16* sync_corr_ue0;
extern s16 prach_ifft[4][1024*2]; extern s16 prach_ifft[4][1024*2];
runmode_t mode;
int rx_input_level_dBm; int rx_input_level_dBm;
int otg_enabled = 0; #ifdef XFORMS
extern int otg_enabled;
#else
int otg_enabled;
#endif
int number_of_cards = 1;
int mbox_bounds[20] = {8,16,24,30,38,46,54,60,68,76,84,90,98,106,114,120,128,136,144, 0}; ///boundaries of slots in terms ob mbox counter rounded up to even numbers
//int mbox_bounds[20] = {6,14,22,28,36,44,52,58,66,74,82,88,96,104,112,118,126,134,142, 148}; ///boundaries of slots in terms ob mbox counter rounded up to even numbers
int init_dlsch_threads(void); int init_dlsch_threads(void);
void cleanup_dlsch_threads(void); void cleanup_dlsch_threads(void);
s32 init_rx_pdsch_thread(void);
void cleanup_rx_pdsch_thread(void);
int init_ulsch_threads(void);
void cleanup_ulsch_threads(void);
LTE_DL_FRAME_PARMS *frame_parms; //void setup_ue_buffers(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms, int carrier);
#ifdef EXMIMO //void setup_eNB_buffers(PHY_VARS_eNB *phy_vars_eNB, LTE_DL_FRAME_PARMS *frame_parms, int carrier);
u32 carrier_freq[4]= {1907600000,1907600000,1907600000,1907600000}; void test_config(int card, int ant, unsigned int rf_mode, int UE_flag);
#endif
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq)
{
return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
}
unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe)
{
return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
}
void signal_handler(int sig) void signal_handler(int sig)
{ {
void *array[10]; void *array[10];
size_t size; size_t size;
oai_exit=1; if (sig==SIGSEGV) {
// get void*'s for all entries on the stack // get void*'s for all entries on the stack
size = backtrace(array, 10); size = backtrace(array, 10);
...@@ -171,320 +198,37 @@ void signal_handler(int sig) ...@@ -171,320 +198,37 @@ void signal_handler(int sig)
fprintf(stderr, "Error: signal %d:\n", sig); fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, 2); backtrace_symbols_fd(array, size, 2);
exit(-1); exit(-1);
}
else {
oai_exit=1;
}
} }
void exit_fun(const char* s) void exit_fun(const char* s)
{ {
void *array[10]; void *array[10];
size_t size; size_t size;
int fd;
printf("Exiting: %s\n",s); printf("Exiting: %s\n",s);
oai_exit=1; oai_exit=1;
rt_sleep(nano2count(FRAME_PERIOD)); //rt_sleep_ns(FRAME_PERIOD);
// cleanup
stop_rt_timer();
fd = 0;
ioctl(openair_fd,openair_STOP,&fd);
munmap((void*)mem_base, BIGPHYS_NUMPAGES*4096);
exit (-1); //exit (-1);
} }
#ifdef XFORMS #ifdef XFORMS
void ia_receiver_on_off( FL_OBJECT *button, long arg) { void *scope_thread(void *arg) {
if (fl_get_button(button)) {
if (UE_flag==1) {
fl_set_object_label(button, "IA Receiver ON");
openair_daq_vars.use_ia_receiver = 1;
fl_set_object_color(button, FL_GREEN, FL_GREEN);
// LOG_I(PHY,"Pressed the button: IA receiver ON\n");
}
else {
fl_set_object_label(button, "DL traffic ON");
fl_set_object_color(button, FL_GREEN, FL_GREEN);
otg_enabled = 1;
}
}
else {
if (UE_flag==1) {
fl_set_object_label(button, "IA Receiver OFF");
openair_daq_vars.use_ia_receiver = 0;
fl_set_object_color(button, FL_RED, FL_RED);
// LOG_I(PHY,"Pressed the button: IA receiver OFF\n");
}
else {
fl_set_object_label(button, "DL traffic OFF");
fl_set_object_color(button, FL_RED, FL_RED);
otg_enabled = 0;
}
}
}
void do_forms2(FD_lte_scope *form,
LTE_DL_FRAME_PARMS *frame_parms,
int pdcch_symbols,
int UE_flag,
s16 **channel,
s16 **channel_f,
s16 **rx_sig,
s16 **rx_sig_f,
s16 *pdcch_comp,
s16 *dlsch_comp,
s16 *dlsch_comp_i,
s16 *dlsch_llr,
s16 *pbch_comp,
s8 *pbch_llr,
u32 *avg_tput,
u32 *avg_tput_time,
u16 tput_window,
s16 coded_bits_per_codeword,
s16 *sync_corr,
s16 sync_corr_len)
{
int i,j,k,s;
int aa, xx=128, yy=128;//b
float x_label[300], y_label[300];//b
float Re,Im;
float mag_sig[NB_ANTENNAS_RX*4*NUMBER_OF_OFDM_CARRIERS*NUMBER_OF_OFDM_SYMBOLS_PER_SLOT],
sig_time[NB_ANTENNAS_RX*4*NUMBER_OF_OFDM_CARRIERS*NUMBER_OF_OFDM_SYMBOLS_PER_SLOT],
sig2[FRAME_LENGTH_COMPLEX_SAMPLES],
time2[FRAME_LENGTH_COMPLEX_SAMPLES],
I[25*12*11*4], Q[25*12*11*4],tput[tput_window],tput_time[tput_window],
*llr,*llr_time;
int ind;
float avg, cum_avg,tput_max=0;
int nb_tx_ant = (UE_flag==1 ? frame_parms->nb_antennas_tx_eNB : 1);
int nb_ce_symb = (UE_flag==1 ? 1 : frame_parms->symbols_per_tti);
llr = malloc(coded_bits_per_codeword*sizeof(float));
llr_time = malloc(coded_bits_per_codeword*sizeof(float));
// Channel frequency response
if ((channel_f != NULL) && (channel_f[0] != NULL))
{
cum_avg = 0;
ind = 0;
for (j=0; j<nb_tx_ant; j++)
{
for (i=0; i<frame_parms->nb_antennas_rx; i++)
{
for (k=0; k<(12*frame_parms->N_RB_DL*nb_ce_symb); k++)
{
sig_time[ind] = (float)ind;
Re = (float)(channel_f[(j<<1)+i][(2*k)]);
Im = (float)(channel_f[(j<<1)+i][(2*k)+1]);
//mag_sig[ind] = (short) rand();
mag_sig[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im));
cum_avg += (short)sqrt((double)Re*Re + (double)Im*Im) ;
ind++;
}
// ind+=NUMBER_OF_OFDM_CARRIERS/4; // spacing for visualization
}
}
avg = cum_avg/NUMBER_OF_USEFUL_CARRIERS;
//fl_set_xyplot_ybounds(form->channel_f,30,70);
fl_set_xyplot_data(form->channel_f,sig_time,mag_sig,ind,"","","");
}
// time domain channel
if ((channel != NULL) && (channel[0] !=NULL))
{
for (i=0; i<512; i++)
{
time2[i] = (float) i;
sig2[i] = (float) (channel[0][4*i]*channel[0][4*i]+channel[0][4*i+1]*channel[0][4*i+1]);
}
fl_set_xyplot_data(form->channel_t_im,time2,sig2,128,"","","");
//fl_set_xyplot_ybounds(form->channel_t_im,0,1e6);
}
/*
// sync_corr
if (sync_corr != NULL)
{
for (i=0; i<sync_corr_len; i++)
{
time2[i] = (float) i;
sig2[i] = (float) sync_corr[i];
}
fl_set_xyplot_data(form->channel_t_im,time2,sig2,sync_corr_len,"","","");
//fl_set_xyplot_ybounds(form->channel_t_im,0,1e6);
}
*/
// rx sig 0
if (rx_sig != NULL) {
if (rx_sig[0] != NULL)
{
//for (i=30720; i<38400; i++)
//for (i=0; i<NUMBER_OF_OFDM_CARRIERS*frame_parms->symbols_per_tti/2; i++) {
for (i=0; i<FRAME_LENGTH_COMPLEX_SAMPLES; i++)
{
sig2[i] = 10*log10(1.0+(double) ((rx_sig[0][2*i])*(rx_sig[0][2*i])+(rx_sig[0][2*i+1])*(rx_sig[0][2*i+1])));
//sig2[i] = (float) ((rx_sig[0][2*i]));
time2[i] = (float) i;
}
fl_set_xyplot_ybounds(form->channel_t_re,30,70);
//fl_set_xyplot_data(form->channel_t_re,&time2[640*12*6],&sig2[640*12*6],640*12,"","","");
fl_set_xyplot_data(form->channel_t_re,time2,sig2,FRAME_LENGTH_COMPLEX_SAMPLES,"","","");
}
/*
// rx sig 1
if (rx_sig[1] !=NULL) {
//for (i=30720; i<38400; i++)
for (i=0; i<FRAME_LENGTH_COMPLEX_SAMPLES; i++)
{
sig2[i] = 10*log10(1.0+(double) ((rx_sig[1][2*i])*(rx_sig[1][2*i])+(rx_sig[1][2*i+1])*(rx_sig[1][2*i+1])));
//sig2[i] = (float) ((rx_sig[1][2*i]));
time2[i] = (float) i;
}
fl_set_xyplot_ybounds(form->channel_t_im,30,70);
//fl_set_xyplot_data(form->channel_t_im,&time2[640*12*6],&sig2[640*12*6],640*12,"","","");
fl_set_xyplot_data(form->channel_t_im,time2,sig2,FRAME_LENGTH_COMPLEX_SAMPLES,"","","");
}
*/
}
// PBCH LLR
if (pbch_llr!=NULL)
{
j=0;
for (i=0; i<1920; i++)
{
llr[j] = (float) pbch_llr[i];
llr_time[j] = (float) j;
//if (i==63)
// i=127;
//else if (i==191)
// i=319;
j++;
}
fl_set_xyplot_data(form->decoder_input,llr_time,llr,1920,"","","");
//fl_set_xyplot_ybounds(form->decoder_input,-100,100);
}
// PBCH I/Q
if (pbch_comp!=NULL)
{
j=0;
for (i=0; i<12*12; i++)
{
I[j] = pbch_comp[2*i];
Q[j] = pbch_comp[2*i+1];
j++;
//if (i==47)
// i=96;
//else if (i==191)
// i=239;
}
fl_set_xyplot_data(form->scatter_plot,I,Q,12*12,"","","");
fl_set_xyplot_xbounds(form->scatter_plot,-100,100);
fl_set_xyplot_ybounds(form->scatter_plot,-100,100);
}
// PDCCH I/Q
if (pdcch_comp!=NULL)
{
j=0;
for (i=0; i<12*25*1; i++)
{
I[j] = pdcch_comp[2*i];
Q[j] = pdcch_comp[2*i+1];
j++;
}
fl_set_xyplot_data(form->scatter_plot1,I,Q,12*25*1,"","","");
fl_set_xyplot_xbounds(form->scatter_plot1,-100,100);
fl_set_xyplot_ybounds(form->scatter_plot1,-100,100);
}
// DLSCH LLR
if (dlsch_llr != NULL)
{
for (i=0; i<coded_bits_per_codeword; i++)
{
llr[i] = (float) dlsch_llr[i];
llr_time[i] = (float) i;
}
fl_set_xyplot_data(form->demod_out,llr_time,llr,coded_bits_per_codeword,"","","");
// fl_set_xyplot_ybounds(form->demod_out,-1000,1000);
}
else
printf("lls==NULL\n");
// DLSCH I/Q
if (dlsch_comp!=NULL)
{
j=0;
for (s=pdcch_symbols; s<frame_parms->symbols_per_tti; s++)
{
for (i=0; i<12*25; i++)
{
I[j] = dlsch_comp[(2*25*12*s)+2*i];
Q[j] = dlsch_comp[(2*25*12*s)+2*i+1];
j++;
}
//if (s==2)
// s=3;
//else if (s==5)
// s=6;
//else if (s==8)
// s=9;
}
fl_set_xyplot_data(form->scatter_plot2,I,Q,j,"","","");
//fl_set_xyplot_xbounds(form->scatter_plot2,-100,100);
//fl_set_xyplot_ybounds(form->scatter_plot2,-100,100);
}
// Throughput
if (avg_tput!=NULL) {
for (i=0; i<tput_window; i++) {
tput[i] = (float) avg_tput[i];
tput_time[i] = (float) avg_tput_time[i];
if (tput[i] > tput_max) {
tput_max = tput[i];
}
}
fl_set_xyplot_data(form->tput,tput_time,tput,tput_window,"","","");
fl_set_xyplot_ybounds(form->tput,0,tput_max);
}
fl_check_forms();
free(llr);
free(llr_time);
}
void *scope_thread(void *arg)
{
s16 prach_corr[1024], i; s16 prach_corr[1024], i;
char stats_buffer[16384]; char stats_buffer[16384];
//FILE *UE_stats, *eNB_stats; //FILE *UE_stats, *eNB_stats;
int len=0; int len=0;
u16 tput_window = 100; struct sched_param sched_param;
unsigned int avg_tput_eNB[tput_window];
unsigned int avg_tput_UE[tput_window]; sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
unsigned int tput_time_UE[tput_window]; sched_setscheduler(0, SCHED_FIFO,&sched_param);
unsigned int tput_time_eNB[tput_window];
memset((void*) avg_tput_UE,0,sizeof(unsigned int)*tput_window); printf("Scope thread has priority %d\n",sched_param.sched_priority);
memset((void*) avg_tput_eNB,0,sizeof(unsigned int)*tput_window);
memset((void*) tput_time_UE,0,sizeof(unsigned int)*tput_window);
memset((void*) tput_time_eNB,0,sizeof(unsigned int)*tput_window);
/* /*
if (UE_flag==1) if (UE_flag==1)
...@@ -493,629 +237,361 @@ void *scope_thread(void *arg) ...@@ -493,629 +237,361 @@ void *scope_thread(void *arg)
eNB_stats = fopen("eNB_stats.txt", "w"); eNB_stats = fopen("eNB_stats.txt", "w");
*/ */
while (!oai_exit) while (!oai_exit) {
{
if (UE_flag==1) { if (UE_flag==1) {
len = dump_ue_stats (PHY_vars_UE_g[0], stats_buffer, 0, mode,rx_input_level_dBm); len = dump_ue_stats (PHY_vars_UE_g[0], stats_buffer, 0, mode,rx_input_level_dBm);
fl_set_object_label(form_stats->stats_text, stats_buffer); fl_set_object_label(form_stats->stats_text, stats_buffer);
//rewind (UE_stats); //rewind (UE_stats);
//fwrite (stats_buffer, 1, len, UE_stats); //fwrite (stats_buffer, 1, len, UE_stats);
/*
if (PHY_vars_UE_g[0]->frame<tput_window) { phy_scope_UE(form_ue[UE_id],
avg_tput_UE[PHY_vars_UE_g[0]->frame] = PHY_vars_UE_g[0]->bitrate[0]/1000; PHY_vars_UE_g[UE_id],
tput_time_UE[PHY_vars_UE_g[0]->frame] = PHY_vars_UE_g[0]->frame; eNB_id,
} UE_id,7);
else {
*/ } else {
memcpy((void*)avg_tput_UE,(void*)&avg_tput_UE[1],(tput_window-1)*sizeof(unsigned int));
memcpy((void*)tput_time_UE,(void*)&tput_time_UE[1],(tput_window-1)*sizeof(unsigned int));
avg_tput_UE[tput_window-1] = PHY_vars_UE_g[0]->bitrate[0]/1000;
tput_time_UE[tput_window-1] = PHY_vars_UE_g[0]->frame;
do_forms2(form_dl,
&(PHY_vars_UE_g[0]->lte_frame_parms),
PHY_vars_UE_g[0]->lte_ue_pdcch_vars[0]->num_pdcch_symbols,
UE_flag,
(s16**)PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates_time[0],
(s16**)PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[0],
(s16**)PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata,
(s16**)PHY_vars_UE_g[0]->lte_ue_common_vars.rxdataF,
(s16*)PHY_vars_UE_g[0]->lte_ue_pdcch_vars[0]->rxdataF_comp[0],
(s16*)PHY_vars_UE_g[0]->lte_ue_pdsch_vars[0]->rxdataF_comp[0],
(s16*)PHY_vars_UE_g[0]->lte_ue_pdsch_vars[1]->rxdataF_comp[0],
(s16*)PHY_vars_UE_g[0]->lte_ue_pdsch_vars[0]->llr[0],
(s16*)PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->rxdataF_comp[0],
(s8*)PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->llr,
avg_tput_UE,
tput_time_UE,
tput_window,
15000,
/*get_G(&PHY_vars_UE_g[0]->lte_frame_parms,
PHY_vars_UE_g[0]->dlsch_ue[0][0]->nb_rb,
PHY_vars_UE_g[0]->dlsch_ue[0][0]->rb_alloc,
get_Qm(PHY_vars_UE_g[0]->dlsch_ue[0][0]->harq_processes[0]->mcs),
PHY_vars_UE_g[0]->lte_ue_pdcch_vars[0]->num_pdcch_symbols,7),*/
sync_corr_ue0,
PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti*10);
}
else {
len = dump_eNB_stats (PHY_vars_eNB_g[0], stats_buffer, 0); len = dump_eNB_stats (PHY_vars_eNB_g[0], stats_buffer, 0);
fl_set_object_label(form_stats->stats_text, stats_buffer); fl_set_object_label(form_stats->stats_text, stats_buffer);
//rewind (eNB_stats); //rewind (eNB_stats);
//fwrite (stats_buffer, 1, len, eNB_stats); //fwrite (stats_buffer, 1, len, eNB_stats);
for(UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
/* phy_scope_eNB(form_enb[UE_id],
if (PHY_vars_eNB_g[0]->frame<tput_window) { PHY_vars_eNB_g[eNB_id],
avg_tput_eNB[PHY_vars_UE_g[0]->frame] = PHY_vars_UE_g[0]->bitrate[0]/1000; UE_id);
tput_time_UE[PHY_vars_UE_g[0]->frame] = PHY_vars_UE_g[0]->frame;
} }
else {
*/
memcpy((void*)avg_tput_eNB,(void*)&avg_tput_eNB[1],(tput_window-1)*sizeof(unsigned int));
memcpy((void*)tput_time_eNB,(void*)&tput_time_eNB[1],(tput_window-1)*sizeof(unsigned int));
avg_tput_eNB[tput_window-1] = PHY_vars_eNB_g[0]->total_dlsch_bitrate/1000;
tput_time_eNB[tput_window-1] = PHY_vars_eNB_g[0]->frame;
for (i=0;i<1024;i++)
prach_corr[i] = ((s32)prach_ifft[0][i<<2]*prach_ifft[0][i<<2]+
(s32)prach_ifft[0][1+(i<<2)]*prach_ifft[0][1+(i<<2)]) >> 15;
do_forms2(form_dl,
&(PHY_vars_eNB_g[0]->lte_frame_parms),
0,
UE_flag,
(s16**)PHY_vars_eNB_g[0]->lte_eNB_pusch_vars[0]->drs_ch_estimates_time[0],
(s16**)PHY_vars_eNB_g[0]->lte_eNB_pusch_vars[0]->drs_ch_estimates[0],
(s16**)PHY_vars_eNB_g[0]->lte_eNB_common_vars.rxdata[0],
(s16**)PHY_vars_eNB_g[0]->lte_eNB_common_vars.rxdataF[0],
NULL,
(s16*)PHY_vars_eNB_g[0]->lte_eNB_pusch_vars[0]->rxdataF_comp[0][0],
NULL,
(s16*)PHY_vars_eNB_g[0]->lte_eNB_pusch_vars[0]->llr,
NULL,
NULL,
avg_tput_eNB,
tput_time_eNB,
tput_window,
PHY_vars_eNB_g[0]->ulsch_eNB[0]->harq_processes[0]->nb_rb*12*get_Qm(PHY_vars_eNB_g[0]->ulsch_eNB[0]->harq_processes[0]->mcs)*PHY_vars_eNB_g[0]->ulsch_eNB[0]->Nsymb_pusch,
prach_corr,
1024);
} }
//printf("doing forms\n"); //printf("doing forms\n");
usleep(100000); // 100 ms sleep(0.1);
} }
//fclose (UE_stats); //fclose (UE_stats);
//fclose (eNB_stats); //fclose (eNB_stats);
return (void*)(1); pthread_exit((void*)arg);
} }
#endif #endif
int dummy_tx_buffer[3840*4] __attribute__((aligned(16))); int dummy_tx_buffer[3840*4] __attribute__((aligned(16)));
static void *sync_hw(void *arg) #ifdef EMOS
{ #define NO_ESTIMATES_DISK 20 //No. of estimates that are aquired before dumped to disk
RT_TASK *task; int channel_buffer_size = SAMPLES_PER_SLOT*4; //one slot, 4 byte per sample
task = rt_task_init_schmod(nam2num("TASK2"), 0, 0, 0, SCHED_FIFO, 0xF);
mlockall(MCL_CURRENT | MCL_FUTURE);
rt_printk("fun0: task %p\n",task);
#ifdef HARD_RT void *emos_thread (void *arg)
rt_make_hard_real_time(); {
#endif char c;
char *fifo2file_buffer, *fifo2file_ptr;
while (!oai_exit) int fifo, counter=0, bytes;
{ long long unsigned int total_bytes=0;
rt_printk("exmimo_pci_interface->mbox = %d\n",((unsigned int *)DAQ_MBOX)[0]); FILE *dumpfile_id;
char dumpfile_name[1024];
time_t starttime_tmp;
struct tm starttime;
rt_sleep(nano2count(FRAME_PERIOD*10)); time_t timer;
} struct tm *now;
} struct gps_data_t *gps_data = NULL;
struct gps_fix_t dummy_gps_data;
struct sched_param sched_param;
int ret;
/* This is the main eNB thread. It gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */ sched_param.sched_priority = sched_get_priority_max(SCHED_FIFO)-1;
static void *eNB_thread(void *arg) sched_setscheduler(0, SCHED_FIFO,&sched_param);
{
RT_TASK *task;
int slot=0,hw_slot,last_slot, next_slot,frame=0;
unsigned int msg1;
unsigned int aa,slot_offset, slot_offset_F;
int diff;
int delay_cnt;
RTIME time_in;
int mbox_target=0,mbox_current=0;
int i;
int tx_offset;
task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF); printf("EMOS thread has priority %d\n",sched_param.sched_priority);
mlockall(MCL_CURRENT | MCL_FUTURE);
rt_printk("Started eNB thread (id %p)\n",task); timer = time(NULL);
now = localtime(&timer);
#ifdef HARD_RT memset(&dummy_gps_data,1,sizeof(struct gps_fix_t));
rt_make_hard_real_time();
#endif
while (!oai_exit) #if GPSD_API_MAJOR_VERSION>=5
ret = gps_open("127.0.0.1","2947",gps_data);
if (ret!=0)
#else
gps_data = gps_open("127.0.0.1","2947");
if (gps_data == NULL)
#endif
{ {
// rt_printk("eNB: slot %d\n",slot); printf("[EMOS] Could not open GPS\n");
//exit(-1);
#ifdef CBMIMO1 }
rt_sem_wait(mutex); #if GPSD_API_MAJOR_VERSION>=4
/* else if (gps_stream(gps_data, WATCH_ENABLE,NULL) != 0)
if ((slot%2000)<10) #else
rt_printk("fun0: Hello World %d, instance_cnt %d!\n",slot,*instance_cnt_ptr_user); else if (gps_query(gps_data, "w+x") != 0)
*/ #endif
while (*instance_cnt_ptr_user<0)
{ {
rt_sem_signal(mutex); //sprintf(tmptxt,"Error sending command to GPS, gps_data = %x", gps_data);
rt_receive(0,&msg1); printf("[EMOS] Error sending command to GPS\n");
rt_sem_wait(mutex); //exit(-1);
/*
if ((slot%2000)<10)
rt_printk("fun0: instance_cnt %d, msg1 %d!\n",*instance_cnt_ptr_user,msg1);
*/
} }
rt_sem_signal(mutex); else
slot = msg1 % LTE_SLOTS_PER_FRAME; printf("[EMOS] Opened GPS, gps_data=%p\n", gps_data);
#else /*
hw_slot = (((((unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15; if (UE_flag==0)
//this is the mbox counter where we should be channel_buffer_size = sizeof(fifo_dump_emos_eNB);
mbox_target = ((((slot+1)%20)*15+1)>>1)%150;
//this is the mbox counter where we are
mbox_current = ((unsigned int *)DAQ_MBOX)[0];
//this is the time we need to sleep in order to synchronize with the hw (in multiples of DAQ_PERIOD)
if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround
diff = 150-mbox_current+mbox_target;
else if ((mbox_current<15) && (mbox_target>=135))
diff = -150+mbox_target-mbox_current;
else else
diff = mbox_target - mbox_current; channel_buffer_size = sizeof(fifo_dump_emos_UE);
*/
if (diff < (-5)) { // allocate memory for NO_FRAMES_DISK channes estimations
rt_printk("eNB Frame %d: missed slot, proceeding with next one (slot %d, hw_slot %d, diff %d)\n",frame, slot, hw_slot, diff); fifo2file_buffer = malloc(NO_ESTIMATES_DISK*channel_buffer_size);
slot++; fifo2file_ptr = fifo2file_buffer;
if (slot==20)
slot=0;
continue;
}
if (diff>8)
rt_printk("eNB Frame %d: skipped slot, waiting for hw to catch up (slot %d, hw_slot %d, mbox_current %d, mbox_target %d, diff %d)\n",frame, slot, hw_slot, mbox_current, mbox_target, diff);
delay_cnt = 0; if (fifo2file_buffer == NULL)
while ((diff>0) && (!oai_exit))
{ {
time_in = rt_get_time_ns(); printf("[EMOS] Cound not allocate memory for fifo2file_buffer\n");
//rt_printk("eNB Frame %d delaycnt %d : hw_slot %d (%d), slot %d, (slot+1)*15=%d, diff %d, time %llu\n",frame,delay_cnt,hw_slot,((unsigned int *)DAQ_MBOX)[0],slot,(((slot+1)*15)>>1),diff,time_in); exit(EXIT_FAILURE);
//rt_printk("Frame %d: slot %d, sleeping for %llu\n", frame, slot, diff*DAQ_PERIOD); }
rt_sleep(nano2count(diff*DAQ_PERIOD));
hw_slot = (((((unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15; if ((fifo = open(CHANSOUNDER_FIFO_DEV, O_RDONLY)) < 0)
//rt_printk("eNB Frame %d : hw_slot %d, time %llu\n",frame,hw_slot,rt_get_time_ns());
delay_cnt++;
if (delay_cnt == 10)
{ {
oai_exit = 1; fprintf(stderr, "[EMOS] Error opening the fifo\n");
rt_printk("eNB Frame %d: HW stopped ... \n",frame); exit(EXIT_FAILURE);
} }
mbox_current = ((unsigned int *)DAQ_MBOX)[0];
if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround
diff = 150-mbox_current+mbox_target; time(&starttime_tmp);
else localtime_r(&starttime_tmp,&starttime);
diff = mbox_target - mbox_current; snprintf(dumpfile_name,1024,"/tmp/%s_data_%d%02d%02d_%02d%02d%02d.EMOS",
(UE_flag==0) ? "eNB" : "UE",
1900+starttime.tm_year, starttime.tm_mon+1, starttime.tm_mday, starttime.tm_hour, starttime.tm_min, starttime.tm_sec);
dumpfile_id = fopen(dumpfile_name,"w");
if (dumpfile_id == NULL)
{
fprintf(stderr, "[EMOS] Error opening dumpfile %s\n",dumpfile_name);
exit(EXIT_FAILURE);
} }
#endif
last_slot = (slot)%LTE_SLOTS_PER_FRAME;
if (last_slot <0)
last_slot+=20;
next_slot = (slot+3)%LTE_SLOTS_PER_FRAME;
//PHY_vars_eNB_g[0]->frame = frame; printf("[EMOS] starting dump, channel_buffer_size=%d ...\n",channel_buffer_size);
if (frame>5) while (!oai_exit)
{ {
bytes = rtf_read_timed(fifo, fifo2file_ptr, channel_buffer_size,100);
if (bytes<=0)
continue;
/* /*
if (frame%100==0) if (UE_flag==0)
rt_printk("frame %d (%d), slot %d, hw_slot %d, next_slot %d (before): DAQ_MBOX %d\n",frame, PHY_vars_eNB_g[0]->frame, slot, hw_slot,next_slot,DAQ_MBOX[0]); printf("eNB: count %d, frame %d, read: %d bytes from the fifo\n",counter, ((fifo_dump_emos_eNB*)fifo2file_ptr)->frame_tx,bytes);
else
printf("UE: count %d, frame %d, read: %d bytes from the fifo\n",counter, ((fifo_dump_emos_UE*)fifo2file_ptr)->frame_rx,bytes);
*/ */
if (fs4_test==0)
{
phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[0], 0);
#ifndef IFFT_FPGA
slot_offset_F = (next_slot)*
(PHY_vars_eNB_g[0]->lte_frame_parms.ofdm_symbol_size)*
((PHY_vars_eNB_g[0]->lte_frame_parms.Ncp==1) ? 6 : 7);
slot_offset = (next_slot)*
(PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti>>1);
if ((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_DL)||
((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_S)&&((next_slot&1)==0)))
{
// rt_printk("Frame %d: Generating slot %d\n",frame,next_slot);
for (aa=0; aa<PHY_vars_eNB_g[0]->lte_frame_parms.nb_antennas_tx; aa++) fifo2file_ptr += channel_buffer_size;
counter ++;
total_bytes += bytes;
if ((counter%NO_ESTIMATES_DISK)==0)
{ {
if (PHY_vars_eNB_g[0]->lte_frame_parms.Ncp == 1) //reset stuff
fifo2file_ptr = fifo2file_buffer;
//counter = 0;
//flush buffer to disk
if (fwrite(fifo2file_buffer, sizeof(char), NO_ESTIMATES_DISK*channel_buffer_size, dumpfile_id) != NO_ESTIMATES_DISK*channel_buffer_size)
{ {
PHY_ofdm_mod(&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdataF[0][aa][slot_offset_F], fprintf(stderr, "[EMOS] Error writing to dumpfile\n");
#ifdef BIT8_TX exit(EXIT_FAILURE);
&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][slot_offset>>1],
#else
dummy_tx_buffer,//&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][slot_offset],
#endif
PHY_vars_eNB_g[0]->lte_frame_parms.log2_symbol_size,
6,
PHY_vars_eNB_g[0]->lte_frame_parms.nb_prefix_samples,
PHY_vars_eNB_g[0]->lte_frame_parms.twiddle_ifft,
PHY_vars_eNB_g[0]->lte_frame_parms.rev,
CYCLIC_PREFIX);
} }
else /*
if (gps_data)
{ {
normal_prefix_mod(&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdataF[0][aa][slot_offset_F], if (gps_poll(gps_data) != 0) {
#ifdef BIT8_TX printf("[EMOS] problem polling data from gps\n");
&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][slot_offset>>1],
#else
dummy_tx_buffer,//&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][slot_offset],
#endif
7,
&(PHY_vars_eNB_g[0]->lte_frame_parms));
} }
#ifdef EXMIMO else {
for (i=0; i<PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti/2; i++) printf("[EMOS] lat %g, lon %g\n",gps_data->fix.latitude,gps_data->fix.longitude);
}
if (fwrite(&(gps_data->fix), sizeof(char), sizeof(struct gps_fix_t), dumpfile_id) != sizeof(struct gps_fix_t))
{ {
tx_offset = (int)slot_offset+time_offset[aa]+i; printf("[EMOS] Error writing to dumpfile, stopping recording\n");
if (tx_offset<0) exit(EXIT_FAILURE);
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti;
if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti;
((short*)&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][tx_offset])[0]=
((short*)dummy_tx_buffer)[2*i]<<4;
((short*)&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][tx_offset])[1]=
((short*)dummy_tx_buffer)[2*i+1]<<4;
} }
#endif //EXMIMO
} }
else
{
printf("[EMOS] WARNING: No GPS data available, storing dummy packet\n");
if (fwrite(&(dummy_gps_data), sizeof(char), sizeof(struct gps_fix_t), dumpfile_id) != sizeof(struct gps_fix_t))
{
printf("[EMOS] Error writing to dumpfile, stopping recording\n");
exit(EXIT_FAILURE);
} }
} }
#endif //IFFT_FPGA
/*
if (frame%100==0)
rt_printk("hw_slot %d (after): DAQ_MBOX %d\n",hw_slot,DAQ_MBOX[0]);
*/ */
} }
if ((counter%2000)==0)
/* printf("[EMOS] count %d (%d sec), total bytes wrote %llu\n", counter, counter/2000, total_bytes);
if ((slot%2000)<10)
rt_printk("fun0: doing very hard work\n");
*/
#ifndef CBMIMO1
slot++;
if (slot==20)
slot=0;
#endif
//slot++;
if ((slot%20)==0)
frame++;
#ifdef CBMIMO1
rt_sem_wait(mutex);
(*instance_cnt_ptr_user)--;
//rt_printk("fun0: instance_cnt %d!\n",*instance_cnt_ptr_user);
rt_sem_signal(mutex);
#endif
} }
rt_printk("fun0: finished, ran %d times.\n",slot); free(fifo2file_buffer);
fclose(dumpfile_id);
close(fifo);
#ifdef HARD_RT pthread_exit((void*) arg);
rt_make_soft_real_time();
#endif
// clean task
rt_task_delete(task);
rt_printk("Task deleted. returning\n");
return 0;
} }
#endif
/* This is the main UE thread. Initially it is doing a periodic get_frame. One synchronized it gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */ /* This is the main eNB thread. It gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */
static void *UE_thread(void *arg) static void *eNB_thread(void *arg)
{ {
#ifdef RTAI
RT_TASK *task; RT_TASK *task;
RTIME in, out, diff; RTIME now;
int slot=0,frame=0,hw_slot,last_slot, next_slot; #endif
unsigned char slot=0,last_slot, next_slot;
int hw_slot,frame=0;
unsigned int msg1; unsigned int msg1;
unsigned int aa,slot_offset, slot_offset_F; unsigned int aa,slot_offset, slot_offset_F;
static int is_synchronized = 0; int diff;
static int received_slots = 0;
static int slot0 = 0;
int delay_cnt; int delay_cnt;
RTIME time_in; RTIME time_in, time_diff;
int hw_slot_offset=0,rx_offset_mbox=0,mbox_target=0,mbox_current=0; int mbox_target=0,mbox_current=0;
int diff2; int i,ret;
static int first_run=1; int tx_offset;
int carrier_freq_offset = 0; //-7500; int bytes;
int i;
#ifdef RTAI
task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF); task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF);
mlockall(MCL_CURRENT | MCL_FUTURE); LOG_D(HW,"Started eNB thread (id %p)\n",task);
#ifndef TIMER_ONESHOT_MODE
rt_printk("Started UE thread (id %p)\n",task); now = rt_get_time();
ret = rt_task_make_periodic(task, now, nano2count(500000LL));
if (ret!=0)
LOG_E(HW,"Problem with periodic timer\n");
#endif
#endif
#ifdef HARD_RT #ifdef HARD_RT
rt_make_hard_real_time(); rt_make_hard_real_time();
#endif #endif
if (mode == rx_calib_ue) { mlockall(MCL_CURRENT | MCL_FUTURE);
carrier_freq_offset = -7500;
for (i=0; i<4; i++) { timing_info.time_min = 100000000ULL;
frame_parms->carrier_freq[i] = carrier_freq[i]+carrier_freq_offset; timing_info.time_max = 0;
frame_parms->carrier_freqtx[i] = carrier_freq[i]+carrier_freq_offset; timing_info.time_avg = 0;
} timing_info.n_samples = 0;
ioctl(openair_fd,openair_DUMP_CONFIG,frame_parms);
// dump_frame_parms(frame_parms);
}
while (!oai_exit) while (!oai_exit)
{ {
#ifdef CBMIMO1 hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15;
rt_sem_wait(mutex); //LOG_D(HW,"eNB frame %d, time %llu: slot %d, hw_slot %d (mbox %d)\n",frame,rt_get_time_ns(),slot,hw_slot,((unsigned int *)DAQ_MBOX)[0]);
/*
if ((slot%2000)<10)
rt_printk("fun0: Hello World %d, instance_cnt %d!\n",slot,*instance_cnt_ptr_user);
*/
while (*instance_cnt_ptr_user<0)
{
rt_sem_signal(mutex);
rt_receive(0,&msg1);
rt_sem_wait(mutex);
/*
if ((slot%2000)<10)
rt_printk("fun0: instance_cnt %d, msg1 %d!\n",*instance_cnt_ptr_user,msg1);
*/
}
rt_sem_signal(mutex);
slot = (msg1 - slot0) % LTE_SLOTS_PER_FRAME;
#else
hw_slot = (((((unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15; //the slot the hw is about to store
if (is_synchronized) {
//this is the mbox counter that indicates the start of the frame
rx_offset_mbox = (PHY_vars_UE_g[0]->rx_offset * 150) / (10*PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti);
//this is the mbox counter where we should be //this is the mbox counter where we should be
mbox_target = (((((slot+1)%20)*15+1)>>1) + rx_offset_mbox + 1)%150; //mbox_target = ((((slot+1)%20)*15+1)>>1)%150;
mbox_target = mbox_bounds[slot];
//this is the mbox counter where we are //this is the mbox counter where we are
mbox_current = ((unsigned int *)DAQ_MBOX)[0]; mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0];
//this is the time we need to sleep in order to synchronize with the hw (in multiples of DAQ_PERIOD) //this is the time we need to sleep in order to synchronize with the hw (in multiples of DAQ_PERIOD)
if ((mbox_current>=120) && (mbox_target<30)) //handle the frame wrap-arround
diff2 = 150-mbox_current+mbox_target;
else if ((mbox_current<30) && (mbox_target>=120))
diff2 = -150+mbox_target-mbox_current;
else
diff2 = mbox_target - mbox_current;
if (diff2 <(-5)) {
rt_printk("UE Frame %d: missed slot, proceeding with next one (slot %d, hw_slot %d, diff %d)\n",frame, slot, hw_slot, diff2);
slot++;
if (slot==20)
slot=0;
continue;
}
if (diff2>8)
rt_printk("UE Frame %d: skipped slot, waiting for hw to catch up (slot %d, hw_slot %d, mbox_current %d, mbox_target %d, diff %d)\n",frame, slot, hw_slot, mbox_current, mbox_target, diff2);
/*
if (frame%100==0)
rt_printk("frame %d (%d), slot %d, hw_slot %d, rx_offset_mbox %d, mbox_target %d, mbox_current %d, diff %d\n",frame, PHY_vars_UE_g[0]->frame, slot,hw_slot,rx_offset_mbox,mbox_target,mbox_current,diff2);
*/
timing_info[slot].time0 = rt_get_time_ns();
timing_info[slot].mbox0 = ((unsigned int *)DAQ_MBOX)[0];
delay_cnt = 0;
while ((diff2>0) && (!oai_exit) && (is_synchronized) )
{
rt_sleep(nano2count(diff2*DAQ_PERIOD));
hw_slot = (((((unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15;
delay_cnt++;
if (delay_cnt == 30)
{
oai_exit = 1;
rt_printk("UE frame %d: HW stopped ... \n",frame);
}
mbox_current = ((unsigned int *)DAQ_MBOX)[0];
if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround
diff2 = 150-mbox_current+mbox_target; diff = 150-mbox_current+mbox_target;
else if ((mbox_current<15) && (mbox_target>=135))
diff = -150+mbox_target-mbox_current;
else else
diff2 = mbox_target - mbox_current; diff = mbox_target - mbox_current;
}
timing_info[slot].time1 = rt_get_time_ns();
timing_info[slot].mbox1 = ((unsigned int *)DAQ_MBOX)[0];
timing_info[slot].mbox_target = mbox_target;
}
#endif
last_slot = (slot)%LTE_SLOTS_PER_FRAME;
if (last_slot <0)
last_slot+=LTE_SLOTS_PER_FRAME;
next_slot = (slot+3)%LTE_SLOTS_PER_FRAME;
timing_info[slot].frame = PHY_vars_UE_g[0]->frame;
timing_info[slot].hw_slot = hw_slot;
timing_info[slot].last_slot = last_slot;
timing_info[slot].next_slot = next_slot;
if (is_synchronized)
{
/*
if (frame%100==0)
rt_printk("frame %d (%d), slot %d, hw_slot %d, last_slot %d (before): DAQ_MBOX %d\n",frame, PHY_vars_UE_g[0]->frame, slot,hw_slot,last_slot,DAQ_MBOX[0]);
*/
in = rt_get_time_ns();
phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[0], 0, 0,mode);
out = rt_get_time_ns();
diff = out-in;
/*
if (frame % 100 == 0)
rt_printk("hw_slot %d (after): DAQ_MBOX %d\n",hw_slot,DAQ_MBOX[0]);
rt_printk("Frame %d: last_slot %d, phy_procedures_lte_ue time_in %llu, time_out %llu, diff %llu\n",
frame, last_slot,in,out,diff);
*/
timing_info[slot].time2 = rt_get_time_ns();
timing_info[slot].mbox2 = ((unsigned int *)DAQ_MBOX)[0];
}
else // we are not yet synchronized
{
hw_slot_offset = 0;
#ifdef CBMIMO1
if (received_slots==0)
{
ioctl(openair_fd,openair_GET_BUFFER,NULL);
}
if (received_slots==(100*LTE_SLOTS_PER_FRAME)-1) //we got enough slots so we can do sync (the factor 100 is to wait some time longer)
{
rt_printk("fun0: slot %d: doing sync\n",slot);
received_slots = -1; // will be increased below
if (initial_sync(PHY_vars_UE_g[0],mode)==0)
{
lte_adjust_synch(&PHY_vars_UE_g[0]->lte_frame_parms,
PHY_vars_UE_g[0],
0,
1,
16384);
ioctl(openair_fd,openair_SET_RX_OFFSET,&PHY_vars_UE_g[0]->rx_offset); //synchronize hardware
// here we should actually do another dump config with the parameters obtained from the sync.
ioctl(openair_fd,openair_START_TX_SIG,NULL); //start the DMA transfers vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_ENB, slot);
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_ENB, frame);
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *((volatile unsigned int *) openair0_exmimo_pci[card].rxcnt_ptr[0]));
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DIFF, diff);
//for better visualization afterwards time_in = rt_get_time_ns();
for (aa=0; aa<PHY_vars_UE_g[0]->lte_frame_parms.nb_antennas_rx; aa++) //LOG_D(HW,"eNB Frame %d delaycnt %d : hw_slot %d (%d), slot %d, (slot+1)*15=%d, diff %d, time %llu\n",frame,delay_cnt,hw_slot,((unsigned int *)DAQ_MBOX)[0],slot,(((slot+1)*15)>>1),diff,time_in);
memset(PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata[aa],0, //LOG_D(HW,"eNB Frame %d, time %llu: sleeping for %llu (slot %d, hw_slot %d, diff %d, mbox %d, delay_cnt %d)\n", frame, time_in, diff*DAQ_PERIOD,slot,hw_slot,diff,((volatile unsigned int *)DAQ_MBOX)[0],delay_cnt);
PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,1);
is_synchronized = 1; #ifdef TIMER_ONESHOT_MODE
slot0 = msg1; //ret = rt_sleep_ns(DAQ_PERIOD * (slot%4==0?6:8));
} ret = rt_sleep_ns(500000);
} if (ret)
received_slots++; LOG_D(HW,"eNB Frame %d, time %llu: rt_sleep_ns returned %d\n",frame, time_in);
#else #else
slot = 0; rt_task_wait_period();
ioctl(openair_fd,openair_GET_BUFFER,NULL); #endif
rt_sleep(nano2count(FRAME_PERIOD)); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,0);
// rt_printk("fun0: slot %d: doing sync\n",slot);
if (initial_sync(PHY_vars_UE_g[0],mode)==0) { //hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15;
/* //LOG_D(HW,"eNB Frame %d : hw_slot %d, time %llu\n",frame,hw_slot,rt_get_time_ns());
lte_adjust_synch(&PHY_vars_UE_g[0]->lte_frame_parms,
PHY_vars_UE_g[0],
0,
1,
16384);
*/
//for better visualization afterwards
/*
for (aa=0; aa<PHY_vars_UE_g[0]->lte_frame_parms.nb_antennas_rx; aa++)
memset(PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata[aa],0,
PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int));
*/
if (mode == rx_calib_ue) {
oai_exit=1;
}
else {
is_synchronized = 1;
ioctl(openair_fd,openair_START_TX_SIG,NULL); //start the DMA transfers
hw_slot_offset = (PHY_vars_UE_g[0]->rx_offset<<1) / PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti; mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0];
rt_printk("Got synch: hw_slot_offset %d\n",hw_slot_offset); if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround
} diff = 150-mbox_current+mbox_target;
} else if ((mbox_current<15) && (mbox_target>=135))
else { diff = -150+mbox_target-mbox_current;
carrier_freq_offset += 100; else
if (carrier_freq_offset > 7500) { diff = mbox_target - mbox_current;
LOG_I(PHY,"[initial_sync] No cell synchronization found, abondoning\n");
oai_exit = 1;
}
else {
LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",carrier_freq_offset);
for (i=0; i<4; i++) {
frame_parms->carrier_freq[i] = carrier_freq[i]+carrier_freq_offset;
frame_parms->carrier_freqtx[i] = carrier_freq[i]+carrier_freq_offset;
}
ioctl(openair_fd,openair_DUMP_CONFIG,frame_parms);
// dump_frame_parms(frame_parms);
}
}
#endif last_slot = (slot)%LTE_SLOTS_PER_FRAME;
} if (last_slot <0)
last_slot+=20;
next_slot = (slot+3)%LTE_SLOTS_PER_FRAME;
/*
if ((slot%2000)<10)
rt_printk("fun0: doing very hard work\n");
*/
#ifdef CBMIMO1
rt_sem_wait(mutex);
(*instance_cnt_ptr_user)--;
//rt_printk("fun0: instance_cnt %d!\n",*instance_cnt_ptr_user);
rt_sem_signal(mutex);
#else
slot++; slot++;
if (slot==20) if (slot==20) {
{
slot=0; slot=0;
frame++; frame++;
} }
if (frame==1000)
oai_exit=1;
#if defined(ENABLE_ITTI)
itti_update_lte_time(frame, slot);
#endif #endif
} }
rt_printk("fun0: finished, ran %d times.\n",slot);
LOG_D(HW,"eNB_thread: finished, ran %d times.\n",frame);
#ifdef HARD_RT #ifdef HARD_RT
rt_make_soft_real_time(); rt_make_soft_real_time();
#endif #endif
// clean task // clean task
#ifdef RTAI
rt_task_delete(task); rt_task_delete(task);
rt_printk("Task deleted. returning\n"); #endif
LOG_D(HW,"Task deleted. returning\n");
return 0; return 0;
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
#ifdef RTAI
RT_TASK *task; RT_TASK *task;
RTIME period;
#endif
int i,j,aa; int i,j,aa;
void *status;
/*
#ifdef EXMIMO
u32 rf_mode_max[4] = {55759,55759,55759,55759}; u32 rf_mode_max[4] = {55759,55759,55759,55759};
u32 rf_mode_med[4] = {39375,39375,39375,39375}; u32 rf_mode_med[4] = {39375,39375,39375,39375};
u32 rf_mode_byp[4] = {22991,22991,22991,22991}; u32 rf_mode_byp[4] = {22991,22991,22991,22991};
*/
u32 my_rf_mode = RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX;
u32 rf_mode_base = TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM;
u32 rf_mode[4] = {my_rf_mode,0,0,0};
u32 rf_local[4] = {8255000,8255000,8255000,8255000}; // UE zepto u32 rf_local[4] = {8255000,8255000,8255000,8255000}; // UE zepto
//{8254617, 8254617, 8254617, 8254617}; //eNB khalifa //{8254617, 8254617, 8254617, 8254617}; //eNB khalifa
//{8255067,8254810,8257340,8257340}; // eNB PETRONAS //{8255067,8254810,8257340,8257340}; // eNB PETRONAS
u32 rf_vcocal[4] = {910,910,910,910}; u32 rf_vcocal[4] = {910,910,910,910};
u32 rf_vcocal_850[4] = {2015, 2015, 2015, 2015};
u32 rf_rxdc[4] = {32896,32896,32896,32896}; u32 rf_rxdc[4] = {32896,32896,32896,32896};
u32 rxgain[4]={30,30,30,30}; u32 rxgain[4] = {20,20,20,20};
u32 txgain[4]={25,25,25,25}; u32 txgain[4] = {20,20,20,20};
#endif
u8 eNB_id=0,UE_id=0;
u16 Nid_cell = 0; u16 Nid_cell = 0;
u8 cooperation_flag=0, transmission_mode=1, abstraction_flag=0; u8 cooperation_flag=0, transmission_mode=1, abstraction_flag=0;
u8 beta_ACK=0,beta_RI=0,beta_CQI=2; u8 beta_ACK=0,beta_RI=0,beta_CQI=2;
...@@ -1132,18 +608,21 @@ int main(int argc, char **argv) { ...@@ -1132,18 +608,21 @@ int main(int argc, char **argv) {
char rxg_fname[100]; char rxg_fname[100];
char txg_fname[100]; char txg_fname[100];
char rflo_fname[100]; char rflo_fname[100];
char rfdc_fname[100];
FILE *rxg_fd=NULL; FILE *rxg_fd=NULL;
FILE *txg_fd=NULL; FILE *txg_fd=NULL;
FILE *rflo_fd=NULL; FILE *rflo_fd=NULL;
FILE *rfdc_fd=NULL;
unsigned int rxg_max[4]={133,133,133,133}, rxg_med[4]={127,127,127,127}, rxg_byp[4]={120,120,120,120}; unsigned int rxg_max[4]={133,133,133,133}, rxg_med[4]={127,127,127,127}, rxg_byp[4]={120,120,120,120};
int tx_max_power; int tx_max_power=0;
char line[1000]; char line[1000];
int l; int l;
int ret, ant;
int ant_offset=0;
#ifdef EMOS
int error_code; int error_code;
#endif char *itti_dump_file = NULL;
const struct option long_options[] = { const struct option long_options[] = {
{"calib-ue-rx", required_argument, NULL, 256}, {"calib-ue-rx", required_argument, NULL, 256},
...@@ -1153,17 +632,16 @@ int main(int argc, char **argv) { ...@@ -1153,17 +632,16 @@ int main(int argc, char **argv) {
{"no-L2-connect", no_argument, NULL, 260}, {"no-L2-connect", no_argument, NULL, 260},
{NULL, 0, NULL, 0}}; {NULL, 0, NULL, 0}};
mode = normal_txrx; //mode = normal_txrx;
#ifdef XFORMS while ((c = getopt_long (argc, argv, "C:K:O:ST:UdF:V",long_options,NULL)) != -1)
char title[255];
#endif
while ((c = getopt_long (argc, argv, "C:ST:UdF:",long_options,NULL)) != -1)
{ {
switch (c) switch (c)
{ {
case 'V':
ouput_vcd = 1;
break;
case 'd': case 'd':
do_forms=1; do_forms=1;
break; break;
...@@ -1182,6 +660,28 @@ int main(int argc, char **argv) { ...@@ -1182,6 +660,28 @@ int main(int argc, char **argv) {
case 'T': case 'T':
tcxo=atoi(optarg); tcxo=atoi(optarg);
break; break;
case 'K':
#if defined(ENABLE_ITTI)
itti_dump_file = strdup(optarg);
#else
printf("-K option is disabled when ENABLE_ITTI is not defined\n");
#endif
break;
case 'O':
#if defined(ENABLE_USE_MME)
EPC_MODE_ENABLED = 1;
if (optarg == NULL) /* No IP address provided: use localhost */
{
memcpy(&EPC_MODE_MME_ADDRESS[0], "127.0.0.1", 10);
} else {
u8 ip_length = strlen(optarg) + 1;
memcpy(&EPC_MODE_MME_ADDRESS[0], optarg,
ip_length > 16 ? 16 : ip_length);
}
#else
printf("You enabled mme mode without s1ap compiled...\n");
#endif
break;
case 'F': case 'F':
sprintf(rxg_fname,"%srxg.lime",optarg); sprintf(rxg_fname,"%srxg.lime",optarg);
rxg_fd = fopen(rxg_fname,"r"); rxg_fd = fopen(rxg_fname,"r");
...@@ -1218,7 +718,7 @@ int main(int argc, char **argv) { ...@@ -1218,7 +718,7 @@ int main(int argc, char **argv) {
} }
} }
else else
printf("%s not found, running with defaults\n",rxg_fname); printf("%s not found, running with defaults\n",txg_fname);
sprintf(rflo_fname,"%srflo.lime",optarg); sprintf(rflo_fname,"%srflo.lime",optarg);
rflo_fd = fopen(rflo_fname,"r"); rflo_fd = fopen(rflo_fname,"r");
...@@ -1229,8 +729,17 @@ int main(int argc, char **argv) { ...@@ -1229,8 +729,17 @@ int main(int argc, char **argv) {
else else
printf("%s not found, running with defaults\n",rflo_fname); printf("%s not found, running with defaults\n",rflo_fname);
sprintf(rfdc_fname,"%srfdc.lime",optarg);
rfdc_fd = fopen(rfdc_fname,"r");
if (rfdc_fd) {
printf("Loading RF DC parameters from %s\n",rfdc_fname);
fscanf(rfdc_fd,"%d %d %d %d",&rf_rxdc[0],&rf_rxdc[1],&rf_rxdc[2],&rf_rxdc[3]);
}
else
printf("%s not found, running with defaults\n",rfdc_fname);
break; break;
/*
case 256: case 256:
mode = rx_calib_ue; mode = rx_calib_ue;
rx_input_level_dBm = atoi(optarg); rx_input_level_dBm = atoi(optarg);
...@@ -1252,6 +761,7 @@ int main(int argc, char **argv) { ...@@ -1252,6 +761,7 @@ int main(int argc, char **argv) {
case 260: case 260:
mode = no_L2_connect; mode = no_L2_connect;
break; break;
*/
default: default:
break; break;
} }
...@@ -1263,63 +773,58 @@ int main(int argc, char **argv) { ...@@ -1263,63 +773,58 @@ int main(int argc, char **argv) {
printf("configuring for eNB\n"); printf("configuring for eNB\n");
//randominit (0); //randominit (0);
set_taus_seed (0); //set_taus_seed (0);
// initialize the log (see log.h for details) // initialize the log (see log.h for details)
logInit(); logInit();
#if defined(ENABLE_ITTI)
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
# if defined(ENABLE_USE_MME)
if (itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0) {
LOG_E(EMU, "Create task failed");
LOG_D(EMU, "Initializing SCTP task interface: FAILED\n");
return -1;
}
if (itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
LOG_E(EMU, "Create task failed");
LOG_D(EMU, "Initializing S1AP task interface: FAILED\n");
return -1;
}
# endif
if (itti_create_task(TASK_L2L1, l2l1_task, NULL) < 0) {
LOG_E(EMU, "Create task failed");
LOG_D(EMU, "Initializing L2L1 task interface: FAILED\n");
return -1;
}
// Handle signals until all tasks are terminated
// itti_wait_tasks_end();
#endif
if (ouput_vcd) {
if (UE_flag==1)
vcd_signal_dumper_init("/tmp/openair_dump_UE.vcd");
else
vcd_signal_dumper_init("/tmp/openair_dump_eNB.vcd");
}
#ifdef NAS_NETLINK #ifdef NAS_NETLINK
netlink_init(); netlink_init();
#endif #endif
// to make a graceful exit when ctrl-c is pressed // to make a graceful exit when ctrl-c is pressed
signal(SIGSEGV, signal_handler); signal(SIGSEGV, signal_handler);
signal(SIGINT, signal_handler);
// init the parameters #ifndef RTAI
frame_parms = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS)); check_clock();
frame_parms->N_RB_DL = 25;
frame_parms->N_RB_UL = 25;
frame_parms->Ncp = 0;
frame_parms->Ncp_UL = 0;
frame_parms->Nid_cell = Nid_cell;
frame_parms->nushift = 0;
frame_parms->nb_antennas_tx_eNB = 2; //initial value overwritten by initial sync later
frame_parms->nb_antennas_tx = (UE_flag==0) ? 2 : 1;
frame_parms->nb_antennas_rx = (UE_flag==0) ? 1 : 1;
frame_parms->mode1_flag = (transmission_mode == 1) ? 1 : 0;
frame_parms->frame_type = 1;
#ifdef CBMIMO1
if (fs4_test==1)
frame_parms->tdd_config = 255;
else
#endif #endif
frame_parms->tdd_config = 3;
frame_parms->tdd_config_S = 0;
frame_parms->phich_config_common.phich_resource = oneSixth;
frame_parms->phich_config_common.phich_duration = normal;
frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0
// hardware specific parameters
// for CBMIMO
frame_parms->dual_tx = 0;
frame_parms->freq_idx = 1;
init_frame_parms(frame_parms,1);
phy_init_top(frame_parms);
phy_init_lte_top(frame_parms);
//init prach for openair1 test
frame_parms->prach_config_common.rootSequenceIndex=1;
frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
frame_parms->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
frame_parms->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;
prach_fmt = get_prach_fmt(frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
frame_parms->frame_type);
N_ZC = (prach_fmt <4)?839:139;
if (UE_flag==1) { g_log->log_component[HW].level = LOG_DEBUG;
g_log->log_component[HW].flag = LOG_HIGH;
#ifdef OPENAIR2 #ifdef OPENAIR2
g_log->log_component[PHY].level = LOG_INFO; g_log->log_component[PHY].level = LOG_INFO;
#else #else
...@@ -1334,252 +839,155 @@ int main(int argc, char **argv) { ...@@ -1334,252 +839,155 @@ int main(int argc, char **argv) {
g_log->log_component[PDCP].flag = LOG_HIGH; g_log->log_component[PDCP].flag = LOG_HIGH;
g_log->log_component[OTG].level = LOG_INFO; g_log->log_component[OTG].level = LOG_INFO;
g_log->log_component[OTG].flag = LOG_HIGH; g_log->log_component[OTG].flag = LOG_HIGH;
g_log->log_component[RRC].level = LOG_INFO;
g_log->log_component[RRC].flag = LOG_HIGH;
frame_parms->node_id = NODE;
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE*));
PHY_vars_UE_g[0] = init_lte_UE(frame_parms, UE_id,abstraction_flag,transmission_mode);
for (i=0;i<NUMBER_OF_eNB_MAX;i++) { // Initialize card
PHY_vars_UE_g[0]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; ret = openair0_open();
PHY_vars_UE_g[0]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; if ( ret != 0 ) {
PHY_vars_UE_g[0]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; if (ret == -1)
printf("Error opening /dev/openair0");
if (ret == -2)
printf("Error mapping bigshm");
if (ret == -3)
printf("Error mapping RX or TX buffer");
return(ret);
} }
compute_prach_seq(&PHY_vars_UE_g[0]->lte_frame_parms.prach_config_common, printf ("Detected %d number of cards, %d number of antennas.\n", openair0_num_detected_cards, openair0_num_antennas[card]);
PHY_vars_UE_g[0]->lte_frame_parms.frame_type,
PHY_vars_UE_g[0]->X_u);
PHY_vars_UE_g[0]->lte_ue_pdcch_vars[0]->crnti = 0x1234; p_exmimo_config = openair0_exmimo_pci[card].exmimo_config_ptr;
#ifndef OPENAIR2 p_exmimo_id = openair0_exmimo_pci[card].exmimo_id_ptr;
PHY_vars_UE_g[0]->lte_ue_pdcch_vars[0]->crnti = 0x1235;
//PHY_vars_UE_g[0]->lte_frame_parms.
#endif
NB_UE_INST=1;
NB_INST=1;
openair_daq_vars.manual_timing_advance = 0; printf("Card %d: ExpressMIMO %d, HW Rev %d, SW Rev 0x%d\n", card, p_exmimo_id->board_exmimoversion, p_exmimo_id->board_hwrev, p_exmimo_id->board_swrev);
//openair_daq_vars.timing_advance = TIMING_ADVANCE_HW;
openair_daq_vars.rx_gain_mode = DAQ_AGC_ON;
openair_daq_vars.use_ia_receiver = 0;
// if AGC is off, the following values will be used if (p_exmimo_id->board_swrev>=BOARD_SWREV_CNTL2)
for (i=0;i<4;i++) p_exmimo_config->framing.eNB_flag = 0;
rxgain[i]=30; else
p_exmimo_config->framing.eNB_flag = !UE_flag;
for (i=0;i<4;i++) { p_exmimo_config->framing.tdd_config = DUPLEXMODE_FDD + TXRXSWITCH_LSB;
PHY_vars_UE_g[0]->rx_gain_max[i] = rxg_max[i]; for (ant=0; ant<4; ant++)
PHY_vars_UE_g[0]->rx_gain_med[i] = rxg_med[i]; p_exmimo_config->framing.resampling_factor[ant] = RESAMPLING_FACTOR;
PHY_vars_UE_g[0]->rx_gain_byp[i] = rxg_byp[i];
}
if ((mode == normal_txrx) || (mode == rx_calib_ue) || (mode == no_L2_connect) || (mode == debug_prach)) { /*
for (i=0; i<4; i++) { for (ant=0;ant<max(frame_parms->nb_antennas_tx,frame_parms->nb_antennas_rx);ant++)
PHY_vars_UE_g[0]->rx_gain_mode[i] = max_gain; p_exmimo_config->rf.rf_mode[ant] = rf_mode_base;
frame_parms->rfmode[i] = rf_mode_max[i]; for (ant=0;ant<frame_parms->nb_antennas_tx;ant++)
} p_exmimo_config->rf.rf_mode[ant] += (TXEN + DMAMODE_TX);
PHY_vars_UE_g[0]->rx_total_gain_dB = PHY_vars_UE_g[0]->rx_gain_max[0]; for (ant=0;ant<frame_parms->nb_antennas_rx;ant++)
} p_exmimo_config->rf.rf_mode[ant] += (RXEN + DMAMODE_RX);
else if ((mode == rx_calib_ue_med)) { for (ant=max(frame_parms->nb_antennas_tx,frame_parms->nb_antennas_rx);ant<4;ant++) {
for (i=0; i<4; i++) { p_exmimo_config->rf.rf_mode[ant] = 0;
PHY_vars_UE_g[0]->rx_gain_mode[i] = med_gain; carrier_freq[ant] = 0; //this turns off all other LIMEs
frame_parms->rfmode[i] = rf_mode_med[i];
}
PHY_vars_UE_g[0]->rx_total_gain_dB = PHY_vars_UE_g[0]->rx_gain_med[0];
}
else if ((mode == rx_calib_ue_byp)) {
for (i=0; i<4; i++) {
PHY_vars_UE_g[0]->rx_gain_mode[i] = byp_gain;
frame_parms->rfmode[i] = rf_mode_byp[i];
}
PHY_vars_UE_g[0]->rx_total_gain_dB = PHY_vars_UE_g[0]->rx_gain_byp[0];
} }
*/
PHY_vars_UE_g[0]->tx_power_max_dBm = tx_max_power; ant_offset = 0;
for (ant=0; ant<4; ant++) {
if (ant==ant_offset) {
//if (1) {
p_exmimo_config->rf.rf_mode[ant] = rf_mode_base;
//p_exmimo_config->rf.rf_mode[ant] += (TXEN + DMAMODE_TX);
p_exmimo_config->rf.rf_mode[ant] += (RXEN + DMAMODE_RX);
} }
else { else {
#ifdef OPENAIR2 p_exmimo_config->rf.rf_mode[ant] = 0;
g_log->log_component[PHY].level = LOG_INFO; carrier_freq[ant] = 0; //this turns off all other LIMEs
#else }
g_log->log_component[PHY].level = LOG_INFO;
#endif
g_log->log_component[PHY].flag = LOG_HIGH;
g_log->log_component[MAC].level = LOG_INFO;
g_log->log_component[MAC].flag = LOG_HIGH;
g_log->log_component[RLC].level = LOG_INFO;
g_log->log_component[RLC].flag = LOG_HIGH;
g_log->log_component[PDCP].level = LOG_INFO;
g_log->log_component[PDCP].flag = LOG_HIGH;
g_log->log_component[OTG].level = LOG_INFO;
g_log->log_component[OTG].flag = LOG_HIGH;
frame_parms->node_id = PRIMARY_CH;
PHY_vars_eNB_g = malloc(sizeof(PHY_VARS_eNB*));
PHY_vars_eNB_g[0] = init_lte_eNB(frame_parms,eNB_id,Nid_cell,cooperation_flag,transmission_mode,abstraction_flag);
for (i=0;i<NUMBER_OF_UE_MAX;i++) {
PHY_vars_eNB_g[0]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
PHY_vars_eNB_g[0]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI;
PHY_vars_eNB_g[0]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI;
} }
compute_prach_seq(&PHY_vars_eNB_g[0]->lte_frame_parms.prach_config_common, for (ant = 0; ant<4; ant++) {
PHY_vars_eNB_g[0]->lte_frame_parms.frame_type, p_exmimo_config->rf.do_autocal[ant] = 1;
PHY_vars_eNB_g[0]->X_u); p_exmimo_config->rf.rf_freq_rx[ant] = carrier_freq[ant];
p_exmimo_config->rf.rf_freq_tx[ant] = carrier_freq[ant];
NB_eNB_INST=1; p_exmimo_config->rf.rx_gain[ant][0] = rxgain[ant];
NB_INST=1; p_exmimo_config->rf.tx_gain[ant][0] = txgain[ant];
openair_daq_vars.ue_dl_rb_alloc=0x1fff;
openair_daq_vars.target_ue_dl_mcs=16;
openair_daq_vars.ue_ul_nb_rb=10;
openair_daq_vars.target_ue_ul_mcs=4;
// if AGC is off, the following values will be used p_exmimo_config->rf.rf_local[ant] = rf_local[ant];
for (i=0;i<4;i++) p_exmimo_config->rf.rf_rxdc[ant] = rf_rxdc[ant];
rxgain[i]=30;
// set eNB to max gain if ((carrier_freq[ant] >= 850000000) && (carrier_freq[ant] <= 865000000)) {
PHY_vars_eNB_g[0]->rx_total_gain_eNB_dB = rxg_max[0]; //was measured at rxgain=30; p_exmimo_config->rf.rf_vcocal[ant] = rf_vcocal_850[ant];
for (i=0; i<4; i++) { p_exmimo_config->rf.rffe_band_mode[ant] = DD_TDD;
frame_parms->rfmode[i] = rf_mode_max[i];
} }
else if ((carrier_freq[ant] >= 1900000000) && (carrier_freq[ant] <= 2000000000)) {
p_exmimo_config->rf.rf_vcocal[ant] = rf_vcocal[ant];
p_exmimo_config->rf.rffe_band_mode[ant] = B19G_TDD;
} }
else {
// for Express MIMO p_exmimo_config->rf.rf_vcocal[ant] = rf_vcocal[ant];
for (i=0; i<4; i++) { p_exmimo_config->rf.rffe_band_mode[ant] = 0;
frame_parms->carrier_freq[i] = carrier_freq[i];
frame_parms->carrier_freqtx[i] = carrier_freq[i];
frame_parms->rxgain[i] = rxgain[i];
frame_parms->txgain[i] = txgain[i];
//frame_parms->rf_mode is set above (individually for UE and eNB)
frame_parms->rflocal[i] = rf_local[i];
frame_parms->rfvcolocal[i] = rf_vcocal[i];
frame_parms->rxdc[i] = rf_rxdc[i];
} }
dump_frame_parms(frame_parms); p_exmimo_config->rf.rffe_gain_txlow[ant] = 31;
p_exmimo_config->rf.rffe_gain_txhigh[ant] = 31;
mac_xface = malloc(sizeof(MAC_xface)); p_exmimo_config->rf.rffe_gain_rxfinal[ant] = 52;
p_exmimo_config->rf.rffe_gain_rxlow[ant] = 31;
#ifdef OPENAIR2 }
int eMBMS_active=0;
l2_init(frame_parms,eMBMS_active);
if (UE_flag == 1)
mac_xface->dl_phy_sync_success (0, 0, 0, 1);
else
mac_xface->mrbch_phy_sync_failure (0, 0, 0);
#endif
mac_xface->macphy_exit = &exit_fun;
#ifdef OPENAIR2
//if (otg_enabled) {
init_all_otg(0);
g_otg->seed = 0;
init_seeds(g_otg->seed);
g_otg->num_nodes = 2;
for (i=0; i<g_otg->num_nodes; i++){
for (j=0; j<g_otg->num_nodes; j++){
g_otg->application_idx[i][j] = 1;
//g_otg->packet_gen_type=SUBSTRACT_STRING;
g_otg->aggregation_level[i][j][0]=1;
g_otg->application_type[i][j][0] = BCBR; //MCBR, BCBR
}
}
init_predef_traffic();
//}
#endif
// start up the hardware
openair_fd=setup_oai_hw(frame_parms);
number_of_cards = 1;
// connect the TX/RX buffers number_of_cards = openair0_num_detected_cards;
if (UE_flag==1)
{
setup_ue_buffers(PHY_vars_UE_g[0],frame_parms,0);
#ifndef CBMIMO1
for (i=0; i<frame_parms->samples_per_tti*10; i++)
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++)
PHY_vars_UE_g[0]->lte_ue_common_vars.txdata[aa][i] = 0x00010001;
#endif
}
else
{
setup_eNB_buffers(PHY_vars_eNB_g[0],frame_parms);
if (fs4_test==0)
{
#ifndef CBMIMO1
printf("Setting eNB buffer to all-RX\n");
// Set LSBs for antenna switch (ExpressMIMO)
for (i=0; i<frame_parms->samples_per_tti*10; i++)
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++)
PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][i] = 0x00010001;
// Set the last OFDM symbol of subframe 4 to TX to allow enough time for switch to settle
// (that's ok since the last symbol can be configured as SRS)
/* /*
for (i=frame_parms->samples_per_tti*5-0*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples); if (p_exmimo_id->board_exmimoversion==1) //ExpressMIMO1
i<frame_parms->samples_per_tti*5; i++) openair_daq_vars.timing_advance = 138;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) else //ExpressMIMO2
PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][i] = 0x0; openair_daq_vars.timing_advance = 0;
*/ */
#endif openair0_dump_config(card);
}
else printf("EXMIMO_CONFIG: rf_mode 0x %x %x %x %x, [0]: TXRXEn %d, TXLPFEn %d, TXLPF %d, RXLPFEn %d, RXLPF %d, RFBB %d, LNA %d, LNAGain %d, RXLPFMode %d, SWITCH %d, rf_rxdc %d, rf_local %d, rf_vcocal %d\n",
{ p_exmimo_config->rf.rf_mode[0],
printf("Setting eNB buffer to fs/4 test signal\n"); p_exmimo_config->rf.rf_mode[1],
for (j=0; j<PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti*10; j+=4) p_exmimo_config->rf.rf_mode[2],
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) p_exmimo_config->rf.rf_mode[3],
{ (p_exmimo_config->rf.rf_mode[0]&3), // RXen+TXen
#ifdef CBMIMO1 (p_exmimo_config->rf.rf_mode[0]&4)>>2, //TXLPFen
amp = 0x80; (p_exmimo_config->rf.rf_mode[0]&TXLPFMASK)>>3, //TXLPF
((char*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+1] = 0; (p_exmimo_config->rf.rf_mode[0]&128)>>7, //RXLPFen
((char*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+3] = amp-1; (p_exmimo_config->rf.rf_mode[0]&RXLPFMASK)>>8, //TXLPF
((char*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+5] = 0; (p_exmimo_config->rf.rf_mode[0]&RFBBMASK)>>16, // RFBB mode
((char*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+7] = amp; (p_exmimo_config->rf.rf_mode[0]&LNAMASK)>>12, // RFBB mode
((char*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j] = amp-1; (p_exmimo_config->rf.rf_mode[0]&LNAGAINMASK)>>14, // RFBB mode
((char*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+2] = 0; (p_exmimo_config->rf.rf_mode[0]&RXLPFMODEMASK)>>19, // RXLPF mode
((char*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+4] = amp; (p_exmimo_config->framing.tdd_config&TXRXSWITCH_MASK)>>1, // Switch mode
((char*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+6] = 0; p_exmimo_config->rf.rf_rxdc[0],
#else p_exmimo_config->rf.rf_local[0],
amp = 0x8000; p_exmimo_config->rf.rf_vcocal[0]);
((short*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+1] = 0;
((short*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+3] = amp-1; for (ant=0;ant<4;ant++)
((short*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+5] = 0; p_exmimo_config->rf.do_autocal[ant] = 0;
((short*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+7] = amp;
((short*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j] = amp-1;
((short*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+2] = 0;
((short*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+4] = amp;
((short*)PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa])[2*j+6] = 0;
#endif
}
}
}
#ifdef EMOS #ifdef EMOS
error_code = rtf_create(CHANSOUNDER_FIFO_MINOR,CHANSOUNDER_FIFO_SIZE); error_code = rtf_create(CHANSOUNDER_FIFO_MINOR,CHANSOUNDER_FIFO_SIZE);
printf("[OPENAIR][SCHED][INIT] Created EMOS FIFO %d, error code %d\n",CHANSOUNDER_FIFO_MINOR,error_code); if (error_code==0)
printf("[OPENAIR][SCHED][INIT] Created EMOS FIFO %d\n",CHANSOUNDER_FIFO_MINOR);
else if (error_code==ENODEV)
printf("[OPENAIR][SCHED][INIT] Problem: EMOS FIFO %d is greater than or equal to RTF_NO\n",CHANSOUNDER_FIFO_MINOR);
else if (error_code==ENOMEM)
printf("[OPENAIR][SCHED][INIT] Problem: cannot allocate memory for EMOS FIFO %d\n",CHANSOUNDER_FIFO_MINOR);
else
printf("[OPENAIR][SCHED][INIT] Problem creating EMOS FIFO %d, error_code %d\n",CHANSOUNDER_FIFO_MINOR,error_code);
#endif #endif
mlockall(MCL_CURRENT | MCL_FUTURE);
#ifdef RTAI
// make main thread LXRT soft realtime // make main thread LXRT soft realtime
task = rt_task_init_schmod(nam2num("MYTASK"), 9, 0, 0, SCHED_FIFO, 0xF); task = rt_task_init_schmod(nam2num("MYTASK"), 9, 0, 0, SCHED_FIFO, 0xF);
mlockall(MCL_CURRENT | MCL_FUTURE);
// start realtime timer and scheduler // start realtime timer and scheduler
//rt_set_oneshot_mode(); #ifdef TIMER_ONESHOT_MODE
rt_set_periodic_mode(); rt_set_oneshot_mode();
start_rt_timer(0); start_rt_timer(0);
printf("started RTAI timer inoneshot mode\n");
//now = rt_get_time() + 10*PERIOD; #else
//rt_task_make_periodic(task, now, PERIOD); rt_set_periodic_mode();
period = start_rt_timer(nano2count(500000));
printf("started RTAI timer with period %llu ns\n",count2nano(period));
#endif
printf("Init mutex\n"); printf("Init mutex\n");
//mutex = rt_get_adr(nam2num("MUTEX")); //mutex = rt_get_adr(nam2num("MUTEX"));
...@@ -1591,154 +999,287 @@ int main(int argc, char **argv) { ...@@ -1591,154 +999,287 @@ int main(int argc, char **argv) {
} }
else else
printf("mutex=%p\n",mutex); printf("mutex=%p\n",mutex);
/*
cond = rt_cond_init(nam2num("CONDITION"));
//cond = rt_get_adr(nam2num("CONDITION"));
if (cond==0)
printf("Error init cond\n");
*/
// initialize the instance cnt before starting the thread
instance_cnt_ptr_user = &instance_cnt;
// signal the driver to set up for user-space operation
// this will initialize the semaphore and the task pointers in the kernel
// further we receive back the pointer to the shared instance counter which is used to signal if the thread is busy or not. This pointer needs to be mapped to user space.
ioctl(openair_fd,openair_START_LXRT,&instance_cnt_ptr_kern);
instance_cnt_ptr_user = (int*) (instance_cnt_ptr_kern -bigphys_top+mem_base);
*instance_cnt_ptr_user = -1;
printf("instance_cnt_ptr_kern %p, instance_cnt_ptr_user %p, *instance_cnt_ptr_user %d\n", (void*) instance_cnt_ptr_kern, (void*) instance_cnt_ptr_user,*instance_cnt_ptr_user);
rt_sleep(nano2count(FRAME_PERIOD));
ioctl(openair_fd,openair_GET_PCI_INTERFACE,&pci_interface_ptr_kern);
#ifdef CBMIMO1
ioctl(openair_fd,openair_SET_TCXO_DAC,(void *)&tcxo);
#endif #endif
#ifdef CBMIMO1 DAQ_MBOX = (volatile unsigned int *) openair0_exmimo_pci[card].rxcnt_ptr[0];
pci_interface[0] = (PCI_interface_t*) (pci_interface_ptr_kern-bigphys_top+mem_base);
printf("pci_interface_ptr_kern = %p, pci_interface = %p, tcxo_dac =%d\n", (void*) pci_interface_ptr_kern, pci_interface[0],pci_interface[0]->tcxo_dac);
#else
exmimo_pci_interface = (exmimo_pci_interface_t*) (pci_interface_ptr_kern-bigphys_top+mem_base);
printf("pci_interface_ptr_kern = %p, exmimo_pci_interface = %p\n", (void*) pci_interface_ptr_kern, exmimo_pci_interface);
DAQ_MBOX = (unsigned int *)(0xc0000000+exmimo_pci_interface->rf.mbox-bigphys_top+mem_base);
#endif
// this starts the DMA transfers // this starts the DMA transfers
if (UE_flag!=1) if (UE_flag!=1)
ioctl(openair_fd,openair_START_TX_SIG,NULL); openair0_start_rt_acquisition(card);
#ifdef XFORMS #ifdef XFORMS
if (do_forms==1) if (do_forms==1) {
{
fl_initialize (&argc, argv, NULL, 0, 0); fl_initialize (&argc, argv, NULL, 0, 0);
form_dl = create_form_lte_scope();
form_stats = create_form_stats_form(); form_stats = create_form_stats_form();
if (UE_flag==1) if (UE_flag==1) {
form_ue[UE_id] = create_lte_phy_scope_ue();
sprintf (title, "LTE DL SCOPE UE"); sprintf (title, "LTE DL SCOPE UE");
else fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
sprintf (title, "LTE UL SCOPE eNB"); } else {
fl_show_form (form_dl->lte_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); for(UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
form_enb[UE_id] = create_lte_phy_scope_enb();
sprintf (title, "UE%d LTE UL SCOPE eNB",UE_id+1);
fl_show_form (form_enb[UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
}
}
fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
if (UE_flag==0) { if (UE_flag==0) {
//fl_hide_object(form->ia_receiver_button); for (UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
if (otg_enabled) { if (otg_enabled) {
fl_set_button(form_dl->ia_receiver_button,1); fl_set_button(form_enb[UE_id]->button_0,1);
fl_set_object_label(form_dl->ia_receiver_button,"DL traffic ON"); fl_set_object_label(form_enb[UE_id]->button_0,"DL Traffic ON");
} }
else { else {
fl_set_button(form_dl->ia_receiver_button,0); fl_set_button(form_enb[UE_id]->button_0,0);
fl_set_object_label(form_dl->ia_receiver_button,"DL traffic OFF"); fl_set_object_label(form_enb[UE_id]->button_0,"DL Traffic OFF");
}
} }
} }
else { else {
//fl_show_object(form->ia_receiver_button);
if (openair_daq_vars.use_ia_receiver) { if (openair_daq_vars.use_ia_receiver) {
fl_set_button(form_dl->ia_receiver_button,1); fl_set_button(form_ue[UE_id]->button_0,1);
fl_set_object_label(form_dl->ia_receiver_button, "IA Receiver ON"); fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
} }
else { else {
fl_set_button(form_dl->ia_receiver_button,0); fl_set_button(form_ue[UE_id]->button_0,0);
fl_set_object_label(form_dl->ia_receiver_button, "IA Receiver OFF"); fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
} }
} }
thread2 = pthread_create(&thread2, NULL, scope_thread, NULL); ret = pthread_create(&thread2, NULL, scope_thread, NULL);
printf("Scope thread created, ret=%d\n",ret);
} }
#endif #endif
rt_sleep(nano2count(10*FRAME_PERIOD)); #ifdef EMOS
ret = pthread_create(&thread3, NULL, emos_thread, NULL);
printf("EMOS thread created, ret=%d\n",ret);
#endif
rt_sleep_ns(10*FRAME_PERIOD);
#ifndef RTAI
pthread_attr_init (&attr_dlsch_threads);
pthread_attr_setstacksize(&attr_dlsch_threads,OPENAIR_THREAD_STACK_SIZE);
//attr_dlsch_threads.priority = 1;
sched_param_dlsch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
pthread_attr_setschedparam (&attr_dlsch_threads, &sched_param_dlsch);
pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO);
#endif
// start the main thread // start the main thread
if (UE_flag == 1) { if (UE_flag == 1) {
/*
#ifdef RTAI
thread1 = rt_thread_create(UE_thread, NULL, 100000000); thread1 = rt_thread_create(UE_thread, NULL, 100000000);
#else
error_code = pthread_create(&thread1, &attr_dlsch_threads, UE_thread, NULL);
if (error_code!= 0) {
LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code);
return(error_code);
}
else {
LOG_D(HW,"[lte-softmodem.c] Allocate UE_thread successful\n");
}
#endif
#ifdef DLSCH_THREAD #ifdef DLSCH_THREAD
//init_rx_pdsch_threads(); init_rx_pdsch_thread();
rt_sleep(nano2count(FRAME_PERIOD/10)); rt_sleep_ns(FRAME_PERIOD/10);
init_dlsch_threads(); init_dlsch_threads();
#endif #endif
printf("UE threads created\n");
*/
} }
else { else {
#ifdef RTAI
thread0 = rt_thread_create(eNB_thread, NULL, 100000000); thread0 = rt_thread_create(eNB_thread, NULL, 100000000);
#else
error_code = pthread_create(&thread0, &attr_dlsch_threads, eNB_thread, NULL);
if (error_code!= 0) {
LOG_D(HW,"[lte-softmodem.c] Could not allocate eNB_thread, error %d\n",error_code);
return(error_code);
}
else {
LOG_D(HW,"[lte-softmodem.c] Allocate eNB_thread successful\n");
}
#endif
#ifdef ULSCH_THREAD #ifdef ULSCH_THREAD
init_ulsch_threads(); init_ulsch_threads();
#endif #endif
printf("eNB threads created\n");
} }
#ifndef CBMIMO1
// sync_thread = rt_thread_create(sync_hw,NULL,10000000);
#endif
printf("threads created\n");
// wait for end of program // wait for end of program
printf("TYPE <ENTER> TO TERMINATE\n"); printf("TYPE <CTRL-C> TO TERMINATE\n");
getchar(); //getchar();
while (oai_exit==0)
rt_sleep_ns(FRAME_PERIOD);
// stop threads
#ifdef XFORMS #ifdef XFORMS
printf("waiting for XFORMS thread\n");
if (do_forms==1) if (do_forms==1)
{ {
//pthread_join? pthread_join(thread2,&status);
fl_hide_form(form_stats->stats_form); fl_hide_form(form_stats->stats_form);
fl_free_form(form_stats->stats_form); fl_free_form(form_stats->stats_form);
fl_hide_form(form_dl->lte_scope); if (UE_flag==1) {
fl_free_form(form_dl->lte_scope); fl_hide_form(form_ue[UE_id]->lte_phy_scope_ue);
fl_free_form(form_ue[UE_id]->lte_phy_scope_ue);
} else {
for(UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
fl_hide_form(form_enb[UE_id]->lte_phy_scope_enb);
fl_free_form(form_enb[UE_id]->lte_phy_scope_enb);
}
}
} }
#endif #endif
// stop threads printf("stopping MODEM threads\n");
oai_exit=1;
rt_sleep(nano2count(FRAME_PERIOD));
// cleanup // cleanup
if (UE_flag == 1) { if (UE_flag == 1) {
/*
#ifdef RTAI
rt_thread_join(thread1);
#else
pthread_join(thread1,&status);
#endif
#ifdef DLSCH_THREAD #ifdef DLSCH_THREAD
cleanup_dlsch_threads(); cleanup_dlsch_threads();
//cleanup_rx_pdsch_threads(); cleanup_rx_pdsch_thread();
#endif #endif
*/
} }
else { else {
#ifdef RTAI
rt_thread_join(thread0);
#else
pthread_join(thread0,&status);
#endif
#ifdef ULSCH_THREAD #ifdef ULSCH_THREAD
cleanup_ulsch_threads(); cleanup_ulsch_threads();
#endif #endif
} }
#ifdef OPENAIR2
//cleanup_pdcp_thread();
#endif
#ifdef RTAI
stop_rt_timer(); stop_rt_timer();
#endif
printf("stopping card\n");
openair0_stop(card);
printf("closing openair0_lib\n");
openair0_close();
fd = 0; #ifdef EMOS
ioctl(openair_fd,openair_STOP,&fd); printf("waiting for EMOS thread\n");
munmap((void*)mem_base, BIGPHYS_NUMPAGES*4096); pthread_cancel(thread3);
pthread_join(thread3,&status);
#endif
#ifdef EMOS #ifdef EMOS
error_code = rtf_destroy(CHANSOUNDER_FIFO_MINOR); error_code = rtf_destroy(CHANSOUNDER_FIFO_MINOR);
printf("[OPENAIR][SCHED][CLEANUP] EMOS FIFO closed, error_code %d\n", error_code); printf("[OPENAIR][SCHED][CLEANUP] EMOS FIFO closed, error_code %d\n", error_code);
#endif #endif
if (ouput_vcd)
vcd_signal_dumper_close();
logClean();
return 0; return 0;
} }
void test_config(int card, int ant, unsigned int rf_mode, int UE_flag) {
p_exmimo_config->framing.eNB_flag = !UE_flag;
p_exmimo_config->framing.tdd_config = 0;
p_exmimo_config->framing.resampling_factor[ant] = 2;
p_exmimo_config->rf.rf_freq_rx[ant] = 1907600000;
p_exmimo_config->rf.rf_freq_tx[ant] = 1907600000;;
p_exmimo_config->rf.rx_gain[ant][0] = 20;
p_exmimo_config->rf.tx_gain[ant][0] = 10;
p_exmimo_config->rf.rf_mode[ant] = rf_mode;
p_exmimo_config->rf.rf_local[ant] = build_rflocal(20,25,26,04);
p_exmimo_config->rf.rf_rxdc[ant] = build_rfdc(128, 128);
p_exmimo_config->rf.rf_vcocal[ant] = (0xE<<6) + 0xE;
}
/*
void setup_ue_buffers(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms, int carrier) {
int i;
if (phy_vars_ue) {
if ((frame_parms->nb_antennas_rx>1) && (carrier>0)) {
printf("RX antennas > 1 and carrier > 0 not possible\n");
exit(-1);
}
if ((frame_parms->nb_antennas_tx>1) && (carrier>0)) {
printf("TX antennas > 1 and carrier > 0 not possible\n");
exit(-1);
}
// replace RX signal buffers with mmaped HW versions
for (i=0;i<frame_parms->nb_antennas_rx;i++) {
free(phy_vars_ue->lte_ue_common_vars.rxdata[i]);
phy_vars_ue->lte_ue_common_vars.rxdata[i] = (s32*) openair0_exmimo_pci[card].adc_head[i+carrier];
printf("rxdata[%d] @ %p\n",i,phy_vars_ue->lte_ue_common_vars.rxdata[i]);
}
for (i=0;i<frame_parms->nb_antennas_tx;i++) {
free(phy_vars_ue->lte_ue_common_vars.txdata[i]);
phy_vars_ue->lte_ue_common_vars.txdata[i] = (s32*) openair0_exmimo_pci[card].dac_head[i+carrier];
printf("txdata[%d] @ %p\n",i,phy_vars_ue->lte_ue_common_vars.txdata[i]);
}
}
}
void setup_eNB_buffers(PHY_VARS_eNB *phy_vars_eNB, LTE_DL_FRAME_PARMS *frame_parms, int carrier) {
int i,j;
if (phy_vars_eNB) {
if ((frame_parms->nb_antennas_rx>1) && (carrier>0)) {
printf("RX antennas > 1 and carrier > 0 not possible\n");
exit(-1);
}
if ((frame_parms->nb_antennas_tx>1) && (carrier>0)) {
printf("TX antennas > 1 and carrier > 0 not possible\n");
exit(-1);
}
// replace RX signal buffers with mmaped HW versions
for (i=0;i<frame_parms->nb_antennas_rx;i++) {
free(phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i]);
phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i] = (s32*) openair0_exmimo_pci[card].adc_head[i+carrier];
printf("rxdata[%d] @ %p\n",i,phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i]);
for (j=0;j<16;j++) {
printf("rxbuffer %d: %x\n",j,phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i][j]);
phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i][j] = 16-j;
}
}
for (i=0;i<frame_parms->nb_antennas_tx;i++) {
free(phy_vars_eNB->lte_eNB_common_vars.txdata[0][i]);
phy_vars_eNB->lte_eNB_common_vars.txdata[0][i] = (s32*) openair0_exmimo_pci[card].dac_head[i+carrier];
printf("txdata[%d] @ %p\n",i,phy_vars_eNB->lte_eNB_common_vars.txdata[0][i]);
for (j=0;j<16;j++) {
printf("txbuffer %d: %x\n",j,phy_vars_eNB->lte_eNB_common_vars.txdata[0][i][j]);
phy_vars_eNB->lte_eNB_common_vars.txdata[0][i][j] = 16-j;
}
}
}
}
*/
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