Commit 86f0bee1 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/NR_gNB_qtscope_llrPlot_fix' into integration_2023_w31

parents 5f240017 17b191a0
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "PHY/NR_ESTIMATION/nr_ul_estimation.h" #include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
#include "PHY/defs_nr_common.h" #include "PHY/defs_nr_common.h"
#include "common/utils/nr/nr_common.h" #include "common/utils/nr/nr_common.h"
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
//#define DEBUG_CH_COMP //#define DEBUG_CH_COMP
//#define DEBUG_RB_EXT //#define DEBUG_RB_EXT
...@@ -2015,6 +2016,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -2015,6 +2016,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
ad_shift = -3; // For 2-layers, we are already doing a bit shift in the nr_ulsch_mmse_2layers() function, so we can use more bits ad_shift = -3; // For 2-layers, we are already doing a bit shift in the nr_ulsch_mmse_2layers() function, so we can use more bits
} }
int num_re_total = 0;
for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) {
uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
if (dmrs_symbol_flag == 1) { if (dmrs_symbol_flag == 1) {
...@@ -2037,6 +2039,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -2037,6 +2039,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB; nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
} }
num_re_total += nb_re_pusch;
pusch_vars->ul_valid_re_per_slot[symbol] = nb_re_pusch; pusch_vars->ul_valid_re_per_slot[symbol] = nb_re_pusch;
LOG_D(PHY, "symbol %d: nb_re_pusch %d, DMRS symbl used for Chest :%d \n", symbol, nb_re_pusch, pusch_vars->dmrs_symbol); LOG_D(PHY, "symbol %d: nb_re_pusch %d, DMRS symbl used for Chest :%d \n", symbol, nb_re_pusch, pusch_vars->dmrs_symbol);
...@@ -2214,4 +2217,9 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -2214,4 +2217,9 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
rxdataF_ext_offset += pusch_vars->ul_valid_re_per_slot[symbol]; rxdataF_ext_offset += pusch_vars->ul_valid_re_per_slot[symbol];
} }
} // symbol loop } // symbol loop
if (!(frame % 128)) {
int num_llr = num_re_total*rel15_ul->qam_mod_order;
GnbScopeUpdate(gNB, puschLLRe, num_llr);
GnbScopeUpdate(gNB, puschIQe, num_re_total);
}
} }
...@@ -70,6 +70,22 @@ float Limits_KPI_ue[2][2] = { ...@@ -70,6 +70,22 @@ float Limits_KPI_ue[2][2] = {
{0.2, 10} // Throughput in Mbs {0.2, 10} // Throughput in Mbs
}; };
// Plot updater
PlotUpdater puschLlrUpdater;
PlotUpdater puschIqUpdater;
void scopeUpdaterGnb(enum PlotTypeGnbIf plotType, int numElt)
{
switch (plotType) {
case puschLLRe:
puschLlrUpdater.updatePlot(numElt);
break;
case puschIQe:
puschIqUpdater.updatePlot(numElt);
break;
}
}
/* This class creates the window when choosing the option 'Configs' to configure the threshold values. */ /* This class creates the window when choosing the option 'Configs' to configure the threshold values. */
ConfigBoxFloat::ConfigBoxFloat(float *valuePtr, QWidget *parent) : QLineEdit(parent), valuePtr(valuePtr) ConfigBoxFloat::ConfigBoxFloat(float *valuePtr, QWidget *parent) : QLineEdit(parent), valuePtr(valuePtr)
{ {
...@@ -178,7 +194,8 @@ KPIListSelectUE::KPIListSelectUE(QWidget *parent) : QComboBox(parent) ...@@ -178,7 +194,8 @@ KPIListSelectUE::KPIListSelectUE(QWidget *parent) : QComboBox(parent)
this->addItem("Configs", static_cast<int>(PlotTypeUE::config)); this->addItem("Configs", static_cast<int>(PlotTypeUE::config));
} }
WaterFall::WaterFall(complex16 *values, NR_DL_FRAME_PARMS *frame_parms, QWidget *parent) : QWidget(parent), values(values), frame_parms(frame_parms) WaterFall::WaterFall(complex16 *values, NR_DL_FRAME_PARMS *frame_parms, QWidget *parent)
: QWidget(parent), values(values), frame_parms(frame_parms)
{ {
this->iteration = 0; this->iteration = 0;
this->image = nullptr; this->image = nullptr;
...@@ -187,8 +204,8 @@ WaterFall::WaterFall(complex16 *values, NR_DL_FRAME_PARMS *frame_parms, QWidget ...@@ -187,8 +204,8 @@ WaterFall::WaterFall(complex16 *values, NR_DL_FRAME_PARMS *frame_parms, QWidget
startTimer(100); startTimer(100);
} }
/* this function to plot the waterfall graph for the RX signal in time domain for one frame. x-axis shows the frame divided into slots /* this function to plot the waterfall graph for the RX signal in time domain for one frame. x-axis shows the frame divided into
and the y-axis is a color map depending on the SquaredNorm of the received signal at the correspoinding slot. */ slots and the y-axis is a color map depending on the SquaredNorm of the received signal at the correspoinding slot. */
void WaterFall::timerEvent(QTimerEvent *event) void WaterFall::timerEvent(QTimerEvent *event)
{ {
if (!this->isVisible()) if (!this->isVisible())
...@@ -340,17 +357,19 @@ void CIRPlotUE::timerEvent(QTimerEvent *event) ...@@ -340,17 +357,19 @@ void CIRPlotUE::timerEvent(QTimerEvent *event)
maxY = std::max(maxY, value); maxY = std::max(maxY, value);
} }
this->axisX->setRange(-this->len / 2, this->len / 2);
this->axisY->setMax(maxY); this->axisY->setMax(maxY);
this->series->replace(points); this->series->replace(points);
} }
} }
LLRPlot::LLRPlot(int16_t *data, int len) : data(data), len(len) LLRPlot::LLRPlot(int16_t *data, int len, int interval, PlotUpdater *plotUpdater) : data(data), len(len), plotUpdater(plotUpdater)
{ {
this->legend()->hide(); this->legend()->hide();
// add new series to the chart // add new series to the chart
this->series = new QScatterSeries(); this->series = new QScatterSeries();
this->series->setUseOpenGL();
this->series->setMarkerSize(3); this->series->setMarkerSize(3);
this->series->setMarkerShape(QScatterSeries::MarkerShapeRectangle); this->series->setMarkerShape(QScatterSeries::MarkerShapeRectangle);
this->series->setColor(Qt::blue); this->series->setColor(Qt::blue);
...@@ -360,7 +379,6 @@ LLRPlot::LLRPlot(int16_t *data, int len) : data(data), len(len) ...@@ -360,7 +379,6 @@ LLRPlot::LLRPlot(int16_t *data, int len) : data(data), len(len)
// add new X axis // add new X axis
this->axisX = new QValueAxis(); this->axisX = new QValueAxis();
this->axisX->setLabelFormat("%d"); this->axisX->setLabelFormat("%d");
this->axisX->setRange(0, len);
this->addAxis(this->axisX, Qt::AlignBottom); this->addAxis(this->axisX, Qt::AlignBottom);
this->series->attachAxis(this->axisX); this->series->attachAxis(this->axisX);
...@@ -369,26 +387,44 @@ LLRPlot::LLRPlot(int16_t *data, int len) : data(data), len(len) ...@@ -369,26 +387,44 @@ LLRPlot::LLRPlot(int16_t *data, int len) : data(data), len(len)
this->addAxis(this->axisY, Qt::AlignLeft); this->addAxis(this->axisY, Qt::AlignLeft);
this->series->attachAxis(this->axisY); this->series->attachAxis(this->axisY);
startTimer(1000); if (interval)
startTimer(interval);
if (plotUpdater)
connect(plotUpdater, &PlotUpdater::updatePlot, this, &LLRPlot::updatePlot, Qt::QueuedConnection);
} }
void LLRPlot::timerEvent(QTimerEvent *event) LLRPlot::~LLRPlot()
{
if (this->plotUpdater)
disconnect(this->plotUpdater, &PlotUpdater::updatePlot, this, &LLRPlot::updatePlot);
}
void LLRPlot::updatePlot(int len)
{ {
this->len = len;
if (!this->isVisible()) if (!this->isVisible())
return; return;
QVector<QPointF> points(this->len); QVector<QPointF> points(len);
int maxY = this->axisY->max(); int maxY = this->axisY->max();
for (int i = 0; i < this->len; i++) { for (int i = 0; i < len; i++) {
points[i] = QPointF(i, this->data[i]); points[i] = QPointF(i, this->data[i]);
maxY = std::max(maxY, abs(this->data[i])); maxY = std::max(maxY, abs(this->data[i]));
} }
this->axisX->setRange(0, len);
this->axisY->setRange(-maxY, maxY); this->axisY->setRange(-maxY, maxY);
this->series->replace(points); this->series->replace(points);
} }
void LLRPlot::timerEvent(QTimerEvent *event)
{
this->updatePlot(this->len);
}
void LLRPlotUE::timerEvent(QTimerEvent *event) void LLRPlotUE::timerEvent(QTimerEvent *event)
{ {
if (!this->isVisible()) if (!this->isVisible())
...@@ -406,17 +442,19 @@ void LLRPlotUE::timerEvent(QTimerEvent *event) ...@@ -406,17 +442,19 @@ void LLRPlotUE::timerEvent(QTimerEvent *event)
maxY = std::max(maxY, abs(this->data[i])); maxY = std::max(maxY, abs(this->data[i]));
} }
this->axisX->setRange(0, this->len);
this->axisY->setRange(-maxY, maxY); this->axisY->setRange(-maxY, maxY);
this->series->replace(points); this->series->replace(points);
} }
} }
IQPlot::IQPlot(complex16 *data, int len) : data(data), len(len) IQPlot::IQPlot(complex16 *data, int len, int interval, PlotUpdater *plotUpdater) : data(data), len(len), plotUpdater(plotUpdater)
{ {
this->legend()->hide(); this->legend()->hide();
// add new series to the chart // add new series to the chart
this->series = new QScatterSeries(); this->series = new QScatterSeries();
this->series->setUseOpenGL();
this->series->setMarkerSize(3); this->series->setMarkerSize(3);
this->series->setMarkerShape(QScatterSeries::MarkerShapeRectangle); this->series->setMarkerShape(QScatterSeries::MarkerShapeRectangle);
this->series->setColor(Qt::blue); this->series->setColor(Qt::blue);
...@@ -433,19 +471,31 @@ IQPlot::IQPlot(complex16 *data, int len) : data(data), len(len) ...@@ -433,19 +471,31 @@ IQPlot::IQPlot(complex16 *data, int len) : data(data), len(len)
this->addAxis(this->axisY, Qt::AlignLeft); this->addAxis(this->axisY, Qt::AlignLeft);
this->series->attachAxis(this->axisY); this->series->attachAxis(this->axisY);
startTimer(1000); if (interval)
startTimer(interval);
if (plotUpdater)
connect(plotUpdater, &PlotUpdater::updatePlot, this, &IQPlot::updatePlot, Qt::QueuedConnection);
} }
void IQPlot::timerEvent(QTimerEvent *event) IQPlot::~IQPlot()
{
if (this->plotUpdater)
disconnect(this->plotUpdater, &PlotUpdater::updatePlot, this, &IQPlot::updatePlot);
}
void IQPlot::updatePlot(int len)
{ {
this->len = len;
if (!this->isVisible()) if (!this->isVisible())
return; return;
QVector<QPointF> points(this->len); QVector<QPointF> points(len);
int maxX = this->axisX->max(); int maxX = this->axisX->max();
int maxY = this->axisY->max(); int maxY = this->axisY->max();
for (int i = 0; i < this->len; i++) { for (int i = 0; i < len; i++) {
points[i] = QPointF(this->data[i].r, this->data[i].i); points[i] = QPointF(this->data[i].r, this->data[i].i);
maxX = std::max(maxX, abs(this->data[i].r)); maxX = std::max(maxX, abs(this->data[i].r));
...@@ -457,6 +507,11 @@ void IQPlot::timerEvent(QTimerEvent *event) ...@@ -457,6 +507,11 @@ void IQPlot::timerEvent(QTimerEvent *event)
this->series->replace(points); this->series->replace(points);
} }
void IQPlot::timerEvent(QTimerEvent *event)
{
this->updatePlot(this->len);
}
void IQPlotUE::timerEvent(QTimerEvent *event) void IQPlotUE::timerEvent(QTimerEvent *event)
{ {
if (!this->isVisible()) if (!this->isVisible())
...@@ -667,7 +722,10 @@ PainterWidgetGnb::PainterWidgetGnb(QWidget *config, QComboBox *comboBox, scopeDa ...@@ -667,7 +722,10 @@ PainterWidgetGnb::PainterWidgetGnb(QWidget *config, QComboBox *comboBox, scopeDa
this->plotType = PlotTypeGnb::empty; this->plotType = PlotTypeGnb::empty;
makeConnections(this->comboBox->currentIndex()); makeConnections(this->comboBox->currentIndex());
connect(this->comboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &PainterWidgetGnb::makeConnections); connect(this->comboBox,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this,
&PainterWidgetGnb::makeConnections);
} }
float PainterWidgetGnb::getValue() float PainterWidgetGnb::getValue()
...@@ -778,15 +836,13 @@ void PainterWidgetGnb::makeConnections(int type) ...@@ -778,15 +836,13 @@ void PainterWidgetGnb::makeConnections(int type)
} }
case PlotTypeGnb::puschLLR: { case PlotTypeGnb::puschLLR: {
int num_re = frame_parms->N_RB_UL * 12 * frame_parms->symbols_per_slot; int init_coded_bits_per_codeword = 100;
int Qm = 2; newChart = new LLRPlot((int16_t *)p->gNB->pusch_vars[0].llr, init_coded_bits_per_codeword, 0, &puschLlrUpdater);
int coded_bits_per_codeword = num_re * Qm;
newChart = new LLRPlot((int16_t *)p->gNB->pusch_vars[0].llr, coded_bits_per_codeword);
break; break;
} }
case PlotTypeGnb::puschIQ: { case PlotTypeGnb::puschIQ: {
int num_re = frame_parms->N_RB_UL * 12 * frame_parms->symbols_per_slot; int init_num_re = 100;
newChart = new IQPlot((complex16 *)p->gNB->pusch_vars[0].rxdataF_comp[0], num_re); newChart = new IQPlot((complex16 *)p->gNB->pusch_vars[0].rxdataF_comp[0], init_num_re, 0, &puschIqUpdater);
break; break;
} }
case PlotTypeGnb::puschSNR: { case PlotTypeGnb::puschSNR: {
...@@ -846,7 +902,8 @@ void PainterWidgetGnb::makeConnections(int type) ...@@ -846,7 +902,8 @@ void PainterWidgetGnb::makeConnections(int type)
/* @UE: This is the main function of the UE sub-widgets, i.e., for each KPI. This function will be called /* @UE: This is the main function of the UE sub-widgets, i.e., for each KPI. This function will be called
only once when the the sub-widget is created, and it mainly initializes the widget variables and structures. */ only once when the the sub-widget is created, and it mainly initializes the widget variables and structures. */
PainterWidgetUE::PainterWidgetUE(QWidget *config, QComboBox *comboBox, PHY_VARS_NR_UE *ue) : config(config), comboBox(comboBox), ue(ue) PainterWidgetUE::PainterWidgetUE(QWidget *config, QComboBox *comboBox, PHY_VARS_NR_UE *ue)
: config(config), comboBox(comboBox), ue(ue)
{ {
this->chartView = new QChartView(this); this->chartView = new QChartView(this);
this->chartView->hide(); this->chartView->hide();
...@@ -854,7 +911,10 @@ PainterWidgetUE::PainterWidgetUE(QWidget *config, QComboBox *comboBox, PHY_VARS_ ...@@ -854,7 +911,10 @@ PainterWidgetUE::PainterWidgetUE(QWidget *config, QComboBox *comboBox, PHY_VARS_
this->plotType = PlotTypeUE::empty; this->plotType = PlotTypeUE::empty;
makeConnections(this->comboBox->currentIndex()); makeConnections(this->comboBox->currentIndex());
connect(this->comboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &PainterWidgetUE::makeConnections); connect(this->comboBox,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this,
&PainterWidgetUE::makeConnections);
} }
float PainterWidgetUE::getValue() float PainterWidgetUE::getValue()
...@@ -891,7 +951,6 @@ float PainterWidgetUE::getValue() ...@@ -891,7 +951,6 @@ float PainterWidgetUE::getValue()
case PlotTypeUE::timingAdvance: case PlotTypeUE::timingAdvance:
return (float)this->ue->timing_advance; return (float)this->ue->timing_advance;
default: default:
return 0; return 0;
} }
...@@ -1240,6 +1299,7 @@ void nrgNBinitQtScope(scopeParms_t *p) ...@@ -1240,6 +1299,7 @@ void nrgNBinitQtScope(scopeParms_t *p)
scope->argc = p->argc; scope->argc = p->argc;
scope->argv = p->argv; scope->argv = p->argv;
scope->ru = p->ru; scope->ru = p->ru;
scope->scopeUpdater = scopeUpdaterGnb;
scope->copyData = copyData; scope->copyData = copyData;
copyDataMutexInit(scope); copyDataMutexInit(scope);
......
...@@ -94,11 +94,20 @@ class ValueProvider { ...@@ -94,11 +94,20 @@ class ValueProvider {
class ValueProviderUE : public ValueProvider { class ValueProviderUE : public ValueProvider {
public: public:
/// This pure virtual function is meant to provide the graph values to be plotted /// This pure virtual function is meant to provide the graph values to be plotted
virtual scopeGraphData_t *getPlotValue() { virtual scopeGraphData_t *getPlotValue()
{
return nullptr; return nullptr;
} }
}; };
/// Class for emitting a queued signal to update plots
class PlotUpdater : public QObject {
Q_OBJECT
signals:
void updatePlot(int numElt);
};
/// An editable GUI field for a dialog box to set certain KPI configurations /// An editable GUI field for a dialog box to set certain KPI configurations
class ConfigBoxFloat : public QLineEdit { class ConfigBoxFloat : public QLineEdit {
Q_OBJECT Q_OBJECT
...@@ -234,7 +243,9 @@ class CIRPlotUE : public CIRPlot { ...@@ -234,7 +243,9 @@ class CIRPlotUE : public CIRPlot {
Q_OBJECT Q_OBJECT
public: public:
CIRPlotUE(complex16 *data, int len, ValueProviderUE *valueProvider) : CIRPlot(data, len), valueProvider(valueProvider) {} CIRPlotUE(complex16 *data, int len, ValueProviderUE *valueProvider) : CIRPlot(data, len), valueProvider(valueProvider)
{
}
protected: protected:
/// This function is triggered when the own timer expires. It updates the plotted CIR /// This function is triggered when the own timer expires. It updates the plotted CIR
...@@ -253,10 +264,19 @@ class LLRPlot : public QChart { ...@@ -253,10 +264,19 @@ class LLRPlot : public QChart {
/// Constructor /// Constructor
/// \param data Pointer to the LLR data /// \param data Pointer to the LLR data
/// \param len Length of the LLR data /// \param len Length of the LLR data
LLRPlot(int16_t *data, int len); /// \param interval update interval in ms (0 means no timer-triggered updates)
/// \param plotUpdater pointer to a PlotUpdater for update notifications
LLRPlot(int16_t *data, int len, int interval = 1000, PlotUpdater *plotUpdater = nullptr);
/// Destructor
~LLRPlot();
public slots:
/// This function updates the plotted LLR
void updatePlot(int len);
protected: protected:
/// This function is triggered when the own timer expires. It updates the plotted LLR /// This function is triggered when the own timer expires. It calls updatePlot() to update the plotted LLR
/// \param event Pointer to the timer event /// \param event Pointer to the timer event
virtual void timerEvent(QTimerEvent *event) override; virtual void timerEvent(QTimerEvent *event) override;
...@@ -266,6 +286,9 @@ class LLRPlot : public QChart { ...@@ -266,6 +286,9 @@ class LLRPlot : public QChart {
/// Length of the LLR data /// Length of the LLR data
int len; int len;
/// Pointer to a PlotUpdater for update notifications
PlotUpdater *plotUpdater;
/// Scatter series used to plot the LLR in the chart /// Scatter series used to plot the LLR in the chart
QScatterSeries *series; QScatterSeries *series;
...@@ -280,7 +303,9 @@ class LLRPlotUE : public LLRPlot { ...@@ -280,7 +303,9 @@ class LLRPlotUE : public LLRPlot {
Q_OBJECT Q_OBJECT
public: public:
LLRPlotUE(int16_t *data, int len, ValueProviderUE *valueProvider) : LLRPlot(data, len), valueProvider(valueProvider) {} LLRPlotUE(int16_t *data, int len, ValueProviderUE *valueProvider) : LLRPlot(data, len), valueProvider(valueProvider)
{
}
protected: protected:
/// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram /// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram
...@@ -299,10 +324,19 @@ class IQPlot : public QChart { ...@@ -299,10 +324,19 @@ class IQPlot : public QChart {
/// Constructor /// Constructor
/// \param data Pointer to the complex I/Q data /// \param data Pointer to the complex I/Q data
/// \param len Length of the I/Q data /// \param len Length of the I/Q data
IQPlot(complex16 *data, int len); /// \param interval update interval in ms (0 means no timer-triggered updates)
/// \param plotUpdater pointer to a PlotUpdater for update notifications
IQPlot(complex16 *data, int len, int interval = 1000, PlotUpdater *plotUpdater = nullptr);
/// Destructor
~IQPlot();
public slots:
/// This function updates the plotted I/Q constellation diagram
void updatePlot(int len);
protected: protected:
/// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram /// This function is triggered when the own timer expires. It calls updatePlot() to update the plotted I/Q constellation diagram
/// \param event Pointer to the timer event /// \param event Pointer to the timer event
virtual void timerEvent(QTimerEvent *event) override; virtual void timerEvent(QTimerEvent *event) override;
...@@ -312,6 +346,9 @@ class IQPlot : public QChart { ...@@ -312,6 +346,9 @@ class IQPlot : public QChart {
/// Length of the I/Q data /// Length of the I/Q data
int len; int len;
/// Pointer to a PlotUpdater for update notifications
PlotUpdater *plotUpdater;
/// Scatter series used to plot the I/Q constellation diagram /// Scatter series used to plot the I/Q constellation diagram
QScatterSeries *series; QScatterSeries *series;
...@@ -326,7 +363,9 @@ class IQPlotUE : public IQPlot { ...@@ -326,7 +363,9 @@ class IQPlotUE : public IQPlot {
Q_OBJECT Q_OBJECT
public: public:
IQPlotUE(complex16 *data, int len, ValueProviderUE *valueProvider) : IQPlot(data, len), valueProvider(valueProvider) {} IQPlotUE(complex16 *data, int len, ValueProviderUE *valueProvider) : IQPlot(data, len), valueProvider(valueProvider)
{
}
protected: protected:
/// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram /// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram
......
...@@ -738,6 +738,18 @@ static void *scope_thread_gNB(void *arg) { ...@@ -738,6 +738,18 @@ static void *scope_thread_gNB(void *arg) {
} }
#endif #endif
static void scopeUpdaterGnb(enum PlotTypeGnbIf plotType, int numElt)
{
switch (plotType) {
case puschLLRe:
/* update PUSCH LLR plot */
break;
case puschIQe:
/* update PUSCH IQ plot */
break;
}
}
STATICFORXSCOPE void gNBinitScope(scopeParms_t *p) STATICFORXSCOPE void gNBinitScope(scopeParms_t *p)
{ {
AssertFatal(p->gNB->scopeData = calloc(sizeof(scopeData_t), 1), ""); AssertFatal(p->gNB->scopeData = calloc(sizeof(scopeData_t), 1), "");
...@@ -746,6 +758,7 @@ STATICFORXSCOPE void gNBinitScope(scopeParms_t *p) ...@@ -746,6 +758,7 @@ STATICFORXSCOPE void gNBinitScope(scopeParms_t *p)
scope->argv=p->argv; scope->argv=p->argv;
scope->ru=p->ru; scope->ru=p->ru;
scope->gNB=p->gNB; scope->gNB=p->gNB;
scope->scopeUpdater = scopeUpdaterGnb;
scope->copyData = copyData; scope->copyData = copyData;
#ifndef WEBSRVSCOPE #ifndef WEBSRVSCOPE
pthread_t forms_thread; pthread_t forms_thread;
......
...@@ -70,6 +70,11 @@ enum scopeDataType { ...@@ -70,6 +70,11 @@ enum scopeDataType {
MAX_SCOPE_TYPES MAX_SCOPE_TYPES
}; };
enum PlotTypeGnbIf {
puschLLRe,
puschIQe,
};
#define COPIES_MEM 4 #define COPIES_MEM 4
typedef struct { typedef struct {
...@@ -89,6 +94,7 @@ typedef struct scopeData_s { ...@@ -89,6 +94,7 @@ typedef struct scopeData_s {
pthread_mutex_t copyDataMutex; pthread_mutex_t copyDataMutex;
scopeGraphData_t *copyDataBufs[MAX_SCOPE_TYPES][COPIES_MEM]; scopeGraphData_t *copyDataBufs[MAX_SCOPE_TYPES][COPIES_MEM];
int copyDataBufsIdx[MAX_SCOPE_TYPES]; int copyDataBufsIdx[MAX_SCOPE_TYPES];
void (*scopeUpdater)(enum PlotTypeGnbIf plotType, int numElements);
} scopeData_t; } scopeData_t;
int load_softscope(char *exectype, void *initarg); int load_softscope(char *exectype, void *initarg);
...@@ -102,6 +108,9 @@ void copyData(void *, enum scopeDataType type, void *dataIn, int elementSz, int ...@@ -102,6 +108,9 @@ void copyData(void *, enum scopeDataType type, void *dataIn, int elementSz, int
#define gNBscopeCopy(gnb, type, ...) \ #define gNBscopeCopy(gnb, type, ...) \
if (gnb->scopeData) \ if (gnb->scopeData) \
((scopeData_t *)gnb->scopeData)->copyData((scopeData_t *)gNB->scopeData, type, ##__VA_ARGS__); ((scopeData_t *)gnb->scopeData)->copyData((scopeData_t *)gNB->scopeData, type, ##__VA_ARGS__);
#define GnbScopeUpdate(gnb, type, numElt) \
if (gnb->scopeData) \
((scopeData_t *)gnb->scopeData)->scopeUpdater(type, numElt);
extended_kpi_ue* getKPIUE(); extended_kpi_ue* getKPIUE();
......
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