Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG UE
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
OpenXG UE
Commits
679485c1
Commit
679485c1
authored
Oct 04, 2018
by
Raphael Defosseux
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/352-support-for-n300' into develop_integration_2018_w40
parents
75e4d96c
33dea061
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
970 additions
and
1053 deletions
+970
-1053
openair1/SCHED/ru_procedures.c
openair1/SCHED/ru_procedures.c
+0
-4
openair2/ENB_APP/enb_paramdef.h
openair2/ENB_APP/enb_paramdef.h
+1
-1
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+940
-929
targets/RT/USER/lte-enb.c
targets/RT/USER/lte-enb.c
+0
-2
targets/RT/USER/lte-softmodem.c
targets/RT/USER/lte-softmodem.c
+0
-116
targets/RT/USER/lte-softmodem.h
targets/RT/USER/lte-softmodem.h
+6
-1
targets/RT/USER/lte-uesoftmodem.c
targets/RT/USER/lte-uesoftmodem.c
+23
-0
No files found.
openair1/SCHED/ru_procedures.c
View file @
679485c1
...
@@ -50,10 +50,6 @@
...
@@ -50,10 +50,6 @@
#include "targets/RT/USER/rt_wrapper.h"
#include "targets/RT/USER/rt_wrapper.h"
// RU OFDM Modulator, used in IF4p5 RRU, RCC/RAU with IF5, eNodeB
extern
openair0_config_t
openair0_cfg
[
MAX_CARDS
];
extern
int
oai_exit
;
extern
int
oai_exit
;
...
...
openair2/ENB_APP/enb_paramdef.h
View file @
679485c1
...
@@ -146,7 +146,7 @@ typedef enum {
...
@@ -146,7 +146,7 @@ typedef enum {
{CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \
{CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \
{CONFIG_STRING_RU_SDR_ADDRS, NULL, 0, strptr:NULL, defstrval:"
0.0.0.
0", TYPE_STRING, 0}, \
{CONFIG_STRING_RU_SDR_ADDRS, NULL, 0, strptr:NULL, defstrval:"
type=b20
0", TYPE_STRING, 0}, \
{CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \
{CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \
}
}
...
...
targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
View file @
679485c1
...
@@ -65,211 +65,191 @@
...
@@ -65,211 +65,191 @@
/*! \brief USRP Configuration */
/*! \brief USRP Configuration */
typedef
struct
{
typedef
struct
{
// --------------------------------
// --------------------------------
// variables for USRP configuration
// variables for USRP configuration
// --------------------------------
// --------------------------------
//! USRP device pointer
//! USRP device pointer
uhd
::
usrp
::
multi_usrp
::
sptr
usrp
;
uhd
::
usrp
::
multi_usrp
::
sptr
usrp
;
//create a send streamer and a receive streamer
//create a send streamer and a receive streamer
//! USRP TX Stream
//! USRP TX Stream
uhd
::
tx_streamer
::
sptr
tx_stream
;
uhd
::
tx_streamer
::
sptr
tx_stream
;
//! USRP RX Stream
//! USRP RX Stream
uhd
::
rx_streamer
::
sptr
rx_stream
;
uhd
::
rx_streamer
::
sptr
rx_stream
;
//! USRP TX Metadata
//! USRP TX Metadata
uhd
::
tx_metadata_t
tx_md
;
uhd
::
tx_metadata_t
tx_md
;
//! USRP RX Metadata
//! USRP RX Metadata
uhd
::
rx_metadata_t
rx_md
;
uhd
::
rx_metadata_t
rx_md
;
//! Sampling rate
//! Sampling rate
double
sample_rate
;
double
sample_rate
;
//! TX forward samples. We use usrp_time_offset to get this value
//! TX forward samples. We use usrp_time_offset to get this value
int
tx_forward_nsamps
;
//166 for 20Mhz
int
tx_forward_nsamps
;
//166 for 20Mhz
// --------------------------------
// --------------------------------
// Debug and output control
// Debug and output control
// --------------------------------
// --------------------------------
int
num_underflows
;
int
num_underflows
;
int
num_overflows
;
int
num_overflows
;
int
num_seq_errors
;
int
num_seq_errors
;
int64_t
tx_count
;
int64_t
tx_count
;
int64_t
rx_count
;
int64_t
rx_count
;
int
wait_for_first_pps
;
int
wait_for_first_pps
;
int
use_gps
;
int
use_gps
;
//! timestamp of RX packet
//! timestamp of RX packet
openair0_timestamp
rx_timestamp
;
openair0_timestamp
rx_timestamp
;
}
usrp_state_t
;
}
usrp_state_t
;
//void print_notes(void)
//void print_notes(void)
//{
//{
// Helpful notes
// Helpful notes
// std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n");
// 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("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("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("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n");
// std::cout << boost::format("****************************************************************************************************************\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
();
uhd
::
set_thread_priority_safe
();
//std::string args;
//Set up program options
//std::string args;
//po::options_description desc("Allowed options");
//desc.add_options()
//Set up program options
//("help", "help message")
//po::options_description desc("Allowed options");
//("args", po::value<std::string>(&args)->default_value(""), "USRP device arguments")
//desc.add_options()
//;
//("help", "help message")
//po::variables_map vm;
//("args", po::value<std::string>(&args)->default_value(""), "USRP device arguments")
//po::store(po::parse_command_line(argc, argv, desc), vm);
//;
//po::notify(vm);
//po::variables_map vm;
//Print the help message
//po::store(po::parse_command_line(argc, argv, desc), vm);
//if (vm.count("help"))
//po::notify(vm);
//{
// std::cout << boost::format("Synchronize USRP to GPS %s") % desc << std::endl;
//Print the help message
// return EXIT_FAILURE;
//if (vm.count("help"))
//}
//{
//Create a USRP device
// std::cout << boost::format("Synchronize USRP to GPS %s") % desc << std::endl;
//std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args;
// return EXIT_FAILURE;
//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
;
//Create a USRP device
//std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args;
try
{
//uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
size_t
num_mboards
=
s
->
usrp
->
get_num_mboards
();
//std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string();
size_t
num_gps_locked
=
0
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
for
(
size_t
mboard
=
0
;
mboard
<
num_mboards
;
mboard
++
)
{
std
::
cout
<<
"Synchronizing mboard "
<<
mboard
<<
": "
<<
s
->
usrp
->
get_mboard_name
(
mboard
)
<<
std
::
endl
;
try
//Set references to GPSDO
{
s
->
usrp
->
set_clock_source
(
"gpsdo"
,
mboard
);
size_t
num_mboards
=
s
->
usrp
->
get_num_mboards
();
s
->
usrp
->
set_time_source
(
"gpsdo"
,
mboard
);
size_t
num_gps_locked
=
0
;
//std::cout << std::endl;
for
(
size_t
mboard
=
0
;
mboard
<
num_mboards
;
mboard
++
)
//print_notes();
{
//std::cout << std::endl;
std
::
cout
<<
"Synchronizing mboard "
<<
mboard
<<
": "
<<
s
->
usrp
->
get_mboard_name
(
mboard
)
<<
std
::
endl
;
//Check for 10 MHz lock
std
::
vector
<
std
::
string
>
sensor_names
=
s
->
usrp
->
get_mboard_sensor_names
(
mboard
);
//Set references to GPSDO
s
->
usrp
->
set_clock_source
(
"gpsdo"
,
mboard
);
if
(
std
::
find
(
sensor_names
.
begin
(),
sensor_names
.
end
(),
"ref_locked"
)
!=
sensor_names
.
end
())
{
s
->
usrp
->
set_time_source
(
"gpsdo"
,
mboard
);
std
::
cout
<<
"Waiting for reference lock..."
<<
std
::
flush
;
bool
ref_locked
=
false
;
//std::cout << std::endl;
//print_notes();
for
(
int
i
=
0
;
i
<
30
and
not
ref_locked
;
i
++
)
{
//std::cout << std::endl;
ref_locked
=
s
->
usrp
->
get_mboard_sensor
(
"ref_locked"
,
mboard
).
to_bool
();
//Check for 10 MHz lock
if
(
not
ref_locked
)
{
std
::
vector
<
std
::
string
>
sensor_names
=
s
->
usrp
->
get_mboard_sensor_names
(
mboard
);
std
::
cout
<<
"."
<<
std
::
flush
;
if
(
std
::
find
(
sensor_names
.
begin
(),
sensor_names
.
end
(),
"ref_locked"
)
!=
sensor_names
.
end
())
boost
::
this_thread
::
sleep
(
boost
::
posix_time
::
seconds
(
1
));
{
}
std
::
cout
<<
"Waiting for reference lock..."
<<
std
::
flush
;
}
bool
ref_locked
=
false
;
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
)
{
std
::
cout
<<
"."
<<
std
::
flush
;
boost
::
this_thread
::
sleep
(
boost
::
posix_time
::
seconds
(
1
));
}
}
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
{
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
)
{
num_gps_locked
++
;
std
::
cout
<<
boost
::
format
(
"GPS Locked
\n
"
);
}
else
{
std
::
cerr
<<
"WARNING: GPS not locked - time will not be accurate until locked"
<<
std
::
endl
;
}
//Set to GPS time
if
(
ref_locked
)
{
uhd
::
time_spec_t
gps_time
=
uhd
::
time_spec_t
(
time_t
(
s
->
usrp
->
get_mboard_sensor
(
"gps_time"
,
mboard
).
to_int
()));
std
::
cout
<<
"LOCKED"
<<
std
::
endl
;
//s->usrp->set_time_next_pps(gps_time+1.0, mboard);
}
else
{
s
->
usrp
->
set_time_next_pps
(
uhd
::
time_spec_t
(
0.0
));
std
::
cout
<<
"FAILED"
<<
std
::
endl
;
std
::
cout
<<
"Failed to lock to GPSDO 10 MHz Reference. Exiting."
<<
std
::
endl
;
//Wait for it to apply
exit
(
EXIT_FAILURE
);
//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
);
std
::
cout
<<
"USRP time: "
<<
(
boost
::
format
(
"%0.9f"
)
%
time_last_pps
.
get_real_secs
())
<<
std
::
endl
;
std
::
cout
<<
"GPSDO time: "
<<
(
boost
::
format
(
"%0.9f"
)
%
gps_time
.
get_real_secs
())
<<
std
::
endl
;
//if (gps_time.get_real_secs() == time_last_pps.get_real_secs())
// std::cout << std::endl << "SUCCESS: USRP time synchronized to GPS time" << std::endl << std::endl;
//else
// std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl;
}
}
}
else
{
std
::
cout
<<
boost
::
format
(
"ref_locked sensor not present on this board.
\n
"
);
}
if
(
num_gps_locked
==
num_mboards
and
num_mboards
>
1
)
//Wait for GPS lock
{
bool
gps_locked
=
s
->
usrp
->
get_mboard_sensor
(
"gps_locked"
,
mboard
).
to_bool
();
//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
())
{
boost
::
this_thread
::
sleep
(
boost
::
posix_time
::
milliseconds
(
1
));
}
//Sleep a little to make sure all devices have seen a PPS edge
if
(
gps_locked
)
{
boost
::
this_thread
::
sleep
(
boost
::
posix_time
::
milliseconds
(
200
))
;
num_gps_locked
++
;
std
::
cout
<<
boost
::
format
(
"GPS Locked
\n
"
);
//Compare times across all mboards
}
else
{
bool
all_matched
=
true
;
std
::
cerr
<<
"WARNING: GPS not locked - time will not be accurate until locked"
<<
std
::
endl
;
uhd
::
time_spec_t
mboard0_time
=
s
->
usrp
->
get_time_last_pps
(
0
);
}
for
(
size_t
mboard
=
1
;
mboard
<
num_mboards
;
mboard
++
)
{
//Set to GPS time
uhd
::
time_spec_t
mboard_time
=
s
->
usrp
->
get_time_last_pps
(
mboard
);
uhd
::
time_spec_t
gps_time
=
uhd
::
time_spec_t
(
time_t
(
s
->
usrp
->
get_mboard_sensor
(
"gps_time"
,
mboard
).
to_int
())
);
if
(
mboard_time
!=
mboard0_time
)
//s->usrp->set_time_next_pps(gps_time+1.0, mboard);
{
s
->
usrp
->
set_time_next_pps
(
uhd
::
time_spec_t
(
0.0
));
all_matched
=
false
;
//Wait for it to apply
std
::
cerr
<<
(
boost
::
format
(
"ERROR: Times are not aligned: USRP 0=%0.9f, USRP %d=%0.9f"
)
//The wait is 2 seconds because N-Series has a known issue where
%
mboard0_time
.
get_real_secs
()
//the time at the last PPS does not properly update at the PPS edge
%
mboard
//when the time is actually set.
%
mboard_time
.
get_real_secs
())
<<
std
::
endl
;
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
()));
if
(
all_matched
)
uhd
::
time_spec_t
time_last_pps
=
s
->
usrp
->
get_time_last_pps
(
mboard
);
{
std
::
cout
<<
"USRP time: "
<<
(
boost
::
format
(
"%0.9f"
)
%
time_last_pps
.
get_real_secs
())
<<
std
::
endl
;
std
::
cout
<<
"SUCCESS: USRP times aligned"
<<
std
::
endl
<<
std
::
endl
;
std
::
cout
<<
"GPSDO time: "
<<
(
boost
::
format
(
"%0.9f"
)
%
gps_time
.
get_real_secs
())
<<
std
::
endl
;
}
else
{
//if (gps_time.get_real_secs() == time_last_pps.get_real_secs())
std
::
cout
<<
"ERROR: USRP times are not aligned
"
<<
std
::
endl
<<
std
::
endl
;
// std::cout << std::endl << "SUCCESS: USRP time synchronized to GPS time
" << std::endl << std::endl;
}
//else
}
// std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl;
}
}
catch
(
std
::
exception
&
e
)
{
if
(
num_gps_locked
==
num_mboards
and
num_mboards
>
1
)
{
std
::
cout
<<
boost
::
format
(
"
\n
Error: %s"
)
%
e
.
what
();
//Check to see if all USRP times are aligned
std
::
cout
<<
boost
::
format
(
"This could mean that you have not installed the GPSDO correctly.
\n\n
"
);
//First, wait for PPS.
std
::
cout
<<
boost
::
format
(
"Visit one of these pages if the problem persists:
\n
"
);
uhd
::
time_spec_t
time_last_pps
=
s
->
usrp
->
get_time_last_pps
();
std
::
cout
<<
boost
::
format
(
" * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html"
);
std
::
cout
<<
boost
::
format
(
" * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html
\n\n
"
);
while
(
time_last_pps
==
s
->
usrp
->
get_time_last_pps
())
{
std
::
cout
<<
boost
::
format
(
" * E3X0: http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_hw_gps
\n\n
"
);
boost
::
this_thread
::
sleep
(
boost
::
posix_time
::
milliseconds
(
1
));
exit
(
EXIT_FAILURE
);
}
//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
++
)
{
uhd
::
time_spec_t
mboard_time
=
s
->
usrp
->
get_time_last_pps
(
mboard
);
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
()
%
mboard
%
mboard_time
.
get_real_secs
())
<<
std
::
endl
;
}
}
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
)
{
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
"
);
std
::
cout
<<
boost
::
format
(
" * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html"
);
std
::
cout
<<
boost
::
format
(
" * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html
\n\n
"
);
std
::
cout
<<
boost
::
format
(
" * E3X0: http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_hw_gps
\n\n
"
);
exit
(
EXIT_FAILURE
);
}
return
EXIT_SUCCESS
;
return
EXIT_SUCCESS
;
}
}
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
...
@@ -315,24 +295,18 @@ char config_hlp_sf_wdelay[] = CONFIG_HLP_SF_WDELAY;
...
@@ -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
@param device pointer to the device structure specific to the RF hardware target
*/
*/
static
int
trx_usrp_start
(
openair0_device
*
device
)
{
static
int
trx_usrp_start
(
openair0_device
*
device
)
{
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
!=
2
)
{
// not replay mode
#endif
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
if
(
u_sf_mode
!=
2
)
{
// not replay mode
// setup GPIO for TDD, GPIO(4) = ATR_RX
#endif
//set data direction register (DDR) to output
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
);
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"DDR"
,
0x1f
,
0x1f
);
//set control register to ATR
//set control register to ATR
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"CTRL"
,
0x1f
,
0x1f
);
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"CTRL"
,
0x1f
,
0x1f
);
//set ATR register
//set ATR register
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"ATR_RX"
,
1
<<
4
,
0x1f
);
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"ATR_RX"
,
1
<<
4
,
0x1f
);
// init recv and send streaming
// init recv and send streaming
uhd
::
stream_cmd_t
cmd
(
uhd
::
stream_cmd_t
::
STREAM_MODE_START_CONTINUOUS
);
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
));
LOG_I
(
PHY
,
"Time in secs now: %llu
\n
"
,
s
->
usrp
->
get_time_now
().
to_ticks
(
s
->
sample_rate
));
...
@@ -340,28 +314,26 @@ static int trx_usrp_start(openair0_device *device) {
...
@@ -340,28 +314,26 @@ static int trx_usrp_start(openair0_device *device) {
if
(
s
->
use_gps
==
1
)
{
if
(
s
->
use_gps
==
1
)
{
s
->
wait_for_first_pps
=
1
;
s
->
wait_for_first_pps
=
1
;
cmd
.
time_spec
=
s
->
usrp
->
get_time_last_pps
()
+
uhd
::
time_spec_t
(
1.0
);
cmd
.
time_spec
=
s
->
usrp
->
get_time_last_pps
()
+
uhd
::
time_spec_t
(
1.0
);
}
}
else
{
else
{
s
->
wait_for_first_pps
=
0
;
s
->
wait_for_first_pps
=
0
;
cmd
.
time_spec
=
s
->
usrp
->
get_time_now
()
+
uhd
::
time_spec_t
(
0.05
);
cmd
.
time_spec
=
s
->
usrp
->
get_time_now
()
+
uhd
::
time_spec_t
(
0.05
);
}
}
cmd
.
stream_now
=
false
;
// start at constant delay
cmd
.
stream_now
=
false
;
// start at constant delay
s
->
rx_stream
->
issue_stream_cmd
(
cmd
);
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
.
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
.
has_time_spec
=
true
;
s
->
tx_md
.
start_of_burst
=
true
;
s
->
tx_md
.
start_of_burst
=
true
;
s
->
tx_md
.
end_of_burst
=
false
;
s
->
tx_md
.
end_of_burst
=
false
;
s
->
rx_count
=
0
;
s
->
rx_count
=
0
;
s
->
tx_count
=
0
;
s
->
tx_count
=
0
;
s
->
rx_timestamp
=
0
;
s
->
rx_timestamp
=
0
;
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
}
}
#endif
return
0
;
#endif
return
0
;
}
}
/*! \brief Terminate operation of the USRP transceiver -- free all associated resources
/*! \brief Terminate operation of the USRP transceiver -- free all associated resources
* \param device the hardware to use
* \param device the hardware to use
...
@@ -369,12 +341,14 @@ static int trx_usrp_start(openair0_device *device) {
...
@@ -369,12 +341,14 @@ static int trx_usrp_start(openair0_device *device) {
static
void
trx_usrp_end
(
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...
#if defined(USRP_REC_PLAY) // For some ugly reason, this can be called several times...
static
int
done
=
0
;
static
int
done
=
0
;
if
(
done
==
1
)
return
;
if
(
done
==
1
)
return
;
done
=
1
;
done
=
1
;
if
(
u_sf_mode
!=
2
)
{
// not subframes replay
#endif
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
if
(
u_sf_mode
!=
2
)
{
// not subframes replay
#endif
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
//send a mini EOB packet
s
->
tx_md
.
end_of_burst
=
true
;
s
->
tx_md
.
end_of_burst
=
true
;
...
@@ -382,55 +356,67 @@ static void trx_usrp_end(openair0_device *device) {
...
@@ -382,55 +356,67 @@ static void trx_usrp_end(openair0_device *device) {
s
->
tx_md
.
end_of_burst
=
false
;
s
->
tx_md
.
end_of_burst
=
false
;
sleep
(
1
);
sleep
(
1
);
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
}
}
#endif
#endif
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
==
1
)
{
// subframes store
pFile
=
fopen
(
u_sf_filename
,
"wb+"
);
if
(
u_sf_mode
==
1
)
{
// subframes store
if
(
pFile
==
NULL
)
{
pFile
=
fopen
(
u_sf_filename
,
"wb+"
);
std
::
cerr
<<
"Cannot open "
<<
u_sf_filename
<<
std
::
endl
;
}
else
{
if
(
pFile
==
NULL
)
{
unsigned
int
i
=
0
;
std
::
cerr
<<
"Cannot open "
<<
u_sf_filename
<<
std
::
endl
;
unsigned
int
modu
=
0
;
}
else
{
if
((
modu
=
nb_samples
%
10
)
!=
0
)
{
unsigned
int
i
=
0
;
nb_samples
-=
modu
;
// store entire number of frames
unsigned
int
modu
=
0
;
}
std
::
cerr
<<
"Writing "
<<
nb_samples
<<
" subframes to "
<<
u_sf_filename
<<
" ..."
<<
std
::
endl
;
if
((
modu
=
nb_samples
%
10
)
!=
0
)
{
for
(
i
=
0
;
i
<
nb_samples
;
i
++
)
{
nb_samples
-=
modu
;
// store entire number of frames
fwrite
(
ms_sample
+
i
,
sizeof
(
unsigned
char
),
sizeof
(
iqrec_t
),
pFile
);
}
fclose
(
pFile
);
std
::
cerr
<<
"File "
<<
u_sf_filename
<<
" closed."
<<
std
::
endl
;
}
}
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
(
u_sf_mode
==
1
)
{
// record
if
(
ms_sample
!=
NULL
)
{
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
;
}
}
else
{
if
(
ms_sample
!=
NULL
)
{
if
(
ms_sample
!=
NULL
)
{
free
((
void
*
)
ms_sample
);
free
(
ms_sample
);
ms_sample
=
NULL
;
ms_sample
=
NULL
;
}
}
}
if
(
u_sf_mode
==
2
)
{
// replay
if
(
iqfd
!=
0
)
{
if
(
use_mmap
)
{
close
(
iqfd
);
if
(
ms_sample
!=
MAP_FAILED
)
{
iqfd
=
0
;
munmap
(
ms_sample
,
sb
.
st_size
);
ms_sample
=
NULL
;
}
if
(
mmapfd
!=
0
)
{
close
(
mmapfd
);
mmapfd
=
0
;
}
}
else
{
if
(
ms_sample
!=
NULL
)
{
free
(
ms_sample
);
ms_sample
=
NULL
;
}
if
(
iqfd
!=
0
)
{
close
(
iqfd
);
iqfd
=
0
;
}
}
}
}
}
#endif
}
#endif
}
}
/*! \brief Called to send samples to the USRP RF target
/*! \brief Called to send samples to the USRP RF target
...
@@ -444,78 +430,80 @@ static void trx_usrp_end(openair0_device *device) {
...
@@ -444,78 +430,80 @@ 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
)
{
static
int
trx_usrp_write
(
openair0_device
*
device
,
openair0_timestamp
timestamp
,
void
**
buff
,
int
nsamps
,
int
cc
,
int
flags
)
{
int
ret
=
0
;
int
ret
=
0
;
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
!=
2
)
{
// not replay mode
if
(
u_sf_mode
!=
2
)
{
// not replay mode
#endif
#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
int
nsamps2
;
// aligned to upper 32 or 16 byte boundary
#if defined(__x86_64) || defined(__i386__)
#if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__
#ifdef __AVX2__
nsamps2
=
(
nsamps
+
7
)
>>
3
;
nsamps2
=
(
nsamps
+
7
)
>>
3
;
__m256i
buff_tx
[
2
][
nsamps2
];
__m256i
buff_tx
[
2
][
nsamps2
];
#else
#else
nsamps2
=
(
nsamps
+
3
)
>>
2
;
nsamps2
=
(
nsamps
+
3
)
>>
2
;
__m128i
buff_tx
[
2
][
nsamps2
];
__m128i
buff_tx
[
2
][
nsamps2
];
#endif
#endif
#elif defined(__arm__)
#elif defined(__arm__)
nsamps2
=
(
nsamps
+
3
)
>>
2
;
nsamps2
=
(
nsamps
+
3
)
>>
2
;
int16x8_t
buff_tx
[
2
][
nsamps2
];
int16x8_t
buff_tx
[
2
][
nsamps2
];
#endif
#endif
// bring RX data into 12 LSBs for softmodem RX
// bring RX data into 12 LSBs for softmodem RX
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
{
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
{
for
(
int
j
=
0
;
j
<
nsamps2
;
j
++
)
{
for
(
int
j
=
0
;
j
<
nsamps2
;
j
++
)
{
#if defined(__x86_64__) || defined(__i386__)
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
#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
#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
#endif
#elif defined(__arm__)
#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
#endif
}
}
}
}
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
;
s
->
tx_md
.
has_time_spec
=
flags
;
if
(
flags
>
0
)
if
(
flags
>
0
)
s
->
tx_md
.
has_time_spec
=
true
;
s
->
tx_md
.
has_time_spec
=
true
;
else
else
s
->
tx_md
.
has_time_spec
=
false
;
s
->
tx_md
.
has_time_spec
=
false
;
if
(
flags
==
2
)
{
// start of burst
if
(
flags
==
2
)
{
// start of burst
s
->
tx_md
.
start_of_burst
=
true
;
s
->
tx_md
.
start_of_burst
=
true
;
s
->
tx_md
.
end_of_burst
=
false
;
s
->
tx_md
.
end_of_burst
=
false
;
}
else
if
(
flags
==
3
)
{
// end of burst
}
else
if
(
flags
==
3
)
{
// end of burst
s
->
tx_md
.
start_of_burst
=
false
;
s
->
tx_md
.
start_of_burst
=
false
;
s
->
tx_md
.
end_of_burst
=
true
;
s
->
tx_md
.
end_of_burst
=
true
;
}
else
if
(
flags
==
4
)
{
// start and end
}
else
if
(
flags
==
4
)
{
// start and end
s
->
tx_md
.
start_of_burst
=
true
;
s
->
tx_md
.
start_of_burst
=
true
;
s
->
tx_md
.
end_of_burst
=
true
;
s
->
tx_md
.
end_of_burst
=
true
;
}
else
if
(
flags
==
1
)
{
// middle of burst
}
else
if
(
flags
==
1
)
{
// middle of burst
s
->
tx_md
.
start_of_burst
=
false
;
s
->
tx_md
.
start_of_burst
=
false
;
s
->
tx_md
.
end_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
.
has_time_spec
=
false
;
s
->
tx_md
.
start_of_burst
=
false
;
s
->
tx_md
.
start_of_burst
=
false
;
s
->
tx_md
.
end_of_burst
=
true
;
s
->
tx_md
.
end_of_burst
=
true
;
}
}
if
(
cc
>
1
)
{
std
::
vector
<
void
*>
buff_ptrs
;
if
(
cc
>
1
)
{
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
std
::
vector
<
void
*>
buff_ptrs
;
buff_ptrs
.
push_back
(
buff_tx
[
i
]);
ret
=
(
int
)
s
->
tx_stream
->
send
(
buff_ptrs
,
nsamps
,
s
->
tx_md
,
1e-3
);
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
}
else
buff_ptrs
.
push_back
(
buff_tx
[
i
]);
ret
=
(
int
)
s
->
tx_stream
->
send
(
buff_tx
[
0
],
nsamps
,
s
->
tx_md
,
1e-3
);
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
(
ret
!=
nsamps
)
LOG_E
(
PHY
,
"[xmit] tx samples %d != %d
\n
"
,
ret
,
nsamps
);
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
}
else
{
}
else
{
struct
timespec
req
;
struct
timespec
req
;
...
@@ -524,8 +512,8 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
...
@@ -524,8 +512,8 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
nanosleep
(
&
req
,
NULL
);
nanosleep
(
&
req
,
NULL
);
ret
=
nsamps
;
ret
=
nsamps
;
}
}
#endif
#endif
return
ret
;
return
ret
;
}
}
...
@@ -541,12 +529,13 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
...
@@ -541,12 +529,13 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
* \returns the number of sample read
* \returns the number of sample read
*/
*/
static
int
trx_usrp_read
(
openair0_device
*
device
,
openair0_timestamp
*
ptimestamp
,
void
**
buff
,
int
nsamps
,
int
cc
)
{
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
samples_received
=
0
,
i
,
j
;
int
nsamps2
;
// aligned to upper 32 or 16 byte boundary
int
nsamps2
;
// aligned to upper 32 or 16 byte boundary
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
!=
2
)
{
// not replay mode
if
(
u_sf_mode
!=
2
)
{
// not replay mode
#endif
#endif
#if defined(__x86_64) || defined(__i386__)
#if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__
#ifdef __AVX2__
nsamps2
=
(
nsamps
+
7
)
>>
3
;
nsamps2
=
(
nsamps
+
7
)
>>
3
;
...
@@ -561,66 +550,79 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
...
@@ -561,66 +550,79 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
#endif
#endif
if
(
device
->
type
==
USRP_B200_DEV
)
{
if
(
device
->
type
==
USRP_B200_DEV
)
{
if
(
cc
>
1
)
{
if
(
cc
>
1
)
{
// receive multiple channels (e.g. RF A and RF B)
// receive multiple channels (e.g. RF A and RF B)
std
::
vector
<
void
*>
buff_ptrs
;
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
);
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
buff_ptrs
.
push_back
(
buff_tmp
[
i
]);
}
else
{
// receive a single channel (e.g. from connector RF A)
samples_received
=
s
->
rx_stream
->
recv
(
buff_ptrs
,
nsamps
,
s
->
rx_md
);
samples_received
=
0
;
}
else
{
while
(
samples_received
!=
nsamps
)
{
// receive a single channel (e.g. from connector RF A)
samples_received
+=
s
->
rx_stream
->
recv
(
buff_tmp
[
0
]
+
samples_received
,
samples_received
=
0
;
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
))
while
(
samples_received
!=
nsamps
)
{
break
;
samples_received
+=
s
->
rx_stream
->
recv
(
buff_tmp
[
0
]
+
samples_received
,
if
((
s
->
wait_for_first_pps
==
1
)
&&
(
samples_received
!=
nsamps
))
{
printf
(
"sleep...
\n
"
);}
//usleep(100);
nsamps
-
samples_received
,
s
->
rx_md
);
}
if
(
samples_received
==
nsamps
)
s
->
wait_for_first_pps
=
0
;
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);
}
}
}
// bring RX data into 12 LSBs for softmodem RX
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
{
if
(
samples_received
==
nsamps
)
s
->
wait_for_first_pps
=
0
;
for
(
int
j
=
0
;
j
<
nsamps2
;
j
++
)
{
}
// 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__)
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
#ifdef __AVX2__
((
__m256i
*
)
buff
[
i
])[
j
]
=
_mm256_srai_epi16
(
buff_tmp
[
i
][
j
],
4
);
((
__m256i
*
)
buff
[
i
])[
j
]
=
_mm256_srai_epi16
(
buff_tmp
[
i
][
j
],
4
);
#else
#else
((
__m128i
*
)
buff
[
i
])[
j
]
=
_mm_srai_epi16
(
buff_tmp
[
i
][
j
],
4
);
((
__m128i
*
)
buff
[
i
])[
j
]
=
_mm_srai_epi16
(
buff_tmp
[
i
][
j
],
4
);
#endif
#endif
#elif defined(__arm__)
#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
#endif
}
}
}
}
}
else
if
(
device
->
type
==
USRP_X300_DEV
)
{
}
else
if
(
device
->
type
==
USRP_X300_DEV
)
{
if
(
cc
>
1
)
{
if
(
cc
>
1
)
{
// receive multiple channels (e.g. RF A and RF B)
// receive multiple channels (e.g. RF A and RF B)
std
::
vector
<
void
*>
buff_ptrs
;
std
::
vector
<
void
*>
buff_ptrs
;
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
buff_ptrs
.
push_back
(
buff
[
i
]);
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
{
samples_received
=
s
->
rx_stream
->
recv
(
buff_ptrs
,
nsamps
,
s
->
rx_md
);
// receive a single channel (e.g. from connector RF A)
}
else
{
samples_received
=
s
->
rx_stream
->
recv
(
buff
[
0
],
nsamps
,
s
->
rx_md
);
// 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
)
if
(
samples_received
<
nsamps
)
LOG_E
(
PHY
,
"[recv] received %d samples out of %d
\n
"
,
samples_received
,
nsamps
);
LOG_E
(
PHY
,
"[recv] received %d samples out of %d
\n
"
,
samples_received
,
nsamps
);
if
(
s
->
rx_md
.
error_code
!=
uhd
::
rx_metadata_t
::
ERROR_CODE_NONE
)
if
(
s
->
rx_md
.
error_code
!=
uhd
::
rx_metadata_t
::
ERROR_CODE_NONE
)
LOG_E
(
PHY
,
"%s
\n
"
,
s
->
rx_md
.
to_pp_string
(
true
).
c_str
());
LOG_E
(
PHY
,
"%s
\n
"
,
s
->
rx_md
.
to_pp_string
(
true
).
c_str
());
s
->
rx_count
+=
nsamps
;
s
->
rx_count
+=
nsamps
;
s
->
rx_timestamp
=
s
->
rx_md
.
time_spec
.
to_ticks
(
s
->
sample_rate
);
s
->
rx_timestamp
=
s
->
rx_md
.
time_spec
.
to_ticks
(
s
->
sample_rate
);
*
ptimestamp
=
s
->
rx_timestamp
;
*
ptimestamp
=
s
->
rx_timestamp
;
#if defined (USRP_REC_PLAY)
#if defined (USRP_REC_PLAY)
}
}
#endif
#endif
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
==
1
)
{
// record mode
if
(
u_sf_mode
==
1
)
{
// record mode
// Copy subframes to memory (later dump on a file)
// Copy subframes to memory (later dump on a file)
if
(
nb_samples
<
u_sf_max
)
{
if
(
nb_samples
<
u_sf_max
)
{
(
ms_sample
+
nb_samples
)
->
header
=
BELL_LABS_IQ_HEADER
;
(
ms_sample
+
nb_samples
)
->
header
=
BELL_LABS_IQ_HEADER
;
(
ms_sample
+
nb_samples
)
->
ts
=
*
ptimestamp
;
(
ms_sample
+
nb_samples
)
->
ts
=
*
ptimestamp
;
memcpy
((
ms_sample
+
nb_samples
)
->
samples
,
buff
[
0
],
nsamps
*
4
);
memcpy
((
ms_sample
+
nb_samples
)
->
samples
,
buff
[
0
],
nsamps
*
4
);
nb_samples
++
;
nb_samples
++
;
...
@@ -629,62 +631,78 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
...
@@ -629,62 +631,78 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
if
(
cur_samples
==
nb_samples
)
{
if
(
cur_samples
==
nb_samples
)
{
cur_samples
=
0
;
cur_samples
=
0
;
wrap_count
++
;
wrap_count
++
;
if
(
wrap_count
==
u_sf_loops
)
{
if
(
wrap_count
==
u_sf_loops
)
{
std
::
cerr
<<
"USRP device terminating subframes replay mode after "
<<
u_sf_loops
<<
" loops."
<<
std
::
endl
;
std
::
cerr
<<
"USRP device terminating subframes replay mode after "
<<
u_sf_loops
<<
" loops."
<<
std
::
endl
;
return
0
;
// should make calling process exit
return
0
;
// should make calling process exit
}
}
wrap_ts
=
wrap_count
*
(
nb_samples
*
(((
int
)(
device
->
openair0_cfg
[
0
].
sample_rate
))
/
1000
));
wrap_ts
=
wrap_count
*
(
nb_samples
*
(((
int
)(
device
->
openair0_cfg
[
0
].
sample_rate
))
/
1000
));
if
(
!
use_mmap
)
{
if
(
!
use_mmap
)
{
if
(
lseek
(
iqfd
,
0
,
SEEK_SET
)
==
0
)
{
if
(
lseek
(
iqfd
,
0
,
SEEK_SET
)
==
0
)
{
std
::
cerr
<<
"Seeking at the beginning of IQ file"
<<
std
::
endl
;
std
::
cerr
<<
"Seeking at the beginning of IQ file"
<<
std
::
endl
;
}
else
{
}
else
{
std
::
cerr
<<
"Problem seeking at the beginning of IQ file"
<<
std
::
endl
;
std
::
cerr
<<
"Problem seeking at the beginning of IQ file"
<<
std
::
endl
;
}
}
}
}
}
}
if
(
use_mmap
)
{
if
(
use_mmap
)
{
if
(
cur_samples
<
nb_samples
)
{
if
(
cur_samples
<
nb_samples
)
{
*
ptimestamp
=
(
ms_sample
[
0
].
ts
+
(
cur_samples
*
(((
int
)(
device
->
openair0_cfg
[
0
].
sample_rate
))
/
1000
)))
+
wrap_ts
;
*
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
if
(
cur_samples
==
0
)
{
<<
" ts="
<<
*
ptimestamp
<<
std
::
endl
;
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
++
;
memcpy
(
buff
[
0
],
&
ms_sample
[
cur_samples
].
samples
[
0
],
nsamps
*
4
);
cur_samples
++
;
}
}
}
else
{
}
else
{
// read sample from file
// read sample from file
if
(
read
(
iqfd
,
ms_sample
,
sizeof
(
iqrec_t
))
!=
sizeof
(
iqrec_t
))
{
if
(
read
(
iqfd
,
ms_sample
,
sizeof
(
iqrec_t
))
!=
sizeof
(
iqrec_t
))
{
std
::
cerr
<<
"pb reading iqfile at index "
<<
sizeof
(
iqrec_t
)
*
cur_samples
<<
std
::
endl
;
std
::
cerr
<<
"pb reading iqfile at index "
<<
sizeof
(
iqrec_t
)
*
cur_samples
<<
std
::
endl
;
close
(
iqfd
);
close
(
iqfd
);
free
(
ms_sample
);
free
(
ms_sample
);
ms_sample
=
NULL
;
ms_sample
=
NULL
;
iqfd
=
0
;
iqfd
=
0
;
exit
(
-
1
);
exit
(
-
1
);
}
}
if
(
cur_samples
<
nb_samples
)
{
if
(
cur_samples
<
nb_samples
)
{
static
int64_t
ts0
=
0
;
static
int64_t
ts0
=
0
;
if
((
cur_samples
==
0
)
&&
(
wrap_count
==
0
))
{
ts0
=
ms_sample
->
ts
;
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
*
ptimestamp
=
ts0
+
(
cur_samples
*
(((
int
)(
device
->
openair0_cfg
[
0
].
sample_rate
))
/
1000
))
+
wrap_ts
;
<<
" ts="
<<
*
ptimestamp
<<
std
::
endl
;
}
if
(
cur_samples
==
0
)
{
memcpy
(
buff
[
0
],
&
ms_sample
->
samples
[
0
],
nsamps
*
4
);
std
::
cerr
<<
"starting subframes file with wrap_count="
<<
wrap_count
<<
" wrap_ts="
<<
wrap_ts
cur_samples
++
;
<<
" ts="
<<
*
ptimestamp
<<
std
::
endl
;
// Prepare for next read
}
off_t
where
=
lseek
(
iqfd
,
cur_samples
*
sizeof
(
iqrec_t
),
SEEK_SET
);
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
;
struct
timespec
req
;
req
.
tv_sec
=
0
;
req
.
tv_sec
=
0
;
req
.
tv_nsec
=
u_sf_read_delay
*
1000
;
req
.
tv_nsec
=
u_sf_read_delay
*
1000
;
nanosleep
(
&
req
,
NULL
);
nanosleep
(
&
req
,
NULL
);
return
nsamps
;
return
nsamps
;
}
}
#endif
#endif
return
samples_received
;
return
samples_received
;
}
}
...
@@ -694,16 +712,14 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
...
@@ -694,16 +712,14 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
* \param b second 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
();
return
std
::
fabs
(
a
-
b
)
<
std
::
numeric_limits
<
double
>::
epsilon
();
}
}
void
*
freq_thread
(
void
*
arg
)
{
void
*
freq_thread
(
void
*
arg
)
{
openair0_device
*
device
=
(
openair0_device
*
)
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
]);
s
->
usrp
->
set_tx_freq
(
device
->
openair0_cfg
[
0
].
tx_freq
[
0
]);
s
->
usrp
->
set_rx_freq
(
device
->
openair0_cfg
[
0
].
rx_freq
[
0
]);
}
}
/*! \brief Set frequencies (TX/RX). Spawns a thread to handle the frequency change to not block the calling thread
/*! \brief Set frequencies (TX/RX). Spawns a thread to handle the frequency change to not block the calling thread
* \param device the hardware to use
* \param device the hardware to use
...
@@ -711,23 +727,20 @@ void *freq_thread(void *arg) {
...
@@ -711,23 +727,20 @@ void *freq_thread(void *arg) {
* \param dummy dummy variable not used
* \param dummy dummy variable not used
* \returns 0 in success
* \returns 0 in success
*/
*/
int
trx_usrp_set_freq
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
,
int
dont_block
)
{
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
;
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
pthread_t
f_thread
;
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
]);
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
)
// spawn a thread to handle the frequency change to not block the calling thread
pthread_create
(
&
f_thread
,
NULL
,
freq_thread
,(
void
*
)
device
);
if
(
dont_block
==
1
)
else
{
pthread_create
(
&
f_thread
,
NULL
,
freq_thread
,(
void
*
)
device
);
s
->
usrp
->
set_tx_freq
(
device
->
openair0_cfg
[
0
].
tx_freq
[
0
]);
else
{
s
->
usrp
->
set_rx_freq
(
device
->
openair0_cfg
[
0
].
rx_freq
[
0
]);
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
);
return
(
0
);
}
}
/*! \brief Set RX frequencies
/*! \brief Set RX frequencies
...
@@ -735,21 +748,16 @@ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,
...
@@ -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
* \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
)
{
int
openair0_set_rx_frequencies
(
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
;
static
int
first_call
=
1
;
static
int
first_call
=
1
;
static
double
rf_freq
,
diff
;
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
;
uhd
::
tune_request_t
rx_tune_req
(
openair0_cfg
[
0
].
rx_freq
[
0
]);
rx_tune_req
.
rf_freq
=
openair0_cfg
[
0
].
rx_freq
[
0
];
rf_freq
=
openair0_cfg
[
0
].
rx_freq
[
0
];
rx_tune_req
.
rf_freq_policy
=
uhd
::
tune_request_t
::
POLICY_MANUAL
;
s
->
usrp
->
set_rx_freq
(
rx_tune_req
);
rx_tune_req
.
rf_freq
=
openair0_cfg
[
0
].
rx_freq
[
0
];
return
(
0
);
rf_freq
=
openair0_cfg
[
0
].
rx_freq
[
0
];
s
->
usrp
->
set_rx_freq
(
rx_tune_req
);
return
(
0
);
}
}
/*! \brief Set Gains (TX/RX)
/*! \brief Set Gains (TX/RX)
...
@@ -757,62 +765,62 @@ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *open
...
@@ -757,62 +765,62 @@ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *open
* \param openair0_cfg RF frontend parameters set by application
* \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
,
int
trx_usrp_set_gains
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
openair0_config_t
*
openair0_cfg
)
{
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
);
}
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
s
->
usrp
->
set_rx_gain
(
openair0_cfg
[
0
].
rx_gain
[
0
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
0
]);
::
uhd
::
gain_range_t
gain_range_tx
=
s
->
usrp
->
get_tx_gain_range
(
0
);
LOG_I
(
PHY
,
"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)
\n
"
,
s
->
usrp
->
set_tx_gain
(
gain_range_tx
.
stop
()
-
openair0_cfg
[
0
].
tx_gain
[
0
]);
openair0_cfg
[
0
].
rx_gain
[
0
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
0
],
::
uhd
::
gain_range_t
gain_range
=
s
->
usrp
->
get_rx_gain_range
(
0
);
openair0_cfg
[
0
].
rx_gain
[
0
],
gain_range
.
stop
());
// limit to maximum gain
return
(
0
);
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
/*! \brief Stop USRP
* \param card refers to the hardware index to use
* \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
);
return
(
0
);
}
}
/*! \brief USRPB210 RX calibration table */
/*! \brief USRPB210 RX calibration table */
rx_gain_calib_table_t
calib_table_b210
[]
=
{
rx_gain_calib_table_t
calib_table_b210
[]
=
{
{
3500000000.0
,
44.0
},
{
3500000000.0
,
44.0
},
{
2660000000.0
,
49.0
},
{
2660000000.0
,
49.0
},
{
2300000000.0
,
50.0
},
{
2300000000.0
,
50.0
},
{
1880000000.0
,
53.0
},
{
1880000000.0
,
53.0
},
{
816000000.0
,
58.0
},
{
816000000.0
,
58.0
},
{
-
1
,
0
}
{
-
1
,
0
}
};
};
/*! \brief USRPB210 RX calibration table */
/*! \brief USRPB210 RX calibration table */
rx_gain_calib_table_t
calib_table_b210_38
[]
=
{
rx_gain_calib_table_t
calib_table_b210_38
[]
=
{
{
3500000000.0
,
44.0
},
{
3500000000.0
,
44.0
},
{
2660000000.0
,
49.8
},
{
2660000000.0
,
49.8
},
{
2300000000.0
,
51.0
},
{
2300000000.0
,
51.0
},
{
1880000000.0
,
53.0
},
{
1880000000.0
,
53.0
},
{
816000000.0
,
57.0
},
{
816000000.0
,
57.0
},
{
-
1
,
0
}
{
-
1
,
0
}
};
};
/*! \brief USRPx310 RX calibration table */
/*! \brief USRPx310 RX calibration table */
rx_gain_calib_table_t
calib_table_x310
[]
=
{
rx_gain_calib_table_t
calib_table_x310
[]
=
{
{
3500000000.0
,
77.0
},
{
3500000000.0
,
77.0
},
{
2660000000.0
,
81.0
},
{
2660000000.0
,
81.0
},
{
2300000000.0
,
81.0
},
{
2300000000.0
,
81.0
},
{
1880000000.0
,
82.0
},
{
1880000000.0
,
82.0
},
{
816000000.0
,
85.0
},
{
816000000.0
,
85.0
},
{
-
1
,
0
}
{
-
1
,
0
}
};
};
/*! \brief Set RX gain offset
/*! \brief Set RX gain offset
...
@@ -821,72 +829,81 @@ rx_gain_calib_table_t calib_table_x310[] = {
...
@@ -821,72 +829,81 @@ rx_gain_calib_table_t calib_table_x310[] = {
* \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
)
{
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
;
int
i
=
0
;
if
(
bw_gain_adjust
==
1
)
{
// loop through calibration table to find best adjustment factor for RX frequency
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
double
min_diff
=
6e9
,
diff
,
gain_adj
=
0.0
;
case
30720000
:
if
(
bw_gain_adjust
==
1
)
{
break
;
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
case
30720000
:
case
23040000
:
break
;
gain_adj
=
1.25
;
case
23040000
:
break
;
gain_adj
=
1.25
;
break
;
case
15360000
:
case
15360000
:
gain_adj
=
3.0
;
gain_adj
=
3.0
;
break
;
break
;
case
7680000
:
case
7680000
:
gain_adj
=
6.0
;
gain_adj
=
6.0
;
break
;
break
;
case
3840000
:
gain_adj
=
9.0
;
case
3840000
:
break
;
gain_adj
=
9.0
;
case
1920000
:
break
;
gain_adj
=
12.0
;
break
;
case
1920000
:
default:
gain_adj
=
12.0
;
LOG_E
(
PHY
,
"unknown sampling rate %d
\n
"
,(
int
)
openair0_cfg
[
0
].
sample_rate
);
break
;
exit
(
-
1
);
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
"
,
while
(
openair0_cfg
->
rx_gain_calib_table
[
i
].
freq
>
0
)
{
i
,
diff
=
fabs
(
openair0_cfg
->
rx_freq
[
chain_index
]
-
openair0_cfg
->
rx_gain_calib_table
[
i
].
freq
);
openair0_cfg
->
rx_gain_calib_table
[
i
].
freq
,
LOG_I
(
PHY
,
"cal %d: freq %f, offset %f, diff %f
\n
"
,
openair0_cfg
->
rx_gain_calib_table
[
i
].
offset
,
diff
);
i
,
if
(
min_diff
>
diff
)
{
openair0_cfg
->
rx_gain_calib_table
[
i
].
freq
,
min_diff
=
diff
;
openair0_cfg
->
rx_gain_calib_table
[
i
].
offset
,
diff
);
openair0_cfg
->
rx_gain_offset
[
chain_index
]
=
openair0_cfg
->
rx_gain_calib_table
[
i
].
offset
+
gain_adj
;
}
if
(
min_diff
>
diff
)
{
i
++
;
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
* \param device the hardware to use
* \returns 0 on success
* \returns 0 on success
*/
*/
int
trx_usrp_get_stats
(
openair0_device
*
device
)
{
int
trx_usrp_get_stats
(
openair0_device
*
device
)
{
return
(
0
);
return
(
0
);
}
}
/*! \brief Reset the USRP statistics
/*! \brief Reset the USRP statistics
* \param device the hardware to use
* \param device the hardware to use
* \returns 0 on success
* \returns 0 on success
*/
*/
int
trx_usrp_reset_stats
(
openair0_device
*
device
)
{
int
trx_usrp_reset_stats
(
openair0_device
*
device
)
{
return
(
0
);
return
(
0
);
}
}
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
extern
"C"
{
extern
"C"
{
/*! \brief Initializer for USRP record/playback config
/*! \brief Initializer for USRP record/playback config
* \param parameter array description
* \param parameter array description
* \returns 0 on success
* \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
// --subframes-file
memcpy
(
usrp_recplay_params
[
0
].
optname
,
config_opt_sf_file
,
strlen
(
config_opt_sf_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
;
usrp_recplay_params
[
0
].
helpstr
=
config_hlp_sf_file
;
...
@@ -943,9 +960,8 @@ int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) {
...
@@ -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
].
defuintval
=
DEF_SF_DELAY_WRITE
;
usrp_recplay_params
[
6
].
type
=
TYPE_UINT
;
usrp_recplay_params
[
6
].
type
=
TYPE_UINT
;
usrp_recplay_params
[
6
].
numelt
=
0
;
usrp_recplay_params
[
6
].
numelt
=
0
;
return
0
;
// always ok
return
0
;
// always ok
}
}
}
}
#endif
#endif
...
@@ -954,478 +970,473 @@ extern "C" {
...
@@ -954,478 +970,473 @@ extern "C" {
* \param device the hardware to use
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \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].sdr_addrs == '%s'
\n
"
,
openair0_cfg
[
0
].
sdr_addrs
);
LOG_D
(
PHY
,
"openair0_cfg[0].clock_source == '%d'
\n
"
,
openair0_cfg
[
0
].
clock_source
);
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
)
{
(
void
)
strcpy
(
u_sf_filename
,
DEF_SF_FILE
);
}
if
(
u_sf_replay
==
1
)
u_sf_mode
=
2
;
if
(
u_sf_record
==
1
)
u_sf_mode
=
1
;
if
(
u_sf_mode
==
2
)
{
// Replay subframes from from file
int
bw_gain_adjust
=
0
;
device
->
openair0_cfg
=
openair0_cfg
;
device
->
type
=
USRP_B200_DEV
;
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_b210_38
;
bw_gain_adjust
=
1
;
openair0_cfg
[
0
].
tx_sample_advance
=
80
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
openair0_cfg
[
0
].
iq_txshift
=
4
;
//shift
openair0_cfg
[
0
].
iq_rxrescale
=
15
;
//rescale iqs
set_rx_gain_offset
(
&
openair0_cfg
[
0
],
0
,
bw_gain_adjust
);
device
->
priv
=
NULL
;
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
;
device
->
trx_stop_func
=
trx_usrp_stop
;
device
->
trx_set_freq_func
=
trx_usrp_set_freq
;
device
->
trx_set_gains_func
=
trx_usrp_set_gains
;
device
->
openair0_cfg
=
openair0_cfg
;
std
::
cerr
<<
"USRP device initialized in subframes replay mode for "
<<
u_sf_loops
<<
" loops. Use mmap="
<<
use_mmap
<<
std
::
endl
;
}
else
{
#endif
uhd
::
set_thread_priority_safe
(
1.0
);
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
;
int
vers
=
0
,
subvers
=
0
,
subsubvers
=
0
;
int
bw_gain_adjust
=
0
;
#if defined(USRP_REC_PLAY)
#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
)
{
if
(
u_sf_mode
==
1
)
{
(
void
)
strcpy
(
u_sf_filename
,
DEF_SF_FILE
)
;
std
::
cerr
<<
"USRP device initialized in subframes record mode"
<<
std
::
endl
;
}
}
if
(
u_sf_replay
==
1
)
u_sf_mode
=
2
;
if
(
u_sf_record
==
1
)
u_sf_mode
=
1
;
if
(
u_sf_mode
==
2
)
{
// Replay subframes from from file
int
bw_gain_adjust
=
0
;
device
->
openair0_cfg
=
openair0_cfg
;
device
->
type
=
USRP_B200_DEV
;
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_b210_38
;
bw_gain_adjust
=
1
;
openair0_cfg
[
0
].
tx_sample_advance
=
80
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
openair0_cfg
[
0
].
iq_txshift
=
4
;
//shift
openair0_cfg
[
0
].
iq_rxrescale
=
15
;
//rescale iqs
set_rx_gain_offset
(
&
openair0_cfg
[
0
],
0
,
bw_gain_adjust
);
device
->
priv
=
NULL
;
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
;
device
->
trx_stop_func
=
trx_usrp_stop
;
device
->
trx_set_freq_func
=
trx_usrp_set_freq
;
device
->
trx_set_gains_func
=
trx_usrp_set_gains
;
device
->
openair0_cfg
=
openair0_cfg
;
std
::
cerr
<<
"USRP device initialized in subframes replay mode for "
<<
u_sf_loops
<<
" loops. Use mmap="
<<
use_mmap
<<
std
::
endl
;
}
else
{
#endif
#endif
uhd
::
set_thread_priority_safe
(
1.0
);
sscanf
(
uhd
::
get_version_string
().
c_str
(),
"%d.%d.%d"
,
&
vers
,
&
subvers
,
&
subsubvers
);
usrp_state_t
*
s
=
(
usrp_state_t
*
)
calloc
(
sizeof
(
usrp_state_t
),
1
);
LOG_I
(
PHY
,
"Checking for USRPs : UHD %s (%d.%d.%d)
\n
"
,
uhd
::
get_version_string
().
c_str
(),
vers
,
subvers
,
subsubvers
);
if
(
openair0_cfg
[
0
].
clock_source
==
gpsdo
)
s
->
use_gps
=
1
;
std
::
string
args
;
if
(
openair0_cfg
[
0
].
sdr_addrs
==
NULL
)
{
// Initialize USRP device
args
=
"type=b200"
;
device
->
openair0_cfg
=
openair0_cfg
;
}
else
{
args
=
openair0_cfg
[
0
].
sdr_addrs
;
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
)
{
// Check whether sdr_addrs contains multiple IP addresses
// and split and add them to addr_args
if
(
strstr
(
openair0_cfg
[
0
].
sdr_addrs
,
","
)
!=
NULL
)
{
char
*
addr0
=
openair0_cfg
[
0
].
sdr_addrs
;
// Replace , with \0
strsep
(
&
openair0_cfg
[
0
].
sdr_addrs
,
","
);
char
*
addr1
=
openair0_cfg
[
0
].
sdr_addrs
;
// Allocate memory for ",addr0=,addr1=\0" and the addresses
size_t
addr_args_len
=
sizeof
(
char
)
*
(
15
+
strlen
(
addr0
)
+
strlen
(
addr1
));
addr_args
=
(
char
*
)
malloc
(
addr_args_len
);
snprintf
(
addr_args
,
addr_args_len
,
",addr0=%s,addr1=%s"
,
addr0
,
addr1
);
args
+=
addr_args
;
LOG_D
(
PHY
,
"addr_args == '%s'
\n
"
,
addr_args
);
}
}
}
}
uhd
::
device_addrs_t
device_adds
=
uhd
::
device
::
find
(
args
);
uhd
::
device_addrs_t
device_adds
=
uhd
::
device
::
find
(
args
);
int
vers
=
0
,
subvers
=
0
,
subsubvers
=
0
;
if
(
device_adds
.
size
()
==
0
)
{
int
bw_gain_adjust
=
0
;
std
::
cerr
<<
"No USRP Device Found. "
<<
std
::
endl
;
free
(
s
);
return
-
1
;
}
else
if
(
device_adds
.
size
()
>
1
)
{
std
::
cerr
<<
"More than one USRP Device Found. Please specify device more precisely in config file."
<<
std
::
endl
;
free
(
s
);
return
-
1
;
}
#if defined(USRP_REC_PLAY)
std
::
cerr
<<
"Found USRP "
<<
device_adds
[
0
].
get
(
"type"
)
<<
"
\n
"
;
if
(
u_sf_mode
==
1
)
{
double
usrp_master_clock
;
std
::
cerr
<<
"USRP device initialized in subframes record mode"
<<
std
::
endl
;
}
if
(
device_adds
[
0
].
get
(
"type"
)
==
"b200"
)
{
#endif
printf
(
"Found USRP b200
\n
"
);
sscanf
(
uhd
::
get_version_string
().
c_str
(),
"%d.%d.%d"
,
&
vers
,
&
subvers
,
&
subsubvers
)
;
device
->
type
=
USRP_B200_DEV
;
LOG_I
(
PHY
,
"Checking for USRPs : UHD %s (%d.%d.%d)
\n
"
,
usrp_master_clock
=
30.72e6
;
uhd
::
get_version_string
().
c_str
(),
vers
,
subvers
,
subsubvers
);
args
+=
boost
::
str
(
boost
::
format
(
",master_clock_rate=%f"
)
%
usrp_master_clock
);
args
+=
",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360"
;
if
(
device_adds
.
size
()
==
0
)
{
}
double
usrp_master_clock
=
184.32e6
;
if
(
device_adds
[
0
].
get
(
"type"
)
==
"n3xx"
)
{
std
::
string
args
=
"type=x300"
;
printf
(
"Found USRP n300
\n
"
)
;
device
->
type
=
USRP_X300_DEV
;
//treat it as X300 for now
if
(
addr_args
)
{
usrp_master_clock
=
122.88e6
;
args
+=
addr_args
;
args
+=
boost
::
str
(
boost
::
format
(
",master_clock_rate=%f"
)
%
usrp_master_clock
)
;
}
}
// workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate
if
(
device_adds
[
0
].
get
(
"type"
)
==
"x300"
)
{
printf
(
"Found USRP x300
\n
"
);
device
->
type
=
USRP_X300_DEV
;
usrp_master_clock
=
184.32e6
;
args
+=
boost
::
str
(
boost
::
format
(
",master_clock_rate=%f"
)
%
usrp_master_clock
);
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";
s
->
usrp
=
uhd
::
usrp
::
multi_usrp
::
make
(
args
);
uhd
::
device_addrs_t
device_adds
=
uhd
::
device
::
find
(
args
);
if
(
device_adds
.
size
()
==
0
)
{
// lock mboard clocks
args
+=
",addr=192.168.30.2"
;
if
(
openair0_cfg
[
0
].
clock_source
==
internal
)
s
->
usrp
->
set_clock_source
(
"internal"
);
else
s
->
usrp
->
set_clock_source
(
"external"
);
uhd
::
device_addrs_t
device_adds
=
uhd
::
device
::
find
(
args
);
if
(
device
->
type
==
USRP_X300_DEV
)
{
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
);
if
(
device_adds
.
size
()
==
0
)
{
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
case
122880000
:
std
::
cerr
<<
"No USRP Device Found. "
<<
std
::
endl
;
// from usrp_time_offset
free
(
s
);
//openair0_cfg[0].samples_per_packet = 2048;
return
-
1
;
openair0_cfg
[
0
].
tx_sample_advance
=
15
;
//to be checked
}
openair0_cfg
[
0
].
tx_bw
=
80e6
;
}
openair0_cfg
[
0
].
rx_bw
=
80e6
;
LOG_I
(
PHY
,
"Found USRP X300
\n
"
);
break
;
s
->
usrp
=
uhd
::
usrp
::
multi_usrp
::
make
(
args
);
// lock mboard clocks
case
61440000
:
if
(
openair0_cfg
[
0
].
clock_source
==
internal
)
// from usrp_time_offset
s
->
usrp
->
set_clock_source
(
"internal"
);
//openair0_cfg[0].samples_per_packet = 2048;
else
openair0_cfg
[
0
].
tx_sample_advance
=
15
;
s
->
usrp
->
set_clock_source
(
"external"
);
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;
openair0_cfg
[
0
].
tx_sample_advance
=
15
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
//Setting device type to USRP X300/X310
case
15360000
:
device
->
type
=
USRP_X300_DEV
;
//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
;
// this is not working yet, master clock has to be set via constructor
case
7680000
:
// set master clock rate and sample rate for tx & rx for streaming
//openair0_cfg[0].samples_per_packet = 2048;
//s->usrp->set_master_clock_rate(usrp_master_clock);
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
;
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_x310
;
default:
LOG_E
(
PHY
,
"Error: unknown sampling rate %f
\n
"
,
openair0_cfg
[
0
].
sample_rate
);
exit
(
-
1
);
break
;
}
}
if
(
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
;
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
std
::
cerr
<<
"-- Using calibration table: calib_table_x3
10"
<<
std
::
endl
;
// Bell Labs info
std
::
cerr
<<
"-- Using calibration table: calib_table_b2
10"
<<
std
::
endl
;
// Bell Labs info
#endif
#endif
}
else
{
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_b210_38
;
bw_gain_adjust
=
1
;
#if defined(USRP_REC_PLAY)
std
::
cerr
<<
"-- Using calibration table: calib_table_b210_38"
<<
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
)
{
case
30720000
:
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
s
->
usrp
->
set_master_clock_rate
(
30.72e6
);
case
122880000
:
//openair0_cfg[0].samples_per_packet = 1024;
// from usrp_time_offset
openair0_cfg
[
0
].
tx_sample_advance
=
115
;
//openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
tx_sample_advance
=
15
;
//to be checked
openair0_cfg
[
0
].
rx_bw
=
20e6
;
openair0_cfg
[
0
].
tx_bw
=
80e6
;
break
;
openair0_cfg
[
0
].
rx_bw
=
80e6
;
break
;
case
61440000
:
// from usrp_time_offset
//openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg
[
0
].
tx_sample_advance
=
15
;
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;
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:
LOG_E
(
PHY
,
"Error: unknown sampling rate %f
\n
"
,
openair0_cfg
[
0
].
sample_rate
);
exit
(
-
1
);
break
;
}
}
else
{
case
23040000
:
LOG_I
(
PHY
,
"Found USRP B200
\n
"
);
s
->
usrp
->
set_master_clock_rate
(
23.04e6
);
//to be checked
args
+=
",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360"
;
//openair0_cfg[0].samples_per_packet = 1024;
s
->
usrp
=
uhd
::
usrp
::
multi_usrp
::
make
(
args
);
openair0_cfg
[
0
].
tx_sample_advance
=
113
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
// s->usrp->set_rx_subdev_spec(rx_subdev);
case
15360000
:
// s->usrp->set_tx_subdev_spec(tx_subdev);
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
;
// do not explicitly set the clock to "internal", because this will disable the gpsdo
case
7680000
:
// // lock mboard clocks
s
->
usrp
->
set_master_clock_rate
(
30.72e6
);
// s->usrp->set_clock_source("internal");
//openair0_cfg[0].samples_per_packet = 1024;
// set master clock rate and sample rate for tx & rx for streaming
openair0_cfg
[
0
].
tx_sample_advance
=
80
;
openair0_cfg
[
0
].
tx_bw
=
20e6
;
openair0_cfg
[
0
].
rx_bw
=
20e6
;
break
;
// lock mboard clocks
case
1920000
:
if
(
openair0_cfg
[
0
].
clock_source
==
internal
){
s
->
usrp
->
set_master_clock_rate
(
30.72e6
);
s
->
usrp
->
set_clock_source
(
"internal"
);
//openair0_cfg[0].samples_per_packet = 1024;
}
openair0_cfg
[
0
].
tx_sample_advance
=
40
;
else
{
openair0_cfg
[
0
].
tx_bw
=
20e6
;
s
->
usrp
->
set_clock_source
(
"external"
);
openair0_cfg
[
0
].
rx_bw
=
20e6
;
s
->
usrp
->
set_time_source
(
"external"
);
break
;
}
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
;
#if defined(USRP_REC_PLAY)
std
::
cerr
<<
"-- Using calibration table: calib_table_b210"
<<
std
::
endl
;
// Bell Labs info
#endif
}
else
{
openair0_cfg
[
0
].
rx_gain_calib_table
=
calib_table_b210_38
;
bw_gain_adjust
=
1
;
#if defined(USRP_REC_PLAY)
std
::
cerr
<<
"-- Using calibration table: calib_table_b210_38"
<<
std
::
endl
;
// Bell Labs info
#endif
}
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
default:
case
30720000
:
LOG_E
(
PHY
,
"Error: unknown sampling rate %f
\n
"
,
openair0_cfg
[
0
].
sample_rate
);
s
->
usrp
->
set_master_clock_rate
(
30.72e6
);
exit
(
-
1
);
//openair0_cfg[0].samples_per_packet = 1024;
break
;
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:
LOG_E
(
PHY
,
"Error: unknown sampling rate %f
\n
"
,
openair0_cfg
[
0
].
sample_rate
);
exit
(
-
1
);
break
;
}
}
}
}
/* device specific */
/* device specific */
//openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered
//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].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered
openair0_cfg
[
0
].
iq_txshift
=
4
;
//shift
openair0_cfg
[
0
].
iq_txshift
=
4
;
//shift
openair0_cfg
[
0
].
iq_rxrescale
=
15
;
//rescale iqs
openair0_cfg
[
0
].
iq_rxrescale
=
15
;
//rescale iqs
for
(
int
i
=
0
;
i
<
s
->
usrp
->
get_rx_num_channels
();
i
++
)
{
for
(
int
i
=
0
;
i
<
s
->
usrp
->
get_rx_num_channels
();
i
++
)
{
if
(
i
<
openair0_cfg
[
0
].
rx_num_channels
)
{
if
(
i
<
openair0_cfg
[
0
].
rx_num_channels
)
{
s
->
usrp
->
set_rx_rate
(
openair0_cfg
[
0
].
sample_rate
,
i
);
s
->
usrp
->
set_rx_rate
(
openair0_cfg
[
0
].
sample_rate
,
i
);
s
->
usrp
->
set_rx_freq
(
openair0_cfg
[
0
].
rx_freq
[
i
],
i
);
s
->
usrp
->
set_rx_freq
(
openair0_cfg
[
0
].
rx_freq
[
i
],
i
);
set_rx_gain_offset
(
&
openair0_cfg
[
0
],
i
,
bw_gain_adjust
);
set_rx_gain_offset
(
&
openair0_cfg
[
0
],
i
,
bw_gain_adjust
);
::
uhd
::
gain_range_t
gain_range
=
s
->
usrp
->
get_rx_gain_range
(
i
);
::
uhd
::
gain_range_t
gain_range
=
s
->
usrp
->
get_rx_gain_range
(
i
);
// limit to maximum gain
// limit to maximum gain
AssertFatal
(
openair0_cfg
[
0
].
rx_gain
[
i
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
i
]
<=
gain_range
.
stop
(),
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
"
,
"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
());
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
);
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
,
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
],
openair0_cfg
[
0
].
rx_gain
[
i
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
i
],
gain_range
.
stop
());
openair0_cfg
[
0
].
rx_gain
[
i
]
-
openair0_cfg
[
0
].
rx_gain_offset
[
i
],
gain_range
.
stop
());
}
}
}
}
LOG_D
(
PHY
,
"usrp->get_tx_num_channels() == %zd
\n
"
,
s
->
usrp
->
get_tx_num_channels
());
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
);
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
++
)
{
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
);
::
uhd
::
gain_range_t
gain_range_tx
=
s
->
usrp
->
get_tx_gain_range
(
i
);
if
(
i
<
openair0_cfg
[
0
].
tx_num_channels
)
{
if
(
i
<
openair0_cfg
[
0
].
tx_num_channels
)
{
s
->
usrp
->
set_tx_rate
(
openair0_cfg
[
0
].
sample_rate
,
i
);
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_freq
(
openair0_cfg
[
0
].
tx_freq
[
i
],
i
);
s
->
usrp
->
set_tx_gain
(
gain_range_tx
.
stop
()
-
openair0_cfg
[
0
].
tx_gain
[
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
]);
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_clock_source("external");
//s->usrp->set_time_source("external");
//s->usrp->set_time_source("external");
// display USRP settings
// display USRP settings
LOG_I
(
PHY
,
"Actual master clock: %fMHz...
\n
"
,
s
->
usrp
->
get_master_clock_rate
()
/
1e6
);
LOG_I
(
PHY
,
"Actual master clock: %fMHz...
\n
"
,
s
->
usrp
->
get_master_clock_rate
()
/
1e6
);
sleep
(
1
);
sleep
(
1
);
// create tx & rx streamer
uhd
::
stream_args_t
stream_args_rx
(
"sc16"
,
"sc16"
);
// create tx & rx streamer
int
samples
=
openair0_cfg
[
0
].
sample_rate
;
uhd
::
stream_args_t
stream_args_rx
(
"sc16"
,
"sc16"
);
int
max
=
s
->
usrp
->
get_rx_stream
(
stream_args_rx
)
->
get_max_num_samps
();
int
samples
=
openair0_cfg
[
0
].
sample_rate
;
samples
/=
10000
;
int
max
=
s
->
usrp
->
get_rx_stream
(
stream_args_rx
)
->
get_max_num_samps
();
LOG_I
(
PHY
,
"RF board max packet size %u, size for 100µs jitter %d
\n
"
,
max
,
samples
);
samples
/=
10000
;
LOG_I
(
PHY
,
"RF board max packet size %u, size for 100µs jitter %d
\n
"
,
max
,
samples
);
if
(
samples
<
max
)
if
(
samples
<
max
)
stream_args_rx
.
args
[
"spp"
]
=
str
(
boost
::
format
(
"%d"
)
%
samples
);
stream_args_rx
.
args
[
"spp"
]
=
str
(
boost
::
format
(
"%d"
)
%
samples
);
LOG_I
(
PHY
,
"rx_max_num_samps %zu
\n
"
,
LOG_I
(
PHY
,
"rx_max_num_samps %zu
\n
"
,
s
->
usrp
->
get_rx_stream
(
stream_args_rx
)
->
get_max_num_samps
());
s
->
usrp
->
get_rx_stream
(
stream_args_rx
)
->
get_max_num_samps
());
for
(
int
i
=
0
;
i
<
openair0_cfg
[
0
].
rx_num_channels
;
i
++
)
for
(
int
i
=
0
;
i
<
openair0_cfg
[
0
].
rx_num_channels
;
i
++
)
stream_args_rx
.
channels
.
push_back
(
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"
);
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
);
for
(
int
i
=
0
;
i
<
openair0_cfg
[
0
].
tx_num_channels
;
i
++
)
s
->
tx_stream
=
s
->
usrp
->
get_tx_stream
(
stream_args_tx
);
stream_args_tx
.
channels
.
push_back
(
i
);
/* Setting TX/RX BW after streamers are created due to USRP calibration issue */
s
->
tx_stream
=
s
->
usrp
->
get_tx_stream
(
stream_args_tx
);
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
);
/* 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
++
)
for
(
int
i
=
0
;
i
<
s
->
usrp
->
get_rx_num_channels
()
&&
i
<
openair0_cfg
[
0
].
rx_num_channels
;
i
++
)
s
->
usrp
->
set_tx_bandwidth
(
openair0_cfg
[
0
].
tx_bw
,
i
);
s
->
usrp
->
set_rx_bandwidth
(
openair0_cfg
[
0
].
rx_bw
,
i
);
for
(
int
i
=
0
;
i
<
s
->
usrp
->
get_rx_num_channels
()
&&
i
<
openair0_cfg
[
0
].
rx_num_channels
;
i
++
)
for
(
int
i
=
0
;
i
<
openair0_cfg
[
0
].
rx_num_channels
;
i
++
)
{
s
->
usrp
->
set_rx_bandwidth
(
openair0_cfg
[
0
].
rx_bw
,
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
);
for
(
int
i
=
0
;
i
<
openair0_cfg
[
0
].
rx_num_channels
;
i
++
)
{
LOG_I
(
PHY
,
" Actual RX frequency: %fGHz...
\n
"
,
s
->
usrp
->
get_rx_freq
(
i
)
/
1e9
);
LOG_I
(
PHY
,
"RX Channel %d
\n
"
,
i
);
LOG_I
(
PHY
,
" Actual RX gain: %f...
\n
"
,
s
->
usrp
->
get_rx_gain
(
i
));
LOG_I
(
PHY
,
" Actual RX sample rate: %fMSps...
\n
"
,
s
->
usrp
->
get_rx_rate
(
i
)
/
1e6
);
LOG_I
(
PHY
,
" Actual RX bandwidth: %fM...
\n
"
,
s
->
usrp
->
get_rx_bandwidth
(
i
)
/
1e6
);
LOG_I
(
PHY
,
" Actual RX frequency: %fGHz...
\n
"
,
s
->
usrp
->
get_rx_freq
(
i
)
/
1e9
);
LOG_I
(
PHY
,
" Actual RX antenna: %s...
\n
"
,
s
->
usrp
->
get_rx_antenna
(
i
).
c_str
());
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
++
)
{
for
(
int
i
=
0
;
i
<
openair0_cfg
[
0
].
tx_num_channels
;
i
++
)
{
LOG_I
(
PHY
,
"TX Channel %d
\n
"
,
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 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 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 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 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
,
" 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
());
LOG_I
(
PHY
,
"Device timestamp: %f...
\n
"
,
s
->
usrp
->
get_time_now
().
get_real_secs
());
device
->
priv
=
s
;
device
->
priv
=
s
;
device
->
trx_start_func
=
trx_usrp_start
;
device
->
trx_start_func
=
trx_usrp_start
;
device
->
trx_write_func
=
trx_usrp_write
;
device
->
trx_write_func
=
trx_usrp_write
;
device
->
trx_read_func
=
trx_usrp_read
;
device
->
trx_read_func
=
trx_usrp_read
;
device
->
trx_get_stats_func
=
trx_usrp_get_stats
;
device
->
trx_get_stats_func
=
trx_usrp_g
et_stats
;
device
->
trx_reset_stats_func
=
trx_usrp_res
et_stats
;
device
->
trx_reset_stats_func
=
trx_usrp_reset_stats
;
device
->
trx_end_func
=
trx_usrp_end
;
device
->
trx_end_func
=
trx_usrp_end
;
device
->
trx_stop_func
=
trx_usrp_stop
;
device
->
trx_stop_func
=
trx_usrp_stop
;
device
->
trx_set_freq_func
=
trx_usrp_set_freq
;
device
->
trx_set_freq_func
=
trx_usrp_set_freq
;
device
->
trx_set_gains_func
=
trx_usrp_set_gains
;
device
->
trx_set_gains_func
=
trx_usrp_set_gains
;
device
->
openair0_cfg
=
openair0_cfg
;
device
->
openair0_cfg
=
openair0_cfg
;
s
->
sample_rate
=
openair0_cfg
[
0
].
sample_rate
;
s
->
sample_rate
=
openair0_cfg
[
0
].
sample_rate
;
// TODO:
// TODO:
// init tx_forward_nsamps based usrp_time_offset ex
// init tx_forward_nsamps based usrp_time_offset ex
if
(
is_equal
(
s
->
sample_rate
,
(
double
)
30.72e6
))
if
(
is_equal
(
s
->
sample_rate
,
(
double
)
30.72e6
))
s
->
tx_forward_nsamps
=
176
;
s
->
tx_forward_nsamps
=
176
;
if
(
is_equal
(
s
->
sample_rate
,
(
double
)
15.36e6
))
if
(
is_equal
(
s
->
sample_rate
,
(
double
)
15.36e6
))
s
->
tx_forward_nsamps
=
90
;
s
->
tx_forward_nsamps
=
90
;
if
(
is_equal
(
s
->
sample_rate
,
(
double
)
7.68e6
))
s
->
tx_forward_nsamps
=
50
;
if
(
is_equal
(
s
->
sample_rate
,
(
double
)
7.68e6
))
s
->
tx_forward_nsamps
=
50
;
if
(
s
->
use_gps
==
1
)
{
if
(
sync_to_gps
(
device
)
)
{
if
(
s
->
use_gps
==
1
)
{
LOG_I
(
PHY
,
"USRP fails to sync with GPS...
\n
"
);
if
(
sync_to_gps
(
device
))
{
exit
(
0
);
LOG_I
(
PHY
,
"USRP fails to sync with GPS...
\n
"
);
}
exit
(
0
);
}
}
#if defined(USRP_REC_PLAY)
}
}
#if defined(USRP_REC_PLAY)
}
#endif
#endif
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
if
(
u_sf_mode
==
1
)
{
// record mode
ms_sample
=
(
iqrec_t
*
)
malloc
(
u_sf_max
*
sizeof
(
iqrec_t
));
if
(
u_sf_mode
==
1
)
{
// record mode
if
(
ms_sample
==
NULL
)
{
ms_sample
=
(
iqrec_t
*
)
malloc
(
u_sf_max
*
sizeof
(
iqrec_t
));
std
::
cerr
<<
"Memory allocation failed for subframe record or replay mode."
<<
std
::
endl
;
exit
(
-
1
);
if
(
ms_sample
==
NULL
)
{
}
std
::
cerr
<<
"Memory allocation failed for subframe record or replay mode."
<<
std
::
endl
;
memset
(
ms_sample
,
0
,
u_sf_max
*
BELL_LABS_IQ_BYTES_PER_SF
);
exit
(
-
1
);
}
}
if
(
u_sf_mode
==
2
)
{
if
(
use_mmap
)
{
memset
(
ms_sample
,
0
,
u_sf_max
*
BELL_LABS_IQ_BYTES_PER_SF
);
// use mmap
}
mmapfd
=
open
(
u_sf_filename
,
O_RDONLY
|
O_LARGEFILE
);
if
(
mmapfd
!=
0
)
{
if
(
u_sf_mode
==
2
)
{
fstat
(
mmapfd
,
&
sb
);
if
(
use_mmap
)
{
std
::
cerr
<<
"Loading subframes using mmap() from "
<<
u_sf_filename
<<
" size="
<<
(
uint64_t
)
sb
.
st_size
<<
" bytes ..."
<<
std
::
endl
;
// use mmap
ms_sample
=
(
iqrec_t
*
)
mmap
(
NULL
,
sb
.
st_size
,
PROT_WRITE
,
MAP_PRIVATE
,
mmapfd
,
0
);
mmapfd
=
open
(
u_sf_filename
,
O_RDONLY
|
O_LARGEFILE
);
if
(
ms_sample
!=
MAP_FAILED
)
{
nb_samples
=
(
sb
.
st_size
/
sizeof
(
iqrec_t
));
if
(
mmapfd
!=
0
)
{
int
aligned
=
(((
unsigned
long
)
ms_sample
&
31
)
==
0
)
?
1
:
0
;
fstat
(
mmapfd
,
&
sb
);
std
::
cerr
<<
"Loaded "
<<
nb_samples
<<
" subframes."
<<
std
::
endl
;
std
::
cerr
<<
"Loading subframes using mmap() from "
<<
u_sf_filename
<<
" size="
<<
(
uint64_t
)
sb
.
st_size
<<
" bytes ..."
<<
std
::
endl
;
if
(
aligned
==
0
)
{
ms_sample
=
(
iqrec_t
*
)
mmap
(
NULL
,
sb
.
st_size
,
PROT_WRITE
,
MAP_PRIVATE
,
mmapfd
,
0
);
std
::
cerr
<<
"mmap address is not 32 bytes aligned, exiting."
<<
std
::
endl
;
close
(
mmapfd
);
if
(
ms_sample
!=
MAP_FAILED
)
{
exit
(
-
1
);
nb_samples
=
(
sb
.
st_size
/
sizeof
(
iqrec_t
));
}
int
aligned
=
(((
unsigned
long
)
ms_sample
&
31
)
==
0
)
?
1
:
0
;
}
else
{
std
::
cerr
<<
"Loaded "
<<
nb_samples
<<
" subframes."
<<
std
::
endl
;
std
::
cerr
<<
"Cannot mmap file, exiting."
<<
std
::
endl
;
close
(
mmapfd
);
if
(
aligned
==
0
)
{
exit
(
-
1
);
std
::
cerr
<<
"mmap address is not 32 bytes aligned, exiting."
<<
std
::
endl
;
}
close
(
mmapfd
);
}
else
{
exit
(
-
1
);
std
::
cerr
<<
"Cannot open "
<<
u_sf_filename
<<
" , exiting."
<<
std
::
endl
;
}
exit
(
-
1
);
}
else
{
}
std
::
cerr
<<
"Cannot mmap file, exiting."
<<
std
::
endl
;
}
else
{
close
(
mmapfd
);
iqfd
=
open
(
u_sf_filename
,
O_RDONLY
|
O_LARGEFILE
);
exit
(
-
1
);
if
(
iqfd
!=
0
)
{
}
fstat
(
iqfd
,
&
sb
);
}
else
{
nb_samples
=
(
sb
.
st_size
/
sizeof
(
iqrec_t
));
std
::
cerr
<<
"Cannot open "
<<
u_sf_filename
<<
" , exiting."
<<
std
::
endl
;
std
::
cerr
<<
"Loading "
<<
nb_samples
<<
" subframes from "
<<
u_sf_filename
exit
(
-
1
);
<<
" size="
<<
(
uint64_t
)
sb
.
st_size
<<
" bytes ..."
<<
std
::
endl
;
}
// allocate buffer for 1 sample at a time
}
else
{
ms_sample
=
(
iqrec_t
*
)
malloc
(
sizeof
(
iqrec_t
));
iqfd
=
open
(
u_sf_filename
,
O_RDONLY
|
O_LARGEFILE
);
if
(
ms_sample
==
NULL
)
{
std
::
cerr
<<
"Memory allocation failed for individual subframe replay mode."
<<
std
::
endl
;
if
(
iqfd
!=
0
)
{
close
(
iqfd
);
fstat
(
iqfd
,
&
sb
);
exit
(
-
1
);
nb_samples
=
(
sb
.
st_size
/
sizeof
(
iqrec_t
));
}
std
::
cerr
<<
"Loading "
<<
nb_samples
<<
" subframes from "
<<
u_sf_filename
memset
(
ms_sample
,
0
,
sizeof
(
iqrec_t
));
<<
" size="
<<
(
uint64_t
)
sb
.
st_size
<<
" bytes ..."
<<
std
::
endl
;
// point at beginning of file
// allocate buffer for 1 sample at a time
if
(
lseek
(
iqfd
,
0
,
SEEK_SET
)
==
0
)
{
ms_sample
=
(
iqrec_t
*
)
malloc
(
sizeof
(
iqrec_t
));
std
::
cerr
<<
"Initial seek at beginning of the file"
<<
std
::
endl
;
}
else
{
if
(
ms_sample
==
NULL
)
{
std
::
cerr
<<
"Problem initial seek at beginning of the file"
<<
std
::
endl
;
std
::
cerr
<<
"Memory allocation failed for individual subframe replay mode."
<<
std
::
endl
;
}
close
(
iqfd
);
}
else
{
exit
(
-
1
);
std
::
cerr
<<
"Cannot open "
<<
u_sf_filename
<<
" , exiting."
<<
std
::
endl
;
}
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
;
}
else
{
std
::
cerr
<<
"Problem initial seek at beginning of the file"
<<
std
::
endl
;
}
}
else
{
std
::
cerr
<<
"Cannot open "
<<
u_sf_filename
<<
" , exiting."
<<
std
::
endl
;
exit
(
-
1
);
}
}
}
#endif
return
0
;
}
}
#endif
return
0
;
}
}
}
/*@}*/
/*@}*/
targets/RT/USER/lte-enb.c
View file @
679485c1
...
@@ -111,8 +111,6 @@ extern volatile int start_UE;
...
@@ -111,8 +111,6 @@ extern volatile int start_UE;
#endif
#endif
extern
volatile
int
oai_exit
;
extern
volatile
int
oai_exit
;
extern
openair0_config_t
openair0_cfg
[
MAX_CARDS
];
extern
int
transmission_mode
;
extern
int
transmission_mode
;
extern
int
oaisim_flag
;
extern
int
oaisim_flag
;
...
...
targets/RT/USER/lte-softmodem.c
View file @
679485c1
...
@@ -171,8 +171,6 @@ double rx_gain_off = 0.0;
...
@@ -171,8 +171,6 @@ double rx_gain_off = 0.0;
double
sample_rate
=
30.72e6
;
double
sample_rate
=
30.72e6
;
double
bw
=
10.0e6
;
double
bw
=
10.0e6
;
static
int
tx_max_power
[
MAX_NUM_CCs
];
/* = {0,0}*/
;
char
rf_config_file
[
1024
];
char
rf_config_file
[
1024
];
int
chain_offset
=
0
;
int
chain_offset
=
0
;
...
@@ -199,7 +197,6 @@ int otg_enabled;
...
@@ -199,7 +197,6 @@ int otg_enabled;
//int number_of_cards = 1;
//int number_of_cards = 1;
static
LTE_DL_FRAME_PARMS
*
frame_parms
[
MAX_NUM_CCs
];
uint32_t
target_dl_mcs
=
28
;
//maximum allowed mcs
uint32_t
target_dl_mcs
=
28
;
//maximum allowed mcs
uint32_t
target_ul_mcs
=
20
;
uint32_t
target_ul_mcs
=
20
;
uint32_t
timing_advance
=
0
;
uint32_t
timing_advance
=
0
;
...
@@ -250,8 +247,6 @@ WORKER_CONF_t get_thread_worker_conf(void)
...
@@ -250,8 +247,6 @@ WORKER_CONF_t get_thread_worker_conf(void)
/* struct for ethernet specific parameters given in eNB conf file */
/* struct for ethernet specific parameters given in eNB conf file */
eth_params_t
*
eth_params
;
eth_params_t
*
eth_params
;
openair0_config_t
openair0_cfg
[
MAX_CARDS
];
double
cpuf
;
double
cpuf
;
extern
char
uecap_xer
[
1024
];
extern
char
uecap_xer
[
1024
];
...
@@ -632,112 +627,6 @@ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
...
@@ -632,112 +627,6 @@ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
}
}
void
init_openair0
(
void
)
{
int
card
;
int
i
;
for
(
card
=
0
;
card
<
MAX_CARDS
;
card
++
)
{
openair0_cfg
[
card
].
mmapped_dma
=
mmapped_dma
;
openair0_cfg
[
card
].
configFilename
=
NULL
;
if
(
frame_parms
[
0
]
->
N_RB_DL
==
100
)
{
if
(
numerology
==
0
)
{
if
(
frame_parms
[
0
]
->
threequarter_fs
)
{
openair0_cfg
[
card
].
sample_rate
=
23.04e6
;
openair0_cfg
[
card
].
samples_per_frame
=
230400
;
openair0_cfg
[
card
].
tx_bw
=
10e6
;
openair0_cfg
[
card
].
rx_bw
=
10e6
;
}
else
{
openair0_cfg
[
card
].
sample_rate
=
30.72e6
;
openair0_cfg
[
card
].
samples_per_frame
=
307200
;
openair0_cfg
[
card
].
tx_bw
=
10e6
;
openair0_cfg
[
card
].
rx_bw
=
10e6
;
}
}
else
if
(
numerology
==
1
)
{
openair0_cfg
[
card
].
sample_rate
=
61.44e6
;
openair0_cfg
[
card
].
samples_per_frame
=
307200
;
openair0_cfg
[
card
].
tx_bw
=
20e6
;
openair0_cfg
[
card
].
rx_bw
=
20e6
;
}
else
if
(
numerology
==
2
)
{
openair0_cfg
[
card
].
sample_rate
=
122.88e6
;
openair0_cfg
[
card
].
samples_per_frame
=
307200
;
openair0_cfg
[
card
].
tx_bw
=
20e6
;
openair0_cfg
[
card
].
rx_bw
=
20e6
;
}
else
{
printf
(
"Un supported numerology
\n
"
);
}
}
else
if
(
frame_parms
[
0
]
->
N_RB_DL
==
50
)
{
openair0_cfg
[
card
].
sample_rate
=
15.36e6
;
openair0_cfg
[
card
].
samples_per_frame
=
153600
;
openair0_cfg
[
card
].
tx_bw
=
5e6
;
openair0_cfg
[
card
].
rx_bw
=
5e6
;
}
else
if
(
frame_parms
[
0
]
->
N_RB_DL
==
25
)
{
openair0_cfg
[
card
].
sample_rate
=
7.68e6
;
openair0_cfg
[
card
].
samples_per_frame
=
76800
;
openair0_cfg
[
card
].
tx_bw
=
2.5e6
;
openair0_cfg
[
card
].
rx_bw
=
2.5e6
;
}
else
if
(
frame_parms
[
0
]
->
N_RB_DL
==
6
)
{
openair0_cfg
[
card
].
sample_rate
=
1.92e6
;
openair0_cfg
[
card
].
samples_per_frame
=
19200
;
openair0_cfg
[
card
].
tx_bw
=
1.5e6
;
openair0_cfg
[
card
].
rx_bw
=
1.5e6
;
}
if
(
frame_parms
[
0
]
->
frame_type
==
TDD
)
openair0_cfg
[
card
].
duplex_mode
=
duplex_mode_TDD
;
else
//FDD
openair0_cfg
[
card
].
duplex_mode
=
duplex_mode_FDD
;
printf
(
"HW: Configuring card %d, nb_antennas_tx/rx %d/%d
\n
"
,
card
,
RC
.
eNB
[
0
][
0
]
->
frame_parms
.
nb_antennas_tx
,
RC
.
eNB
[
0
][
0
]
->
frame_parms
.
nb_antennas_rx
);
openair0_cfg
[
card
].
Mod_id
=
0
;
openair0_cfg
[
card
].
num_rb_dl
=
frame_parms
[
0
]
->
N_RB_DL
;
openair0_cfg
[
card
].
clock_source
=
clock_source
;
openair0_cfg
[
card
].
tx_num_channels
=
min
(
2
,
RC
.
eNB
[
0
][
0
]
->
frame_parms
.
nb_antennas_tx
);
openair0_cfg
[
card
].
rx_num_channels
=
min
(
2
,
RC
.
eNB
[
0
][
0
]
->
frame_parms
.
nb_antennas_rx
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
if
(
i
<
openair0_cfg
[
card
].
tx_num_channels
)
openair0_cfg
[
card
].
tx_freq
[
i
]
=
downlink_frequency
[
0
][
i
]
;
else
openair0_cfg
[
card
].
tx_freq
[
i
]
=
0
.
0
;
if
(
i
<
openair0_cfg
[
card
].
rx_num_channels
)
openair0_cfg
[
card
].
rx_freq
[
i
]
=
downlink_frequency
[
0
][
i
]
+
uplink_frequency_offset
[
0
][
i
]
;
else
openair0_cfg
[
card
].
rx_freq
[
i
]
=
0
.
0
;
openair0_cfg
[
card
].
autocal
[
i
]
=
1
;
openair0_cfg
[
card
].
tx_gain
[
i
]
=
tx_gain
[
0
][
i
];
openair0_cfg
[
card
].
rx_gain
[
i
]
=
RC
.
eNB
[
0
][
0
]
->
rx_total_gain_dB
;
openair0_cfg
[
card
].
configFilename
=
rf_config_file
;
printf
(
"Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f
\n
"
,
card
,
i
,
openair0_cfg
[
card
].
tx_gain
[
i
],
openair0_cfg
[
card
].
rx_gain
[
i
],
openair0_cfg
[
card
].
tx_freq
[
i
],
openair0_cfg
[
card
].
rx_freq
[
i
]);
}
}
/* for loop on cards */
}
void
wait_RUs
(
void
)
{
void
wait_RUs
(
void
)
{
LOG_I
(
PHY
,
"Waiting for RUs to be configured ... RC.ru_mask:%02lx
\n
"
,
RC
.
ru_mask
);
LOG_I
(
PHY
,
"Waiting for RUs to be configured ... RC.ru_mask:%02lx
\n
"
,
RC
.
ru_mask
);
...
@@ -922,9 +811,6 @@ int main( int argc, char **argv )
...
@@ -922,9 +811,6 @@ int main( int argc, char **argv )
mode
=
normal_txrx
;
mode
=
normal_txrx
;
memset
(
&
openair0_cfg
[
0
],
0
,
sizeof
(
openair0_config_t
)
*
MAX_CARDS
);
memset
(
tx_max_power
,
0
,
sizeof
(
int
)
*
MAX_NUM_CCs
);
set_latency_target
();
set_latency_target
();
...
@@ -1283,8 +1169,6 @@ int main( int argc, char **argv )
...
@@ -1283,8 +1169,6 @@ int main( int argc, char **argv )
pthread_mutex_destroy
(
&
ue_pf_po_mutex
);
pthread_mutex_destroy
(
&
ue_pf_po_mutex
);
// *** Handle per CC_id openair0
for
(
ru_id
=
0
;
ru_id
<
RC
.
nb_RU
;
ru_id
++
)
{
for
(
ru_id
=
0
;
ru_id
<
RC
.
nb_RU
;
ru_id
++
)
{
if
(
RC
.
ru
[
ru_id
]
->
rfdevice
.
trx_end_func
)
{
if
(
RC
.
ru
[
ru_id
]
->
rfdevice
.
trx_end_func
)
{
...
...
targets/RT/USER/lte-softmodem.h
View file @
679485c1
...
@@ -98,6 +98,9 @@
...
@@ -98,6 +98,9 @@
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n"
#define CONFIG_HLP_USRP_CLK_SRC "USRP clock source: 'internal' or 'external'\n"
/***************************************************************************************************************************************/
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
when calling config_get or config_getlist functions */
when calling config_get or config_getlist functions */
...
@@ -147,7 +150,9 @@
...
@@ -147,7 +150,9 @@
{"num-ues", NULL, 0, u8ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT8, 0}, \
{"num-ues", NULL, 0, u8ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT8, 0}, \
{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \
{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
}
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \
{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0} \
}
#define DEFAULT_DLF 2680000000
#define DEFAULT_DLF 2680000000
...
...
targets/RT/USER/lte-uesoftmodem.c
View file @
679485c1
...
@@ -223,6 +223,9 @@ int numerology = 0;
...
@@ -223,6 +223,9 @@ int numerology = 0;
char
*
parallel_config
=
NULL
;
char
*
parallel_config
=
NULL
;
char
*
worker_config
=
NULL
;
char
*
worker_config
=
NULL
;
char
*
usrp_args
=
NULL
;
char
*
usrp_clksrc
=
NULL
;
static
THREAD_STRUCT
thread_struct
;
static
THREAD_STRUCT
thread_struct
;
void
set_parallel_conf
(
char
*
parallel_conf
)
void
set_parallel_conf
(
char
*
parallel_conf
)
{
{
...
@@ -739,6 +742,26 @@ void init_openair0(LTE_DL_FRAME_PARMS *frame_parms,int rxgain) {
...
@@ -739,6 +742,26 @@ void init_openair0(LTE_DL_FRAME_PARMS *frame_parms,int rxgain) {
openair0_cfg
[
card
].
tx_freq
[
i
],
openair0_cfg
[
card
].
tx_freq
[
i
],
openair0_cfg
[
card
].
rx_freq
[
i
]);
openair0_cfg
[
card
].
rx_freq
[
i
]);
}
}
if
(
usrp_args
)
openair0_cfg
[
card
].
sdr_addrs
=
usrp_args
;
if
(
usrp_clksrc
)
{
if
(
strcmp
(
usrp_clksrc
,
"internal"
)
==
0
)
{
openair0_cfg
[
card
].
clock_source
=
internal
;
LOG_D
(
PHY
,
"USRP clock source set as internal
\n
"
);
}
else
if
(
strcmp
(
usrp_clksrc
,
"external"
)
==
0
)
{
openair0_cfg
[
card
].
clock_source
=
external
;
LOG_D
(
PHY
,
"USRP clock source set as external
\n
"
);
}
else
if
(
strcmp
(
usrp_clksrc
,
"gpsdo"
)
==
0
)
{
openair0_cfg
[
card
].
clock_source
=
gpsdo
;
LOG_D
(
PHY
,
"USRP clock source set as gpsdo
\n
"
);
}
else
{
openair0_cfg
[
card
].
clock_source
=
internal
;
LOG_I
(
PHY
,
"USRP clock source unknown ('%s'). defaulting to internal
\n
"
,
usrp_clksrc
);
}
}
else
{
openair0_cfg
[
card
].
clock_source
=
internal
;
LOG_I
(
PHY
,
"USRP clock source not specified. defaulting to internal
\n
"
);
}
}
}
}
}
...
...
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