diff options
Diffstat (limited to 'host/lib/usrp/cores')
-rw-r--r-- | host/lib/usrp/cores/gpio_atr_3000.cpp | 88 | ||||
-rw-r--r-- | host/lib/usrp/cores/gpio_atr_3000.hpp | 18 | ||||
-rw-r--r-- | host/lib/usrp/cores/gpio_core_200.cpp | 46 | ||||
-rw-r--r-- | host/lib/usrp/cores/gpio_core_200.hpp | 24 |
4 files changed, 135 insertions, 41 deletions
diff --git a/host/lib/usrp/cores/gpio_atr_3000.cpp b/host/lib/usrp/cores/gpio_atr_3000.cpp index 3e0aa1f03..5844af601 100644 --- a/host/lib/usrp/cores/gpio_atr_3000.cpp +++ b/host/lib/usrp/cores/gpio_atr_3000.cpp @@ -164,7 +164,7 @@ public: } } -private: +protected: //Special RB addr value to indicate no readback //This value is invalid as a real address because it is not a multiple of 4 static const wb_iface::wb_addr_type READBACK_DISABLED = 0xFFFFFFFF; @@ -172,11 +172,16 @@ private: class masked_reg_t : public uhd::soft_reg32_wo_t { public: masked_reg_t(const wb_iface::wb_addr_type offset): uhd::soft_reg32_wo_t(offset) { - set(REGISTER, 0); + uhd::soft_reg32_wo_t::set(REGISTER, 0); } virtual void set_with_mask(const boost::uint32_t value, const boost::uint32_t mask) { - set(REGISTER, (value&mask)|(get(REGISTER)&(~mask))); + uhd::soft_reg32_wo_t::set(REGISTER, + (value&mask)|(uhd::soft_reg32_wo_t::get(REGISTER)&(~mask))); + } + + virtual boost::uint32_t get() { + return uhd::soft_reg32_wo_t::get(uhd::soft_reg32_wo_t::REGISTER); } virtual void flush() { @@ -196,14 +201,22 @@ private: _atr_idle_cache = (value&mask)|(_atr_idle_cache&(~mask)); } + virtual boost::uint32_t get() { + return _atr_idle_cache; + } + void set_gpio_out_with_mask(const boost::uint32_t value, const boost::uint32_t mask) { _gpio_out_cache = (value&mask)|(_gpio_out_cache&(~mask)); } + virtual boost::uint32_t get_gpio_out() { + return _gpio_out_cache; + } + virtual void flush() { set(REGISTER, - (_atr_idle_cache & (~_atr_disable_reg.get(REGISTER))) | - (_gpio_out_cache & _atr_disable_reg.get(REGISTER)) + (_atr_idle_cache & (~_atr_disable_reg.get())) | + (_gpio_out_cache & _atr_disable_reg.get()) ); masked_reg_t::flush(); } @@ -247,44 +260,75 @@ public: db_gpio_atr_3000_impl(wb_iface::sptr iface, const wb_iface::wb_addr_type base, const wb_iface::wb_addr_type rb_addr): gpio_atr_3000_impl(iface, base, rb_addr) { /* NOP */ } - inline void set_pin_ctrl(const db_unit_t unit, const boost::uint16_t value) + inline void set_pin_ctrl(const db_unit_t unit, const boost::uint32_t value, const boost::uint32_t mask) { - gpio_atr_3000_impl::set_atr_mode(MODE_ATR, compute_mask(unit, value)); - gpio_atr_3000_impl::set_atr_mode(MODE_GPIO, compute_mask(unit, ~value)); + gpio_atr_3000_impl::set_atr_mode(MODE_ATR, compute_mask(unit, value&mask)); + gpio_atr_3000_impl::set_atr_mode(MODE_GPIO, compute_mask(unit, (~value)&mask)); } - inline void set_gpio_ddr(const db_unit_t unit, const boost::uint16_t value) + inline boost::uint32_t get_pin_ctrl(const db_unit_t unit) { - gpio_atr_3000_impl::set_gpio_ddr(DDR_OUTPUT, compute_mask(unit, value)); - gpio_atr_3000_impl::set_gpio_ddr(DDR_INPUT, compute_mask(unit, ~value)); + return (~_atr_disable_reg.get()) >> compute_shift(unit); } - inline void set_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr, const boost::uint16_t value) + inline void set_gpio_ddr(const db_unit_t unit, const boost::uint32_t value, const boost::uint32_t mask) { - gpio_atr_3000_impl::set_atr_reg(atr, - static_cast<boost::uint32_t>(value) << compute_shift(unit), - compute_mask(unit, 0xFFFF)); + gpio_atr_3000_impl::set_gpio_ddr(DDR_OUTPUT, compute_mask(unit, value&mask)); + gpio_atr_3000_impl::set_gpio_ddr(DDR_INPUT, compute_mask(unit, (~value)&mask)); } - inline void set_gpio_out(const db_unit_t unit, const boost::uint16_t value) + inline boost::uint32_t get_gpio_ddr(const db_unit_t unit) + { + return _ddr_reg.get() >> compute_shift(unit); + } + + inline void set_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr, const boost::uint32_t value, const boost::uint32_t mask) + { + gpio_atr_3000_impl::set_atr_reg(atr, value << compute_shift(unit), compute_mask(unit, mask)); + } + + inline boost::uint32_t get_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr) + { + masked_reg_t* reg = NULL; + switch (atr) { + case ATR_REG_IDLE: reg = &_atr_idle_reg; break; + case ATR_REG_RX_ONLY: reg = &_atr_rx_reg; break; + case ATR_REG_TX_ONLY: reg = &_atr_tx_reg; break; + case ATR_REG_FULL_DUPLEX: reg = &_atr_fdx_reg; break; + default: reg = &_atr_idle_reg; break; + } + return (reg->get() & compute_mask(unit, MASK_SET_ALL)) >> compute_shift(unit); + } + + inline void set_gpio_out(const db_unit_t unit, const boost::uint32_t value, const boost::uint32_t mask) { gpio_atr_3000_impl::set_gpio_out( static_cast<boost::uint32_t>(value) << compute_shift(unit), - compute_mask(unit, 0xFFFF)); + compute_mask(unit, mask)); } - inline boost::uint16_t read_gpio(const db_unit_t unit) + inline boost::uint32_t get_gpio_out(const db_unit_t unit) { - return boost::uint16_t(gpio_atr_3000_impl::read_gpio() >> compute_shift(unit)); + return (_atr_idle_reg.get_gpio_out() & compute_mask(unit, MASK_SET_ALL)) >> compute_shift(unit); + } + + inline boost::uint32_t read_gpio(const db_unit_t unit) + { + return (gpio_atr_3000_impl::read_gpio() & compute_mask(unit, MASK_SET_ALL)) >> compute_shift(unit); } private: inline boost::uint32_t compute_shift(const db_unit_t unit) { - return (unit == dboard_iface::UNIT_RX) ? 0 : 16; + switch (unit) { + case dboard_iface::UNIT_RX: return 0; + case dboard_iface::UNIT_TX: return 16; + default: return 0; + } } - inline boost::uint32_t compute_mask(const db_unit_t unit, const boost::uint16_t mask) { - return static_cast<boost::uint32_t>(mask) << (compute_shift(unit)); + inline boost::uint32_t compute_mask(const db_unit_t unit, const boost::uint32_t mask) { + boost::uint32_t tmp_mask = (unit == dboard_iface::UNIT_BOTH) ? mask : (mask & 0xFFFF); + return tmp_mask << (compute_shift(unit)); } }; diff --git a/host/lib/usrp/cores/gpio_atr_3000.hpp b/host/lib/usrp/cores/gpio_atr_3000.hpp index b30cd3b85..7b90429fe 100644 --- a/host/lib/usrp/cores/gpio_atr_3000.hpp +++ b/host/lib/usrp/cores/gpio_atr_3000.hpp @@ -132,7 +132,9 @@ public: * \param unit the side of the daughterboard interface to configure (TX or RX) * \param value if value[i] is 1, the i'th bit is in ATR mode otherwise it is in GPIO mode */ - virtual void set_pin_ctrl(const db_unit_t unit, const boost::uint16_t value) = 0; + virtual void set_pin_ctrl(const db_unit_t unit, const boost::uint32_t value, const boost::uint32_t mask) = 0; + + virtual boost::uint32_t get_pin_ctrl(const db_unit_t unit) = 0; /*! * Configure the direction for all pins in the daughterboard connector @@ -140,7 +142,9 @@ public: * \param unit the side of the daughterboard interface to configure (TX or RX) * \param value if value[i] is 1, the i'th bit is an output otherwise it is an input */ - virtual void set_gpio_ddr(const db_unit_t unit, const boost::uint16_t value) = 0; + virtual void set_gpio_ddr(const db_unit_t unit, const boost::uint32_t value, const boost::uint32_t mask) = 0; + + virtual boost::uint32_t get_gpio_ddr(const db_unit_t unit) = 0; /*! * Write the specified value to the ATR register (all bits) @@ -149,7 +153,9 @@ public: * \param unit the side of the daughterboard interface to configure (TX or RX) * \param value the value to write */ - virtual void set_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr, const boost::uint16_t value) = 0; + virtual void set_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr, const boost::uint32_t value, const boost::uint32_t mask) = 0; + + virtual boost::uint32_t get_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr) = 0; /*! * Write the specified value to the GPIO register (all bits) @@ -157,7 +163,9 @@ public: * \param atr the type of ATR register to write to {IDLE, RX, TX, FDX} * \param value the value to write */ - virtual void set_gpio_out(const db_unit_t unit, const boost::uint16_t value) = 0; + virtual void set_gpio_out(const db_unit_t unit, const boost::uint32_t value, const boost::uint32_t mask) = 0; + + virtual boost::uint32_t get_gpio_out(const db_unit_t unit) = 0; /*! * Read the state of the GPIO pins @@ -167,7 +175,7 @@ public: * \param unit the side of the daughterboard interface to configure (TX or RX) * \return the value read back */ - virtual boost::uint16_t read_gpio(const db_unit_t unit) = 0; + virtual boost::uint32_t read_gpio(const db_unit_t unit) = 0; }; }}} //namespaces diff --git a/host/lib/usrp/cores/gpio_core_200.cpp b/host/lib/usrp/cores/gpio_core_200.cpp index 05a689845..8e00a881f 100644 --- a/host/lib/usrp/cores/gpio_core_200.cpp +++ b/host/lib/usrp/cores/gpio_core_200.cpp @@ -27,6 +27,11 @@ using namespace uhd; using namespace usrp; +template <typename T> +static void shadow_it(T &shadow, const T &value, const T &mask){ + shadow = (shadow & ~mask) | (value & mask); +} + gpio_core_200::~gpio_core_200(void){ /* NOP */ } @@ -36,30 +41,55 @@ public: gpio_core_200_impl(wb_iface::sptr iface, const size_t base, const size_t rb_addr): _iface(iface), _base(base), _rb_addr(rb_addr) { /* NOP */ } - void set_pin_ctrl(const unit_t unit, const boost::uint16_t value){ - _pin_ctrl[unit] = value; //shadow + void set_pin_ctrl(const unit_t unit, const boost::uint16_t value, const boost::uint16_t mask){ + if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + shadow_it(_pin_ctrl[unit], value, mask); this->update(); //full update } - void set_atr_reg(const unit_t unit, const atr_reg_t atr, const boost::uint16_t value){ - _atr_regs[unit][atr] = value; //shadow + boost::uint16_t get_pin_ctrl(unit_t unit){ + if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + return _pin_ctrl[unit]; + } + + void set_atr_reg(const unit_t unit, const atr_reg_t atr, const boost::uint16_t value, const boost::uint16_t mask){ + if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + shadow_it(_atr_regs[unit][atr], value, mask); this->update(); //full update } - void set_gpio_ddr(const unit_t unit, const boost::uint16_t value){ - _gpio_ddr[unit] = value; //shadow + boost::uint16_t get_atr_reg(unit_t unit, atr_reg_t reg){ + if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + return _atr_regs[unit][reg]; + } + + void set_gpio_ddr(const unit_t unit, const boost::uint16_t value, const boost::uint16_t mask){ + if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + shadow_it(_gpio_ddr[unit], value, mask); _iface->poke32(REG_GPIO_DDR, //update the 32 bit register (boost::uint32_t(_gpio_ddr[dboard_iface::UNIT_RX]) << shift_by_unit(dboard_iface::UNIT_RX)) | (boost::uint32_t(_gpio_ddr[dboard_iface::UNIT_TX]) << shift_by_unit(dboard_iface::UNIT_TX)) ); } - void set_gpio_out(const unit_t unit, const boost::uint16_t value){ - _gpio_out[unit] = value; //shadow + boost::uint16_t get_gpio_ddr(unit_t unit){ + if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + return _gpio_ddr[unit]; + } + + void set_gpio_out(const unit_t unit, const boost::uint16_t value, const boost::uint16_t mask){ + if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + shadow_it(_gpio_out[unit], value, mask); this->update(); //full update } + boost::uint16_t get_gpio_out(unit_t unit){ + if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); + return _gpio_out[unit]; + } + boost::uint16_t read_gpio(const unit_t unit){ + if (unit == dboard_iface::UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported in gpio_core_200"); return boost::uint16_t(_iface->peek32(_rb_addr) >> shift_by_unit(unit)); } diff --git a/host/lib/usrp/cores/gpio_core_200.hpp b/host/lib/usrp/cores/gpio_core_200.hpp index c60507792..67aa8bde8 100644 --- a/host/lib/usrp/cores/gpio_core_200.hpp +++ b/host/lib/usrp/cores/gpio_core_200.hpp @@ -38,20 +38,32 @@ public: virtual ~gpio_core_200(void) = 0; //! makes a new GPIO core from iface and slave base - static sptr make(uhd::wb_iface::sptr iface, const size_t base, const size_t rb_addr); + static sptr make( + uhd::wb_iface::sptr iface, const size_t base, const size_t rb_addr); //! 1 = ATR - virtual void set_pin_ctrl(const unit_t unit, const boost::uint16_t value) = 0; + virtual void set_pin_ctrl( + const unit_t unit, const boost::uint16_t value, const boost::uint16_t mask) = 0; - virtual void set_atr_reg(const unit_t unit, const atr_reg_t atr, const boost::uint16_t value) = 0; + virtual boost::uint16_t get_pin_ctrl(unit_t unit) = 0; + + virtual void set_atr_reg( + const unit_t unit, const atr_reg_t atr, const boost::uint16_t value, const boost::uint16_t mask) = 0; + + virtual boost::uint16_t get_atr_reg(unit_t unit, atr_reg_t reg) = 0; //! 1 = OUTPUT - virtual void set_gpio_ddr(const unit_t unit, const boost::uint16_t value) = 0; + virtual void set_gpio_ddr( + const unit_t unit, const boost::uint16_t value, const boost::uint16_t mask) = 0; - virtual void set_gpio_out(const unit_t unit, const boost::uint16_t value) = 0; + virtual boost::uint16_t get_gpio_ddr(unit_t unit) = 0; - virtual boost::uint16_t read_gpio(const unit_t unit) = 0; + virtual void set_gpio_out( + const unit_t unit, const boost::uint16_t value, const boost::uint16_t mask) = 0; + virtual boost::uint16_t get_gpio_out(unit_t unit) = 0; + + virtual boost::uint16_t read_gpio(const unit_t unit) = 0; }; //! Simple wrapper for 32 bit write only |