diff options
author | jcorgan | 2009-04-04 05:59:44 +0000 |
---|---|---|
committer | jcorgan | 2009-04-04 05:59:44 +0000 |
commit | 40402fb8f5c1009b6fa205303c7a57b0ae918148 (patch) | |
tree | 9faab37d57dc43f2e5c7a56ccec54926929a64c3 /usrp2/host | |
parent | 0907e015a341269f1d9fdb556fcadd8c051c7f81 (diff) | |
download | gnuradio-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.am | 3 | ||||
-rw-r--r-- | usrp2/host/apps/gpio.cc | 46 | ||||
-rw-r--r-- | usrp2/host/include/usrp2/usrp2.h | 89 | ||||
-rw-r--r-- | usrp2/host/lib/control.h | 12 | ||||
-rw-r--r-- | usrp2/host/lib/usrp2.cc | 31 | ||||
-rw-r--r-- | usrp2/host/lib/usrp2_impl.cc | 157 | ||||
-rw-r--r-- | usrp2/host/lib/usrp2_impl.h | 5 |
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); |