diff options
Diffstat (limited to 'host/usrp_e_utils/clkgen_config.hpp')
| -rw-r--r-- | host/usrp_e_utils/clkgen_config.hpp | 305 | 
1 files changed, 305 insertions, 0 deletions
diff --git a/host/usrp_e_utils/clkgen_config.hpp b/host/usrp_e_utils/clkgen_config.hpp new file mode 100644 index 000000000..f39f8bb19 --- /dev/null +++ b/host/usrp_e_utils/clkgen_config.hpp @@ -0,0 +1,305 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef USRP_E_UTILS_CLKGEN_CONFIG_HPP +#define USRP_E_UTILS_CLKGEN_CONFIG_HPP + +#include <iostream> +#include <sstream> +#include <fstream> +#include <string> +#include <cstdlib> + +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> + +#include <linux/spi/spidev.h> + +namespace usrp_e_clkgen_config_utility{ + +// Programming data for clock gen chip +static const unsigned int config_data[] = { +	0x000024, +	0x023201, +	0x000081, +	0x000400, +	0x00104c, +	0x001101, +	0x001200, +	0x001300, +	0x001414, +	0x001500, +	0x001604, +	0x001704, +	0x001807, +	0x001900, +	//0x001a00,//for debug +	0x001a32, +	0x001b12, +	0x001c44, +	0x001d00, +	0x001e00, +	0x00f062, +	0x00f162, +	0x00f262, +	0x00f362, +	0x00f462, +	0x00f562, +	0x00f662, +	0x00f762, +	0x00f862, +	0x00f962, +	0x00fa62, +	0x00fb62, +	0x00fc00, +	0x00fd00, +	0x019021, +	0x019100, +	0x019200, +	0x019321, +	0x019400, +	0x019500, +	0x019611, +	0x019700, +	0x019800, +	0x019900, +	0x019a00, +	0x019b00, +	0x01e003, +	0x01e102, +	0x023000, +	0x023201, +	0x0b0201, +	0x0b0300, +	0x001fff, +	0x0a0000, +	0x0a0100, +	0x0a0200, +	0x0a0302, +	0x0a0400, +	0x0a0504, +	0x0a060e, +	0x0a0700, +	0x0a0810, +	0x0a090e, +	0x0a0a00, +	0x0a0bf0, +	0x0a0c0b, +	0x0a0d01, +	0x0a0e90, +	0x0a0f01, +	0x0a1001, +	0x0a11e0, +	0x0a1201, +	0x0a1302, +	0x0a1430, +	0x0a1580, +	0x0a16ff, +	0x023201, +	0x0b0301, +	0x023201, +}; + + +const unsigned int CLKGEN_SELECT = 145; + + +enum gpio_direction {IN, OUT}; + +class gpio { +	public: + +	gpio(unsigned int gpio_num, gpio_direction pin_direction, bool close_action); +	~gpio(); + +	bool get_value(); +	void set_value(bool state); + +	private: + +	unsigned int gpio_num; + +	std::stringstream base_path; +	std::fstream value_file; +	std::fstream direction_file; +	bool close_action; // True set to input and release, false do nothing +}; + +class spidev { +	public: + +	spidev(std::string dev_name); +	~spidev(); + +	void send(char *wbuf, char *rbuf, unsigned int nbytes); + +	private: + +	int fd; + +}; + +gpio::gpio(unsigned int _gpio_num, gpio_direction pin_direction, bool close_action) +:close_action(close_action) +{ +	std::fstream export_file; + +	gpio_num = _gpio_num; + +	export_file.open("/sys/class/gpio/export", std::ios::out); +	if (!export_file.is_open())  ///\todo Poor error handling +		std::cout << "Failed to open gpio export file." << std::endl; + +	export_file << gpio_num << std::endl; + +	base_path << "/sys/class/gpio/gpio" << gpio_num << std::flush; + +	std::string direction_file_name; + +	direction_file_name = base_path.str() + "/direction"; + +	direction_file.open(direction_file_name.c_str());  +	if (!direction_file.is_open()) +		std::cout << "Failed to open direction file." << std::endl; +	if (pin_direction == OUT) +		direction_file << "out" << std::endl; +	else +		direction_file << "in" << std::endl; + +	std::string value_file_name; + +	value_file_name = base_path.str() + "/value"; + +	value_file.open(value_file_name.c_str(), std::ios_base::in | std::ios_base::out); +	if (!value_file.is_open()) +		std::cout << "Failed to open value file." << std::endl; +} + +bool gpio::get_value() +{ + +	std::string val; + +	std::getline(value_file, val); +	value_file.seekg(0); + +	if (val == "0") +		return false; +	else if (val == "1") +		return true; +	else +		std::cout << "Data read from value file|" << val << "|" << std::endl; + +	return false; +} + +void gpio::set_value(bool state) +{ + +	if (state) +		value_file << "1" << std::endl; +	else +		value_file << "0" << std::endl; +} + +gpio::~gpio() +{ +	if (close_action) { +		std::fstream unexport_file; + +		direction_file << "in" << std::endl; + +		unexport_file.open("/sys/class/gpio/unexport", std::ios::out); +		if (!unexport_file.is_open())  ///\todo Poor error handling +			std::cout << "Failed to open gpio export file." << std::endl; + +		unexport_file << gpio_num << std::endl; +		 +	 } + +} + +spidev::spidev(std::string fname) +{ +	int ret; +	int mode = 0; +	int speed = 12000; +	int bits = 24; + +	fd = open(fname.c_str(), O_RDWR); + +	ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); +	ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); +	ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); +} +	 + +spidev::~spidev() +{ +	close(fd); +} + +void spidev::send(char *buf, char *rbuf, unsigned int nbytes) +{ +	int ret; + +	struct spi_ioc_transfer tr; +	tr.tx_buf = (unsigned long) buf; +	tr.rx_buf = (unsigned long) rbuf; +	tr.len = nbytes; +	tr.delay_usecs = 0; +	tr.speed_hz = 12000; +	tr.bits_per_word = 24; + +	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + +} + +static void send_config_to_clkgen(gpio &chip_select, const unsigned int data[], unsigned int data_size) +{ +	spidev spi("/dev/spidev1.0"); +	unsigned int rbuf; + +	for (unsigned int i = 0; i < data_size; i++) { + +		//std::cout << "sending " << std::hex << data[i] << std::endl; +		chip_select.set_value(0); +		spi.send((char *)&data[i], (char *)&rbuf, 4); +		chip_select.set_value(1); +		unsigned int addr = (data[i] >> 8) & 0xfff; +		if (addr == 0x232 || addr == 0x000){ +			std::cout << "." << std::flush; +			sleep(1); +		} +	}; +	std::cout << std::endl; +} + +}//namespace usrp_e_clkgen_config_utility + +//int main(int argc, char *argv[]) +static void clock_genconfig_main(void) +{ +	using namespace usrp_e_clkgen_config_utility; +	gpio clkgen_select(CLKGEN_SELECT, OUT, true); + +	send_config_to_clkgen(clkgen_select, config_data, sizeof(config_data)/sizeof(config_data[0])); +} + +#endif /*USRP_E_UTILS_CLKGEN_CONFIG_HPP*/  | 
