diff options
author | Derek Kozel <derek.kozel@ettus.com> | 2016-04-04 17:53:52 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2016-04-08 16:50:54 -0700 |
commit | 0811fbed937c1ed679c514929728a992b46738a6 (patch) | |
tree | 6c2b8cf62c53169d2e7fa47c661b101bb74d2d32 | |
parent | 088b852844692e9d366e3e44336883adf0305623 (diff) | |
download | uhd-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.hpp | 8 | ||||
-rw-r--r-- | host/lib/types/serial.cpp | 3 | ||||
-rw-r--r-- | host/lib/usrp/cores/spi_core_3000.cpp | 26 |
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) |