Make USRP GPIO control more flexible

- adding support for x410 GPIO
This commit is contained in:
Florian Kaltenberger
2023-01-19 14:32:01 +01:00
committed by Robert Schmidt
parent 214aa50595
commit faba9ac244
4 changed files with 65 additions and 55 deletions
+48 -39
View File
@@ -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&0xff;
int flags_msb = (flags>>8)&0xff;
int flags_burst = flags&0xf;
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