Commit 427b9794 authored by laurent's avatar laurent

coarse scope cleanup

parent d098d93d
......@@ -954,7 +954,9 @@ if(!IS_SOFTMODEM_NOS1)
scopeParms_t p;
p.argc=&argc;
p.argv=argv;
startScope(&p);
p.gNB=RC.gNB[0];
p.ru=RC.ru[0];
gNBinitScope(&p);
}
if (nfapi_mode != 1 && nfapi_mode != 2) {
......
......@@ -76,36 +76,11 @@ unsigned short config_frames[4] = {2,9,11,13};
#include <openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h>
#include <openair1/SCHED_NR_UE/fapi_nr_ue_l1.h>
#include <forms.h>
/* Callbacks, globals and object handlers */
extern void reset_stats( FL_OBJECT *, long );
//extern void initTpool(char *params, tpool_t *pool, bool performanceMeas);
/* Forms and Objects */
typedef struct {
FL_FORM *stats_form;
void *vdata;
char *cdata;
long ldata;
FL_OBJECT *stats_text;
FL_OBJECT *stats_button;
} FD_stats_form;
extern FD_stats_form *create_form_stats_form( void );
#include "PHY/TOOLS/nr_phy_scope.h"
//#include "stats.h"
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
#include "PHY/TOOLS/nr_phy_scope.h"
// at eNB 0, an UL scope for every UE
FD_phy_scope_nrue *form_nrue[NUMBER_OF_UE_MAX];
//FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
char title[255];
static pthread_t forms_thread; //xforms
#include <executables/nr-uesoftmodem.h>
#include "executables/softmodem-common.h"
......@@ -304,35 +279,6 @@ void reset_stats(FL_OBJECT *button, long arg) {
}*/
}
static void *scope_thread(void *arg) {
sleep(5);
while (!oai_exit) {
phy_scope_nrUE(form_nrue[0],
PHY_vars_UE_g[0][0],
0,0,1);
usleep(100*1000);
}
pthread_exit((void *)arg);
}
void init_scope(void) {
int fl_argc=1;
if (do_forms==1) {
char *name="5G-UE-scope";
fl_initialize (&fl_argc, &name, NULL, 0, 0);
int UE_id = 0;
form_nrue[UE_id] = create_phy_scope_nrue();
sprintf (title, "NR DL SCOPE UE");
fl_show_form (form_nrue[UE_id]->phy_scope_nrue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
threadCreate(&forms_thread, scope_thread, NULL, "scope", -1, OAI_PRIORITY_RT_LOW);
}
}
void *l2l1_task(void *arg) {
MessageDef *message_p = NULL;
int result;
......@@ -782,7 +728,8 @@ int main( int argc, char **argv ) {
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
configure_linux();
mlockall(MCL_CURRENT | MCL_FUTURE);
init_scope();
if (do_forms)
nrUEinitScope(PHY_vars_UE_g[0][0]);
number_of_cards = 1;
for(int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
......
......@@ -821,15 +821,14 @@ int rx_pdsch(PHY_VARS_UE *ue,
pllr_symbol_cw0 += llr_offset_symbol;
pllr_symbol_cw1 += llr_offset_symbol;
/*
LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n",
LOG_D(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p energy: %d\n",
frame, subframe,symbol,
nb_rb,dlsch0_harq->Qm,
pdsch_vars[eNB_id]->llr_length[symbol],
pdsch_vars[eNB_id]->llr_offset[symbol],
(int16_t*)pdsch_vars[eNB_id]->llr[0],
pllr_symbol_cw0);
*/
pllr_symbol_cw0,
signal_energy(pdsch_vars[eNB_id]->rxdataF_comp0[0], 7*2*frame_parms->N_RB_DL*12));
switch (dlsch0_harq->Qm) {
case 2 :
if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
......
......@@ -27,6 +27,7 @@
#include "PHY/impl_defs_nr.h"
#include "PHY/sse_intrin.h"
#include <common/utils/LOG/log.h>
__m64 byte2m64_re[256];
__m64 byte2m64_im[256];
......@@ -42,7 +43,7 @@ void init_byte2m64(void) {
byte2m64_im[s] = _mm_insert_pi16(byte2m64_im[s],(1-2*((s>>5)&1)),2);
byte2m64_re[s] = _mm_insert_pi16(byte2m64_re[s],(1-2*((s>>6)&1)),3);
byte2m64_im[s] = _mm_insert_pi16(byte2m64_im[s],(1-2*((s>>7)&1)),3);
printf("init_scrambling_luts: s %x (%d) ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
LOG_T(PHY,"init_scrambling_luts: s %x (%d) ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
((uint16_t*)&s)[0],
(1-2*(s&1)),
((int16_t*)&byte2m64_re[s])[0],((int16_t*)&byte2m64_im[s])[0],
......
......@@ -1145,6 +1145,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
//-------------------- LLRs computation --------------------
//----------------------------------------------------------
start_meas(&gNB->ulsch_llr_stats);
AssertFatal(gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order+nb_re_pusch*rel15_ul->qam_mod_order < (8*((3*8*6144)+12)) , "Mysterious llr buffer size check");
nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB],
gNB->pusch_vars[UE_id]->ul_ch_mag0,
gNB->pusch_vars[UE_id]->ul_ch_magb0,
......
......@@ -9,6 +9,8 @@
*
* http://www.openairinterface.org/?page_id=698
*
* Author and copyright: Laurent Thomas, open-cells.com
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
......@@ -26,6 +28,7 @@
#include "executables/nr-softmodem-common.h"
#define TPUT_WINDOW_LENGTH 100
#define localBuff(NaMe,SiZe) float NaMe[SiZe]; memset(NaMe,0,sizeof(NaMe));
int otg_enabled;
FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
......@@ -36,10 +39,40 @@ float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
float tput_ue_max[NUMBER_OF_UE_MAX] = {0};
typedef struct {
int16_t r;
int16_t i;
} scopeSample_t;
#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
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);
} OAIgraph_t;
/* Forms and Objects */
typedef struct {
FL_FORM *phy_scope;
OAIgraph_t graph[20];
FL_OBJECT *button_0;
} FD_phy_scope_t;
static void ia_receiver_on_off( FL_OBJECT *button, long arg)
{
typedef struct {
FL_FORM *stats_form;
void *vdata;
char *cdata;
long ldata;
FL_OBJECT *stats_text;
FL_OBJECT *stats_button;
} FD_stats_form;
static void drawsymbol(FL_OBJECT *obj, int id,
FL_POINT *p, int n, int w, int h) {
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;
......@@ -51,9 +84,7 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg)
}
}
static void dl_traffic_on_off( FL_OBJECT *button, long arg)
{
static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
if (fl_get_button(button)) {
fl_set_object_label(button, "DL Traffic ON");
otg_enabled = 1;
......@@ -65,764 +96,639 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg)
}
}
FD_phy_scope_gnb *create_phy_scope_gnb( void )
{
FL_OBJECT *obj;
FD_phy_scope_gnb *fdui = fl_malloc( sizeof *fdui );
// Define form
fdui->phy_scope_gnb = 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 );
// Received signal
fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
fl_set_xyplot_ybounds(fdui->rxsig_t,10,70);
// Time-domain channel response
fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "SRS Frequency Response (samples, abs)" );
fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
// Frequency-domain channel response
fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
fl_set_xyplot_ybounds( fdui->chest_f,30,70);
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);
return graph;
}
// LLR of PUSCH
fdui->pusch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)" );
fl_set_object_boxtype( fdui->pusch_llr, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pusch_llr, FL_BLACK, FL_YELLOW );
fl_set_object_lcolor( fdui->pusch_llr, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pusch_llr,2);
static OAIgraph_t gNBcommonGraph( void (*funct) (FL_OBJECT *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;
return graph;
}
// I/Q PUSCH comp
fdui->pusch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 200, "PUSCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pusch_comp, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pusch_comp, FL_BLACK, FL_YELLOW );
fl_set_object_lcolor( fdui->pusch_comp, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pusch_comp,2);
fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
static OAIgraph_t nrUEcommonGraph( void (*funct) (FL_OBJECT *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;
return graph;
}
// I/Q PUCCH comp (format 1)
fdui->pucch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 480, 240, 100, "PUCCH1 Energy (SR)" );
fl_set_object_boxtype( fdui->pucch_comp1, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pucch_comp1, FL_BLACK, FL_YELLOW );
fl_set_object_lcolor( fdui->pucch_comp1, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pucch_comp1,2);
// fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
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;
// I/Q PUCCH comp (fromat 1a/b)
fdui->pucch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 600, 240, 100, "PUCCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pucch_comp, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pucch_comp, FL_BLACK, FL_YELLOW );
fl_set_object_lcolor( fdui->pucch_comp, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pucch_comp,2);
// fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
if (form==NULL)
form=remeberForm;
else
remeberForm=form;
// Throughput on PUSCH
fdui->pusch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 480, 500, 100, "PUSCH Throughput [frame]/[kbit/s]" );
fl_set_object_boxtype( fdui->pusch_tput, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pusch_tput, FL_BLACK, FL_WHITE );
fl_set_object_lcolor( fdui->pusch_tput, FL_WHITE ); // Label color
if (form==NULL) return;
// Generic eNB Button
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 );
int i=0;
fl_end_form( );
fdui->phy_scope_gnb->fdui = fdui;
while (form->graph[i].graph) {
form->graph[i].gNBfunct(form->graph[i].graph, phy_vars_gnb, phy_vars_ru, UE_id);
i++;
}
return fdui;
fl_check_forms();
}
void phy_scope_gNB(FD_phy_scope_gnb *form,
PHY_VARS_gNB *phy_vars_gnb,
RU_t *phy_vars_ru,
int UE_id)
{
int i, arx; //int i,i2,arx,atx,ind,k;
NR_DL_FRAME_PARMS *frame_parms = &phy_vars_gnb->frame_parms;
//int nsymb_ce = 12*frame_parms->N_RB_UL*frame_parms->symbols_per_tti;
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
//uint8_t nb_antennas_tx = 1; // frame_parms->nb_antennas_tx; // in LTE Rel. 8 and 9 only a single transmit antenna is assumed at the UE
int16_t **rxsig_t, **rxsig_f;
// int16_t **chest_t=NULL;
// int16_t **chest_f=NULL;
// int16_t *pusch_llr=NULL;
// int32_t *pusch_comp=NULL;
// int32_t *pucch1_comp=NULL;
// int32_t *pucch1_thres=NULL;
// int32_t *pucch1ab_comp=NULL;
// float Re,Im,ymax;
float *llr, *bit;
// float I[nsymb_ce*2], Q[nsymb_ce*2];
// float I_pucch[10240],Q_pucch[10240],A_pucch[10240],B_pucch[10240],C_pucch[10240];
float *rxsig_t_dB[nb_antennas_rx];
float *rxsig_f_dB[nb_antennas_rx];
float time[frame_parms->samples_per_frame];
// float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
// uint32_t total_dlsch_bitrate = phy_vars_gnb->total_dlsch_bitrate;
int coded_bits_per_codeword = 0;
// uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2
int Qm = 2;
/*
if (!RC.nrmac[0]->UE_info.active[UE_id])
static void timeSignal (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
// Received signal in time domain of receive antenna 0
if (!phy_vars_ru->common.rxdata)
return;
// choose max MCS to compute coded_bits_per_codeword
if (phy_vars_gnb->ulsch[UE_id][0]!=NULL) {
for (harq_pid=0; harq_pid<3; harq_pid++) {
//Qm = cmax(phy_vars_gnb->ulsch[UE_id][0]->harq_processes->Qm,Qm);
}
}
*/
coded_bits_per_codeword = frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti;
for (arx=0; arx<nb_antennas_rx; arx++) {
rxsig_t_dB[arx] = (float*) calloc(frame_parms->samples_per_frame,sizeof(float));
rxsig_f_dB[arx] = (float*) calloc(frame_parms->samples_per_slot_wCP,sizeof(float));
}
llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
bit = malloc(coded_bits_per_codeword*sizeof(float));
rxsig_t = (int16_t**) phy_vars_ru->common.rxdata;
rxsig_f = (int16_t**) phy_vars_ru->common.rxdataF;
//chest_t = (int16_t**) phy_vars_gnb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id];
/* chest_t = (int16_t**) phy_vars_gnb->srs_vars[UE_id].srs_ch_estimates;
chest_f = (int16_t**) phy_vars_gnb->pusch_vars[UE_id]->drs_ch_estimates;
pusch_llr = (int16_t*) phy_vars_gnb->pusch_vars[UE_id]->llr;
pusch_comp = (int32_t*) phy_vars_gnb->pusch_vars[UE_id]->rxdataF_comp;
pucch1_comp = (int32_t*) phy_vars_gnb->pucch1_stats[UE_id];
pucch1_thres = (int32_t*) phy_vars_gnb->pucch1_stats_thres[UE_id];
pucch1ab_comp = (int32_t*) phy_vars_gnb->pucch1ab_stats[UE_id];
*/
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];
// Received signal in time domain of receive antenna 0
if (rxsig_t != NULL) {
if (rxsig_t[0] != NULL) {
for (i=0; i<frame_parms->samples_per_frame; i++) {
rxsig_t_dB[0][i] = 10*log10(1.0+(float) ((rxsig_t[0][2*i])*(rxsig_t[0][2*i])+(rxsig_t[0][2*i+1])*(rxsig_t[0][2*i+1])));
time[i] = (float) i;
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]));
}
fl_set_xyplot_data(form->rxsig_t,time,rxsig_t_dB[0],frame_parms->samples_per_frame,"","","");
}
for (arx=1; arx<nb_antennas_rx; arx++) {
if (rxsig_t[arx] != NULL) {
for (i=0; i<frame_parms->samples_per_frame; i++) {
rxsig_t_dB[arx][i] = 10*log10(1.0+(float) ((rxsig_t[arx][2*i])*(rxsig_t[arx][2*i])+(rxsig_t[arx][2*i+1])*(rxsig_t[arx][2*i+1])));
}
fl_add_xyplot_overlay(form->rxsig_t,arx,time,rxsig_t_dB[arx],frame_parms->samples_per_frame,rx_antenna_colors[arx]);
}
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]);
}
}
}
/*
// Channel Impulse Response
if (chest_t != NULL) {
ymax = 0;
if (chest_t[0] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size); i++) {
//i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size;
i2=i;
//time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1));
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;
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[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1]));
chest_t_abs[i] = 10*log10(1.0 + SquaredNorm(chest_t[0][i]));
if (chest_t_abs[0][i] > ymax)
ymax = chest_t_abs[0][i];
if (chest_t_abs[i] > ymax)
ymax = chest_t_abs[i];
}
fl_set_xyplot_data(form->chest_t,time2,chest_t_abs[0],(frame_parms->ofdm_symbol_size),"","","");
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);
}
}
}
for (arx=1; arx<nb_antennas_rx; arx++) {
if (chest_t[arx] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
chest_t_abs[arx][i] = 10*log10((float) (1+chest_t[arx][2*i]*chest_t[arx][2*i]+chest_t[arx][2*i+1]*chest_t[arx][2*i+1]));
// Avoid flickering effect
// fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
fl_set_xyplot_ybounds(graph,0,ymax);
}
if (chest_t_abs[arx][i] > ymax)
ymax = chest_t_abs[arx][i];
}
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;
fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
}
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;
}
// Avoid flickering effect
// fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
fl_set_xyplot_ybounds(form->chest_t,0,ymax);
fl_set_xyplot_data(graph,time,rxsig_f_dB,frame_parms->samples_per_slot_wCP,"","","");
}
*/
// Channel Frequency Response
if (rxsig_f != NULL) {
if (rxsig_f[0] != NULL) {
for (i=0; i<frame_parms->samples_per_slot_wCP; i++) {
rxsig_f_dB[0][i] = 10*log10(1.0+(float) ((rxsig_f[0][2*i])*(rxsig_f[0][2*i])+(rxsig_f[0][2*i+1])*(rxsig_f[0][2*i+1])));
time[i] = (float) i;
}
fl_set_xyplot_data(form->chest_t,time,rxsig_f_dB[0],frame_parms->samples_per_slot_wCP,"","","");
}
}
/*
for (arx=0; arx<nb_antennas_rx; arx++) {
if (chest_f[(atx<<1)+arx] != NULL) {
for (k=0; k<nsymb_ce; k++) {
freq[ind] = (float)ind;
Re = (float)(chest_f[(atx<<1)+arx][(2*k)]);
Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]);
chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im));
ind++;
}
}
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,"","","");
*/
}
for (arx=1; arx<nb_antennas_rx; arx++) {
fl_add_xyplot_overlay(form->chest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
}
// other tx antennas
if (nb_antennas_tx > 1) {
if (nb_antennas_rx > 1) {
for (atx=1; atx<nb_antennas_tx; atx++) {
for (arx=0; arx<nb_antennas_rx; arx++) {
fl_add_xyplot_overlay(form->chest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
}
}
} else { // 1 rx antenna
atx=1;
arx=0;
fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
}
}
}
static void puschLLR (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
// PUSCH LLRs
if (pusch_llr != NULL) {
for (i=0; i<coded_bits_per_codeword; i++) {
llr[i] = (float) pusch_llr[i];
bit[i] = (float) i;
}
if (!phy_vars_gnb->pusch_vars[UE_id]->llr)
return;
fl_set_xyplot_data(form->pusch_llr,bit,llr,coded_bits_per_codeword,"","","");
//NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
//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;
}
fl_set_xyplot_data(graph,bit,llr,coded_bits_per_codeword,"","","");
}
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 (pusch_comp!=NULL) {
ind=0;
for (k=0; k<frame_parms->symbols_per_tti; k++) {
for (i=0; i<12*frame_parms->N_RB_UL; i++) {
I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i];
Q[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1];
ind++;
}
}
if (!phy_vars_gnb->pusch_vars[UE_id]->rxdataF_comp)
return;
fl_set_xyplot_data(form->pusch_comp,I,Q,ind,"","","");
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;
}
fl_set_xyplot_data(graph,I,Q,sz,"","","");
// PUSCH I/Q of MF Output
if (pucch1ab_comp!=NULL) {
for (ind=0; ind<10240; ind++) {
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];
for (int ind=0; ind<10240; ind++) {
I_pucch[ind] = (float)pucch1ab_comp[2*(ind)];
Q_pucch[ind] = (float)pucch1ab_comp[2*(ind)+1];
A_pucch[ind] = pucch1_comp?(10*log10(pucch1_comp[ind])):0;
B_pucch[ind] = ind;
int32_t *pucch1_thres = (int32_t *) NULL; // phy_vars_gnb->pucch1_stats_thres[UE_id];
C_pucch[ind] = pucch1_thres?(float)pucch1_thres[ind]:0;
}
fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","","");
fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","","");
fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED);
fl_set_xyplot_ybounds(form->pucch_comp,-5000,5000);
fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000);
fl_set_xyplot_ybounds(form->pucch_comp1,0,80);
fl_set_xyplot_data(graph,I_pucch,Q_pucch,10240,"","","");
fl_set_xyplot_data(graph,B_pucch,A_pucch,1024,"","","");
fl_add_xyplot_overlay(graph,1,B_pucch,C_pucch,1024,FL_RED);
fl_set_xyplot_ybounds(graph,-5000,5000);
fl_set_xyplot_xbounds(graph,-5000,5000);
fl_set_xyplot_ybounds(graph,0,80);
}
}
static void pucchEnergy (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
}
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) {
// 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;
// tput_enb[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
fl_set_xyplot_data(form->pusch_tput,tput_time_enb[UE_id],tput_enb[UE_id],TPUT_WINDOW_LENGTH,"","","");
// tput_enb[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
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);
*/
fl_check_forms();
free(llr);
free(bit);
}
FD_phy_scope_nrue *create_phy_scope_nrue( void )
{
static FD_phy_scope_t *create_phy_scope_gnb(int UE_id ) {
FL_OBJECT *obj;
FD_phy_scope_nrue *fdui = fl_malloc( sizeof *fdui );
FD_phy_scope_t *fdui = fl_malloc( sizeof *fdui );
// Define form
fdui->phy_scope_nrue = fl_bgn_form( FL_NO_BOX, 800, 900 );
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, 900, "" );
obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
fl_set_object_color( obj, FL_BLACK, FL_BLACK );
// Received signal
fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
fl_set_xyplot_ybounds(fdui->rxsig_t,10,70);
fdui->graph[0] = gNBcommonGraph( timeSignal, FL_IMPULSE_XYPLOT, 20, 20, 370, 100,
"Received Signal (Time-Domain, dB)", FL_RED );
// Time-domain channel response
fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" );
fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
fdui->graph[1] = gNBcommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, 20, 370, 100,
"SRS Frequency Response (samples, abs)", FL_RED );
// Frequency-domain channel response
fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
fl_set_xyplot_ybounds( fdui->chest_f,30,70);
// LLR of PBCH
fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" );
fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pbch_llr, FL_BLACK, FL_GREEN );
fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pbch_llr,2);
fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR);
//fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920);
// I/Q PBCH comp
fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN );
fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pbch_comp,2);
// fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100);
// fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100);
// LLR of PDCCH
fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" );
fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN );
fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pdcch_llr,2);
// I/Q PDCCH comp
fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pdcch_comp, FL_BLACK, FL_CYAN );
fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pdcch_comp,2);
fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR);
// LLR of PDSCH
fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW );
fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pdsch_llr,2);
fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR);
// I/Q PDSCH comp
fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500, 240, 200, "PDSCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW );
fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pdsch_comp,2);
// Throughput on PDSCH
fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" );
fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE );
fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color
fdui->graph[2] = gNBcommonGraph( frequencyResponse, FL_IMPULSE_XYPLOT, 20, 140, 760, 100,
"Channel Frequency Response (RE, dB)", FL_RED );
// LLR of PUSCH
fdui->graph[3] = gNBcommonGraph( puschLLR, FL_POINTS_XYPLOT, 20, 260, 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,
"PUSCH I/Q of MF Output", FL_YELLOW );
// I/Q PUCCH comp (format 1)
fdui->graph[5] = gNBcommonGraph( pucchEnergy, FL_POINTS_XYPLOT, 540, 480, 240, 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,
"PUCCH I/Q of MF Output", FL_YELLOW );
// Throughput on PUSCH
fdui->graph[7] = gNBcommonGraph( puschThroughtput, FL_NORMAL_XYPLOT, 20, 480, 500, 100,
"PUSCH Throughput [frame]/[kbit/s]", FL_WHITE );
fdui->graph[8].graph=NULL;
// Generic UE Button
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;
fl_set_button(fdui->button_0,0);
fl_set_object_label(fdui->button_0, "IA Receiver OFF");
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);
// 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_nrue->fdui = fdui;
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);
return fdui;
}
void phy_scope_nrUE(FD_phy_scope_nrue *form,
PHY_VARS_NR_UE *phy_vars_ue,
int eNB_id,
int UE_id,
uint8_t subframe)
{
int i,arx,atx,ind,k;
NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
//int nsymb_ce = frame_parms->ofdm_symbol_size;//*frame_parms->symbols_per_tti;
int samples_per_frame = frame_parms->samples_per_frame;
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_gNB;
int16_t **rxsig_t;
float **rxsig_t_dB;
float *time;
float *corr;
int16_t **chest_t;
int16_t **chest_f;
int16_t *pdsch_llr;
int16_t *pdsch_comp;
//int16_t *pdsch_mag;
int8_t *pdcch_llr;
int16_t *pdcch_comp;
int16_t *pbch_llr;
int16_t *pbch_comp;
float llr_pbch[1920], bit_pbch[1920];
float *llr, *bit;
float *llr_pdcch, *bit_pdcch;
float *I, *Q;
int num_pdcch_symbols=2;
int num_re = 4500;
int Qm = 2;
int coded_bits_per_codeword = num_re*Qm;
int symbol, first_symbol=2,nb_re;
int nb_rb_pdsch=50,nb_symb_sch=9;
float ymax=1;
float **chest_t_abs;
float Re,Im;
float *chest_f_abs;
float *freq;
static int overlay = 0;
/*
int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
int mcs = 0;
unsigned char harq_pid = 0;
*/
/*
if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
static FD_phy_scope_t *form_gnb[NUMBER_OF_UE_MAX]= {0};
static unsigned char scope_enb_num_ue = 1;
if (harq_pid>=8)
return;
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;
pthread_attr_getstacksize(&atr, &stksize);
pthread_attr_setstacksize(&atr,32*1024*1024 );
sleep(3); // no clean interthread barriers
mcs = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs;
while (!oai_exit) {
int ue_cnt=0;
// Button 0
if(!phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
// we are in TM5
fl_show_object(form->button_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++;
}
}
}
if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) {
num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols;
}
// coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
coded_bits_per_codeword = get_G(frame_parms,
phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
get_Qm(mcs),
phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
num_pdcch_symbols,
frame,
subframe,
beamforming_mode);
} else {
coded_bits_per_codeword = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
}
*/
I = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
Q = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*));
for (arx=0; arx<nb_antennas_rx; arx++) {
chest_t_abs[arx] = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
usleep(99*1000);
}
chest_f_abs = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
freq = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
// printf("%s",stats_buffer);
/*#ifdef ENABLE_XFORMS_WRITE_STATS
llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
bit = malloc(coded_bits_per_codeword*sizeof(float));
llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
if (eNB_stats) {
rewind (gNB_stats);
fwrite (stats_buffer, 1, len, gNB_stats);
fclose (gNB_stats);
}
rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
rxsig_t_dB = calloc(nb_antennas_rx,sizeof(float*));
for (arx=0; arx<nb_antennas_rx; arx++) {
rxsig_t_dB[arx] = (float*) calloc(samples_per_frame,sizeof(float));
}
time = calloc(samples_per_frame,sizeof(float));
corr = calloc(samples_per_frame,sizeof(float));
#endif
pthread_exit((void *)arg);
}*/
return NULL;
}
chest_t = (int16_t**) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time;
chest_f = (int16_t**) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
void gNBinitScope(scopeParms_t *p) {
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
fl_initialize (p->argc, p->argv, NULL, 0, 0);
pbch_llr = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[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
pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
// pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0
pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
//pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
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) {
// Received signal in time domain of receive antenna 0
if (rxsig_t != NULL) {
if (rxsig_t[0] != NULL) {
for (i=0; i<samples_per_frame; i++) {
rxsig_t_dB[0][i] = 10*log10(1.0+(float) ((rxsig_t[0][2*i])*(rxsig_t[0][2*i])+(rxsig_t[0][2*i+1])*(rxsig_t[0][2*i+1])));
time[i] = (float) i;
}
if (! phy_vars_ue->common_vars.rxdata)
return;
fl_set_xyplot_data(form->rxsig_t,time,rxsig_t_dB[0],samples_per_frame,"","","");
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;
}
/*
for (arx=1; arx<nb_antennas_rx; arx++) {
if (rxsig_t[arx] != NULL) {
for (i=0; i<FRAME_LENGTH_COMPLEX_SAMPLES; i++) {
rxsig_t_dB[arx][i] = 10*log10(1.0+(float) ((rxsig_t[arx][2*i])*(rxsig_t[arx][2*i])+(rxsig_t[arx][2*i+1])*(rxsig_t[arx][2*i+1])));
}
fl_set_xyplot_data(graph,time,rxsig_t_dB,samples_per_frame,"","","");
}
fl_add_xyplot_overlay(form->rxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
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) {
for (ind=0;ind<3;ind++) {
//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 (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;
}
*/
}
}
else {
if (overlay) { //there was a previous overlay
fl_clear_xyplot(form->chest_t);
overlay = 0;
// if the UE is not synchronized, we can make only the time*power graph
}
}
static void ueChannelResponse (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// Channel Impulse Response
if (chest_t != NULL) {
ymax = 0;
if (!phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time)
return;
if (chest_t[0] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
chest_t_abs[0][i] = (float) (chest_t[0][2*i]*chest_t[0][2*i]+chest_t[0][2*i+1]*chest_t[0][2*i+1]);
time[i] = (float) i;
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];
}
if (chest_t_abs[0][i] > ymax)
ymax = chest_t_abs[0][i];
}
fl_set_xyplot_data(graph,time,chest_t_abs,(frame_parms->ofdm_symbol_size>>3),"","","");
}
fl_set_xyplot_data(form->chest_t,time,chest_t_abs[0],(frame_parms->ofdm_symbol_size>>3),"","","");
}
/*
for (arx=1; arx<nb_antennas_rx; arx++) {
if (chest_t[arx] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
chest_t_abs[arx][i] = (float) (chest_t[arx][4*i]*chest_t[arx][4*i]+chest_t[arx][4*i+1]*chest_t[arx][4*i+1]);
if (chest_t_abs[arx][i] > ymax)
ymax = chest_t_abs[arx][i];
}
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]);
fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
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(form->chest_t,0,(double) ymax);
}
}
// Channel Frequency Response (includes 5 complex sample for filter)
if (chest_f != NULL) {
ind = 0;
for (atx=0; atx<nb_antennas_tx; atx++) {
for (arx=0; arx<nb_antennas_rx; arx++) {
if (chest_f[(atx<<1)+arx] != NULL) {
for (k=0; k<frame_parms->ofdm_symbol_size; k++) {
freq[ind] = (float)ind;
Re = (float)(chest_f[(atx<<1)+arx][6144+(2*k)]);
Im = (float)(chest_f[(atx<<1)+arx][6144+(2*k)+1]);
chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im));
ind++;
}
}
}
}
// Avoid flickering effect
// fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); // Does not always work...
fl_set_xyplot_ybounds(graph,0,(double) ymax);
}
// 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,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(form->chest_f,freq,chest_f_abs,frame_parms->ofdm_symbol_size,"","","");
/*
for (arx=1; arx<nb_antennas_rx; arx++) {
fl_add_xyplot_overlay(form->chest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
}
static void uePbchFrequencyResp (FL_OBJECT *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;
// other tx antennas
if (nb_antennas_tx > 1) {
if (nb_antennas_rx > 1) {
for (atx=1; atx<nb_antennas_tx; atx++) {
for (arx=0; arx<nb_antennas_rx; arx++) {
fl_add_xyplot_overlay(form->chest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
}
NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_gNB;
scopeSample_t **chest_f = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
int ind = 0;
float chest_f_abs[frame_parms->ofdm_symbol_size];
float freq[frame_parms->ofdm_symbol_size];
for (int atx=0; atx<nb_antennas_tx; atx++) {
for (int arx=0; arx<nb_antennas_rx; arx++) {
if (chest_f[(atx<<1)+arx] != NULL) {
for (int k=0; k<frame_parms->ofdm_symbol_size; k++) {
freq[ind] = (float)ind;
chest_f_abs[ind] = (short)10*log10(1.0+SquaredNorm(chest_f[(atx<<1)+arx][6144+k]));
ind++;
}
} else { // 1 rx antenna
atx=1;
arx=0;
fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],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,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,"","","");
}
static void uePbchLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PBCH LLRs
if (pbch_llr != NULL) {
for (i=0; i<864; i++) {
llr_pbch[i] = (float) pbch_llr[i];
bit_pbch[i] = (float) i;
}
if ( !phy_vars_ue->pbch_vars[eNB_id]->llr)
return;
int16_t *pbch_llr = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->llr;
float llr_pbch[864], bit_pbch[864];
fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,864,"","","");
for (int i=0; i<864; i++) {
llr_pbch[i] = (float) pbch_llr[i];
bit_pbch[i] = (float) i;
}
first_symbol=1;
fl_set_xyplot_data(graph,bit_pbch,llr_pbch,864,"","","");
}
static void uePbchIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PBCH I/Q of MF Output
if (pbch_comp!=NULL) {
for (symbol=first_symbol; symbol<(first_symbol+3); symbol++) {
if (symbol == 2 || symbol == 6)
nb_re = 72;
else
nb_re = 180;
for (i=0; i<nb_re; i++) {
I[i] = pbch_comp[2*symbol*20*12+2*i];
Q[i] = pbch_comp[2*symbol*20*12+2*i+1];
}
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];
localBuff(I,180*3);
localBuff(Q,180*3);
int first_symbol=1;
int base=0;
for (int symbol=first_symbol; symbol<(first_symbol+3); symbol++) {
int nb_re;
if (symbol == 2 || symbol == 6)
nb_re = 72;
else
nb_re = 180;
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];
}
fl_set_xyplot_data(form->pbch_comp,I,Q,432,"","","");
base+=nb_re;
}
fl_set_xyplot_data(graph,I,Q,base,"","","");
}
static void uePcchLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PDCCH LLRs
if (pdcch_llr != NULL) {
for (i=0; i<100; i++) { //12*frame_parms->N_RB_DL*2*num_pdcch_symbols
llr_pdcch[i] = (float) pdcch_llr[2*24*9 +i];
bit_pdcch[i] = (float) i;
}
if (!phy_vars_ue->pdcch_vars[0][eNB_id]->llr)
return;
fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
uint8_t nb_antennas_tx = frame_parms->nb_antennas_tx;
scopeSample_t **chest_f = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
int ind = 0;
float chest_f_abs[frame_parms->ofdm_symbol_size];
float freq[frame_parms->ofdm_symbol_size];
for (int atx=0; atx<nb_antennas_tx; atx++) {
for (int arx=0; arx<nb_antennas_rx; arx++) {
if (chest_f[(atx<<1)+arx] != NULL) {
for (int k=0; k<frame_parms->ofdm_symbol_size; k++) {
freq[ind] = (float)ind;
chest_f_abs[ind] = (short)10*log10(1.0+SquaredNorm(chest_f[(atx<<1)+arx][6144+k]));
ind++;
}
}
}
}
// 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,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,"","","");
}
static void uePcchIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PDCCH I/Q of MF Output
if (pdcch_comp!=NULL) {
for (i=0; i<100; i++) {
I[i] = pdcch_comp[2*50*12+2*i];
Q[i] = pdcch_comp[2*50*12+2*i+1];
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
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];
for (int i=0; i< nb; i++) {
I[base+i] = pdcch_comp[i*2];
Q[base+i] = pdcch_comp[i*2+1];
}
fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
base+=nb;
}
fl_set_xyplot_data(graph,I,Q,base,"","","");
}
static void uePdschLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PDSCH LLRs
if (pdsch_llr != NULL) {
for (i=0; i<coded_bits_per_codeword; i++) {
llr[i] = (float) pdsch_llr[i];
bit[i] = (float) i;
if (!phy_vars_ue->pdsch_vars[0][eNB_id]->llr[0])
return;
int num_re = 4500;
int Qm = 2;
int coded_bits_per_codeword = num_re*Qm;
localBuff(llr,coded_bits_per_codeword*RX_NB_TH_MAX);
localBuff(bit,coded_bits_per_codeword*RX_NB_TH_MAX);
int base=0;
for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
int16_t *pdsch_llr = (int16_t *) phy_vars_ue->pdsch_vars[thr][eNB_id]->llr[0]; // stream 0
for (int i=0; i<coded_bits_per_codeword; i++) {
llr[base+i] = (float) pdsch_llr[i];
bit[base+i] = (float) base+i;
}
//fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword);
fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","","");
base+=coded_bits_per_codeword;
}
first_symbol = 2;
ind = 0;
//fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword);
fl_set_xyplot_data(graph,bit,llr,base,"","","");
}
static void uePdschIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PDSCH I/Q of MF Output
if (pdsch_comp!=NULL) {
for (symbol=0;symbol<nb_symb_sch;symbol++) {
for (i=0; i<nb_rb_pdsch*12; i++) {
I[ind] = pdsch_comp[2*((first_symbol+symbol)*frame_parms->N_RB_DL*12+i) ];
Q[ind] = pdsch_comp[2*((first_symbol+symbol)*frame_parms->N_RB_DL*12+i)+1];
ind++;
}
if (!phy_vars_ue->pdsch_vars[0][eNB_id]->rxdataF_comp0[0])
return;
NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
int sz=7*2*frame_parms->N_RB_DL*12; // size of the malloced buffer
localBuff(I,sz*RX_NB_TH_MAX);
localBuff(Q,sz*RX_NB_TH_MAX);
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];
for (int s=0; s<sz; s++) {
I[s+base] += pdsch_comp[2*s];
Q[s+base] += pdsch_comp[2*s+1];
}
fl_set_xyplot_data(form->pdsch_comp,I,Q,nb_symb_sch*nb_rb_pdsch*12,"","","");
base+=sz;
}
fl_set_xyplot_data(graph,I,Q,base,"","","");
/*
// PDSCH Throughput
......@@ -833,119 +739,155 @@ void phy_scope_nrUE(FD_phy_scope_nrue *form,
tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
if (tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] > tput_ue_max[UE_id]) {
tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
}
fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","","");
fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
*/
}
fl_check_forms();
static void uePdschThroughput (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
}
free(time);
free(corr);
for (arx=0; arx<nb_antennas_rx; arx++) {
free(rxsig_t_dB[arx]);
}
free(rxsig_t_dB);
free(I);
free(Q);
free(llr);
free(bit);
free(bit_pdcch);
free(llr_pdcch);
free(chest_t_abs);
/*
free(chest_f_abs);
for (arx=0; arx<nb_antennas_rx; arx++) {
free(chest_t_abs[arx]);
static FD_phy_scope_t *create_phy_scope_nrue( int ID ) {
FL_OBJECT *obj;
FD_phy_scope_t *fdui = fl_malloc( sizeof *fdui );
// 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 );
// Received signal
fdui->graph[0] = nrUEcommonGraph(ueTimeResponse,
FL_IMPULSE_XYPLOT, 20, 20, 370, 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 );
// Frequency-domain channel response
fdui->graph[2] = nrUEcommonGraph(uePbchFrequencyResp,
FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency data (RE, dB)", FL_RED );
// LLR of PBCH
fdui->graph[3] = nrUEcommonGraph(uePbchLLR,
FL_POINTS_XYPLOT, 20, 260, 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 );
// LLR of PDCCH
fdui->graph[5] = nrUEcommonGraph(uePcchLLR,
FL_POINTS_XYPLOT, 20, 380, 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 );
// LLR of PDSCH
fdui->graph[7] = nrUEcommonGraph(uePdschLLR,
FL_POINTS_XYPLOT, 20, 500, 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 );
// Throughput on PDSCH
fdui->graph[9] = nrUEcommonGraph(uePdschThroughput,
FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]", FL_WHITE );
fdui->graph[10].graph=NULL;
// Generic UE Button
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;
fl_set_button(fdui->button_0,0);
fl_set_object_label(fdui->button_0, "IA Receiver OFF");
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);
fl_end_form( );
fdui->phy_scope->fdui = fdui;
char buf[100];
sprintf(buf,"NR DL SCOPE UE %d", ID);
fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, buf);
return fdui;
}
void phy_scope_nrUE(FD_phy_scope_t *form,
PHY_VARS_NR_UE *phy_vars_ue,
int eNB_id,
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].nrUEfunct(form->graph[i].graph, phy_vars_ue, eNB_id, UE_id);
i++;
}
free(chest_t_abs);
*/
fl_check_forms();
}
static FD_phy_scope_t *form_nrue[NUMBER_OF_UE_MAX];
static pthread_t forms_thread;
typedef struct {
FL_FORM *stats_form;
void *vdata;
char *cdata;
long ldata;
FL_OBJECT *stats_text;
FL_OBJECT *stats_button;
} FD_stats_form;
static void *nrUEscopeThread(void *arg) {
PHY_VARS_NR_UE *ue=(PHY_VARS_NR_UE *)arg;
size_t stksize;
pthread_attr_t atr;
pthread_attr_getstacksize(&atr, &stksize);
pthread_attr_setstacksize(&atr,32*1024*1024 );
while (!oai_exit) {
phy_scope_nrUE(form_nrue[0],
ue,
0,0);
usleep(99*1000);
}
pthread_exit((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);
threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
}
// current status is that every UE has a DL scope for a SINGLE eNB (gnb_id=0)
// at eNB 0, an UL scope for every UE
FD_phy_scope_gnb *form_gnb[NUMBER_OF_UE_MAX];
// Kept to put back the functionality soon
#if 0
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
//char title[255];
unsigned char scope_enb_num_ue = 1;
//static pthread_t forms_thread; //xforms
void reset_stats_gNB(FL_OBJECT *button,
long arg)
{
static void reset_stats_gNB(FL_OBJECT *button,
long arg) {
int i,k;
//PHY_VARS_gNB *phy_vars_gNB = RC.gNB[0][0];
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
for (k=0; k<8; k++) { //harq_processes
/* for (j=0; j<phy_vars_gNB->dlsch[i][0]->Mlimit; j++) {
phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0;
phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0;
phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0;
}
phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0;
phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0;
phy_vars_gNB->UE_stats[i].ulsch_consecutive_errors=0;
phy_vars_gNB->UE_stats[i].dlsch_sliding_cnt=0;
phy_vars_gNB->UE_stats[i].dlsch_NAK_round0=0;
phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0;*/
}
}
}
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
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_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0;
phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0;
phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0;
}
phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0;
phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0;
phy_vars_gNB->UE_stats[i].ulsch_consecutive_errors=0;
phy_vars_gNB->UE_stats[i].dlsch_sliding_cnt=0;
phy_vars_gNB->UE_stats[i].dlsch_NAK_round0=0;
phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0;*/
}
sleep(1);
}
// 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;
}
FD_stats_form * create_form_stats_form( void ) {
static FD_stats_form *create_form_stats_form(int ID) {
FL_OBJECT *obj;
FD_stats_form *fdui = fl_malloc( sizeof *fdui );
fdui->vdata = fdui->cdata = NULL;
......@@ -963,24 +905,8 @@ FD_stats_form * create_form_stats_form( void ) {
fdui->stats_form->fdui = fdui;
return fdui;
}
#endif
void startScope(scopeParms_t * p) {
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
char title[255];
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();
sprintf (title, "LTE UL SCOPE eNB for UE %d",UE_id);
fl_show_form (form_gnb[UE_id]->phy_scope_gnb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
} // UE_id
pthread_t forms_thread;
threadCreate(&forms_thread, scope_thread_gNB, p, "scope", -1, OAI_PRIORITY_RT_LOW);
}
......@@ -35,55 +35,15 @@
//#include "PHY/impl_defs_top.h"
#include "PHY/defs_nr_UE.h"
/* Forms and Objects */
typedef struct {
FL_FORM * phy_scope_gnb;
FL_OBJECT * rxsig_t;
FL_OBJECT * chest_f;
FL_OBJECT * chest_t;
FL_OBJECT * pusch_comp;
FL_OBJECT * pucch_comp;
FL_OBJECT * pucch_comp1;
FL_OBJECT * pusch_llr;
FL_OBJECT * pusch_tput;
FL_OBJECT * button_0;
} FD_phy_scope_gnb;
typedef struct {
FL_FORM * phy_scope_nrue;
FL_OBJECT * rxsig_t;
FL_OBJECT * chest_f;
FL_OBJECT * chest_t;
FL_OBJECT * pbch_comp;
FL_OBJECT * pbch_llr;
FL_OBJECT * pdcch_comp;
FL_OBJECT * pdcch_llr;
FL_OBJECT * pdsch_comp;
FL_OBJECT * pdsch_llr;
FL_OBJECT * pdsch_comp1;
FL_OBJECT * pdsch_llr1;
FL_OBJECT * pdsch_tput;
FL_OBJECT * button_0;
} FD_phy_scope_nrue;
typedef struct {
int *argc;
char **argv;
RU_t* ru;
RU_t *ru;
PHY_VARS_gNB *gNB;
} scopeParms_t;
extern unsigned char scope_enb_num_ue;
FD_phy_scope_nrue * create_phy_scope_nrue( void );
void phy_scope_nrUE(FD_phy_scope_nrue *form,
PHY_VARS_NR_UE *phy_vars_ue,
int eNB_id,
int UE_id,
uint8_t subframe);
void startScope(scopeParms_t * p);
void gNBinitScope(scopeParms_t *p);
void nrUEinitScope(PHY_VARS_NR_UE *ue);
extern RAN_CONTEXT_t RC;
#endif
......@@ -476,14 +476,16 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
b->trashingPacket=true;
} else if ( b->lastReceivedTS < b->th.timestamp) {
int nbAnt= b->th.nbAnt;
if ( b->th.timestamp-b->lastReceivedTS < CirSize ) {
for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) {
for (int a=0; a < nbAnt; a++) {
b->circularBuf[(index*nbAnt+a)%CirSize].r = 0;
b->circularBuf[(index*nbAnt+a)%CirSize].i = 0;
}
}
} else {
memset(b->circularBuf, 0, sampleToByte(CirSize,1));
}
if (b->lastReceivedTS != 0 && b->th.timestamp-b->lastReceivedTS > 50 )
LOG_W(HW,"UEsock: %d gap of: %ld in reception\n", fd, b->th.timestamp-b->lastReceivedTS );
b->lastReceivedTS=b->th.timestamp;
......@@ -646,10 +648,11 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
);
else { // no channel modeling
sample_t *out=(sample_t *)samplesVoid[a];
const int64_t base=t->nextTimestamp*nbAnt+a;
for ( int i=0; i < nsamps; i++ ) {
out[i].r+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize].r;
out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize].i;
const int idx=(i*nbAnt+base)%CirSize;
out[i].r+=ptr->circularBuf[idx].r;
out[i].i+=ptr->circularBuf[idx].i;
}
} // end of no channel modeling
} // end for a...
......
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