|
|
|
@@ -26,6 +26,7 @@
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include "nr_phy_scope.h"
|
|
|
|
|
#include "executables/nr-softmodem-common.h"
|
|
|
|
|
#include <forms.h>
|
|
|
|
|
|
|
|
|
|
#define TPUT_WINDOW_LENGTH 100
|
|
|
|
|
#define localBuff(NaMe,SiZe) float NaMe[SiZe]; memset(NaMe,0,sizeof(NaMe));
|
|
|
|
@@ -47,8 +48,13 @@ typedef struct {
|
|
|
|
|
|
|
|
|
|
typedef struct OAIgraph {
|
|
|
|
|
FL_OBJECT *graph;
|
|
|
|
|
void (*gNBfunct) (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id);
|
|
|
|
|
void (*nrUEfunct) (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id);
|
|
|
|
|
float maxX;
|
|
|
|
|
float maxY;
|
|
|
|
|
float minX;
|
|
|
|
|
float minY;
|
|
|
|
|
int iteration;
|
|
|
|
|
void (*gNBfunct) (struct OAIgraph *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id);
|
|
|
|
|
void (*nrUEfunct)(struct OAIgraph *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id);
|
|
|
|
|
} OAIgraph_t;
|
|
|
|
|
|
|
|
|
|
/* Forms and Objects */
|
|
|
|
@@ -56,7 +62,7 @@ typedef struct {
|
|
|
|
|
FL_FORM *phy_scope;
|
|
|
|
|
OAIgraph_t graph[20];
|
|
|
|
|
FL_OBJECT *button_0;
|
|
|
|
|
} FD_phy_scope_t;
|
|
|
|
|
} OAI_phy_scope_t;
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
FL_FORM *stats_form;
|
|
|
|
@@ -72,18 +78,8 @@ static void drawsymbol(FL_OBJECT *obj, int id,
|
|
|
|
|
fl_points( p, n, FL_YELLOW);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ia_receiver_on_off( FL_OBJECT *button, long arg) {
|
|
|
|
|
if (fl_get_button(button)) {
|
|
|
|
|
fl_set_object_label(button, "IA Receiver ON");
|
|
|
|
|
// PHY_vars_UE_g[0][0]->use_ia_receiver = 1;
|
|
|
|
|
fl_set_object_color(button, FL_GREEN, FL_GREEN);
|
|
|
|
|
} else {
|
|
|
|
|
fl_set_object_label(button, "IA Receiver OFF");
|
|
|
|
|
// PHY_vars_UE_g[0][0]->use_ia_receiver = 0;
|
|
|
|
|
fl_set_object_color(button, FL_RED, FL_RED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// button callback example
|
|
|
|
|
#if 0
|
|
|
|
|
static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
|
|
|
|
|
if (fl_get_button(button)) {
|
|
|
|
|
fl_set_object_label(button, "DL Traffic ON");
|
|
|
|
@@ -95,201 +91,197 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
|
|
|
|
|
fl_set_object_color(button, FL_RED, FL_RED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static FL_OBJECT *commonGraph( int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
|
|
|
|
|
FL_OBJECT *graph;
|
|
|
|
|
graph=fl_add_xyplot(type, x, y, w, h, label);
|
|
|
|
|
fl_set_object_boxtype(graph, FL_EMBOSSED_BOX );
|
|
|
|
|
fl_set_object_lcolor(graph, FL_WHITE ); // Label color
|
|
|
|
|
fl_set_xyplot_symbol(graph, 0, drawsymbol);
|
|
|
|
|
fl_set_object_color(graph, FL_BLACK, pointColor);
|
|
|
|
|
fl_set_xyplot_symbol(graph, -1, drawsymbol);
|
|
|
|
|
return graph;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static OAIgraph_t gNBcommonGraph( void (*funct) (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id),
|
|
|
|
|
static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id),
|
|
|
|
|
int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
|
|
|
|
|
OAIgraph_t graph;
|
|
|
|
|
graph.graph=commonGraph(type, x, y, w, h, label, pointColor);
|
|
|
|
|
graph.gNBfunct=funct;
|
|
|
|
|
graph.nrUEfunct=NULL;
|
|
|
|
|
graph.maxX=0;
|
|
|
|
|
graph.maxY=0;
|
|
|
|
|
graph.minX=0;
|
|
|
|
|
graph.minY=0;
|
|
|
|
|
return graph;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static OAIgraph_t nrUEcommonGraph( void (*funct) (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id),
|
|
|
|
|
static OAIgraph_t nrUEcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id),
|
|
|
|
|
int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
|
|
|
|
|
OAIgraph_t graph;
|
|
|
|
|
graph.graph=commonGraph(type, x, y, w, h, label, pointColor);
|
|
|
|
|
graph.gNBfunct=NULL;
|
|
|
|
|
graph.nrUEfunct=funct;
|
|
|
|
|
graph.maxX=0;
|
|
|
|
|
graph.maxY=0;
|
|
|
|
|
graph.minX=0;
|
|
|
|
|
graph.minY=0;
|
|
|
|
|
return graph;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void phy_scope_gNB(FD_phy_scope_t *form,
|
|
|
|
|
PHY_VARS_gNB *phy_vars_gnb,
|
|
|
|
|
RU_t *phy_vars_ru,
|
|
|
|
|
int UE_id) {
|
|
|
|
|
static FD_phy_scope_t *remeberForm=NULL;
|
|
|
|
|
|
|
|
|
|
if (form==NULL)
|
|
|
|
|
form=remeberForm;
|
|
|
|
|
else
|
|
|
|
|
remeberForm=form;
|
|
|
|
|
|
|
|
|
|
if (form==NULL) return;
|
|
|
|
|
|
|
|
|
|
int i=0;
|
|
|
|
|
|
|
|
|
|
while (form->graph[i].graph) {
|
|
|
|
|
form->graph[i].gNBfunct(form->graph[i].graph, phy_vars_gnb, phy_vars_ru, UE_id);
|
|
|
|
|
i++;
|
|
|
|
|
static void setRange(OAIgraph_t *graph, float minX, float maxX, float minY, float maxY) {
|
|
|
|
|
if ( maxX > graph->maxX || maxY > graph->maxY || minX < graph->minX || minY < graph->minY ) {
|
|
|
|
|
graph->maxX=max(graph->maxX,maxX);
|
|
|
|
|
graph->minX=min(graph->minX,minX);
|
|
|
|
|
graph->maxY=max(graph->maxY,maxY);
|
|
|
|
|
graph->minY=min(graph->minY,minY);
|
|
|
|
|
fl_set_xyplot_ybounds(graph->graph, graph->minY, graph->maxY);
|
|
|
|
|
fl_set_xyplot_xbounds(graph->graph, graph->minX, graph->maxX);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_check_forms();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void timeSignal (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
|
|
|
|
|
static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, int NoAutoScale) {
|
|
|
|
|
if (layer==0)
|
|
|
|
|
fl_set_xyplot_data(graph->graph,x,y,len,"","","");
|
|
|
|
|
else
|
|
|
|
|
fl_add_xyplot_overlay(graph->graph,layer,x,y,len,rx_antenna_colors[layer]);
|
|
|
|
|
|
|
|
|
|
if ( NoAutoScale && graph->iteration%NoAutoScale == 0) {
|
|
|
|
|
float maxX=0, maxY=0, minX=0, minY=0;
|
|
|
|
|
|
|
|
|
|
for (int k=0; k<len; k++) {
|
|
|
|
|
maxX=max(maxX,x[k]);
|
|
|
|
|
minX=min(minX,x[k]);
|
|
|
|
|
maxY=max(maxY,y[k]);
|
|
|
|
|
minY=min(minY,y[k]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setRange(graph,minX,maxX, minY, maxY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
graph->iteration++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void genericLogPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) {
|
|
|
|
|
float *values=malloc(len*sizeof(*values));
|
|
|
|
|
float *time=malloc(len*sizeof(*time));
|
|
|
|
|
|
|
|
|
|
for (int ant=0; ant<nb_ant; ant++) {
|
|
|
|
|
if (data[ant] != NULL) {
|
|
|
|
|
for (int i=0; i<len; i+=8) {
|
|
|
|
|
float *vals=values+i;
|
|
|
|
|
float *tim=time+i;
|
|
|
|
|
const scopeSample_t *in=&(data[ant][i]);
|
|
|
|
|
|
|
|
|
|
for (int k=0; k<8; k++ ) {
|
|
|
|
|
vals[k] = 10*log10(1.0+SquaredNorm(in[k]));
|
|
|
|
|
tim[k] = i+k;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oai_xygraph(graph,time,values, len, ant, 10);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(values);
|
|
|
|
|
free(time);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) {
|
|
|
|
|
float values[len];
|
|
|
|
|
float time[len];
|
|
|
|
|
|
|
|
|
|
for (int ant=0; ant<nb_ant; ant++) {
|
|
|
|
|
if (data[ant] != NULL) {
|
|
|
|
|
for (int i=0; i<len; i++) {
|
|
|
|
|
values[i] = SquaredNorm(data[ant][i]);
|
|
|
|
|
time[i] = i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oai_xygraph(graph,time,values, len, ant, 10);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void timeSignal (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, const int nb_UEs) {
|
|
|
|
|
// Received signal in time domain of receive antenna 0
|
|
|
|
|
if (!phy_vars_ru->common.rxdata)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
|
|
|
|
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
|
|
|
|
|
scopeSample_t **rxsig_t = (scopeSample_t **)phy_vars_ru->common.rxdata;
|
|
|
|
|
float rxsig_t_dB[frame_parms->samples_per_frame];
|
|
|
|
|
float time[frame_parms->samples_per_frame];
|
|
|
|
|
genericLogPowerPerAntena(graph, frame_parms->nb_antennas_rx,
|
|
|
|
|
(const scopeSample_t **)phy_vars_ru->common.rxdata,
|
|
|
|
|
frame_parms->samples_per_frame);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int arx=0; arx<nb_antennas_rx; arx++) {
|
|
|
|
|
if (rxsig_t[arx] != NULL) {
|
|
|
|
|
for (int i=0; i<frame_parms->samples_per_frame; i++) {
|
|
|
|
|
rxsig_t_dB[i] = 10*log10(1.0+SquaredNorm(rxsig_t[arx][i]));
|
|
|
|
|
time[i] = i;
|
|
|
|
|
static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
|
|
|
|
const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size;
|
|
|
|
|
float values[len];
|
|
|
|
|
float time[len];
|
|
|
|
|
const int ant=0; // display antenna 0 for each UE
|
|
|
|
|
|
|
|
|
|
for (int ue=0; ue<nb_UEs; ue++) {
|
|
|
|
|
scopeSample_t *data= (scopeSample_t *)phy_vars_gnb->pusch_vars[ue]->ul_ch_estimates_time[ant];
|
|
|
|
|
|
|
|
|
|
if (data != NULL) {
|
|
|
|
|
for (int i=0; i<len; i++) {
|
|
|
|
|
values[i] = SquaredNorm(data[i]);
|
|
|
|
|
time[i] = i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (arx==0)
|
|
|
|
|
fl_set_xyplot_data(graph,time,rxsig_t_dB, frame_parms->samples_per_frame,"","","");
|
|
|
|
|
else
|
|
|
|
|
fl_add_xyplot_overlay(graph,arx,time,rxsig_t_dB,frame_parms->samples_per_frame,rx_antenna_colors[arx]);
|
|
|
|
|
oai_xygraph(graph,time,values, len, ue, 10);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void timeResponse (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
|
|
|
|
|
if (!phy_vars_gnb->pusch_vars[UE_id]->ul_ch_estimates_time)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
static void frequencyResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
|
|
|
|
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
|
|
|
|
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
|
|
|
|
|
scopeSample_t **chest_t = (scopeSample_t **) phy_vars_gnb->pusch_vars[UE_id]->ul_ch_estimates_time;
|
|
|
|
|
int ymax = 0;
|
|
|
|
|
float time2[2*frame_parms->ofdm_symbol_size];
|
|
|
|
|
float chest_t_abs[2*frame_parms->ofdm_symbol_size];
|
|
|
|
|
|
|
|
|
|
for (int arx=0; arx<nb_antennas_rx; arx++) {
|
|
|
|
|
if (chest_t[arx] !=NULL) {
|
|
|
|
|
for (int i=0; i<(2*frame_parms->ofdm_symbol_size); i++) {
|
|
|
|
|
time2[i] = (float)i;
|
|
|
|
|
chest_t_abs[i] = 10*log10(1.0 + SquaredNorm(chest_t[0][i]));
|
|
|
|
|
|
|
|
|
|
if (chest_t_abs[i] > ymax)
|
|
|
|
|
ymax = chest_t_abs[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (arx==0)
|
|
|
|
|
fl_set_xyplot_data(graph,time2,chest_t_abs,(2*frame_parms->ofdm_symbol_size),"","","");
|
|
|
|
|
else {
|
|
|
|
|
fl_add_xyplot_overlay(graph,arx,time2,chest_t_abs,(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
|
|
|
|
|
fl_set_xyplot_overlay_type(graph,arx,FL_DASHED_XYPLOT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Avoid flickering effect
|
|
|
|
|
// fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
|
|
|
|
|
fl_set_xyplot_ybounds(graph,0,ymax);
|
|
|
|
|
genericLogPowerPerAntena(graph, frame_parms->nb_antennas_rx,
|
|
|
|
|
(const scopeSample_t **)phy_vars_ru->common.rxdataF,
|
|
|
|
|
frame_parms->samples_per_slot_wCP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void frequencyResponse (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
|
|
|
|
|
// Channel Frequency Response
|
|
|
|
|
if (!phy_vars_ru->common.rxdataF)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
|
|
|
|
//uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
|
|
|
|
|
scopeSample_t **rxsig_f = (scopeSample_t **) phy_vars_ru->common.rxdataF;
|
|
|
|
|
float rxsig_f_dB[frame_parms->samples_per_slot_wCP];
|
|
|
|
|
float time[frame_parms->samples_per_slot_wCP];
|
|
|
|
|
|
|
|
|
|
if (rxsig_f[0] != NULL) {
|
|
|
|
|
for (int i=0; i<frame_parms->samples_per_slot_wCP; i++) {
|
|
|
|
|
rxsig_f_dB[i] = 10*log10(1.0+ SquaredNorm(rxsig_f[0][i]));
|
|
|
|
|
time[i] = (float) i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_set_xyplot_data(graph,time,rxsig_f_dB,frame_parms->samples_per_slot_wCP,"","","");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
for (int arx=1; arx<nb_antennas_rx; arx++) {
|
|
|
|
|
if (chest_f[(atx<<1)+arx] != NULL) {
|
|
|
|
|
for (int k=0; k<nsymb_ce; k++) {
|
|
|
|
|
time[k] = (float)ind;
|
|
|
|
|
chest_f_abs[k] = (short)10*log10(1.0+SquaredNorm(chest_f[(atx<<1)+arx][k]));
|
|
|
|
|
ind++;
|
|
|
|
|
}
|
|
|
|
|
fl_add_xyplot_overlay(form->chest_f,1,time,chest_f_abs,nsymb_ce,rx_antenna_colors[arx]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
/*
|
|
|
|
|
// tx antenna 0
|
|
|
|
|
fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
|
|
|
|
|
fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,3);
|
|
|
|
|
fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
|
|
|
|
|
fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void puschLLR (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
|
|
|
|
|
// PUSCH LLRs
|
|
|
|
|
if (!phy_vars_gnb->pusch_vars[UE_id]->llr)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
//NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
|
|
|
|
static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
|
|
|
|
//int Qm = 2;
|
|
|
|
|
int16_t *pusch_llr = (int16_t *) phy_vars_gnb->pusch_vars[UE_id]->llr;
|
|
|
|
|
int coded_bits_per_codeword =3*8*6144+12; // (8*((3*8*6144)+12)); // frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti;
|
|
|
|
|
float llr[coded_bits_per_codeword];
|
|
|
|
|
float bit[coded_bits_per_codeword];
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<coded_bits_per_codeword; i++) {
|
|
|
|
|
llr[i] = (float) pusch_llr[i];
|
|
|
|
|
bit[i] = (float) i;
|
|
|
|
|
}
|
|
|
|
|
for (int ue=0; ue<nb_UEs; ue++) {
|
|
|
|
|
int16_t *pusch_llr = (int16_t *)phy_vars_gnb->pusch_vars[ue]->llr;
|
|
|
|
|
|
|
|
|
|
fl_set_xyplot_data(graph,bit,llr,coded_bits_per_codeword,"","","");
|
|
|
|
|
if (pusch_llr) {
|
|
|
|
|
for (int i=0; i<coded_bits_per_codeword; i++) {
|
|
|
|
|
llr[i] = (float) pusch_llr[i];
|
|
|
|
|
bit[i] = (float) i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oai_xygraph(graph,bit,llr,coded_bits_per_codeword,ue,10);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void puschIQ (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
|
|
|
|
|
// PUSCH I/Q of MF Output
|
|
|
|
|
if (!phy_vars_gnb->pusch_vars[UE_id]->rxdataF_comp)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
static void puschIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
|
|
|
|
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
|
|
|
|
scopeSample_t *pusch_comp = (scopeSample_t *) phy_vars_gnb->pusch_vars[UE_id]->rxdataF_comp[0];
|
|
|
|
|
int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot;
|
|
|
|
|
float I[sz], Q[sz];
|
|
|
|
|
|
|
|
|
|
for (int k=0; k<sz; k++ ) {
|
|
|
|
|
I[k] = pusch_comp[k].r;
|
|
|
|
|
Q[k] = pusch_comp[k].i;
|
|
|
|
|
for (int ue=0; ue<nb_UEs; ue++) {
|
|
|
|
|
scopeSample_t *pusch_comp = (scopeSample_t *) phy_vars_gnb->pusch_vars[ue]->rxdataF_comp[0];
|
|
|
|
|
|
|
|
|
|
if (pusch_comp) {
|
|
|
|
|
for (int k=0; k<sz; k++ ) {
|
|
|
|
|
I[k] = pusch_comp[k].r;
|
|
|
|
|
Q[k] = pusch_comp[k].i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oai_xygraph(graph,I,Q,sz,ue,10);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_set_xyplot_data(graph,I,Q,sz,"","","");
|
|
|
|
|
|
|
|
|
|
static void pucchEnergy (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
|
|
|
|
// PUSCH I/Q of MF Output
|
|
|
|
|
// Code to fixed, disabled for cppcheck
|
|
|
|
|
#if 0
|
|
|
|
|
if (NULL) {
|
|
|
|
|
/*
|
|
|
|
|
int32_t *pucch1ab_comp = (int32_t *) NULL; //phy_vars_gnb->pucch1ab_stats[UE_id];
|
|
|
|
|
int32_t *pucch1_comp = (int32_t *) NULL; //phy_vars_gnb->pucch1_stats[UE_id];
|
|
|
|
|
float I_pucch[10240],Q_pucch[10240],A_pucch[10240],B_pucch[10240],C_pucch[10240];
|
|
|
|
@@ -310,17 +302,15 @@ static void puschIQ (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_var
|
|
|
|
|
fl_set_xyplot_xbounds(graph,-5000,5000);
|
|
|
|
|
fl_set_xyplot_ybounds(graph,0,80);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void pucchEnergy (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
|
|
|
|
|
static void pucchIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void pucchIQ (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void puschThroughtput (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
|
|
|
|
|
static void puschThroughtput (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
|
|
|
|
// PUSCH Throughput
|
|
|
|
|
/*
|
|
|
|
|
memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
|
|
|
|
|
memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
|
|
|
|
|
tput_time_enb[UE_id][TPUT_WINDOW_LENGTH-1] = (float) 0;
|
|
|
|
@@ -328,224 +318,126 @@ static void puschThroughtput (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t
|
|
|
|
|
fl_set_xyplot_data(graph,tput_time_enb[UE_id],tput_enb[UE_id],TPUT_WINDOW_LENGTH,"","","");
|
|
|
|
|
// fl_get_xyplot_ybounds(form->pusch_tput,&ymin,&ymax);
|
|
|
|
|
// fl_set_xyplot_ybounds(form->pusch_tput,0,ymax);
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static FD_phy_scope_t *create_phy_scope_gnb(int UE_id ) {
|
|
|
|
|
static OAI_phy_scope_t *create_phy_scope_gnb(void) {
|
|
|
|
|
FL_OBJECT *obj;
|
|
|
|
|
FD_phy_scope_t *fdui = fl_malloc( sizeof *fdui );
|
|
|
|
|
OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
|
|
|
|
|
// Define form
|
|
|
|
|
fdui->phy_scope = fl_bgn_form( FL_NO_BOX, 800, 800 );
|
|
|
|
|
// This the whole UI box
|
|
|
|
|
obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
|
|
|
|
|
fl_set_object_color( obj, FL_BLACK, FL_BLACK );
|
|
|
|
|
fl_set_object_color( obj, FL_BLACK, FL_WHITE );
|
|
|
|
|
int curY=0,x,y,w,h;
|
|
|
|
|
// Received signal
|
|
|
|
|
fdui->graph[0] = gNBcommonGraph( timeSignal, FL_IMPULSE_XYPLOT, 20, 20, 370, 100,
|
|
|
|
|
fdui->graph[0] = gNBcommonGraph( timeSignal, FL_NORMAL_XYPLOT, 0, curY, 400, 100,
|
|
|
|
|
"Received Signal (Time-Domain, dB)", FL_RED );
|
|
|
|
|
// Time-domain channel response
|
|
|
|
|
fdui->graph[1] = gNBcommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, 20, 370, 100,
|
|
|
|
|
fdui->graph[1] = gNBcommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, curY, 400, 100,
|
|
|
|
|
"SRS Frequency Response (samples, abs)", FL_RED );
|
|
|
|
|
fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h);
|
|
|
|
|
curY+=h;
|
|
|
|
|
// Frequency-domain channel response
|
|
|
|
|
fdui->graph[2] = gNBcommonGraph( frequencyResponse, FL_IMPULSE_XYPLOT, 20, 140, 760, 100,
|
|
|
|
|
fdui->graph[2] = gNBcommonGraph( frequencyResponse, FL_NORMAL_XYPLOT, 0, curY, 800, 100,
|
|
|
|
|
"Channel Frequency Response (RE, dB)", FL_RED );
|
|
|
|
|
fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h);
|
|
|
|
|
curY+=h;
|
|
|
|
|
// LLR of PUSCH
|
|
|
|
|
fdui->graph[3] = gNBcommonGraph( puschLLR, FL_POINTS_XYPLOT, 20, 260, 500, 200,
|
|
|
|
|
fdui->graph[3] = gNBcommonGraph( puschLLR, FL_POINTS_XYPLOT, 0, curY, 500, 200,
|
|
|
|
|
"PUSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
|
|
|
|
|
// I/Q PUSCH comp
|
|
|
|
|
fdui->graph[4] = gNBcommonGraph( puschIQ, FL_POINTS_XYPLOT, 540, 260, 240, 200,
|
|
|
|
|
fdui->graph[4] = gNBcommonGraph( puschIQ, FL_POINTS_XYPLOT, 500, curY, 300, 200,
|
|
|
|
|
"PUSCH I/Q of MF Output", FL_YELLOW );
|
|
|
|
|
fl_get_object_bbox(fdui->graph[3].graph,&x, &y,&w, &h);
|
|
|
|
|
curY+=h;
|
|
|
|
|
// I/Q PUCCH comp (format 1)
|
|
|
|
|
fdui->graph[5] = gNBcommonGraph( pucchEnergy, FL_POINTS_XYPLOT, 540, 480, 240, 100,
|
|
|
|
|
fdui->graph[5] = gNBcommonGraph( pucchEnergy, FL_POINTS_XYPLOT, 0, curY, 300, 100,
|
|
|
|
|
"PUCCH1 Energy (SR)", FL_YELLOW );
|
|
|
|
|
// fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
|
|
|
|
|
// I/Q PUCCH comp (fromat 1a/b)
|
|
|
|
|
fdui->graph[6] = gNBcommonGraph( pucchIQ, FL_POINTS_XYPLOT, 540, 600, 240, 100,
|
|
|
|
|
fdui->graph[6] = gNBcommonGraph( pucchIQ, FL_POINTS_XYPLOT, 500, curY, 300, 100,
|
|
|
|
|
"PUCCH I/Q of MF Output", FL_YELLOW );
|
|
|
|
|
fl_get_object_bbox(fdui->graph[6].graph,&x, &y,&w, &h);
|
|
|
|
|
curY+=h;
|
|
|
|
|
// Throughput on PUSCH
|
|
|
|
|
fdui->graph[7] = gNBcommonGraph( puschThroughtput, FL_NORMAL_XYPLOT, 20, 480, 500, 100,
|
|
|
|
|
fdui->graph[7] = gNBcommonGraph( puschThroughtput, FL_NORMAL_XYPLOT, 0, curY, 500, 100,
|
|
|
|
|
"PUSCH Throughput [frame]/[kbit/s]", FL_WHITE );
|
|
|
|
|
fdui->graph[8].graph=NULL;
|
|
|
|
|
|
|
|
|
|
// Generic eNB Button
|
|
|
|
|
if (0) { // code kept to later add command buttons
|
|
|
|
|
fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" );
|
|
|
|
|
fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
|
|
|
|
|
fl_set_button(fdui->button_0,0);
|
|
|
|
|
otg_enabled = 0;
|
|
|
|
|
fl_set_object_label(fdui->button_0, "DL Traffic OFF");
|
|
|
|
|
fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
|
|
|
|
|
fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_end_form( );
|
|
|
|
|
fdui->phy_scope->fdui = fdui;
|
|
|
|
|
char title[100];
|
|
|
|
|
sprintf (title, "LTE UL SCOPE eNB for UE %d",UE_id);
|
|
|
|
|
fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
|
|
|
|
|
fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, "LTE UL SCOPE gNB");
|
|
|
|
|
return fdui;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static FD_phy_scope_t *form_gnb[NUMBER_OF_UE_MAX]= {0};
|
|
|
|
|
static unsigned char scope_enb_num_ue = 1;
|
|
|
|
|
static const int scope_enb_num_ue = 1;
|
|
|
|
|
void phy_scope_gNB(OAI_phy_scope_t *form,
|
|
|
|
|
PHY_VARS_gNB *phy_vars_gnb,
|
|
|
|
|
RU_t *phy_vars_ru,
|
|
|
|
|
int UE_id) {
|
|
|
|
|
static OAI_phy_scope_t *remeberForm=NULL;
|
|
|
|
|
|
|
|
|
|
if (form==NULL)
|
|
|
|
|
form=remeberForm;
|
|
|
|
|
else
|
|
|
|
|
remeberForm=form;
|
|
|
|
|
|
|
|
|
|
if (form==NULL) return;
|
|
|
|
|
|
|
|
|
|
int i=0;
|
|
|
|
|
|
|
|
|
|
while (form->graph[i].graph) {
|
|
|
|
|
form->graph[i].gNBfunct(form->graph+i, phy_vars_gnb, phy_vars_ru, UE_id);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_check_forms();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void *scope_thread_gNB(void *arg) {
|
|
|
|
|
scopeParms_t *p=(scopeParms_t *) arg;
|
|
|
|
|
//# ifdef ENABLE_XFORMS_WRITE_STATS
|
|
|
|
|
// FILE *gNB_stats = fopen("gNB_stats.txt", "w");
|
|
|
|
|
//#endif
|
|
|
|
|
size_t stksize;
|
|
|
|
|
pthread_attr_t atr;
|
|
|
|
|
size_t stksize=0;
|
|
|
|
|
pthread_attr_t atr= {0};
|
|
|
|
|
pthread_attr_getstacksize(&atr, &stksize);
|
|
|
|
|
pthread_attr_setstacksize(&atr,32*1024*1024 );
|
|
|
|
|
sleep(3); // no clean interthread barriers
|
|
|
|
|
fl_initialize (p->argc, p->argv, NULL, 0, 0);
|
|
|
|
|
int nb_ue=min(NUMBER_OF_UE_MAX, scope_enb_num_ue);
|
|
|
|
|
OAI_phy_scope_t *form_gnb = create_phy_scope_gnb();
|
|
|
|
|
|
|
|
|
|
while (!oai_exit) {
|
|
|
|
|
int ue_cnt=0;
|
|
|
|
|
|
|
|
|
|
for(int UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
|
|
|
|
|
if ((ue_cnt<scope_enb_num_ue)) {
|
|
|
|
|
//this function needs to be written
|
|
|
|
|
phy_scope_gNB(form_gnb[ue_cnt], p->gNB, p->ru, UE_id);
|
|
|
|
|
ue_cnt++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
phy_scope_gNB(form_gnb, p->gNB, p->ru, nb_ue);
|
|
|
|
|
usleep(99*1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// printf("%s",stats_buffer);
|
|
|
|
|
/*#ifdef ENABLE_XFORMS_WRITE_STATS
|
|
|
|
|
|
|
|
|
|
if (eNB_stats) {
|
|
|
|
|
rewind (gNB_stats);
|
|
|
|
|
fwrite (stats_buffer, 1, len, gNB_stats);
|
|
|
|
|
fclose (gNB_stats);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
pthread_exit((void *)arg);
|
|
|
|
|
}*/
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void gNBinitScope(scopeParms_t *p) {
|
|
|
|
|
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
|
|
|
|
|
fl_initialize (p->argc, p->argv, NULL, 0, 0);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
form_stats_l2 = create_form_stats_form();
|
|
|
|
|
fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");
|
|
|
|
|
form_stats = create_form_stats_form();
|
|
|
|
|
fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
|
|
|
|
|
*/
|
|
|
|
|
for(int UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
|
|
|
|
|
form_gnb[UE_id] = create_phy_scope_gnb(UE_id);
|
|
|
|
|
} // UE_id
|
|
|
|
|
|
|
|
|
|
static scopeParms_t parms;
|
|
|
|
|
memcpy(&parms,p,sizeof(parms));
|
|
|
|
|
pthread_t forms_thread;
|
|
|
|
|
threadCreate(&forms_thread, scope_thread_gNB, &parms, "scope", -1, OAI_PRIORITY_RT_LOW);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ueTimeResponse (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
static void ueTimeResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
// Received signal in time domain of receive antenna 0
|
|
|
|
|
if (! phy_vars_ue->common_vars.rxdata)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
|
|
|
|
|
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
|
|
|
|
|
int samples_per_frame = frame_parms->samples_per_frame;
|
|
|
|
|
scopeSample_t **rxsig_t = (scopeSample_t **) phy_vars_ue->common_vars.rxdata;
|
|
|
|
|
float rxsig_t_dB[samples_per_frame];
|
|
|
|
|
float time[samples_per_frame];
|
|
|
|
|
|
|
|
|
|
if (rxsig_t[0] != NULL) {
|
|
|
|
|
for (int i=0; i<samples_per_frame; i++) {
|
|
|
|
|
rxsig_t_dB[i] = 10*log10(1.0+SquaredNorm(rxsig_t[0][i]));
|
|
|
|
|
time[i] = (float) i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_set_xyplot_data(graph,time,rxsig_t_dB,samples_per_frame,"","","");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int arx=1; arx<nb_antennas_rx; arx++) {
|
|
|
|
|
if (rxsig_t[arx] != NULL) {
|
|
|
|
|
for (int i=0; i<FRAME_LENGTH_COMPLEX_SAMPLES; i++) {
|
|
|
|
|
rxsig_t_dB[i] = 10*log10(1.0+SquaredNorm(rxsig_t[arx][i]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_add_xyplot_overlay(graph,arx,time,rxsig_t_dB,FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (phy_vars_ue->is_synchronized==0) {
|
|
|
|
|
//float corr[samples_per_frame];
|
|
|
|
|
for (int ind=0; ind<3; ind++) {
|
|
|
|
|
/*
|
|
|
|
|
if (pss_corr_ue[ind]) {
|
|
|
|
|
for (i=0; i<samples_per_frame; i++) {
|
|
|
|
|
corr[i] = (float) pss_corr_ue[ind][i];
|
|
|
|
|
time[i] = (float) i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ind==0)
|
|
|
|
|
fl_set_xyplot_data(form->chest_t,time,corr,samples_per_frame,"","","");
|
|
|
|
|
else
|
|
|
|
|
fl_add_xyplot_overlay(form->chest_t,ind,time,corr,samples_per_frame,rx_antenna_colors[ind]);
|
|
|
|
|
|
|
|
|
|
overlay = 1;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if the UE is not synchronized, we can make only the time*power graph
|
|
|
|
|
}
|
|
|
|
|
genericLogPowerPerAntena(graph, phy_vars_ue->frame_parms.nb_antennas_rx,
|
|
|
|
|
(const scopeSample_t **) phy_vars_ue->common_vars.rxdata,
|
|
|
|
|
phy_vars_ue->frame_parms.samples_per_frame);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ueChannelResponse (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
static void ueChannelResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
// Channel Impulse Response
|
|
|
|
|
if (!phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
|
|
|
|
|
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
|
|
|
|
|
scopeSample_t **chest_t = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time;
|
|
|
|
|
int ymax = 0;
|
|
|
|
|
float chest_t_abs[frame_parms->ofdm_symbol_size];
|
|
|
|
|
float time[frame_parms->ofdm_symbol_size>>3];
|
|
|
|
|
|
|
|
|
|
if (chest_t[0] !=NULL) {
|
|
|
|
|
for (int i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
|
|
|
|
|
chest_t_abs[i] = SquaredNorm(chest_t[0][i]);
|
|
|
|
|
time[i] = (float) i;
|
|
|
|
|
|
|
|
|
|
if (chest_t_abs[i] > ymax)
|
|
|
|
|
ymax = chest_t_abs[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_set_xyplot_data(graph,time,chest_t_abs,(frame_parms->ofdm_symbol_size>>3),"","","");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int arx=1; arx<nb_antennas_rx; arx++) {
|
|
|
|
|
if (chest_t[arx] !=NULL) {
|
|
|
|
|
for (int i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
|
|
|
|
|
chest_t_abs[i] = SquaredNorm(chest_t[arx][i]);
|
|
|
|
|
|
|
|
|
|
if (chest_t_abs[i] > ymax)
|
|
|
|
|
ymax = chest_t_abs[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_add_xyplot_overlay(graph,arx,time,chest_t_abs,(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
|
|
|
|
|
fl_set_xyplot_overlay_type(graph,arx,FL_DASHED_XYPLOT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Avoid flickering effect
|
|
|
|
|
// fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); // Does not always work...
|
|
|
|
|
fl_set_xyplot_ybounds(graph,0,(double) ymax);
|
|
|
|
|
genericPowerPerAntena(graph, phy_vars_ue->frame_parms.nb_antennas_rx,
|
|
|
|
|
(const scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time,
|
|
|
|
|
phy_vars_ue->frame_parms.ofdm_symbol_size>>3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void uePbchFrequencyResp (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
// Channel Frequency Response (includes 5 complex sample for filter)
|
|
|
|
|
if (!phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates)
|
|
|
|
|
return;
|
|
|
|
@@ -575,10 +467,10 @@ static void uePbchFrequencyResp (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue,
|
|
|
|
|
//fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
|
|
|
|
|
// fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
|
|
|
|
|
//fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
|
|
|
|
|
fl_set_xyplot_data(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,"","","");
|
|
|
|
|
oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void uePbchLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
static void uePbchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
// PBCH LLRs
|
|
|
|
|
if ( !phy_vars_ue->pbch_vars[eNB_id]->llr)
|
|
|
|
|
return;
|
|
|
|
@@ -591,15 +483,15 @@ static void uePbchLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
|
|
|
|
|
bit_pbch[i] = (float) i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_set_xyplot_data(graph,bit_pbch,llr_pbch,864,"","","");
|
|
|
|
|
oai_xygraph(graph,bit_pbch,llr_pbch,864,0,10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void uePbchIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
// PBCH I/Q of MF Output
|
|
|
|
|
if (!phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0])
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
int16_t *pbch_comp = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
|
|
|
|
|
scopeSample_t *pbch_comp = (scopeSample_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
|
|
|
|
|
localBuff(I,180*3);
|
|
|
|
|
localBuff(Q,180*3);
|
|
|
|
|
int first_symbol=1;
|
|
|
|
@@ -616,17 +508,17 @@ static void uePbchIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id
|
|
|
|
|
AssertFatal(base+nb_re<180*3,"");
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<nb_re; i++) {
|
|
|
|
|
I[base+i] = pbch_comp[2*symbol*20*12+2*i];
|
|
|
|
|
Q[base+i] = pbch_comp[2*symbol*20*12+2*i+1];
|
|
|
|
|
I[base+i] = pbch_comp[symbol*20*12+i].r;
|
|
|
|
|
Q[base+i] = pbch_comp[symbol*20*12+i].i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base+=nb_re;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_set_xyplot_data(graph,I,Q,base,"","","");
|
|
|
|
|
oai_xygraph(graph,I,Q,base,0,10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void uePcchLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
// PDCCH LLRs
|
|
|
|
|
if (!phy_vars_ue->pdcch_vars[0][eNB_id]->llr)
|
|
|
|
|
return;
|
|
|
|
@@ -656,34 +548,34 @@ static void uePcchLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
|
|
|
|
|
//fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
|
|
|
|
|
// fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
|
|
|
|
|
//fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
|
|
|
|
|
fl_set_xyplot_data(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,"","","");
|
|
|
|
|
oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void uePcchIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
// PDCCH I/Q of MF Output
|
|
|
|
|
if (!phy_vars_ue->pdcch_vars[0][eNB_id]->rxdataF_comp[0])
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
int nb=12*273*4; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
|
|
|
|
|
int nb=4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
|
|
|
|
|
localBuff(I,nb*RX_NB_TH_MAX);
|
|
|
|
|
localBuff(Q,nb*RX_NB_TH_MAX);
|
|
|
|
|
int base=0;
|
|
|
|
|
|
|
|
|
|
for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
|
|
|
|
|
int16_t *pdcch_comp = (int16_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->rxdataF_comp[0];
|
|
|
|
|
scopeSample_t *pdcch_comp = (scopeSample_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->rxdataF_comp[0];
|
|
|
|
|
|
|
|
|
|
for (int i=0; i< nb; i++) {
|
|
|
|
|
I[base+i] = pdcch_comp[i*2];
|
|
|
|
|
Q[base+i] = pdcch_comp[i*2+1];
|
|
|
|
|
I[base+i] = pdcch_comp[i].r;
|
|
|
|
|
Q[base+i] = pdcch_comp[i].i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base+=nb;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_set_xyplot_data(graph,I,Q,base,"","","");
|
|
|
|
|
oai_xygraph(graph,I,Q,base,0,10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void uePdschLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
// PDSCH LLRs
|
|
|
|
|
if (!phy_vars_ue->pdsch_vars[0][eNB_id]->llr[0])
|
|
|
|
|
return;
|
|
|
|
@@ -707,10 +599,10 @@ static void uePdschLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword);
|
|
|
|
|
fl_set_xyplot_data(graph,bit,llr,base,"","","");
|
|
|
|
|
oai_xygraph(graph,bit,llr,base,0,10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void uePdschIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
// PDSCH I/Q of MF Output
|
|
|
|
|
if (!phy_vars_ue->pdsch_vars[0][eNB_id]->rxdataF_comp0[0])
|
|
|
|
|
return;
|
|
|
|
@@ -722,17 +614,20 @@ static void uePdschIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
|
|
|
|
|
int base=0;
|
|
|
|
|
|
|
|
|
|
for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
|
|
|
|
|
int16_t *pdsch_comp = (int16_t *) phy_vars_ue->pdsch_vars[thr][eNB_id]->rxdataF_comp0[0];
|
|
|
|
|
scopeSample_t *pdsch_comp = (scopeSample_t *) phy_vars_ue->pdsch_vars[thr][eNB_id]->rxdataF_comp0[0];
|
|
|
|
|
|
|
|
|
|
for (int s=0; s<sz; s++) {
|
|
|
|
|
I[s+base] += pdsch_comp[2*s];
|
|
|
|
|
Q[s+base] += pdsch_comp[2*s+1];
|
|
|
|
|
I[s+base] += pdsch_comp[s].r;
|
|
|
|
|
Q[s+base] += pdsch_comp[s].i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base+=sz;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_set_xyplot_data(graph,I,Q,base,"","","");
|
|
|
|
|
oai_xygraph(graph,I,Q,base,0,10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void uePdschThroughput (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
// PDSCH Throughput
|
|
|
|
@@ -752,50 +647,59 @@ static void uePdschIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void uePdschThroughput (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static FD_phy_scope_t *create_phy_scope_nrue( int ID ) {
|
|
|
|
|
static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
|
|
|
|
|
FL_OBJECT *obj;
|
|
|
|
|
FD_phy_scope_t *fdui = fl_malloc( sizeof *fdui );
|
|
|
|
|
OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
|
|
|
|
|
// Define form
|
|
|
|
|
fdui->phy_scope = fl_bgn_form( FL_NO_BOX, 800, 900 );
|
|
|
|
|
// This the whole UI box
|
|
|
|
|
obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 900, "" );
|
|
|
|
|
fl_set_object_color( obj, FL_BLACK, FL_BLACK );
|
|
|
|
|
int curY=0,x,y,w,h;
|
|
|
|
|
// Received signal
|
|
|
|
|
fdui->graph[0] = nrUEcommonGraph(ueTimeResponse,
|
|
|
|
|
FL_IMPULSE_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)", FL_RED );
|
|
|
|
|
FL_NORMAL_XYPLOT, 0, curY, 400, 100, "Received Signal (Time-Domain, dB)", FL_RED );
|
|
|
|
|
// Time-domain channel response
|
|
|
|
|
fdui->graph[1] = nrUEcommonGraph(ueChannelResponse,
|
|
|
|
|
FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)", FL_RED );
|
|
|
|
|
FL_NORMAL_XYPLOT, 400, curY, 400, 100, "Channel Impulse Response (samples, abs)", FL_RED );
|
|
|
|
|
fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h);
|
|
|
|
|
curY+=h;
|
|
|
|
|
// Frequency-domain channel response
|
|
|
|
|
fdui->graph[2] = nrUEcommonGraph(uePbchFrequencyResp,
|
|
|
|
|
FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency data (RE, dB)", FL_RED );
|
|
|
|
|
FL_IMPULSE_XYPLOT, 0, curY, 800, 100, "Channel Frequency data (RE, dB)", FL_RED );
|
|
|
|
|
fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h);
|
|
|
|
|
curY+=h;
|
|
|
|
|
// LLR of PBCH
|
|
|
|
|
fdui->graph[3] = nrUEcommonGraph(uePbchLLR,
|
|
|
|
|
FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)", FL_GREEN );
|
|
|
|
|
FL_POINTS_XYPLOT, 0, curY, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)", FL_GREEN );
|
|
|
|
|
fl_set_xyplot_xgrid(fdui->graph[3].graph,FL_GRID_MAJOR);
|
|
|
|
|
// I/Q PBCH comp
|
|
|
|
|
fdui->graph[4] = nrUEcommonGraph(uePbchIQ,
|
|
|
|
|
FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output", FL_GREEN );
|
|
|
|
|
FL_POINTS_XYPLOT, 500, curY, 300, 100, "PBCH I/Q of MF Output", FL_GREEN );
|
|
|
|
|
fl_get_object_bbox(fdui->graph[3].graph,&x, &y,&w, &h);
|
|
|
|
|
curY+=h;
|
|
|
|
|
// LLR of PDCCH
|
|
|
|
|
fdui->graph[5] = nrUEcommonGraph(uePcchLLR,
|
|
|
|
|
FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)", FL_CYAN );
|
|
|
|
|
FL_POINTS_XYPLOT, 0, curY, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)", FL_CYAN );
|
|
|
|
|
// I/Q PDCCH comp
|
|
|
|
|
fdui->graph[6] = nrUEcommonGraph(uePcchIQ,
|
|
|
|
|
FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output", FL_CYAN );
|
|
|
|
|
FL_POINTS_XYPLOT, 500, curY, 300, 100, "PDCCH I/Q of MF Output", FL_CYAN );
|
|
|
|
|
fl_get_object_bbox(fdui->graph[5].graph,&x, &y,&w, &h);
|
|
|
|
|
curY+=h;
|
|
|
|
|
// LLR of PDSCH
|
|
|
|
|
fdui->graph[7] = nrUEcommonGraph(uePdschLLR,
|
|
|
|
|
FL_POINTS_XYPLOT, 20, 500, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
|
|
|
|
|
FL_POINTS_XYPLOT, 0, curY, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
|
|
|
|
|
// I/Q PDSCH comp
|
|
|
|
|
fdui->graph[8] = nrUEcommonGraph(uePdschIQ,
|
|
|
|
|
FL_POINTS_XYPLOT, 540, 500, 240, 200, "PDSCH I/Q of MF Output", FL_YELLOW );
|
|
|
|
|
FL_POINTS_XYPLOT, 500, curY, 300, 200, "PDSCH I/Q of MF Output", FL_YELLOW );
|
|
|
|
|
fl_get_object_bbox(fdui->graph[8].graph,&x, &y,&w, &h);
|
|
|
|
|
curY+=h;
|
|
|
|
|
// Throughput on PDSCH
|
|
|
|
|
fdui->graph[9] = nrUEcommonGraph(uePdschThroughput,
|
|
|
|
|
FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]", FL_WHITE );
|
|
|
|
|
FL_NORMAL_XYPLOT, 0, curY, 500, 100, "PDSCH Throughput [frame]/[kbit/s]", FL_WHITE );
|
|
|
|
|
fdui->graph[10].graph=NULL;
|
|
|
|
|
// Generic UE Button
|
|
|
|
|
#if 0
|
|
|
|
|
fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
|
|
|
|
|
fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
|
|
|
|
|
//openair_daq_vars.use_ia_receiver = 0;
|
|
|
|
@@ -804,6 +708,7 @@ static FD_phy_scope_t *create_phy_scope_nrue( int ID ) {
|
|
|
|
|
fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
|
|
|
|
|
fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 );
|
|
|
|
|
fl_hide_object(fdui->button_0);
|
|
|
|
|
#endif
|
|
|
|
|
fl_end_form( );
|
|
|
|
|
fdui->phy_scope->fdui = fdui;
|
|
|
|
|
char buf[100];
|
|
|
|
@@ -812,11 +717,11 @@ static FD_phy_scope_t *create_phy_scope_nrue( int ID ) {
|
|
|
|
|
return fdui;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void phy_scope_nrUE(FD_phy_scope_t *form,
|
|
|
|
|
void phy_scope_nrUE(OAI_phy_scope_t *form,
|
|
|
|
|
PHY_VARS_NR_UE *phy_vars_ue,
|
|
|
|
|
int eNB_id,
|
|
|
|
|
int UE_id) {
|
|
|
|
|
static FD_phy_scope_t *remeberForm=NULL;
|
|
|
|
|
static OAI_phy_scope_t *remeberForm=NULL;
|
|
|
|
|
|
|
|
|
|
if (form==NULL)
|
|
|
|
|
form=remeberForm;
|
|
|
|
@@ -829,15 +734,13 @@ void phy_scope_nrUE(FD_phy_scope_t *form,
|
|
|
|
|
int i=0;
|
|
|
|
|
|
|
|
|
|
while (form->graph[i].graph) {
|
|
|
|
|
form->graph[i].nrUEfunct(form->graph[i].graph, phy_vars_ue, eNB_id, UE_id);
|
|
|
|
|
form->graph[i].nrUEfunct(form->graph+i, phy_vars_ue, eNB_id, UE_id);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fl_check_forms();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static FD_phy_scope_t *form_nrue[NUMBER_OF_UE_MAX];
|
|
|
|
|
static pthread_t forms_thread;
|
|
|
|
|
|
|
|
|
|
static void *nrUEscopeThread(void *arg) {
|
|
|
|
|
PHY_VARS_NR_UE *ue=(PHY_VARS_NR_UE *)arg;
|
|
|
|
@@ -845,9 +748,13 @@ static void *nrUEscopeThread(void *arg) {
|
|
|
|
|
pthread_attr_t atr;
|
|
|
|
|
pthread_attr_getstacksize(&atr, &stksize);
|
|
|
|
|
pthread_attr_setstacksize(&atr,32*1024*1024 );
|
|
|
|
|
int fl_argc=1;
|
|
|
|
|
char *name="5G-UE-scope";
|
|
|
|
|
fl_initialize (&fl_argc, &name, NULL, 0, 0);
|
|
|
|
|
OAI_phy_scope_t *form_nrue=create_phy_scope_nrue(0);
|
|
|
|
|
|
|
|
|
|
while (!oai_exit) {
|
|
|
|
|
phy_scope_nrUE(form_nrue[0],
|
|
|
|
|
phy_scope_nrUE(form_nrue,
|
|
|
|
|
ue,
|
|
|
|
|
0,0);
|
|
|
|
|
usleep(99*1000);
|
|
|
|
@@ -857,10 +764,7 @@ static void *nrUEscopeThread(void *arg) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nrUEinitScope(PHY_VARS_NR_UE *ue) {
|
|
|
|
|
int fl_argc=1;
|
|
|
|
|
char *name="5G-UE-scope";
|
|
|
|
|
fl_initialize (&fl_argc, &name, NULL, 0, 0);
|
|
|
|
|
form_nrue[0] = create_phy_scope_nrue(0);
|
|
|
|
|
pthread_t forms_thread;
|
|
|
|
|
threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -893,7 +797,7 @@ static void reset_stats_gNB(FL_OBJECT *button,
|
|
|
|
|
|
|
|
|
|
static FD_stats_form *create_form_stats_form(int ID) {
|
|
|
|
|
FL_OBJECT *obj;
|
|
|
|
|
FD_stats_form *fdui = fl_malloc( sizeof *fdui );
|
|
|
|
|
FD_stats_form *fdui = calloc(( sizeof *fdui ),1);
|
|
|
|
|
fdui->vdata = fdui->cdata = NULL;
|
|
|
|
|
fdui->ldata = 0;
|
|
|
|
|
fdui->stats_form = fl_bgn_form( FL_NO_BOX, 1115, 900 );
|
|
|
|
|