diff options
| -rw-r--r-- | host/lib/usrp/cores/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/lib/usrp/cores/i2c_core_100.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/cores/time64_core_200.cpp | 131 | ||||
| -rw-r--r-- | host/lib/usrp/cores/time64_core_200.hpp | 61 | 
4 files changed, 194 insertions, 1 deletions
diff --git a/host/lib/usrp/cores/CMakeLists.txt b/host/lib/usrp/cores/CMakeLists.txt index 588726ad5..5b2997131 100644 --- a/host/lib/usrp/cores/CMakeLists.txt +++ b/host/lib/usrp/cores/CMakeLists.txt @@ -24,4 +24,5 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})  LIBUHD_APPEND_SOURCES(      ${CMAKE_CURRENT_SOURCE_DIR}/i2c_core_100.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/spi_core_100.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/time64_core_200.cpp  ) diff --git a/host/lib/usrp/cores/i2c_core_100.hpp b/host/lib/usrp/cores/i2c_core_100.hpp index f14d14f2a..4eb1b8086 100644 --- a/host/lib/usrp/cores/i2c_core_100.hpp +++ b/host/lib/usrp/cores/i2c_core_100.hpp @@ -28,7 +28,7 @@ class i2c_core_100 : boost::noncopyable, public uhd::i2c_iface{  public:      typedef boost::shared_ptr<i2c_core_100> sptr; -    //! makes a new spi core from iface and slave base +    //! makes a new i2c core from iface and slave base      sptr make(wb_iface::sptr iface, const size_t base);  }; diff --git a/host/lib/usrp/cores/time64_core_200.cpp b/host/lib/usrp/cores/time64_core_200.cpp new file mode 100644 index 000000000..ec8c390d0 --- /dev/null +++ b/host/lib/usrp/cores/time64_core_200.cpp @@ -0,0 +1,131 @@ +// +// 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 "time64_core_200.hpp" +#include <uhd/exception.hpp> +#include <uhd/utils/assert_has.hpp> + +#define REG_TIME64_SECS        _base + 0 +#define REG_TIME64_TICKS       _base + 2 +#define REG_TIME64_FLAGS       _base + 3 +#define REG_TIME64_IMM         _base + 4 +#define REG_TIME64_TPS         _base + 5 +#define REG_TIME64_MIMO_SYNC   _base + 6 //lower byte is delay cycles + +//pps flags (see above) +#define FLAG_TIME64_PPS_NEGEDGE (0 << 0) +#define FLAG_TIME64_PPS_POSEDGE (1 << 0) +#define FLAG_TIME64_PPS_SMA     (0 << 1) +#define FLAG_TIME64_PPS_MIMO    (1 << 1) //apparently not used + +#define FLAG_TIME64_LATCH_NOW 1 +#define FLAG_TIME64_LATCH_NEXT_PPS 0 + +#define FLAG_TIME64_MIMO_SYNC (1 << 8) + +using namespace uhd; + +class time64_core_200_impl : public time64_core_200{ +public: +    time64_core_200_impl( +        wb_iface::sptr iface, const size_t base, +        const readback_bases_type &readback_bases, +        const size_t mimo_delay_cycles +    ): +        _iface(iface), _base(base), +        _readback_bases(readback_bases), +        _mimo_delay_cycles(mimo_delay_cycles) +    { +        _sources.push_back("none"); +        _sources.push_back("sma"); +        _sources.push_back("sma neg edge"); +        if (_mimo_delay_cycles != 0) _sources.push_back("mimo"); +    } + +    void set_tick_rate(const double rate){ +        _tick_rate = rate; +        _iface->poke32(REG_TIME64_TPS, rate); +    } + +    uhd::time_spec_t get_time_now(void){ +        for (size_t i = 0; i < 3; i++){ //special algorithm because we cant rest 64 bits synchronously +            const boost::uint32_t secs = _iface->peek32(_readback_bases.rb_secs_imm); +            const boost::uint32_t ticks = _iface->peek32(_readback_bases.rb_ticks_imm); +            if (secs != _iface->peek32(_readback_bases.rb_secs_imm)) continue; +            return time_spec_t(secs, ticks, _tick_rate); +        } +        throw uhd::runtime_error("time64_core_200: get time now timeout"); +    } + +    uhd::time_spec_t get_time_last_pps(void){ +        for (size_t i = 0; i < 3; i++){ //special algorithm because we cant rest 64 bits synchronously +            const boost::uint32_t secs = _iface->peek32(_readback_bases.rb_secs_pps); +            const boost::uint32_t ticks = _iface->peek32(_readback_bases.rb_ticks_pps); +            if (secs != _iface->peek32(_readback_bases.rb_secs_pps)) continue; +            return time_spec_t(secs, ticks, _tick_rate); +        } +        throw uhd::runtime_error("time64_core_200: get time last pps timeout"); +    } + +    void set_time_now(const uhd::time_spec_t &time){ +        _iface->poke32(REG_TIME64_TICKS, time.get_tick_count(_tick_rate)); +        _iface->poke32(REG_TIME64_IMM, FLAG_TIME64_LATCH_NOW); +        _iface->poke32(REG_TIME64_SECS, boost::uint32_t(time.get_full_secs())); //latches all 3 +    } + +    void set_time_next_pps(const uhd::time_spec_t &time){ +        _iface->poke32(REG_TIME64_TICKS, time.get_tick_count(_tick_rate)); +        _iface->poke32(REG_TIME64_IMM, FLAG_TIME64_LATCH_NEXT_PPS); +        _iface->poke32(REG_TIME64_SECS, boost::uint32_t(time.get_full_secs())); //latches all 3 +    } + +    void set_time_source(const std::string &source){ +        assert_has(_sources, source, "time source"); + +        //setup pps flags +        if (source == "sma"){ +            _iface->poke32(REG_TIME64_FLAGS, FLAG_TIME64_PPS_SMA | FLAG_TIME64_PPS_POSEDGE); +        } +        else if (source == "sma neg edge"){ +            _iface->poke32(REG_TIME64_FLAGS, FLAG_TIME64_PPS_SMA | FLAG_TIME64_PPS_NEGEDGE); +        } + +        //setup mimo flags +        if (source == "mimo"){ +            _iface->poke32(REG_TIME64_MIMO_SYNC, FLAG_TIME64_MIMO_SYNC | (_mimo_delay_cycles & 0xff)); +        } +        else{ +            _iface->poke32(REG_TIME64_MIMO_SYNC, 0); +        } +    } + +    std::vector<std::string> get_time_sources(void){ +        return _sources; +    } + +private: +    wb_iface::sptr _iface; +    const size_t _base; +    const readback_bases_type _readback_bases; +    double _tick_rate; +    const size_t _mimo_delay_cycles; +    std::vector<std::string> _sources; +}; + +time64_core_200::sptr time64_core_200::make(wb_iface::sptr iface, const size_t base, const readback_bases_type &readback_bases, const size_t mimo_delay_cycles){ +    return sptr(new time64_core_200_impl(iface, base, readback_bases, mimo_delay_cycles)); +} diff --git a/host/lib/usrp/cores/time64_core_200.hpp b/host/lib/usrp/cores/time64_core_200.hpp new file mode 100644 index 000000000..c6a4cf7e5 --- /dev/null +++ b/host/lib/usrp/cores/time64_core_200.hpp @@ -0,0 +1,61 @@ +// +// 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_LIBUHD_USRP_TIME64_CORE_200_HPP +#define INCLUDED_LIBUHD_USRP_TIME64_CORE_200_HPP + +#include <uhd/config.hpp> +#include <uhd/types/time_spec.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> +#include "wb_iface.hpp" +#include <string> +#include <vector> + +class time64_core_200 : boost::noncopyable{ +public: +    typedef boost::shared_ptr<time64_core_200> sptr; + +    struct readback_bases_type{ +        size_t rb_secs_imm, rb_ticks_imm; +        size_t rb_secs_pps, rb_ticks_pps; +    }; + +    //! makes a new time64 core from iface and slave base +    sptr make( +        wb_iface::sptr iface, const size_t base, +        const readback_bases_type &readback_bases, +        const size_t mimo_delay_cycles = 0 // 0 means no-mimo +    ); + +    virtual void set_tick_rate(const double rate) = 0; + +    virtual uhd::time_spec_t get_time_now(void) = 0; + +    virtual uhd::time_spec_t get_time_last_pps(void) = 0; + +    virtual void set_time_now(const uhd::time_spec_t &time) = 0; + +    virtual void set_time_next_pps(const uhd::time_spec_t &time) = 0; + +    virtual void set_time_source(const std::string &source) = 0; + +    virtual std::vector<std::string> get_time_sources(void) = 0; + +}; + +#endif /* INCLUDED_LIBUHD_USRP_TIME64_CORE_200_HPP */  | 
