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
cedde4ad
Commit
cedde4ad
authored
Dec 26, 2016
by
laurent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
realtime for UE
parent
3bf8768d
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1324 additions
and
2075 deletions
+1324
-2075
common/utils/itti/assertions.h
common/utils/itti/assertions.h
+1
-1
openair1/PHY/defs.h
openair1/PHY/defs.h
+3
-0
openair2/COMMON/platform_types.h
openair2/COMMON/platform_types.h
+1
-1
openair2/UTIL/LOG/log.h
openair2/UTIL/LOG/log.h
+20
-0
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+412
-569
targets/RT/USER/lte-ue.c
targets/RT/USER/lte-ue.c
+887
-1504
No files found.
common/utils/itti/assertions.h
View file @
cedde4ad
...
...
@@ -65,7 +65,7 @@ _Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3)
#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \
_Assert_(cOND, _Assert_Exit_, #vALUE1": %"
PRIdMAX"\n"#vALUE2": %"PRIdMAX"\n"#vALUE3": %"PRIdMAX"\n"#vALUE4": %"PRIdMAX
"\n\n", \
_Assert_(cOND, _Assert_Exit_, #vALUE1": %"
PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX
"\n\n", \
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4)
#define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3)
...
...
openair1/PHY/defs.h
View file @
cedde4ad
...
...
@@ -371,6 +371,9 @@ typedef struct {
pthread_mutex_t
mutex_rxtx
;
/// scheduling parameters for RXn-TXnp4 thread
struct
sched_param
sched_param_rxtx
;
int
sub_frame_start
;
int
sub_frame_step
;
unsigned
long
long
gotIQs
;
}
UE_rxtx_proc_t
;
/// Context data structure for eNB subframe processing
...
...
openair2/COMMON/platform_types.h
View file @
cedde4ad
...
...
@@ -255,7 +255,7 @@ typedef struct protocol_ctxt_s {
(Ctxt_Pp)->subframe = sUBfRAME; \
PROTOCOL_CTXT_COMPUTE_MODULE_ID(Ctxt_Pp)
#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %"
PRIx16
"]"
#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %"
PRIx16
"]"
#define PROTOCOL_CTXT_ARGS(CTXT_Pp) \
(CTXT_Pp)->frame, \
((CTXT_Pp)->enb_flag == ENB_FLAG_YES) ? "eNB":" UE", \
...
...
openair2/UTIL/LOG/log.h
View file @
cedde4ad
...
...
@@ -53,6 +53,26 @@
extern
"C"
{
#endif
extern
double
cpuf
;
static
inline
unsigned
long
long
rdtsc
(
void
)
{
unsigned
long
long
a
,
d
;
__asm__
volatile
(
"rdtsc"
:
"=a"
(
a
),
"=d"
(
d
));
return
(
d
<<
32
)
|
a
;
}
static
inline
unsigned
long
long
checkT
(
int
timeout
,
char
*
file
,
int
line
)
{
static
unsigned
long
long
__thread
last
=
0
;
unsigned
long
long
cur
=
rdtsc
();
int
microCycles
=
(
int
)(
cpuf
*
1000
);
int
duration
=
(
int
)((
cur
-
last
)
/
microCycles
);
if
(
last
!=
0
&&
duration
>
timeout
)
printf
(
"%s:%d lte-ue delay %d (exceed %d)
\n
"
,
file
,
line
,
duration
,
timeout
);
last
=
cur
;
return
cur
;
}
#define check(a) checkT(a,__FILE__,__LINE__)
/** @defgroup _LOG LOG Generator
* @{*/
/* @}*/
...
...
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
View file @
cedde4ad
...
...
@@ -40,10 +40,12 @@
#include <time.h>
#include "UTIL/LOG/log_extern.h"
#include "common_lib.h"
#include "assertions.h"
#ifdef __SSE4_1__
# include <smmintrin.h>
#endif
#ifdef __AVX2__
# include <immintrin.h>
#endif
...
...
@@ -56,16 +58,14 @@
* @{
*/
/*! \brief USRP Configuration */
typedef
struct
{
/*! \brief USRP Configuration */
typedef
struct
{
// --------------------------------
// variables for USRP configuration
// --------------------------------
//! USRP device pointer
uhd
::
usrp
::
multi_usrp
::
sptr
usrp
;
//uhd::usrp::multi_usrp::sptr rx_usrp;
// --------------------------------
// variables for USRP configuration
// --------------------------------
//! USRP device pointer
uhd
::
usrp
::
multi_usrp
::
sptr
usrp
;
//create a send streamer and a receive streamer
//! USRP TX Stream
...
...
@@ -78,141 +78,93 @@ typedef struct
//! USRP RX Metadata
uhd
::
rx_metadata_t
rx_md
;
//! USRP Timestamp Information
uhd
::
time_spec_t
tm_spec
;
//setup variables and allocate buffer
//! USRP Metadata
uhd
::
async_metadata_t
async_md
;
//! Sampling rate
double
sample_rate
;
//! Sampling rat
e
double
sample_rate
;
//! TX forward samples. We use usrp_time_offset to get this valu
e
int
tx_forward_nsamps
;
//166 for 20Mhz
//! time offset between transmiter timestamp and receiver timestamp;
double
tdiff
;
//! TX forward samples. We use usrp_time_offset to get this value
int
tx_forward_nsamps
;
//166 for 20Mhz
// --------------------------------
// Debug and output control
// --------------------------------
int
num_underflows
;
int
num_overflows
;
int
num_seq_errors
;
int64_t
tx_count
;
int64_t
rx_count
;
//! timestamp of RX packet
openair0_timestamp
rx_timestamp
;
}
usrp_state_t
;
// --------------------------------
// Debug and output control
// --------------------------------
//! Number of underflows
int
num_underflows
;
//! Number of overflows
int
num_overflows
;
//! Number of sequential errors
int
num_seq_errors
;
//! tx count
int64_t
tx_count
;
//! rx count
int64_t
rx_count
;
//! timestamp of RX packet
openair0_timestamp
rx_timestamp
;
}
usrp_state_t
;
/*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error
@param device pointer to the device structure specific to the RF hardware target
*/
static
int
trx_usrp_start
(
openair0_device
*
device
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
static
int
trx_usrp_start
(
openair0_device
*
device
)
{
// init recv and send streaming
uhd
::
stream_cmd_t
cmd
(
uhd
::
stream_cmd_t
::
STREAM_MODE_START_CONTINUOUS
);
cmd
.
time_spec
=
s
->
usrp
->
get_time_now
()
+
uhd
::
time_spec_t
(
0.05
);
cmd
.
stream_now
=
false
;
// start at constant delay
s
->
rx_stream
->
issue_stream_cmd
(
cmd
);
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
s
->
tx_md
.
time_spec
=
cmd
.
time_spec
+
uhd
::
time_spec_t
(
1
-
(
double
)
s
->
tx_forward_nsamps
/
s
->
sample_rate
);
s
->
tx_md
.
has_time_spec
=
true
;
s
->
tx_md
.
start_of_burst
=
true
;
s
->
tx_md
.
end_of_burst
=
false
;
// init recv and send streaming
uhd
::
stream_cmd_t
cmd
(
uhd
::
stream_cmd_t
::
STREAM_MODE_START_CONTINUOUS
);
cmd
.
time_spec
=
s
->
usrp
->
get_time_now
()
+
uhd
::
time_spec_t
(
0.05
);
cmd
.
stream_now
=
true
;
s
->
rx_stream
->
issue_stream_cmd
(
cmd
);
s
->
tx_md
.
time_spec
=
cmd
.
time_spec
+
uhd
::
time_spec_t
(
1
-
(
double
)
s
->
tx_forward_nsamps
/
s
->
sample_rate
);
s
->
tx_md
.
has_time_spec
=
true
;
s
->
tx_md
.
start_of_burst
=
true
;
s
->
tx_md
.
end_of_burst
=
false
;
s
->
rx_count
=
0
;
s
->
tx_count
=
0
;
s
->
rx_timestamp
=
0
;
return
0
;
s
->
rx_count
=
0
;
s
->
tx_count
=
0
;
s
->
rx_timestamp
=
0
;
return
0
;
}
/*! \brief Terminate operation of the USRP transceiver -- free all associated resources
* \param device the hardware to use
*/
static
void
trx_usrp_end
(
openair0_device
*
device
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
static
void
trx_usrp_end
(
openair0_device
*
device
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
s
->
rx_stream
->
issue_stream_cmd
(
uhd
::
stream_cmd_t
::
STREAM_MODE_STOP_CONTINUOUS
);
s
->
rx_stream
->
issue_stream_cmd
(
uhd
::
stream_cmd_t
::
STREAM_MODE_STOP_CONTINUOUS
);
//send a mini EOB packet
s
->
tx_md
.
end_of_burst
=
true
;
s
->
tx_stream
->
send
(
""
,
0
,
s
->
tx_md
);
s
->
tx_md
.
end_of_burst
=
false
;
//send a mini EOB packet
s
->
tx_md
.
end_of_burst
=
true
;
s
->
tx_stream
->
send
(
""
,
0
,
s
->
tx_md
);
s
->
tx_md
.
end_of_burst
=
false
;
}
/*! \brief Called to send samples to the USRP RF target
@param device pointer to the device structure specific to the RF hardware target
@param timestamp The timestamp at whicch the first sample MUST be sent
@param timestamp The timestamp at whicch the first sample MUST be sent
@param buff Buffer which holds the samples
@param nsamps number of samples to be sent
@param antenna_id index of the antenna if the device has multiple anteannas
@param flags flags must be set to TRUE if timestamp parameter needs to be applied
*/
static
int
trx_usrp_write
(
openair0_device
*
device
,
openair0_timestamp
timestamp
,
void
**
buff
,
int
nsamps
,
int
cc
,
int
flags
)
{
static
long
long
int
loop
=
0
;
static
long
time_min
=
0
,
time_max
=
0
,
time_avg
=
0
;
struct
timespec
tp_start
,
tp_end
;
long
time_diff
;
clock_gettime
(
CLOCK_MONOTONIC_RAW
,
&
tp_start
);
int
ret
=
0
,
ret_i
=
0
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
*/
static
int
trx_usrp_write
(
openair0_device
*
device
,
openair0_timestamp
timestamp
,
void
**
buff
,
int
nsamps
,
int
cc
,
int
flags
)
{
int
ret
=
0
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
s
->
tx_md
.
time_spec
=
uhd
::
time_spec_t
::
from_ticks
(
timestamp
,
s
->
sample_rate
);
s
->
tx_md
.
time_spec
=
uhd
::
time_spec_t
::
from_ticks
(
timestamp
,
s
->
sample_rate
);
s
->
tx_md
.
has_time_spec
=
flags
;
if
(
flags
)
s
->
tx_md
.
has_time_spec
=
true
;
else
s
->
tx_md
.
has_time_spec
=
false
;
if
(
cc
>
1
)
{
std
::
vector
<
void
*>
buff_ptrs
;
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
buff_ptrs
.
push_back
(
buff
[
i
]);
ret
=
(
int
)
s
->
tx_stream
->
send
(
buff_ptrs
,
nsamps
,
s
->
tx_md
,
1e-3
);
}
else
ret
=
(
int
)
s
->
tx_stream
->
send
(
buff
[
0
],
nsamps
,
s
->
tx_md
,
1e-3
);
if
(
cc
>
1
)
{
std
::
vector
<
void
*>
buff_ptrs
;
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
buff_ptrs
.
push_back
(
buff
[
i
]);
ret
=
(
int
)
s
->
tx_stream
->
send
(
buff_ptrs
,
nsamps
,
s
->
tx_md
,
1e-3
);
}
else
ret
=
(
int
)
s
->
tx_stream
->
send
(
buff
[
0
],
nsamps
,
s
->
tx_md
,
1e-3
);
s
->
tx_md
.
start_of_burst
=
false
;
s
->
tx_md
.
start_of_burst
=
false
;
if
(
ret
!=
nsamps
)
{
printf
(
"[xmit] tx samples %d != %d
\n
"
,
ret
,
nsamps
);
}
if
(
ret
!=
nsamps
)
LOG_E
(
PHY
,
"[xmit] tx samples %d != %d
\n
"
,
ret
,
nsamps
);
clock_gettime
(
CLOCK_MONOTONIC_RAW
,
&
tp_end
);
time_diff
=
(
tp_end
.
tv_sec
-
tp_start
.
tv_sec
)
*
1E09
+
(
tp_end
.
tv_nsec
-
tp_start
.
tv_nsec
);
if
(
time_min
==
0
||
loop
==
1
||
time_min
>
time_diff
)
time_min
=
time_diff
;
if
(
time_max
==
0
||
loop
==
1
||
time_max
<
time_diff
)
time_max
=
time_diff
;
if
(
time_avg
==
0
||
loop
==
1
)
time_avg
=
time_diff
;
else
time_avg
=
(
time_diff
+
time_avg
)
/
2.0
;
/* //prints statics of uhd every 10 seconds
if ( loop % (10 * ((int)device->openair0_cfg[0].sample_rate /(int)nsamps )) ==0)
LOG_I(HW,"usrp_write: min(ns)=%d, max(ns)=%d, avg(ns)=%d\n", (int)time_min, (int)time_max,(int)time_avg);
*/
loop
++
;
return
ret
;
return
ret
;
}
/*! \brief Receive samples from hardware.
...
...
@@ -226,45 +178,42 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
* \param antenna_id Index of antenna for which to receive samples
* \returns the number of sample read
*/
static
int
trx_usrp_read
(
openair0_device
*
device
,
openair0_timestamp
*
ptimestamp
,
void
**
buff
,
int
nsamps
,
int
cc
)
{
static
long
long
int
loop
=
0
;
static
long
time_min
=
0
,
time_max
=
0
,
time_avg
=
0
;
struct
timespec
tp_start
,
tp_end
;
long
time_diff
;
clock_gettime
(
CLOCK_MONOTONIC_RAW
,
&
tp_start
);
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
int
samples_received
=
0
,
i
,
j
;
int
nsamps2
;
// aligned to upper 32 or 16 byte boundary
static
int
trx_usrp_read
(
openair0_device
*
device
,
openair0_timestamp
*
ptimestamp
,
void
**
buff
,
int
nsamps
,
int
cc
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
int
samples_received
=
0
,
i
,
j
;
int
nsamps2
;
// aligned to upper 32 or 16 byte boundary
#if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__
nsamps2
=
(
nsamps
+
7
)
>>
3
;
__m256i
buff_tmp
[
2
][
nsamps2
];
nsamps2
=
(
nsamps
+
7
)
>>
3
;
__m256i
buff_tmp
[
2
][
nsamps2
];
#else
nsamps2
=
(
nsamps
+
3
)
>>
2
;
__m128i
buff_tmp
[
2
][
nsamps2
];
nsamps2
=
(
nsamps
+
3
)
>>
2
;
__m128i
buff_tmp
[
2
][
nsamps2
];
#endif
#elif defined(__arm__)
nsamps2
=
(
nsamps
+
3
)
>>
2
;
int16x8_t
buff_tmp
[
2
][
nsamps2
];
nsamps2
=
(
nsamps
+
3
)
>>
2
;
int16x8_t
buff_tmp
[
2
][
nsamps2
];
#endif
if
(
device
->
type
==
USRP_B200_DEV
)
{
if
(
cc
>
1
)
{
// receive multiple channels (e.g. RF A and RF B)
std
::
vector
<
void
*>
buff_ptrs
;
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
buff_ptrs
.
push_back
(
buff_tmp
[
i
]);
samples_received
=
s
->
rx_stream
->
recv
(
buff_ptrs
,
nsamps
,
s
->
rx_md
);
}
else
{
// receive a single channel (e.g. from connector RF A)
samples_received
=
s
->
rx_stream
->
recv
(
buff_tmp
[
0
],
nsamps
,
s
->
rx_md
);
}
// bring RX data into 12 LSBs for softmodem RX
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
{
for
(
int
j
=
0
;
j
<
nsamps2
;
j
++
)
{
if
(
device
->
type
==
USRP_B200_DEV
)
{
if
(
cc
>
1
)
{
// receive multiple channels (e.g. RF A and RF B)
std
::
vector
<
void
*>
buff_ptrs
;
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
buff_ptrs
.
push_back
(
buff_tmp
[
i
]);
samples_received
=
s
->
rx_stream
->
recv
(
buff_ptrs
,
nsamps
,
s
->
rx_md
);
}
else
{
// receive a single channel (e.g. from connector RF A)
samples_received
=
0
;
while
(
samples_received
!=
nsamps
)
{
samples_received
+=
s
->
rx_stream
->
recv
(
buff_tmp
[
0
]
+
samples_received
,
nsamps
-
samples_received
,
s
->
rx_md
);
if
(
s
->
rx_md
.
error_code
!=
uhd
::
rx_metadata_t
::
ERROR_CODE_NONE
)
break
;
}
}
// bring RX data into 12 LSBs for softmodem RX
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
{
for
(
int
j
=
0
;
j
<
nsamps2
;
j
++
)
{
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
((
__m256i
*
)
buff
[
i
])[
j
]
=
_mm256_srai_epi16
(
buff_tmp
[
i
][
j
],
4
);
...
...
@@ -288,67 +237,26 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
samples_received
=
s
->
rx_stream
->
recv
(
buff
[
0
],
nsamps
,
s
->
rx_md
);
}
}
if
(
samples_received
<
nsamps
)
LOG_E
(
PHY
,
"[recv] received %d samples out of %d
\n
"
,
samples_received
,
nsamps
);
if
(
samples_received
<
nsamps
)
{
printf
(
"[recv] received %d samples out of %d
\n
"
,
samples_received
,
nsamps
);
}
if
(
s
->
rx_md
.
error_code
!=
uhd
::
rx_metadata_t
::
ERROR_CODE_NONE
)
LOG_E
(
PHY
,
s
->
rx_md
.
to_pp_string
(
true
).
c_str
());
//handle the error code
switch
(
s
->
rx_md
.
error_code
){
case
uhd
:
:
rx_metadata_t
::
ERROR_CODE_NONE
:
break
;
case
uhd
:
:
rx_metadata_t
::
ERROR_CODE_OVERFLOW
:
printf
(
"[recv] USRP RX OVERFLOW!
\n
"
);
s
->
num_overflows
++
;
break
;
case
uhd
:
:
rx_metadata_t
::
ERROR_CODE_TIMEOUT
:
printf
(
"[recv] USRP RX TIMEOUT!
\n
"
);
break
;
default:
printf
(
"[recv] Unexpected error on RX, Error code: 0x%x
\n
"
,
s
->
rx_md
.
error_code
);
break
;
}
s
->
rx_count
+=
nsamps
;
s
->
rx_timestamp
=
s
->
rx_md
.
time_spec
.
to_ticks
(
s
->
sample_rate
);
*
ptimestamp
=
s
->
rx_timestamp
;
clock_gettime
(
CLOCK_MONOTONIC_RAW
,
&
tp_end
);
time_diff
=
(
tp_end
.
tv_sec
-
tp_start
.
tv_sec
)
*
1E09
+
(
tp_end
.
tv_nsec
-
tp_start
.
tv_nsec
);
if
(
time_min
==
0
||
loop
==
1
||
time_min
>
time_diff
)
time_min
=
time_diff
;
if
(
time_max
==
0
||
loop
==
1
||
time_max
<
time_diff
)
time_max
=
time_diff
;
if
(
time_avg
==
0
||
loop
==
1
)
time_avg
=
time_diff
;
else
time_avg
=
(
time_diff
+
time_avg
)
/
2.0
;
/*
//prints statics of uhd every 10 seconds
if ( loop % (10 * ((int)device->openair0_cfg[0].sample_rate /(int)nsamps )) ==0)
LOG_I(HW,"usrp_read: min(ns)=%d, max(ns)=%d, avg(ns)=%d\n", (int)time_min, (int)time_max,(int)time_avg);
loop++;*/
return
samples_received
;
s
->
rx_count
+=
nsamps
;
s
->
rx_timestamp
=
s
->
rx_md
.
time_spec
.
to_ticks
(
s
->
sample_rate
);
*
ptimestamp
=
s
->
rx_timestamp
;
#ifdef DEBUG_USRP
check
(
50
);
#endif
return
samples_received
;
}
/*! \brief Get current timestamp of USRP
* \param device the hardware to use
*/
openair0_timestamp
get_usrp_time
(
openair0_device
*
device
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
return
s
->
usrp
->
get_time_now
().
to_ticks
(
s
->
sample_rate
);
}
/*! \brief Compares two variables within precision
* \param a first variable
* \param b second variable
*/
static
bool
is_equal
(
double
a
,
double
b
)
{
static
bool
is_equal
(
double
a
,
double
b
)
{
return
std
::
fabs
(
a
-
b
)
<
std
::
numeric_limits
<
double
>::
epsilon
();
}
...
...
@@ -360,59 +268,60 @@ static bool is_equal(double a, double b)
*/
int
trx_usrp_set_freq
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
,
int
dummy
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
printf
(
"Setting USRP TX Freq %f, RX Freq %f
\n
"
,
openair0_cfg
[
0
].
tx_freq
[
0
],
openair0_cfg
[
0
].
rx_freq
[
0
]);
s
->
usrp
->
set_tx_freq
(
openair0_cfg
[
0
].
tx_freq
[
0
]);
s
->
usrp
->
set_rx_freq
(
openair0_cfg
[
0
].
rx_freq
[
0
]);
LOG_I
(
PHY
,
"Setting USRP TX Freq %f, RX Freq %f
\n
"
,
openair0_cfg
[
0
].
tx_freq
[
0
],
openair0_cfg
[
0
].
rx_freq
[
0
]);
s
->
usrp
->
set_tx_freq
(
openair0_cfg
[
0
].
tx_freq
[
0
]);
s
->
usrp
->
set_rx_freq
(
openair0_cfg
[
0
].
rx_freq
[
0
]);
return
(
0
);
return
(
0
);
}
/*! \brief Set RX frequencies
/*! \brief Set RX frequencies
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success
* \returns 0 in success
*/
int
openair0_set_rx_frequencies
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
static
int
first_call
=
1
;
static
double
rf_freq
,
diff
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
static
int
first_call
=
1
;
static
double
rf_freq
,
diff
;
uhd
::
tune_request_t
rx_tune_req
(
openair0_cfg
[
0
].
rx_freq
[
0
]);
uhd
::
tune_request_t
rx_tune_req
(
openair0_cfg
[
0
].
rx_freq
[
0
]);
rx_tune_req
.
rf_freq_policy
=
uhd
::
tune_request_t
::
POLICY_MANUAL
;
rx_tune_req
.
rf_freq
=
openair0_cfg
[
0
].
rx_freq
[
0
];
rf_freq
=
openair0_cfg
[
0
].
rx_freq
[
0
];
s
->
usrp
->
set_rx_freq
(
rx_tune_req
);
rx_tune_req
.
rf_freq_policy
=
uhd
::
tune_request_t
::
POLICY_MANUAL
;
rx_tune_req
.
rf_freq
=
openair0_cfg
[
0
].
rx_freq
[
0
];
rf_freq
=
openair0_cfg
[
0
].
rx_freq
[
0
];
s
->
usrp
->
set_rx_freq
(
rx_tune_req
);
return
(
0
);
return
(
0
);
}
/*! \brief Set Gains (TX/RX)
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success
* \returns 0 in success
*/
int
trx_usrp_set_gains
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
s
->
usrp
->
set_tx_gain
(
openair0_cfg
[
0
].
tx_gain
[
0
]);
::
uhd
::
gain_range_t
gain_range
=
s
->
usrp
->
get_rx_gain_range
(
0
);
// limit to maximum gain
if
(
openair0_cfg
[
0
].
rx_gain
[
0
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
0
]
>
gain_range
.
stop
())
{
printf
(
"RX Gain 0 too high, reduce by %f dB
\n
"
,
openair0_cfg
[
0
].
rx_gain
[
0
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
0
]
-
gain_range
.
stop
());
exit
(
-
1
);
}
s
->
usrp
->
set_rx_gain
(
openair0_cfg
[
0
].
rx_gain
[
0
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
0
]);
printf
(
"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)
\n
"
,
openair0_cfg
[
0
].
rx_gain
[
0
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
0
],
openair0_cfg
[
0
].
rx_gain
[
0
],
gain_range
.
stop
());
int
trx_usrp_set_gains
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
s
->
usrp
->
set_tx_gain
(
openair0_cfg
[
0
].
tx_gain
[
0
]);
::
uhd
::
gain_range_t
gain_range
=
s
->
usrp
->
get_rx_gain_range
(
0
);
// limit to maximum gain
if
(
openair0_cfg
[
0
].
rx_gain
[
0
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
0
]
>
gain_range
.
stop
())
{
LOG_E
(
PHY
,
"RX Gain 0 too high, reduce by %f dB
\n
"
,
openair0_cfg
[
0
].
rx_gain
[
0
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
0
]
-
gain_range
.
stop
());
exit
(
-
1
);
}
s
->
usrp
->
set_rx_gain
(
openair0_cfg
[
0
].
rx_gain
[
0
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
0
]);
LOG_I
(
PHY
,
"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)
\n
"
,
openair0_cfg
[
0
].
rx_gain
[
0
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
0
],
openair0_cfg
[
0
].
rx_gain
[
0
],
gain_range
.
stop
());
return
(
0
);
}
...
...
@@ -426,376 +335,310 @@ int trx_usrp_stop(openair0_device* device) {
/*! \brief USRPB210 RX calibration table */
rx_gain_calib_table_t
calib_table_b210
[]
=
{
{
3500000000.0
,
44.0
},
{
2660000000.0
,
49.0
},
{
2300000000.0
,
50.0
},
{
1880000000.0
,
53.0
},
{
816000000.0
,
58.0
},
{
-
1
,
0
}};
{
3500000000.0
,
44.0
},
{
2660000000.0
,
49.0
},
{
2300000000.0
,
50.0
},
{
1880000000.0
,
53.0
},
{
816000000.0
,
58.0
},
{
-
1
,
0
}
};
/*! \brief USRPB210 RX calibration table */
rx_gain_calib_table_t
calib_table_b210_38
[]
=
{
{
3500000000.0
,
44.0
},
{
2660000000.0
,
49.8
},
{
2300000000.0
,
51.0
},
{
1880000000.0
,
53.0
},
{
816000000.0
,
57.0
},
{
-
1
,
0
}};
{
3500000000.0
,
44.0
},
{
2660000000.0
,
49.8
},
{
2300000000.0
,
51.0
},
{
1880000000.0
,
53.0
},
{
816000000.0
,
57.0
},
{
-
1
,
0
}
};
/*! \brief USRPx310 RX calibration table */
rx_gain_calib_table_t
calib_table_x310
[]
=
{
{
3500000000.0
,
77.0
},
{
2660000000.0
,
81.0
},
{
2300000000.0
,
81.0
},
{
1880000000.0
,
82.0
},
{
816000000.0
,
85.0
},
{
-
1
,
0
}};
/*! \brief Set RX gain offset
{
3500000000.0
,
77.0
},
{
2660000000.0
,
81.0
},
{
2300000000.0
,
81.0
},
{
1880000000.0
,
82.0
},
{
816000000.0
,
85.0
},
{
-
1
,
0
}
};
/*! \brief Set RX gain offset
* \param openair0_cfg RF frontend parameters set by application
* \param chain_index RF chain to apply settings to
* \returns 0 in success
* \returns 0 in success
*/
void
set_rx_gain_offset
(
openair0_config_t
*
openair0_cfg
,
int
chain_index
,
int
bw_gain_adjust
)
{
int
i
=
0
;
// loop through calibration table to find best adjustment factor for RX frequency
double
min_diff
=
6e9
,
diff
,
gain_adj
=
0.0
;
if
(
bw_gain_adjust
==
1
)
{
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
case
30720000
:
break
;
case
23040000
:
gain_adj
=
1.25
;
break
;
case
15360000
:
gain_adj
=
3.0
;
break
;
case
7680000
:
gain_adj
=
6.0
;
break
;
case
3840000
:
gain_adj
=
9.0
;
break
;
case
1920000
:
gain_adj
=
12.0
;
break
;
default:
printf
(
"unknown sampling rate %d
\n
"
,(
int
)
openair0_cfg
[
0
].
sample_rate
);
exit
(
-
1
);
break
;
int
i
=
0
;
// loop through calibration table to find best adjustment factor for RX frequency
double
min_diff
=
6e9
,
diff
,
gain_adj
=
0.0
;
if
(
bw_gain_adjust
==
1
)
{
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
case
30720000
:
break
;
case
23040000
:
gain_adj
=
1.25
;
break
;
case
15360000
:
gain_adj
=
3.0
;
break
;
case
7680000
:
gain_adj
=
6.0
;
break
;
case
3840000
:
gain_adj
=
9.0
;
break
;
case
1920000
:
gain_adj
=
12.0
;
break
;
default:
LOG_E
(
PHY
,
"unknown sampling rate %d
\n
"
,(
int
)
openair0_cfg
[
0
].
sample_rate
);
exit
(
-
1
);
break
;
}
}
}
while
(
openair0_cfg
->
rx_gain_calib_table
[
i
].
freq
>
0
)
{
diff
=
fabs
(
openair0_cfg
->
rx_freq
[
chain_index
]
-
openair0_cfg
->
rx_gain_calib_table
[
i
].
freq
);
printf
(
"cal %d: freq %f, offset %f, diff %f
\n
"
,
i
,
openair0_cfg
->
rx_gain_calib_table
[
i
].
freq
,
while
(
openair0_cfg
->
rx_gain_calib_table
[
i
].
freq
>
0
)
{
diff
=
fabs
(
openair0_cfg
->
rx_freq
[
chain_index
]
-
openair0_cfg
->
rx_gain_calib_table
[
i
].
freq
);
LOG_I
(
PHY
,
"cal %d: freq %f, offset %f, diff %f
\n
"
,
i
,
openair0_cfg
->
rx_gain_calib_table
[
i
].
freq
,
openair0_cfg
->
rx_gain_calib_table
[
i
].
offset
,
diff
);
if
(
min_diff
>
diff
)
{
min_diff
=
diff
;
openair0_cfg
->
rx_gain_offset
[
chain_index
]
=
openair0_cfg
->
rx_gain_calib_table
[
i
].
offset
+
gain_adj
;
}
i
++
;
}
}
}
/*! \brief print the USRP statistics
/*! \brief print the USRP statistics
* \param device the hardware to use
* \returns 0 on success
*/
int
trx_usrp_get_stats
(
openair0_device
*
device
)
{
return
(
0
);
return
(
0
);
}
/*! \brief Reset the USRP statistics
* \param device the hardware to use
* \returns 0 on success
*/
/*! \brief Reset the USRP statistics
* \param device the hardware to use
* \returns 0 on success
*/
int
trx_usrp_reset_stats
(
openair0_device
*
device
)
{
return
(
0
);
return
(
0
);
}
extern
"C"
{
/*! \brief Initialize Openair USRP target. It returns 0 if OK
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
*/
int
device_init
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
uhd
::
set_thread_priority_safe
(
1.0
);
usrp_state_t
*
s
=
(
usrp_state_t
*
)
malloc
(
sizeof
(
usrp_state_t
));
memset
(
s
,
0
,
sizeof
(
usrp_state_t
));
// Initialize USRP device
device
->
openair0_cfg
=
openair0_cfg
;
std
::
string
args
=
"type=b200"
;
uhd
::
device_addrs_t
device_adds
=
uhd
::
device
::
find
(
args
);
size_t
i
;
int
vers
=
0
,
subvers
=
0
,
subsubvers
=
0
;
int
bw_gain_adjust
=
0
;
/*! \brief Initialize Openair USRP target. It returns 0 if OK
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
*/
int
device_init
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
//uhd::set_thread_priority_safe(1.0);
usrp_state_t
*
s
=
(
usrp_state_t
*
)
calloc
(
sizeof
(
usrp_state_t
),
1
);
// Initialize USRP device
device
->
openair0_cfg
=
openair0_cfg
;
std
::
string
args
=
"type=b200"
;
uhd
::
device_addrs_t
device_adds
=
uhd
::
device
::
find
(
args
);
int
vers
=
0
,
subvers
=
0
,
subsubvers
=
0
;
int
bw_gain_adjust
=
0
;
sscanf
(
uhd
::
get_version_string
().
c_str
(),
"%d.%d.%d"
,
&
vers
,
&
subvers
,
&
subsubvers
);
LOG_I
(
PHY
,
"Checking for USRPs : UHD %s (%d.%d.%d)
\n
"
,
uhd
::
get_version_string
().
c_str
(),
vers
,
subvers
,
subsubvers
);
if
(
device_adds
.
size
()
==
0
)
{
double
usrp_master_clock
=
184.32e6
;
std
::
string
args
=
"type=x300"
;
sscanf
(
uhd
::
get_version_string
().
c_str
(),
"%d.%d.%d"
,
&
vers
,
&
subvers
,
&
subsubvers
);
printf
(
"Checking for USRPs : UHD %s (%d.%d.%d)
\n
"
,
uhd
::
get_version_string
().
c_str
(),
vers
,
subvers
,
subsubvers
);
if
(
device_adds
.
size
()
==
0
)
{
double
usrp_master_clock
=
184.32e6
;
std
::
string
args
=
"type=x300"
;
// workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate
args
+=
boost
::
str
(
boost
::
format
(
",master_clock_rate=%f"
)
%
usrp_master_clock
);
// args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096";
uhd
::
device_addrs_t
device_adds
=
uhd
::
device
::
find
(
args
);
if
(
device_adds
.
size
()
==
0
)
{
std
::
cerr
<<
"No USRP Device Found. "
<<
std
::
endl
;
free
(
s
);
return
-
1
;
}
printf
(
"Found USRP X300
\n
"
);
s
->
usrp
=
uhd
::
usrp
::
multi_usrp
::
make
(
args
);
// s->usrp->set_rx_subdev_spec(rx_subdev);
// s->usrp->set_tx_subdev_spec(tx_subdev);
// lock mboard clocks
s
->
usrp
->
set_clock_source
(
"internal"
);
//Setting device type to USRP X300/X310
device
->
type
=
USRP_X300_DEV
;
// this is not working yet, master clock has to be set via constructor
// set master clock rate and sample rate for tx & rx for streaming
//s->usrp->set_master_clock_rate(usrp_master_clock);
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_x310
;
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
case
30720000
:
// from usrp_time_offset
//openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg
[
0
].
tx_sample_advance
=
15
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
case
15360000
:
//openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg
[
0
].
tx_sample_advance
=
45
;
openair0_cfg
[
0
].
tx_bw
=
10e6
;
openair0_cfg
[
0
].
rx_bw
=
10e6
;
break
;
case
7680000
:
//openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg
[
0
].
tx_sample_advance
=
50
;
openair0_cfg
[
0
].
tx_bw
=
5e6
;
openair0_cfg
[
0
].
rx_bw
=
5e6
;
break
;
case
1920000
:
//openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg
[
0
].
tx_sample_advance
=
50
;
openair0_cfg
[
0
].
tx_bw
=
1.25e6
;
openair0_cfg
[
0
].
rx_bw
=
1.25e6
;
break
;
default:
printf
(
"Error: unknown sampling rate %f
\n
"
,
openair0_cfg
[
0
].
sample_rate
);
exit
(
-
1
);
break
;
}
}
else
{
printf
(
"Found USRP B200"
);
args
+=
",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360"
;
s
->
usrp
=
uhd
::
usrp
::
multi_usrp
::
make
(
args
);
// s->usrp->set_rx_subdev_spec(rx_subdev);
// s->usrp->set_tx_subdev_spec(tx_subdev);
// do not explicitly set the clock to "internal", because this will disable the gpsdo
// // lock mboard clocks
// s->usrp->set_clock_source("internal");
// set master clock rate and sample rate for tx & rx for streaming
device
->
type
=
USRP_B200_DEV
;
if
((
vers
==
3
)
&&
(
subvers
==
9
)
&&
(
subsubvers
>=
2
))
{
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_b210
;
bw_gain_adjust
=
0
;
}
else
{
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_b210_38
;
bw_gain_adjust
=
1
;
}
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
case
30720000
:
s
->
usrp
->
set_master_clock_rate
(
30.72e6
);
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg
[
0
].
tx_sample_advance
=
115
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
case
23040000
:
s
->
usrp
->
set_master_clock_rate
(
23.04e6
);
//to be checked
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg
[
0
].
tx_sample_advance
=
113
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
case
15360000
:
s
->
usrp
->
set_master_clock_rate
(
30.72e06
);
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg
[
0
].
tx_sample_advance
=
103
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
case
7680000
:
s
->
usrp
->
set_master_clock_rate
(
30.72e6
);
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg
[
0
].
tx_sample_advance
=
80
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
case
1920000
:
s
->
usrp
->
set_master_clock_rate
(
30.72e6
);
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg
[
0
].
tx_sample_advance
=
40
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
default:
printf
(
"Error: unknown sampling rate %f
\n
"
,
openair0_cfg
[
0
].
sample_rate
);
exit
(
-
1
);
break
;
}
}
/* device specific */
//openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered
//openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered
openair0_cfg
[
0
].
iq_txshift
=
4
;
//shift
openair0_cfg
[
0
].
iq_rxrescale
=
15
;
//rescale iqs
for
(
i
=
0
;
i
<
s
->
usrp
->
get_rx_num_channels
();
i
++
)
{
if
(
i
<
openair0_cfg
[
0
].
rx_num_channels
)
{
s
->
usrp
->
set_rx_rate
(
openair0_cfg
[
0
].
sample_rate
,
i
);
//s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i);
//printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->usrp->get_rx_num_channels(),openair0_cfg[0].rx_bw/1e6,s->usrp->get_rx_bandwidth(i)/1e6);
s
->
usrp
->
set_rx_freq
(
openair0_cfg
[
0
].
rx_freq
[
i
],
i
);
set_rx_gain_offset
(
&
openair0_cfg
[
0
],
i
,
bw_gain_adjust
);
::
uhd
::
gain_range_t
gain_range
=
s
->
usrp
->
get_rx_gain_range
(
i
);
// limit to maximum gain
if
(
openair0_cfg
[
0
].
rx_gain
[
i
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
i
]
>
gain_range
.
stop
())
{
printf
(
"RX Gain %lu too high, lower by %f dB
\n
"
,
i
,
openair0_cfg
[
0
].
rx_gain
[
i
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
i
]
-
gain_range
.
stop
());
exit
(
-
1
);
}
s
->
usrp
->
set_rx_gain
(
openair0_cfg
[
0
].
rx_gain
[
i
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
i
],
i
);
printf
(
"RX Gain %lu %f (%f) => %f (max %f)
\n
"
,
i
,
openair0_cfg
[
0
].
rx_gain
[
i
],
openair0_cfg
[
0
].
rx_gain_offset
[
i
],
openair0_cfg
[
0
].
rx_gain
[
i
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
i
],
gain_range
.
stop
());
}
}
for
(
i
=
0
;
i
<
s
->
usrp
->
get_tx_num_channels
();
i
++
)
{
if
(
i
<
openair0_cfg
[
0
].
tx_num_channels
)
{
s
->
usrp
->
set_tx_rate
(
openair0_cfg
[
0
].
sample_rate
,
i
);
//s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i);
//printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->usrp->get_tx_num_channels(),openair0_cfg[0].tx_bw/1e6,s->usrp->get_tx_bandwidth(i)/1e6);
s
->
usrp
->
set_tx_freq
(
openair0_cfg
[
0
].
tx_freq
[
i
],
i
);
s
->
usrp
->
set_tx_gain
(
openair0_cfg
[
0
].
tx_gain
[
i
],
i
);
}
}
// display USRP settings
std
::
cout
<<
boost
::
format
(
"Actual master clock: %fMHz..."
)
%
(
s
->
usrp
->
get_master_clock_rate
()
/
1e6
)
<<
std
::
endl
;
sleep
(
1
);
// create tx & rx streamer
uhd
::
stream_args_t
stream_args_rx
(
"sc16"
,
"sc16"
);
//stream_args_rx.args["spp"] = str(boost::format("%d") % 2048);//(openair0_cfg[0].rx_num_channels*openair0_cfg[0].samples_per_packet));
for
(
i
=
0
;
i
<
openair0_cfg
[
0
].
rx_num_channels
;
i
++
)
stream_args_rx
.
channels
.
push_back
(
i
);
s
->
rx_stream
=
s
->
usrp
->
get_rx_stream
(
stream_args_rx
);
std
::
cout
<<
boost
::
format
(
"rx_max_num_samps %u"
)
%
(
s
->
rx_stream
->
get_max_num_samps
())
<<
std
::
endl
;
//openair0_cfg[0].samples_per_packet = s->rx_stream->get_max_num_samps();
uhd
::
stream_args_t
stream_args_tx
(
"sc16"
,
"sc16"
);
//stream_args_tx.args["spp"] = str(boost::format("%d") % 2048);//(openair0_cfg[0].tx_num_channels*openair0_cfg[0].samples_per_packet));
for
(
i
=
0
;
i
<
openair0_cfg
[
0
].
tx_num_channels
;
i
++
)
stream_args_tx
.
channels
.
push_back
(
i
);
s
->
tx_stream
=
s
->
usrp
->
get_tx_stream
(
stream_args_tx
);
std
::
cout
<<
boost
::
format
(
"tx_max_num_samps %u"
)
%
(
s
->
tx_stream
->
get_max_num_samps
())
<<
std
::
endl
;
/* Setting TX/RX BW after streamers are created due to USRP calibration issue */
for
(
i
=
0
;
i
<
s
->
usrp
->
get_tx_num_channels
();
i
++
)
{
if
(
i
<
openair0_cfg
[
0
].
tx_num_channels
)
{
s
->
usrp
->
set_tx_bandwidth
(
openair0_cfg
[
0
].
tx_bw
,
i
);
printf
(
"Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)
\n
"
,
i
,
s
->
usrp
->
get_tx_num_channels
(),
openair0_cfg
[
0
].
tx_bw
/
1e6
,
s
->
usrp
->
get_tx_bandwidth
(
i
)
/
1e6
);
}
}
for
(
i
=
0
;
i
<
s
->
usrp
->
get_rx_num_channels
();
i
++
)
{
if
(
i
<
openair0_cfg
[
0
].
rx_num_channels
)
{
s
->
usrp
->
set_rx_bandwidth
(
openair0_cfg
[
0
].
rx_bw
,
i
);
printf
(
"Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)
\n
"
,
i
,
s
->
usrp
->
get_rx_num_channels
(),
openair0_cfg
[
0
].
rx_bw
/
1e6
,
s
->
usrp
->
get_rx_bandwidth
(
i
)
/
1e6
);
}
}
s
->
usrp
->
set_time_now
(
uhd
::
time_spec_t
(
0.0
));
for
(
i
=
0
;
i
<
openair0_cfg
[
0
].
rx_num_channels
;
i
++
)
{
if
(
i
<
openair0_cfg
[
0
].
rx_num_channels
)
{
printf
(
"RX Channel %lu
\n
"
,
i
);
std
::
cout
<<
boost
::
format
(
"Actual RX sample rate: %fMSps..."
)
%
(
s
->
usrp
->
get_rx_rate
(
i
)
/
1e6
)
<<
std
::
endl
;
std
::
cout
<<
boost
::
format
(
"Actual RX frequency: %fGHz..."
)
%
(
s
->
usrp
->
get_rx_freq
(
i
)
/
1e9
)
<<
std
::
endl
;
std
::
cout
<<
boost
::
format
(
"Actual RX gain: %f..."
)
%
(
s
->
usrp
->
get_rx_gain
(
i
))
<<
std
::
endl
;
std
::
cout
<<
boost
::
format
(
"Actual RX bandwidth: %fM..."
)
%
(
s
->
usrp
->
get_rx_bandwidth
(
i
)
/
1e6
)
<<
std
::
endl
;
std
::
cout
<<
boost
::
format
(
"Actual RX antenna: %s..."
)
%
(
s
->
usrp
->
get_rx_antenna
(
i
))
<<
std
::
endl
;
}
}
for
(
i
=
0
;
i
<
openair0_cfg
[
0
].
tx_num_channels
;
i
++
)
{
if
(
i
<
openair0_cfg
[
0
].
tx_num_channels
)
{
printf
(
"TX Channel %lu
\n
"
,
i
);
std
::
cout
<<
std
::
endl
<<
boost
::
format
(
"Actual TX sample rate: %fMSps..."
)
%
(
s
->
usrp
->
get_tx_rate
(
i
)
/
1e6
)
<<
std
::
endl
;
std
::
cout
<<
boost
::
format
(
"Actual TX frequency: %fGHz..."
)
%
(
s
->
usrp
->
get_tx_freq
(
i
)
/
1e9
)
<<
std
::
endl
;
std
::
cout
<<
boost
::
format
(
"Actual TX gain: %f..."
)
%
(
s
->
usrp
->
get_tx_gain
(
i
))
<<
std
::
endl
;
std
::
cout
<<
boost
::
format
(
"Actual TX bandwidth: %fM..."
)
%
(
s
->
usrp
->
get_tx_bandwidth
(
i
)
/
1e6
)
<<
std
::
endl
;
std
::
cout
<<
boost
::
format
(
"Actual TX antenna: %s..."
)
%
(
s
->
usrp
->
get_tx_antenna
(
i
))
<<
std
::
endl
;
}
}
std
::
cout
<<
boost
::
format
(
"Device timestamp: %f..."
)
%
(
s
->
usrp
->
get_time_now
().
get_real_secs
())
<<
std
::
endl
;
device
->
priv
=
s
;
device
->
trx_start_func
=
trx_usrp_start
;
device
->
trx_write_func
=
trx_usrp_write
;
device
->
trx_read_func
=
trx_usrp_read
;
// args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096";
uhd
::
device_addrs_t
device_adds
=
uhd
::
device
::
find
(
args
);
if
(
device_adds
.
size
()
==
0
)
{
std
::
cerr
<<
"No USRP Device Found. "
<<
std
::
endl
;
free
(
s
);
return
-
1
;
}
LOG_I
(
PHY
,
"Found USRP X300
\n
"
);
s
->
usrp
=
uhd
::
usrp
::
multi_usrp
::
make
(
args
);
// lock mboard clocks
s
->
usrp
->
set_clock_source
(
"internal"
);
//Setting device type to USRP X300/X310
device
->
type
=
USRP_X300_DEV
;
// this is not working yet, master clock has to be set via constructor
// set master clock rate and sample rate for tx & rx for streaming
//s->usrp->set_master_clock_rate(usrp_master_clock);
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_x310
;
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
case
30720000
:
// from usrp_time_offset
openair0_cfg
[
0
].
tx_sample_advance
=
15
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
case
15360000
:
openair0_cfg
[
0
].
tx_sample_advance
=
45
;
openair0_cfg
[
0
].
tx_bw
=
10e6
;
openair0_cfg
[
0
].
rx_bw
=
10e6
;
break
;
case
7680000
:
openair0_cfg
[
0
].
tx_sample_advance
=
50
;
openair0_cfg
[
0
].
tx_bw
=
5e6
;
openair0_cfg
[
0
].
rx_bw
=
5e6
;
break
;
case
1920000
:
openair0_cfg
[
0
].
tx_sample_advance
=
50
;
openair0_cfg
[
0
].
tx_bw
=
1.25e6
;
openair0_cfg
[
0
].
rx_bw
=
1.25e6
;
break
;
default:
LOG_E
(
PHY
,
"Error: unknown sampling rate %f
\n
"
,
openair0_cfg
[
0
].
sample_rate
);
exit
(
-
1
);
break
;
}
}
else
{
LOG_I
(
PHY
,
"Found USRP B200
\n
"
);
args
+=
",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360"
;
s
->
usrp
=
uhd
::
usrp
::
multi_usrp
::
make
(
args
);
device
->
type
=
USRP_B200_DEV
;
if
((
vers
==
3
)
&&
(
subvers
==
9
)
&&
(
subsubvers
>=
2
))
{
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_b210
;
bw_gain_adjust
=
0
;
}
else
{
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_b210_38
;
bw_gain_adjust
=
1
;
}
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
case
30720000
:
s
->
usrp
->
set_master_clock_rate
(
30.72e6
);
openair0_cfg
[
0
].
tx_sample_advance
=
115
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
case
23040000
:
s
->
usrp
->
set_master_clock_rate
(
23.04e6
);
//to be checked
openair0_cfg
[
0
].
tx_sample_advance
=
113
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
case
15360000
:
s
->
usrp
->
set_master_clock_rate
(
30.72e06
);
openair0_cfg
[
0
].
tx_sample_advance
=
103
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
case
7680000
:
s
->
usrp
->
set_master_clock_rate
(
30.72e6
);
openair0_cfg
[
0
].
tx_sample_advance
=
80
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
case
1920000
:
s
->
usrp
->
set_master_clock_rate
(
30.72e6
);
openair0_cfg
[
0
].
tx_sample_advance
=
40
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
default:
LOG_E
(
PHY
,
"Error: unknown sampling rate %f
\n
"
,
openair0_cfg
[
0
].
sample_rate
);
exit
(
-
1
);
break
;
}
}
openair0_cfg
[
0
].
iq_txshift
=
4
;
//shift
openair0_cfg
[
0
].
iq_rxrescale
=
15
;
//rescale iqs
for
(
int
i
=
0
;
i
<
s
->
usrp
->
get_rx_num_channels
();
i
++
)
{
if
(
i
<
openair0_cfg
[
0
].
rx_num_channels
)
{
s
->
usrp
->
set_rx_rate
(
openair0_cfg
[
0
].
sample_rate
,
i
);
s
->
usrp
->
set_rx_freq
(
openair0_cfg
[
0
].
rx_freq
[
i
],
i
);
set_rx_gain_offset
(
&
openair0_cfg
[
0
],
i
,
bw_gain_adjust
);
::
uhd
::
gain_range_t
gain_range
=
s
->
usrp
->
get_rx_gain_range
(
i
);
// limit to maximum gain
AssertFatal
(
openair0_cfg
[
0
].
rx_gain
[
i
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
i
]
<=
gain_range
.
stop
(),
"RX Gain too high, lower by %f dB
\n
"
,
openair0_cfg
[
0
].
rx_gain
[
i
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
i
]
-
gain_range
.
stop
());
s
->
usrp
->
set_rx_gain
(
openair0_cfg
[
0
].
rx_gain
[
i
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
i
],
i
);
LOG_I
(
PHY
,
"RX Gain %d %f (%f) => %f (max %f)
\n
"
,
i
,
openair0_cfg
[
0
].
rx_gain
[
i
],
openair0_cfg
[
0
].
rx_gain_offset
[
i
],
openair0_cfg
[
0
].
rx_gain
[
i
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
i
],
gain_range
.
stop
());
}
}
for
(
int
i
=
0
;
i
<
s
->
usrp
->
get_tx_num_channels
();
i
++
)
{
if
(
i
<
openair0_cfg
[
0
].
tx_num_channels
)
{
s
->
usrp
->
set_tx_rate
(
openair0_cfg
[
0
].
sample_rate
,
i
);
s
->
usrp
->
set_tx_freq
(
openair0_cfg
[
0
].
tx_freq
[
i
],
i
);
s
->
usrp
->
set_tx_gain
(
openair0_cfg
[
0
].
tx_gain
[
i
],
i
);
}
}
//s->usrp->set_clock_source("external");
//s->usrp->set_time_source("external");
// display USRP settings
LOG_I
(
PHY
,
"Actual master clock: %fMHz...
\n
"
,
s
->
usrp
->
get_master_clock_rate
()
/
1e6
);
// create tx & rx streamer
uhd
::
stream_args_t
stream_args_rx
(
"sc16"
,
"sc16"
);
int
samples
=
openair0_cfg
[
0
].
sample_rate
;
//while ( samples > s->rx_stream->get_max_num_samps())
samples
/=
24000
;
stream_args_rx
.
args
[
"spp"
]
=
str
(
boost
::
format
(
"%d"
)
%
samples
);
for
(
int
i
=
0
;
i
<
openair0_cfg
[
0
].
rx_num_channels
;
i
++
)
stream_args_rx
.
channels
.
push_back
(
i
);
s
->
rx_stream
=
s
->
usrp
->
get_rx_stream
(
stream_args_rx
);
LOG_I
(
PHY
,
"rx_max_num_samps %u
\n
"
,
s
->
rx_stream
->
get_max_num_samps
());
uhd
::
stream_args_t
stream_args_tx
(
"sc16"
,
"sc16"
);
for
(
int
i
=
0
;
i
<
openair0_cfg
[
0
].
tx_num_channels
;
i
++
)
stream_args_tx
.
channels
.
push_back
(
i
);
s
->
tx_stream
=
s
->
usrp
->
get_tx_stream
(
stream_args_tx
);
/* Setting TX/RX BW after streamers are created due to USRP calibration issue */
for
(
int
i
=
0
;
i
<
s
->
usrp
->
get_tx_num_channels
()
&&
i
<
openair0_cfg
[
0
].
tx_num_channels
;
i
++
)
s
->
usrp
->
set_tx_bandwidth
(
openair0_cfg
[
0
].
tx_bw
,
i
);
for
(
int
i
=
0
;
i
<
s
->
usrp
->
get_rx_num_channels
()
&&
i
<
openair0_cfg
[
0
].
rx_num_channels
;
i
++
)
s
->
usrp
->
set_rx_bandwidth
(
openair0_cfg
[
0
].
rx_bw
,
i
);
s
->
usrp
->
set_time_now
(
uhd
::
time_spec_t
(
0.0
));
for
(
int
i
=
0
;
i
<
openair0_cfg
[
0
].
rx_num_channels
;
i
++
)
{
LOG_I
(
PHY
,
"RX Channel %d
\n
"
,
i
);
LOG_I
(
PHY
,
" Actual RX sample rate: %fMSps...
\n
"
,
s
->
usrp
->
get_rx_rate
(
i
)
/
1e6
);
LOG_I
(
PHY
,
" Actual RX frequency: %fGHz...
\n
"
,
s
->
usrp
->
get_rx_freq
(
i
)
/
1e9
);
LOG_I
(
PHY
,
" Actual RX gain: %f...
\n
"
,
s
->
usrp
->
get_rx_gain
(
i
));
LOG_I
(
PHY
,
" Actual RX bandwidth: %fM...
\n
"
,
s
->
usrp
->
get_rx_bandwidth
(
i
)
/
1e6
);
LOG_I
(
PHY
,
" Actual RX antenna: %s...
\n
"
,
s
->
usrp
->
get_rx_antenna
(
i
).
c_str
());
}
for
(
int
i
=
0
;
i
<
openair0_cfg
[
0
].
tx_num_channels
;
i
++
)
{
LOG_I
(
PHY
,
"TX Channel %d
\n
"
,
i
);
LOG_I
(
PHY
,
" Actual TX sample rate: %fMSps...
\n
"
,
s
->
usrp
->
get_tx_rate
(
i
)
/
1e6
);
LOG_I
(
PHY
,
" Actual TX frequency: %fGHz...
\n
"
,
s
->
usrp
->
get_tx_freq
(
i
)
/
1e9
);
LOG_I
(
PHY
,
" Actual TX gain: %f...
\n
"
,
s
->
usrp
->
get_tx_gain
(
i
));
LOG_I
(
PHY
,
" Actual TX bandwidth: %fM...
\n
"
,
s
->
usrp
->
get_tx_bandwidth
(
i
)
/
1e6
);
LOG_I
(
PHY
,
" Actual TX antenna: %s...
\n
"
,
s
->
usrp
->
get_tx_antenna
(
i
).
c_str
());
}
LOG_I
(
PHY
,
"Device timestamp: %f...
\n
"
,
s
->
usrp
->
get_time_now
().
get_real_secs
());
device
->
priv
=
s
;
device
->
trx_start_func
=
trx_usrp_start
;
device
->
trx_write_func
=
trx_usrp_write
;
device
->
trx_read_func
=
trx_usrp_read
;
device
->
trx_get_stats_func
=
trx_usrp_get_stats
;
device
->
trx_reset_stats_func
=
trx_usrp_reset_stats
;
device
->
trx_end_func
=
trx_usrp_end
;
...
...
targets/RT/USER/lte-ue.c
View file @
cedde4ad
This source diff could not be displayed because it is too large. You can
view the blob
instead.
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