aboutsummaryrefslogtreecommitdiffstats
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
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
-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