diff options
Diffstat (limited to 'host/lib/usrp/common')
| -rw-r--r-- | host/lib/usrp/common/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/lib/usrp/common/fw_comm_protocol.h | 102 | ||||
| -rw-r--r-- | host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp | 245 | ||||
| -rw-r--r-- | host/lib/usrp/common/usrp3_fw_ctrl_iface.hpp | 72 | 
4 files changed, 0 insertions, 420 deletions
diff --git a/host/lib/usrp/common/CMakeLists.txt b/host/lib/usrp/common/CMakeLists.txt index 9f4cf09b5..9480d0284 100644 --- a/host/lib/usrp/common/CMakeLists.txt +++ b/host/lib/usrp/common/CMakeLists.txt @@ -38,5 +38,4 @@ LIBUHD_APPEND_SOURCES(      ${CMAKE_CURRENT_SOURCE_DIR}/validate_subdev_spec.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/recv_packet_demuxer.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/fifo_ctrl_excelsior.cpp -    ${CMAKE_CURRENT_SOURCE_DIR}/usrp3_fw_ctrl_iface.cpp  ) diff --git a/host/lib/usrp/common/fw_comm_protocol.h b/host/lib/usrp/common/fw_comm_protocol.h deleted file mode 100644 index 14adb33a9..000000000 --- a/host/lib/usrp/common/fw_comm_protocol.h +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright 2014 Ettus Research LLC -// -// 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/>. -// - -#ifndef INCLUDED_FW_COMM_PROTOCOL -#define INCLUDED_FW_COMM_PROTOCOL - -#include <stdint.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif - -/*! - * Structs and constants for communication between firmware and host. - * This header is shared by the firmware and host code. - * Therefore, this header may only contain valid C code. - */ -#ifdef __cplusplus -extern "C" { -#endif - -#define FW_COMM_PROTOCOL_SIGNATURE  0xACE3 -#define FW_COMM_PROTOCOL_VERSION    0 -#define FW_COMM_MAX_DATA_WORDS      16 -#define FW_COMM_PROTOCOL_MTU        256 - -#define FW_COMM_FLAGS_ACK           0x00000001 -#define FW_COMM_FLAGS_CMD_MASK      0x00000FF0 -#define FW_COMM_FLAGS_ERROR_MASK    0xFF000000 - -#define FW_COMM_CMD_ECHO            0x00000000 -#define FW_COMM_CMD_POKE32          0x00000010 -#define FW_COMM_CMD_PEEK32          0x00000020 -#define FW_COMM_CMD_BLOCK_POKE32    0x00000030 -#define FW_COMM_CMD_BLOCK_PEEK32    0x00000040 - -#define FW_COMM_ERR_PKT_ERROR       0x80000000 -#define FW_COMM_ERR_CMD_ERROR       0x40000000 -#define FW_COMM_ERR_SIZE_ERROR      0x20000000 - -#define FW_COMM_GENERATE_ID(prod)   ((((uint32_t) FW_COMM_PROTOCOL_SIGNATURE) << 0)  | \ -                                     (((uint32_t) prod)                       << 16) | \ -                                     (((uint32_t) FW_COMM_PROTOCOL_VERSION)   << 24)) - -#define FW_COMM_GET_PROTOCOL_SIG(id) ((uint16_t)(id & 0xFFFF)) -#define FW_COMM_GET_PRODUCT_ID(id)   ((uint8_t)(id >> 16)) -#define FW_COMM_GET_PROTOCOL_VER(id) ((uint8_t)(id >> 24)) - -typedef struct -{ -    uint32_t id;            //Protocol and device identifier -    uint32_t flags;         //Holds commands and ack messages -    uint32_t sequence;      //Sequence number (specific to FW communication transactions) -    uint32_t data_words;    //Number of data words in payload -    uint32_t addr;          //Address field for the command in flags -    uint32_t data[FW_COMM_MAX_DATA_WORDS];  //Data field for the command in flags -} fw_comm_pkt_t; - -#ifdef __cplusplus -} //extern "C" -#endif - -// The following definitions are only useful in firmware. Exclude in host code. -#ifndef __cplusplus - -typedef void (*poke32_func)(const uint32_t addr, const uint32_t data); -typedef uint32_t (*peek32_func)(const uint32_t addr); - -/*! - * Process a firmware communication packet and compute a response. - * Args: - * - (in) request: Pointer to the request struct - * - (out) response: Pointer to the response struct - * - (in) product_id: The 8-bit usrp3 specific product ID (for request filtering) - * - (func) poke_callback, peek_callback: Callback functions for a single peek/poke - * - return value: Send a response packet - */ -bool process_fw_comm_protocol_pkt( -    const fw_comm_pkt_t* request, -    fw_comm_pkt_t* response, -    uint8_t product_id, -    uint32_t iface_id, -    poke32_func poke_callback, -    peek32_func peek_callback -); - -#endif  //ifdef __cplusplus - -#endif /* INCLUDED_FW_COMM_PROTOCOL */ diff --git a/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp b/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp deleted file mode 100644 index 35758d4dd..000000000 --- a/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp +++ /dev/null @@ -1,245 +0,0 @@ -// -// Copyright 2013 Ettus Research LLC -// -// 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/>. -// - -#include "usrp3_fw_ctrl_iface.hpp" - -#include <uhd/utils/byteswap.hpp> -#include <uhd/utils/msg.hpp> -#include <uhd/exception.hpp> -#include <boost/format.hpp> -#include <boost/asio.hpp> //used for htonl and ntohl -#include "fw_comm_protocol.h" - -namespace uhd { namespace usrp { namespace usrp3 { - -//---------------------------------------------------------- -// Factory method -//---------------------------------------------------------- -uhd::wb_iface::sptr usrp3_fw_ctrl_iface::make( -    uhd::transport::udp_simple::sptr udp_xport, -    const uint16_t product_id, -    const bool verbose) -{ -    return wb_iface::sptr(new usrp3_fw_ctrl_iface(udp_xport, product_id, verbose)); -} - -//---------------------------------------------------------- -// udp_fw_ctrl_iface -//---------------------------------------------------------- - -usrp3_fw_ctrl_iface::usrp3_fw_ctrl_iface( -    uhd::transport::udp_simple::sptr udp_xport, -    const uint16_t product_id, -    const bool verbose) : -    _product_id(product_id), _verbose(verbose), _udp_xport(udp_xport), -    _seq_num(0) -{ -    flush(); -    peek32(0); -} - -usrp3_fw_ctrl_iface::~usrp3_fw_ctrl_iface() -{ -    flush(); -} - -void usrp3_fw_ctrl_iface::flush() -{ -    boost::mutex::scoped_lock lock(_mutex); -    _flush(); -} - -void usrp3_fw_ctrl_iface::poke32(const wb_addr_type addr, const uint32_t data) -{ -    boost::mutex::scoped_lock lock(_mutex); - -    for (size_t i = 1; i <= NUM_RETRIES; i++) { -        try { -            _poke32(addr, data); -            return; -        } catch(const std::exception &ex) { -            const std::string error_msg = str(boost::format( -                "udp fw poke32 failure #%u\n%s") % i % ex.what()); -            if (_verbose) UHD_MSG(warning) << error_msg << std::endl; -            if (i == NUM_RETRIES) throw uhd::io_error(error_msg); -        } -    } -} - -uint32_t usrp3_fw_ctrl_iface::peek32(const wb_addr_type addr) -{ -    boost::mutex::scoped_lock lock(_mutex); - -    for (size_t i = 1; i <= NUM_RETRIES; i++) { -        try { -            return _peek32(addr); -        } catch(const std::exception &ex) { -            const std::string error_msg = str(boost::format( -                "udp fw peek32 failure #%u\n%s") % i % ex.what()); -            if (_verbose) UHD_MSG(warning) << error_msg << std::endl; -            if (i == NUM_RETRIES) throw uhd::io_error(error_msg); -        } -    } -    return 0; -} - -void usrp3_fw_ctrl_iface::_poke32(const wb_addr_type addr, const uint32_t data) -{ -    //Load request struct -    fw_comm_pkt_t request; -    request.id = uhd::htonx<uint32_t>(FW_COMM_GENERATE_ID(_product_id)); -    request.flags = uhd::htonx<uint32_t>(FW_COMM_FLAGS_ACK | FW_COMM_CMD_POKE32); -    request.sequence = uhd::htonx<uint32_t>(_seq_num++); -    request.addr = uhd::htonx(addr); -    request.data_words = 1; -    request.data[0] = uhd::htonx(data); - -    //Send request -    _flush(); -    _udp_xport->send(boost::asio::buffer(&request, sizeof(request))); - -    //Recv reply -    fw_comm_pkt_t reply; -    const size_t nbytes = _udp_xport->recv(boost::asio::buffer(&reply, sizeof(reply)), 1.0); -    if (nbytes == 0) throw uhd::io_error("udp fw poke32 - reply timed out"); - -    //Sanity checks -    const size_t flags = uhd::ntohx<uint32_t>(reply.flags); -    UHD_ASSERT_THROW(nbytes == sizeof(reply)); -    UHD_ASSERT_THROW(not (flags & FW_COMM_FLAGS_ERROR_MASK)); -    UHD_ASSERT_THROW(flags & FW_COMM_CMD_POKE32); -    UHD_ASSERT_THROW(flags & FW_COMM_FLAGS_ACK); -    UHD_ASSERT_THROW(reply.sequence == request.sequence); -    UHD_ASSERT_THROW(reply.addr == request.addr); -    UHD_ASSERT_THROW(reply.data[0] == request.data[0]); -} - -uint32_t usrp3_fw_ctrl_iface::_peek32(const wb_addr_type addr) -{ -    //Load request struct -    fw_comm_pkt_t request; -    request.id = uhd::htonx<uint32_t>(FW_COMM_GENERATE_ID(_product_id)); -    request.flags = uhd::htonx<uint32_t>(FW_COMM_FLAGS_ACK | FW_COMM_CMD_PEEK32); -    request.sequence = uhd::htonx<uint32_t>(_seq_num++); -    request.addr = uhd::htonx(addr); -    request.data_words = 1; -    request.data[0] = 0; - -    //Send request -    _flush(); -    _udp_xport->send(boost::asio::buffer(&request, sizeof(request))); - -    //Recv reply -    fw_comm_pkt_t reply; -    const size_t nbytes = _udp_xport->recv(boost::asio::buffer(&reply, sizeof(reply)), 1.0); -    if (nbytes == 0) throw uhd::io_error("udp fw peek32 - reply timed out"); - -    //Sanity checks -    const size_t flags = uhd::ntohx<uint32_t>(reply.flags); -    UHD_ASSERT_THROW(nbytes == sizeof(reply)); -    UHD_ASSERT_THROW(not (flags & FW_COMM_FLAGS_ERROR_MASK)); -    UHD_ASSERT_THROW(flags & FW_COMM_CMD_PEEK32); -    UHD_ASSERT_THROW(flags & FW_COMM_FLAGS_ACK); -    UHD_ASSERT_THROW(reply.sequence == request.sequence); -    UHD_ASSERT_THROW(reply.addr == request.addr); - -    //return result! -    return uhd::ntohx<uint32_t>(reply.data[0]); -} - -void usrp3_fw_ctrl_iface::_flush(void) -{ -    char buff[FW_COMM_PROTOCOL_MTU] = {}; -    while (_udp_xport->recv(boost::asio::buffer(buff), 0.0)) { -        /*NOP*/ -    } -} - -std::vector<std::string> usrp3_fw_ctrl_iface::discover_devices( -    const std::string& addr_hint, const std::string& port, -    uint16_t product_id) -{ -    std::vector<std::string> addrs; - -    //Create a UDP transport to communicate: -    //Some devices will cause a throw when opened for a broadcast address. -    //We print and recover so the caller can loop through all bcast addrs. -    uhd::transport::udp_simple::sptr udp_bcast_xport; -    try { -        udp_bcast_xport = uhd::transport::udp_simple::make_broadcast(addr_hint, port); -    } catch(const std::exception &e) { -        UHD_MSG(error) << boost::format("Cannot open UDP transport on %s for discovery\n%s") -        % addr_hint % e.what() << std::endl; -        return addrs; -    } - -    //Send dummy request -    fw_comm_pkt_t request; -    request.id = uhd::htonx<uint32_t>(FW_COMM_GENERATE_ID(product_id)); -    request.flags = uhd::htonx<uint32_t>(FW_COMM_FLAGS_ACK|FW_COMM_CMD_ECHO); -    request.sequence = uhd::htonx<uint32_t>(std::rand()); -    udp_bcast_xport->send(boost::asio::buffer(&request, sizeof(request))); - -    //loop for replies until timeout -    while (true) { -        char buff[FW_COMM_PROTOCOL_MTU] = {}; -        const size_t nbytes = udp_bcast_xport->recv(boost::asio::buffer(buff), 0.050); -        if (nbytes != sizeof(fw_comm_pkt_t)) break; //No more responses or responses are invalid - -        const fw_comm_pkt_t *reply = (const fw_comm_pkt_t *)buff; -        if (request.id       == reply->id && -            request.flags    == reply->flags && -            request.sequence == reply->sequence) -        { -            addrs.push_back(udp_bcast_xport->get_recv_addr()); -        } -    } - -    return addrs; -} - -uint32_t usrp3_fw_ctrl_iface::get_iface_id( -    const std::string& addr, const std::string& port, -    uint16_t product_id) -{ -    uhd::transport::udp_simple::sptr udp_xport = -        uhd::transport::udp_simple::make_connected(addr, port); - -    //Send dummy request -    fw_comm_pkt_t request; -    request.id = uhd::htonx<uint32_t>(FW_COMM_GENERATE_ID(product_id)); -    request.flags = uhd::htonx<uint32_t>(FW_COMM_FLAGS_ACK|FW_COMM_CMD_ECHO); -    request.sequence = uhd::htonx<uint32_t>(std::rand()); -    udp_xport->send(boost::asio::buffer(&request, sizeof(request))); - -    //loop for replies until timeout -    char buff[FW_COMM_PROTOCOL_MTU] = {}; -    const size_t nbytes = udp_xport->recv(boost::asio::buffer(buff), 1.0); - -    const fw_comm_pkt_t *reply = (const fw_comm_pkt_t *)buff; -    if (nbytes            >  0 && -        request.id        == reply->id && -        request.flags     == reply->flags && -        request.sequence  == reply->sequence) -    { -        return uhd::ntohx<uint32_t>(reply->data[0]); -    } else { -        throw uhd::io_error("udp get_iface_id - bad response"); -    } -} - -}}} //namespace diff --git a/host/lib/usrp/common/usrp3_fw_ctrl_iface.hpp b/host/lib/usrp/common/usrp3_fw_ctrl_iface.hpp deleted file mode 100644 index 9dc35ef9e..000000000 --- a/host/lib/usrp/common/usrp3_fw_ctrl_iface.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright 2014 Ettus Research LLC -// -// 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/>. -// - -#ifndef INCLUDED_LIBUHD_USRP_USRP3_UDP_FW_CTRL_IFACE_HPP -#define INCLUDED_LIBUHD_USRP_USRP3_UDP_FW_CTRL_IFACE_HPP - -#include <uhd/types/wb_iface.hpp> -#include <uhd/transport/udp_simple.hpp> -#include <boost/thread/mutex.hpp> -#include <vector> - -namespace uhd { namespace usrp { namespace usrp3 { - -class usrp3_fw_ctrl_iface : public uhd::wb_iface -{ -public: -    usrp3_fw_ctrl_iface( -        uhd::transport::udp_simple::sptr udp_xport, -        const uint16_t product_id, -        const bool verbose); -    virtual ~usrp3_fw_ctrl_iface(); - -    // -- uhd::wb_iface -- -    void poke32(const wb_addr_type addr, const uint32_t data); -    uint32_t peek32(const wb_addr_type addr); -    void flush(); - -    static uhd::wb_iface::sptr make( -        uhd::transport::udp_simple::sptr udp_xport, -        const uint16_t product_id, -        const bool verbose = true); -    // -- uhd::wb_iface -- - -    static std::vector<std::string> discover_devices( -        const std::string& addr_hint, const std::string& port, -        uint16_t product_id); - -    static uint32_t get_iface_id( -        const std::string& addr, const std::string& port, -        uint16_t product_id); - -private: -    void _poke32(const wb_addr_type addr, const uint32_t data); -    uint32_t _peek32(const wb_addr_type addr); -    void _flush(void); - -    const uint16_t               _product_id; -    const bool                          _verbose; -    uhd::transport::udp_simple::sptr    _udp_xport; -    uint32_t                     _seq_num; -    boost::mutex                        _mutex; - -    static const size_t NUM_RETRIES = 3; -}; - -}}} //namespace - -#endif //INCLUDED_LIBUHD_USRP_USRP3_USRP3_UDP_FW_CTRL_HPP  | 
