Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wangwenhui
OpenXG-RAN
Commits
c4a91bcc
Commit
c4a91bcc
authored
Dec 29, 2020
by
Laurent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
scope, dirty replay
parent
0f3629ae
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
249 additions
and
97 deletions
+249
-97
executables/nr-ue.c
executables/nr-ue.c
+6
-5
openair1/PHY/TOOLS/nr_phy_scope.c
openair1/PHY/TOOLS/nr_phy_scope.c
+228
-91
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+4
-1
openair2/RRC/NR_UE/rrc_UE.c
openair2/RRC/NR_UE/rrc_UE.c
+5
-0
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+6
-0
No files found.
executables/nr-ue.c
View file @
c4a91bcc
...
...
@@ -745,14 +745,13 @@ void *UE_thread(void *arg) {
if
(
tmp
->
proc
.
decoded_frame_rx
!=
-
1
)
decoded_frame_rx
=
(((
mac
->
mib
->
systemFrameNumber
.
buf
[
0
]
>>
mac
->
mib
->
systemFrameNumber
.
bits_unused
)
<<
4
)
|
tmp
->
proc
.
decoded_frame_rx
);
//decoded_frame_rx=tmp->proc.decoded_frame_rx;
else
decoded_frame_rx
=-
1
;
pushNotifiedFIFO_nothreadSafe
(
&
freeBlocks
,
res
);
}
if
(
(
decoded_frame_rx
!=
curMsg
->
proc
.
frame_rx
)
&&
(((
decoded_frame_rx
+
1
)
%
MAX_FRAME_NUMBER
)
!=
curMsg
->
proc
.
frame_rx
)
&&
(((
decoded_frame_rx
+
2
)
%
MAX_FRAME_NUMBER
)
!=
curMsg
->
proc
.
frame_rx
))
if
(
decoded_frame_rx
>
0
&&
decoded_frame_rx
!=
curMsg
->
proc
.
frame_rx
)
LOG_E
(
PHY
,
"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode
\n
"
,
decoded_frame_rx
,
curMsg
->
proc
.
frame_rx
);
...
...
@@ -781,7 +780,7 @@ void *UE_thread(void *arg) {
msgToPush
->
key
=
slot_nr
;
pushTpool
(
Tpool
,
msgToPush
);
if
(
IS_SOFTMODEM_RFSIM
||
IS_SOFTMODEM_NOS1
)
{
//getenv("RFSIMULATOR")
if
(
getenv
(
"RFSIMULATOR"
)
||
IS_SOFTMODEM_RFSIM
||
IS_SOFTMODEM_NOS1
)
{
//getenv("RFSIMULATOR")
// FixMe: Wait previous thread is done, because race conditions seems too bad
// in case of actual RF board, the overlap between threads mitigate the issue
// We must receive one message, that proves the slot processing is done
...
...
@@ -791,6 +790,8 @@ void *UE_thread(void *arg) {
if
(
tmp
->
proc
.
decoded_frame_rx
!=
-
1
)
decoded_frame_rx
=
(((
mac
->
mib
->
systemFrameNumber
.
buf
[
0
]
>>
mac
->
mib
->
systemFrameNumber
.
bits_unused
)
<<
4
)
|
tmp
->
proc
.
decoded_frame_rx
);
else
decoded_frame_rx
=-
1
;
//decoded_frame_rx=tmp->proc.decoded_frame_rx;
pushNotifiedFIFO_nothreadSafe
(
&
freeBlocks
,
res
);
...
...
openair1/PHY/TOOLS/nr_phy_scope.c
View file @
c4a91bcc
...
...
@@ -30,16 +30,13 @@
#include <forms.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
}
;
int
otg_enabled
;
float
tput_time_enb
[
NUMBER_OF_UE_MAX
][
TPUT_WINDOW_LENGTH
]
=
{{
0
}};
float
tput_enb
[
NUMBER_OF_UE_MAX
][
TPUT_WINDOW_LENGTH
]
=
{{
0
}};
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
};
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
};
typedef
struct
{
int16_t
r
;
...
...
@@ -49,10 +46,17 @@ typedef struct {
typedef
struct
OAIgraph
{
FL_OBJECT
*
graph
;
FL_OBJECT
*
text
;
float
maxX
;
float
maxY
;
float
minX
;
float
minY
;
int
x
;
int
y
;
int
w
;
int
h
;
int
waterFallh
;
double
*
waterFallAvg
;
int
iteration
;
void
(
*
gNBfunct
)
(
struct
OAIgraph
*
graph
,
PHY_VARS_gNB
*
phy_vars_gnb
,
RU_t
*
phy_vars_ru
,
int
UE_id
);
void
(
*
nrUEfunct
)(
struct
OAIgraph
*
graph
,
PHY_VARS_NR_UE
*
phy_vars_ue
,
int
eNB_id
,
int
UE_id
);
...
...
@@ -94,38 +98,57 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
}
#endif
static
FL_OBJECT
*
commonGraph
(
int
type
,
FL_Coord
x
,
FL_Coord
y
,
FL_Coord
w
,
FL_Coord
h
,
const
char
*
label
,
FL_COLOR
pointColor
)
{
FL_OBJECT
*
graph
;
graph
=
fl_add_xyplot
(
type
,
x
,
y
,
w
,
h
,
label
);
fl_set_object_lcolor
(
graph
,
FL_WHITE
);
// Label color
fl_set_object_color
(
graph
,
FL_BLACK
,
pointColor
);
fl_set_xyplot_symbol
(
graph
,
-
1
,
drawsymbol
);
return
graph
;
#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
);
for
(
int
i
=
0
;
i
<
graph
->
waterFallh
;
i
++
)
graph
->
waterFallAvg
[
i
]
=
0
;
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
;
graph
->
iteration
=
0
;
}
static
OAIgraph_t
gNBcommonGraph
(
void
(
*
funct
)
(
OAIgraph_t
*
graph
,
PHY_VARS_gNB
*
phy_vars_gnb
,
RU_t
*
phy_vars_ru
,
int
UE_id
),
int
type
,
FL_Coord
x
,
FL_Coord
y
,
FL_Coord
w
,
FL_Coord
h
,
const
char
*
label
,
FL_COLOR
pointColor
)
{
OAIgraph_t
graph
;
graph
.
graph
=
commonGraph
(
type
,
x
,
y
,
w
,
h
,
label
,
pointColor
);
commonGraph
(
&
graph
,
type
,
x
,
y
,
w
,
h
,
label
,
pointColor
);
graph
.
gNBfunct
=
funct
;
graph
.
nrUEfunct
=
NULL
;
graph
.
maxX
=
0
;
graph
.
maxY
=
0
;
graph
.
minX
=
0
;
graph
.
minY
=
0
;
return
graph
;
}
static
OAIgraph_t
nrUEcommonGraph
(
void
(
*
funct
)
(
OAIgraph_t
*
graph
,
PHY_VARS_NR_UE
*
phy_vars_ue
,
int
eNB_id
,
int
UE_id
),
int
type
,
FL_Coord
x
,
FL_Coord
y
,
FL_Coord
w
,
FL_Coord
h
,
const
char
*
label
,
FL_COLOR
pointColor
)
{
OAIgraph_t
graph
;
graph
.
graph
=
commonGraph
(
type
,
x
,
y
,
w
,
h
,
label
,
pointColor
);
commonGraph
(
&
graph
,
type
,
x
,
y
,
w
,
h
,
label
,
pointColor
);
graph
.
gNBfunct
=
NULL
;
graph
.
nrUEfunct
=
funct
;
graph
.
maxX
=
0
;
graph
.
maxY
=
0
;
graph
.
minX
=
0
;
graph
.
minY
=
0
;
return
graph
;
}
...
...
@@ -140,11 +163,39 @@ static void setRange(OAIgraph_t *graph, float minX, float maxX, float minY, floa
}
}
static
void
oai_xygraph
(
OAIgraph_t
*
graph
,
float
*
x
,
float
*
y
,
int
len
,
int
layer
,
int
NoAutoScale
)
{
if
(
layer
==
0
)
fl_set_xyplot_data
(
graph
->
graph
,
x
,
y
,
len
,
""
,
""
,
""
);
else
fl_add_xyplot_overlay
(
graph
->
graph
,
layer
,
x
,
y
,
len
,
rx_antenna_colors
[
layer
]);
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
;
//LOG_E(HW,"enter oai_xygraph_getbuff, it=%d\n",graph->iteration);
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
);
if
(
NoAutoScale
&&
graph
->
iteration
%
NoAutoScale
==
0
)
{
float
maxX
=
0
,
maxY
=
0
,
minX
=
0
,
minY
=
0
;
...
...
@@ -156,46 +207,87 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye
minY
=
min
(
minY
,
y
[
k
]);
}
setRange
(
graph
,
minX
,
maxX
,
minY
,
maxY
);
setRange
(
graph
,
minX
-
5
,
maxX
+
5
,
minY
-
5
,
maxY
+
5
);
}
graph
->
iteration
++
;
}
static
void
genericWaterFall
(
OAIgraph_t
*
graph
,
scopeSample_t
*
values
,
const
int
datasize
)
{
fl_winset
(
FL_ObjWin
(
graph
->
graph
));
const
int
samplesPerPixel
=
datasize
/
graph
->
w
;
int
row
=
graph
->
iteration
%
(
graph
->
waterFallh
);
double
avg
=
0
;
for
(
int
i
=
0
;
i
<
graph
->
waterFallh
;
i
++
)
avg
+=
graph
->
waterFallAvg
[
i
];
avg
/=
graph
->
waterFallh
;
graph
->
waterFallAvg
[
row
]
=
0
;
for
(
int
pix
=
0
;
pix
<
graph
->
w
;
pix
++
)
{
scopeSample_t
*
end
=
values
+
(
pix
+
1
)
*
samplesPerPixel
;
end
-=
2
;
AssertFatal
(
end
<=
values
+
datasize
,
"diff : %ld"
,
end
-
values
+
datasize
);
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
;
fl_point
(
pix
,
graph
->
iteration
%
(
graph
->
waterFallh
),
water_colors
[
col
]);
}
fl_set_object_label_f
(
graph
->
text
,
"average I/Q module: %4.1f"
,
sqrt
(
avg
));
graph
->
iteration
++
;
}
static
void
genericLogPowerPerAntena
(
OAIgraph_t
*
graph
,
const
int
nb_ant
,
const
scopeSample_t
**
data
,
const
int
len
)
{
float
*
values
=
malloc
(
len
*
sizeof
(
*
values
))
;
float
*
time
=
malloc
(
len
*
sizeof
(
*
time
)
);
float
*
values
,
*
time
;
oai_xygraph_getbuff
(
graph
,
&
time
,
&
values
,
len
,
0
);
for
(
int
ant
=
0
;
ant
<
nb_ant
;
ant
++
)
{
if
(
data
[
ant
]
!=
NULL
)
{
float
*
values
,
*
time
;
oai_xygraph_getbuff
(
graph
,
&
time
,
&
values
,
len
,
ant
);
for
(
int
i
=
0
;
i
<
len
;
i
+=
8
)
{
float
*
vals
=
values
+
i
;
float
*
tim
=
time
+
i
;
const
scopeSample_t
*
in
=&
(
data
[
ant
][
i
]);
// TRY AUTOMATIC simd BY GCC
for
(
int
k
=
0
;
k
<
8
;
k
++
)
{
vals
[
k
]
=
10
*
log10
(
1
.
0
+
SquaredNorm
(
in
[
k
]));
tim
[
k
]
=
i
+
k
;
}
}
oai_xygraph
(
graph
,
time
,
values
,
len
,
ant
,
10
);
}
}
free
(
values
);
free
(
time
);
}
static
void
genericPowerPerAntena
(
OAIgraph_t
*
graph
,
const
int
nb_ant
,
const
scopeSample_t
**
data
,
const
int
len
)
{
float
values
[
len
]
;
float
time
[
len
]
;
float
*
values
,
*
time
;
oai_xygraph_getbuff
(
graph
,
&
time
,
&
values
,
len
,
0
)
;
for
(
int
ant
=
0
;
ant
<
nb_ant
;
ant
++
)
{
if
(
data
[
ant
]
!=
NULL
)
{
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
values
[
i
]
=
SquaredNorm
(
data
[
ant
][
i
]);
time
[
i
]
=
i
;
}
oai_xygraph
(
graph
,
time
,
values
,
len
,
ant
,
10
);
...
...
@@ -203,6 +295,13 @@ static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const sc
}
}
static
void
gNBWaterFall
(
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
;
//use 1st antenna
genericWaterFall
(
graph
,
(
scopeSample_t
*
)
phy_vars_ru
->
common
.
rxdata
[
0
],
frame_parms
->
samples_per_frame
);
}
/* replaced by waterfall
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)
...
...
@@ -213,11 +312,12 @@ static void timeSignal (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy
(const scopeSample_t **)phy_vars_ru->common.rxdata,
frame_parms->samples_per_frame);
}
*/
static
void
timeResponse
(
OAIgraph_t
*
graph
,
PHY_VARS_gNB
*
phy_vars_gnb
,
RU_t
*
phy_vars_ru
,
int
nb_UEs
)
{
const
int
len
=
2
*
phy_vars_gnb
->
frame_parms
.
ofdm_symbol_size
;
float
values
[
len
]
;
float
time
[
len
]
;
float
*
values
,
*
time
;
oai_xygraph_getbuff
(
graph
,
&
time
,
&
values
,
len
,
0
)
;
const
int
ant
=
0
;
// display antenna 0 for each UE
for
(
int
ue
=
0
;
ue
<
nb_UEs
;
ue
++
)
{
...
...
@@ -226,7 +326,6 @@ static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *p
if
(
data
!=
NULL
)
{
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
values
[
i
]
=
SquaredNorm
(
data
[
i
]);
time
[
i
]
=
i
;
}
oai_xygraph
(
graph
,
time
,
values
,
len
,
ue
,
10
);
...
...
@@ -234,26 +333,33 @@ static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *p
}
}
static
void
gNBfreqWaterFall
(
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
;
//use 1st antenna
genericWaterFall
(
graph
,
(
scopeSample_t
*
)
phy_vars_ru
->
common
.
rxdataF
[
0
],
frame_parms
->
samples_per_frame_wCP
);
}
/*
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);
}
*/
static
void
puschLLR
(
OAIgraph_t
*
graph
,
PHY_VARS_gNB
*
phy_vars_gnb
,
RU_t
*
phy_vars_ru
,
int
nb_UEs
)
{
//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;
float
llr
[
coded_bits_per_codeword
];
float
bit
[
coded_bits_per_codeword
];
for
(
int
ue
=
0
;
ue
<
nb_UEs
;
ue
++
)
{
int16_t
*
pusch_llr
=
(
int16_t
*
)
phy_vars_gnb
->
pusch_vars
[
ue
]
->
llr
;
float
*
llr
,
*
bit
;
oai_xygraph_getbuff
(
graph
,
&
bit
,
&
llr
,
coded_bits_per_codeword
,
ue
);
if
(
pusch_llr
)
{
for
(
int
i
=
0
;
i
<
coded_bits_per_codeword
;
i
++
)
{
llr
[
i
]
=
(
float
)
pusch_llr
[
i
];
bit
[
i
]
=
(
float
)
i
;
}
oai_xygraph
(
graph
,
bit
,
llr
,
coded_bits_per_codeword
,
ue
,
10
);
...
...
@@ -264,10 +370,11 @@ static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_v
static
void
puschIQ
(
OAIgraph_t
*
graph
,
PHY_VARS_gNB
*
phy_vars_gnb
,
RU_t
*
phy_vars_ru
,
int
nb_UEs
)
{
NR_DL_FRAME_PARMS
*
frame_parms
=&
phy_vars_gnb
->
frame_parms
;
int
sz
=
frame_parms
->
N_RB_UL
*
12
*
frame_parms
->
symbols_per_slot
;
float
I
[
sz
],
Q
[
sz
];
for
(
int
ue
=
0
;
ue
<
nb_UEs
;
ue
++
)
{
scopeSample_t
*
pusch_comp
=
(
scopeSample_t
*
)
phy_vars_gnb
->
pusch_vars
[
ue
]
->
rxdataF_comp
[
0
];
float
*
I
,
*
Q
;
oai_xygraph_getbuff
(
graph
,
&
I
,
&
Q
,
sz
,
ue
);
if
(
pusch_comp
)
{
for
(
int
k
=
0
;
k
<
sz
;
k
++
)
{
...
...
@@ -312,6 +419,9 @@ static void pucchIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_va
static
void
puschThroughtput
(
OAIgraph_t
*
graph
,
PHY_VARS_gNB
*
phy_vars_gnb
,
RU_t
*
phy_vars_ru
,
int
nb_UEs
)
{
// PUSCH Throughput
/*
float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
float tput_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
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;
...
...
@@ -332,18 +442,18 @@ static OAI_phy_scope_t *create_phy_scope_gnb(void) {
fl_set_object_color
(
obj
,
FL_BLACK
,
FL_WHITE
);
int
curY
=
0
,
x
,
y
,
w
,
h
;
// Received signal
fdui
->
graph
[
0
]
=
gNBcommonGraph
(
timeSignal
,
FL_NORMAL_XYPLOT
,
0
,
curY
,
400
,
100
,
"Received Signal (Time-Domain,
dB
)"
,
FL_RED
);
fdui
->
graph
[
0
]
=
gNBcommonGraph
(
gNBWaterFall
,
WATERFALL
,
0
,
curY
,
400
,
100
,
"Received Signal (Time-Domain,
one frame
)"
,
FL_RED
);
// Time-domain channel response
fdui
->
graph
[
1
]
=
gNBcommonGraph
(
timeResponse
,
FL_NORMAL_XYPLOT
,
410
,
curY
,
400
,
100
,
"SRS Frequency Response (samples, abs)"
,
FL_RED
);
fl_get_object_bbox
(
fdui
->
graph
[
0
].
graph
,
&
x
,
&
y
,
&
w
,
&
h
);
fl_get_object_bbox
(
fdui
->
graph
[
1
].
graph
,
&
x
,
&
y
,
&
w
,
&
h
);
curY
+=
h
;
// Frequency-domain channel response
fdui
->
graph
[
2
]
=
gNBcommonGraph
(
frequencyResponse
,
FL_NORMAL_XYPLOT
,
0
,
curY
,
800
,
100
,
"Channel Frequency
Response (RE, dB
)"
,
FL_RED
);
fdui
->
graph
[
2
]
=
gNBcommonGraph
(
gNBfreqWaterFall
,
WATERFALL
,
0
,
curY
,
800
,
100
,
"Channel Frequency
domain (RE, one frame
)"
,
FL_RED
);
fl_get_object_bbox
(
fdui
->
graph
[
2
].
graph
,
&
x
,
&
y
,
&
w
,
&
h
);
curY
+=
h
;
curY
+=
h
+
15
;
// LLR of PUSCH
fdui
->
graph
[
3
]
=
gNBcommonGraph
(
puschLLR
,
FL_POINTS_XYPLOT
,
0
,
curY
,
500
,
200
,
"PUSCH Log-Likelihood Ratios (LLR, mag)"
,
FL_YELLOW
);
...
...
@@ -376,14 +486,15 @@ void phy_scope_gNB(OAI_phy_scope_t *form,
PHY_VARS_gNB
*
phy_vars_gnb
,
RU_t
*
phy_vars_ru
,
int
UE_id
)
{
static
OAI_phy_scope_t
*
remeberForm
=
NULL
;
static
OAI_phy_scope_t
*
reme
m
berForm
=
NULL
;
if
(
form
==
NULL
)
form
=
remeberForm
;
form
=
reme
m
berForm
;
else
remeberForm
=
form
;
reme
m
berForm
=
form
;
if
(
form
==
NULL
)
return
;
if
(
form
==
NULL
)
return
;
int
i
=
0
;
...
...
@@ -392,7 +503,7 @@ void phy_scope_gNB(OAI_phy_scope_t *form,
i
++
;
}
fl_check_forms
();
//
fl_check_forms();
}
static
void
*
scope_thread_gNB
(
void
*
arg
)
{
...
...
@@ -406,7 +517,9 @@ static void *scope_thread_gNB(void *arg) {
pthread_attr_getstacksize
(
&
atr
,
&
stksize
);
pthread_attr_setstacksize
(
&
atr
,
32
*
1024
*
1024
);
sleep
(
3
);
// no clean interthread barriers
fl_initialize
(
p
->
argc
,
p
->
argv
,
NULL
,
0
,
0
);
int
fl_argc
=
1
;
char
*
name
=
"5G-gNB-scope"
;
fl_initialize
(
&
fl_argc
,
&
name
,
NULL
,
0
,
0
);
int
nb_ue
=
min
(
NUMBER_OF_UE_MAX
,
scope_enb_num_ue
);
OAI_phy_scope_t
*
form_gnb
=
create_phy_scope_gnb
();
...
...
@@ -425,12 +538,21 @@ void gNBinitScope(scopeParms_t *p) {
threadCreate
(
&
forms_thread
,
scope_thread_gNB
,
&
parms
,
"scope"
,
-
1
,
OAI_PRIORITY_RT_LOW
);
}
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
],
phy_vars_ue
->
frame_parms
.
samples_per_frame
);
}
/* replaced by waterfall
static void ueTimeResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// Received signal in time domain of receive antenna 0
genericLogPowerPerAntena(graph, phy_vars_ue->frame_parms.nb_antennas_rx,
(const scopeSample_t **) phy_vars_ue->common_vars.rxdata,
phy_vars_ue->frame_parms.samples_per_frame);
}
*/
static
void
ueChannelResponse
(
OAIgraph_t
*
graph
,
PHY_VARS_NR_UE
*
phy_vars_ue
,
int
eNB_id
,
int
UE_id
)
{
// Channel Impulse Response
...
...
@@ -439,6 +561,15 @@ static void ueChannelResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue,
phy_vars_ue
->
frame_parms
.
ofdm_symbol_size
>>
3
);
}
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
],
frame_parms
->
samples_per_slot_wCP
);
}
/*
static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// Channel Frequency Response (includes 5 complex sample for filter)
if (!phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates)
...
...
@@ -449,12 +580,13 @@ static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue
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
]
;
float
*freq, *chest_f_abs
;
oai_xygraph_getbuff(graph, &freq, &chest_f_abs, frame_parms->ofdm_symbol_size, 0)
;
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]));
...
...
@@ -471,6 +603,7 @@ static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue
//fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10);
}
*/
static
void
uePbchLLR
(
OAIgraph_t
*
graph
,
PHY_VARS_NR_UE
*
phy_vars_ue
,
int
eNB_id
,
int
UE_id
)
{
// PBCH LLRs
...
...
@@ -478,11 +611,11 @@ static void uePbchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
return
;
int16_t
*
pbch_llr
=
(
int16_t
*
)
phy_vars_ue
->
pbch_vars
[
eNB_id
]
->
llr
;
float
llr_pbch
[
864
],
bit_pbch
[
864
];
float
*
llr_pbch
,
*
bit_pbch
;
oai_xygraph_getbuff
(
graph
,
&
bit_pbch
,
&
llr_pbch
,
864
,
0
);
for
(
int
i
=
0
;
i
<
864
;
i
++
)
{
llr_pbch
[
i
]
=
(
float
)
pbch_llr
[
i
];
bit_pbch
[
i
]
=
(
float
)
i
;
}
oai_xygraph
(
graph
,
bit_pbch
,
llr_pbch
,
864
,
0
,
10
);
...
...
@@ -494,8 +627,8 @@ static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
return
;
scopeSample_t
*
pbch_comp
=
(
scopeSample_t
*
)
phy_vars_ue
->
pbch_vars
[
eNB_id
]
->
rxdataF_comp
[
0
];
localBuff
(
I
,
180
*
3
)
;
localBuff
(
Q
,
180
*
3
);
float
*
I
,
*
Q
;
oai_xygraph_getbuff
(
graph
,
&
I
,
&
Q
,
180
*
3
,
0
);
int
first_symbol
=
1
;
int
base
=
0
;
...
...
@@ -517,6 +650,7 @@ static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
base
+=
nb_re
;
}
AssertFatal
(
base
<=
180
*
3
,
""
);
oai_xygraph
(
graph
,
I
,
Q
,
base
,
0
,
10
);
}
...
...
@@ -528,8 +662,8 @@ static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
int
num_re
=
4
*
273
*
12
;
// 12*frame_parms->N_RB_DL*num_pdcch_symbols
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
);
float
*
llr
,
*
bit
;
oai_xygraph_getbuff
(
graph
,
&
bit
,
&
llr
,
coded_bits_per_codeword
*
RX_NB_TH_MAX
,
0
);
int
base
=
0
;
for
(
int
thr
=
0
;
thr
<
RX_NB_TH_MAX
;
thr
++
)
{
...
...
@@ -537,12 +671,12 @@ static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
for
(
int
i
=
0
;
i
<
coded_bits_per_codeword
;
i
++
)
{
llr
[
base
+
i
]
=
(
float
)
pdcch_llr
[
i
];
bit
[
base
+
i
]
=
(
float
)
base
+
i
;
}
base
+=
coded_bits_per_codeword
;
}
AssertFatal
(
base
<=
coded_bits_per_codeword
*
RX_NB_TH_MAX
,
""
);
oai_xygraph
(
graph
,
bit
,
llr
,
base
,
0
,
10
);
}
...
...
@@ -552,8 +686,8 @@ static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
return
;
int
nb
=
4
*
273
*
12
;
// 12*frame_parms->N_RB_DL*num_pdcch_symbols
localBuff
(
I
,
nb
*
RX_NB_TH_MAX
)
;
localBuff
(
Q
,
nb
*
RX_NB_TH_MAX
);
float
*
I
,
*
Q
;
oai_xygraph_getbuff
(
graph
,
&
I
,
&
Q
,
nb
*
RX_NB_TH_MAX
,
0
);
int
base
=
0
;
for
(
int
thr
=
0
;
thr
<
RX_NB_TH_MAX
;
thr
++
)
{
...
...
@@ -567,6 +701,7 @@ static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
base
+=
nb
;
}
AssertFatal
(
base
<=
nb
*
RX_NB_TH_MAX
,
""
);
oai_xygraph
(
graph
,
I
,
Q
,
base
,
0
,
10
);
}
...
...
@@ -578,8 +713,8 @@ static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB
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
);
float
*
llr
,
*
bit
;
oai_xygraph_getbuff
(
graph
,
&
bit
,
&
llr
,
coded_bits_per_codeword
*
RX_NB_TH_MAX
,
0
);
int
base
=
0
;
for
(
int
thr
=
0
;
thr
<
RX_NB_TH_MAX
;
thr
++
)
{
...
...
@@ -593,6 +728,7 @@ static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB
base
+=
coded_bits_per_codeword
;
}
AssertFatal
(
base
<=
coded_bits_per_codeword
*
RX_NB_TH_MAX
,
""
);
//fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword);
oai_xygraph
(
graph
,
bit
,
llr
,
base
,
0
,
10
);
}
...
...
@@ -604,9 +740,11 @@ static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
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
);
float
*
I
,
*
Q
;
oai_xygraph_getbuff
(
graph
,
&
I
,
&
Q
,
sz
*
RX_NB_TH_MAX
,
0
);
int
base
=
0
;
memset
(
I
+
base
,
0
,
sz
*
RX_NB_TH_MAX
*
sizeof
(
*
I
));
memset
(
Q
+
base
,
0
,
sz
*
RX_NB_TH_MAX
*
sizeof
(
*
Q
));
for
(
int
thr
=
0
;
thr
<
RX_NB_TH_MAX
;
thr
++
)
{
scopeSample_t
*
pdsch_comp
=
(
scopeSample_t
*
)
phy_vars_ue
->
pdsch_vars
[
thr
][
eNB_id
]
->
rxdataF_comp0
[
0
];
...
...
@@ -619,11 +757,16 @@ static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
base
+=
sz
;
}
oai_xygraph
(
graph
,
I
,
Q
,
base
,
0
,
10
);
AssertFatal
(
base
<=
sz
*
RX_NB_TH_MAX
,
""
);
oai_xygraph
(
graph
,
I
,
Q
,
sz
*
RX_NB_TH_MAX
,
0
,
10
);
}
static
void
uePdschThroughput
(
OAIgraph_t
*
graph
,
PHY_VARS_NR_UE
*
phy_vars_ue
,
int
eNB_id
,
int
UE_id
)
{
/*
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};
// PDSCH Throughput
memmove( tput_time_ue[UE_id], &tput_time_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
...
...
@@ -652,18 +795,18 @@ static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
fl_set_object_color
(
obj
,
FL_BLACK
,
FL_BLACK
);
int
curY
=
0
,
x
,
y
,
w
,
h
;
// Received signal
fdui
->
graph
[
0
]
=
nrUEcommonGraph
(
ue
TimeResponse
,
FL_NORMAL_XYPLOT
,
0
,
curY
,
400
,
100
,
"Received Signal (Time-Domain, dB
)"
,
FL_RED
);
fdui
->
graph
[
0
]
=
nrUEcommonGraph
(
ue
WaterFall
,
WATERFALL
,
0
,
curY
,
400
,
100
,
"Received Signal (Time-Domain, one frame
)"
,
FL_RED
);
// Time-domain channel response
fdui
->
graph
[
1
]
=
nrUEcommonGraph
(
ueChannelResponse
,
FL_NORMAL_XYPLOT
,
400
,
curY
,
400
,
100
,
"Channel Impulse Response (samples, abs)"
,
FL_RED
);
fl_get_object_bbox
(
fdui
->
graph
[
0
].
graph
,
&
x
,
&
y
,
&
w
,
&
h
);
fl_get_object_bbox
(
fdui
->
graph
[
1
].
graph
,
&
x
,
&
y
,
&
w
,
&
h
);
curY
+=
h
;
// Frequency-domain channel response
fdui
->
graph
[
2
]
=
nrUEcommonGraph
(
ue
PbchFrequencyResp
,
FL_IMPULSE_XYPLOT
,
0
,
curY
,
800
,
100
,
"Channel Frequency data (RE, dB
)"
,
FL_RED
);
fdui
->
graph
[
2
]
=
nrUEcommonGraph
(
ue
FreqWaterFall
,
WATERFALL
,
0
,
curY
,
800
,
100
,
"Channel Frequency (RE, one slot
)"
,
FL_RED
);
fl_get_object_bbox
(
fdui
->
graph
[
2
].
graph
,
&
x
,
&
y
,
&
w
,
&
h
);
curY
+=
h
;
curY
+=
h
+
15
;
// LLR of PBCH
fdui
->
graph
[
3
]
=
nrUEcommonGraph
(
uePbchLLR
,
FL_POINTS_XYPLOT
,
0
,
curY
,
500
,
100
,
"PBCH Log-Likelihood Ratios (LLR, mag)"
,
FL_GREEN
);
...
...
@@ -733,7 +876,7 @@ void phy_scope_nrUE(OAI_phy_scope_t *form,
i
++
;
}
fl_check_forms
();
//
fl_check_forms();
}
...
...
@@ -766,11 +909,11 @@ void nrUEinitScope(PHY_VARS_NR_UE *ue) {
void
nrscope_autoinit
(
void
*
dataptr
)
{
AssertFatal
(
(
IS_SOFTMODEM_GNB_BIT
||
IS_SOFTMODEM_5GUE_BIT
),
"Scope cannot find NRUE or GNB context"
);
if
(
IS_SOFTMODEM_GNB_BIT
)
gNBinitScope
(
dataptr
);
gNBinitScope
(
dataptr
);
else
nrUEinitScope
(
dataptr
);
nrUEinitScope
(
dataptr
);
}
// Kept to put back the functionality soon
#if 0
...
...
@@ -799,8 +942,6 @@ static void reset_stats_gNB(FL_OBJECT *button,
}
}
static FD_stats_form *create_form_stats_form(int ID) {
FL_OBJECT *obj;
FD_stats_form *fdui = calloc(( sizeof *fdui ),1);
...
...
@@ -820,7 +961,3 @@ static FD_stats_form *create_form_stats_form(int ID) {
return fdui;
}
#endif
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
View file @
c4a91bcc
...
...
@@ -1236,7 +1236,10 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
rx_ind
.
rx_indication_body
[
0
].
pdsch_pdu
.
pdu
=
dlsch0
->
harq_processes
[
harq_pid
]
->
b
;
rx_ind
.
rx_indication_body
[
0
].
pdsch_pdu
.
pdu_length
=
dlsch0
->
harq_processes
[
harq_pid
]
->
TBS
>>
3
;
LOG_D
(
PHY
,
"PDU length in bits: %d, in bytes: %d
\n
"
,
dlsch0
->
harq_processes
[
harq_pid
]
->
TBS
,
rx_ind
.
rx_indication_body
[
0
].
pdsch_pdu
.
pdu_length
);
LOG_W
(
PHY
,
"PDU length in bits: %d, in bytes: %d
\n
"
,
dlsch0
->
harq_processes
[
harq_pid
]
->
TBS
,
rx_ind
.
rx_indication_body
[
0
].
pdsch_pdu
.
pdu_length
);
for
(
int
i
=
0
;
i
<
rx_ind
.
rx_indication_body
[
0
].
pdsch_pdu
.
pdu_length
;
i
++
)
printf
(
"%x:"
,
dlsch0
->
harq_processes
[
harq_pid
]
->
b
[
i
]);
printf
(
"ret: %d
\n
"
,
ret
);
rx_ind
.
number_pdus
=
1
;
// send to mac
...
...
openair2/RRC/NR_UE/rrc_UE.c
View file @
c4a91bcc
...
...
@@ -1499,7 +1499,12 @@ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index
SEQUENCE_free
(
&
asn_DEF_NR_BCCH_BCH_Message
,
(
void
*
)
sib1
,
1
);
}
sib1
=
bcch_message
->
message
.
choice
.
c1
->
choice
.
systemInformationBlockType1
;
if
(
*
(
int64_t
*
)
sib1
!=
1
)
{
printf
(
"%llx
\n
"
,
*
(
int64_t
*
)
sib1
);
xer_fprint
(
stdout
,
&
asn_DEF_NR_SIB1
,
(
const
void
*
)
sib1
);
}
else
LOG_E
(
PHY
,
"sib1 is starting by 8 times 0
\n
"
);
}
return
0
;
...
...
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
View file @
c4a91bcc
...
...
@@ -657,6 +657,12 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
}
if
(
samples_received
==
nsamps
)
s
->
wait_for_first_pps
=
0
;
}
if
(
getenv
(
"recorded"
)
)
{
static
int
h
=-
1
;
if
(
h
==-
1
)
h
=
open
(
getenv
(
"recorded"
),
O_RDONLY
,
0
);
read
(
h
,
buff_tmp
[
0
],
nsamps
*
4
);
}
// bring RX data into 12 LSBs for softmodem RX
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment