diff options
| author | Josh Blum <josh@joshknows.com> | 2011-06-15 07:35:49 +0100 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2011-06-15 07:35:49 +0100 | 
| commit | 5bbc3c6282bb73db72d3dd1738aa906a89a6f772 (patch) | |
| tree | dd3f374a5690499033a5f0d57886bfbe0a56543f /host/lib | |
| parent | 5f3635ad0bf464edf0eea58ac94eb71f33d4de1d (diff) | |
| download | uhd-5bbc3c6282bb73db72d3dd1738aa906a89a6f772.tar.gz uhd-5bbc3c6282bb73db72d3dd1738aa906a89a6f772.tar.bz2 uhd-5bbc3c6282bb73db72d3dd1738aa906a89a6f772.zip | |
e100: clean up gpio wrapper stuff, fix order of setup in make()
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/usrp/e100/e100_iface.cpp | 138 | ||||
| -rw-r--r-- | host/lib/usrp/e100/e100_impl.cpp | 10 | 
2 files changed, 68 insertions, 80 deletions
| diff --git a/host/lib/usrp/e100/e100_iface.cpp b/host/lib/usrp/e100/e100_iface.cpp index d61ef42ad..e44e438b0 100644 --- a/host/lib/usrp/e100/e100_iface.cpp +++ b/host/lib/usrp/e100/e100_iface.cpp @@ -34,6 +34,57 @@ using namespace uhd;  using namespace uhd::usrp;  /*********************************************************************** + * Sysfs GPIO wrapper class + **********************************************************************/ +class gpio{ +public: +    gpio(const int num, const std::string &dir) : _num(num){ +        this->set_xport("export"); +        this->set_dir(dir); +        _value_file.open(str(boost::format("/sys/class/gpio/gpio%d/value") % num).c_str(), std::ios_base::in | std::ios_base::out); +    } +    ~gpio(void){ +        _value_file.close(); +        this->set_dir("in"); +        this->set_xport("unexport"); +    } +    void operator()(const int val){ +        _value_file << val << std::endl << std::flush; +    } +    int operator()(void){ +        std::string val; +        std::getline(_value_file, val); +        _value_file.seekg(0); +        return int(val.at(0) - '0') & 0x1; +    } +private: +    void set_xport(const std::string &xport){ +        std::ofstream export_file(("/sys/class/gpio/" + xport).c_str()); +        export_file << _num << std::endl << std::flush; +        export_file.close(); +    } +    void set_dir(const std::string &dir){ +        std::ofstream dir_file(str(boost::format("/sys/class/gpio/gpio%d/direction") % _num).c_str()); +        dir_file << dir << std::endl << std::flush; +        dir_file.close(); +    } +    const int _num; +    std::fstream _value_file; +}; + +//We only init the gpios when we have to use them (in the aux spi call). +//This way, the device discovery cannot unexport them from another process. +struct iface_gpios_type{ +    typedef boost::shared_ptr<iface_gpios_type> sptr; +    iface_gpios_type(void): +        spi_sclk_gpio(65, "out"), +        spi_sen_gpio(186, "out"), +        spi_mosi_gpio(145, "out"), +        spi_miso_gpio(147, "in"){} +    gpio spi_sclk_gpio, spi_sen_gpio, spi_mosi_gpio, spi_miso_gpio; +}; + +/***********************************************************************   * I2C device node implementation wrapper   **********************************************************************/  class i2c_dev_iface : public i2c_iface{ @@ -281,92 +332,29 @@ public:      }      boost::uint32_t bitbang_spi( -        boost::uint32_t bits, -        size_t num_bits, -        bool readback +        boost::uint32_t bits, size_t num_bits, bool readback      ){ -        boost::uint32_t rb_bits = 0; +        if (_gpios.get() == NULL) { //init on demand... +            _gpios = iface_gpios_type::sptr(new iface_gpios_type()); +        } -        _spi_bitbanger.spi_sen_gpio_write(0); +        boost::uint32_t rb_bits = 0; +        _gpios->spi_sen_gpio(0);          for (size_t i = 0; i < num_bits; i++){ -            _spi_bitbanger.spi_sclk_gpio_write(0); -            _spi_bitbanger.spi_mosi_gpio_write((bits >> (num_bits-i-1)) & 0x1); +            _gpios->spi_sclk_gpio(0); +            _gpios->spi_mosi_gpio((bits >> (num_bits-i-1)) & 0x1);              boost::this_thread::sleep(boost::posix_time::microseconds(10)); -            if (readback) rb_bits = (rb_bits << 1) | _spi_bitbanger.spi_miso_gpio_read(); -            _spi_bitbanger.spi_sclk_gpio_write(1); +            if (readback) rb_bits = (rb_bits << 1) | _gpios->spi_miso_gpio(); +            _gpios->spi_sclk_gpio(1);              boost::this_thread::sleep(boost::posix_time::microseconds(10));          } -        _spi_bitbanger.spi_sen_gpio_write(1); +        _gpios->spi_sen_gpio(1);          boost::this_thread::sleep(boost::posix_time::microseconds(100)); -          return rb_bits;      } -    class bitbang_spi_guts{ -    public: -        bitbang_spi_guts(void){ -            //setup gpio pin directions -            this->set_gpio_direction(spi_sclk_gpio, "out"); -            this->set_gpio_direction(spi_sen_gpio, "out"); -            this->set_gpio_direction(spi_mosi_gpio, "out"); -            this->set_gpio_direction(spi_miso_gpio, "in"); - -            //open the gpio pin values -            _spi_sclk_gpio_value.open(str(boost::format("/sys/class/gpio/gpio%d/value") % spi_sclk_gpio).c_str()); -            _spi_sen_gpio_value.open(str(boost::format("/sys/class/gpio/gpio%d/value") % spi_sen_gpio).c_str()); -            _spi_mosi_gpio_value.open(str(boost::format("/sys/class/gpio/gpio%d/value") % spi_mosi_gpio).c_str()); -            _spi_miso_gpio_value.open(str(boost::format("/sys/class/gpio/gpio%d/value") % spi_miso_gpio).c_str()); -        } - -        ~bitbang_spi_guts(void){ -            this->set_gpio_direction(spi_sclk_gpio, "in"); -            this->set_gpio_direction(spi_sen_gpio, "in"); -            this->set_gpio_direction(spi_mosi_gpio, "in"); -        } - -        void spi_sclk_gpio_write(int val){ -            _spi_sclk_gpio_value << val << std::endl << std::flush; -        } - -        void spi_sen_gpio_write(int val){ -            _spi_sen_gpio_value << val << std::endl << std::flush; -        } - -        void spi_mosi_gpio_write(int val){ -            _spi_mosi_gpio_value << val << std::endl << std::flush; -        } - -        int spi_miso_gpio_read(void){ -            std::string val; -            std::getline(_spi_miso_gpio_value, val); -            _spi_miso_gpio_value.seekg(0); -            return int(val.at(0) - '0') & 0x1; -        } - -    private: -        enum{ -            spi_sclk_gpio = 65, -            spi_sen_gpio = 186, -            spi_mosi_gpio = 145, -            spi_miso_gpio = 147, -        }; - -        void set_gpio_direction(int gpio_num, const std::string &dir){ -            std::ofstream export_file("/sys/class/gpio/export"); -            export_file << gpio_num << std::endl << std::flush; -            export_file.close(); - -            std::ofstream dir_file(str(boost::format("/sys/class/gpio/gpio%d/direction") % gpio_num).c_str()); -            dir_file << dir << std::endl << std::flush; -            dir_file.close(); -        } - -        std::ofstream _spi_sclk_gpio_value, _spi_sen_gpio_value, _spi_mosi_gpio_value; -        std::ifstream _spi_miso_gpio_value; -    }; -      /*******************************************************************       * UART       ******************************************************************/ @@ -382,7 +370,7 @@ private:      int _node_fd;      i2c_dev_iface _i2c_dev_iface;      boost::mutex _ctrl_mutex; -    bitbang_spi_guts _spi_bitbanger; +    iface_gpios_type::sptr _gpios;  };  /*********************************************************************** diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp index 5485388f9..40ae20eaa 100644 --- a/host/lib/usrp/e100/e100_impl.cpp +++ b/host/lib/usrp/e100/e100_impl.cpp @@ -90,11 +90,6 @@ static device::sptr e100_make(const device_addr_t &device_addr){      //setup the main interface into fpga      const std::string node = device_addr["node"];      e100_iface::sptr iface = e100_iface::make(); -    iface->open(node); - -    //setup clock control here to ensure that the FPGA has a good clock before we continue -    const double master_clock_rate = device_addr.cast<double>("master_clock_rate", E100_DEFAULT_CLOCK_RATE); -    e100_clock_ctrl::sptr clock_ctrl = e100_clock_ctrl::make(iface, master_clock_rate);      //extract the fpga path for usrp-e and compute hash      const std::string e100_fpga_image = find_image_path(device_addr.get("fpga", E100_FPGA_FILE_NAME)); @@ -104,12 +99,17 @@ static device::sptr e100_make(const device_addr_t &device_addr){      // - close the device node      // - load the fpga bin file      // - re-open the device node +    iface->open(node); //open here so we can do FPGA hash check      if (iface->peek32(E100_REG_RB_MISC_TEST32) != file_hash){          iface->close();          e100_load_fpga(e100_fpga_image);          iface->open(node);      } +    //setup clock control here to ensure that the FPGA has a good clock before we continue +    const double master_clock_rate = device_addr.cast<double>("master_clock_rate", E100_DEFAULT_CLOCK_RATE); +    e100_clock_ctrl::sptr clock_ctrl = e100_clock_ctrl::make(iface, master_clock_rate); +      //Perform wishbone readback tests, these tests also write the hash      bool test_fail = false;      UHD_MSG(status) << "Performing wishbone readback test... " << std::flush; | 
