aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDerek Kozel <derek.kozel@ettus.com>2016-04-04 17:53:52 -0700
committerMartin Braun <martin.braun@ettus.com>2016-04-08 16:50:54 -0700
commit0811fbed937c1ed679c514929728a992b46738a6 (patch)
tree6c2b8cf62c53169d2e7fa47c661b101bb74d2d32
parent088b852844692e9d366e3e44336883adf0305623 (diff)
downloaduhd-0811fbed937c1ed679c514929728a992b46738a6.tar.gz
uhd-0811fbed937c1ed679c514929728a992b46738a6.tar.bz2
uhd-0811fbed937c1ed679c514929728a992b46738a6.zip
Added option for writes to specify a SPI speed
-rw-r--r--host/include/uhd/types/serial.hpp8
-rw-r--r--host/lib/types/serial.cpp3
-rw-r--r--host/lib/usrp/cores/spi_core_3000.cpp26
3 files changed, 29 insertions, 8 deletions
diff --git a/host/include/uhd/types/serial.hpp b/host/include/uhd/types/serial.hpp
index 7b565c633..5b7f34fbd 100644
--- a/host/include/uhd/types/serial.hpp
+++ b/host/include/uhd/types/serial.hpp
@@ -118,13 +118,19 @@ namespace uhd{
//! on what edge is the miso data valid?
edge_t miso_edge;
+ //! Set the clock speed for this transaction
+ bool use_custom_divider;
+
+ //! Optionally set the SPI clock divider for this transaction
+ size_t divider;
+
/*!
* Create a new spi config.
* \param edge the default edge for mosi and miso
*/
spi_config_t(edge_t edge = EDGE_RISE);
};
-
+
/*!
* The SPI interface class.
* Provides routines to transact SPI and do other useful things which haven't been defined yet.
diff --git a/host/lib/types/serial.cpp b/host/lib/types/serial.cpp
index 9b8336dd8..52961691c 100644
--- a/host/lib/types/serial.cpp
+++ b/host/lib/types/serial.cpp
@@ -40,7 +40,8 @@ spi_config_t::spi_config_t(edge_t edge):
mosi_edge(edge),
miso_edge(edge)
{
- /* NOP */
+ // By default don't use a custom clock speed for the transaction
+ use_custom_divider = false;
}
void i2c_iface::write_eeprom(
diff --git a/host/lib/usrp/cores/spi_core_3000.cpp b/host/lib/usrp/cores/spi_core_3000.cpp
index 0656d910a..d33624b0d 100644
--- a/host/lib/usrp/cores/spi_core_3000.cpp
+++ b/host/lib/usrp/cores/spi_core_3000.cpp
@@ -34,7 +34,7 @@ class spi_core_3000_impl : public spi_core_3000
{
public:
spi_core_3000_impl(wb_iface::sptr iface, const size_t base, const size_t readback):
- _iface(iface), _base(base), _readback(readback), _ctrl_word_cache(0)
+ _iface(iface), _base(base), _readback(readback), _ctrl_word_cache(0), _divider_cache(0)
{
this->set_divider(30);
}
@@ -46,7 +46,21 @@ public:
size_t num_bits,
bool readback
){
- boost::mutex::scoped_lock lock(_mutex);
+ boost::lock_guard<boost::mutex> lock(_mutex);
+
+ //load SPI divider
+ size_t spi_divider = _div;
+ if (config.use_custom_divider) {
+ //The resulting SPI frequency will be f_system/(2*(divider+1))
+ //This math ensures the frequency will be equal to or less than the target
+ spi_divider = (config.divider-1)/2;
+ }
+
+ //conditionally send SPI divider
+ if (spi_divider != _divider_cache) {
+ _iface->poke32(SPI_DIV, spi_divider);
+ _divider_cache = spi_divider;
+ }
//load control word
boost::uint32_t ctrl_word = 0;
@@ -55,17 +69,16 @@ public:
if (config.mosi_edge == spi_config_t::EDGE_FALL) ctrl_word |= (1 << 31);
if (config.miso_edge == spi_config_t::EDGE_RISE) ctrl_word |= (1 << 30);
- //load data word (must be in upper bits)
- const boost::uint32_t data_out = data << (32 - num_bits);
-
//conditionally send control word
if (_ctrl_word_cache != ctrl_word)
{
- _iface->poke32(SPI_DIV, _div);
_iface->poke32(SPI_CTRL, ctrl_word);
_ctrl_word_cache = ctrl_word;
}
+ //load data word (must be in upper bits)
+ const boost::uint32_t data_out = data << (32 - num_bits);
+
//send data word
_iface->poke32(SPI_DATA, data_out);
@@ -91,6 +104,7 @@ private:
boost::uint32_t _ctrl_word_cache;
boost::mutex _mutex;
size_t _div;
+ size_t _divider_cache;
};
spi_core_3000::sptr spi_core_3000::make(wb_iface::sptr iface, const size_t base, const size_t readback)