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
常顺宇
OpenXG-RAN
Commits
c4afc399
Commit
c4afc399
authored
Sep 28, 2018
by
Florian Kaltenberger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
astyling usrp_lib.cpp
parent
7d602d5c
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
946 additions
and
906 deletions
+946
-906
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+946
-906
No files found.
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
View file @
c4afc399
...
...
@@ -105,20 +105,17 @@ typedef struct {
//void print_notes(void)
//{
// Helpful notes
// std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n");
// std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS signals are now from the GPSDO.\n");
// std::cout << boost::format("If you would like to use the internal reference(TCXO) in other applications, you must configure that explicitly.\n");
// std::cout << boost::format("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n");
// std::cout << boost::format("****************************************************************************************************************\n");
// Helpful notes
// std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n");
// std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS signals are now from the GPSDO.\n");
// std::cout << boost::format("If you would like to use the internal reference(TCXO) in other applications, you must configure that explicitly.\n");
// std::cout << boost::format("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n");
// std::cout << boost::format("****************************************************************************************************************\n");
//}
static
int
sync_to_gps
(
openair0_device
*
device
)
{
static
int
sync_to_gps
(
openair0_device
*
device
)
{
uhd
::
set_thread_priority_safe
();
//std::string args;
//Set up program options
//po::options_description desc("Allowed options");
//desc.add_options()
...
...
@@ -128,75 +125,64 @@ static int sync_to_gps(openair0_device *device)
//po::variables_map vm;
//po::store(po::parse_command_line(argc, argv, desc), vm);
//po::notify(vm);
//Print the help message
//if (vm.count("help"))
//{
// std::cout << boost::format("Synchronize USRP to GPS %s") % desc << std::endl;
// return EXIT_FAILURE;
//}
//Create a USRP device
//std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args;
//uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
//std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string();
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
try
{
try
{
size_t
num_mboards
=
s
->
usrp
->
get_num_mboards
();
size_t
num_gps_locked
=
0
;
for
(
size_t
mboard
=
0
;
mboard
<
num_mboards
;
mboard
++
)
{
std
::
cout
<<
"Synchronizing mboard "
<<
mboard
<<
": "
<<
s
->
usrp
->
get_mboard_name
(
mboard
)
<<
std
::
endl
;
for
(
size_t
mboard
=
0
;
mboard
<
num_mboards
;
mboard
++
)
{
std
::
cout
<<
"Synchronizing mboard "
<<
mboard
<<
": "
<<
s
->
usrp
->
get_mboard_name
(
mboard
)
<<
std
::
endl
;
//Set references to GPSDO
s
->
usrp
->
set_clock_source
(
"gpsdo"
,
mboard
);
s
->
usrp
->
set_time_source
(
"gpsdo"
,
mboard
);
//std::cout << std::endl;
//print_notes();
//std::cout << std::endl;
//Check for 10 MHz lock
std
::
vector
<
std
::
string
>
sensor_names
=
s
->
usrp
->
get_mboard_sensor_names
(
mboard
);
if
(
std
::
find
(
sensor_names
.
begin
(),
sensor_names
.
end
(),
"ref_locked"
)
!=
sensor_names
.
end
())
{
if
(
std
::
find
(
sensor_names
.
begin
(),
sensor_names
.
end
(),
"ref_locked"
)
!=
sensor_names
.
end
())
{
std
::
cout
<<
"Waiting for reference lock..."
<<
std
::
flush
;
bool
ref_locked
=
false
;
for
(
int
i
=
0
;
i
<
30
and
not
ref_locked
;
i
++
)
{
for
(
int
i
=
0
;
i
<
30
and
not
ref_locked
;
i
++
)
{
ref_locked
=
s
->
usrp
->
get_mboard_sensor
(
"ref_locked"
,
mboard
).
to_bool
();
if
(
not
ref_locked
)
{
if
(
not
ref_locked
)
{
std
::
cout
<<
"."
<<
std
::
flush
;
boost
::
this_thread
::
sleep
(
boost
::
posix_time
::
seconds
(
1
));
}
}
if
(
ref_locked
)
{
if
(
ref_locked
)
{
std
::
cout
<<
"LOCKED"
<<
std
::
endl
;
}
else
{
std
::
cout
<<
"FAILED"
<<
std
::
endl
;
std
::
cout
<<
"Failed to lock to GPSDO 10 MHz Reference. Exiting."
<<
std
::
endl
;
exit
(
EXIT_FAILURE
);
}
}
else
{
}
else
{
std
::
cout
<<
boost
::
format
(
"ref_locked sensor not present on this board.
\n
"
);
}
//Wait for GPS lock
bool
gps_locked
=
s
->
usrp
->
get_mboard_sensor
(
"gps_locked"
,
mboard
).
to_bool
();
if
(
gps_locked
)
{
if
(
gps_locked
)
{
num_gps_locked
++
;
std
::
cout
<<
boost
::
format
(
"GPS Locked
\n
"
);
}
else
{
}
else
{
std
::
cerr
<<
"WARNING: GPS not locked - time will not be accurate until locked"
<<
std
::
endl
;
}
...
...
@@ -204,13 +190,11 @@ static int sync_to_gps(openair0_device *device)
uhd
::
time_spec_t
gps_time
=
uhd
::
time_spec_t
(
time_t
(
s
->
usrp
->
get_mboard_sensor
(
"gps_time"
,
mboard
).
to_int
()));
//s->usrp->set_time_next_pps(gps_time+1.0, mboard);
s
->
usrp
->
set_time_next_pps
(
uhd
::
time_spec_t
(
0.0
));
//Wait for it to apply
//The wait is 2 seconds because N-Series has a known issue where
//the time at the last PPS does not properly update at the PPS edge
//when the time is actually set.
boost
::
this_thread
::
sleep
(
boost
::
posix_time
::
seconds
(
2
));
//Check times
gps_time
=
uhd
::
time_spec_t
(
time_t
(
s
->
usrp
->
get_mboard_sensor
(
"gps_time"
,
mboard
).
to_int
()));
uhd
::
time_spec_t
time_last_pps
=
s
->
usrp
->
get_time_last_pps
(
mboard
);
...
...
@@ -222,27 +206,25 @@ static int sync_to_gps(openair0_device *device)
// std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl;
}
if
(
num_gps_locked
==
num_mboards
and
num_mboards
>
1
)
{
if
(
num_gps_locked
==
num_mboards
and
num_mboards
>
1
)
{
//Check to see if all USRP times are aligned
//First, wait for PPS.
uhd
::
time_spec_t
time_last_pps
=
s
->
usrp
->
get_time_last_pps
();
while
(
time_last_pps
==
s
->
usrp
->
get_time_last_pps
())
{
while
(
time_last_pps
==
s
->
usrp
->
get_time_last_pps
())
{
boost
::
this_thread
::
sleep
(
boost
::
posix_time
::
milliseconds
(
1
));
}
//Sleep a little to make sure all devices have seen a PPS edge
boost
::
this_thread
::
sleep
(
boost
::
posix_time
::
milliseconds
(
200
));
//Compare times across all mboards
bool
all_matched
=
true
;
uhd
::
time_spec_t
mboard0_time
=
s
->
usrp
->
get_time_last_pps
(
0
);
for
(
size_t
mboard
=
1
;
mboard
<
num_mboards
;
mboard
++
)
{
for
(
size_t
mboard
=
1
;
mboard
<
num_mboards
;
mboard
++
)
{
uhd
::
time_spec_t
mboard_time
=
s
->
usrp
->
get_time_last_pps
(
mboard
);
if
(
mboard_time
!=
mboard0_time
)
{
if
(
mboard_time
!=
mboard0_time
)
{
all_matched
=
false
;
std
::
cerr
<<
(
boost
::
format
(
"ERROR: Times are not aligned: USRP 0=%0.9f, USRP %d=%0.9f"
)
%
mboard0_time
.
get_real_secs
()
...
...
@@ -250,16 +232,14 @@ static int sync_to_gps(openair0_device *device)
%
mboard_time
.
get_real_secs
())
<<
std
::
endl
;
}
}
if
(
all_matched
)
{
if
(
all_matched
)
{
std
::
cout
<<
"SUCCESS: USRP times aligned"
<<
std
::
endl
<<
std
::
endl
;
}
else
{
std
::
cout
<<
"ERROR: USRP times are not aligned"
<<
std
::
endl
<<
std
::
endl
;
}
}
}
catch
(
std
::
exception
&
e
)
{
}
catch
(
std
::
exception
&
e
)
{
std
::
cout
<<
boost
::
format
(
"
\n
Error: %s"
)
%
e
.
what
();
std
::
cout
<<
boost
::
format
(
"This could mean that you have not installed the GPSDO correctly.
\n\n
"
);
std
::
cout
<<
boost
::
format
(
"Visit one of these pages if the problem persists:
\n
"
);
...
...
@@ -315,24 +295,18 @@ char config_hlp_sf_wdelay[] = CONFIG_HLP_SF_WDELAY;
@param device pointer to the device structure specific to the RF hardware target
*/
static
int
trx_usrp_start
(
openair0_device
*
device
)
{
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
!=
2
)
{
// not replay mode
#endif
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
// setup GPIO for TDD, GPIO(4) = ATR_RX
//set data direction register (DDR) to output
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"DDR"
,
0x1f
,
0x1f
);
//set control register to ATR
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"CTRL"
,
0x1f
,
0x1f
);
//set ATR register
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"ATR_RX"
,
1
<<
4
,
0x1f
);
// init recv and send streaming
uhd
::
stream_cmd_t
cmd
(
uhd
::
stream_cmd_t
::
STREAM_MODE_START_CONTINUOUS
);
LOG_I
(
PHY
,
"Time in secs now: %llu
\n
"
,
s
->
usrp
->
get_time_now
().
to_ticks
(
s
->
sample_rate
));
...
...
@@ -341,25 +315,23 @@ static int trx_usrp_start(openair0_device *device) {
if
(
s
->
use_gps
==
1
)
{
s
->
wait_for_first_pps
=
1
;
cmd
.
time_spec
=
s
->
usrp
->
get_time_last_pps
()
+
uhd
::
time_spec_t
(
1.0
);
}
else
{
}
else
{
s
->
wait_for_first_pps
=
0
;
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
);
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
;
#if defined(USRP_REC_PLAY)
}
#endif
return
0
;
}
...
...
@@ -369,12 +341,14 @@ static int trx_usrp_start(openair0_device *device) {
static
void
trx_usrp_end
(
openair0_device
*
device
)
{
#if defined(USRP_REC_PLAY) // For some ugly reason, this can be called several times...
static
int
done
=
0
;
if
(
done
==
1
)
return
;
done
=
1
;
if
(
u_sf_mode
!=
2
)
{
// not subframes replay
#endif
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
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
;
...
...
@@ -383,38 +357,48 @@ static void trx_usrp_end(openair0_device *device) {
sleep
(
1
);
#if defined(USRP_REC_PLAY)
}
#endif
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
==
1
)
{
// subframes store
pFile
=
fopen
(
u_sf_filename
,
"wb+"
);
if
(
pFile
==
NULL
)
{
std
::
cerr
<<
"Cannot open "
<<
u_sf_filename
<<
std
::
endl
;
}
else
{
unsigned
int
i
=
0
;
unsigned
int
modu
=
0
;
if
((
modu
=
nb_samples
%
10
)
!=
0
)
{
nb_samples
-=
modu
;
// store entire number of frames
}
std
::
cerr
<<
"Writing "
<<
nb_samples
<<
" subframes to "
<<
u_sf_filename
<<
" ..."
<<
std
::
endl
;
for
(
i
=
0
;
i
<
nb_samples
;
i
++
)
{
fwrite
(
ms_sample
+
i
,
sizeof
(
unsigned
char
),
sizeof
(
iqrec_t
),
pFile
);
}
fclose
(
pFile
);
std
::
cerr
<<
"File "
<<
u_sf_filename
<<
" closed."
<<
std
::
endl
;
}
}
if
(
u_sf_mode
==
1
)
{
// record
if
(
ms_sample
!=
NULL
)
{
free
((
void
*
)
ms_sample
);
free
((
void
*
)
ms_sample
);
ms_sample
=
NULL
;
}
}
if
(
u_sf_mode
==
2
)
{
// replay
if
(
use_mmap
)
{
if
(
ms_sample
!=
MAP_FAILED
)
{
munmap
(
ms_sample
,
sb
.
st_size
);
ms_sample
=
NULL
;
}
if
(
mmapfd
!=
0
)
{
close
(
mmapfd
);
mmapfd
=
0
;
...
...
@@ -424,12 +408,14 @@ static void trx_usrp_end(openair0_device *device) {
free
(
ms_sample
);
ms_sample
=
NULL
;
}
if
(
iqfd
!=
0
)
{
close
(
iqfd
);
iqfd
=
0
;
}
}
}
#endif
}
...
...
@@ -444,10 +430,10 @@ static void trx_usrp_end(openair0_device *device) {
static
int
trx_usrp_write
(
openair0_device
*
device
,
openair0_timestamp
timestamp
,
void
**
buff
,
int
nsamps
,
int
cc
,
int
flags
)
{
int
ret
=
0
;
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
!=
2
)
{
// not replay mode
#endif
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
int
nsamps2
;
// aligned to upper 32 or 16 byte boundary
#if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__
...
...
@@ -467,12 +453,12 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
for
(
int
j
=
0
;
j
<
nsamps2
;
j
++
)
{
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
buff_tx
[
i
][
j
]
=
_mm256_slli_epi16
(((
__m256i
*
)
buff
[
i
])[
j
],
4
);
buff_tx
[
i
][
j
]
=
_mm256_slli_epi16
(((
__m256i
*
)
buff
[
i
])[
j
],
4
);
#else
buff_tx
[
i
][
j
]
=
_mm_slli_epi16
(((
__m128i
*
)
buff
[
i
])[
j
],
4
);
buff_tx
[
i
][
j
]
=
_mm_slli_epi16
(((
__m128i
*
)
buff
[
i
])[
j
],
4
);
#endif
#elif defined(__arm__)
buff_tx
[
i
][
j
]
=
vshlq_n_s16
(((
int16x8_t
*
)
buff
[
i
])[
j
],
4
);
buff_tx
[
i
][
j
]
=
vshlq_n_s16
(((
int16x8_t
*
)
buff
[
i
])[
j
],
4
);
#endif
}
}
...
...
@@ -480,7 +466,6 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
s
->
tx_md
.
time_spec
=
uhd
::
time_spec_t
::
from_ticks
(
timestamp
,
s
->
sample_rate
);
s
->
tx_md
.
has_time_spec
=
flags
;
if
(
flags
>
0
)
s
->
tx_md
.
has_time_spec
=
true
;
else
...
...
@@ -499,23 +484,26 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
s
->
tx_md
.
start_of_burst
=
false
;
s
->
tx_md
.
end_of_burst
=
false
;
}
if
(
flags
==
10
){
// fail safe mode
if
(
flags
==
10
)
{
// fail safe mode
s
->
tx_md
.
has_time_spec
=
false
;
s
->
tx_md
.
start_of_burst
=
false
;
s
->
tx_md
.
end_of_burst
=
true
;
}
if
(
cc
>
1
)
{
std
::
vector
<
void
*>
buff_ptrs
;
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
buff_ptrs
.
push_back
(
buff_tx
[
i
]);
ret
=
(
int
)
s
->
tx_stream
->
send
(
buff_ptrs
,
nsamps
,
s
->
tx_md
,
1e-3
);
}
else
ret
=
(
int
)
s
->
tx_stream
->
send
(
buff_tx
[
0
],
nsamps
,
s
->
tx_md
,
1e-3
);
if
(
ret
!=
nsamps
)
LOG_E
(
PHY
,
"[xmit] tx samples %d != %d
\n
"
,
ret
,
nsamps
);
#if defined(USRP_REC_PLAY)
}
else
{
struct
timespec
req
;
...
...
@@ -524,8 +512,8 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
nanosleep
(
&
req
,
NULL
);
ret
=
nsamps
;
}
#endif
#endif
return
ret
;
}
...
...
@@ -541,10 +529,11 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
* \returns the number of sample read
*/
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
;
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(USRP_REC_PLAY)
if
(
u_sf_mode
!=
2
)
{
// not replay mode
#endif
#if defined(__x86_64) || defined(__i386__)
...
...
@@ -564,20 +553,29 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
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
->
wait_for_first_pps
==
0
)
&&
(
s
->
rx_md
.
error_code
!=
uhd
::
rx_metadata_t
::
ERROR_CODE_NONE
))
break
;
if
((
s
->
wait_for_first_pps
==
1
)
&&
(
samples_received
!=
nsamps
))
{
printf
(
"sleep...
\n
"
);}
//usleep(100);
if
((
s
->
wait_for_first_pps
==
1
)
&&
(
samples_received
!=
nsamps
))
{
printf
(
"sleep...
\n
"
);
//usleep(100);
}
}
if
(
samples_received
==
nsamps
)
s
->
wait_for_first_pps
=
0
;
}
// bring RX data into 12 LSBs for softmodem RX
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
{
for
(
int
j
=
0
;
j
<
nsamps2
;
j
++
)
{
...
...
@@ -588,7 +586,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
((
__m128i
*
)
buff
[
i
])[
j
]
=
_mm_srai_epi16
(
buff_tmp
[
i
][
j
],
4
);
#endif
#elif defined(__arm__)
((
int16x8_t
*
)
buff
[
i
])[
j
]
=
vshrq_n_s16
(
buff_tmp
[
i
][
j
],
4
);
((
int16x8_t
*
)
buff
[
i
])[
j
]
=
vshrq_n_s16
(
buff_tmp
[
i
][
j
],
4
);
#endif
}
}
...
...
@@ -598,12 +596,14 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
std
::
vector
<
void
*>
buff_ptrs
;
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
buff_ptrs
.
push_back
(
buff
[
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
[
0
],
nsamps
,
s
->
rx_md
);
}
}
if
(
samples_received
<
nsamps
)
LOG_E
(
PHY
,
"[recv] received %d samples out of %d
\n
"
,
samples_received
,
nsamps
);
...
...
@@ -615,8 +615,10 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
*
ptimestamp
=
s
->
rx_timestamp
;
#if defined (USRP_REC_PLAY)
}
#endif
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
==
1
)
{
// record mode
// Copy subframes to memory (later dump on a file)
if
(
nb_samples
<
u_sf_max
)
{
...
...
@@ -629,11 +631,14 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
if
(
cur_samples
==
nb_samples
)
{
cur_samples
=
0
;
wrap_count
++
;
if
(
wrap_count
==
u_sf_loops
)
{
std
::
cerr
<<
"USRP device terminating subframes replay mode after "
<<
u_sf_loops
<<
" loops."
<<
std
::
endl
;
return
0
;
// should make calling process exit
}
wrap_ts
=
wrap_count
*
(
nb_samples
*
(((
int
)(
device
->
openair0_cfg
[
0
].
sample_rate
))
/
1000
));
if
(
!
use_mmap
)
{
if
(
lseek
(
iqfd
,
0
,
SEEK_SET
)
==
0
)
{
std
::
cerr
<<
"Seeking at the beginning of IQ file"
<<
std
::
endl
;
...
...
@@ -642,13 +647,16 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
}
}
}
if
(
use_mmap
)
{
if
(
cur_samples
<
nb_samples
)
{
*
ptimestamp
=
(
ms_sample
[
0
].
ts
+
(
cur_samples
*
(((
int
)(
device
->
openair0_cfg
[
0
].
sample_rate
))
/
1000
)))
+
wrap_ts
;
if
(
cur_samples
==
0
)
{
std
::
cerr
<<
"starting subframes file with wrap_count="
<<
wrap_count
<<
" wrap_ts="
<<
wrap_ts
<<
" ts="
<<
*
ptimestamp
<<
std
::
endl
;
}
memcpy
(
buff
[
0
],
&
ms_sample
[
cur_samples
].
samples
[
0
],
nsamps
*
4
);
cur_samples
++
;
}
...
...
@@ -665,26 +673,36 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
if
(
cur_samples
<
nb_samples
)
{
static
int64_t
ts0
=
0
;
if
((
cur_samples
==
0
)
&&
(
wrap_count
==
0
))
{
ts0
=
ms_sample
->
ts
;
}
*
ptimestamp
=
ts0
+
(
cur_samples
*
(((
int
)(
device
->
openair0_cfg
[
0
].
sample_rate
))
/
1000
))
+
wrap_ts
;
if
(
cur_samples
==
0
)
{
std
::
cerr
<<
"starting subframes file with wrap_count="
<<
wrap_count
<<
" wrap_ts="
<<
wrap_ts
<<
" ts="
<<
*
ptimestamp
<<
std
::
endl
;
}
memcpy
(
buff
[
0
],
&
ms_sample
->
samples
[
0
],
nsamps
*
4
);
cur_samples
++
;
// Prepare for next read
off_t
where
=
lseek
(
iqfd
,
cur_samples
*
sizeof
(
iqrec_t
),
SEEK_SET
);
}
}
struct
timespec
req
;
req
.
tv_sec
=
0
;
req
.
tv_nsec
=
u_sf_read_delay
*
1000
;
nanosleep
(
&
req
,
NULL
);
return
nsamps
;
}
#endif
return
samples_received
;
}
...
...
@@ -698,10 +716,8 @@ static bool is_equal(double a, double b) {
}
void
*
freq_thread
(
void
*
arg
)
{
openair0_device
*
device
=
(
openair0_device
*
)
arg
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
s
->
usrp
->
set_tx_freq
(
device
->
openair0_cfg
[
0
].
tx_freq
[
0
]);
s
->
usrp
->
set_rx_freq
(
device
->
openair0_cfg
[
0
].
rx_freq
[
0
]);
}
...
...
@@ -711,23 +727,20 @@ void *freq_thread(void *arg) {
* \param dummy dummy variable not used
* \returns 0 in success
*/
int
trx_usrp_set_freq
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
,
int
dont_block
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
int
trx_usrp_set_freq
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
,
int
dont_block
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
pthread_t
f_thread
;
printf
(
"Setting USRP TX Freq %f, RX Freq %f
\n
"
,
openair0_cfg
[
0
].
tx_freq
[
0
],
openair0_cfg
[
0
].
rx_freq
[
0
]);
// spawn a thread to handle the frequency change to not block the calling thread
if
(
dont_block
==
1
)
pthread_create
(
&
f_thread
,
NULL
,
freq_thread
,(
void
*
)
device
);
pthread_create
(
&
f_thread
,
NULL
,
freq_thread
,(
void
*
)
device
);
else
{
s
->
usrp
->
set_tx_freq
(
device
->
openair0_cfg
[
0
].
tx_freq
[
0
]);
s
->
usrp
->
set_rx_freq
(
device
->
openair0_cfg
[
0
].
rx_freq
[
0
]);
}
return
(
0
);
}
/*! \brief Set RX frequencies
...
...
@@ -735,21 +748,16 @@ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,
* \param openair0_cfg RF frontend parameters set by application
* \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
;
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
;
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
);
return
(
0
);
}
/*! \brief Set Gains (TX/RX)
...
...
@@ -757,31 +765,31 @@ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *open
* \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success
*/
int
trx_usrp_set_gains
(
openair0_device
*
device
,
int
trx_usrp_set_gains
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
::
uhd
::
gain_range_t
gain_range_tx
=
s
->
usrp
->
get_tx_gain_range
(
0
);
s
->
usrp
->
set_tx_gain
(
gain_range_tx
.
stop
()
-
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
);
}
/*! \brief Stop USRP
* \param card refers to the hardware index to use
*/
int
trx_usrp_stop
(
openair0_device
*
device
)
{
int
trx_usrp_stop
(
openair0_device
*
device
)
{
return
(
0
);
}
...
...
@@ -821,45 +829,54 @@ rx_gain_calib_table_t calib_table_x310[] = {
* \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:
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
);
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
++
;
}
}
...
...
@@ -868,7 +885,7 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_
* \param device the hardware to use
* \returns 0 on success
*/
int
trx_usrp_get_stats
(
openair0_device
*
device
)
{
int
trx_usrp_get_stats
(
openair0_device
*
device
)
{
return
(
0
);
}
...
...
@@ -876,17 +893,17 @@ int trx_usrp_get_stats(openair0_device* device) {
* \param device the hardware to use
* \returns 0 on success
*/
int
trx_usrp_reset_stats
(
openair0_device
*
device
)
{
int
trx_usrp_reset_stats
(
openair0_device
*
device
)
{
return
(
0
);
}
#if defined(USRP_REC_PLAY)
extern
"C"
{
/*! \brief Initializer for USRP record/playback config
/*! \brief Initializer for USRP record/playback config
* \param parameter array description
* \returns 0 on success
*/
int
trx_usrp_recplay_config_init
(
paramdef_t
*
usrp_recplay_params
)
{
int
trx_usrp_recplay_config_init
(
paramdef_t
*
usrp_recplay_params
)
{
// --subframes-file
memcpy
(
usrp_recplay_params
[
0
].
optname
,
config_opt_sf_file
,
strlen
(
config_opt_sf_file
));
usrp_recplay_params
[
0
].
helpstr
=
config_hlp_sf_file
;
...
...
@@ -943,9 +960,8 @@ int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) {
usrp_recplay_params
[
6
].
defuintval
=
DEF_SF_DELAY_WRITE
;
usrp_recplay_params
[
6
].
type
=
TYPE_UINT
;
usrp_recplay_params
[
6
].
numelt
=
0
;
return
0
;
// always ok
}
}
}
#endif
...
...
@@ -954,32 +970,36 @@ extern "C" {
* \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
)
{
int
device_init
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
LOG_D
(
PHY
,
"openair0_cfg[0].sdr_addrs == '%s'
\n
"
,
openair0_cfg
[
0
].
sdr_addrs
);
LOG_D
(
PHY
,
"openair0_cfg[0].clock_source == '%d'
\n
"
,
openair0_cfg
[
0
].
clock_source
);
#if defined(USRP_REC_PLAY)
paramdef_t
usrp_recplay_params
[
7
];
struct
sysinfo
systeminfo
;
// to check
static
int
done
=
0
;
if
(
done
==
1
)
{
return
0
;
}
// prevent from multiple init
done
=
1
;
// end to check
// Use mmap for IQ files for systems with less than 6GB total RAM
sysinfo
(
&
systeminfo
);
if
(
systeminfo
.
totalram
<
6144000000
)
{
use_mmap
=
0
;
}
memset
(
usrp_recplay_params
,
0
,
7
*
sizeof
(
paramdef_t
));
memset
(
&
u_sf_filename
[
0
],
0
,
1024
);
if
(
trx_usrp_recplay_config_init
(
usrp_recplay_params
)
!=
0
)
{
std
::
cerr
<<
"USRP device record/replay mode configuration error exiting"
<<
std
::
endl
;
return
-
1
;
}
config_process_cmdline
(
usrp_recplay_params
,
sizeof
(
usrp_recplay_params
)
/
sizeof
(
paramdef_t
),
NULL
);
if
(
strlen
(
u_sf_filename
)
==
0
)
{
...
...
@@ -987,6 +1007,7 @@ extern "C" {
}
if
(
u_sf_replay
==
1
)
u_sf_mode
=
2
;
if
(
u_sf_record
==
1
)
u_sf_mode
=
1
;
if
(
u_sf_mode
==
2
)
{
...
...
@@ -1018,17 +1039,16 @@ extern "C" {
}
else
{
#endif
uhd
::
set_thread_priority_safe
(
1.0
);
usrp_state_t
*
s
=
(
usrp_state_t
*
)
calloc
(
sizeof
(
usrp_state_t
),
1
);
usrp_state_t
*
s
=
(
usrp_state_t
*
)
calloc
(
sizeof
(
usrp_state_t
),
1
);
if
(
openair0_cfg
[
0
].
clock_source
==
gpsdo
)
s
->
use_gps
=
1
;
// Initialize USRP device
device
->
openair0_cfg
=
openair0_cfg
;
std
::
string
args
=
"type=b200"
;
char
*
addr_args
=
NULL
;
// Check whether sdr_addrs is set in the config or not
if
(
openair0_cfg
[
0
].
sdr_addrs
!=
NULL
)
{
if
(
strcmp
(
openair0_cfg
[
0
].
sdr_addrs
,
"0.0.0.0"
)
!=
0
)
{
...
...
@@ -1050,21 +1070,20 @@ extern "C" {
}
uhd
::
device_addrs_t
device_adds
=
uhd
::
device
::
find
(
args
);
int
vers
=
0
,
subvers
=
0
,
subsubvers
=
0
;
int
bw_gain_adjust
=
0
;
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
==
1
)
{
std
::
cerr
<<
"USRP device initialized in subframes record mode"
<<
std
::
endl
;
}
#endif
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"
;
...
...
@@ -1074,24 +1093,23 @@ extern "C" {
// 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
)
{
args
+=
",addr=192.168.30.2"
;
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
if
(
openair0_cfg
[
0
].
clock_source
==
internal
)
s
->
usrp
->
set_clock_source
(
"internal"
);
...
...
@@ -1100,17 +1118,13 @@ extern "C" {
//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
;
#if defined(USRP_REC_PLAY)
std
::
cerr
<<
"-- Using calibration table: calib_table_x310"
<<
std
::
endl
;
// Bell Labs info
#endif
LOG_I
(
PHY
,
"%s() sample_rate:%u
\n
"
,
__FUNCTION__
,
(
int
)
openair0_cfg
[
0
].
sample_rate
);
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
...
...
@@ -1121,6 +1135,7 @@ extern "C" {
openair0_cfg
[
0
].
tx_bw
=
80e6
;
openair0_cfg
[
0
].
rx_bw
=
80e6
;
break
;
case
61440000
:
// from usrp_time_offset
//openair0_cfg[0].samples_per_packet = 2048;
...
...
@@ -1128,6 +1143,7 @@ extern "C" {
openair0_cfg
[
0
].
tx_bw
=
40e6
;
openair0_cfg
[
0
].
rx_bw
=
40e6
;
break
;
case
30720000
:
// from usrp_time_offset
//openair0_cfg[0].samples_per_packet = 2048;
...
...
@@ -1135,30 +1151,33 @@ extern "C" {
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:
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"
;
...
...
@@ -1173,15 +1192,15 @@ extern "C" {
// set master clock rate and sample rate for tx & rx for streaming
// lock mboard clocks
if
(
openair0_cfg
[
0
].
clock_source
==
internal
)
{
if
(
openair0_cfg
[
0
].
clock_source
==
internal
)
{
s
->
usrp
->
set_clock_source
(
"internal"
);
}
else
{
}
else
{
s
->
usrp
->
set_clock_source
(
"external"
);
s
->
usrp
->
set_time_source
(
"external"
);
}
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
;
...
...
@@ -1204,6 +1223,7 @@ extern "C" {
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;
...
...
@@ -1211,6 +1231,7 @@ extern "C" {
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;
...
...
@@ -1218,6 +1239,7 @@ extern "C" {
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;
...
...
@@ -1225,6 +1247,7 @@ extern "C" {
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;
...
...
@@ -1232,6 +1255,7 @@ extern "C" {
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
);
...
...
@@ -1250,7 +1274,6 @@ extern "C" {
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
(),
...
...
@@ -1265,42 +1288,45 @@ extern "C" {
LOG_D
(
PHY
,
"usrp->get_tx_num_channels() == %zd
\n
"
,
s
->
usrp
->
get_tx_num_channels
());
LOG_D
(
PHY
,
"openair0_cfg[0].tx_num_channels == %d
\n
"
,
openair0_cfg
[
0
].
tx_num_channels
);
for
(
int
i
=
0
;
i
<
s
->
usrp
->
get_tx_num_channels
();
i
++
)
{
::
uhd
::
gain_range_t
gain_range_tx
=
s
->
usrp
->
get_tx_gain_range
(
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
(
gain_range_tx
.
stop
()
-
openair0_cfg
[
0
].
tx_gain
[
i
],
i
);
LOG_I
(
PHY
,
"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf
\n
"
,
gain_range_tx
.
stop
()
-
openair0_cfg
[
0
].
tx_gain
[
i
],
gain_range_tx
.
stop
(),
openair0_cfg
[
0
].
tx_gain
[
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
);
sleep
(
1
);
// create tx & rx streamer
uhd
::
stream_args_t
stream_args_rx
(
"sc16"
,
"sc16"
);
int
samples
=
openair0_cfg
[
0
].
sample_rate
;
int
max
=
s
->
usrp
->
get_rx_stream
(
stream_args_rx
)
->
get_max_num_samps
();
samples
/=
10000
;
LOG_I
(
PHY
,
"RF board max packet size %u, size for 100µs jitter %d
\n
"
,
max
,
samples
);
if
(
samples
<
max
)
stream_args_rx
.
args
[
"spp"
]
=
str
(
boost
::
format
(
"%d"
)
%
samples
);
LOG_I
(
PHY
,
"rx_max_num_samps %zu
\n
"
,
s
->
usrp
->
get_rx_stream
(
stream_args_rx
)
->
get_max_num_samps
());
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
);
s
->
rx_stream
=
s
->
usrp
->
get_rx_stream
(
stream_args_rx
);
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 */
...
...
@@ -1329,7 +1355,6 @@ extern "C" {
}
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
;
...
...
@@ -1341,14 +1366,16 @@ extern "C" {
device
->
trx_set_freq_func
=
trx_usrp_set_freq
;
device
->
trx_set_gains_func
=
trx_usrp_set_gains
;
device
->
openair0_cfg
=
openair0_cfg
;
s
->
sample_rate
=
openair0_cfg
[
0
].
sample_rate
;
// TODO:
// init tx_forward_nsamps based usrp_time_offset ex
if
(
is_equal
(
s
->
sample_rate
,
(
double
)
30.72e6
))
s
->
tx_forward_nsamps
=
176
;
if
(
is_equal
(
s
->
sample_rate
,
(
double
)
15.36e6
))
s
->
tx_forward_nsamps
=
90
;
if
(
is_equal
(
s
->
sample_rate
,
(
double
)
7.68e6
))
s
->
tx_forward_nsamps
=
50
;
...
...
@@ -1361,28 +1388,36 @@ extern "C" {
#if defined(USRP_REC_PLAY)
}
#endif
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
==
1
)
{
// record mode
ms_sample
=
(
iqrec_t
*
)
malloc
(
u_sf_max
*
sizeof
(
iqrec_t
));
ms_sample
=
(
iqrec_t
*
)
malloc
(
u_sf_max
*
sizeof
(
iqrec_t
));
if
(
ms_sample
==
NULL
)
{
std
::
cerr
<<
"Memory allocation failed for subframe record or replay mode."
<<
std
::
endl
;
exit
(
-
1
);
}
memset
(
ms_sample
,
0
,
u_sf_max
*
BELL_LABS_IQ_BYTES_PER_SF
);
}
if
(
u_sf_mode
==
2
)
{
if
(
use_mmap
)
{
// use mmap
mmapfd
=
open
(
u_sf_filename
,
O_RDONLY
|
O_LARGEFILE
);
if
(
mmapfd
!=
0
)
{
fstat
(
mmapfd
,
&
sb
);
std
::
cerr
<<
"Loading subframes using mmap() from "
<<
u_sf_filename
<<
" size="
<<
(
uint64_t
)
sb
.
st_size
<<
" bytes ..."
<<
std
::
endl
;
ms_sample
=
(
iqrec_t
*
)
mmap
(
NULL
,
sb
.
st_size
,
PROT_WRITE
,
MAP_PRIVATE
,
mmapfd
,
0
);
ms_sample
=
(
iqrec_t
*
)
mmap
(
NULL
,
sb
.
st_size
,
PROT_WRITE
,
MAP_PRIVATE
,
mmapfd
,
0
);
if
(
ms_sample
!=
MAP_FAILED
)
{
nb_samples
=
(
sb
.
st_size
/
sizeof
(
iqrec_t
));
int
aligned
=
(((
unsigned
long
)
ms_sample
&
31
)
==
0
)
?
1
:
0
;
std
::
cerr
<<
"Loaded "
<<
nb_samples
<<
" subframes."
<<
std
::
endl
;
if
(
aligned
==
0
)
{
std
::
cerr
<<
"mmap address is not 32 bytes aligned, exiting."
<<
std
::
endl
;
close
(
mmapfd
);
...
...
@@ -1399,19 +1434,23 @@ extern "C" {
}
}
else
{
iqfd
=
open
(
u_sf_filename
,
O_RDONLY
|
O_LARGEFILE
);
if
(
iqfd
!=
0
)
{
fstat
(
iqfd
,
&
sb
);
nb_samples
=
(
sb
.
st_size
/
sizeof
(
iqrec_t
));
std
::
cerr
<<
"Loading "
<<
nb_samples
<<
" subframes from "
<<
u_sf_filename
<<
" size="
<<
(
uint64_t
)
sb
.
st_size
<<
" bytes ..."
<<
std
::
endl
;
// allocate buffer for 1 sample at a time
ms_sample
=
(
iqrec_t
*
)
malloc
(
sizeof
(
iqrec_t
));
ms_sample
=
(
iqrec_t
*
)
malloc
(
sizeof
(
iqrec_t
));
if
(
ms_sample
==
NULL
)
{
std
::
cerr
<<
"Memory allocation failed for individual subframe replay mode."
<<
std
::
endl
;
close
(
iqfd
);
exit
(
-
1
);
}
memset
(
ms_sample
,
0
,
sizeof
(
iqrec_t
));
// point at beginning of file
if
(
lseek
(
iqfd
,
0
,
SEEK_SET
)
==
0
)
{
std
::
cerr
<<
"Initial seek at beginning of the file"
<<
std
::
endl
;
...
...
@@ -1424,6 +1463,7 @@ extern "C" {
}
}
}
#endif
return
0
;
}
...
...
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