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