Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lizhongxiao
OpenXG-RAN
Commits
faba9ac2
Commit
faba9ac2
authored
Apr 22, 2022
by
Florian Kaltenberger
Committed by
Robert Schmidt
Jan 19, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make USRP GPIO control more flexible
- adding support for x410 GPIO
parent
214aa505
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
65 additions
and
55 deletions
+65
-55
executables/nr-ru.c
executables/nr-ru.c
+15
-14
maketags
maketags
+1
-1
radio/COMMON/common_lib.h
radio/COMMON/common_lib.h
+1
-1
radio/USRP/USERSPACE/LIB/usrp_lib.cpp
radio/USRP/USERSPACE/LIB/usrp_lib.cpp
+48
-39
No files found.
executables/nr-ru.c
View file @
faba9ac2
...
...
@@ -733,7 +733,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
T_INT
(
0
),
T_BUFFER
(
&
ru
->
common
.
txdata
[
0
][
fp
->
get_samples_slot_timestamp
(
slot
,
fp
,
0
)],
fp
->
samples_per_subframe
*
4
));
int
sf_extension
=
0
;
int
siglen
=
fp
->
get_samples_per_slot
(
slot
,
fp
);
int
flags
=
0
;
int
flags
=
0
,
flags_burst
=
0
,
flags_gpio
=
0
;
if
(
cfg
->
cell_config
.
frame_duplex_type
.
value
==
TDD
&&
!
get_softmodem_params
()
->
continuous_tx
)
{
int
slot_type
=
nr_slot_select
(
cfg
,
frame
,
slot
%
fp
->
slots_per_frame
);
...
...
@@ -760,39 +760,37 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
}
//+ ru->end_of_burst_delay;
flags
=
3
;
// end of burst
flags
_burst
=
3
;
// end of burst
}
else
if
(
slot_type
==
NR_DOWNLINK_SLOT
)
{
int
prevslot_type
=
nr_slot_select
(
cfg
,
frame
,(
slot
+
(
fp
->
slots_per_frame
-
1
))
%
fp
->
slots_per_frame
);
int
nextslot_type
=
nr_slot_select
(
cfg
,
frame
,(
slot
+
1
)
%
fp
->
slots_per_frame
);
if
(
prevslot_type
==
NR_UPLINK_SLOT
)
{
flags
=
2
;
// start of burst
flags
_burst
=
2
;
// start of burst
sf_extension
=
ru
->
sf_extension
;
}
else
if
(
nextslot_type
==
NR_UPLINK_SLOT
)
{
flags
=
3
;
// end of burst
flags
_burst
=
3
;
// end of burst
}
else
{
flags
=
1
;
// middle of burst
flags
_burst
=
1
;
// middle of burst
}
}
}
else
{
// FDD
if
(
proc
->
first_tx
==
1
)
{
flags
=
2
;
// start of burst
flags
_burst
=
2
;
// start of burst
}
else
{
flags
=
1
;
// middle of burst
flags
_burst
=
1
;
// middle of burst
}
}
if
(
flags
)
{
if
(
fp
->
freq_range
==
nr_FR2
)
{
// the beam index is written in bits 8-10 of the flags
// bit 11 enables the gpio programming
// currently we switch beams every 10 slots (should = 1 TDD period in FR2) and we take the beam index of the first symbol of the first slot of this period
int
beam
=
0
;
if
(
slot
%
10
==
0
)
{
if
(
ru
->
common
.
beam_id
&&
(
ru
->
common
.
beam_id
[
0
][
slot
*
fp
->
symbols_per_slot
]
<
8
))
{
beam
=
ru
->
common
.
beam_id
[
0
][
slot
*
fp
->
symbols_per_slot
]
|
8
;
beam
=
ru
->
common
.
beam_id
[
0
][
slot
*
fp
->
symbols_per_slot
];
}
}
LOG_D
(
HW
,
"slot %d, beam %d
\n
"
,
slot
,
ru
->
common
.
beam_id
[
0
][
slot
*
fp
->
symbols_per_slot
]);
/*
if (slot==0 || slot==40) beam=0|8;
...
...
@@ -800,9 +798,12 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
if (slot==20 || slot==60) beam=2|8;
if (slot==30 || slot==70) beam=3|8;
*/
flags
|=
beam
<<
8
;
LOG_D
(
HW
,
"slot %d, beam %d
\n
"
,
slot
,
ru
->
common
.
beam_id
[
0
][
slot
*
fp
->
symbols_per_slot
]);
flags_gpio
=
beam
&
0x1000
;
//enable change of gpio
}
flags
=
flags_burst
|
flags_gpio
<<
4
;
if
(
proc
->
first_tx
==
1
)
proc
->
first_tx
=
0
;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(
VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS
,
flags
);
...
...
@@ -825,7 +826,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
(
long
long
unsigned
int
)(
timestamp
+
ru
->
ts_offset
-
ru
->
openair0_cfg
.
tx_sample_advance
-
sf_extension
),
frame
,
slot
,
proc
->
frame_tx_unwrap
,
slot
,
flags
,
siglen
+
sf_extension
,
txs
,
10
*
log10
((
double
)
signal_energy
(
txp
[
0
],
siglen
+
sf_extension
)));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE
,
0
);
//AssertFatal(txs == 0,"trx write function error %d\n", txs);
}
}
// this is for RU with local RF unit
...
...
maketags
View file @
faba9ac2
#!/bin/sh
echo
"building ctags for openair1 and openair2 ..."
ctags
-e
-R
--exclude
=
openair1/DOCS/
--exclude
=
openair2/DOCS/
--exclude
=
openair1/SIMULATION/
--exclude
=
targets/DOCS/
--exclude
=
targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi executables
ctags
-e
-R
--exclude
=
openair1/DOCS/
--exclude
=
openair2/DOCS/
--exclude
=
openair1/SIMULATION/
--exclude
=
targets/DOCS/
--exclude
=
targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi executables
sdr
radio/COMMON/common_lib.h
View file @
faba9ac2
...
...
@@ -315,7 +315,7 @@ typedef struct {
int
cc
;
signed
char
first_packet
;
signed
char
last_packet
;
int
flags_
msb
;
int
flags_
gpio
;
}
openair0_write_package_t
;
typedef
struct
{
...
...
radio/USRP/USERSPACE/LIB/usrp_lib.cpp
View file @
faba9ac2
...
...
@@ -59,7 +59,6 @@
/** @addtogroup _USRP_PHY_RF_INTERFACE_
* @{
*/
int
gpio789
=
0
;
extern
int
usrp_tx_thread
;
...
...
@@ -88,6 +87,9 @@ typedef struct {
//! TX forward samples. We use usrp_time_offset to get this value
int
tx_forward_nsamps
;
//166 for 20Mhz
//! gpio bank to use
std
::
string
gpio_bank
;
// --------------------------------
// Debug and output control
// --------------------------------
...
...
@@ -258,27 +260,41 @@ static int sync_to_gps(openair0_device *device) {
return
EXIT_SUCCESS
;
}
#define ATR_MASK 0x7f //pins controlled by ATR
#define ATR_RX 0x50 //data[4] and data[6]
#define ATR_XX 0x20 //data[5]
#define MAN_MASK ATR_MASK^0xFFF //manually controlled pins
/*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error
@param device pointer to the device structure specific to the RF hardware target
*/
static
int
trx_usrp_start
(
openair0_device
*
device
)
{
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
if
(
device
->
type
!=
USRP_X400_DEV
)
{
// setup GPIO for TDD, GPIO(4) = ATR_RX
//set data direction register (DDR) to output
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"DDR"
,
0xfff
,
0xfff
);
//set lower 7 bits to be controlled automatically by ATR (the rest 5 bits are controlled manually)
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"CTRL"
,
0x7f
,
0xfff
);
//set pins 4 (RX_TX_Switch) and 6 (Shutdown PA) to 1 when the radio is only receiving (ATR_RX)
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"ATR_RX"
,
(
1
<<
4
)
|
(
1
<<
6
),
0x7f
);
// set pin 5 (Shutdown LNA) to 1 when the radio is transmitting and receiveing (ATR_XX)
// (we use full duplex here, because our RX is on all the time - this might need to change later)
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"ATR_XX"
,
(
1
<<
5
),
0x7f
);
// set the output pins to 1
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"OUT"
,
7
<<
7
,
0xf80
);
}
s
->
gpio_bank
=
"FP0"
;
//good for B210, X310 and N310
#if UHD_VERSION>4000000
if
(
device
->
type
==
USRP_X400_DEV
)
{
// Set every pin on GPIO0 to be controlled by DB0_RF0
std
::
vector
<
std
::
string
>
sxx
{
12
,
"DB0_RF0"
};
s
->
gpio_bank
=
"GPIO0"
;
s
->
usrp
->
set_gpio_src
(
s
->
gpio_bank
,
sxx
);
}
#endif
// setup GPIO for TDD, GPIO(4) = ATR_RX
//set data direction register (DDR) to output
s
->
usrp
->
set_gpio_attr
(
s
->
gpio_bank
,
"DDR"
,
0xfff
,
0xfff
);
//set bits to be controlled automatically by ATR
s
->
usrp
->
set_gpio_attr
(
s
->
gpio_bank
,
"CTRL"
,
ATR_MASK
,
0xfff
);
//set bits to 1 when the radio is only receiving (ATR_RX)
s
->
usrp
->
set_gpio_attr
(
s
->
gpio_bank
,
"ATR_RX"
,
ATR_RX
,
ATR_MASK
);
// set bits to 1 when the radio is transmitting and receiveing (ATR_XX)
// (we use full duplex here, because our RX is on all the time - this might need to change later)
s
->
usrp
->
set_gpio_attr
(
s
->
gpio_bank
,
"ATR_XX"
,
ATR_XX
,
ATR_MASK
);
// set all other pins to manual
s
->
usrp
->
set_gpio_attr
(
s
->
gpio_bank
,
"OUT"
,
MAN_MASK
,
0xfff
);
s
->
wait_for_first_pps
=
1
;
s
->
rx_count
=
0
;
s
->
tx_count
=
0
;
...
...
@@ -373,8 +389,8 @@ static int trx_usrp_write(openair0_device *device,
usrp_state_t
*
s
=
(
usrp_state_t
*
)
device
->
priv
;
int
nsamps2
;
// aligned to upper 32 or 16 byte boundary
int
flags_
lsb
=
flags
&
0xf
f
;
int
flags_
msb
=
(
flags
>>
8
)
&
0xff
;
int
flags_
burst
=
flags
&
0x
f
;
int
flags_
gpio
=
(
flags
>>
4
)
&
0x1fff
;
//MSB to enable sending GPIO command, 12 LSB carry GPIO values
int
end
;
openair0_thread_t
*
write_thread
=
&
device
->
write_thread
;
...
...
@@ -384,28 +400,28 @@ static int trx_usrp_write(openair0_device *device,
bool
first_packet_state
=
false
,
last_packet_state
=
false
;
if
(
flags_
lsb
==
2
)
{
// start of burst
if
(
flags_
burst
==
2
)
{
// start of burst
// s->tx_md.start_of_burst = true;
// s->tx_md.end_of_burst = false;
first_packet_state
=
true
;
last_packet_state
=
false
;
}
else
if
(
flags_
lsb
==
3
)
{
// end of burst
}
else
if
(
flags_
burst
==
3
)
{
// end of burst
//s->tx_md.start_of_burst = false;
//s->tx_md.end_of_burst = true;
first_packet_state
=
false
;
last_packet_state
=
true
;
}
else
if
(
flags_
lsb
==
4
)
{
// start and end
}
else
if
(
flags_
burst
==
4
)
{
// start and end
// s->tx_md.start_of_burst = true;
// s->tx_md.end_of_burst = true;
first_packet_state
=
true
;
last_packet_state
=
true
;
}
else
if
(
flags_
lsb
==
1
)
{
// middle of burst
}
else
if
(
flags_
burst
==
1
)
{
// middle of burst
// s->tx_md.start_of_burst = false;
// s->tx_md.end_of_burst = false;
first_packet_state
=
false
;
last_packet_state
=
false
;
}
else
if
(
flags_
lsb
==
10
)
{
// fail safe mode
else
if
(
flags_
burst
==
10
)
{
// fail safe mode
// s->tx_md.has_time_spec = false;
// s->tx_md.start_of_burst = false;
// s->tx_md.end_of_burst = true;
...
...
@@ -449,12 +465,11 @@ static int trx_usrp_write(openair0_device *device,
s
->
tx_count
++
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO
,
1
);
// bit 3 enables gpio (for backward compatibility)
if
(
flags_msb
&
8
)
{
// push GPIO bits 7-9 from flags_msb
int
gpio789
=
(
flags_msb
&
7
)
<<
7
;
// bit 13 enables gpio
if
(
flags_gpio
&
0x1000
)
{
// push GPIO bits
s
->
usrp
->
set_command_time
(
s
->
tx_md
.
time_spec
);
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"OUT"
,
gpio789
,
0x380
);
s
->
usrp
->
set_gpio_attr
(
s
->
gpio_bank
,
"OUT"
,
flags_gpio
,
MAN_MASK
);
s
->
usrp
->
clear_command_time
();
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO
,
0
);
...
...
@@ -489,7 +504,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHI
write_package
[
end
].
cc
=
cc
;
write_package
[
end
].
first_packet
=
first_packet_state
;
write_package
[
end
].
last_packet
=
last_packet_state
;
write_package
[
end
].
flags_
msb
=
flags_msb
;
write_package
[
end
].
flags_
gpio
=
flags_gpio
;
for
(
int
i
=
0
;
i
<
cc
;
i
++
)
write_package
[
end
].
buff
[
i
]
=
buff
[
i
];
write_thread
->
count_write
++
;
...
...
@@ -526,7 +541,7 @@ void *trx_usrp_write_thread(void * arg){
int
cc
;
signed
char
first_packet
;
signed
char
last_packet
;
int
flags_
msb
;
int
flags_
gpio
;
while
(
1
){
pthread_mutex_lock
(
&
write_thread
->
mutex_write
);
...
...
@@ -544,7 +559,7 @@ void *trx_usrp_write_thread(void * arg){
cc
=
write_package
[
start
].
cc
;
first_packet
=
write_package
[
start
].
first_packet
;
last_packet
=
write_package
[
start
].
last_packet
;
flags_
msb
=
write_package
[
start
].
flags_msb
;
flags_
gpio
=
write_package
[
start
].
flags_gpio
;
write_thread
->
start
=
(
write_thread
->
start
+
1
)
%
MAX_WRITE_THREAD_PACKAGE
;
write_thread
->
count_write
--
;
pthread_mutex_unlock
(
&
write_thread
->
mutex_write
);
...
...
@@ -589,11 +604,10 @@ void *trx_usrp_write_thread(void * arg){
s
->
tx_count
++
;
// bit 3 enables gpio (for backward compatibility)
if
(
flags_msb
&
8
)
{
// push GPIO bits 7-9 from flags_msb
int
gpio789
=
(
flags_msb
&
7
)
<<
7
;
if
(
flags_gpio
&
0x1000
)
{
// push GPIO bits
s
->
usrp
->
set_command_time
(
s
->
tx_md
.
time_spec
);
s
->
usrp
->
set_gpio_attr
(
"FP0"
,
"OUT"
,
gpio789
,
0x380
);
s
->
usrp
->
set_gpio_attr
(
s
->
gpio_bank
,
"OUT"
,
flags_gpio
,
MAN_MASK
);
s
->
usrp
->
clear_command_time
();
}
...
...
@@ -740,11 +754,6 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
s
->
rx_timestamp
=
s
->
rx_md
.
time_spec
.
to_ticks
(
s
->
sample_rate
);
*
ptimestamp
=
s
->
rx_timestamp
;
// push GPIO bits 7-9 from flags_msb
/*s->usrp->set_command_time(uhd::time_spec_t::from_ticks((s->rx_timestamp+(2*nsamps)),s->sample_rate));
s->usrp->set_gpio_attr("FP0", "OUT", gpio789<<7, 0x380);
s->usrp->clear_command_time();
gpio789 = (gpio789+1)&7;*/
recplay_state_t
*
recPlay
=
device
->
recplay_state
;
if
(
recPlay
!=
NULL
)
{
// record mode
...
...
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