diff options
| -rw-r--r-- | host/lib/usrp/b100/b100_ctrl.cpp | 257 | ||||
| -rw-r--r-- | host/lib/usrp/b100/b100_ctrl.hpp | 70 | ||||
| -rw-r--r-- | host/lib/usrp/b100/ctrl_packet.hpp | 75 | 
3 files changed, 0 insertions, 402 deletions
| diff --git a/host/lib/usrp/b100/b100_ctrl.cpp b/host/lib/usrp/b100/b100_ctrl.cpp deleted file mode 100644 index e6136c00e..000000000 --- a/host/lib/usrp/b100/b100_ctrl.cpp +++ /dev/null @@ -1,257 +0,0 @@ -// -// Copyright 2011 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 "b100_ctrl.hpp" -#include <uhd/transport/bounded_buffer.hpp> -#include <uhd/transport/usb_zero_copy.hpp> -#include <uhd/transport/zero_copy.hpp> -#include <uhd/transport/vrt_if_packet.hpp> -#include <uhd/utils/thread_priority.hpp> -#include <uhd/utils/msg.hpp> -#include <uhd/utils/tasks.hpp> -#include <uhd/types/metadata.hpp> -#include <uhd/types/serial.hpp> -#include "ctrl_packet.hpp" -#include <boost/thread/thread.hpp> -#include <boost/bind.hpp> -#include <uhd/exception.hpp> - -using namespace uhd::transport; -using namespace uhd; - -bool b100_ctrl_debug = false; - -class b100_ctrl_impl : public b100_ctrl { -public: -    b100_ctrl_impl(uhd::transport::zero_copy_if::sptr ctrl_transport): -        sync_ctrl_fifo(2), -        _ctrl_transport(ctrl_transport), -        _seq(0) -    { -        viking_marauder = task::make(boost::bind(&b100_ctrl_impl::viking_marauder_loop, this)); -    } - -    ~b100_ctrl_impl(void){ -        //stop the marauder first so it cant access deconstructed objects -        viking_marauder.reset(); -    } - -    int write(boost::uint32_t addr, const ctrl_data_t &data); -    ctrl_data_t read(boost::uint32_t addr, size_t len); - -    bool get_ctrl_data(ctrl_data_t &pkt_data, double timeout); - -    void poke32(wb_addr_type addr, boost::uint32_t data){ -        boost::mutex::scoped_lock lock(_ctrl_mutex); - -        ctrl_data_t words(2); -        words[0] = data & 0x0000FFFF; -        words[1] = data >> 16; -        this->write(addr, words); -    } - -    boost::uint32_t peek32(wb_addr_type addr){ -        boost::mutex::scoped_lock lock(_ctrl_mutex); - -        ctrl_data_t words = this->read(addr, 2); -        return boost::uint32_t((boost::uint32_t(words[1]) << 16) | words[0]); -    } - -    void poke16(wb_addr_type addr, boost::uint16_t data){ -        boost::mutex::scoped_lock lock(_ctrl_mutex); - -        ctrl_data_t words(1); -        words[0] = data; -        this->write(addr, words); -    } - -    boost::uint16_t peek16(wb_addr_type addr){ -        boost::mutex::scoped_lock lock(_ctrl_mutex); - -        ctrl_data_t words = this->read(addr, 1); -        return boost::uint16_t(words[0]); -    } - -    void set_async_cb(const async_cb_type &async_cb){ -        boost::mutex::scoped_lock lock(_async_mutex); -        _async_cb = async_cb; -    } - -private: -    int send_pkt(boost::uint16_t *cmd); - -    //änd hërë wë gö ä-Vïkïng för äsynchronous control packets -    void viking_marauder_loop(void); -    bounded_buffer<ctrl_data_t> sync_ctrl_fifo; -    async_cb_type _async_cb; -    task::sptr viking_marauder; - -    uhd::transport::zero_copy_if::sptr _ctrl_transport; -    boost::uint8_t _seq; -    boost::mutex _ctrl_mutex, _async_mutex; -}; - -/*********************************************************************** - * helper functions for packing/unpacking control packets - **********************************************************************/ -void pack_ctrl_pkt(boost::uint16_t *pkt_buff, -                          const ctrl_pkt_t &pkt){ -    //first two bits are OP -    //next six bits are CALLBACKS -    //next 8 bits are SEQUENCE -    //next 16 bits are LENGTH (16-bit word) -    //next 32 bits are ADDRESS (16-bit word LSW) -    //then DATA (28 16-bit words) -    pkt_buff[0] = (boost::uint16_t(pkt.pkt_meta.op) << 14) | (boost::uint16_t(pkt.pkt_meta.callbacks) << 8) | pkt.pkt_meta.seq; -    pkt_buff[1] = pkt.pkt_meta.len; -    pkt_buff[2] = (pkt.pkt_meta.addr & 0x00000FFF); -    pkt_buff[3] = 0x0000; //address high bits always 0 on this device - -    for(size_t i = 0; i < pkt.data.size(); i++) { -        pkt_buff[4+i] = pkt.data[i]; -    } -} - -void unpack_ctrl_pkt(const boost::uint16_t *pkt_buff, -                            ctrl_pkt_t &pkt){ -    pkt.pkt_meta.seq = pkt_buff[0] & 0xFF; -    pkt.pkt_meta.op = CTRL_PKT_OP_READ; //really this is useless -    pkt.pkt_meta.len = pkt_buff[1]; -    pkt.pkt_meta.callbacks = 0; //callbacks aren't implemented yet -    pkt.pkt_meta.addr = pkt_buff[2] | boost::uint32_t(pkt_buff[3] << 16); - -    //let's check this so we don't go pushing 64K of crap onto the pkt -    if(pkt.pkt_meta.len > CTRL_PACKET_DATA_LENGTH) { -        throw uhd::runtime_error("Received control packet too long"); -    } - -    for(int i = 4; i < 4+pkt.pkt_meta.len; i++) pkt.data.push_back(pkt_buff[i]); -} - -int b100_ctrl_impl::send_pkt(boost::uint16_t *cmd) { -    managed_send_buffer::sptr sbuf = _ctrl_transport->get_send_buff(); -    if(!sbuf.get()) { -        throw uhd::runtime_error("Control channel send error"); -    } - -    //FIXME there's a better way to do this -    for(size_t i = 0; i < (CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)); i++) { -        sbuf->cast<boost::uint16_t *>()[i] = cmd[i]; -    } -    sbuf->commit(CTRL_PACKET_LENGTH); //fixed size transaction -    return 0; -} - -int b100_ctrl_impl::write(boost::uint32_t addr, const ctrl_data_t &data) { -    UHD_ASSERT_THROW(data.size() <= (CTRL_PACKET_DATA_LENGTH / sizeof(boost::uint16_t))); -    ctrl_pkt_t pkt; -    pkt.data = data; -    pkt.pkt_meta.op = CTRL_PKT_OP_WRITE; -    pkt.pkt_meta.callbacks = 0; -    pkt.pkt_meta.seq = _seq++; -    pkt.pkt_meta.len = pkt.data.size(); -    pkt.pkt_meta.addr = addr; -    boost::uint16_t pkt_buff[CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)] = {}; - -    pack_ctrl_pkt(pkt_buff, pkt); -    size_t result = send_pkt(pkt_buff); -    return result; -} - -ctrl_data_t b100_ctrl_impl::read(boost::uint32_t addr, size_t len) { -    UHD_ASSERT_THROW(len <= (CTRL_PACKET_DATA_LENGTH / sizeof(boost::uint16_t))); - -    ctrl_pkt_t pkt; -    pkt.pkt_meta.op = CTRL_PKT_OP_READ; -    pkt.pkt_meta.callbacks = 0; -    pkt.pkt_meta.seq = _seq++; -    pkt.pkt_meta.len = len; -    pkt.pkt_meta.addr = addr; -    boost::uint16_t pkt_buff[CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)] = {}; - -    //flush anything that might be in the queue -    while (get_ctrl_data(pkt.data, 0.0)){ -        UHD_MSG(error) << "B100: control read found unexpected packet." << std::endl; -    } - -    pack_ctrl_pkt(pkt_buff, pkt); -    send_pkt(pkt_buff); - -    //block with timeout waiting for the response to appear -    if (not get_ctrl_data(pkt.data, 0.1)) throw uhd::runtime_error( -        "B100: timeout waiting for control response packet." -    ); - -    return pkt.data; -} - -/*********************************************************************** - * Viking marauders go pillaging for asynchronous control packets in the - * control response endpoint. Sync packets go in sync_ctrl_fifo, - * async TX error messages go in async_msg_fifo. sync_ctrl_fifo should - * never have more than 1 message in it, since it's expected that we'll - * wait for a control operation to finish before starting another one. - **********************************************************************/ -void b100_ctrl_impl::viking_marauder_loop(void){ -    set_thread_priority_safe(); - -    while (not boost::this_thread::interruption_requested()){ -        managed_recv_buffer::sptr rbuf = _ctrl_transport->get_recv_buff(1.0); -        if(rbuf.get() == NULL) continue; //that's ok, there are plenty of villages to pillage! -        const boost::uint16_t *pkt_buf = rbuf->cast<const boost::uint16_t *>(); - -        if(pkt_buf[0] >> 8 == CTRL_PACKET_HEADER_MAGIC) { -            //so it's got a control packet header, let's parse it. -            ctrl_pkt_t pkt; -            unpack_ctrl_pkt(pkt_buf, pkt); - -            if(pkt.pkt_meta.seq != boost::uint8_t(_seq - 1)) { -                UHD_MSG(error) -                    << "Sequence error on control channel." << std::endl -                    << "Exiting control loop." << std::endl -                ; -                return; -            } -            if(pkt.pkt_meta.len > (CTRL_PACKET_LENGTH - CTRL_PACKET_HEADER_LENGTH)) { -                UHD_MSG(error) -                    << "Control channel packet length too long" << std::endl -                    << "Exiting control loop." << std::endl -                ; -                return; -            } - -            //push it onto the queue -            sync_ctrl_fifo.push_with_pop_on_full(pkt.data); -        } -        else{ //otherwise let the async callback handle it -            boost::mutex::scoped_lock lock(_async_mutex); -            if (not _async_cb.empty()) _async_cb(rbuf); -        } -    } -} - -bool b100_ctrl_impl::get_ctrl_data(ctrl_data_t &pkt_data, double timeout){ -    boost::this_thread::disable_interruption di; //disable because the wait can throw -    return sync_ctrl_fifo.pop_with_timed_wait(pkt_data, timeout); -} - -/*********************************************************************** - * Public make function for b100_ctrl interface - **********************************************************************/ -b100_ctrl::sptr b100_ctrl::make(uhd::transport::zero_copy_if::sptr ctrl_transport){ -    return sptr(new b100_ctrl_impl(ctrl_transport)); -} diff --git a/host/lib/usrp/b100/b100_ctrl.hpp b/host/lib/usrp/b100/b100_ctrl.hpp deleted file mode 100644 index 74884d525..000000000 --- a/host/lib/usrp/b100/b100_ctrl.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// Copyright 2011 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_B100_CTRL_HPP -#define INCLUDED_B100_CTRL_HPP - -#include "wb_iface.hpp" -#include <uhd/transport/usb_zero_copy.hpp> -#include <uhd/types/serial.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/utility.hpp> -#include "ctrl_packet.hpp" -#include <boost/function.hpp> - -class b100_ctrl : boost::noncopyable, public wb_iface{ -public: -    typedef boost::shared_ptr<b100_ctrl> sptr; -    typedef boost::function<void(uhd::transport::managed_recv_buffer::sptr)> async_cb_type; - -    /*! -     * Make a USRP control object from a data transport -     * \param ctrl_transport a USB data transport -     * \return a new b100 control object -     */ -    static sptr make(uhd::transport::zero_copy_if::sptr ctrl_transport); - -    //! set an async callback for messages -    virtual void set_async_cb(const async_cb_type &async_cb) = 0; - -    /*! -     * Write a byte vector to an FPGA register -     * \param addr the FPGA register address -     * \param bytes the data to write -     * \return 0 on success, error code on failure -     */ -    virtual int write(boost::uint32_t addr, const ctrl_data_t &data) = 0; - -    /*! -     * Read a byte vector from an FPGA register (blocking read) -     * \param addr the FPGA register address -     * \param len the length of the read -     * \return a vector of bytes from the register(s) in question -     */ -    virtual ctrl_data_t read(boost::uint32_t addr, size_t len) = 0; - -    /*! -     * Get a sync ctrl packet (blocking) -     * \param the packet data buffer -     * \param the timeout value -     * \return true if it got something -     */ -    virtual bool get_ctrl_data(ctrl_data_t &pkt_data, double timeout) = 0; - -}; - -#endif /* INCLUDED_B100_CTRL_HPP */ diff --git a/host/lib/usrp/b100/ctrl_packet.hpp b/host/lib/usrp/b100/ctrl_packet.hpp deleted file mode 100644 index bab1f0de1..000000000 --- a/host/lib/usrp/b100/ctrl_packet.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright 2011 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_CTRL_PACKET_HPP -#define INCLUDED_CTRL_PACKET_HPP - -#include <uhd/config.hpp> -#include <boost/cstdint.hpp> -#include <uhd/types/serial.hpp> - -typedef std::vector<boost::uint16_t> ctrl_data_t; - -/*! - * Control packet operation type - */ -enum ctrl_pkt_op_t {  -    CTRL_PKT_OP_WRITE = 1, -    CTRL_PKT_OP_READ = 2, -    CTRL_PKT_OP_READBACK = 3 -}; - -/*! - * Control packet transaction length - */ -const size_t CTRL_PACKET_LENGTH = 32; -const size_t CTRL_PACKET_HEADER_LENGTH = 8; -const size_t CTRL_PACKET_DATA_LENGTH = 24; //=length-header - -/*! - * Control packet header magic value - */ -const boost::uint8_t CTRL_PACKET_HEADER_MAGIC = 0xAA; - -/*!  - * Callback triggers for readback operation - */ -//FIXME: these are not real numbers, callbacks aren't implemented yet -const boost::uint16_t CTRL_PACKET_CALLBACK_SPI = 0x0001; -const boost::uint16_t CTRL_PACKET_CALLBACK_I2C = 0x0002; -//and so on - -/*! - * Metadata structure to describe a control packet - */ -struct UHD_API ctrl_pkt_meta_t { -    ctrl_pkt_op_t op; -    boost::uint8_t callbacks; -    boost::uint8_t seq; -    boost::uint16_t len; -    boost::uint32_t addr; -}; - -/*!  - * Full control packet structure - */ -struct UHD_API ctrl_pkt_t { -    ctrl_pkt_meta_t pkt_meta; -    ctrl_data_t data; -}; - -#endif /* INCLUDED_CTRL_PACKET_HPP */ | 
