aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorAshish Chaudhari <ashish@ettus.com>2015-10-10 14:30:27 -0700
committerAshish Chaudhari <ashish@ettus.com>2015-10-10 14:30:27 -0700
commitea982f5f0d4b138f230638624c5e17fa3902706d (patch)
tree596d0c1f42138e3269787ad4f6eeeb92148ea82a /host/lib
parent3fe7539f8b24f4474ed9c303ca089eed0170b44e (diff)
downloaduhd-ea982f5f0d4b138f230638624c5e17fa3902706d.tar.gz
uhd-ea982f5f0d4b138f230638624c5e17fa3902706d.tar.bz2
uhd-ea982f5f0d4b138f230638624c5e17fa3902706d.zip
usrp3: Fixed issue where ATR Idle could clobber GPIO out
- gpio_atr_3000 will not blindly use the mask when writing the ATR and GPIO OUT values. The mask will be ANDed with the value in the ATR Disable register
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/usrp/cores/gpio_atr_3000.cpp27
-rw-r--r--host/lib/usrp/cores/gpio_atr_3000.hpp4
2 files changed, 21 insertions, 10 deletions
diff --git a/host/lib/usrp/cores/gpio_atr_3000.cpp b/host/lib/usrp/cores/gpio_atr_3000.cpp
index d5f73988d..7f48abc69 100644
--- a/host/lib/usrp/cores/gpio_atr_3000.cpp
+++ b/host/lib/usrp/cores/gpio_atr_3000.cpp
@@ -82,7 +82,7 @@ public:
_ddr_reg.flush();
}
- virtual void set_atr_reg(const gpio_atr_reg_t atr, const boost::uint32_t value, const boost::uint32_t mask)
+ virtual void set_atr_reg(const gpio_atr_reg_t atr, const boost::uint32_t value, const boost::uint32_t mask = MASK_SET_ALL)
{
//Set the value of the specified ATR register. For bits with ATR Disable set to 1,
//the IDLE register will hold the output state
@@ -96,10 +96,23 @@ public:
case ATR_REG_FULL_DUPLEX: reg = &_atr_fdx_reg; break;
default: reg = &_atr_idle_reg; break;
}
- reg->set_with_mask(value, mask);
+ //For protection we only write to bits that have the mode ATR by masking the user
+ //specified "mask" with ~atr_disable.
+ reg->set_with_mask(value, mask & (~_atr_disable_reg.get(masked_reg_t::REGISTER)));
reg->flush();
}
+ virtual void set_gpio_out(const boost::uint32_t value, const boost::uint32_t mask = MASK_SET_ALL) {
+ //Set the value of the specified GPIO output register.
+ //This setting will only get applied to all bits in the "mask" that are 1. All other
+ //bits will retain their old value.
+
+ //For protection we only write to bits that have the mode GPIO by masking the user
+ //specified "mask" with atr_disable.
+ _atr_idle_reg.set_with_mask(value, mask & _atr_disable_reg.get(masked_reg_t::REGISTER));
+ _atr_idle_reg.flush();
+ }
+
virtual boost::uint32_t read_gpio()
{
//Read the state of the GPIO pins
@@ -128,23 +141,23 @@ public:
break;
case GPIO_OUT:
//Only set bits that are driven statically
- set_atr_reg(ATR_REG_IDLE, value, _atr_disable_reg.get(masked_reg_t::REGISTER));
+ set_atr_reg(ATR_REG_IDLE, value);
break;
case GPIO_ATR_0X:
//Only set bits that are driven by the ATR engine
- set_atr_reg(ATR_REG_IDLE, value, ~_atr_disable_reg.get(masked_reg_t::REGISTER));
+ set_atr_reg(ATR_REG_IDLE, value);
break;
case GPIO_ATR_RX:
//Only set bits that are driven by the ATR engine
- set_atr_reg(ATR_REG_RX_ONLY, value, ~_atr_disable_reg.get(masked_reg_t::REGISTER));
+ set_atr_reg(ATR_REG_RX_ONLY, value);
break;
case GPIO_ATR_TX:
//Only set bits that are driven by the ATR engine
- set_atr_reg(ATR_REG_TX_ONLY, value, ~_atr_disable_reg.get(masked_reg_t::REGISTER));
+ set_atr_reg(ATR_REG_TX_ONLY, value);
break;
case GPIO_ATR_XX:
//Only set bits that are driven by the ATR engine
- set_atr_reg(ATR_REG_FULL_DUPLEX, value, ~_atr_disable_reg.get(masked_reg_t::REGISTER));
+ set_atr_reg(ATR_REG_FULL_DUPLEX, value);
break;
default:
UHD_THROW_INVALID_CODE_PATH();
diff --git a/host/lib/usrp/cores/gpio_atr_3000.hpp b/host/lib/usrp/cores/gpio_atr_3000.hpp
index 28ec360ca..b30cd3b85 100644
--- a/host/lib/usrp/cores/gpio_atr_3000.hpp
+++ b/host/lib/usrp/cores/gpio_atr_3000.hpp
@@ -86,9 +86,7 @@ public:
* \param value the value to write
* \param mask only writes to the bits where mask is non-zero
*/
- inline void set_gpio_out(const boost::uint32_t value, const boost::uint32_t mask = MASK_SET_ALL) {
- set_atr_reg(ATR_REG_IDLE, value, mask);
- }
+ virtual void set_gpio_out(const boost::uint32_t value, const boost::uint32_t mask = MASK_SET_ALL) = 0;
/*!
* Read the state of the GPIO pins