summaryrefslogtreecommitdiff
path: root/usrp2/host
diff options
context:
space:
mode:
authorjcorgan2009-04-04 05:59:44 +0000
committerjcorgan2009-04-04 05:59:44 +0000
commit40402fb8f5c1009b6fa205303c7a57b0ae918148 (patch)
tree9faab37d57dc43f2e5c7a56ccec54926929a64c3 /usrp2/host
parent0907e015a341269f1d9fdb556fcadd8c051c7f81 (diff)
downloadgnuradio-40402fb8f5c1009b6fa205303c7a57b0ae918148.tar.gz
gnuradio-40402fb8f5c1009b6fa205303c7a57b0ae918148.tar.bz2
gnuradio-40402fb8f5c1009b6fa205303c7a57b0ae918148.zip
Merged r10712:10765 from jcorgan/gpio into trunk. Adds out-of-band and streaming GPIO functions for USRP2.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10766 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'usrp2/host')
-rw-r--r--usrp2/host/apps/Makefile.am3
-rw-r--r--usrp2/host/apps/gpio.cc46
-rw-r--r--usrp2/host/include/usrp2/usrp2.h89
-rw-r--r--usrp2/host/lib/control.h12
-rw-r--r--usrp2/host/lib/usrp2.cc31
-rw-r--r--usrp2/host/lib/usrp2_impl.cc157
-rw-r--r--usrp2/host/lib/usrp2_impl.h5
7 files changed, 341 insertions, 2 deletions
diff --git a/usrp2/host/apps/Makefile.am b/usrp2/host/apps/Makefile.am
index b6f1c03ff..da44776c9 100644
--- a/usrp2/host/apps/Makefile.am
+++ b/usrp2/host/apps/Makefile.am
@@ -36,7 +36,8 @@ noinst_PROGRAMS = \
gen_const \
rx_streaming_samples \
tx_samples \
- test_mimo_tx
+ test_mimo_tx \
+ gpio
find_usrps_SOURCES = find_usrps.cc
usrp2_burn_mac_addr_SOURCES = usrp2_burn_mac_addr.cc
diff --git a/usrp2/host/apps/gpio.cc b/usrp2/host/apps/gpio.cc
new file mode 100644
index 000000000..770b54ee2
--- /dev/null
+++ b/usrp2/host/apps/gpio.cc
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <usrp2/usrp2.h>
+#include <iostream>
+
+int
+main(int argc, char **argv)
+{
+ usrp2::usrp2::sptr u2 = usrp2::usrp2::make("eth0");
+
+ // Set io_tx[15] as FPGA output
+ u2->set_gpio_ddr(usrp2::GPIO_TX_BANK, 0x8000, 0x8000);
+
+ // Set io_tx[15] under host sofware control
+ u2->set_gpio_sels(usrp2::GPIO_TX_BANK, "s...............");
+
+ // Write pins
+ uint16_t v = 0x8765;
+ u2->write_gpio(usrp2::GPIO_TX_BANK, v, 0x8000);
+
+ // Read back
+ v = 0;
+ u2->read_gpio(usrp2::GPIO_TX_BANK, &v);
+ printf("TX GPIO read: %04X\n", v);
+ return 0;
+}
diff --git a/usrp2/host/include/usrp2/usrp2.h b/usrp2/host/include/usrp2/usrp2.h
index 70d800bf0..e80eda3e4 100644
--- a/usrp2/host/include/usrp2/usrp2.h
+++ b/usrp2/host/include/usrp2/usrp2.h
@@ -63,6 +63,10 @@ namespace usrp2 {
props_vector_t find(const std::string &ifc, const std::string &mac_addr="");
class tune_result;
+
+ // FIXME: get from firmware include
+ static const int GPIO_TX_BANK = 0;
+ static const int GPIO_RX_BANK = 1;
class usrp2 : boost::noncopyable
{
@@ -414,6 +418,91 @@ namespace usrp2 {
*/
bool poke32(uint32_t addr, const std::vector<uint32_t> &data);
+ /*!
+ * Set daughterboard GPIO data direction register.
+ *
+ * \param bank GPIO_TX_BANK or GPIO_RX_BANK
+ * \param value 16-bits, 0=FPGA input, 1=FPGA output
+ * \param mask 16-bits, 0=ignore, 1=set
+ *
+ * \returns true iff successful
+ *
+ * WARNING: Improper usage of this function may result in damage to the USRP2
+ *
+ */
+ bool set_gpio_ddr(int bank, uint16_t value, uint16_t mask);
+
+ /*!
+ * Set daughterboard GPIO output selection register. For those GPIO pins that
+ * are configured as outputs in the DDR, this settings configures the source
+ * of the pin value.
+ *
+ * \param bank GPIO_TX_BANK or GPIO_RX_BANK
+ * \param sels Exactly 16 character MSB->LSB string. For each position:
+ * '.' = ignore this bit, i.e., leave current value
+ * 'a' = Output ATR value
+ * 's' = Output host software controlled value
+ * '0' = Output FPGA debug bus 0 value
+ * '1' = Output FPGA debug bus 1 value
+ *
+ * \returns true iff successful
+ *
+ * WARNING: Improper usage of this function may result in damage to the USRP2
+ *
+ */
+ bool set_gpio_sels(int bank, std::string sels);
+
+ /*!
+ * Set daughterboard GPIO pin values.
+ *
+ * \param bank GPIO_TX_BANK or GPIO_RX_BANK
+ * \param value 16 bits, 0=low, 1=high
+ * \param mask 16 bits, 0=ignore, 1=set
+ *
+ * \returns true iff successful
+ *
+ * WARNING: Improper usage of this function may result in damage to the USRP2
+ *
+ */
+ bool write_gpio(int bank, uint16_t value, uint16_t mask);
+
+ /*!
+ * Read daughterboard GPIO pin values
+ *
+ * \param bank GPIO_TX_BANK or GPIO_RX_BANK
+ * \param value pointer to uint16_t to hold read results
+ *
+ * \returns true iff successful
+ *
+ */
+ bool read_gpio(int bank, uint16_t *value);
+
+ /*!
+ * Set GPIO streaming mode
+ *
+ * Individually enables streaming GPIO pins through LSBs of DSP
+ * samples.
+ *
+ * On receive, io_rx[15] replaces I[0], io_rx[14] replaces Q[0]
+ * On transmit, I[0] maps to io_tx[15], Q[0] maps to io_tx[14]
+ * (Transmit streaming is not yet implemented.)
+ *
+ * The selected GPIO pins must have been set as inputs or outputs
+ * and, for transmit, set to software control.
+ *
+ * When enabled, the replaced DSP sample LSBs become 0.
+ *
+ * \param bank GPIO_TX_BANK or GPIO_RX_BANK
+ * \param enable enable[0] controls I channel LSB
+ * enable[1] controls Q channel LSB
+ *
+ * \returns true iff successful
+ *
+ * WARNING: Improper usage of this function may result in damage to the USRP2
+ *
+ */
+ bool enable_gpio_streaming(int bank, int enable);
+
#if 0 // not yet implemented
/*!
* \brief Write EEPROM on motherboard or any daughterboard.
diff --git a/usrp2/host/lib/control.h b/usrp2/host/lib/control.h
index 0e8fcfe57..9adc1618f 100644
--- a/usrp2/host/lib/control.h
+++ b/usrp2/host/lib/control.h
@@ -99,6 +99,18 @@ namespace usrp2 {
op_generic_t eop;
};
+ struct op_gpio_cmd {
+ u2_eth_packet_t h;
+ op_gpio_t op;
+ op_generic_t eop;
+ };
+
+ struct op_gpio_set_sels_cmd {
+ u2_eth_packet_t h;
+ op_gpio_set_sels_t op;
+ op_generic_t eop;
+ };
+
/*!
* Control mechanism to allow API calls to block waiting for reply packets
*/
diff --git a/usrp2/host/lib/usrp2.cc b/usrp2/host/lib/usrp2.cc
index 2e8540e91..8160d01fa 100644
--- a/usrp2/host/lib/usrp2.cc
+++ b/usrp2/host/lib/usrp2.cc
@@ -437,8 +437,37 @@ namespace usrp2 {
return d_impl->poke32(addr, data);
}
-} // namespace usrp2
+ bool
+ usrp2::set_gpio_ddr(int bank, uint16_t value, uint16_t mask)
+ {
+ return d_impl->set_gpio_ddr(bank, value, mask);
+ }
+ bool
+ usrp2::set_gpio_sels(int bank, std::string src)
+ {
+ return d_impl->set_gpio_sels(bank, src);
+ }
+
+ bool
+ usrp2::write_gpio(int bank, uint16_t value, uint16_t mask)
+ {
+ return d_impl->write_gpio(bank, value, mask);
+ }
+
+ bool
+ usrp2::read_gpio(int bank, uint16_t *value)
+ {
+ return d_impl->read_gpio(bank, value);
+ }
+
+ bool
+ usrp2::enable_gpio_streaming(int bank, int enable)
+ {
+ return d_impl->enable_gpio_streaming(bank, enable);
+ }
+
+} // namespace usrp2
std::ostream& operator<<(std::ostream &os, const usrp2::props &x)
{
diff --git a/usrp2/host/lib/usrp2_impl.cc b/usrp2/host/lib/usrp2_impl.cc
index 9c30bce92..561b53101 100644
--- a/usrp2/host/lib/usrp2_impl.cc
+++ b/usrp2/host/lib/usrp2_impl.cc
@@ -1293,4 +1293,161 @@ namespace usrp2 {
return success;
}
+ bool usrp2::impl::set_gpio_ddr(int bank, uint16_t value, uint16_t mask)
+ {
+ if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) {
+ fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n");
+ return false;
+ }
+
+ op_gpio_cmd cmd;
+ op_generic_t reply;
+
+ memset(&cmd, 0, sizeof(cmd));
+ init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
+ cmd.op.opcode = OP_GPIO_SET_DDR;
+ cmd.op.len = sizeof(cmd.op);
+ cmd.op.rid = d_next_rid++;
+ cmd.op.bank = static_cast<uint8_t>(bank);
+ cmd.op.value = htons(value);
+ cmd.op.mask = htons(mask);
+ cmd.eop.opcode = OP_EOP;
+ cmd.eop.len = sizeof(cmd.eop);
+
+ pending_reply p(cmd.op.rid, &reply, sizeof(reply));
+ if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ return false;
+
+ bool success = (ntohx(reply.ok) == 1);
+ return success;
+ }
+
+ bool usrp2::impl::set_gpio_sels(int bank, std::string sels)
+ {
+ if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) {
+ fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n");
+ return false;
+ }
+
+ if (sels.size() != 16) {
+ fprintf(stderr, "set_gpio_sels: sels must be exactly 16 bytes\n");
+ return false;
+ }
+
+ op_gpio_set_sels_cmd cmd;
+ op_generic_t reply;
+
+ memset(&cmd, 0, sizeof(cmd));
+ init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
+ cmd.op.opcode = OP_GPIO_SET_SELS;
+ cmd.op.len = sizeof(cmd.op);
+ cmd.op.rid = d_next_rid++;
+ cmd.op.bank = static_cast<uint8_t>(bank);
+ memcpy(&cmd.op.sels, sels.c_str(), 16);
+ cmd.eop.opcode = OP_EOP;
+ cmd.eop.len = sizeof(cmd.eop);
+
+ pending_reply p(cmd.op.rid, &reply, sizeof(reply));
+ if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ return false;
+
+ bool success = (ntohx(reply.ok) == 1);
+ return success;
+ }
+
+ bool usrp2::impl::write_gpio(int bank, uint16_t value, uint16_t mask)
+ {
+ if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) {
+ fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n");
+ return false;
+ }
+
+ op_gpio_cmd cmd;
+ op_generic_t reply;
+
+ memset(&cmd, 0, sizeof(cmd));
+ init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
+ cmd.op.opcode = OP_GPIO_WRITE;
+ cmd.op.len = sizeof(cmd.op);
+ cmd.op.rid = d_next_rid++;
+ cmd.op.bank = static_cast<uint8_t>(bank);
+ cmd.op.value = htons(value);
+ cmd.op.mask = htons(mask);
+ cmd.eop.opcode = OP_EOP;
+ cmd.eop.len = sizeof(cmd.eop);
+
+ pending_reply p(cmd.op.rid, &reply, sizeof(reply));
+ if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ return false;
+
+ bool success = (ntohx(reply.ok) == 1);
+ return success;
+ }
+
+ bool usrp2::impl::read_gpio(int bank, uint16_t *value)
+ {
+ if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) {
+ fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n");
+ return false;
+ }
+
+ op_gpio_cmd cmd;
+ op_gpio_read_reply_t reply;
+
+ memset(&cmd, 0, sizeof(cmd));
+ init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
+ cmd.op.opcode = OP_GPIO_READ;
+ cmd.op.len = sizeof(cmd.op);
+ cmd.op.rid = d_next_rid++;
+ cmd.op.bank = static_cast<uint8_t>(bank);
+ cmd.op.value = 0; // not used
+ cmd.op.mask = 0; // not used
+ cmd.eop.opcode = OP_EOP;
+ cmd.eop.len = sizeof(cmd.eop);
+
+ pending_reply p(cmd.op.rid, &reply, sizeof(reply));
+ if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ return false;
+
+ bool success = (ntohx(reply.ok) == 1);
+ if (success && (value != NULL))
+ *value = ntohs(reply.value);
+
+ return success;
+ }
+
+ bool usrp2::impl::enable_gpio_streaming(int bank, int enable)
+ {
+ if (bank != GPIO_RX_BANK) {
+ fprintf(stderr, "enable_gpio_streaming: only RX streaming is currently implemented\n");
+ return false;
+ }
+
+ if ((enable & ~0x03) != 0) {
+ fprintf(stderr, "enable_gpio_streaming: invalid enable format\n");
+ return false;
+ }
+
+ op_gpio_cmd cmd;
+ op_generic_t reply;
+
+ memset(&cmd, 0, sizeof(cmd));
+ init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
+ cmd.op.opcode = OP_GPIO_STREAM;
+ cmd.op.len = sizeof(cmd.op);
+ cmd.op.rid = d_next_rid++;
+ cmd.op.bank = static_cast<uint8_t>(bank);
+ cmd.op.value = htons((uint16_t)enable);
+ cmd.op.mask = 0; // not used
+ cmd.eop.opcode = OP_EOP;
+ cmd.eop.len = sizeof(cmd.eop);
+
+ pending_reply p(cmd.op.rid, &reply, sizeof(reply));
+ if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ return false;
+
+ bool success = (ntohx(reply.ok) == 1);
+ return success;
+ }
+
} // namespace usrp2
diff --git a/usrp2/host/lib/usrp2_impl.h b/usrp2/host/lib/usrp2_impl.h
index c36a6d3c5..c5079a856 100644
--- a/usrp2/host/lib/usrp2_impl.h
+++ b/usrp2/host/lib/usrp2_impl.h
@@ -133,6 +133,11 @@ namespace usrp2 {
bool set_rx_decim(int decimation_factor);
int rx_decim() { return d_rx_decim; }
bool set_rx_scale_iq(int scale_i, int scale_q);
+ bool set_gpio_ddr(int bank, uint16_t value, uint16_t mask);
+ bool set_gpio_sels(int bank, std::string src);
+ bool enable_gpio_streaming(int bank, int enable);
+ bool write_gpio(int bank, uint16_t value, uint16_t mask);
+ bool read_gpio(int bank, uint16_t *value);
bool start_rx_streaming(unsigned int channel, unsigned int items_per_frame);
bool rx_samples(unsigned int channel, rx_sample_handler *handler);
bool stop_rx_streaming(unsigned int channel);