nr_phy_scope.c 33.8 KB
Newer Older
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
1
2
3
4
5
6
7
8
9
10
11
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
Thomas Laurent's avatar
Thomas Laurent committed
12
13
 * Author and copyright: Laurent Thomas, open-cells.com
 *
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * 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.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

/* Form definition file generated by fdesign */

#include <stdlib.h>
#include "nr_phy_scope.h"
28
#include "executables/softmodem-common.h"
knopp's avatar
knopp committed
29
#include "executables/nr-softmodem-common.h"
Thomas Laurent's avatar
Thomas Laurent committed
30
#include <forms.h>
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
31
32

#define TPUT_WINDOW_LENGTH 100
33
#define ScaleZone 4
Thomas Laurent's avatar
Thomas Laurent committed
34
#define localBuff(NaMe,SiZe) float NaMe[SiZe]; memset(NaMe,0,sizeof(NaMe));
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
35

Thomas Laurent's avatar
Thomas Laurent committed
36
int otg_enabled;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
37

Thomas Laurent's avatar
Thomas Laurent committed
38
39
const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED};
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
40

41
typedef struct complex16 scopeSample_t;
Thomas Laurent's avatar
Thomas Laurent committed
42
43
44
45
#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)

typedef struct OAIgraph {
  FL_OBJECT *graph;
Thomas Laurent's avatar
Thomas Laurent committed
46
  FL_OBJECT *text;
Thomas Laurent's avatar
Thomas Laurent committed
47
48
49
50
  float maxX;
  float maxY;
  float minX;
  float minY;
Thomas Laurent's avatar
Thomas Laurent committed
51
52
53
54
55
56
  int x;
  int y;
  int w;
  int h;
  int waterFallh;
  double *waterFallAvg;
57
  boolean_t initDone;
Thomas Laurent's avatar
Thomas Laurent committed
58
  int iteration;
59
  void (*gNBfunct) (struct OAIgraph *graph, scopeData_t *p, int UE_id);
Thomas Laurent's avatar
Thomas Laurent committed
60
  void (*nrUEfunct)(struct OAIgraph *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id);
Thomas Laurent's avatar
Thomas Laurent committed
61
62
63
64
65
66
67
} OAIgraph_t;

/* Forms and Objects */
typedef struct {
  FL_FORM    *phy_scope;
  OAIgraph_t graph[20];
  FL_OBJECT *button_0;
Thomas Laurent's avatar
Thomas Laurent committed
68
} OAI_phy_scope_t;
69

Thomas Laurent's avatar
Thomas Laurent committed
70
71
72
73
74
75
76
77
78
79
80
81
82
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);
}
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
83

Thomas Laurent's avatar
Thomas Laurent committed
84
85
// button callback example
#if 0
Thomas Laurent's avatar
Thomas Laurent committed
86
static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
87
88
89
90
91
92
93
94
95
96
  if (fl_get_button(button)) {
    fl_set_object_label(button, "DL Traffic ON");
    otg_enabled = 1;
    fl_set_object_color(button, FL_GREEN, FL_GREEN);
  } else {
    fl_set_object_label(button, "DL Traffic OFF");
    otg_enabled = 0;
    fl_set_object_color(button, FL_RED, FL_RED);
  }
}
Thomas Laurent's avatar
Thomas Laurent committed
97
#endif
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
98

Thomas Laurent's avatar
Thomas Laurent committed
99
100
101
102
103
104
#define WATERFALL 10000

static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
  if (type==WATERFALL) {
    graph->waterFallh=h-15;
    graph->waterFallAvg=malloc(sizeof(*graph->waterFallAvg) * graph->waterFallh);
105
106
107

    for (int i=0; i< graph->waterFallh; i++)
      graph->waterFallAvg[i]=0;
Thomas Laurent's avatar
Thomas Laurent committed
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

    graph->graph=fl_add_canvas(FL_NORMAL_CANVAS, x, y, w, graph->waterFallh, label);
    graph->text=fl_add_text(FL_NORMAL_TEXT, x, y+graph->waterFallh, w, 15, label);
    fl_set_object_lcolor(graph->text,FL_WHITE);
    fl_set_object_color(graph->text, FL_BLACK, FL_BLACK);
    fl_set_object_lalign(graph->text, FL_ALIGN_CENTER );
  } else {
    graph->graph=fl_add_xyplot(type, x, y, w, h, label);
    fl_set_object_lcolor(graph->graph, FL_WHITE ); // Label color
    fl_set_object_color(graph->graph, FL_BLACK, pointColor);

    for (int i=0; i< FL_MAX_XYPLOTOVERLAY; i++)
      fl_set_xyplot_symbol(graph->graph, i, drawsymbol);
  }

  graph->x=x;
  graph->y=y;
  graph->w=w;
  graph->h=h;
  graph->maxX=0;
  graph->maxY=0;
  graph->minX=0;
  graph->minY=0;
131
  graph->initDone=false;
Thomas Laurent's avatar
Thomas Laurent committed
132
  graph->iteration=0;
Thomas Laurent's avatar
Thomas Laurent committed
133
}
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
134

135
static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, scopeData_t *p, int UE_id),
Thomas Laurent's avatar
Thomas Laurent committed
136
137
                                  int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
  OAIgraph_t graph;
Thomas Laurent's avatar
Thomas Laurent committed
138
  commonGraph(&graph, type, x, y, w, h, label, pointColor);
Thomas Laurent's avatar
Thomas Laurent committed
139
140
141
142
  graph.gNBfunct=funct;
  graph.nrUEfunct=NULL;
  return graph;
}
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
143

Thomas Laurent's avatar
Thomas Laurent committed
144
static OAIgraph_t nrUEcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id),
Thomas Laurent's avatar
Thomas Laurent committed
145
146
                                   int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
  OAIgraph_t graph;
Thomas Laurent's avatar
Thomas Laurent committed
147
  commonGraph(&graph, type, x, y, w, h, label, pointColor);
Thomas Laurent's avatar
Thomas Laurent committed
148
149
150
151
  graph.gNBfunct=NULL;
  graph.nrUEfunct=funct;
  return graph;
}
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
152

Thomas Laurent's avatar
Thomas Laurent committed
153
static void setRange(OAIgraph_t *graph, float minX, float maxX, float minY, float maxY) {
154
155
156
157
158
  if ( maxX > graph->maxX ||  minX < graph->minX ||
       abs(maxX-graph->maxX)>abs(graph->maxX)/2 ||
       abs(maxX-graph->maxX)>abs(graph->maxX)/2 ) {
    graph->maxX/=2;
    graph->minX/=2;
Thomas Laurent's avatar
Thomas Laurent committed
159
160
    graph->maxX=max(graph->maxX,maxX);
    graph->minX=min(graph->minX,minX);
161
162
163
164
165
166
167
168
    fl_set_xyplot_xbounds(graph->graph, graph->minX*1.2, graph->maxX*1.2);
  }

  if ( maxY > graph->maxY || minY < graph->minY ||
       abs(maxY-graph->maxY)>abs(graph->maxY)/2 ||
       abs(maxY-graph->maxY)>abs(graph->maxY)/2 ) {
    graph->maxY/=2;
    graph->minY/=2;
Thomas Laurent's avatar
Thomas Laurent committed
169
170
    graph->maxY=max(graph->maxY,maxY);
    graph->minY=min(graph->minY,minY);
171
    fl_set_xyplot_ybounds(graph->graph, graph->minY*1.2, graph->maxY*1.2);
Thomas Laurent's avatar
Thomas Laurent committed
172
173
  }
}
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
174

Thomas Laurent's avatar
Thomas Laurent committed
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len, int layer) {
  float *old_x;
  float *old_y;
  int old_len=-1;

  if (graph->iteration >1)
    fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len);

  if (old_len != len) {
    LOG_W(HW,"allocating graph of %d scope\n", len);
    float values[len];
    float time[len];

    // make time in case we will use it
    for (int i=0; i<len; i++)
      time[i] = values[i] = i;

    if (layer==0)
      fl_set_xyplot_data(graph->graph,time,values,len,"","","");
    else
      fl_add_xyplot_overlay(graph->graph,layer,time,values,len,rx_antenna_colors[layer]);

    fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len);
    AssertFatal(old_len==len,"");
  }

  *x=old_x;
  *y=old_y;
}

static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, boolean_t NoAutoScale) {
  fl_redraw_object(graph->graph);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
207

Thomas Laurent's avatar
Thomas Laurent committed
208
209
  if ( NoAutoScale && graph->iteration%NoAutoScale == 0) {
    float maxX=0, maxY=0, minX=0, minY=0;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
210

Thomas Laurent's avatar
Thomas Laurent committed
211
212
213
214
215
216
    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]);
    }
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
217

Thomas Laurent's avatar
Thomas Laurent committed
218
    setRange(graph, minX-5, maxX+5, minY-5, maxY+5);
Thomas Laurent's avatar
Thomas Laurent committed
219
  }
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
220

Thomas Laurent's avatar
Thomas Laurent committed
221
  graph->iteration++;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
222
223
}

224
static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) {
225
  if ( values == NULL )
226
227
    return;

Thomas Laurent's avatar
Thomas Laurent committed
228
229
  fl_winset(FL_ObjWin(graph->graph));
  const int samplesPerPixel=datasize/graph->w;
230
231
  int displayPart=graph->waterFallh-ScaleZone;
  int row=graph->iteration%displayPart;
Thomas Laurent's avatar
Thomas Laurent committed
232
233
  double avg=0;

234
  for (int i=0; i < displayPart; i++)
Thomas Laurent's avatar
Thomas Laurent committed
235
236
    avg+=graph->waterFallAvg[i];

237
  avg/=displayPart;
Thomas Laurent's avatar
Thomas Laurent committed
238
239
240
241
242
  graph->waterFallAvg[row]=0;

  for (int pix=0; pix<graph->w; pix++) {
    scopeSample_t *end=values+(pix+1)*samplesPerPixel;
    end-=2;
243
    AssertFatal(end <= values+datasize,"diff : %ld", end-values+datasize);
Thomas Laurent's avatar
Thomas Laurent committed
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
    double val=0;

    for (scopeSample_t *s=values+(pix)*samplesPerPixel;
         s <end;
         s++)
      val += SquaredNorm(*s);

    val/=samplesPerPixel;
    graph->waterFallAvg[row]+=val/graph->w;
    int col=0;

    if (val > avg*2 )
      col=1;

    if (val > avg*10 )
      col=2;

    if (val > avg*100 )
      col=3;

264
    fl_point(pix, graph->iteration%displayPart, water_colors[col]);
Thomas Laurent's avatar
Thomas Laurent committed
265
  }
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
266

267
268
269
270
271
272
273
274
275
276
277
278
  if (graph->initDone==false) {
    for ( int i=0; i < graph->waterFallh; i++ )
      for ( int j = 0 ; j < graph->w ; j++ )
        fl_point(j, i, FL_BLACK);

    for ( int i=1; i<divisions; i++)
      for (int j= displayPart; j<graph->waterFallh; j++)
        fl_point(i*(graph->w/divisions),j, FL_WHITE);

    graph->initDone=true;
  }

279
  fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, 0/*sqrt(avg)*/);
Thomas Laurent's avatar
Thomas Laurent committed
280
  graph->iteration++;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
281
282
}

Thomas Laurent's avatar
Thomas Laurent committed
283
static void genericPowerPerAntena(OAIgraph_t  *graph, const int nb_ant, const scopeSample_t **data, const int len) {
Thomas Laurent's avatar
Thomas Laurent committed
284
285
  float *values, *time;
  oai_xygraph_getbuff(graph, &time, &values, len, 0);
Thomas Laurent's avatar
Thomas Laurent committed
286

Thomas Laurent's avatar
Thomas Laurent committed
287
288
289
290
  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]);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
291
292
      }

Thomas Laurent's avatar
Thomas Laurent committed
293
      oai_xygraph(graph,time,values, len, ant, 10);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
294
    }
Thomas Laurent's avatar
Thomas Laurent committed
295
296
  }
}
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
297

298
299
static void gNBWaterFall (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
  NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
Thomas Laurent's avatar
Thomas Laurent committed
300
  //use 1st antenna
301
  genericWaterFall(graph, (scopeSample_t *)p->ru->common.rxdata[0],
302
303
                   frame_parms->samples_per_frame,  frame_parms->slots_per_frame,
                   "X axis:one frame in time");
Thomas Laurent's avatar
Thomas Laurent committed
304
305
306
}

/* replaced by waterfall
Thomas Laurent's avatar
Thomas Laurent committed
307
308
309
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)
Thomas Laurent's avatar
Thomas Laurent committed
310
    return;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
311

Thomas Laurent's avatar
Thomas Laurent committed
312
  NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
Thomas Laurent's avatar
Thomas Laurent committed
313
314
315
316
  genericLogPowerPerAntena(graph, frame_parms->nb_antennas_rx,
                           (const scopeSample_t **)phy_vars_ru->common.rxdata,
                           frame_parms->samples_per_frame);
}
Thomas Laurent's avatar
Thomas Laurent committed
317
*/
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
318

319
320
static void timeResponse (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
  const int len=2*p->gNB->frame_parms.ofdm_symbol_size;
Thomas Laurent's avatar
Thomas Laurent committed
321
322
  float *values, *time;
  oai_xygraph_getbuff(graph, &time, &values, len, 0);
Thomas Laurent's avatar
Thomas Laurent committed
323
  const int ant=0; // display antenna 0 for each UE
324

Thomas Laurent's avatar
Thomas Laurent committed
325
  for (int ue=0; ue<nb_UEs; ue++) {
326
327
328
329
330
331
332
333
334
    if ( p->gNB->pusch_vars && p->gNB->pusch_vars[ue] &&
         p->gNB->pusch_vars[ue]->ul_ch_estimates_time &&
         p->gNB->pusch_vars[ue]->ul_ch_estimates_time[ant] ) {
      scopeSample_t *data= (scopeSample_t *)p->gNB->pusch_vars[ue]->ul_ch_estimates_time[ant];

      if (data != NULL) {
        for (int i=0; i<len; i++) {
          values[i] = SquaredNorm(data[i]);
        }
Thomas Laurent's avatar
Thomas Laurent committed
335

336
        oai_xygraph(graph,time,values, len, ue, 10);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
337
338
      }
    }
Thomas Laurent's avatar
Thomas Laurent committed
339
340
  }
}
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
341

342
343
static void gNBfreqWaterFall (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
  NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
Thomas Laurent's avatar
Thomas Laurent committed
344
  //use 1st antenna
345
  genericWaterFall(graph, (scopeSample_t *)p->rxdataF, frame_parms->samples_per_frame_wCP,
346
                   frame_parms->slots_per_frame,
347
                   "X axis: Frequency domain, one subframe");
Thomas Laurent's avatar
Thomas Laurent committed
348
349
350
}

/*
Thomas Laurent's avatar
Thomas Laurent committed
351
352
353
354
355
356
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;
  genericLogPowerPerAntena(graph, frame_parms->nb_antennas_rx,
                           (const scopeSample_t **)phy_vars_ru->common.rxdataF,
                           frame_parms->samples_per_slot_wCP);
}
Thomas Laurent's avatar
Thomas Laurent committed
357
*/
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
358

359
static void puschLLR (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
Thomas Laurent's avatar
Thomas Laurent committed
360
361
362
  //int Qm = 2;
  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;

Thomas Laurent's avatar
Thomas Laurent committed
363
  for (int ue=0; ue<nb_UEs; ue++) {
364
365
366
367
368
369
    if ( p->gNB->pusch_vars &&
         p->gNB->pusch_vars[ue] &&
         p->gNB->pusch_vars[ue]->llr ) {
      int16_t *pusch_llr = (int16_t *)p->gNB->pusch_vars[ue]->llr;
      float *llr, *bit;
      oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword, ue);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
370

Thomas Laurent's avatar
Thomas Laurent committed
371
372
373
      for (int i=0; i<coded_bits_per_codeword; i++) {
        llr[i] = (float) pusch_llr[i];
      }
Thomas Laurent's avatar
Thomas Laurent committed
374

Thomas Laurent's avatar
Thomas Laurent committed
375
376
377
378
      oai_xygraph(graph,bit,llr,coded_bits_per_codeword,ue,10);
    }
  }
}
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
379

380
381
static void puschIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
  NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
Thomas Laurent's avatar
Thomas Laurent committed
382
383
  int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot;

Thomas Laurent's avatar
Thomas Laurent committed
384
  for (int ue=0; ue<nb_UEs; ue++) {
385
386
387
388
389
390
391
    if ( p->gNB->pusch_vars &&
         p->gNB->pusch_vars[ue] &&
         p->gNB->pusch_vars[ue]->rxdataF_comp &&
         p->gNB->pusch_vars[ue]->rxdataF_comp[0] ) {
      scopeSample_t *pusch_comp = (scopeSample_t *) p->gNB->pusch_vars[ue]->rxdataF_comp[0];
      float *I, *Q;
      oai_xygraph_getbuff(graph, &I, &Q, sz, ue);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
392

Thomas Laurent's avatar
Thomas Laurent committed
393
394
395
396
      for (int k=0; k<sz; k++ ) {
        I[k] = pusch_comp[k].r;
        Q[k] = pusch_comp[k].i;
      }
Thomas Laurent's avatar
Thomas Laurent committed
397

Thomas Laurent's avatar
Thomas Laurent committed
398
399
400
401
402
      oai_xygraph(graph,I,Q,sz,ue,10);
    }
  }
}

403
static void pucchEnergy (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
404
  // PUSCH I/Q of MF Output
Thomas Laurent's avatar
Thomas Laurent committed
405
  /*
Thomas Laurent's avatar
Thomas Laurent committed
406
407
408
    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];
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
409

Thomas Laurent's avatar
Thomas Laurent committed
410
    for (int ind=0; ind<10240; ind++) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
411
412
      I_pucch[ind] = (float)pucch1ab_comp[2*(ind)];
      Q_pucch[ind] = (float)pucch1ab_comp[2*(ind)+1];
413
      A_pucch[ind] = pucch1_comp?(10*log10(pucch1_comp[ind])):0;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
414
      B_pucch[ind] = ind;
Thomas Laurent's avatar
Thomas Laurent committed
415
      int32_t *pucch1_thres = (int32_t *) NULL; // phy_vars_gnb->pucch1_stats_thres[UE_id];
416
      C_pucch[ind] = pucch1_thres?(float)pucch1_thres[ind]:0;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
417
418
    }

Thomas Laurent's avatar
Thomas Laurent committed
419
420
421
422
423
424
    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);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
425
  }
Thomas Laurent's avatar
Thomas Laurent committed
426
  */
Thomas Laurent's avatar
Thomas Laurent committed
427
428
}

429
static void pucchIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
Thomas Laurent's avatar
Thomas Laurent committed
430
}
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
431

432
static void puschThroughtput (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
433
  // PUSCH Throughput
Thomas Laurent's avatar
Thomas Laurent committed
434
  /*
Thomas Laurent's avatar
Thomas Laurent committed
435
436
437
  float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
  float tput_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};

Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
438
439
  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) );
440
  tput_time_enb[UE_id][TPUT_WINDOW_LENGTH-1]  = (float) 0;
Thomas Laurent's avatar
Thomas Laurent committed
441
442
  //  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,"","","");
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
443
444
  //    fl_get_xyplot_ybounds(form->pusch_tput,&ymin,&ymax);
  //    fl_set_xyplot_ybounds(form->pusch_tput,0,ymax);
Thomas Laurent's avatar
Thomas Laurent committed
445
  */
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
446
}
Thomas Laurent's avatar
Thomas Laurent committed
447
static OAI_phy_scope_t *create_phy_scope_gnb(void) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
448
  FL_OBJECT *obj;
Thomas Laurent's avatar
Thomas Laurent committed
449
  OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
450
  // Define form
Thomas Laurent's avatar
Thomas Laurent committed
451
  fdui->phy_scope = fl_bgn_form( FL_NO_BOX, 800, 800 );
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
452
  // This the whole UI box
Thomas Laurent's avatar
Thomas Laurent committed
453
  obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
Thomas Laurent's avatar
Thomas Laurent committed
454
455
  fl_set_object_color( obj, FL_BLACK, FL_WHITE );
  int curY=0,x,y,w,h;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
456
  // Received signal
Thomas Laurent's avatar
Thomas Laurent committed
457
458
  fdui->graph[0] = gNBcommonGraph( gNBWaterFall, WATERFALL, 0, curY, 400, 100,
                                   "Received Signal (Time-Domain, one frame)", FL_RED );
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
459
  // Time-domain channel response
Thomas Laurent's avatar
Thomas Laurent committed
460
  fdui->graph[1] = gNBcommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, curY, 400, 100,
Thomas Laurent's avatar
Thomas Laurent committed
461
                                   "SRS Frequency Response (samples, abs)", FL_RED );
Thomas Laurent's avatar
Thomas Laurent committed
462
  fl_get_object_bbox(fdui->graph[1].graph,&x, &y,&w, &h);
Thomas Laurent's avatar
Thomas Laurent committed
463
  curY+=h;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
464
  // Frequency-domain channel response
Thomas Laurent's avatar
Thomas Laurent committed
465
466
  fdui->graph[2] = gNBcommonGraph( gNBfreqWaterFall, WATERFALL, 0, curY, 800, 100,
                                   "Channel Frequency domain (RE, one frame)", FL_RED );
Thomas Laurent's avatar
Thomas Laurent committed
467
  fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h);
468
  curY+=h+20;
Thomas Laurent's avatar
Thomas Laurent committed
469
  // LLR of PUSCH
Thomas Laurent's avatar
Thomas Laurent committed
470
  fdui->graph[3] = gNBcommonGraph( puschLLR, FL_POINTS_XYPLOT, 0, curY, 500, 200,
Thomas Laurent's avatar
Thomas Laurent committed
471
472
                                   "PUSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
  // I/Q PUSCH comp
Thomas Laurent's avatar
Thomas Laurent committed
473
  fdui->graph[4] = gNBcommonGraph( puschIQ, FL_POINTS_XYPLOT, 500, curY, 300, 200,
Thomas Laurent's avatar
Thomas Laurent committed
474
                                   "PUSCH I/Q of MF Output", FL_YELLOW );
Thomas Laurent's avatar
Thomas Laurent committed
475
476
  fl_get_object_bbox(fdui->graph[3].graph,&x, &y,&w, &h);
  curY+=h;
Thomas Laurent's avatar
Thomas Laurent committed
477
  // I/Q PUCCH comp (format 1)
Thomas Laurent's avatar
Thomas Laurent committed
478
  fdui->graph[5] = gNBcommonGraph( pucchEnergy, FL_POINTS_XYPLOT, 0, curY, 300, 100,
Thomas Laurent's avatar
Thomas Laurent committed
479
480
481
                                   "PUCCH1 Energy (SR)", FL_YELLOW );
  //  fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
  // I/Q PUCCH comp (fromat 1a/b)
Thomas Laurent's avatar
Thomas Laurent committed
482
  fdui->graph[6] = gNBcommonGraph( pucchIQ, FL_POINTS_XYPLOT, 500, curY, 300, 100,
Thomas Laurent's avatar
Thomas Laurent committed
483
                                   "PUCCH I/Q of MF Output", FL_YELLOW );
Thomas Laurent's avatar
Thomas Laurent committed
484
485
  fl_get_object_bbox(fdui->graph[6].graph,&x, &y,&w, &h);
  curY+=h;
Thomas Laurent's avatar
Thomas Laurent committed
486
  // Throughput on PUSCH
Thomas Laurent's avatar
Thomas Laurent committed
487
  fdui->graph[7] = gNBcommonGraph( puschThroughtput, FL_NORMAL_XYPLOT, 0, curY, 500, 100,
Thomas Laurent's avatar
Thomas Laurent committed
488
489
                                   "PUSCH Throughput [frame]/[kbit/s]", FL_WHITE );
  fdui->graph[8].graph=NULL;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
490
  fl_end_form( );
Thomas Laurent's avatar
Thomas Laurent committed
491
  fdui->phy_scope->fdui = fdui;
Thomas Laurent's avatar
Thomas Laurent committed
492
  fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, "LTE UL SCOPE gNB");
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
493
494
  return fdui;
}
Thomas Laurent's avatar
Thomas Laurent committed
495
496
static const int scope_enb_num_ue = 1;
void phy_scope_gNB(OAI_phy_scope_t *form,
497
                   scopeData_t *p,
Thomas Laurent's avatar
Thomas Laurent committed
498
                   int UE_id) {
Thomas Laurent's avatar
Thomas Laurent committed
499
  static OAI_phy_scope_t *rememberForm=NULL;
Thomas Laurent's avatar
Thomas Laurent committed
500
501

  if (form==NULL)
Thomas Laurent's avatar
Thomas Laurent committed
502
    form=rememberForm;
Thomas Laurent's avatar
Thomas Laurent committed
503
  else
Thomas Laurent's avatar
Thomas Laurent committed
504
    rememberForm=form;
Thomas Laurent's avatar
Thomas Laurent committed
505

Thomas Laurent's avatar
Thomas Laurent committed
506
507
  if (form==NULL)
    return;
Thomas Laurent's avatar
Thomas Laurent committed
508
509
510
511

  int i=0;

  while (form->graph[i].graph) {
512
    form->graph[i].gNBfunct(form->graph+i, p, UE_id);
Thomas Laurent's avatar
Thomas Laurent committed
513
514
515
    i++;
  }

Thomas Laurent's avatar
Thomas Laurent committed
516
  //fl_check_forms();
Thomas Laurent's avatar
Thomas Laurent committed
517
}
Thomas Laurent's avatar
Thomas Laurent committed
518
static void *scope_thread_gNB(void *arg) {
519
  scopeData_t *p=(scopeData_t *) arg;
Thomas Laurent's avatar
Thomas Laurent committed
520
521
522
  //# ifdef ENABLE_XFORMS_WRITE_STATS
  //  FILE *gNB_stats = fopen("gNB_stats.txt", "w");
  //#endif
Thomas Laurent's avatar
Thomas Laurent committed
523
  size_t stksize=0;
Thomas Schlichter's avatar
Thomas Schlichter committed
524
525
  pthread_attr_t atr;
  pthread_attr_init(&atr);
Thomas Laurent's avatar
Thomas Laurent committed
526
527
528
  pthread_attr_getstacksize(&atr, &stksize);
  pthread_attr_setstacksize(&atr,32*1024*1024 );
  sleep(3); // no clean interthread barriers
Thomas Laurent's avatar
Thomas Laurent committed
529
530
531
  int fl_argc=1;
  char *name="5G-gNB-scope";
  fl_initialize (&fl_argc, &name, NULL, 0, 0);
Thomas Laurent's avatar
Thomas Laurent committed
532
533
  int nb_ue=min(NUMBER_OF_UE_MAX, scope_enb_num_ue);
  OAI_phy_scope_t  *form_gnb = create_phy_scope_gnb();
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
534

Thomas Laurent's avatar
Thomas Laurent committed
535
  while (!oai_exit) {
536
    phy_scope_gNB(form_gnb, p, nb_ue);
Thomas Laurent's avatar
Thomas Laurent committed
537
    usleep(99*1000);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
538
539
  }

Thomas Laurent's avatar
Thomas Laurent committed
540
541
  return NULL;
}
542
543
544
545
546
547
static void copyRxdataF(int32_t *data, int slot,  void *scopeData) {
  scopeData_t *scope=(scopeData_t *)scopeData;
  memcpy(scope->rxdataF + slot*scope->gNB->frame_parms.samples_per_slot_wCP,
         data,
         scope->gNB->frame_parms.samples_per_slot_wCP);
}
548

549
void gNBinitScope(scopeParms_t *p) {
550
  AssertFatal(p->gNB->scopeData=malloc(sizeof(scopeData_t)),"");
551
552
553
554
555
556
  scopeData_t *scope=(scopeData_t *) p->gNB->scopeData;
  scope->argc=p->argc;
  scope->argv=p->argv;
  scope->ru=p->ru;
  scope->gNB=p->gNB;
  scope->slotFunc=copyRxdataF;
557
  AssertFatal(scope->rxdataF=(int32_t *) calloc(p->gNB->frame_parms.samples_per_frame_wCP*sizeof(int32_t),1),"");
Thomas Laurent's avatar
Thomas Laurent committed
558
  pthread_t forms_thread;
559
  threadCreate(&forms_thread, scope_thread_gNB, p->gNB->scopeData, "scope", -1, OAI_PRIORITY_RT_LOW);
Thomas Laurent's avatar
Thomas Laurent committed
560
}
Thomas Laurent's avatar
Thomas Laurent committed
561
562
563
564
static void ueWaterFall  (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
  genericWaterFall(graph,
                   (scopeSample_t *) phy_vars_ue->common_vars.rxdata[0],
565
566
567
                   phy_vars_ue->frame_parms.samples_per_frame,
                   phy_vars_ue->frame_parms.slots_per_frame,
                   "X axis: one frame time");
Thomas Laurent's avatar
Thomas Laurent committed
568
569
}
/* replaced by waterfall
Thomas Laurent's avatar
Thomas Laurent committed
570
static void ueTimeResponse  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
571
  // Received signal in time domain of receive antenna 0
Thomas Laurent's avatar
Thomas Laurent committed
572
573
574
  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);
Thomas Laurent's avatar
Thomas Laurent committed
575
}
Thomas Laurent's avatar
Thomas Laurent committed
576
*/
Thomas Laurent's avatar
Thomas Laurent committed
577
static void ueChannelResponse  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
578
  // Channel Impulse Response
Thomas Laurent's avatar
Thomas Laurent committed
579
580
581
  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);
Thomas Laurent's avatar
Thomas Laurent committed
582
}
Thomas Laurent's avatar
Thomas Laurent committed
583
584
585
586
587
static void ueFreqWaterFall (OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id ) {
  NR_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->frame_parms;
  //use 1st antenna
  genericWaterFall(graph,
                   (scopeSample_t *)phy_vars_ue->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0],
588
589
590
                   frame_parms->samples_per_slot_wCP,
                   phy_vars_ue->frame_parms.slots_per_frame,
                   "X axis: one frame frequency" );
Thomas Laurent's avatar
Thomas Laurent committed
591
592
}
/*
Thomas Laurent's avatar
Thomas Laurent committed
593
static void uePbchFrequencyResp  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
Thomas Laurent's avatar
Thomas Laurent committed
594
595
596
  // Channel Frequency Response (includes 5 complex sample for filter)
  if (!phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates)
    return;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
597

Thomas Laurent's avatar
Thomas Laurent committed
598
599
600
601
602
  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;
Thomas Laurent's avatar
Thomas Laurent committed
603
604
  float *freq, *chest_f_abs;
  oai_xygraph_getbuff(graph, &freq, &chest_f_abs, frame_parms->ofdm_symbol_size, 0);
Thomas Laurent's avatar
Thomas Laurent committed
605
606
607
608

  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) {
Thomas Laurent's avatar
Thomas Laurent committed
609

Thomas Laurent's avatar
Thomas Laurent committed
610
611
612
613
        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++;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
614
615
616
617
        }
      }
    }
  }
Thomas Laurent's avatar
Thomas Laurent committed
618
619
620
621
622
623

  // 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);
Thomas Laurent's avatar
Thomas Laurent committed
624
  oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10);
Thomas Laurent's avatar
Thomas Laurent committed
625
}
Thomas Laurent's avatar
Thomas Laurent committed
626
*/
Thomas Laurent's avatar
Thomas Laurent committed
627
static void uePbchLLR  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
628
  // PBCH LLRs
Thomas Laurent's avatar
Thomas Laurent committed
629
630
631
632
  if ( !phy_vars_ue->pbch_vars[eNB_id]->llr)
    return;

  int16_t *pbch_llr = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->llr;
Thomas Laurent's avatar
Thomas Laurent committed
633
634
  float *llr_pbch, *bit_pbch;
  oai_xygraph_getbuff(graph, &bit_pbch, &llr_pbch, 864, 0);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
635

Thomas Laurent's avatar
Thomas Laurent committed
636
637
  for (int i=0; i<864; i++) {
    llr_pbch[i] = (float) pbch_llr[i];
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
638
639
  }

Thomas Laurent's avatar
Thomas Laurent committed
640
  oai_xygraph(graph,bit_pbch,llr_pbch,864,0,10);
Thomas Laurent's avatar
Thomas Laurent committed
641
}
Thomas Laurent's avatar
Thomas Laurent committed
642
static void uePbchIQ  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
643
  // PBCH I/Q of MF Output
Thomas Laurent's avatar
Thomas Laurent committed
644
645
646
  if (!phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0])
    return;

Thomas Laurent's avatar
Thomas Laurent committed
647
  scopeSample_t *pbch_comp = (scopeSample_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
Thomas Laurent's avatar
Thomas Laurent committed
648
649
  float *I, *Q;
  oai_xygraph_getbuff(graph, &I, &Q, 180*3, 0);
650
651
  memset(I,0,180*3*sizeof(*I));
  memset(Q,0,180*3*sizeof(*Q));
Thomas Laurent's avatar
Thomas Laurent committed
652
653
654
655
656
657
658
659
660
661
662
663
664
665
  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++) {
Thomas Laurent's avatar
Thomas Laurent committed
666
667
      I[base+i] = pbch_comp[symbol*20*12+i].r;
      Q[base+i] = pbch_comp[symbol*20*12+i].i;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
668
    }
Thomas Laurent's avatar
Thomas Laurent committed
669
670

    base+=nb_re;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
671
672
  }

Thomas Laurent's avatar
Thomas Laurent committed
673
  AssertFatal(base <= 180*3,"");
674
  oai_xygraph(graph,I,Q,base,0, 10);
Thomas Laurent's avatar
Thomas Laurent committed
675
}
Thomas Laurent's avatar
Thomas Laurent committed
676
static void uePcchLLR  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
677
  // PDCCH LLRs
Thomas Laurent's avatar
Thomas Laurent committed
678
679
  if (!phy_vars_ue->pdcch_vars[0][eNB_id]->llr)
    return;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
680

681
682
683
  //int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
  //int Qm = 2;
  int coded_bits_per_codeword = 2*4*100*12; //num_re*Qm;
Thomas Laurent's avatar
Thomas Laurent committed
684
685
  float *llr, *bit;
  oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0);
686
  int base=0;
Thomas Laurent's avatar
Thomas Laurent committed
687

688
689
690
691
692
  for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
    int16_t *pdcch_llr = (int16_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->llr;

    for (int i=0; i<coded_bits_per_codeword; i++) {
      llr[base+i] = (float) pdcch_llr[i];
Thomas Laurent's avatar
Thomas Laurent committed
693
    }
694
695

    base+=coded_bits_per_codeword;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
696
697
  }

Thomas Laurent's avatar
Thomas Laurent committed
698
  AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, "");
699
  oai_xygraph(graph,bit,llr,base,0,10);
Thomas Laurent's avatar
Thomas Laurent committed
700
}
Thomas Laurent's avatar
Thomas Laurent committed
701
static void uePcchIQ  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
702
  // PDCCH I/Q of MF Output
Thomas Laurent's avatar
Thomas Laurent committed
703
704
705
  if (!phy_vars_ue->pdcch_vars[0][eNB_id]->rxdataF_comp[0])
    return;

Thomas Laurent's avatar
Thomas Laurent committed
706
  int nb=4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
Thomas Laurent's avatar
Thomas Laurent committed
707
708
  float *I, *Q;
  oai_xygraph_getbuff(graph, &I, &Q, nb*RX_NB_TH_MAX, 0);
Thomas Laurent's avatar
Thomas Laurent committed
709
710
711
  int base=0;

  for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
Thomas Laurent's avatar
Thomas Laurent committed
712
    scopeSample_t *pdcch_comp = (scopeSample_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->rxdataF_comp[0];
Thomas Laurent's avatar
Thomas Laurent committed
713
714

    for (int i=0; i< nb; i++) {
Thomas Laurent's avatar
Thomas Laurent committed
715
716
      I[base+i] = pdcch_comp[i].r;
      Q[base+i] = pdcch_comp[i].i;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
717
    }
Thomas Laurent's avatar
Thomas Laurent committed
718
719

    base+=nb;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
720
721
  }

Thomas Laurent's avatar
Thomas Laurent committed
722
  AssertFatal(base <= nb*RX_NB_TH_MAX, "");
Thomas Laurent's avatar
Thomas Laurent committed
723
  oai_xygraph(graph,I,Q,base,0,10);
Thomas Laurent's avatar
Thomas Laurent committed
724
}
Thomas Laurent's avatar
Thomas Laurent committed
725
static void uePdschLLR  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
726
  // PDSCH LLRs
Thomas Laurent's avatar
Thomas Laurent committed
727
728
729
730
731
732
  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;
Thomas Laurent's avatar
Thomas Laurent committed
733
734
  float *llr, *bit;
  oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0);
Thomas Laurent's avatar
Thomas Laurent committed
735
736
737
738
739
740
741
742
  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;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
743
744
    }

Thomas Laurent's avatar
Thomas Laurent committed
745
    base+=coded_bits_per_codeword;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
746
747
  }

Thomas Laurent's avatar
Thomas Laurent committed
748
  AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, "");
Thomas Laurent's avatar
Thomas Laurent committed
749
  //fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword);
Thomas Laurent's avatar
Thomas Laurent committed
750
  oai_xygraph(graph,bit,llr,base,0,10);
Thomas Laurent's avatar
Thomas Laurent committed
751
}
Thomas Laurent's avatar
Thomas Laurent committed
752
static void uePdschIQ  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
753
  // PDSCH I/Q of MF Output
Thomas Laurent's avatar
Thomas Laurent committed
754
755
756
757
758
  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
Thomas Laurent's avatar
Thomas Laurent committed
759
760
  float *I, *Q;
  oai_xygraph_getbuff(graph, &I, &Q, sz*RX_NB_TH_MAX, 0);
Thomas Laurent's avatar
Thomas Laurent committed
761
  int base=0;
Thomas Laurent's avatar
Thomas Laurent committed
762
763
  memset(I+base, 0, sz*RX_NB_TH_MAX * sizeof(*I));
  memset(Q+base, 0, sz*RX_NB_TH_MAX * sizeof(*Q));
Thomas Laurent's avatar
Thomas Laurent committed
764
765

  for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
Thomas Laurent's avatar
Thomas Laurent committed
766
    scopeSample_t *pdsch_comp = (scopeSample_t *) phy_vars_ue->pdsch_vars[thr][eNB_id]->rxdataF_comp0[0];
Thomas Laurent's avatar
Thomas Laurent committed
767
768

    for (int s=0; s<sz; s++) {
Thomas Laurent's avatar
Thomas Laurent committed
769
770
      I[s+base] += pdsch_comp[s].r;
      Q[s+base] += pdsch_comp[s].i;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
771
    }
Thomas Laurent's avatar
Thomas Laurent committed
772
773

    base+=sz;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
774
  }
Thomas Laurent's avatar
Thomas Laurent committed
775

Thomas Laurent's avatar
Thomas Laurent committed
776
777
  AssertFatal(base <= sz*RX_NB_TH_MAX, "");
  oai_xygraph(graph,I,Q,sz*RX_NB_TH_MAX,0,10);
Thomas Laurent's avatar
Thomas Laurent committed
778
779
}
static void uePdschThroughput  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
780
  /*
Thomas Laurent's avatar
Thomas Laurent committed
781
782
783
784
  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};

Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
785
786
787
788
789
790
791
792
793

  // PDSCH Throughput
  memmove( tput_time_ue[UE_id], &tput_time_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
  memmove( tput_ue[UE_id],      &tput_ue[UE_id][1],      (TPUT_WINDOW_LENGTH-1)*sizeof(float) );

  tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1]  = (float) frame;
  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]) {
Thomas Laurent's avatar
Thomas Laurent committed
794
  tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
795
796
797
798
799
800
  }

  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]);
  */
Thomas Laurent's avatar
Thomas Laurent committed
801
}
Thomas Laurent's avatar
Thomas Laurent committed
802
static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
Thomas Laurent's avatar
Thomas Laurent committed
803
  FL_OBJECT *obj;
Thomas Laurent's avatar
Thomas Laurent committed
804
  OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
Thomas Laurent's avatar
Thomas Laurent committed
805
806
807
808
809
  // 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 );
Thomas Laurent's avatar
Thomas Laurent committed
810
  int curY=0,x,y,w,h;
Thomas Laurent's avatar
Thomas Laurent committed
811
  // Received signal
Thomas Laurent's avatar
Thomas Laurent committed
812
813
  fdui->graph[0] = nrUEcommonGraph(ueWaterFall,
                                   WATERFALL, 0, curY, 400, 100, "Received Signal (Time-Domain, one frame)", FL_RED );
Thomas Laurent's avatar
Thomas Laurent committed
814
815
  // Time-domain channel response
  fdui->graph[1] = nrUEcommonGraph(ueChannelResponse,
Thomas Laurent's avatar
Thomas Laurent committed
816
                                   FL_NORMAL_XYPLOT, 400, curY, 400, 100, "Channel Impulse Response (samples, abs)", FL_RED );
Thomas Laurent's avatar
Thomas Laurent committed
817
  fl_get_object_bbox(fdui->graph[1].graph,&x, &y,&w, &h);
Thomas Laurent's avatar
Thomas Laurent committed
818
  curY+=h;
Thomas Laurent's avatar
Thomas Laurent committed
819
  // Frequency-domain channel response
Thomas Laurent's avatar
Thomas Laurent committed
820
821
  fdui->graph[2] = nrUEcommonGraph(ueFreqWaterFall,
                                   WATERFALL, 0, curY, 800, 100, "Channel Frequency (RE, one slot)", FL_RED );
Thomas Laurent's avatar
Thomas Laurent committed
822
  fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h);
823
  curY+=h+20;
Thomas Laurent's avatar
Thomas Laurent committed
824
825
  // LLR of PBCH
  fdui->graph[3] = nrUEcommonGraph(uePbchLLR,
Thomas Laurent's avatar
Thomas Laurent committed
826
                                   FL_POINTS_XYPLOT, 0, curY, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)", FL_GREEN );
Thomas Laurent's avatar
Thomas Laurent committed
827
828
829
  fl_set_xyplot_xgrid(fdui->graph[3].graph,FL_GRID_MAJOR);
  // I/Q PBCH comp
  fdui->graph[4] = nrUEcommonGraph(uePbchIQ,
Thomas Laurent's avatar
Thomas Laurent committed
830
831
832
                                   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;
Thomas Laurent's avatar
Thomas Laurent committed
833
834
  // LLR of PDCCH
  fdui->graph[5] = nrUEcommonGraph(uePcchLLR,
Thomas Laurent's avatar
Thomas Laurent committed
835
                                   FL_POINTS_XYPLOT, 0, curY, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)", FL_CYAN );
Thomas Laurent's avatar
Thomas Laurent committed
836
837
  // I/Q PDCCH comp
  fdui->graph[6] = nrUEcommonGraph(uePcchIQ,
Thomas Laurent's avatar
Thomas Laurent committed
838
839
840
                                   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;
Thomas Laurent's avatar
Thomas Laurent committed
841
842
  // LLR of PDSCH
  fdui->graph[7] = nrUEcommonGraph(uePdschLLR,
Thomas Laurent's avatar
Thomas Laurent committed
843
                                   FL_POINTS_XYPLOT, 0, curY, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
Thomas Laurent's avatar
Thomas Laurent committed
844
845
  // I/Q PDSCH comp
  fdui->graph[8] = nrUEcommonGraph(uePdschIQ,
Thomas Laurent's avatar
Thomas Laurent committed
846
847
848
                                   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;
Thomas Laurent's avatar
Thomas Laurent committed
849
850
  // Throughput on PDSCH
  fdui->graph[9] = nrUEcommonGraph(uePdschThroughput,
Thomas Laurent's avatar
Thomas Laurent committed
851
                                   FL_NORMAL_XYPLOT, 0, curY, 500, 100, "PDSCH Throughput [frame]/[kbit/s]", FL_WHITE );
Thomas Laurent's avatar
Thomas Laurent committed
852
853
  fdui->graph[10].graph=NULL;
  // Generic UE Button
Thomas Laurent's avatar
Thomas Laurent committed
854
#if 0
Thomas Laurent's avatar
Thomas Laurent committed
855
856
857
858
859
860
861
862
  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);
Thomas Laurent's avatar
Thomas Laurent committed
863
#endif
Thomas Laurent's avatar
Thomas Laurent committed
864
865
866
867
868
869
870
  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;
}
Thomas Laurent's avatar
Thomas Laurent committed
871
void phy_scope_nrUE(OAI_phy_scope_t *form,
Thomas Laurent's avatar
Thomas Laurent committed
872
873
874
                    PHY_VARS_NR_UE *phy_vars_ue,
                    int eNB_id,
                    int UE_id) {
Thomas Laurent's avatar
Thomas Laurent committed
875
  static OAI_phy_scope_t *remeberForm=NULL;
Thomas Laurent's avatar
Thomas Laurent committed
876
877
878
879
880
881
882
883
884
885
886
887

  if (form==NULL)
    form=remeberForm;
  else
    remeberForm=form;

  if (form==NULL)
    return;

  int i=0;

  while (form->graph[i].graph) {
Thomas Laurent's avatar
Thomas Laurent committed
888
    form->graph[i].nrUEfunct(form->graph+i, phy_vars_ue, eNB_id, UE_id);
Thomas Laurent's avatar
Thomas Laurent committed
889
    i++;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
890
  }
Thomas Laurent's avatar
Thomas Laurent committed
891

Thomas Laurent's avatar
Thomas Laurent committed
892
  //fl_check_forms();
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
893
}
Thomas Laurent's avatar
Thomas Laurent committed
894
895
896
static void *nrUEscopeThread(void *arg) {
  PHY_VARS_NR_UE *ue=(PHY_VARS_NR_UE *)arg;
  size_t stksize;
897
  pthread_attr_t atr={0};
Thomas Laurent's avatar
Thomas Laurent committed
898
899
  pthread_attr_getstacksize(&atr, &stksize);
  pthread_attr_setstacksize(&atr,32*1024*1024 );
Thomas Laurent's avatar
Thomas Laurent committed
900
901
902
903
  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);
Thomas Laurent's avatar
Thomas Laurent committed
904
905

  while (!oai_exit) {
906
    fl_freeze_form(form_nrue->phy_scope);
Thomas Laurent's avatar
Thomas Laurent committed
907
    phy_scope_nrUE(form_nrue,
Thomas Laurent's avatar
Thomas Laurent committed
908
909
                   ue,
                   0,0);
910
911
    fl_unfreeze_form(form_nrue->phy_scope);
    fl_redraw_form(form_nrue->phy_scope);
Thomas Laurent's avatar
Thomas Laurent committed
912
913
914
915
916
    usleep(99*1000);
  }

  pthread_exit((void *)arg);
}
917
void nrUEinitScope(PHY_VARS_NR_UE *ue) {
Thomas Laurent's avatar
Thomas Laurent committed
918
  pthread_t forms_thread;
Thomas Laurent's avatar
Thomas Laurent committed
919
920
  threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
}
921
922
void nrscope_autoinit(void *dataptr) {
  AssertFatal( (IS_SOFTMODEM_GNB_BIT||IS_SOFTMODEM_5GUE_BIT),"Scope cannot find NRUE or GNB context");
Thomas Laurent's avatar
Thomas Laurent committed
923

924
  if (IS_SOFTMODEM_GNB_BIT)
Thomas Laurent's avatar
Thomas Laurent committed
925
    gNBinitScope(dataptr);
926
  else
Thomas Laurent's avatar
Thomas Laurent committed
927
    nrUEinitScope(dataptr);
928
}
Thomas Laurent's avatar
Thomas Laurent committed
929
930
// Kept to put back the functionality soon
#if 0
931
932
933
//FD_stats_form                  *form_stats=NULL,*form_stats_l2=NULL;
//char                            title[255];
//static pthread_t                forms_thread; //xforms
Thomas Laurent's avatar
Thomas Laurent committed
934
935
static void reset_stats_gNB(FL_OBJECT *button,
                            long arg) {
936
937
938
939
940
  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
941
      /*      for (j=0; j<phy_vars_gNB->dlsch[i][0]->Mlimit; j++) {
Thomas Laurent's avatar
Thomas Laurent committed
942
943
944
              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;