From be576635cbba32bec56974fc24f5ae859f6722da Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Mon, 22 Feb 2010 16:44:15 -0800 Subject: place to put omap tools --- host/apps/omap_debug/README | 1 + 1 file changed, 1 insertion(+) create mode 100644 host/apps/omap_debug/README (limited to 'host') diff --git a/host/apps/omap_debug/README b/host/apps/omap_debug/README new file mode 100644 index 000000000..bbe0c2cc4 --- /dev/null +++ b/host/apps/omap_debug/README @@ -0,0 +1 @@ +OMAP development tools go here -- cgit v1.2.3 From fa35b710c09d7cb4a410313fd24d0ea2aa4172a3 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 23 Feb 2010 02:06:59 +0000 Subject: Initial checkin of u1e testing code. Some of these may not be really useful anymore. --- host/apps/omap_debug/fpga-downloader.cc | 251 ++++++++++++++++++++++++++++++++ host/apps/omap_debug/test.c | 34 +++++ host/apps/omap_debug/u1e-read-stream.c | 21 +++ host/apps/omap_debug/usrp1-e-ctl.c | 52 +++++++ host/apps/omap_debug/usrp1-e-ram.c | 25 ++++ host/apps/omap_debug/usrp1-e-read.c | 18 +++ host/apps/omap_debug/usrp1-e-write.c | 21 +++ 7 files changed, 422 insertions(+) create mode 100644 host/apps/omap_debug/fpga-downloader.cc create mode 100644 host/apps/omap_debug/test.c create mode 100644 host/apps/omap_debug/u1e-read-stream.c create mode 100644 host/apps/omap_debug/usrp1-e-ctl.c create mode 100644 host/apps/omap_debug/usrp1-e-ram.c create mode 100644 host/apps/omap_debug/usrp1-e-read.c create mode 100644 host/apps/omap_debug/usrp1-e-write.c (limited to 'host') diff --git a/host/apps/omap_debug/fpga-downloader.cc b/host/apps/omap_debug/fpga-downloader.cc new file mode 100644 index 000000000..fb96b64a3 --- /dev/null +++ b/host/apps/omap_debug/fpga-downloader.cc @@ -0,0 +1,251 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003,2004,2008,2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* + * Configuration connections + * + * CCK - MCSPI1_CLK + * DIN - MCSPI1_MOSI + * PROG_B - GPIO_175 - output (change mux) + * DONE - GPIO_173 - input (change mux) + * INIT_B - GPIO_114 - input (change mux) + * +*/ + +const unsigned int PROG_B = 175; +const unsigned int DONE = 173; +const unsigned int INIT_B = 114; + +static std::string bit_file = "safe_u1e.bin"; + +const int BUF_SIZE = 4096; + +enum gpio_direction {IN, OUT}; + +class gpio { + public: + + gpio(unsigned int gpio_num, gpio_direction pin_direction); + + bool get_value(); + void set_value(bool state); + + private: + + std::stringstream base_path; + std::fstream value_file; +}; + +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) +{ + std::fstream export_file; + + 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::fstream direction_file; + 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; +} + +static void prepare_fpga_for_configuration(gpio &prog, gpio &init) +{ + + prog.set_value(true); + prog.set_value(false); + prog.set_value(true); + +#if 0 + bool ready_to_program(false); + unsigned int count(0); + do { + ready_to_program = init.get_value(); + count++; + + sleep(1); + } while (count < 10 && !ready_to_program); + + if (count == 10) { + std::cout << "FPGA not ready for programming." << std::endl; + exit(-1); + } +#endif +} + +spidev::spidev(std::string fname) +{ + int ret; + int mode = 0; + int speed = 12000000; + int bits = 8; + + 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 = 48000000; + tr.bits_per_word = 8; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + +} + +static void send_file_to_fpga(std::string &file_name, gpio &error, gpio &done) +{ + std::ifstream bitstream; + + std::cout << "File name - " << file_name.c_str() << std::endl; + + bitstream.open(file_name.c_str(), std::ios::binary); + if (!bitstream.is_open()) + std::cout << "File " << file_name << " not opened succesfully." << std::endl; + + spidev spi("/dev/spidev1.0"); + char buf[BUF_SIZE]; + char rbuf[BUF_SIZE]; + + do { + bitstream.read(buf, BUF_SIZE); + spi.send(buf, rbuf, bitstream.gcount()); + + if (error.get_value()) + std::cout << "INIT_B went high, error occured." << std::endl; + + if (!done.get_value()) + std::cout << "Configuration complete." << std::endl; + + } while (bitstream.gcount() == BUF_SIZE); +} + +int main(int argc, char *argv[]) +{ + + gpio gpio_prog_b(PROG_B, OUT); + gpio gpio_init_b(INIT_B, IN); + gpio gpio_done (DONE, IN); + + if (argc == 2) + bit_file = argv[1]; + + std::cout << "FPGA config file: " << bit_file << std::endl; + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "Done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bit_file, gpio_init_b, gpio_done); +} + diff --git a/host/apps/omap_debug/test.c b/host/apps/omap_debug/test.c new file mode 100644 index 000000000..36f4d700a --- /dev/null +++ b/host/apps/omap_debug/test.c @@ -0,0 +1,34 @@ +#include + +void +main() +{ + int x; + char *y; + long long z; + + x = 0x01020304; + z = 0x0102030405060708LL; + + printf("%x\n",x); + y = (char *)&x; + printf("%x\n",y[0]); + printf("%x\n",y[1]); + printf("%x\n",y[2]); + printf("%x\n",y[3]); + + printf("Printing z ...\n"); + printf("%llx\n",z); + printf("Printing z done\n"); + + y = (char *)&z; + printf("%x\n",y[0]); + printf("%x\n",y[1]); + printf("%x\n",y[2]); + printf("%x\n",y[3]); + printf("%x\n",y[4]); + printf("%x\n",y[5]); + printf("%x\n",y[6]); + printf("%x\n",y[7]); +} + diff --git a/host/apps/omap_debug/u1e-read-stream.c b/host/apps/omap_debug/u1e-read-stream.c new file mode 100644 index 000000000..4e4c21d9e --- /dev/null +++ b/host/apps/omap_debug/u1e-read-stream.c @@ -0,0 +1,21 @@ +#include +#include +#include + +int main(int rgc, char *argv[]) +{ + int fp, cnt, n; + short buf[1024]; + + n = 0; + + fp = open("/dev/usrp1_e0", O_RDONLY); + printf("fp = %d\n", fp); + + do { + cnt = read(fp, buf, 2048); + n++; +// printf("Bytes read - %d\n", cnt); + } while(n < 10*512); + printf("Data - %hX\n", buf[0]); +} diff --git a/host/apps/omap_debug/usrp1-e-ctl.c b/host/apps/omap_debug/usrp1-e-ctl.c new file mode 100644 index 000000000..045e7ce19 --- /dev/null +++ b/host/apps/omap_debug/usrp1-e-ctl.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include + +#include "usrp1_e.h" + +// Usage: usrp1_e_ctl w|r offset number_of_values val1 val2 .... + +int main(int argc, char *argv[]) +{ + int fp, i, cnt, ret; + struct usrp1_e_ctl *ctl_data; + + if (argc < 4) { + printf("Usage: usrp1_e_ctl w|r offset number_of_values val1 val2 ....\n"); + exit(-1); + } + + cnt = atoi(argv[3]); + + ctl_data = malloc(sizeof(struct usrp1_e_ctl) + cnt*2); + + ctl_data->offset = atoi(argv[2]); + ctl_data->count = cnt; + + printf("Sizeof usrp1_e_ctl struct = %d\n", sizeof(struct usrp1_e_ctl)); + + fp = open("/dev/usrp1_e0", O_RDWR); + printf("fp = %d\n", fp); + + if (*argv[1] == 'w') { + for (i=0; ibuf[i] = atoi(argv[4+i]); + + ret = ioctl(fp, USRP1_E_WRITE_CTL, ctl_data); + printf("Return value from write ioctl = %d\n", ret); + } + + if (*argv[1] == 'r') { + ret = ioctl(fp, USRP1_E_READ_CTL, ctl_data); + printf("Return value from write ioctl = %d\n", ret); + + for (i=0; icount; i++) { + if (!(i%8)) + printf("\nData at %4d :", i); + printf(" %5d", ctl_data->buf[i]); + } + printf("\n"); + } +} diff --git a/host/apps/omap_debug/usrp1-e-ram.c b/host/apps/omap_debug/usrp1-e-ram.c new file mode 100644 index 000000000..d548f7ccd --- /dev/null +++ b/host/apps/omap_debug/usrp1-e-ram.c @@ -0,0 +1,25 @@ +#include +#include +#include + +int main(int rgc, char *argv[]) +{ + int fp, i, cnt; + unsigned short buf[1024]; + unsigned short buf_rb[1024]; + + fp = open("/dev/usrp1_e0", O_RDWR); + printf("fp = %d\n", fp); + + for (i=0; i<1024; i++) + buf[i] = i*256; + write(fp, buf, 2048); + read(fp, buf_rb, 2048); + + printf("Read back %hX %hX\n", buf_rb[0], buf_rb[1]); + + for (i=0; i<1024; i++) { + if (buf[i] != buf_rb[i]) + printf("Read - %hX, expected - %hX\n", buf_rb[i], buf[i]); + } +} diff --git a/host/apps/omap_debug/usrp1-e-read.c b/host/apps/omap_debug/usrp1-e-read.c new file mode 100644 index 000000000..c28f018d5 --- /dev/null +++ b/host/apps/omap_debug/usrp1-e-read.c @@ -0,0 +1,18 @@ +#include +#include +#include + +int main(int rgc, char *argv[]) +{ + int fp, cnt; + short buf[1024]; + + fp = open("/dev/usrp1_e0", O_RDONLY); + printf("fp = %d\n", fp); + + do { + cnt = read(fp, buf, 2048); +// printf("Bytes read - %d\n", cnt); + } while(1); + printf("Data - %hX\n", buf[0]); +} diff --git a/host/apps/omap_debug/usrp1-e-write.c b/host/apps/omap_debug/usrp1-e-write.c new file mode 100644 index 000000000..f29cc7032 --- /dev/null +++ b/host/apps/omap_debug/usrp1-e-write.c @@ -0,0 +1,21 @@ +#include +#include +#include + +int main(int rgc, char *argv[]) +{ + int fp, i, cnt; + short buf[1024]; + + fp = open("/dev/usrp1_e0", O_WRONLY); + printf("fp = %d\n", fp); + + for (i=0; i<1024; i++) { + buf[i] = i; + } + + do { + cnt = write(fp, buf, 2048); + printf("Bytes written - %d\n", cnt); + } while (1); +} -- cgit v1.2.3 From 1e49264f713701a89fb2bc079344273df5a94c06 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 23 Feb 2010 02:09:51 +0000 Subject: Initial checkin of useful shell scripts. --- host/apps/omap_debug/fetch-bin.sh | 1 + host/apps/omap_debug/fetch-kernel.sh | 2 ++ host/apps/omap_debug/fetch-module.sh | 1 + 3 files changed, 4 insertions(+) create mode 100755 host/apps/omap_debug/fetch-bin.sh create mode 100755 host/apps/omap_debug/fetch-kernel.sh create mode 100755 host/apps/omap_debug/fetch-module.sh (limited to 'host') diff --git a/host/apps/omap_debug/fetch-bin.sh b/host/apps/omap_debug/fetch-bin.sh new file mode 100755 index 000000000..9fb09a10d --- /dev/null +++ b/host/apps/omap_debug/fetch-bin.sh @@ -0,0 +1 @@ +scp balister@192.168.1.182:Download/u1e.bin . diff --git a/host/apps/omap_debug/fetch-kernel.sh b/host/apps/omap_debug/fetch-kernel.sh new file mode 100755 index 000000000..e3bc1b0ad --- /dev/null +++ b/host/apps/omap_debug/fetch-kernel.sh @@ -0,0 +1,2 @@ +scp balister@192.168.1.182:src/git/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage + diff --git a/host/apps/omap_debug/fetch-module.sh b/host/apps/omap_debug/fetch-module.sh new file mode 100755 index 000000000..95140df15 --- /dev/null +++ b/host/apps/omap_debug/fetch-module.sh @@ -0,0 +1 @@ +scp balister@192.168.1.182:src/git/kernel_usrp/drivers/misc/usrp1_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc -- cgit v1.2.3 From ba0bbdb3ca3815ca45766cc5f2d06a4d12810f0f Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Mon, 22 Feb 2010 18:37:29 -0800 Subject: first cut at automatically setting the debug pins --- host/apps/omap_debug/set_debug_pins.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100755 host/apps/omap_debug/set_debug_pins.py (limited to 'host') diff --git a/host/apps/omap_debug/set_debug_pins.py b/host/apps/omap_debug/set_debug_pins.py new file mode 100755 index 000000000..982c290ef --- /dev/null +++ b/host/apps/omap_debug/set_debug_pins.py @@ -0,0 +1,34 @@ +#!/usr/bin/python + +import os + +# Memory Map +misc_base = 0 +uart_base = 1 +spi_base = 2 +i2c_base = 3 +gpio_base = 4 +settings_base = 5 + +# GPIO offset +gpio_pins = 0 +gpio_ddr = 4 +gpio_ctrl_lo = 8 +gpio_ctrl_hi = 12 + +def set_reg(reg, val): + os.system("usrp1-e-ctl w %d 1 %d" % (reg,val)) + +def get_reg(reg): + fin,fout = os.popen4("usrp1-e-ctl r %d 1" % (reg,)) + print fout.read() + +# Set DDRs to output +set_reg(gpio_base+gpio_ddr, 0xFFFF) +set_reg(gpio_base+gpio_ddr+2, 0xFFFF) + +# Set CTRL to Debug #0 ( A is for debug 0, F is for debug 1 ) +set_reg(gpio_base+ctrl_lo, 0xAAAA) +set_reg(gpio_base+ctrl_lo+2, 0xAAAA) +set_reg(gpio_base+ctrl_hi, 0xAAAA) +set_reg(gpio_base+ctrl_hi+2, 0xAAAA) -- cgit v1.2.3 From 3cd7bc9be6420623eb7803e490b39ecc75d83ed9 Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Mon, 22 Feb 2010 18:43:16 -0800 Subject: full neame --- host/apps/omap_debug/set_debug_pins.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/set_debug_pins.py b/host/apps/omap_debug/set_debug_pins.py index 982c290ef..d67cc3e58 100755 --- a/host/apps/omap_debug/set_debug_pins.py +++ b/host/apps/omap_debug/set_debug_pins.py @@ -28,7 +28,7 @@ set_reg(gpio_base+gpio_ddr, 0xFFFF) set_reg(gpio_base+gpio_ddr+2, 0xFFFF) # Set CTRL to Debug #0 ( A is for debug 0, F is for debug 1 ) -set_reg(gpio_base+ctrl_lo, 0xAAAA) -set_reg(gpio_base+ctrl_lo+2, 0xAAAA) -set_reg(gpio_base+ctrl_hi, 0xAAAA) -set_reg(gpio_base+ctrl_hi+2, 0xAAAA) +set_reg(gpio_base+gpio_ctrl_lo, 0xAAAA) +set_reg(gpio_base+gpio_ctrl_lo+2, 0xAAAA) +set_reg(gpio_base+gpio_ctrl_hi, 0xAAAA) +set_reg(gpio_base+gpio_ctrl_hi+2, 0xAAAA) -- cgit v1.2.3 From f6ec1e45117f5794facd1cd8e11cbfacabdeb166 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Feb 2010 02:18:54 +0000 Subject: Commit wip. Programs that fetch OS code sync now. --- host/apps/omap_debug/fetch-bin.sh | 1 + host/apps/omap_debug/fetch-kernel.sh | 1 + host/apps/omap_debug/fetch-module.sh | 1 + host/apps/omap_debug/set_debug_pins.py | 4 ++-- 4 files changed, 5 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/fetch-bin.sh b/host/apps/omap_debug/fetch-bin.sh index 9fb09a10d..1ceec4fd2 100755 --- a/host/apps/omap_debug/fetch-bin.sh +++ b/host/apps/omap_debug/fetch-bin.sh @@ -1 +1,2 @@ scp balister@192.168.1.182:Download/u1e.bin . +sync diff --git a/host/apps/omap_debug/fetch-kernel.sh b/host/apps/omap_debug/fetch-kernel.sh index e3bc1b0ad..08b470e9b 100755 --- a/host/apps/omap_debug/fetch-kernel.sh +++ b/host/apps/omap_debug/fetch-kernel.sh @@ -1,2 +1,3 @@ scp balister@192.168.1.182:src/git/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage +sync diff --git a/host/apps/omap_debug/fetch-module.sh b/host/apps/omap_debug/fetch-module.sh index 95140df15..6511958f9 100755 --- a/host/apps/omap_debug/fetch-module.sh +++ b/host/apps/omap_debug/fetch-module.sh @@ -1 +1,2 @@ scp balister@192.168.1.182:src/git/kernel_usrp/drivers/misc/usrp1_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc +sync diff --git a/host/apps/omap_debug/set_debug_pins.py b/host/apps/omap_debug/set_debug_pins.py index d67cc3e58..bedabc20c 100755 --- a/host/apps/omap_debug/set_debug_pins.py +++ b/host/apps/omap_debug/set_debug_pins.py @@ -17,10 +17,10 @@ gpio_ctrl_lo = 8 gpio_ctrl_hi = 12 def set_reg(reg, val): - os.system("usrp1-e-ctl w %d 1 %d" % (reg,val)) + os.system("./usrp1-e-ctl w %d 1 %d" % (reg,val)) def get_reg(reg): - fin,fout = os.popen4("usrp1-e-ctl r %d 1" % (reg,)) + fin,fout = os.popen4("./usrp1-e-ctl r %d 1" % (reg,)) print fout.read() # Set DDRs to output -- cgit v1.2.3 From a9f8ba6e37e1349ce61b5022ddaff1c64dd52bd3 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 25 Feb 2010 18:26:00 +0000 Subject: added usrp1e conditional compilation, and checking of device node (aka file for now) --- host/lib/CMakeLists.txt | 14 ++++++-- host/lib/usrp/usrp1e/usrp1e_impl.cpp | 69 ++++++++++++++++++++++++++++++++++++ host/lib/usrp/usrp1e/usrp1e_impl.hpp | 23 ++++++++++++ host/lib/usrp/usrp2/usrp2_impl.cpp | 1 - 4 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 host/lib/usrp/usrp1e/usrp1e_impl.cpp create mode 100644 host/lib/usrp/usrp1e/usrp1e_impl.hpp (limited to 'host') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index edfefa127..96fba6e53 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -41,9 +41,17 @@ SET(libuhd_sources ######################################################################## # Conditionally add the usrp1e sources ######################################################################## -LIST(APPEND libuhd_sources - usrp/usrp1e/usrp1e_none.cpp -) +INCLUDE(CheckIncludeFile) +CHECK_INCLUDE_FILE("linux/ioctl.h" HAS_LINUX_IOCTL_H) +IF(HAS_LINUX_IOCTL_H) + LIST(APPEND libuhd_sources + usrp/usrp1e/usrp1e_impl.cpp + ) +ELSE(HAS_LINUX_IOCTL_H) + LIST(APPEND libuhd_sources + usrp/usrp1e/usrp1e_none.cpp + ) +ENDIF(HAS_LINUX_IOCTL_H) ######################################################################## # Setup libuhd library diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.cpp b/host/lib/usrp/usrp1e/usrp1e_impl.cpp new file mode 100644 index 000000000..93265ab17 --- /dev/null +++ b/host/lib/usrp/usrp1e/usrp1e_impl.cpp @@ -0,0 +1,69 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include "usrp1e_impl.hpp" + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * Helper Functions + **********************************************************************/ +static bool file_exists(const std::string &file_path){ + return access(file_path.c_str(), F_OK) == 0; +} + +/*********************************************************************** + * Discovery + **********************************************************************/ +device_addrs_t usrp1e::discover(const device_addr_t &device_addr){ + device_addrs_t usrp1e_addrs; + + //if a node was provided, use it and only it + if (device_addr.has_key("node")){ + if (not file_exists(device_addr["node"])) return usrp1e_addrs; + device_addr_t new_addr; + new_addr["name"] = "USRP1E"; + new_addr["type"] = "usrp1e"; + new_addr["node"] = device_addr["node"]; + usrp1e_addrs.push_back(new_addr); + } + + //otherwise look for a few nodes at small indexes + else{ + for(size_t i = 0; i < 5; i++){ + std::string node = str(boost::format("/dev/usrp1_e%d") % i); + if (not file_exists(node)) continue; + device_addr_t new_addr; + new_addr["name"] = "USRP1E"; + new_addr["type"] = "usrp1e"; + new_addr["node"] = node; + usrp1e_addrs.push_back(new_addr); + } + } + + return usrp1e_addrs; +} + +/*********************************************************************** + * Make + **********************************************************************/ +device::sptr usrp1e::make(const device_addr_t &){ + throw std::runtime_error("not implemented yet"); +} diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.hpp b/host/lib/usrp/usrp1e/usrp1e_impl.hpp new file mode 100644 index 000000000..3f5f89ec6 --- /dev/null +++ b/host/lib/usrp/usrp1e/usrp1e_impl.hpp @@ -0,0 +1,23 @@ +// +// Copyright 2010 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 . +// + +#include + +#ifndef INCLUDED_USRP1E_IMPL_HPP +#define INCLUDED_USRP1E_IMPL_HPP + +#endif /* INCLUDED_USRP1E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 06876d241..5aa5d6e8d 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -62,7 +62,6 @@ uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ device_addr_t new_addr; new_addr["name"] = "USRP2"; new_addr["type"] = "usrp2"; - new_addr["transport"] = "udp"; new_addr["addr"] = ip_addr.to_string(); usrp2_addrs.push_back(new_addr); break; -- cgit v1.2.3 From 778a41b393b7d517463950c4ac014d3a2eb8eceb Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 25 Feb 2010 19:43:20 +0000 Subject: added usrp1e fpga loader --- host/include/uhd/usrp/usrp1e.hpp | 6 + host/lib/CMakeLists.txt | 21 ++- host/lib/usrp/usrp1e/fpga-downloader.cc | 262 ++++++++++++++++++++++++++++++++ host/lib/usrp/usrp1e/usrp1e_none.cpp | 4 + 4 files changed, 288 insertions(+), 5 deletions(-) create mode 100644 host/lib/usrp/usrp1e/fpga-downloader.cc (limited to 'host') diff --git a/host/include/uhd/usrp/usrp1e.hpp b/host/include/uhd/usrp/usrp1e.hpp index 00748e55f..60a6a191a 100644 --- a/host/include/uhd/usrp/usrp1e.hpp +++ b/host/include/uhd/usrp/usrp1e.hpp @@ -41,6 +41,12 @@ public: * \return a device sptr to a new usrp1e */ static device::sptr make(const device_addr_t &addr); + + /*! + * Load the FPGA with an image file. + * \param bin_file the name of the fpga image file + */ + static void load_fpga(const std::string &bin_file); }; }} //namespace diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 96fba6e53..33314e729 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -41,17 +41,28 @@ SET(libuhd_sources ######################################################################## # Conditionally add the usrp1e sources ######################################################################## -INCLUDE(CheckIncludeFile) -CHECK_INCLUDE_FILE("linux/ioctl.h" HAS_LINUX_IOCTL_H) -IF(HAS_LINUX_IOCTL_H) +INCLUDE(CheckIncludeFiles) +SET(usrp1e_required_headers + linux/ioctl.h + linux/spi/spidev.h +) +CHECK_INCLUDE_FILES( + "${usrp1e_required_headers}" + HAS_USRP1E_REQUIRED_HEADERS +) + +IF(HAS_USRP1E_REQUIRED_HEADERS) + MESSAGE(STATUS "Building usrp1e support...") LIST(APPEND libuhd_sources + usrp/usrp1e/fpga-downloader.cc usrp/usrp1e/usrp1e_impl.cpp ) -ELSE(HAS_LINUX_IOCTL_H) +ELSE(HAS_USRP1E_REQUIRED_HEADERS) + MESSAGE(STATUS "Skipping usrp1e support...") LIST(APPEND libuhd_sources usrp/usrp1e/usrp1e_none.cpp ) -ENDIF(HAS_LINUX_IOCTL_H) +ENDIF(HAS_USRP1E_REQUIRED_HEADERS) ######################################################################## # Setup libuhd library diff --git a/host/lib/usrp/usrp1e/fpga-downloader.cc b/host/lib/usrp/usrp1e/fpga-downloader.cc new file mode 100644 index 000000000..15023d945 --- /dev/null +++ b/host/lib/usrp/usrp1e/fpga-downloader.cc @@ -0,0 +1,262 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* + * Configuration connections + * + * CCK - MCSPI1_CLK + * DIN - MCSPI1_MOSI + * PROG_B - GPIO_175 - output (change mux) + * DONE - GPIO_173 - input (change mux) + * INIT_B - GPIO_114 - input (change mux) + * +*/ + +const unsigned int PROG_B = 175; +const unsigned int DONE = 173; +const unsigned int INIT_B = 114; + +static std::string bit_file = "safe_u1e.bin"; + +const int BUF_SIZE = 4096; + +enum gpio_direction {IN, OUT}; + +class gpio { + public: + + gpio(unsigned int gpio_num, gpio_direction pin_direction); + + bool get_value(); + void set_value(bool state); + + private: + + std::stringstream base_path; + std::fstream value_file; +}; + +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) +{ + std::fstream export_file; + + 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::fstream direction_file; + 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; +} + +static void prepare_fpga_for_configuration(gpio &prog, gpio &)//init) +{ + + prog.set_value(true); + prog.set_value(false); + prog.set_value(true); + +#if 0 + bool ready_to_program(false); + unsigned int count(0); + do { + ready_to_program = init.get_value(); + count++; + + sleep(1); + } while (count < 10 && !ready_to_program); + + if (count == 10) { + std::cout << "FPGA not ready for programming." << std::endl; + exit(-1); + } +#endif +} + +spidev::spidev(std::string fname) +{ + int ret; + int mode = 0; + int speed = 12000000; + int bits = 8; + + 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 = 48000000; + tr.bits_per_word = 8; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + +} + +static void send_file_to_fpga(std::string &file_name, gpio &error, gpio &done) +{ + std::ifstream bitstream; + + std::cout << "File name - " << file_name.c_str() << std::endl; + + bitstream.open(file_name.c_str(), std::ios::binary); + if (!bitstream.is_open()) + std::cout << "File " << file_name << " not opened succesfully." << std::endl; + + spidev spi("/dev/spidev1.0"); + char buf[BUF_SIZE]; + char rbuf[BUF_SIZE]; + + do { + bitstream.read(buf, BUF_SIZE); + spi.send(buf, rbuf, bitstream.gcount()); + + if (error.get_value()) + std::cout << "INIT_B went high, error occured." << std::endl; + + if (!done.get_value()) + std::cout << "Configuration complete." << std::endl; + + } while (bitstream.gcount() == BUF_SIZE); +} + +/* +int main(int argc, char *argv[]) +{ + + gpio gpio_prog_b(PROG_B, OUT); + gpio gpio_init_b(INIT_B, IN); + gpio gpio_done (DONE, IN); + + if (argc == 2) + bit_file = argv[1]; + + std::cout << "FPGA config file: " << bit_file << std::endl; + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "Done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bit_file, gpio_init_b, gpio_done); +} +*/ + +#include +void uhd::usrp::usrp1e::load_fpga(const std::string &bin_file){ + gpio gpio_prog_b(PROG_B, OUT); + gpio gpio_init_b(INIT_B, IN); + gpio gpio_done (DONE, IN); + + std::cout << "FPGA config file: " << bin_file << std::endl; + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "Done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bit_file, gpio_init_b, gpio_done); +} diff --git a/host/lib/usrp/usrp1e/usrp1e_none.cpp b/host/lib/usrp/usrp1e/usrp1e_none.cpp index 1c8cf9a5b..ac0b12a75 100644 --- a/host/lib/usrp/usrp1e/usrp1e_none.cpp +++ b/host/lib/usrp/usrp1e/usrp1e_none.cpp @@ -32,3 +32,7 @@ device_addrs_t usrp1e::discover(const device_addr_t &){ device::sptr usrp1e::make(const device_addr_t &){ throw std::runtime_error("this build has no usrp1e support"); } + +void usrp1e::load_fpga(const std::string &){ + throw std::runtime_error("this build has no usrp1e support"); +} -- cgit v1.2.3 From 1b965831ae7588c7879d84de4e5fbd78ca614761 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 26 Feb 2010 11:01:19 +0000 Subject: made app to load usrp1e fpga images, and tested it to be working --- host/apps/CMakeLists.txt | 4 ++- host/apps/usrp1e_load_fpga.cpp | 47 +++++++++++++++++++++++++++++++++ host/lib/usrp/usrp1e/fpga-downloader.cc | 6 ++--- 3 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 host/apps/usrp1e_load_fpga.cpp (limited to 'host') diff --git a/host/apps/CMakeLists.txt b/host/apps/CMakeLists.txt index f4428f958..a7068e5a4 100644 --- a/host/apps/CMakeLists.txt +++ b/host/apps/CMakeLists.txt @@ -16,7 +16,9 @@ # ADD_EXECUTABLE(discover_usrps discover_usrps.cpp) - TARGET_LINK_LIBRARIES(discover_usrps uhd) +ADD_EXECUTABLE(usrp1e_load_fpga usrp1e_load_fpga.cpp) +TARGET_LINK_LIBRARIES(usrp1e_load_fpga uhd) + INSTALL(TARGETS discover_usrps RUNTIME DESTINATION ${RUNTIME_DIR}) diff --git a/host/apps/usrp1e_load_fpga.cpp b/host/apps/usrp1e_load_fpga.cpp new file mode 100644 index 000000000..d5960b391 --- /dev/null +++ b/host/apps/usrp1e_load_fpga.cpp @@ -0,0 +1,47 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include +#include + +namespace po = boost::program_options; + +int main(int argc, char *argv[]){ + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("file", po::value(), "path to fpga bin file") + ; + + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help") or vm.count("file") == 0){ + std::cout << boost::format("USRP1E Load FPGA %s") % desc << std::endl; + return ~0; + } + + //load the fpga + std::string file = vm["file"].as(); + uhd::usrp::usrp1e::load_fpga(file); + + return 0; +} diff --git a/host/lib/usrp/usrp1e/fpga-downloader.cc b/host/lib/usrp/usrp1e/fpga-downloader.cc index 15023d945..f7c78b875 100644 --- a/host/lib/usrp/usrp1e/fpga-downloader.cc +++ b/host/lib/usrp/usrp1e/fpga-downloader.cc @@ -43,7 +43,7 @@ const unsigned int PROG_B = 175; const unsigned int DONE = 173; const unsigned int INIT_B = 114; -static std::string bit_file = "safe_u1e.bin"; +//static std::string bit_file = "safe_u1e.bin"; const int BUF_SIZE = 4096; @@ -198,7 +198,7 @@ void spidev::send(char *buf, char *rbuf, unsigned int nbytes) } -static void send_file_to_fpga(std::string &file_name, gpio &error, gpio &done) +static void send_file_to_fpga(const std::string &file_name, gpio &error, gpio &done) { std::ifstream bitstream; @@ -258,5 +258,5 @@ void uhd::usrp::usrp1e::load_fpga(const std::string &bin_file){ std::cout << "Done = " << gpio_done.get_value() << std::endl; - send_file_to_fpga(bit_file, gpio_init_b, gpio_done); + send_file_to_fpga(bin_file, gpio_init_b, gpio_done); } -- cgit v1.2.3 From e273ea92d83d46ca350ac07e3d836a4d99b106c2 Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Mon, 8 Mar 2010 16:13:06 -0800 Subject: proper flags bits --- host/apps/omap_debug/set_debug_pins.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/set_debug_pins.py b/host/apps/omap_debug/set_debug_pins.py index d67cc3e58..20071db6b 100755 --- a/host/apps/omap_debug/set_debug_pins.py +++ b/host/apps/omap_debug/set_debug_pins.py @@ -3,12 +3,12 @@ import os # Memory Map -misc_base = 0 -uart_base = 1 -spi_base = 2 -i2c_base = 3 -gpio_base = 4 -settings_base = 5 +misc_base = 0 << 7 +uart_base = 1 << 7 +spi_base = 2 << 7 +i2c_base = 3 << 7 +gpio_base = 4 << 7 +settings_base = 5 << 7 # GPIO offset gpio_pins = 0 -- cgit v1.2.3 From 10ee8022dd22f13f942d8bfeeca3b380224fff52 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 18 Mar 2010 19:38:06 +0000 Subject: added usrp1e implementation skeleton, began filling it in... --- host/include/uhd/usrp/dboard_id.hpp | 3 +- host/lib/CMakeLists.txt | 4 + host/lib/usrp/usrp1e/dboard_impl.cpp | 76 +++++++++++++++++ host/lib/usrp/usrp1e/dboard_interface.cpp | 135 ++++++++++++++++++++++++++++++ host/lib/usrp/usrp1e/dsp_impl.cpp | 63 ++++++++++++++ host/lib/usrp/usrp1e/mboard_impl.cpp | 42 ++++++++++ host/lib/usrp/usrp1e/usrp1e_impl.cpp | 33 ++++++++ host/lib/usrp/usrp1e/usrp1e_impl.hpp | 97 +++++++++++++++++++++ 8 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 host/lib/usrp/usrp1e/dboard_impl.cpp create mode 100644 host/lib/usrp/usrp1e/dboard_interface.cpp create mode 100644 host/lib/usrp/usrp1e/dsp_impl.cpp create mode 100644 host/lib/usrp/usrp1e/mboard_impl.cpp (limited to 'host') diff --git a/host/include/uhd/usrp/dboard_id.hpp b/host/include/uhd/usrp/dboard_id.hpp index 62c61661c..370cd1fbb 100644 --- a/host/include/uhd/usrp/dboard_id.hpp +++ b/host/include/uhd/usrp/dboard_id.hpp @@ -25,9 +25,10 @@ namespace uhd{ namespace usrp{ typedef boost::uint16_t dboard_id_t; -static const dboard_id_t ID_NONE = 0xffff; +static const dboard_id_t ID_NONE = 0xffff; //TODO: REMOVE ME namespace dboard_id{ + static const dboard_id_t NONE = 0xffff; std::string to_string(const dboard_id_t &id); } diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 7d7fcbea9..e547fef85 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -63,7 +63,11 @@ CHECK_INCLUDE_FILES( IF(HAS_USRP1E_REQUIRED_HEADERS) MESSAGE(STATUS "Building usrp1e support...") LIST(APPEND libuhd_sources + usrp/usrp1e/dboard_impl.cpp + usrp/usrp1e/dboard_interface.cpp + usrp/usrp1e/dsp_impl.cpp usrp/usrp1e/fpga-downloader.cc + usrp/usrp1e/mboard_impl.cpp usrp/usrp1e/usrp1e_impl.cpp ) ELSE(HAS_USRP1E_REQUIRED_HEADERS) diff --git a/host/lib/usrp/usrp1e/dboard_impl.cpp b/host/lib/usrp/usrp1e/dboard_impl.cpp new file mode 100644 index 000000000..7d46366bc --- /dev/null +++ b/host/lib/usrp/usrp1e/dboard_impl.cpp @@ -0,0 +1,76 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include "usrp1e_impl.hpp" + +using namespace uhd::usrp; + +/*********************************************************************** + * Dboard Initialization + **********************************************************************/ +void usrp1e_impl::dboard_init(void){ + dboard_id_t rx_dboard_id = dboard_id::NONE; //TODO get these from the eeprom + dboard_id_t tx_dboard_id = dboard_id::NONE; + + //create a new dboard interface and manager + dboard_interface::sptr dboard_interface( + make_usrp1e_dboard_interface(this) + ); + _dboard_manager = dboard_manager::make( + rx_dboard_id, tx_dboard_id, dboard_interface + ); + + //setup the dboard proxies + _rx_dboard_proxy = wax_obj_proxy( + boost::bind(&usrp1e_impl::rx_dboard_get, this, _1, _2), + boost::bind(&usrp1e_impl::rx_dboard_set, this, _1, _2) + ); + _tx_dboard_proxy = wax_obj_proxy( + boost::bind(&usrp1e_impl::tx_dboard_get, this, _1, _2), + boost::bind(&usrp1e_impl::tx_dboard_set, this, _1, _2) + ); +} + +/*********************************************************************** + * RX Dboard Get + **********************************************************************/ +void usrp1e_impl::rx_dboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * RX Dboard Set + **********************************************************************/ +void usrp1e_impl::rx_dboard_set(const wax::obj &, const wax::obj &){ + +} + +/*********************************************************************** + * TX Dboard Get + **********************************************************************/ +void usrp1e_impl::tx_dboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * TX Dboard Set + **********************************************************************/ +void usrp1e_impl::tx_dboard_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp1e/dboard_interface.cpp b/host/lib/usrp/usrp1e/dboard_interface.cpp new file mode 100644 index 000000000..b3e06f7be --- /dev/null +++ b/host/lib/usrp/usrp1e/dboard_interface.cpp @@ -0,0 +1,135 @@ +// +// Copyright 2010 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 . +// + +#include +#include "usrp1e_impl.hpp" + +using namespace uhd::usrp; + +class usrp1e_dboard_interface : public dboard_interface{ +public: + usrp1e_dboard_interface(usrp1e_impl *impl); + ~usrp1e_dboard_interface(void); + + void write_aux_dac(unit_type_t, int, int); + int read_aux_adc(unit_type_t, int); + + void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t); + void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t); + void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t); + boost::uint16_t read_gpio(gpio_bank_t); + + void write_i2c(int, const byte_vector_t &); + byte_vector_t read_i2c(int, size_t); + + double get_rx_clock_rate(void); + double get_tx_clock_rate(void); + +private: + byte_vector_t transact_spi( + spi_dev_t dev, + spi_latch_t latch, + spi_push_t push, + const byte_vector_t &buf, + bool readback + ); + + usrp1e_impl *_impl; +}; + +/*********************************************************************** + * Make Function + **********************************************************************/ +dboard_interface::sptr make_usrp1e_dboard_interface(usrp1e_impl *impl){ + return dboard_interface::sptr(new usrp1e_dboard_interface(impl)); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp1e_dboard_interface::usrp1e_dboard_interface(usrp1e_impl *impl){ + _impl = impl; +} + +usrp1e_dboard_interface::~usrp1e_dboard_interface(void){ + /* NOP */ +} + +/*********************************************************************** + * Clock Rates + **********************************************************************/ +double usrp1e_dboard_interface::get_rx_clock_rate(void){ + throw std::runtime_error("not implemented"); +} + +double usrp1e_dboard_interface::get_tx_clock_rate(void){ + throw std::runtime_error("not implemented"); +} + +/*********************************************************************** + * GPIO + **********************************************************************/ +void usrp1e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ + throw std::runtime_error("not implemented"); +} + +void usrp1e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ + throw std::runtime_error("not implemented"); +} + +boost::uint16_t usrp1e_dboard_interface::read_gpio(gpio_bank_t bank){ + throw std::runtime_error("not implemented"); +} + +void usrp1e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){ + throw std::runtime_error("not implemented"); +} + +/*********************************************************************** + * SPI + **********************************************************************/ +dboard_interface::byte_vector_t usrp1e_dboard_interface::transact_spi( + spi_dev_t dev, + spi_latch_t latch, + spi_push_t push, + const byte_vector_t &buf, + bool readback +){ + throw std::runtime_error("not implemented"); +} + +/*********************************************************************** + * I2C + **********************************************************************/ +void usrp1e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ + throw std::runtime_error("not implemented"); +} + +dboard_interface::byte_vector_t usrp1e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){ + throw std::runtime_error("not implemented"); +} + +/*********************************************************************** + * Aux DAX/ADC + **********************************************************************/ +void usrp1e_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){ + throw std::runtime_error("not implemented"); +} + +int usrp1e_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){ + throw std::runtime_error("not implemented"); +} diff --git a/host/lib/usrp/usrp1e/dsp_impl.cpp b/host/lib/usrp/usrp1e/dsp_impl.cpp new file mode 100644 index 000000000..b6076ef97 --- /dev/null +++ b/host/lib/usrp/usrp1e/dsp_impl.cpp @@ -0,0 +1,63 @@ +// +// Copyright 2010 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 . +// + +#include +#include "usrp1e_impl.hpp" + +using namespace uhd::usrp; + +/*********************************************************************** + * RX DDC Initialization + **********************************************************************/ +void usrp1e_impl::rx_ddc_init(void){ + +} + +/*********************************************************************** + * RX DDC Get + **********************************************************************/ +void usrp1e_impl::rx_ddc_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * RX DDC Set + **********************************************************************/ +void usrp1e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){ + +} + +/*********************************************************************** + * TX DUC Initialization + **********************************************************************/ +void usrp1e_impl::tx_duc_init(void){ + +} + +/*********************************************************************** + * TX DUC Get + **********************************************************************/ +void usrp1e_impl::tx_duc_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * TX DUC Set + **********************************************************************/ +void usrp1e_impl::tx_duc_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp1e/mboard_impl.cpp b/host/lib/usrp/usrp1e/mboard_impl.cpp new file mode 100644 index 000000000..c79ed1820 --- /dev/null +++ b/host/lib/usrp/usrp1e/mboard_impl.cpp @@ -0,0 +1,42 @@ +// +// Copyright 2010 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 . +// + +#include +#include "usrp1e_impl.hpp" + +using namespace uhd::usrp; + +/*********************************************************************** + * Mboard Initialization + **********************************************************************/ +void usrp1e_impl::mboard_init(void){ + +} + +/*********************************************************************** + * Mboard Get + **********************************************************************/ +void usrp1e_impl::mboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * Mboard Set + **********************************************************************/ +void usrp1e_impl::mboard_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.cpp b/host/lib/usrp/usrp1e/usrp1e_impl.cpp index 441f6d060..14c4b7278 100644 --- a/host/lib/usrp/usrp1e/usrp1e_impl.cpp +++ b/host/lib/usrp/usrp1e/usrp1e_impl.cpp @@ -70,3 +70,36 @@ device_addrs_t usrp1e::discover(const device_addr_t &device_addr){ device::sptr usrp1e::make(const device_addr_t &){ throw std::runtime_error("not implemented yet"); } + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp1e_impl::usrp1e_impl(void){ + //initialize the mboard + mboard_init(); + + //initialize the dboards + dboard_init(); + + //initialize the dsps + rx_ddc_init(); + tx_duc_init(); +} + +usrp1e_impl::~usrp1e_impl(void){ + /* NOP */ +} + +/*********************************************************************** + * Device Get + **********************************************************************/ +void usrp1e_impl::get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * Device Set + **********************************************************************/ +void usrp1e_impl::set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.hpp b/host/lib/usrp/usrp1e/usrp1e_impl.hpp index 3f5f89ec6..3b2fcdd57 100644 --- a/host/lib/usrp/usrp1e/usrp1e_impl.hpp +++ b/host/lib/usrp/usrp1e/usrp1e_impl.hpp @@ -16,8 +16,105 @@ // #include +#include #ifndef INCLUDED_USRP1E_IMPL_HPP #define INCLUDED_USRP1E_IMPL_HPP +class usrp1e_impl; // dummy class declaration + +/*! + * Make a usrp1e dboard interface. + * \param impl a pointer to the usrp1e impl object + * \return a sptr to a new dboard interface + */ +uhd::usrp::dboard_interface::sptr make_usrp1e_dboard_interface(usrp1e_impl *impl); + +/*! + * Simple wax obj proxy class: + * Provides a wax obj interface for a set and a get function. + * This allows us to create nested properties structures + * while maintaining flattened code within the implementation. + */ +class wax_obj_proxy : public wax::obj{ +public: + typedef boost::function get_t; + typedef boost::function set_t; + + wax_obj_proxy(void){ + /* NOP */ + } + + wax_obj_proxy(const get_t &get, const set_t &set){ + _get = get; + _set = set; + }; + + ~wax_obj_proxy(void){ + /* NOP */ + } + + void get(const wax::obj &key, wax::obj &val){ + return _get(key, val); + } + + void set(const wax::obj &key, const wax::obj &val){ + return _set(key, val); + } + +private: + get_t _get; + set_t _set; +}; + +/*! + * USRP1E implementation guts: + * The implementation details are encapsulated here. + * Handles properties on the mboard, dboard, dsps... + */ +class usrp1e_impl : public uhd::device{ +public: + typedef boost::shared_ptr sptr; + + usrp1e_impl(void); + ~usrp1e_impl(void); + +private: + //device functions and settings + void get(const wax::obj &, wax::obj &); + void set(const wax::obj &, const wax::obj &); + + //mboard functions and settings + void mboard_init(void); + void mboard_get(const wax::obj &, wax::obj &); + void mboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy _mboard_proxy; + + //xx dboard functions and settings + void dboard_init(void); + uhd::usrp::dboard_manager::sptr _dboard_manager; + + //rx dboard functions and settings + void rx_dboard_get(const wax::obj &, wax::obj &); + void rx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy _rx_dboard_proxy; + + //tx dboard functions and settings + void tx_dboard_get(const wax::obj &, wax::obj &); + void tx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy _tx_dboard_proxy; + + //rx ddc functions and settings + void rx_ddc_init(void); + void rx_ddc_get(const wax::obj &, wax::obj &); + void rx_ddc_set(const wax::obj &, const wax::obj &); + wax_obj_proxy _rx_ddc_proxy; + + //tx duc functions and settings + void tx_duc_init(void); + void tx_duc_get(const wax::obj &, wax::obj &); + void tx_duc_set(const wax::obj &, const wax::obj &); + wax_obj_proxy _tx_duc_proxy; +}; + #endif /* INCLUDED_USRP1E_IMPL_HPP */ -- cgit v1.2.3 From a31761cb0c37b61f7243836d6dd8c40cbf49efc0 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 22 Mar 2010 13:12:03 +0000 Subject: filled in more skeleton code, filled in dboard interface spi and i2c with ioctls, added file descriptor opening, and checking for usrp1 kernel header --- host/lib/CMakeLists.txt | 1 + host/lib/usrp/usrp1e/dboard_impl.cpp | 4 +- host/lib/usrp/usrp1e/dboard_interface.cpp | 60 +++++++++++++++++++++-- host/lib/usrp/usrp1e/dsp_impl.cpp | 11 ++++- host/lib/usrp/usrp1e/mboard_impl.cpp | 6 ++- host/lib/usrp/usrp1e/usrp1e_impl.cpp | 79 ++++++++++++++++++++++++++----- host/lib/usrp/usrp1e/usrp1e_impl.hpp | 48 ++++++++++++------- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 - 8 files changed, 172 insertions(+), 39 deletions(-) (limited to 'host') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index a7dded86b..46cce729e 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -56,6 +56,7 @@ INCLUDE(CheckIncludeFiles) SET(usrp1e_required_headers linux/ioctl.h linux/spi/spidev.h + linux/usrp1_e.h ) CHECK_INCLUDE_FILES( "${usrp1e_required_headers}" diff --git a/host/lib/usrp/usrp1e/dboard_impl.cpp b/host/lib/usrp/usrp1e/dboard_impl.cpp index 7d46366bc..a2798dce3 100644 --- a/host/lib/usrp/usrp1e/dboard_impl.cpp +++ b/host/lib/usrp/usrp1e/dboard_impl.cpp @@ -37,11 +37,11 @@ void usrp1e_impl::dboard_init(void){ ); //setup the dboard proxies - _rx_dboard_proxy = wax_obj_proxy( + _rx_dboard_proxy = wax_obj_proxy::make( boost::bind(&usrp1e_impl::rx_dboard_get, this, _1, _2), boost::bind(&usrp1e_impl::rx_dboard_set, this, _1, _2) ); - _tx_dboard_proxy = wax_obj_proxy( + _tx_dboard_proxy = wax_obj_proxy::make( boost::bind(&usrp1e_impl::tx_dboard_get, this, _1, _2), boost::bind(&usrp1e_impl::tx_dboard_set, this, _1, _2) ); diff --git a/host/lib/usrp/usrp1e/dboard_interface.cpp b/host/lib/usrp/usrp1e/dboard_interface.cpp index b3e06f7be..ef91014ac 100644 --- a/host/lib/usrp/usrp1e/dboard_interface.cpp +++ b/host/lib/usrp/usrp1e/dboard_interface.cpp @@ -16,7 +16,9 @@ // #include +#include //std::copy #include "usrp1e_impl.hpp" +#include using namespace uhd::usrp; @@ -109,18 +111,70 @@ dboard_interface::byte_vector_t usrp1e_dboard_interface::transact_spi( const byte_vector_t &buf, bool readback ){ - throw std::runtime_error("not implemented"); + //load data struct + usrp_e_spi data; + data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; + data.slave = (dev == SPI_RX_DEV)? UE_SPI_CTRL_RXNEG : UE_SPI_CTRL_TXNEG; + data.length = buf.size() * 8; //bytes to bits + boost::uint8_t *data_bytes = reinterpret_cast(&data.data); + + //load the data + ASSERT_THROW(buf.size() <= sizeof(data.data)); + std::copy(buf.begin(), buf.end(), data_bytes); + + //load the flags + data.flags = 0; + data.flags |= (latch == SPI_LATCH_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (push == SPI_PUSH_RISE)? UE_SPI_PUSH_RISE : UE_SPI_PUSH_FALL; + + //call the spi ioctl + _impl->ioctl(USRP_E_SPI, &data); + + //unload the data + byte_vector_t ret(data.length/8); //bits to bytes + ASSERT_THROW(ret.size() <= sizeof(data.data)); + std::copy(data_bytes, data_bytes+ret.size(), ret.begin()); + return ret; } /*********************************************************************** * I2C **********************************************************************/ +static const size_t max_i2c_data_bytes = 10; + void usrp1e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ - throw std::runtime_error("not implemented"); + //allocate some memory for this transaction + ASSERT_THROW(buf.size() <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c &data = reinterpret_cast(mem); + data.addr = i2c_addr; + data.len = buf.size(); + std::copy(buf.begin(), buf.end(), data.data); + + //call the spi ioctl + _impl->ioctl(USRP_E_I2C_WRITE, &data); } dboard_interface::byte_vector_t usrp1e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){ - throw std::runtime_error("not implemented"); + //allocate some memory for this transaction + ASSERT_THROW(num_bytes <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c &data = reinterpret_cast(mem); + data.addr = i2c_addr; + data.len = num_bytes; + + //call the spi ioctl + _impl->ioctl(USRP_E_I2C_READ, &data); + + //unload the data + byte_vector_t ret(data.len); + ASSERT_THROW(ret.size() == num_bytes); + std::copy(data.data, data.data+ret.size(), ret.begin()); + return ret; } /*********************************************************************** diff --git a/host/lib/usrp/usrp1e/dsp_impl.cpp b/host/lib/usrp/usrp1e/dsp_impl.cpp index b6076ef97..862b89184 100644 --- a/host/lib/usrp/usrp1e/dsp_impl.cpp +++ b/host/lib/usrp/usrp1e/dsp_impl.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // +#include #include #include "usrp1e_impl.hpp" @@ -24,7 +25,10 @@ using namespace uhd::usrp; * RX DDC Initialization **********************************************************************/ void usrp1e_impl::rx_ddc_init(void){ - + _rx_ddc_proxy = wax_obj_proxy::make( + boost::bind(&usrp1e_impl::rx_ddc_get, this, _1, _2), + boost::bind(&usrp1e_impl::rx_ddc_set, this, _1, _2) + ); } /*********************************************************************** @@ -45,7 +49,10 @@ void usrp1e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){ * TX DUC Initialization **********************************************************************/ void usrp1e_impl::tx_duc_init(void){ - + _tx_duc_proxy = wax_obj_proxy::make( + boost::bind(&usrp1e_impl::tx_duc_get, this, _1, _2), + boost::bind(&usrp1e_impl::tx_duc_set, this, _1, _2) + ); } /*********************************************************************** diff --git a/host/lib/usrp/usrp1e/mboard_impl.cpp b/host/lib/usrp/usrp1e/mboard_impl.cpp index c79ed1820..b480f7616 100644 --- a/host/lib/usrp/usrp1e/mboard_impl.cpp +++ b/host/lib/usrp/usrp1e/mboard_impl.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // +#include #include #include "usrp1e_impl.hpp" @@ -24,7 +25,10 @@ using namespace uhd::usrp; * Mboard Initialization **********************************************************************/ void usrp1e_impl::mboard_init(void){ - + _mboard_proxy = wax_obj_proxy::make( + boost::bind(&usrp1e_impl::mboard_get, this, _1, _2), + boost::bind(&usrp1e_impl::mboard_set, this, _1, _2) + ); } /*********************************************************************** diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.cpp b/host/lib/usrp/usrp1e/usrp1e_impl.cpp index 14c4b7278..d3b0264a7 100644 --- a/host/lib/usrp/usrp1e/usrp1e_impl.cpp +++ b/host/lib/usrp/usrp1e/usrp1e_impl.cpp @@ -19,9 +19,12 @@ #include #include #include "usrp1e_impl.hpp" +#include //open +#include //ioctl using namespace uhd; using namespace uhd::usrp; +namespace fs = boost::filesystem; STATIC_BLOCK(register_usrp1e_device){ device::register_device(&usrp1e::discover, &usrp1e::make); @@ -30,8 +33,8 @@ STATIC_BLOCK(register_usrp1e_device){ /*********************************************************************** * Helper Functions **********************************************************************/ -static bool file_exists(const std::string &file_path){ - return boost::filesystem::exists(file_path); +static std::string abs_path(const std::string &file_path){ + return fs::system_complete(fs::path(file_path)).file_string(); } /*********************************************************************** @@ -42,10 +45,10 @@ device_addrs_t usrp1e::discover(const device_addr_t &device_addr){ //if a node was provided, use it and only it if (device_addr.has_key("node")){ - if (not file_exists(device_addr["node"])) return usrp1e_addrs; + if (not fs::exists(device_addr["node"])) return usrp1e_addrs; device_addr_t new_addr; new_addr["name"] = "USRP1E"; - new_addr["node"] = device_addr["node"]; + new_addr["node"] = abs_path(device_addr["node"]); usrp1e_addrs.push_back(new_addr); } @@ -53,10 +56,10 @@ device_addrs_t usrp1e::discover(const device_addr_t &device_addr){ else{ for(size_t i = 0; i < 5; i++){ std::string node = str(boost::format("/dev/usrp1_e%d") % i); - if (not file_exists(node)) continue; + if (not fs::exists(node)) continue; device_addr_t new_addr; new_addr["name"] = "USRP1E"; - new_addr["node"] = node; + new_addr["node"] = abs_path(node); usrp1e_addrs.push_back(new_addr); } } @@ -67,14 +70,23 @@ device_addrs_t usrp1e::discover(const device_addr_t &device_addr){ /*********************************************************************** * Make **********************************************************************/ -device::sptr usrp1e::make(const device_addr_t &){ - throw std::runtime_error("not implemented yet"); +device::sptr usrp1e::make(const device_addr_t &device_addr){ + std::string node = device_addr["node"]; + int node_fd = open(node.c_str(), 0); + if (node_fd < 0){ + throw std::runtime_error(str( + boost::format("Failed to open %s") % node + )); + } + return sptr(new usrp1e_impl(node_fd)); } /*********************************************************************** * Structors **********************************************************************/ -usrp1e_impl::usrp1e_impl(void){ +usrp1e_impl::usrp1e_impl(int node_fd){ + _node_fd = node_fd; + //initialize the mboard mboard_init(); @@ -90,16 +102,59 @@ usrp1e_impl::~usrp1e_impl(void){ /* NOP */ } +/*********************************************************************** + * Misc Methods + **********************************************************************/ +void usrp1e_impl::ioctl(int request, void *mem){ + if (::ioctl(_node_fd, request, mem) < 0){ + throw std::runtime_error(str( + boost::format("ioctl failed with request %d") % request + )); + } +} + /*********************************************************************** * Device Get **********************************************************************/ -void usrp1e_impl::get(const wax::obj &, wax::obj &){ - +void usrp1e_impl::get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case DEVICE_PROP_NAME: + val = std::string("usrp1e device"); + return; + + case DEVICE_PROP_MBOARD: + ASSERT_THROW(name == ""); + val = _mboard_proxy->get_link(); + return; + + case DEVICE_PROP_MBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + case DEVICE_PROP_MAX_RX_SAMPLES: + val = size_t(0); //TODO + return; + + case DEVICE_PROP_MAX_TX_SAMPLES: + val = size_t(0); //TODO + return; + + } } /*********************************************************************** * Device Set **********************************************************************/ void usrp1e_impl::set(const wax::obj &, const wax::obj &){ - + throw std::runtime_error("Cannot set in usrp1e device"); } + +/*********************************************************************** + * Device IO (TODO) + **********************************************************************/ +size_t usrp1e_impl::send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const std::string &){return 0;} +size_t usrp1e_impl::recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &){return 0;} diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.hpp b/host/lib/usrp/usrp1e/usrp1e_impl.hpp index 3b2fcdd57..7a09254ec 100644 --- a/host/lib/usrp/usrp1e/usrp1e_impl.hpp +++ b/host/lib/usrp/usrp1e/usrp1e_impl.hpp @@ -40,20 +40,25 @@ class wax_obj_proxy : public wax::obj{ public: typedef boost::function get_t; typedef boost::function set_t; + typedef boost::shared_ptr sptr; - wax_obj_proxy(void){ + static sptr make(const get_t &get, const set_t &set){ + return sptr(new wax_obj_proxy(get, set)); + } + + ~wax_obj_proxy(void){ /* NOP */ } +private: + get_t _get; + set_t _set; + wax_obj_proxy(const get_t &get, const set_t &set){ _get = get; _set = set; }; - ~wax_obj_proxy(void){ - /* NOP */ - } - void get(const wax::obj &key, wax::obj &val){ return _get(key, val); } @@ -61,10 +66,6 @@ public: void set(const wax::obj &key, const wax::obj &val){ return _set(key, val); } - -private: - get_t _get; - set_t _set; }; /*! @@ -74,12 +75,25 @@ private: */ class usrp1e_impl : public uhd::device{ public: - typedef boost::shared_ptr sptr; - - usrp1e_impl(void); + //structors + usrp1e_impl(int node_fd); ~usrp1e_impl(void); + //the io interface + size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const std::string &); + size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &); + + /*! + * Perform an ioctl call on the device node file descriptor. + * This will throw when the internal ioctl call fails. + * \param request the control word + * \param mem pointer to some memory + */ + void ioctl(int request, void *mem); + private: + int _node_fd; + //device functions and settings void get(const wax::obj &, wax::obj &); void set(const wax::obj &, const wax::obj &); @@ -88,7 +102,7 @@ private: void mboard_init(void); void mboard_get(const wax::obj &, wax::obj &); void mboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy _mboard_proxy; + wax_obj_proxy::sptr _mboard_proxy; //xx dboard functions and settings void dboard_init(void); @@ -97,24 +111,24 @@ private: //rx dboard functions and settings void rx_dboard_get(const wax::obj &, wax::obj &); void rx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy _rx_dboard_proxy; + wax_obj_proxy::sptr _rx_dboard_proxy; //tx dboard functions and settings void tx_dboard_get(const wax::obj &, wax::obj &); void tx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy _tx_dboard_proxy; + wax_obj_proxy::sptr _tx_dboard_proxy; //rx ddc functions and settings void rx_ddc_init(void); void rx_ddc_get(const wax::obj &, wax::obj &); void rx_ddc_set(const wax::obj &, const wax::obj &); - wax_obj_proxy _rx_ddc_proxy; + wax_obj_proxy::sptr _rx_ddc_proxy; //tx duc functions and settings void tx_duc_init(void); void tx_duc_get(const wax::obj &, wax::obj &); void tx_duc_set(const wax::obj &, const wax::obj &); - wax_obj_proxy _tx_duc_proxy; + wax_obj_proxy::sptr _tx_duc_proxy; }; #endif /* INCLUDED_USRP1E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 70420fd49..55ac0b192 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -86,8 +86,6 @@ private: */ class usrp2_impl : public uhd::device{ public: - typedef boost::shared_ptr sptr; - /*! * Create a new usrp2 impl base. * \param ctrl_transport the udp transport for control -- cgit v1.2.3 From 09a21dd6d4bc5b7f032e07cfabcba9f55d25b0f6 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 22 Mar 2010 15:31:16 +0000 Subject: bit of io work --- host/lib/usrp/usrp1e/usrp1e_impl.cpp | 48 +++++++++++++++++++++++++----------- host/lib/usrp/usrp1e/usrp1e_impl.hpp | 3 ++- 2 files changed, 35 insertions(+), 16 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.cpp b/host/lib/usrp/usrp1e/usrp1e_impl.cpp index d3b0264a7..8230cc8e4 100644 --- a/host/lib/usrp/usrp1e/usrp1e_impl.cpp +++ b/host/lib/usrp/usrp1e/usrp1e_impl.cpp @@ -71,21 +71,19 @@ device_addrs_t usrp1e::discover(const device_addr_t &device_addr){ * Make **********************************************************************/ device::sptr usrp1e::make(const device_addr_t &device_addr){ - std::string node = device_addr["node"]; - int node_fd = open(node.c_str(), 0); - if (node_fd < 0){ - throw std::runtime_error(str( - boost::format("Failed to open %s") % node - )); - } - return sptr(new usrp1e_impl(node_fd)); + return sptr(new usrp1e_impl(device_addr["node"])); } /*********************************************************************** * Structors **********************************************************************/ -usrp1e_impl::usrp1e_impl(int node_fd){ - _node_fd = node_fd; +usrp1e_impl::usrp1e_impl(const std::string &node){ + //open the device node and check file descriptor + if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ + throw std::runtime_error(str( + boost::format("Failed to open %s") % node + )); + } //initialize the mboard mboard_init(); @@ -99,7 +97,8 @@ usrp1e_impl::usrp1e_impl(int node_fd){ } usrp1e_impl::~usrp1e_impl(void){ - /* NOP */ + //close the device node file descriptor + ::close(_node_fd); } /*********************************************************************** @@ -136,11 +135,11 @@ void usrp1e_impl::get(const wax::obj &key_, wax::obj &val){ return; case DEVICE_PROP_MAX_RX_SAMPLES: - val = size_t(0); //TODO + val = size_t(_max_num_samples); return; case DEVICE_PROP_MAX_TX_SAMPLES: - val = size_t(0); //TODO + val = size_t(_max_num_samples); return; } @@ -156,5 +155,24 @@ void usrp1e_impl::set(const wax::obj &, const wax::obj &){ /*********************************************************************** * Device IO (TODO) **********************************************************************/ -size_t usrp1e_impl::send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const std::string &){return 0;} -size_t usrp1e_impl::recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &){return 0;} +size_t usrp1e_impl::send( + const boost::asio::const_buffer &, + const uhd::tx_metadata_t &, + const std::string &type +){ + if (type != "16sc"){ + throw std::runtime_error(str(boost::format("usrp1e send: cannot handle type \"%s\"") % type)); + } + return 0; +} + +size_t usrp1e_impl::recv( + const boost::asio::mutable_buffer &, + uhd::rx_metadata_t &, + const std::string &type +){ + if (type != "16sc"){ + throw std::runtime_error(str(boost::format("usrp1e recv: cannot handle type \"%s\"") % type)); + } + return 0; +} diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.hpp b/host/lib/usrp/usrp1e/usrp1e_impl.hpp index 7a09254ec..c199a0465 100644 --- a/host/lib/usrp/usrp1e/usrp1e_impl.hpp +++ b/host/lib/usrp/usrp1e/usrp1e_impl.hpp @@ -76,7 +76,7 @@ private: class usrp1e_impl : public uhd::device{ public: //structors - usrp1e_impl(int node_fd); + usrp1e_impl(const std::string &node); ~usrp1e_impl(void); //the io interface @@ -92,6 +92,7 @@ public: void ioctl(int request, void *mem); private: + static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); int _node_fd; //device functions and settings -- cgit v1.2.3 From 3137e2ca001176c4ffc12e091530fe23c82974b6 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 23 Mar 2010 13:38:46 +0000 Subject: Commit random test code. Unfiltered commit of test code I am accumlating on my ewewoneee. Most of this should go away before release. --- host/apps/omap_debug/fetch-bin.sh | 2 +- host/apps/omap_debug/fetch-kernel.sh | 2 +- host/apps/omap_debug/fetch-module.sh | 3 +- host/apps/omap_debug/fetch-u-boot.sh | 3 ++ host/apps/omap_debug/usrp1-e-rw.c | 97 ++++++++++++++++++++++++++++++++++++ host/apps/omap_debug/usrp1-e-spi.c | 40 +++++++++++++++ host/apps/omap_debug/usrp1-e-write.c | 4 +- host/apps/omap_debug/usrp1_e.h | 56 +++++++++++++++++++++ host/apps/omap_debug/write-eeprom.sh | 92 ++++++++++++++++++++++++++++++++++ 9 files changed, 294 insertions(+), 5 deletions(-) create mode 100755 host/apps/omap_debug/fetch-u-boot.sh create mode 100644 host/apps/omap_debug/usrp1-e-rw.c create mode 100644 host/apps/omap_debug/usrp1-e-spi.c create mode 100644 host/apps/omap_debug/usrp1_e.h create mode 100755 host/apps/omap_debug/write-eeprom.sh (limited to 'host') diff --git a/host/apps/omap_debug/fetch-bin.sh b/host/apps/omap_debug/fetch-bin.sh index 1ceec4fd2..beff7ffcd 100755 --- a/host/apps/omap_debug/fetch-bin.sh +++ b/host/apps/omap_debug/fetch-bin.sh @@ -1,2 +1,2 @@ -scp balister@192.168.1.182:Download/u1e.bin . +scp balister@astro:/workspace/usrp1-e-dev/u1e.bin . sync diff --git a/host/apps/omap_debug/fetch-kernel.sh b/host/apps/omap_debug/fetch-kernel.sh index 08b470e9b..7023f5d28 100755 --- a/host/apps/omap_debug/fetch-kernel.sh +++ b/host/apps/omap_debug/fetch-kernel.sh @@ -1,3 +1,3 @@ -scp balister@192.168.1.182:src/git/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage +scp balister@192.168.1.167:src/git/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage sync diff --git a/host/apps/omap_debug/fetch-module.sh b/host/apps/omap_debug/fetch-module.sh index 6511958f9..101ea9aef 100755 --- a/host/apps/omap_debug/fetch-module.sh +++ b/host/apps/omap_debug/fetch-module.sh @@ -1,2 +1,3 @@ -scp balister@192.168.1.182:src/git/kernel_usrp/drivers/misc/usrp1_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc +scp balister@192.168.1.167:src/git/kernel_usrp/drivers/misc/usrp1_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc +scp balister@192.168.1.167:src/git/kernel_usrp/include/linux/usrp1_e.h . sync diff --git a/host/apps/omap_debug/fetch-u-boot.sh b/host/apps/omap_debug/fetch-u-boot.sh new file mode 100755 index 000000000..63d4edcf2 --- /dev/null +++ b/host/apps/omap_debug/fetch-u-boot.sh @@ -0,0 +1,3 @@ +scp balister@astro:/workspace/usrp1-e-dev/u-boot-overo/u-boot.bin /media/mmcblk0p1/ +sync + diff --git a/host/apps/omap_debug/usrp1-e-rw.c b/host/apps/omap_debug/usrp1-e-rw.c new file mode 100644 index 000000000..cd7fbe4dd --- /dev/null +++ b/host/apps/omap_debug/usrp1-e-rw.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include + +struct pkt { + int checksum; + int seq_num; + short data[1020]; +}; + +static int fp; + +static int calc_checksum(struct pkt *p) +{ + int i, sum; + + i = 0; + sum = 0; + + for (i=0; i<1020; i++) + sum += p->data[i]; + + sum += p->seq_num; + + return sum; +} + +static void *read_thread(void *threadid) +{ + int cnt, prev_seq_num; + struct pkt rx_data; + + printf("Greetings from the reading thread!\n"); + + prev_seq_num = 0; + + while (1) { + cnt = read(fp, &rx_data, 2048); + + if (rx_data.seq_num != prev_seq_num + 1) + printf("Sequence number fail, current = %d, previous = %d\n", + rx_data.seq_num, prev_seq_num); + prev_seq_num = rx_data.seq_num; + + if (calc_checksum(&rx_data) != rx_data.checksum) + printf("Checksum fail packet = %d, expected = %d\n", + calc_checksum(&rx_data), rx_data.checksum); + } + +} + +static void *write_thread(void *threadid) +{ + int seq_number, i, cnt; + struct pkt tx_data; + + printf("Greetings from the write thread!\n"); + + for (i=0; i<1020; i++) + tx_data.data[i] = random() >> 16; + + + seq_number = 1; + + while (1) { + tx_data.seq_num = seq_number++; + tx_data.checksum = calc_checksum(&tx_data); + cnt = write(fp, &tx_data, 2048); + } +} + + +int main(int argc, char *argv[]) +{ + int ret; + pthread_t tx, rx; + long int t; + + fp = open("/dev/usrp1_e0", O_RDWR); + printf("fp = %d\n", fp); + + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { + printf("Failed to create rx thread\n"); + exit(-1); + } + + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { + printf("Failed to create tx thread\n"); + exit(-1); + } + + sleep(10000); + + printf("Done sleeping\n"); +} diff --git a/host/apps/omap_debug/usrp1-e-spi.c b/host/apps/omap_debug/usrp1-e-spi.c new file mode 100644 index 000000000..a79d74b18 --- /dev/null +++ b/host/apps/omap_debug/usrp1-e-spi.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include + +#include "usrp1_e.h" + +// Usage: usrp1_e_spi w|rb slave data + +int main(int argc, char *argv[]) +{ + int fp, slave, data, ret; + struct usrp_e_spi spi_dat; + + if (argc < 4) { + printf("Usage: usrp1_e_spi w|rb slave data\n"); + exit(-1); + } + + slave = atoi(argv[2]); + data = atoi(argv[3]); + + fp = open("/dev/usrp1_e0", O_RDWR); + printf("fp = %d\n", fp); + + spi_dat.slave = slave; + spi_dat.data = data; + spi_dat.length = 2; + spi_dat.flags = 0; + + if (*argv[1] == 'r') { + spi_dat.readback = 1; + ret = ioctl(fp, USRP_E_SPI, &spi_dat); + printf("Data returned = %d\n", ret); + } else { + spi_dat.readback = 0; + ioctl(fp, USRP_E_SPI, &spi_dat); + } +} diff --git a/host/apps/omap_debug/usrp1-e-write.c b/host/apps/omap_debug/usrp1-e-write.c index f29cc7032..903c0071f 100644 --- a/host/apps/omap_debug/usrp1-e-write.c +++ b/host/apps/omap_debug/usrp1-e-write.c @@ -14,8 +14,8 @@ int main(int rgc, char *argv[]) buf[i] = i; } - do { +// do { cnt = write(fp, buf, 2048); printf("Bytes written - %d\n", cnt); - } while (1); +// } while (1); } diff --git a/host/apps/omap_debug/usrp1_e.h b/host/apps/omap_debug/usrp1_e.h new file mode 100644 index 000000000..b49b526dc --- /dev/null +++ b/host/apps/omap_debug/usrp1_e.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 Ettus Research, LLC + * + * Written by Philip Balister + * + * 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 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __USRP_E_H +#define __USRP_E_H + +#include +#include + +struct usrp1_e_ctl { + __u32 offset; + __u32 count; + __u16 buf[]; +}; + +// SPI interface + +#define UE_SPI_TXONLY 0 +#define UE_SPI_TXRX 1 + +// Defines for spi ctrl register +#define UE_SPI_CTRL_ASS (1<<13) +#define UE_SPI_CTRL_IE (1<<12) +#define UE_SPI_CTRL_LSB (1<<11) +#define UE_SPI_CTRL_TXNEG (1<<10) +#define UE_SPI_CTRL_RXNEG (1<<9) +#define UE_SPI_CTRL_GO_BSY (1<<8) +#define UE_SPI_CTRL_CHAR_LEN_MASK 0x7f + +#define UE_SPI_PUSH_RISE 0 +#define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG +#define UE_SPI_LATCH_RISE 0 +#define UE_SPI_LATCH_FALL UE_SPI_CTRL_RXNEG + +struct usrp_e_spi { + __u8 readback; + __u32 slave; + __u32 data; + __u32 length; + __u32 flags; +}; + +#define USRP_E_IOC_MAGIC 'u' +#define USRP_E_WRITE_CTL _IOW(USRP_E_IOC_MAGIC, 0x20, struct usrp1_e_ctl) +#define USRP_E_READ_CTL _IOWR(USRP_E_IOC_MAGIC, 0x21, struct usrp1_e_ctl) +#define USRP_E_SPI _IOW(USRP_E_IOC_MAGIC, 0x22, struct usrp_e_spi) + +#endif diff --git a/host/apps/omap_debug/write-eeprom.sh b/host/apps/omap_debug/write-eeprom.sh new file mode 100755 index 000000000..301b06f07 --- /dev/null +++ b/host/apps/omap_debug/write-eeprom.sh @@ -0,0 +1,92 @@ +#!/bin/bash + +if [ $# -ne 3 ] && [ $# -ne 5 ]; +then + echo "Usage:" + echo "" + echo "writeprom.sh deviceid rev fab_rev [envvar envsetting]" + echo + echo " deviceid - expansion board device number from table:" + echo + echo " Summit 0x01" + echo " Tobi 0x02" + echo " Tobi Duo 0x03" + echo " Palo35 0x04" + echo " Palo43 0x05" + echo " Chestnut43 0x06" + echo " Pinto 0x07" + echo + echo " rev - board revision (e.g. 0x00)" + echo " fab_rev - revision marking from pcb (e.g. R2411)" + echo " envvar - optional u-boot env variable name" + echo " (e.g. dvimode)" + echo " envsetting - optional u-boot env variable setting" + echo " (e.g. 1024x768MR-16@60)" + exit 1 +fi + +fabrevision=$3 +if [ ${#fabrevision} -ge 8 ]; then + echo "Error: fab revision string must less than 8 characters" + exit 1 +fi + +envvar=$4 +if [ ${#envar} -ge 16 ]; then + echo "Error: environment variable name string must less than 16 characters" + exit 1 +fi + +envsetting=$5 +if [ ${#ensetting} -ge 64 ]; then + echo "Error: environment setting string must less than 64 characters" + exit 1 +fi + +bus=3 +device=0x51 +vendorid=0x03 + +i2cset -y $bus $device 0x00 0x00 +i2cset -y $bus $device 0x01 $vendorid +i2cset -y $bus $device 0x02 0x00 +i2cset -y $bus $device 0x03 $1 +i2cset -y $bus $device 0x04 $2 +i2cset -y $bus $device 0x05 00 + +let i=6 +hexdumpargs="'${#fabrevision}/1 \"0x%02x \"'" +command="echo -n \"$fabrevision\" | hexdump -e $hexdumpargs" +hex=$(eval $command) +for character in $hex; do + i2cset -y $bus $device $i $character + let i=$i+1 +done +i2cset -y $bus $device $i 0x00 + +if [ $# -eq 5 ] +then + i2cset -y $bus $device 0x05 0x01 + + let i=14 + hexdumpargs="'${#envvar}/1 \"0x%02x \"'" + command="echo -n \"$envvar\" | hexdump -e $hexdumpargs" + hex=$(eval $command) + for character in $hex; do + i2cset -y $bus $device $i $character + let i=$i+1 + done + i2cset -y $bus $device $i 0x00 + + let i=30 + hexdumpargs="'${#envsetting}/1 \"0x%02x \"'" + command="echo -n \"$envsetting\" | hexdump -e $hexdumpargs" + hex=$(eval $command) + for character in $hex; do + i2cset -y $bus $device $i $character + let i=$i+1 + done + i2cset -y $bus $device $i 0x00 +fi + + -- cgit v1.2.3 From 4e5429b2839115235c7be778fe334479b833f128 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 24 Mar 2010 11:33:02 -0400 Subject: Start renaming stuff in line with product name USRP Embedded. --- host/apps/omap_debug/usrp-e-ctl.c | 52 +++++++++++++++++++ host/apps/omap_debug/usrp-e-ram.c | 25 ++++++++++ host/apps/omap_debug/usrp-e-read.c | 18 +++++++ host/apps/omap_debug/usrp-e-rw.c | 97 ++++++++++++++++++++++++++++++++++++ host/apps/omap_debug/usrp-e-spi.c | 40 +++++++++++++++ host/apps/omap_debug/usrp-e-write.c | 21 ++++++++ host/apps/omap_debug/usrp1-e-ctl.c | 52 ------------------- host/apps/omap_debug/usrp1-e-ram.c | 25 ---------- host/apps/omap_debug/usrp1-e-read.c | 18 ------- host/apps/omap_debug/usrp1-e-rw.c | 97 ------------------------------------ host/apps/omap_debug/usrp1-e-spi.c | 40 --------------- host/apps/omap_debug/usrp1-e-write.c | 21 -------- 12 files changed, 253 insertions(+), 253 deletions(-) create mode 100644 host/apps/omap_debug/usrp-e-ctl.c create mode 100644 host/apps/omap_debug/usrp-e-ram.c create mode 100644 host/apps/omap_debug/usrp-e-read.c create mode 100644 host/apps/omap_debug/usrp-e-rw.c create mode 100644 host/apps/omap_debug/usrp-e-spi.c create mode 100644 host/apps/omap_debug/usrp-e-write.c delete mode 100644 host/apps/omap_debug/usrp1-e-ctl.c delete mode 100644 host/apps/omap_debug/usrp1-e-ram.c delete mode 100644 host/apps/omap_debug/usrp1-e-read.c delete mode 100644 host/apps/omap_debug/usrp1-e-rw.c delete mode 100644 host/apps/omap_debug/usrp1-e-spi.c delete mode 100644 host/apps/omap_debug/usrp1-e-write.c (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-ctl.c b/host/apps/omap_debug/usrp-e-ctl.c new file mode 100644 index 000000000..045e7ce19 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-ctl.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include + +#include "usrp1_e.h" + +// Usage: usrp1_e_ctl w|r offset number_of_values val1 val2 .... + +int main(int argc, char *argv[]) +{ + int fp, i, cnt, ret; + struct usrp1_e_ctl *ctl_data; + + if (argc < 4) { + printf("Usage: usrp1_e_ctl w|r offset number_of_values val1 val2 ....\n"); + exit(-1); + } + + cnt = atoi(argv[3]); + + ctl_data = malloc(sizeof(struct usrp1_e_ctl) + cnt*2); + + ctl_data->offset = atoi(argv[2]); + ctl_data->count = cnt; + + printf("Sizeof usrp1_e_ctl struct = %d\n", sizeof(struct usrp1_e_ctl)); + + fp = open("/dev/usrp1_e0", O_RDWR); + printf("fp = %d\n", fp); + + if (*argv[1] == 'w') { + for (i=0; ibuf[i] = atoi(argv[4+i]); + + ret = ioctl(fp, USRP1_E_WRITE_CTL, ctl_data); + printf("Return value from write ioctl = %d\n", ret); + } + + if (*argv[1] == 'r') { + ret = ioctl(fp, USRP1_E_READ_CTL, ctl_data); + printf("Return value from write ioctl = %d\n", ret); + + for (i=0; icount; i++) { + if (!(i%8)) + printf("\nData at %4d :", i); + printf(" %5d", ctl_data->buf[i]); + } + printf("\n"); + } +} diff --git a/host/apps/omap_debug/usrp-e-ram.c b/host/apps/omap_debug/usrp-e-ram.c new file mode 100644 index 000000000..d548f7ccd --- /dev/null +++ b/host/apps/omap_debug/usrp-e-ram.c @@ -0,0 +1,25 @@ +#include +#include +#include + +int main(int rgc, char *argv[]) +{ + int fp, i, cnt; + unsigned short buf[1024]; + unsigned short buf_rb[1024]; + + fp = open("/dev/usrp1_e0", O_RDWR); + printf("fp = %d\n", fp); + + for (i=0; i<1024; i++) + buf[i] = i*256; + write(fp, buf, 2048); + read(fp, buf_rb, 2048); + + printf("Read back %hX %hX\n", buf_rb[0], buf_rb[1]); + + for (i=0; i<1024; i++) { + if (buf[i] != buf_rb[i]) + printf("Read - %hX, expected - %hX\n", buf_rb[i], buf[i]); + } +} diff --git a/host/apps/omap_debug/usrp-e-read.c b/host/apps/omap_debug/usrp-e-read.c new file mode 100644 index 000000000..c28f018d5 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-read.c @@ -0,0 +1,18 @@ +#include +#include +#include + +int main(int rgc, char *argv[]) +{ + int fp, cnt; + short buf[1024]; + + fp = open("/dev/usrp1_e0", O_RDONLY); + printf("fp = %d\n", fp); + + do { + cnt = read(fp, buf, 2048); +// printf("Bytes read - %d\n", cnt); + } while(1); + printf("Data - %hX\n", buf[0]); +} diff --git a/host/apps/omap_debug/usrp-e-rw.c b/host/apps/omap_debug/usrp-e-rw.c new file mode 100644 index 000000000..cd7fbe4dd --- /dev/null +++ b/host/apps/omap_debug/usrp-e-rw.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include + +struct pkt { + int checksum; + int seq_num; + short data[1020]; +}; + +static int fp; + +static int calc_checksum(struct pkt *p) +{ + int i, sum; + + i = 0; + sum = 0; + + for (i=0; i<1020; i++) + sum += p->data[i]; + + sum += p->seq_num; + + return sum; +} + +static void *read_thread(void *threadid) +{ + int cnt, prev_seq_num; + struct pkt rx_data; + + printf("Greetings from the reading thread!\n"); + + prev_seq_num = 0; + + while (1) { + cnt = read(fp, &rx_data, 2048); + + if (rx_data.seq_num != prev_seq_num + 1) + printf("Sequence number fail, current = %d, previous = %d\n", + rx_data.seq_num, prev_seq_num); + prev_seq_num = rx_data.seq_num; + + if (calc_checksum(&rx_data) != rx_data.checksum) + printf("Checksum fail packet = %d, expected = %d\n", + calc_checksum(&rx_data), rx_data.checksum); + } + +} + +static void *write_thread(void *threadid) +{ + int seq_number, i, cnt; + struct pkt tx_data; + + printf("Greetings from the write thread!\n"); + + for (i=0; i<1020; i++) + tx_data.data[i] = random() >> 16; + + + seq_number = 1; + + while (1) { + tx_data.seq_num = seq_number++; + tx_data.checksum = calc_checksum(&tx_data); + cnt = write(fp, &tx_data, 2048); + } +} + + +int main(int argc, char *argv[]) +{ + int ret; + pthread_t tx, rx; + long int t; + + fp = open("/dev/usrp1_e0", O_RDWR); + printf("fp = %d\n", fp); + + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { + printf("Failed to create rx thread\n"); + exit(-1); + } + + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { + printf("Failed to create tx thread\n"); + exit(-1); + } + + sleep(10000); + + printf("Done sleeping\n"); +} diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c new file mode 100644 index 000000000..a79d74b18 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include + +#include "usrp1_e.h" + +// Usage: usrp1_e_spi w|rb slave data + +int main(int argc, char *argv[]) +{ + int fp, slave, data, ret; + struct usrp_e_spi spi_dat; + + if (argc < 4) { + printf("Usage: usrp1_e_spi w|rb slave data\n"); + exit(-1); + } + + slave = atoi(argv[2]); + data = atoi(argv[3]); + + fp = open("/dev/usrp1_e0", O_RDWR); + printf("fp = %d\n", fp); + + spi_dat.slave = slave; + spi_dat.data = data; + spi_dat.length = 2; + spi_dat.flags = 0; + + if (*argv[1] == 'r') { + spi_dat.readback = 1; + ret = ioctl(fp, USRP_E_SPI, &spi_dat); + printf("Data returned = %d\n", ret); + } else { + spi_dat.readback = 0; + ioctl(fp, USRP_E_SPI, &spi_dat); + } +} diff --git a/host/apps/omap_debug/usrp-e-write.c b/host/apps/omap_debug/usrp-e-write.c new file mode 100644 index 000000000..903c0071f --- /dev/null +++ b/host/apps/omap_debug/usrp-e-write.c @@ -0,0 +1,21 @@ +#include +#include +#include + +int main(int rgc, char *argv[]) +{ + int fp, i, cnt; + short buf[1024]; + + fp = open("/dev/usrp1_e0", O_WRONLY); + printf("fp = %d\n", fp); + + for (i=0; i<1024; i++) { + buf[i] = i; + } + +// do { + cnt = write(fp, buf, 2048); + printf("Bytes written - %d\n", cnt); +// } while (1); +} diff --git a/host/apps/omap_debug/usrp1-e-ctl.c b/host/apps/omap_debug/usrp1-e-ctl.c deleted file mode 100644 index 045e7ce19..000000000 --- a/host/apps/omap_debug/usrp1-e-ctl.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include -#include -#include - -#include "usrp1_e.h" - -// Usage: usrp1_e_ctl w|r offset number_of_values val1 val2 .... - -int main(int argc, char *argv[]) -{ - int fp, i, cnt, ret; - struct usrp1_e_ctl *ctl_data; - - if (argc < 4) { - printf("Usage: usrp1_e_ctl w|r offset number_of_values val1 val2 ....\n"); - exit(-1); - } - - cnt = atoi(argv[3]); - - ctl_data = malloc(sizeof(struct usrp1_e_ctl) + cnt*2); - - ctl_data->offset = atoi(argv[2]); - ctl_data->count = cnt; - - printf("Sizeof usrp1_e_ctl struct = %d\n", sizeof(struct usrp1_e_ctl)); - - fp = open("/dev/usrp1_e0", O_RDWR); - printf("fp = %d\n", fp); - - if (*argv[1] == 'w') { - for (i=0; ibuf[i] = atoi(argv[4+i]); - - ret = ioctl(fp, USRP1_E_WRITE_CTL, ctl_data); - printf("Return value from write ioctl = %d\n", ret); - } - - if (*argv[1] == 'r') { - ret = ioctl(fp, USRP1_E_READ_CTL, ctl_data); - printf("Return value from write ioctl = %d\n", ret); - - for (i=0; icount; i++) { - if (!(i%8)) - printf("\nData at %4d :", i); - printf(" %5d", ctl_data->buf[i]); - } - printf("\n"); - } -} diff --git a/host/apps/omap_debug/usrp1-e-ram.c b/host/apps/omap_debug/usrp1-e-ram.c deleted file mode 100644 index d548f7ccd..000000000 --- a/host/apps/omap_debug/usrp1-e-ram.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include - -int main(int rgc, char *argv[]) -{ - int fp, i, cnt; - unsigned short buf[1024]; - unsigned short buf_rb[1024]; - - fp = open("/dev/usrp1_e0", O_RDWR); - printf("fp = %d\n", fp); - - for (i=0; i<1024; i++) - buf[i] = i*256; - write(fp, buf, 2048); - read(fp, buf_rb, 2048); - - printf("Read back %hX %hX\n", buf_rb[0], buf_rb[1]); - - for (i=0; i<1024; i++) { - if (buf[i] != buf_rb[i]) - printf("Read - %hX, expected - %hX\n", buf_rb[i], buf[i]); - } -} diff --git a/host/apps/omap_debug/usrp1-e-read.c b/host/apps/omap_debug/usrp1-e-read.c deleted file mode 100644 index c28f018d5..000000000 --- a/host/apps/omap_debug/usrp1-e-read.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include -#include - -int main(int rgc, char *argv[]) -{ - int fp, cnt; - short buf[1024]; - - fp = open("/dev/usrp1_e0", O_RDONLY); - printf("fp = %d\n", fp); - - do { - cnt = read(fp, buf, 2048); -// printf("Bytes read - %d\n", cnt); - } while(1); - printf("Data - %hX\n", buf[0]); -} diff --git a/host/apps/omap_debug/usrp1-e-rw.c b/host/apps/omap_debug/usrp1-e-rw.c deleted file mode 100644 index cd7fbe4dd..000000000 --- a/host/apps/omap_debug/usrp1-e-rw.c +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include -#include -#include -#include - -struct pkt { - int checksum; - int seq_num; - short data[1020]; -}; - -static int fp; - -static int calc_checksum(struct pkt *p) -{ - int i, sum; - - i = 0; - sum = 0; - - for (i=0; i<1020; i++) - sum += p->data[i]; - - sum += p->seq_num; - - return sum; -} - -static void *read_thread(void *threadid) -{ - int cnt, prev_seq_num; - struct pkt rx_data; - - printf("Greetings from the reading thread!\n"); - - prev_seq_num = 0; - - while (1) { - cnt = read(fp, &rx_data, 2048); - - if (rx_data.seq_num != prev_seq_num + 1) - printf("Sequence number fail, current = %d, previous = %d\n", - rx_data.seq_num, prev_seq_num); - prev_seq_num = rx_data.seq_num; - - if (calc_checksum(&rx_data) != rx_data.checksum) - printf("Checksum fail packet = %d, expected = %d\n", - calc_checksum(&rx_data), rx_data.checksum); - } - -} - -static void *write_thread(void *threadid) -{ - int seq_number, i, cnt; - struct pkt tx_data; - - printf("Greetings from the write thread!\n"); - - for (i=0; i<1020; i++) - tx_data.data[i] = random() >> 16; - - - seq_number = 1; - - while (1) { - tx_data.seq_num = seq_number++; - tx_data.checksum = calc_checksum(&tx_data); - cnt = write(fp, &tx_data, 2048); - } -} - - -int main(int argc, char *argv[]) -{ - int ret; - pthread_t tx, rx; - long int t; - - fp = open("/dev/usrp1_e0", O_RDWR); - printf("fp = %d\n", fp); - - if (pthread_create(&rx, NULL, read_thread, (void *) t)) { - printf("Failed to create rx thread\n"); - exit(-1); - } - - if (pthread_create(&tx, NULL, write_thread, (void *) t)) { - printf("Failed to create tx thread\n"); - exit(-1); - } - - sleep(10000); - - printf("Done sleeping\n"); -} diff --git a/host/apps/omap_debug/usrp1-e-spi.c b/host/apps/omap_debug/usrp1-e-spi.c deleted file mode 100644 index a79d74b18..000000000 --- a/host/apps/omap_debug/usrp1-e-spi.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include -#include -#include - -#include "usrp1_e.h" - -// Usage: usrp1_e_spi w|rb slave data - -int main(int argc, char *argv[]) -{ - int fp, slave, data, ret; - struct usrp_e_spi spi_dat; - - if (argc < 4) { - printf("Usage: usrp1_e_spi w|rb slave data\n"); - exit(-1); - } - - slave = atoi(argv[2]); - data = atoi(argv[3]); - - fp = open("/dev/usrp1_e0", O_RDWR); - printf("fp = %d\n", fp); - - spi_dat.slave = slave; - spi_dat.data = data; - spi_dat.length = 2; - spi_dat.flags = 0; - - if (*argv[1] == 'r') { - spi_dat.readback = 1; - ret = ioctl(fp, USRP_E_SPI, &spi_dat); - printf("Data returned = %d\n", ret); - } else { - spi_dat.readback = 0; - ioctl(fp, USRP_E_SPI, &spi_dat); - } -} diff --git a/host/apps/omap_debug/usrp1-e-write.c b/host/apps/omap_debug/usrp1-e-write.c deleted file mode 100644 index 903c0071f..000000000 --- a/host/apps/omap_debug/usrp1-e-write.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include - -int main(int rgc, char *argv[]) -{ - int fp, i, cnt; - short buf[1024]; - - fp = open("/dev/usrp1_e0", O_WRONLY); - printf("fp = %d\n", fp); - - for (i=0; i<1024; i++) { - buf[i] = i; - } - -// do { - cnt = write(fp, buf, 2048); - printf("Bytes written - %d\n", cnt); -// } while (1); -} -- cgit v1.2.3 From 5463912c324639791b354dea0d6af5e42c1eae77 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 24 Mar 2010 12:00:05 -0400 Subject: Start applying order through Makefile. --- host/apps/omap_debug/Makefile | 1 + 1 file changed, 1 insertion(+) create mode 100644 host/apps/omap_debug/Makefile (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile new file mode 100644 index 000000000..5616a7355 --- /dev/null +++ b/host/apps/omap_debug/Makefile @@ -0,0 +1 @@ +usrp-e-spi : usrp-e-spi.c -- cgit v1.2.3 From 550bf3230aa1a5e7236d5bdb64a77c4ae1acea66 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Mar 2010 16:57:48 +0000 Subject: Update usrp1_e.h header file to match kernel driver. --- host/apps/omap_debug/usrp1_e.h | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp1_e.h b/host/apps/omap_debug/usrp1_e.h index b49b526dc..b34446b01 100644 --- a/host/apps/omap_debug/usrp1_e.h +++ b/host/apps/omap_debug/usrp1_e.h @@ -15,10 +15,16 @@ #include #include -struct usrp1_e_ctl { +struct usrp1_e_ctl16 { __u32 offset; __u32 count; - __u16 buf[]; + __u16 buf[20]; +}; + +struct usrp1_e_ctl32 { + __u32 offset; + __u32 count; + __u32 buf[10]; }; // SPI interface @@ -48,9 +54,19 @@ struct usrp_e_spi { __u32 flags; }; +struct usrp_e_i2c { + __u8 addr; + __u32 len; + __u8 data[]; +}; + #define USRP_E_IOC_MAGIC 'u' -#define USRP_E_WRITE_CTL _IOW(USRP_E_IOC_MAGIC, 0x20, struct usrp1_e_ctl) -#define USRP_E_READ_CTL _IOWR(USRP_E_IOC_MAGIC, 0x21, struct usrp1_e_ctl) -#define USRP_E_SPI _IOW(USRP_E_IOC_MAGIC, 0x22, struct usrp_e_spi) +#define USRP_E_WRITE_CTL16 _IOW(USRP_E_IOC_MAGIC, 0x20, struct usrp1_e_ctl16) +#define USRP_E_READ_CTL16 _IOWR(USRP_E_IOC_MAGIC, 0x21, struct usrp1_e_ctl16) +#define USRP_E_WRITE_CTL32 _IOW(USRP_E_IOC_MAGIC, 0x22, struct usrp1_e_ctl32) +#define USRP_E_READ_CTL32 _IOWR(USRP_E_IOC_MAGIC, 0x23, struct usrp1_e_ctl32) +#define USRP_E_SPI _IOW(USRP_E_IOC_MAGIC, 0x24, struct usrp_e_spi) +#define USRP_E_I2C_READ _IOR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) +#define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) #endif -- cgit v1.2.3 From 4f5cd64188c7e2b5490d910d5e86301c053960ea Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 24 Mar 2010 15:49:08 -0400 Subject: Makefile and usrp-e-spi edits, add i2c test program. --- host/apps/omap_debug/Makefile | 10 ++++++ host/apps/omap_debug/usrp-e-i2c.c | 71 +++++++++++++++++++++++++++++++++++++++ host/apps/omap_debug/usrp-e-spi.c | 4 ++- 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 host/apps/omap_debug/usrp-e-i2c.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 5616a7355..07545a639 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1 +1,11 @@ +CFLAGS=-Wall + +all : usrp-e-spi usrp-e-i2c + usrp-e-spi : usrp-e-spi.c + +usrp-e-i2c : usrp-e-i2c.c + +clean : + rm -f usrp-e-spi + rm -f usrp-e-i2c diff --git a/host/apps/omap_debug/usrp-e-i2c.c b/host/apps/omap_debug/usrp-e-i2c.c new file mode 100644 index 000000000..dce1ae153 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-i2c.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include + +#include "usrp1_e.h" + +// Usage: usrp_e_i2c w address data0 data1 data 2 .... +// Usage: usrp_e_i2c r address count + +int main(int argc, char *argv[]) +{ + int fp, ret, i; + struct usrp_e_i2c *i2c_msg; + int direction, address, count; + + if (argc < 3) { + printf("Usage: usrp1_e_i2c w address data0 data1 data2 ...\n"); + printf("Usage: usrp1_e_i2c r address count\n"); + exit(-1); + } + + if (strcmp(argv[1], "r") == 0) { + direction = 0; + } else if (strcmp(argv[1], "w") == 0) { + direction = 1; + } else { + return -1; + } + + address = atoi(argv[2]); + + fp = open("/dev/usrp1_e0", O_RDWR); + printf("fp = %d\n", fp); + + if (direction) { + count = argc - 2; + } else { + count = atoi(argv[3]); + } + + i2c_msg = malloc(sizeof(i2c_msg) + count * sizeof(char)); + + i2c_msg->addr = address; + i2c_msg->len = count; + + if (direction) { + // Write + + for (i=0; idata[i] = atoi(argv[3+i]); + } + + ret = ioctl(fp, USRP_E_I2C_WRITE, i2c_msg); + printf("Return value from i2c_write ioctl: %d\n", ret); + } else { + // Read + + ret = ioctl(fp, USRP_E_I2C_READ, i2c_msg); + + printf("Ioctl: %d Data read :", ret); + for (i=0; idata[i]); + } + printf("/n"); + + } + return 0; +} diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c index a79d74b18..e10e72b80 100644 --- a/host/apps/omap_debug/usrp-e-spi.c +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "usrp1_e.h" @@ -37,4 +37,6 @@ int main(int argc, char *argv[]) spi_dat.readback = 0; ioctl(fp, USRP_E_SPI, &spi_dat); } + + return 0; } -- cgit v1.2.3 From 28e5e0740a8fc3c7233a1bd5cc6bbc897c586da6 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 25 Mar 2010 17:42:36 +0000 Subject: Updates for header file change from usrp1_e.h to usrp_e.h. --- host/apps/omap_debug/fetch-module.sh | 4 +- host/apps/omap_debug/usrp-e-i2c.c | 8 ++-- host/apps/omap_debug/usrp-e-spi.c | 8 ++-- host/apps/omap_debug/usrp1_e.h | 72 ------------------------------------ host/apps/omap_debug/usrp_e.h | 72 ++++++++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 82 deletions(-) delete mode 100644 host/apps/omap_debug/usrp1_e.h create mode 100644 host/apps/omap_debug/usrp_e.h (limited to 'host') diff --git a/host/apps/omap_debug/fetch-module.sh b/host/apps/omap_debug/fetch-module.sh index 101ea9aef..45cf1f052 100755 --- a/host/apps/omap_debug/fetch-module.sh +++ b/host/apps/omap_debug/fetch-module.sh @@ -1,3 +1,3 @@ -scp balister@192.168.1.167:src/git/kernel_usrp/drivers/misc/usrp1_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc -scp balister@192.168.1.167:src/git/kernel_usrp/include/linux/usrp1_e.h . +scp balister@192.168.1.167:src/git/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc +scp balister@192.168.1.167:src/git/kernel_usrp/include/linux/usrp_e.h . sync diff --git a/host/apps/omap_debug/usrp-e-i2c.c b/host/apps/omap_debug/usrp-e-i2c.c index dce1ae153..417d6d580 100644 --- a/host/apps/omap_debug/usrp-e-i2c.c +++ b/host/apps/omap_debug/usrp-e-i2c.c @@ -5,7 +5,7 @@ #include #include -#include "usrp1_e.h" +#include "usrp_e.h" // Usage: usrp_e_i2c w address data0 data1 data 2 .... // Usage: usrp_e_i2c r address count @@ -17,8 +17,8 @@ int main(int argc, char *argv[]) int direction, address, count; if (argc < 3) { - printf("Usage: usrp1_e_i2c w address data0 data1 data2 ...\n"); - printf("Usage: usrp1_e_i2c r address count\n"); + printf("Usage: usrp_e_i2c w address data0 data1 data2 ...\n"); + printf("Usage: usrp_e_i2c r address count\n"); exit(-1); } @@ -32,7 +32,7 @@ int main(int argc, char *argv[]) address = atoi(argv[2]); - fp = open("/dev/usrp1_e0", O_RDWR); + fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); if (direction) { diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c index e10e72b80..1af47b172 100644 --- a/host/apps/omap_debug/usrp-e-spi.c +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -4,9 +4,9 @@ #include #include -#include "usrp1_e.h" +#include "usrp_e.h" -// Usage: usrp1_e_spi w|rb slave data +// Usage: usrp_e_spi w|rb slave data int main(int argc, char *argv[]) { @@ -14,14 +14,14 @@ int main(int argc, char *argv[]) struct usrp_e_spi spi_dat; if (argc < 4) { - printf("Usage: usrp1_e_spi w|rb slave data\n"); + printf("Usage: usrp_e_spi w|rb slave data\n"); exit(-1); } slave = atoi(argv[2]); data = atoi(argv[3]); - fp = open("/dev/usrp1_e0", O_RDWR); + fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); spi_dat.slave = slave; diff --git a/host/apps/omap_debug/usrp1_e.h b/host/apps/omap_debug/usrp1_e.h deleted file mode 100644 index b34446b01..000000000 --- a/host/apps/omap_debug/usrp1_e.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2010 Ettus Research, LLC - * - * Written by Philip Balister - * - * 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 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __USRP_E_H -#define __USRP_E_H - -#include -#include - -struct usrp1_e_ctl16 { - __u32 offset; - __u32 count; - __u16 buf[20]; -}; - -struct usrp1_e_ctl32 { - __u32 offset; - __u32 count; - __u32 buf[10]; -}; - -// SPI interface - -#define UE_SPI_TXONLY 0 -#define UE_SPI_TXRX 1 - -// Defines for spi ctrl register -#define UE_SPI_CTRL_ASS (1<<13) -#define UE_SPI_CTRL_IE (1<<12) -#define UE_SPI_CTRL_LSB (1<<11) -#define UE_SPI_CTRL_TXNEG (1<<10) -#define UE_SPI_CTRL_RXNEG (1<<9) -#define UE_SPI_CTRL_GO_BSY (1<<8) -#define UE_SPI_CTRL_CHAR_LEN_MASK 0x7f - -#define UE_SPI_PUSH_RISE 0 -#define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG -#define UE_SPI_LATCH_RISE 0 -#define UE_SPI_LATCH_FALL UE_SPI_CTRL_RXNEG - -struct usrp_e_spi { - __u8 readback; - __u32 slave; - __u32 data; - __u32 length; - __u32 flags; -}; - -struct usrp_e_i2c { - __u8 addr; - __u32 len; - __u8 data[]; -}; - -#define USRP_E_IOC_MAGIC 'u' -#define USRP_E_WRITE_CTL16 _IOW(USRP_E_IOC_MAGIC, 0x20, struct usrp1_e_ctl16) -#define USRP_E_READ_CTL16 _IOWR(USRP_E_IOC_MAGIC, 0x21, struct usrp1_e_ctl16) -#define USRP_E_WRITE_CTL32 _IOW(USRP_E_IOC_MAGIC, 0x22, struct usrp1_e_ctl32) -#define USRP_E_READ_CTL32 _IOWR(USRP_E_IOC_MAGIC, 0x23, struct usrp1_e_ctl32) -#define USRP_E_SPI _IOW(USRP_E_IOC_MAGIC, 0x24, struct usrp_e_spi) -#define USRP_E_I2C_READ _IOR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) -#define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) - -#endif diff --git a/host/apps/omap_debug/usrp_e.h b/host/apps/omap_debug/usrp_e.h new file mode 100644 index 000000000..aa8ef3d57 --- /dev/null +++ b/host/apps/omap_debug/usrp_e.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010 Ettus Research, LLC + * + * Written by Philip Balister + * + * 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 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __USRP_E_H +#define __USRP_E_H + +#include +#include + +struct usrp_e_ctl16 { + __u32 offset; + __u32 count; + __u16 buf[20]; +}; + +struct usrp_e_ctl32 { + __u32 offset; + __u32 count; + __u32 buf[10]; +}; + +// SPI interface + +#define UE_SPI_TXONLY 0 +#define UE_SPI_TXRX 1 + +// Defines for spi ctrl register +#define UE_SPI_CTRL_ASS (1<<13) +#define UE_SPI_CTRL_IE (1<<12) +#define UE_SPI_CTRL_LSB (1<<11) +#define UE_SPI_CTRL_TXNEG (1<<10) +#define UE_SPI_CTRL_RXNEG (1<<9) +#define UE_SPI_CTRL_GO_BSY (1<<8) +#define UE_SPI_CTRL_CHAR_LEN_MASK 0x7f + +#define UE_SPI_PUSH_RISE 0 +#define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG +#define UE_SPI_LATCH_RISE 0 +#define UE_SPI_LATCH_FALL UE_SPI_CTRL_RXNEG + +struct usrp_e_spi { + __u8 readback; + __u32 slave; + __u32 data; + __u32 length; + __u32 flags; +}; + +struct usrp_e_i2c { + __u8 addr; + __u32 len; + __u8 data[]; +}; + +#define USRP_E_IOC_MAGIC 'u' +#define USRP_E_WRITE_CTL16 _IOW(USRP_E_IOC_MAGIC, 0x20, struct usrp_e_ctl16) +#define USRP_E_READ_CTL16 _IOWR(USRP_E_IOC_MAGIC, 0x21, struct usrp_e_ctl16) +#define USRP_E_WRITE_CTL32 _IOW(USRP_E_IOC_MAGIC, 0x22, struct usrp_e_ctl32) +#define USRP_E_READ_CTL32 _IOWR(USRP_E_IOC_MAGIC, 0x23, struct usrp_e_ctl32) +#define USRP_E_SPI _IOW(USRP_E_IOC_MAGIC, 0x24, struct usrp_e_spi) +#define USRP_E_I2C_READ _IOR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) +#define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) + +#endif -- cgit v1.2.3 From 717a6acd2b0687348c492cbf2e0813ffd63d847a Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 25 Mar 2010 20:43:59 +0000 Subject: Update read/write test program to new header name and add to Makefile. --- host/apps/omap_debug/Makefile | 6 +++++- host/apps/omap_debug/usrp-e-rw.c | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 07545a639..34446ccc3 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,11 +1,15 @@ CFLAGS=-Wall -all : usrp-e-spi usrp-e-i2c +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-spi : usrp-e-spi.c usrp-e-i2c : usrp-e-i2c.c +usrp-e-rw : usrp-e-rw.c + gcc -o $@ $< -lpthread clean : rm -f usrp-e-spi rm -f usrp-e-i2c + rm -f usrp-e-rw + diff --git a/host/apps/omap_debug/usrp-e-rw.c b/host/apps/omap_debug/usrp-e-rw.c index cd7fbe4dd..5607166b0 100644 --- a/host/apps/omap_debug/usrp-e-rw.c +++ b/host/apps/omap_debug/usrp-e-rw.c @@ -3,6 +3,7 @@ #include #include #include +#include struct pkt { int checksum; @@ -74,11 +75,10 @@ static void *write_thread(void *threadid) int main(int argc, char *argv[]) { - int ret; pthread_t tx, rx; long int t; - fp = open("/dev/usrp1_e0", O_RDWR); + fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); if (pthread_create(&rx, NULL, read_thread, (void *) t)) { -- cgit v1.2.3 From 84df070f371b989ef51b6f2d04c131b34308e5e9 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 26 Mar 2010 15:22:12 +0000 Subject: Add test program to send characters to the wishbone uart. --- host/apps/omap_debug/Makefile | 6 +++++- host/apps/omap_debug/usrp-e-uart.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 host/apps/omap_debug/usrp-e-uart.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 34446ccc3..13b834e28 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ CFLAGS=-Wall -all : usrp-e-spi usrp-e-i2c usrp-e-rw +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-spi : usrp-e-spi.c @@ -8,8 +8,12 @@ usrp-e-i2c : usrp-e-i2c.c usrp-e-rw : usrp-e-rw.c gcc -o $@ $< -lpthread + +usrp-e-uart : usrp-e-uart.c + clean : rm -f usrp-e-spi rm -f usrp-e-i2c rm -f usrp-e-rw + rm -f usrp-e-uart diff --git a/host/apps/omap_debug/usrp-e-uart.c b/host/apps/omap_debug/usrp-e-uart.c new file mode 100644 index 000000000..92f89f45c --- /dev/null +++ b/host/apps/omap_debug/usrp-e-uart.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include + +#include "usrp_e.h" + +// Usage: usrp_e_uart + +#define UART_WRITE_ADDR ((1<<6) + 16) + +int main(int argc, char *argv[]) +{ + int fp, i, ret; + struct usrp_e_ctl16 d; + char *str = argv[1]; + + if (argc < 2) { + printf("Usage: usrp_e_uart n"); + exit(-1); + } + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + for (i=0; i Date: Fri, 26 Mar 2010 19:04:18 +0000 Subject: Working version. --- host/apps/omap_debug/usrp-e-uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-uart.c b/host/apps/omap_debug/usrp-e-uart.c index 92f89f45c..239df9444 100644 --- a/host/apps/omap_debug/usrp-e-uart.c +++ b/host/apps/omap_debug/usrp-e-uart.c @@ -9,7 +9,7 @@ // Usage: usrp_e_uart -#define UART_WRITE_ADDR ((1<<6) + 16) +#define UART_WRITE_ADDR (0x80 + 12) int main(int argc, char *argv[]) { -- cgit v1.2.3 From 930755fce1e5d22a5ede0459dccd6c9501fc642c Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 29 Mar 2010 13:30:17 +0000 Subject: Minor fixes. --- host/apps/omap_debug/usrp-e-i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-i2c.c b/host/apps/omap_debug/usrp-e-i2c.c index 417d6d580..19d64731b 100644 --- a/host/apps/omap_debug/usrp-e-i2c.c +++ b/host/apps/omap_debug/usrp-e-i2c.c @@ -36,7 +36,7 @@ int main(int argc, char *argv[]) printf("fp = %d\n", fp); if (direction) { - count = argc - 2; + count = argc - 3; } else { count = atoi(argv[3]); } @@ -64,7 +64,7 @@ int main(int argc, char *argv[]) for (i=0; idata[i]); } - printf("/n"); + printf("\n"); } return 0; -- cgit v1.2.3 From c81a975766a8831cab1e3123af94b4fe4a09d9bc Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 30 Mar 2010 14:12:11 +0000 Subject: compiling with master merge, renamed usrp1e to usrp_e --- host/apps/usrp1e_load_fpga.cpp | 47 ------ host/include/uhd/usrp/CMakeLists.txt | 2 +- host/include/uhd/usrp/usrp1e.hpp | 54 ------ host/include/uhd/usrp/usrp_e.hpp | 54 ++++++ host/lib/CMakeLists.txt | 20 ++- host/lib/usrp/usrp1e/dboard_impl.cpp | 76 --------- host/lib/usrp/usrp1e/dboard_interface.cpp | 189 --------------------- host/lib/usrp/usrp1e/dsp_impl.cpp | 70 -------- host/lib/usrp/usrp1e/fpga-downloader.cc | 262 ------------------------------ host/lib/usrp/usrp1e/mboard_impl.cpp | 46 ------ host/lib/usrp/usrp1e/usrp1e_impl.cpp | 178 -------------------- host/lib/usrp/usrp1e/usrp1e_impl.hpp | 135 --------------- host/lib/usrp/usrp1e/usrp1e_none.cpp | 38 ----- host/lib/usrp/usrp2/usrp2_impl.cpp | 2 +- host/lib/usrp/usrp_e/dboard_impl.cpp | 76 +++++++++ host/lib/usrp/usrp_e/dboard_interface.cpp | 189 +++++++++++++++++++++ host/lib/usrp/usrp_e/dsp_impl.cpp | 69 ++++++++ host/lib/usrp/usrp_e/fpga-downloader.cc | 262 ++++++++++++++++++++++++++++++ host/lib/usrp/usrp_e/mboard_impl.cpp | 45 +++++ host/lib/usrp/usrp_e/usrp_e_impl.cpp | 179 ++++++++++++++++++++ host/lib/usrp/usrp_e/usrp_e_impl.hpp | 135 +++++++++++++++ host/lib/usrp/usrp_e/usrp_e_none.cpp | 38 +++++ host/utils/CMakeLists.txt | 5 +- host/utils/usrp_e_load_fpga.cpp | 47 ++++++ 24 files changed, 1110 insertions(+), 1108 deletions(-) delete mode 100644 host/apps/usrp1e_load_fpga.cpp delete mode 100644 host/include/uhd/usrp/usrp1e.hpp create mode 100644 host/include/uhd/usrp/usrp_e.hpp delete mode 100644 host/lib/usrp/usrp1e/dboard_impl.cpp delete mode 100644 host/lib/usrp/usrp1e/dboard_interface.cpp delete mode 100644 host/lib/usrp/usrp1e/dsp_impl.cpp delete mode 100644 host/lib/usrp/usrp1e/fpga-downloader.cc delete mode 100644 host/lib/usrp/usrp1e/mboard_impl.cpp delete mode 100644 host/lib/usrp/usrp1e/usrp1e_impl.cpp delete mode 100644 host/lib/usrp/usrp1e/usrp1e_impl.hpp delete mode 100644 host/lib/usrp/usrp1e/usrp1e_none.cpp create mode 100644 host/lib/usrp/usrp_e/dboard_impl.cpp create mode 100644 host/lib/usrp/usrp_e/dboard_interface.cpp create mode 100644 host/lib/usrp/usrp_e/dsp_impl.cpp create mode 100644 host/lib/usrp/usrp_e/fpga-downloader.cc create mode 100644 host/lib/usrp/usrp_e/mboard_impl.cpp create mode 100644 host/lib/usrp/usrp_e/usrp_e_impl.cpp create mode 100644 host/lib/usrp/usrp_e/usrp_e_impl.hpp create mode 100644 host/lib/usrp/usrp_e/usrp_e_none.cpp create mode 100644 host/utils/usrp_e_load_fpga.cpp (limited to 'host') diff --git a/host/apps/usrp1e_load_fpga.cpp b/host/apps/usrp1e_load_fpga.cpp deleted file mode 100644 index d5960b391..000000000 --- a/host/apps/usrp1e_load_fpga.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include -#include -#include -#include - -namespace po = boost::program_options; - -int main(int argc, char *argv[]){ - po::options_description desc("Allowed options"); - desc.add_options() - ("help", "help message") - ("file", po::value(), "path to fpga bin file") - ; - - po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - - //print the help message - if (vm.count("help") or vm.count("file") == 0){ - std::cout << boost::format("USRP1E Load FPGA %s") % desc << std::endl; - return ~0; - } - - //load the fpga - std::string file = vm["file"].as(); - uhd::usrp::usrp1e::load_fpga(file); - - return 0; -} diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt index bab01fdeb..b9be370bd 100644 --- a/host/include/uhd/usrp/CMakeLists.txt +++ b/host/include/uhd/usrp/CMakeLists.txt @@ -21,7 +21,7 @@ INSTALL(FILES dboard_id.hpp dboard_interface.hpp dboard_manager.hpp - usrp1e.hpp + usrp_e.hpp usrp2.hpp DESTINATION ${INCLUDE_DIR}/uhd/usrp ) diff --git a/host/include/uhd/usrp/usrp1e.hpp b/host/include/uhd/usrp/usrp1e.hpp deleted file mode 100644 index 75da58453..000000000 --- a/host/include/uhd/usrp/usrp1e.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2010 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 . -// - -#ifndef INCLUDED_UHD_USRP_USRP1E_HPP -#define INCLUDED_UHD_USRP_USRP1E_HPP - -#include -#include - -namespace uhd{ namespace usrp{ - -/*! - * The usrp1e device class. - */ -class UHD_API usrp1e : public device{ -public: - /*! - * Find usrp1e devices on the system via the device node. - * \param hint a device addr with the usrp1e address filled in - * \return a vector of device addresses for all usrp1es found - */ - static device_addrs_t find(const device_addr_t &hint); - - /*! - * Make a usrp1e from a device address. - * \param addr the device address - * \return a device sptr to a new usrp1e - */ - static device::sptr make(const device_addr_t &addr); - - /*! - * Load the FPGA with an image file. - * \param bin_file the name of the fpga image file - */ - static void load_fpga(const std::string &bin_file); -}; - -}} //namespace - -#endif /* INCLUDED_UHD_USRP_USRP1E_HPP */ diff --git a/host/include/uhd/usrp/usrp_e.hpp b/host/include/uhd/usrp/usrp_e.hpp new file mode 100644 index 000000000..557058261 --- /dev/null +++ b/host/include/uhd/usrp/usrp_e.hpp @@ -0,0 +1,54 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_UHD_USRP_USRP_E_HPP +#define INCLUDED_UHD_USRP_USRP_E_HPP + +#include +#include + +namespace uhd{ namespace usrp{ + +/*! + * The USRP-Embedded device class. + */ +class UHD_API usrp_e : public device{ +public: + /*! + * Find usrp_e devices on the system via the device node. + * \param hint a device addr with the usrp_e address filled in + * \return a vector of device addresses for all usrp-e's found + */ + static device_addrs_t find(const device_addr_t &hint); + + /*! + * Make a usrp_e from a device address. + * \param addr the device address + * \return a device sptr to a new usrp_e + */ + static device::sptr make(const device_addr_t &addr); + + /*! + * Load the FPGA with an image file. + * \param bin_file the name of the fpga image file + */ + static void load_fpga(const std::string &bin_file); +}; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_USRP_E_HPP */ diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 323b69b14..db5e9d273 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -51,6 +51,8 @@ LIST(APPEND libuhd_sources ######################################################################## # Conditionally add the usrp1e sources ######################################################################## +MESSAGE(STATUS "Configuring usrp-e support...") + INCLUDE(CheckIncludeFiles) SET(usrp1e_required_headers linux/ioctl.h @@ -63,19 +65,19 @@ CHECK_INCLUDE_FILES( ) IF(HAS_USRP1E_REQUIRED_HEADERS) - MESSAGE(STATUS "Building usrp1e support...") + MESSAGE(STATUS " Building usrp1e support.") LIST(APPEND libuhd_sources - usrp/usrp1e/dboard_impl.cpp - usrp/usrp1e/dboard_interface.cpp - usrp/usrp1e/dsp_impl.cpp - usrp/usrp1e/fpga-downloader.cc - usrp/usrp1e/mboard_impl.cpp - usrp/usrp1e/usrp1e_impl.cpp + usrp/usrp_e/dboard_impl.cpp + usrp/usrp_e/dboard_interface.cpp + usrp/usrp_e/dsp_impl.cpp + usrp/usrp_e/fpga-downloader.cc + usrp/usrp_e/mboard_impl.cpp + usrp/usrp_e/usrp_e_impl.cpp ) ELSE(HAS_USRP1E_REQUIRED_HEADERS) - MESSAGE(STATUS "Skipping usrp1e support...") + MESSAGE(STATUS " Skipping usrp1e support.") LIST(APPEND libuhd_sources - usrp/usrp1e/usrp1e_none.cpp + usrp/usrp_e/usrp_e_none.cpp ) ENDIF(HAS_USRP1E_REQUIRED_HEADERS) diff --git a/host/lib/usrp/usrp1e/dboard_impl.cpp b/host/lib/usrp/usrp1e/dboard_impl.cpp deleted file mode 100644 index a2798dce3..000000000 --- a/host/lib/usrp/usrp1e/dboard_impl.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include -#include -#include "usrp1e_impl.hpp" - -using namespace uhd::usrp; - -/*********************************************************************** - * Dboard Initialization - **********************************************************************/ -void usrp1e_impl::dboard_init(void){ - dboard_id_t rx_dboard_id = dboard_id::NONE; //TODO get these from the eeprom - dboard_id_t tx_dboard_id = dboard_id::NONE; - - //create a new dboard interface and manager - dboard_interface::sptr dboard_interface( - make_usrp1e_dboard_interface(this) - ); - _dboard_manager = dboard_manager::make( - rx_dboard_id, tx_dboard_id, dboard_interface - ); - - //setup the dboard proxies - _rx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::rx_dboard_get, this, _1, _2), - boost::bind(&usrp1e_impl::rx_dboard_set, this, _1, _2) - ); - _tx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::tx_dboard_get, this, _1, _2), - boost::bind(&usrp1e_impl::tx_dboard_set, this, _1, _2) - ); -} - -/*********************************************************************** - * RX Dboard Get - **********************************************************************/ -void usrp1e_impl::rx_dboard_get(const wax::obj &, wax::obj &){ - -} - -/*********************************************************************** - * RX Dboard Set - **********************************************************************/ -void usrp1e_impl::rx_dboard_set(const wax::obj &, const wax::obj &){ - -} - -/*********************************************************************** - * TX Dboard Get - **********************************************************************/ -void usrp1e_impl::tx_dboard_get(const wax::obj &, wax::obj &){ - -} - -/*********************************************************************** - * TX Dboard Set - **********************************************************************/ -void usrp1e_impl::tx_dboard_set(const wax::obj &, const wax::obj &){ - -} diff --git a/host/lib/usrp/usrp1e/dboard_interface.cpp b/host/lib/usrp/usrp1e/dboard_interface.cpp deleted file mode 100644 index ef91014ac..000000000 --- a/host/lib/usrp/usrp1e/dboard_interface.cpp +++ /dev/null @@ -1,189 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include -#include //std::copy -#include "usrp1e_impl.hpp" -#include - -using namespace uhd::usrp; - -class usrp1e_dboard_interface : public dboard_interface{ -public: - usrp1e_dboard_interface(usrp1e_impl *impl); - ~usrp1e_dboard_interface(void); - - void write_aux_dac(unit_type_t, int, int); - int read_aux_adc(unit_type_t, int); - - void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t); - void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t); - void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t); - boost::uint16_t read_gpio(gpio_bank_t); - - void write_i2c(int, const byte_vector_t &); - byte_vector_t read_i2c(int, size_t); - - double get_rx_clock_rate(void); - double get_tx_clock_rate(void); - -private: - byte_vector_t transact_spi( - spi_dev_t dev, - spi_latch_t latch, - spi_push_t push, - const byte_vector_t &buf, - bool readback - ); - - usrp1e_impl *_impl; -}; - -/*********************************************************************** - * Make Function - **********************************************************************/ -dboard_interface::sptr make_usrp1e_dboard_interface(usrp1e_impl *impl){ - return dboard_interface::sptr(new usrp1e_dboard_interface(impl)); -} - -/*********************************************************************** - * Structors - **********************************************************************/ -usrp1e_dboard_interface::usrp1e_dboard_interface(usrp1e_impl *impl){ - _impl = impl; -} - -usrp1e_dboard_interface::~usrp1e_dboard_interface(void){ - /* NOP */ -} - -/*********************************************************************** - * Clock Rates - **********************************************************************/ -double usrp1e_dboard_interface::get_rx_clock_rate(void){ - throw std::runtime_error("not implemented"); -} - -double usrp1e_dboard_interface::get_tx_clock_rate(void){ - throw std::runtime_error("not implemented"); -} - -/*********************************************************************** - * GPIO - **********************************************************************/ -void usrp1e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); -} - -void usrp1e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); -} - -boost::uint16_t usrp1e_dboard_interface::read_gpio(gpio_bank_t bank){ - throw std::runtime_error("not implemented"); -} - -void usrp1e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); -} - -/*********************************************************************** - * SPI - **********************************************************************/ -dboard_interface::byte_vector_t usrp1e_dboard_interface::transact_spi( - spi_dev_t dev, - spi_latch_t latch, - spi_push_t push, - const byte_vector_t &buf, - bool readback -){ - //load data struct - usrp_e_spi data; - data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; - data.slave = (dev == SPI_RX_DEV)? UE_SPI_CTRL_RXNEG : UE_SPI_CTRL_TXNEG; - data.length = buf.size() * 8; //bytes to bits - boost::uint8_t *data_bytes = reinterpret_cast(&data.data); - - //load the data - ASSERT_THROW(buf.size() <= sizeof(data.data)); - std::copy(buf.begin(), buf.end(), data_bytes); - - //load the flags - data.flags = 0; - data.flags |= (latch == SPI_LATCH_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; - data.flags |= (push == SPI_PUSH_RISE)? UE_SPI_PUSH_RISE : UE_SPI_PUSH_FALL; - - //call the spi ioctl - _impl->ioctl(USRP_E_SPI, &data); - - //unload the data - byte_vector_t ret(data.length/8); //bits to bytes - ASSERT_THROW(ret.size() <= sizeof(data.data)); - std::copy(data_bytes, data_bytes+ret.size(), ret.begin()); - return ret; -} - -/*********************************************************************** - * I2C - **********************************************************************/ -static const size_t max_i2c_data_bytes = 10; - -void usrp1e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ - //allocate some memory for this transaction - ASSERT_THROW(buf.size() <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = i2c_addr; - data.len = buf.size(); - std::copy(buf.begin(), buf.end(), data.data); - - //call the spi ioctl - _impl->ioctl(USRP_E_I2C_WRITE, &data); -} - -dboard_interface::byte_vector_t usrp1e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){ - //allocate some memory for this transaction - ASSERT_THROW(num_bytes <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = i2c_addr; - data.len = num_bytes; - - //call the spi ioctl - _impl->ioctl(USRP_E_I2C_READ, &data); - - //unload the data - byte_vector_t ret(data.len); - ASSERT_THROW(ret.size() == num_bytes); - std::copy(data.data, data.data+ret.size(), ret.begin()); - return ret; -} - -/*********************************************************************** - * Aux DAX/ADC - **********************************************************************/ -void usrp1e_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){ - throw std::runtime_error("not implemented"); -} - -int usrp1e_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){ - throw std::runtime_error("not implemented"); -} diff --git a/host/lib/usrp/usrp1e/dsp_impl.cpp b/host/lib/usrp/usrp1e/dsp_impl.cpp deleted file mode 100644 index 862b89184..000000000 --- a/host/lib/usrp/usrp1e/dsp_impl.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include -#include -#include "usrp1e_impl.hpp" - -using namespace uhd::usrp; - -/*********************************************************************** - * RX DDC Initialization - **********************************************************************/ -void usrp1e_impl::rx_ddc_init(void){ - _rx_ddc_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::rx_ddc_get, this, _1, _2), - boost::bind(&usrp1e_impl::rx_ddc_set, this, _1, _2) - ); -} - -/*********************************************************************** - * RX DDC Get - **********************************************************************/ -void usrp1e_impl::rx_ddc_get(const wax::obj &, wax::obj &){ - -} - -/*********************************************************************** - * RX DDC Set - **********************************************************************/ -void usrp1e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){ - -} - -/*********************************************************************** - * TX DUC Initialization - **********************************************************************/ -void usrp1e_impl::tx_duc_init(void){ - _tx_duc_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::tx_duc_get, this, _1, _2), - boost::bind(&usrp1e_impl::tx_duc_set, this, _1, _2) - ); -} - -/*********************************************************************** - * TX DUC Get - **********************************************************************/ -void usrp1e_impl::tx_duc_get(const wax::obj &, wax::obj &){ - -} - -/*********************************************************************** - * TX DUC Set - **********************************************************************/ -void usrp1e_impl::tx_duc_set(const wax::obj &, const wax::obj &){ - -} diff --git a/host/lib/usrp/usrp1e/fpga-downloader.cc b/host/lib/usrp/usrp1e/fpga-downloader.cc deleted file mode 100644 index f7c78b875..000000000 --- a/host/lib/usrp/usrp1e/fpga-downloader.cc +++ /dev/null @@ -1,262 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -/* - * Configuration connections - * - * CCK - MCSPI1_CLK - * DIN - MCSPI1_MOSI - * PROG_B - GPIO_175 - output (change mux) - * DONE - GPIO_173 - input (change mux) - * INIT_B - GPIO_114 - input (change mux) - * -*/ - -const unsigned int PROG_B = 175; -const unsigned int DONE = 173; -const unsigned int INIT_B = 114; - -//static std::string bit_file = "safe_u1e.bin"; - -const int BUF_SIZE = 4096; - -enum gpio_direction {IN, OUT}; - -class gpio { - public: - - gpio(unsigned int gpio_num, gpio_direction pin_direction); - - bool get_value(); - void set_value(bool state); - - private: - - std::stringstream base_path; - std::fstream value_file; -}; - -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) -{ - std::fstream export_file; - - 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::fstream direction_file; - 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; -} - -static void prepare_fpga_for_configuration(gpio &prog, gpio &)//init) -{ - - prog.set_value(true); - prog.set_value(false); - prog.set_value(true); - -#if 0 - bool ready_to_program(false); - unsigned int count(0); - do { - ready_to_program = init.get_value(); - count++; - - sleep(1); - } while (count < 10 && !ready_to_program); - - if (count == 10) { - std::cout << "FPGA not ready for programming." << std::endl; - exit(-1); - } -#endif -} - -spidev::spidev(std::string fname) -{ - int ret; - int mode = 0; - int speed = 12000000; - int bits = 8; - - 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 = 48000000; - tr.bits_per_word = 8; - - ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); - -} - -static void send_file_to_fpga(const std::string &file_name, gpio &error, gpio &done) -{ - std::ifstream bitstream; - - std::cout << "File name - " << file_name.c_str() << std::endl; - - bitstream.open(file_name.c_str(), std::ios::binary); - if (!bitstream.is_open()) - std::cout << "File " << file_name << " not opened succesfully." << std::endl; - - spidev spi("/dev/spidev1.0"); - char buf[BUF_SIZE]; - char rbuf[BUF_SIZE]; - - do { - bitstream.read(buf, BUF_SIZE); - spi.send(buf, rbuf, bitstream.gcount()); - - if (error.get_value()) - std::cout << "INIT_B went high, error occured." << std::endl; - - if (!done.get_value()) - std::cout << "Configuration complete." << std::endl; - - } while (bitstream.gcount() == BUF_SIZE); -} - -/* -int main(int argc, char *argv[]) -{ - - gpio gpio_prog_b(PROG_B, OUT); - gpio gpio_init_b(INIT_B, IN); - gpio gpio_done (DONE, IN); - - if (argc == 2) - bit_file = argv[1]; - - std::cout << "FPGA config file: " << bit_file << std::endl; - - prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); - - std::cout << "Done = " << gpio_done.get_value() << std::endl; - - send_file_to_fpga(bit_file, gpio_init_b, gpio_done); -} -*/ - -#include -void uhd::usrp::usrp1e::load_fpga(const std::string &bin_file){ - gpio gpio_prog_b(PROG_B, OUT); - gpio gpio_init_b(INIT_B, IN); - gpio gpio_done (DONE, IN); - - std::cout << "FPGA config file: " << bin_file << std::endl; - - prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); - - std::cout << "Done = " << gpio_done.get_value() << std::endl; - - send_file_to_fpga(bin_file, gpio_init_b, gpio_done); -} diff --git a/host/lib/usrp/usrp1e/mboard_impl.cpp b/host/lib/usrp/usrp1e/mboard_impl.cpp deleted file mode 100644 index b480f7616..000000000 --- a/host/lib/usrp/usrp1e/mboard_impl.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include -#include -#include "usrp1e_impl.hpp" - -using namespace uhd::usrp; - -/*********************************************************************** - * Mboard Initialization - **********************************************************************/ -void usrp1e_impl::mboard_init(void){ - _mboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::mboard_get, this, _1, _2), - boost::bind(&usrp1e_impl::mboard_set, this, _1, _2) - ); -} - -/*********************************************************************** - * Mboard Get - **********************************************************************/ -void usrp1e_impl::mboard_get(const wax::obj &, wax::obj &){ - -} - -/*********************************************************************** - * Mboard Set - **********************************************************************/ -void usrp1e_impl::mboard_set(const wax::obj &, const wax::obj &){ - -} diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.cpp b/host/lib/usrp/usrp1e/usrp1e_impl.cpp deleted file mode 100644 index 8230cc8e4..000000000 --- a/host/lib/usrp/usrp1e/usrp1e_impl.cpp +++ /dev/null @@ -1,178 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include -#include -#include -#include "usrp1e_impl.hpp" -#include //open -#include //ioctl - -using namespace uhd; -using namespace uhd::usrp; -namespace fs = boost::filesystem; - -STATIC_BLOCK(register_usrp1e_device){ - device::register_device(&usrp1e::discover, &usrp1e::make); -} - -/*********************************************************************** - * Helper Functions - **********************************************************************/ -static std::string abs_path(const std::string &file_path){ - return fs::system_complete(fs::path(file_path)).file_string(); -} - -/*********************************************************************** - * Discovery - **********************************************************************/ -device_addrs_t usrp1e::discover(const device_addr_t &device_addr){ - device_addrs_t usrp1e_addrs; - - //if a node was provided, use it and only it - if (device_addr.has_key("node")){ - if (not fs::exists(device_addr["node"])) return usrp1e_addrs; - device_addr_t new_addr; - new_addr["name"] = "USRP1E"; - new_addr["node"] = abs_path(device_addr["node"]); - usrp1e_addrs.push_back(new_addr); - } - - //otherwise look for a few nodes at small indexes - else{ - for(size_t i = 0; i < 5; i++){ - std::string node = str(boost::format("/dev/usrp1_e%d") % i); - if (not fs::exists(node)) continue; - device_addr_t new_addr; - new_addr["name"] = "USRP1E"; - new_addr["node"] = abs_path(node); - usrp1e_addrs.push_back(new_addr); - } - } - - return usrp1e_addrs; -} - -/*********************************************************************** - * Make - **********************************************************************/ -device::sptr usrp1e::make(const device_addr_t &device_addr){ - return sptr(new usrp1e_impl(device_addr["node"])); -} - -/*********************************************************************** - * Structors - **********************************************************************/ -usrp1e_impl::usrp1e_impl(const std::string &node){ - //open the device node and check file descriptor - if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ - throw std::runtime_error(str( - boost::format("Failed to open %s") % node - )); - } - - //initialize the mboard - mboard_init(); - - //initialize the dboards - dboard_init(); - - //initialize the dsps - rx_ddc_init(); - tx_duc_init(); -} - -usrp1e_impl::~usrp1e_impl(void){ - //close the device node file descriptor - ::close(_node_fd); -} - -/*********************************************************************** - * Misc Methods - **********************************************************************/ -void usrp1e_impl::ioctl(int request, void *mem){ - if (::ioctl(_node_fd, request, mem) < 0){ - throw std::runtime_error(str( - boost::format("ioctl failed with request %d") % request - )); - } -} - -/*********************************************************************** - * Device Get - **********************************************************************/ -void usrp1e_impl::get(const wax::obj &key_, wax::obj &val){ - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); - - //handle the get request conditioned on the key - switch(key.as()){ - case DEVICE_PROP_NAME: - val = std::string("usrp1e device"); - return; - - case DEVICE_PROP_MBOARD: - ASSERT_THROW(name == ""); - val = _mboard_proxy->get_link(); - return; - - case DEVICE_PROP_MBOARD_NAMES: - val = prop_names_t(1, ""); //vector of size 1 with empty string - return; - - case DEVICE_PROP_MAX_RX_SAMPLES: - val = size_t(_max_num_samples); - return; - - case DEVICE_PROP_MAX_TX_SAMPLES: - val = size_t(_max_num_samples); - return; - - } -} - -/*********************************************************************** - * Device Set - **********************************************************************/ -void usrp1e_impl::set(const wax::obj &, const wax::obj &){ - throw std::runtime_error("Cannot set in usrp1e device"); -} - -/*********************************************************************** - * Device IO (TODO) - **********************************************************************/ -size_t usrp1e_impl::send( - const boost::asio::const_buffer &, - const uhd::tx_metadata_t &, - const std::string &type -){ - if (type != "16sc"){ - throw std::runtime_error(str(boost::format("usrp1e send: cannot handle type \"%s\"") % type)); - } - return 0; -} - -size_t usrp1e_impl::recv( - const boost::asio::mutable_buffer &, - uhd::rx_metadata_t &, - const std::string &type -){ - if (type != "16sc"){ - throw std::runtime_error(str(boost::format("usrp1e recv: cannot handle type \"%s\"") % type)); - } - return 0; -} diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.hpp b/host/lib/usrp/usrp1e/usrp1e_impl.hpp deleted file mode 100644 index c199a0465..000000000 --- a/host/lib/usrp/usrp1e/usrp1e_impl.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include -#include - -#ifndef INCLUDED_USRP1E_IMPL_HPP -#define INCLUDED_USRP1E_IMPL_HPP - -class usrp1e_impl; // dummy class declaration - -/*! - * Make a usrp1e dboard interface. - * \param impl a pointer to the usrp1e impl object - * \return a sptr to a new dboard interface - */ -uhd::usrp::dboard_interface::sptr make_usrp1e_dboard_interface(usrp1e_impl *impl); - -/*! - * Simple wax obj proxy class: - * Provides a wax obj interface for a set and a get function. - * This allows us to create nested properties structures - * while maintaining flattened code within the implementation. - */ -class wax_obj_proxy : public wax::obj{ -public: - typedef boost::function get_t; - typedef boost::function set_t; - typedef boost::shared_ptr sptr; - - static sptr make(const get_t &get, const set_t &set){ - return sptr(new wax_obj_proxy(get, set)); - } - - ~wax_obj_proxy(void){ - /* NOP */ - } - -private: - get_t _get; - set_t _set; - - wax_obj_proxy(const get_t &get, const set_t &set){ - _get = get; - _set = set; - }; - - void get(const wax::obj &key, wax::obj &val){ - return _get(key, val); - } - - void set(const wax::obj &key, const wax::obj &val){ - return _set(key, val); - } -}; - -/*! - * USRP1E implementation guts: - * The implementation details are encapsulated here. - * Handles properties on the mboard, dboard, dsps... - */ -class usrp1e_impl : public uhd::device{ -public: - //structors - usrp1e_impl(const std::string &node); - ~usrp1e_impl(void); - - //the io interface - size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const std::string &); - size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &); - - /*! - * Perform an ioctl call on the device node file descriptor. - * This will throw when the internal ioctl call fails. - * \param request the control word - * \param mem pointer to some memory - */ - void ioctl(int request, void *mem); - -private: - static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); - int _node_fd; - - //device functions and settings - void get(const wax::obj &, wax::obj &); - void set(const wax::obj &, const wax::obj &); - - //mboard functions and settings - void mboard_init(void); - void mboard_get(const wax::obj &, wax::obj &); - void mboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _mboard_proxy; - - //xx dboard functions and settings - void dboard_init(void); - uhd::usrp::dboard_manager::sptr _dboard_manager; - - //rx dboard functions and settings - void rx_dboard_get(const wax::obj &, wax::obj &); - void rx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _rx_dboard_proxy; - - //tx dboard functions and settings - void tx_dboard_get(const wax::obj &, wax::obj &); - void tx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _tx_dboard_proxy; - - //rx ddc functions and settings - void rx_ddc_init(void); - void rx_ddc_get(const wax::obj &, wax::obj &); - void rx_ddc_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _rx_ddc_proxy; - - //tx duc functions and settings - void tx_duc_init(void); - void tx_duc_get(const wax::obj &, wax::obj &); - void tx_duc_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _tx_duc_proxy; -}; - -#endif /* INCLUDED_USRP1E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp1e/usrp1e_none.cpp b/host/lib/usrp/usrp1e/usrp1e_none.cpp deleted file mode 100644 index 94243523d..000000000 --- a/host/lib/usrp/usrp1e/usrp1e_none.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include - -using namespace uhd; -using namespace uhd::usrp; - -/*! - * This file defines the usrp1e discover and make functions - * when the required kernel module headers are not present. - */ - -device_addrs_t usrp1e::find(const device_addr_t &){ - return device_addrs_t(); //return empty list -} - -device::sptr usrp1e::make(const device_addr_t &){ - throw std::runtime_error("this build has no usrp1e support"); -} - -void usrp1e::load_fpga(const std::string &){ - throw std::runtime_error("this build has no usrp1e support"); -} diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 67fbdf8d2..b0ee395fb 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -29,7 +29,7 @@ using namespace uhd::usrp; using namespace uhd::transport; namespace asio = boost::asio; -STATIC_BLOCK(register_usrp2_device){ +UHD_STATIC_BLOCK(register_usrp2_device){ device::register_device(&usrp2::find, &usrp2::make); } diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp new file mode 100644 index 000000000..88d04ce7a --- /dev/null +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -0,0 +1,76 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include "usrp_e_impl.hpp" + +using namespace uhd::usrp; + +/*********************************************************************** + * Dboard Initialization + **********************************************************************/ +void usrp_e_impl::dboard_init(void){ + dboard_id_t rx_dboard_id = dboard_id::NONE; //TODO get these from the eeprom + dboard_id_t tx_dboard_id = dboard_id::NONE; + + //create a new dboard interface and manager + dboard_interface::sptr dboard_interface( + make_usrp_e_dboard_interface(this) + ); + _dboard_manager = dboard_manager::make( + rx_dboard_id, tx_dboard_id, dboard_interface + ); + + //setup the dboard proxies + _rx_dboard_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::rx_dboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::rx_dboard_set, this, _1, _2) + ); + _tx_dboard_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::tx_dboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::tx_dboard_set, this, _1, _2) + ); +} + +/*********************************************************************** + * RX Dboard Get + **********************************************************************/ +void usrp_e_impl::rx_dboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * RX Dboard Set + **********************************************************************/ +void usrp_e_impl::rx_dboard_set(const wax::obj &, const wax::obj &){ + +} + +/*********************************************************************** + * TX Dboard Get + **********************************************************************/ +void usrp_e_impl::tx_dboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * TX Dboard Set + **********************************************************************/ +void usrp_e_impl::tx_dboard_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp_e/dboard_interface.cpp b/host/lib/usrp/usrp_e/dboard_interface.cpp new file mode 100644 index 000000000..c7c7d8c1f --- /dev/null +++ b/host/lib/usrp/usrp_e/dboard_interface.cpp @@ -0,0 +1,189 @@ +// +// Copyright 2010 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 . +// + +#include +#include //std::copy +#include "usrp_e_impl.hpp" +#include + +using namespace uhd::usrp; + +class usrp_e_dboard_interface : public dboard_interface{ +public: + usrp_e_dboard_interface(usrp_e_impl *impl); + ~usrp_e_dboard_interface(void); + + void write_aux_dac(unit_type_t, int, int); + int read_aux_adc(unit_type_t, int); + + void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t); + void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t); + void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t); + boost::uint16_t read_gpio(gpio_bank_t); + + void write_i2c(int, const byte_vector_t &); + byte_vector_t read_i2c(int, size_t); + + double get_rx_clock_rate(void); + double get_tx_clock_rate(void); + +private: + byte_vector_t transact_spi( + spi_dev_t dev, + spi_latch_t latch, + spi_push_t push, + const byte_vector_t &buf, + bool readback + ); + + usrp_e_impl *_impl; +}; + +/*********************************************************************** + * Make Function + **********************************************************************/ +dboard_interface::sptr make_usrp_e_dboard_interface(usrp_e_impl *impl){ + return dboard_interface::sptr(new usrp_e_dboard_interface(impl)); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp_e_dboard_interface::usrp_e_dboard_interface(usrp_e_impl *impl){ + _impl = impl; +} + +usrp_e_dboard_interface::~usrp_e_dboard_interface(void){ + /* NOP */ +} + +/*********************************************************************** + * Clock Rates + **********************************************************************/ +double usrp_e_dboard_interface::get_rx_clock_rate(void){ + throw std::runtime_error("not implemented"); +} + +double usrp_e_dboard_interface::get_tx_clock_rate(void){ + throw std::runtime_error("not implemented"); +} + +/*********************************************************************** + * GPIO + **********************************************************************/ +void usrp_e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ + throw std::runtime_error("not implemented"); +} + +void usrp_e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ + throw std::runtime_error("not implemented"); +} + +boost::uint16_t usrp_e_dboard_interface::read_gpio(gpio_bank_t bank){ + throw std::runtime_error("not implemented"); +} + +void usrp_e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){ + throw std::runtime_error("not implemented"); +} + +/*********************************************************************** + * SPI + **********************************************************************/ +dboard_interface::byte_vector_t usrp_e_dboard_interface::transact_spi( + spi_dev_t dev, + spi_latch_t latch, + spi_push_t push, + const byte_vector_t &buf, + bool readback +){ + //load data struct + usrp_e_spi data; + data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; + data.slave = (dev == SPI_RX_DEV)? UE_SPI_CTRL_RXNEG : UE_SPI_CTRL_TXNEG; + data.length = buf.size() * 8; //bytes to bits + boost::uint8_t *data_bytes = reinterpret_cast(&data.data); + + //load the data + ASSERT_THROW(buf.size() <= sizeof(data.data)); + std::copy(buf.begin(), buf.end(), data_bytes); + + //load the flags + data.flags = 0; + data.flags |= (latch == SPI_LATCH_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (push == SPI_PUSH_RISE)? UE_SPI_PUSH_RISE : UE_SPI_PUSH_FALL; + + //call the spi ioctl + _impl->ioctl(USRP_E_SPI, &data); + + //unload the data + byte_vector_t ret(data.length/8); //bits to bytes + ASSERT_THROW(ret.size() <= sizeof(data.data)); + std::copy(data_bytes, data_bytes+ret.size(), ret.begin()); + return ret; +} + +/*********************************************************************** + * I2C + **********************************************************************/ +static const size_t max_i2c_data_bytes = 10; + +void usrp_e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ + //allocate some memory for this transaction + ASSERT_THROW(buf.size() <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c &data = reinterpret_cast(mem); + data.addr = i2c_addr; + data.len = buf.size(); + std::copy(buf.begin(), buf.end(), data.data); + + //call the spi ioctl + _impl->ioctl(USRP_E_I2C_WRITE, &data); +} + +dboard_interface::byte_vector_t usrp_e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){ + //allocate some memory for this transaction + ASSERT_THROW(num_bytes <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c &data = reinterpret_cast(mem); + data.addr = i2c_addr; + data.len = num_bytes; + + //call the spi ioctl + _impl->ioctl(USRP_E_I2C_READ, &data); + + //unload the data + byte_vector_t ret(data.len); + ASSERT_THROW(ret.size() == num_bytes); + std::copy(data.data, data.data+ret.size(), ret.begin()); + return ret; +} + +/*********************************************************************** + * Aux DAX/ADC + **********************************************************************/ +void usrp_e_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){ + throw std::runtime_error("not implemented"); +} + +int usrp_e_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){ + throw std::runtime_error("not implemented"); +} diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp new file mode 100644 index 000000000..e32c76a3d --- /dev/null +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -0,0 +1,69 @@ +// +// Copyright 2010 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 . +// + +#include +#include "usrp_e_impl.hpp" + +using namespace uhd::usrp; + +/*********************************************************************** + * RX DDC Initialization + **********************************************************************/ +void usrp_e_impl::rx_ddc_init(void){ + _rx_ddc_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::rx_ddc_get, this, _1, _2), + boost::bind(&usrp_e_impl::rx_ddc_set, this, _1, _2) + ); +} + +/*********************************************************************** + * RX DDC Get + **********************************************************************/ +void usrp_e_impl::rx_ddc_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * RX DDC Set + **********************************************************************/ +void usrp_e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){ + +} + +/*********************************************************************** + * TX DUC Initialization + **********************************************************************/ +void usrp_e_impl::tx_duc_init(void){ + _tx_duc_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::tx_duc_get, this, _1, _2), + boost::bind(&usrp_e_impl::tx_duc_set, this, _1, _2) + ); +} + +/*********************************************************************** + * TX DUC Get + **********************************************************************/ +void usrp_e_impl::tx_duc_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * TX DUC Set + **********************************************************************/ +void usrp_e_impl::tx_duc_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp_e/fpga-downloader.cc b/host/lib/usrp/usrp_e/fpga-downloader.cc new file mode 100644 index 000000000..4429786a9 --- /dev/null +++ b/host/lib/usrp/usrp_e/fpga-downloader.cc @@ -0,0 +1,262 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* + * Configuration connections + * + * CCK - MCSPI1_CLK + * DIN - MCSPI1_MOSI + * PROG_B - GPIO_175 - output (change mux) + * DONE - GPIO_173 - input (change mux) + * INIT_B - GPIO_114 - input (change mux) + * +*/ + +const unsigned int PROG_B = 175; +const unsigned int DONE = 173; +const unsigned int INIT_B = 114; + +//static std::string bit_file = "safe_u1e.bin"; + +const int BUF_SIZE = 4096; + +enum gpio_direction {IN, OUT}; + +class gpio { + public: + + gpio(unsigned int gpio_num, gpio_direction pin_direction); + + bool get_value(); + void set_value(bool state); + + private: + + std::stringstream base_path; + std::fstream value_file; +}; + +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) +{ + std::fstream export_file; + + 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::fstream direction_file; + 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; +} + +static void prepare_fpga_for_configuration(gpio &prog, gpio &)//init) +{ + + prog.set_value(true); + prog.set_value(false); + prog.set_value(true); + +#if 0 + bool ready_to_program(false); + unsigned int count(0); + do { + ready_to_program = init.get_value(); + count++; + + sleep(1); + } while (count < 10 && !ready_to_program); + + if (count == 10) { + std::cout << "FPGA not ready for programming." << std::endl; + exit(-1); + } +#endif +} + +spidev::spidev(std::string fname) +{ + int ret; + int mode = 0; + int speed = 12000000; + int bits = 8; + + 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 = 48000000; + tr.bits_per_word = 8; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + +} + +static void send_file_to_fpga(const std::string &file_name, gpio &error, gpio &done) +{ + std::ifstream bitstream; + + std::cout << "File name - " << file_name.c_str() << std::endl; + + bitstream.open(file_name.c_str(), std::ios::binary); + if (!bitstream.is_open()) + std::cout << "File " << file_name << " not opened succesfully." << std::endl; + + spidev spi("/dev/spidev1.0"); + char buf[BUF_SIZE]; + char rbuf[BUF_SIZE]; + + do { + bitstream.read(buf, BUF_SIZE); + spi.send(buf, rbuf, bitstream.gcount()); + + if (error.get_value()) + std::cout << "INIT_B went high, error occured." << std::endl; + + if (!done.get_value()) + std::cout << "Configuration complete." << std::endl; + + } while (bitstream.gcount() == BUF_SIZE); +} + +/* +int main(int argc, char *argv[]) +{ + + gpio gpio_prog_b(PROG_B, OUT); + gpio gpio_init_b(INIT_B, IN); + gpio gpio_done (DONE, IN); + + if (argc == 2) + bit_file = argv[1]; + + std::cout << "FPGA config file: " << bit_file << std::endl; + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "Done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bit_file, gpio_init_b, gpio_done); +} +*/ + +#include +void uhd::usrp::usrp_e::load_fpga(const std::string &bin_file){ + gpio gpio_prog_b(PROG_B, OUT); + gpio gpio_init_b(INIT_B, IN); + gpio gpio_done (DONE, IN); + + std::cout << "FPGA config file: " << bin_file << std::endl; + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "Done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bin_file, gpio_init_b, gpio_done); +} diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp new file mode 100644 index 000000000..333fb2e51 --- /dev/null +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -0,0 +1,45 @@ +// +// Copyright 2010 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 . +// + +#include +#include "usrp_e_impl.hpp" + +using namespace uhd::usrp; + +/*********************************************************************** + * Mboard Initialization + **********************************************************************/ +void usrp_e_impl::mboard_init(void){ + _mboard_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::mboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::mboard_set, this, _1, _2) + ); +} + +/*********************************************************************** + * Mboard Get + **********************************************************************/ +void usrp_e_impl::mboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * Mboard Set + **********************************************************************/ +void usrp_e_impl::mboard_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp new file mode 100644 index 000000000..e821add8c --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -0,0 +1,179 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_impl.hpp" +#include +#include +#include +#include +#include //open +#include //ioctl + +using namespace uhd; +using namespace uhd::usrp; +namespace fs = boost::filesystem; + +UHD_STATIC_BLOCK(register_usrp_e_device){ + device::register_device(&usrp_e::find, &usrp_e::make); +} + +/*********************************************************************** + * Helper Functions + **********************************************************************/ +static std::string abs_path(const std::string &file_path){ + return fs::system_complete(fs::path(file_path)).file_string(); +} + +/*********************************************************************** + * Discovery + **********************************************************************/ +device_addrs_t usrp_e::find(const device_addr_t &device_addr){ + device_addrs_t usrp_e_addrs; + + //if a node was provided, use it and only it + if (device_addr.has_key("node")){ + if (not fs::exists(device_addr["node"])) return usrp_e_addrs; + device_addr_t new_addr; + new_addr["name"] = "USRP-E"; + new_addr["node"] = abs_path(device_addr["node"]); + usrp_e_addrs.push_back(new_addr); + } + + //otherwise look for a few nodes at small indexes + else{ + for(size_t i = 0; i < 5; i++){ + std::string node = str(boost::format("/dev/usrp1_e%d") % i); + if (not fs::exists(node)) continue; + device_addr_t new_addr; + new_addr["name"] = "USRP-E"; + new_addr["node"] = abs_path(node); + usrp_e_addrs.push_back(new_addr); + } + } + + return usrp_e_addrs; +} + +/*********************************************************************** + * Make + **********************************************************************/ +device::sptr usrp_e::make(const device_addr_t &device_addr){ + return sptr(new usrp_e_impl(device_addr["node"])); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp_e_impl::usrp_e_impl(const std::string &node){ + //open the device node and check file descriptor + if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ + throw std::runtime_error(str( + boost::format("Failed to open %s") % node + )); + } + + //initialize the mboard + mboard_init(); + + //initialize the dboards + dboard_init(); + + //initialize the dsps + rx_ddc_init(); + tx_duc_init(); +} + +usrp_e_impl::~usrp_e_impl(void){ + //close the device node file descriptor + ::close(_node_fd); +} + +/*********************************************************************** + * Misc Methods + **********************************************************************/ +void usrp_e_impl::ioctl(int request, void *mem){ + if (::ioctl(_node_fd, request, mem) < 0){ + throw std::runtime_error(str( + boost::format("ioctl failed with request %d") % request + )); + } +} + +/*********************************************************************** + * Device Get + **********************************************************************/ +void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case DEVICE_PROP_NAME: + val = std::string("usrp-e device"); + return; + + case DEVICE_PROP_MBOARD: + ASSERT_THROW(name == ""); + val = _mboard_proxy->get_link(); + return; + + case DEVICE_PROP_MBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + case DEVICE_PROP_MAX_RX_SAMPLES: + val = size_t(_max_num_samples); + return; + + case DEVICE_PROP_MAX_TX_SAMPLES: + val = size_t(_max_num_samples); + return; + + } +} + +/*********************************************************************** + * Device Set + **********************************************************************/ +void usrp_e_impl::set(const wax::obj &, const wax::obj &){ + throw std::runtime_error("Cannot set in usrp-e device"); +} + +/*********************************************************************** + * Device IO (TODO) + **********************************************************************/ +size_t usrp_e_impl::send( + const boost::asio::const_buffer &, + const uhd::tx_metadata_t &, + const io_type_t & +){ + if (true){ + throw std::runtime_error(str(boost::format("usrp-e send: cannot handle type \"%s\"") % "")); + } + return 0; +} + +size_t usrp_e_impl::recv( + const boost::asio::mutable_buffer &, + uhd::rx_metadata_t &, + const io_type_t & +){ + if (true){ + throw std::runtime_error(str(boost::format("usrp-e recv: cannot handle type \"%s\"") % "")); + } + return 0; +} diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp new file mode 100644 index 000000000..e593b13ad --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -0,0 +1,135 @@ +// +// Copyright 2010 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 . +// + +#include +#include + +#ifndef INCLUDED_USRP_E_IMPL_HPP +#define INCLUDED_USRP_E_IMPL_HPP + +class usrp_e_impl; // dummy class declaration + +/*! + * Make a usrp_e dboard interface. + * \param impl a pointer to the usrp_e impl object + * \return a sptr to a new dboard interface + */ +uhd::usrp::dboard_interface::sptr make_usrp_e_dboard_interface(usrp_e_impl *impl); + +/*! + * Simple wax obj proxy class: + * Provides a wax obj interface for a set and a get function. + * This allows us to create nested properties structures + * while maintaining flattened code within the implementation. + */ +class wax_obj_proxy : public wax::obj{ +public: + typedef boost::function get_t; + typedef boost::function set_t; + typedef boost::shared_ptr sptr; + + static sptr make(const get_t &get, const set_t &set){ + return sptr(new wax_obj_proxy(get, set)); + } + + ~wax_obj_proxy(void){ + /* NOP */ + } + +private: + get_t _get; + set_t _set; + + wax_obj_proxy(const get_t &get, const set_t &set){ + _get = get; + _set = set; + }; + + void get(const wax::obj &key, wax::obj &val){ + return _get(key, val); + } + + void set(const wax::obj &key, const wax::obj &val){ + return _set(key, val); + } +}; + +/*! + * USRP1E implementation guts: + * The implementation details are encapsulated here. + * Handles properties on the mboard, dboard, dsps... + */ +class usrp_e_impl : public uhd::device{ +public: + //structors + usrp_e_impl(const std::string &node); + ~usrp_e_impl(void); + + //the io interface + size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &); + size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &); + + /*! + * Perform an ioctl call on the device node file descriptor. + * This will throw when the internal ioctl call fails. + * \param request the control word + * \param mem pointer to some memory + */ + void ioctl(int request, void *mem); + +private: + static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); + int _node_fd; + + //device functions and settings + void get(const wax::obj &, wax::obj &); + void set(const wax::obj &, const wax::obj &); + + //mboard functions and settings + void mboard_init(void); + void mboard_get(const wax::obj &, wax::obj &); + void mboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _mboard_proxy; + + //xx dboard functions and settings + void dboard_init(void); + uhd::usrp::dboard_manager::sptr _dboard_manager; + + //rx dboard functions and settings + void rx_dboard_get(const wax::obj &, wax::obj &); + void rx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _rx_dboard_proxy; + + //tx dboard functions and settings + void tx_dboard_get(const wax::obj &, wax::obj &); + void tx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _tx_dboard_proxy; + + //rx ddc functions and settings + void rx_ddc_init(void); + void rx_ddc_get(const wax::obj &, wax::obj &); + void rx_ddc_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _rx_ddc_proxy; + + //tx duc functions and settings + void tx_duc_init(void); + void tx_duc_get(const wax::obj &, wax::obj &); + void tx_duc_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _tx_duc_proxy; +}; + +#endif /* INCLUDED_USRP_E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp_e/usrp_e_none.cpp b/host/lib/usrp/usrp_e/usrp_e_none.cpp new file mode 100644 index 000000000..09a3c6946 --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_none.cpp @@ -0,0 +1,38 @@ +// +// Copyright 2010 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 . +// + +#include + +using namespace uhd; +using namespace uhd::usrp; + +/*! + * This file defines the usrp1e discover and make functions + * when the required kernel module headers are not present. + */ + +device_addrs_t usrp_e::find(const device_addr_t &){ + return device_addrs_t(); //return empty list +} + +device::sptr usrp_e::make(const device_addr_t &){ + throw std::runtime_error("this build has no usrp1e support"); +} + +void usrp_e::load_fpga(const std::string &){ + throw std::runtime_error("this build has no usrp1e support"); +} diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index 99e648d8a..0b1e058ef 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -19,8 +19,9 @@ ADD_EXECUTABLE(uhd_find_devices uhd_find_devices.cpp) TARGET_LINK_LIBRARIES(uhd_find_devices uhd) INSTALL(TARGETS uhd_find_devices RUNTIME DESTINATION ${RUNTIME_DIR}) -ADD_EXECUTABLE(usrp1e_load_fpga usrp1e_load_fpga.cpp) -TARGET_LINK_LIBRARIES(usrp1e_load_fpga uhd) +ADD_EXECUTABLE(usrp_e_load_fpga usrp_e_load_fpga.cpp) +TARGET_LINK_LIBRARIES(usrp_e_load_fpga uhd) +INSTALL(TARGETS usrp_e_load_fpga RUNTIME DESTINATION ${PKG_DATA_DIR}/utils) ADD_EXECUTABLE(usrp2_burner usrp2_burner.cpp) TARGET_LINK_LIBRARIES(usrp2_burner uhd) diff --git a/host/utils/usrp_e_load_fpga.cpp b/host/utils/usrp_e_load_fpga.cpp new file mode 100644 index 000000000..403130b53 --- /dev/null +++ b/host/utils/usrp_e_load_fpga.cpp @@ -0,0 +1,47 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include +#include + +namespace po = boost::program_options; + +int main(int argc, char *argv[]){ + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("file", po::value(), "path to fpga bin file") + ; + + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help") or vm.count("file") == 0){ + std::cout << boost::format("USRP1E Load FPGA %s") % desc << std::endl; + return ~0; + } + + //load the fpga + std::string file = vm["file"].as(); + uhd::usrp::usrp_e::load_fpga(file); + + return 0; +} -- cgit v1.2.3 From 2f81e2f7086eec7c0ae4370555ddae6e2f6ce2de Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 30 Mar 2010 17:24:39 +0000 Subject: tweak usrp-e cmake config --- host/lib/CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'host') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index db5e9d273..ff002bfc0 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -54,18 +54,18 @@ LIST(APPEND libuhd_sources MESSAGE(STATUS "Configuring usrp-e support...") INCLUDE(CheckIncludeFiles) -SET(usrp1e_required_headers +SET(usrp_e_required_headers linux/ioctl.h linux/spi/spidev.h - linux/usrp1_e.h + linux/usrp_e.h ) CHECK_INCLUDE_FILES( - "${usrp1e_required_headers}" - HAS_USRP1E_REQUIRED_HEADERS + "${usrp_e_required_headers}" + HAVE_USRP_E_REQUIRED_HEADERS ) -IF(HAS_USRP1E_REQUIRED_HEADERS) - MESSAGE(STATUS " Building usrp1e support.") +IF(HAVE_USRP_E_REQUIRED_HEADERS) + MESSAGE(STATUS " Building usrp-e support.") LIST(APPEND libuhd_sources usrp/usrp_e/dboard_impl.cpp usrp/usrp_e/dboard_interface.cpp @@ -74,12 +74,12 @@ IF(HAS_USRP1E_REQUIRED_HEADERS) usrp/usrp_e/mboard_impl.cpp usrp/usrp_e/usrp_e_impl.cpp ) -ELSE(HAS_USRP1E_REQUIRED_HEADERS) - MESSAGE(STATUS " Skipping usrp1e support.") +ELSE(HAVE_USRP_E_REQUIRED_HEADERS) + MESSAGE(STATUS " Skipping usrp-e support.") LIST(APPEND libuhd_sources usrp/usrp_e/usrp_e_none.cpp ) -ENDIF(HAS_USRP1E_REQUIRED_HEADERS) +ENDIF(HAVE_USRP_E_REQUIRED_HEADERS) ######################################################################## # Setup defines for module loading -- cgit v1.2.3 From 03be4d0673c5e0f597db7d27f535956a591bbeb7 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 30 Mar 2010 17:52:27 +0000 Subject: filled in some gpio handling code, some mboard impl, added usrp_e_regs (like memory map) --- host/include/uhd/types/clock_config.hpp | 1 + host/lib/usrp/usrp_e/dboard_impl.cpp | 1 - host/lib/usrp/usrp_e/dboard_interface.cpp | 89 +++++++++++++++++++++++++++---- host/lib/usrp/usrp_e/mboard_impl.cpp | 77 ++++++++++++++++++++++++-- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 3 ++ host/lib/usrp/usrp_e/usrp_e_regs.hpp | 49 +++++++++++++++++ 6 files changed, 206 insertions(+), 14 deletions(-) create mode 100644 host/lib/usrp/usrp_e/usrp_e_regs.hpp (limited to 'host') diff --git a/host/include/uhd/types/clock_config.hpp b/host/include/uhd/types/clock_config.hpp index 42d74ad90..9342fbb7b 100644 --- a/host/include/uhd/types/clock_config.hpp +++ b/host/include/uhd/types/clock_config.hpp @@ -29,6 +29,7 @@ namespace uhd{ */ struct UHD_API clock_config_t{ enum ref_source_t { + REF_AUTO = 'a', //automatic (device specific) REF_INT = 'i', //internal reference REF_SMA = 's', //external sma port REF_MIMO = 'm' //mimo cable (usrp2 only) diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index 88d04ce7a..7c87361e0 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -16,7 +16,6 @@ // #include -#include #include "usrp_e_impl.hpp" using namespace uhd::usrp; diff --git a/host/lib/usrp/usrp_e/dboard_interface.cpp b/host/lib/usrp/usrp_e/dboard_interface.cpp index c7c7d8c1f..a343d93b8 100644 --- a/host/lib/usrp/usrp_e/dboard_interface.cpp +++ b/host/lib/usrp/usrp_e/dboard_interface.cpp @@ -15,10 +15,14 @@ // along with this program. If not, see . // +#include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" +#include #include +#include #include //std::copy -#include "usrp_e_impl.hpp" -#include +#include +#include using namespace uhd::usrp; @@ -31,8 +35,8 @@ public: int read_aux_adc(unit_type_t, int); void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t); - void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t); - void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t); + void set_gpio_ddr(gpio_bank_t, boost::uint16_t); + void write_gpio(gpio_bank_t, boost::uint16_t); boost::uint16_t read_gpio(gpio_bank_t); void write_i2c(int, const byte_vector_t &); @@ -85,20 +89,85 @@ double usrp_e_dboard_interface::get_tx_clock_rate(void){ /*********************************************************************** * GPIO **********************************************************************/ -void usrp_e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); +void usrp_e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value){ + //define mapping of gpio bank to register address + static const uhd::dict bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_ddr)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_ddr)) + ; + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + _impl->ioctl(USRP_E_WRITE_CTL16, &data); } -void usrp_e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); +void usrp_e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value){ + //define mapping of gpio bank to register address + static const uhd::dict bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_io)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_io)) + ; + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + _impl->ioctl(USRP_E_WRITE_CTL16, &data); } boost::uint16_t usrp_e_dboard_interface::read_gpio(gpio_bank_t bank){ - throw std::runtime_error("not implemented"); + //define mapping of gpio bank to register address + static const uhd::dict bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_io)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_io)) + ; + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 1; + + //call the ioctl + _impl->ioctl(USRP_E_READ_CTL16, &data); + + return data.buf[0]; } void usrp_e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); + //define mapping of gpio bank to register address + static const uhd::dict bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_sel_low)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_sel_low)) + ; + + //set the gpio selection mux to atr or software controlled + boost::uint16_t low_sel = 0, high_sel = 0; + for(size_t i = 0; i < 16; i++){ + boost::uint16_t code = (mask & (1 << i))? GPIO_SEL_ATR : GPIO_SEL_SW; + if(i < 8) low_sel |= code << (2*i-0); + else high_sel |= code << (2*i-8); + } + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 2; + data.buf[0] = low_sel; + data.buf[1] = high_sel; + + //call the ioctl + _impl->ioctl(USRP_E_READ_CTL16, &data); + + //----------------------------------------> TODO + //TODO set the atr regs } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index 333fb2e51..1d3f9f466 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -15,9 +15,12 @@ // along with this program. If not, see . // -#include #include "usrp_e_impl.hpp" +#include +#include +#include +using namespace uhd; using namespace uhd::usrp; /*********************************************************************** @@ -28,13 +31,81 @@ void usrp_e_impl::mboard_init(void){ boost::bind(&usrp_e_impl::mboard_get, this, _1, _2), boost::bind(&usrp_e_impl::mboard_set, this, _1, _2) ); + + //init the clock config + _clock_config.ref_source = clock_config_t::REF_AUTO; + _clock_config.pps_source = clock_config_t::PPS_SMA; + + //TODO poke the clock config regs } /*********************************************************************** * Mboard Get **********************************************************************/ -void usrp_e_impl::mboard_get(const wax::obj &, wax::obj &){ - +void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + + //handle the get request conditioned on the key + switch(key.as()){ + case MBOARD_PROP_NAME: + val = std::string("usrp-e mboard"); + return; + + case MBOARD_PROP_OTHERS: + val = prop_names_t(); + return; + + case MBOARD_PROP_RX_DBOARD: + ASSERT_THROW(name == ""); + val = _rx_dboard_proxy->get_link(); + return; + + case MBOARD_PROP_RX_DBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + case MBOARD_PROP_TX_DBOARD: + ASSERT_THROW(name == ""); + val = _tx_dboard_proxy->get_link(); + return; + + case MBOARD_PROP_TX_DBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + case MBOARD_PROP_CLOCK_RATE: + //val = TODO probably remove this property + return; + + case MBOARD_PROP_RX_DSP: + ASSERT_THROW(name == "ddc0"); + val = _rx_ddc_proxy->get_link(); + return; + + case MBOARD_PROP_RX_DSP_NAMES: + val = prop_names_t(1, "ddc0"); + return; + + case MBOARD_PROP_TX_DSP: + ASSERT_THROW(name == "duc0"); + val = _tx_duc_proxy->get_link(); + return; + + case MBOARD_PROP_TX_DSP_NAMES: + val = prop_names_t(1, "duc0"); + return; + + case MBOARD_PROP_CLOCK_CONFIG: + val = _clock_config; + return; + + case MBOARD_PROP_TIME_NOW: + case MBOARD_PROP_TIME_NEXT_PPS: + throw std::runtime_error("Error: trying to get write-only property on usrp-e mboard"); + + } } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index e593b13ad..643589754 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // +#include #include #include @@ -95,6 +96,8 @@ private: static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); int _node_fd; + uhd::clock_config_t _clock_config; + //device functions and settings void get(const wax::obj &, wax::obj &); void set(const wax::obj &, const wax::obj &); diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp new file mode 100644 index 000000000..219f459a5 --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -0,0 +1,49 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_USRP_E_REGS_HPP +#define INCLUDED_USRP_E_REGS_HPP + +#include + +//////////////////////////////////////////////// +// GPIO, Slave 4 +// +// These go to the daughterboard i/o pins + +#define GPIO_BASE 0x40 + +struct gpio_regs_t{ + boost::uint16_t rx_io; // tx data in high 16, rx in low 16 + boost::uint16_t tx_io; + boost::uint16_t rx_ddr; // 32 bits, 1 means output. tx in high 16, rx in low 16 + boost::uint16_t tx_ddr; + boost::uint16_t tx_sel_low; // 16 2-bit fields select which source goes to TX DB + boost::uint16_t tx_sel_high; + boost::uint16_t rx_sel_low; // 16 2-bit fields select which source goes to RX DB + boost::uint16_t rx_sel_high; +}; + +// each 2-bit sel field is layed out this way +#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg +#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic +#define GPIO_SEL_DEBUG_0 2 // if pin is an output, debug lines from FPGA fabric +#define GPIO_SEL_DEBUG_1 3 // if pin is an output, debug lines from FPGA fabric + +//#define gpio_base ((gpio_regs_t *) GPIO_BASE) + +#endif /* INCLUDED_USRP_E_REGS_HPP */ -- cgit v1.2.3 From 3e01c94fe0c690293f13a09666deb79fcb6af58c Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 1 Apr 2010 12:44:55 +0000 Subject: Spi word length is in bits, not bytes. --- host/apps/omap_debug/usrp-e-spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c index 1af47b172..f7131bbe3 100644 --- a/host/apps/omap_debug/usrp-e-spi.c +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -26,7 +26,7 @@ int main(int argc, char *argv[]) spi_dat.slave = slave; spi_dat.data = data; - spi_dat.length = 2; + spi_dat.length = 32; spi_dat.flags = 0; if (*argv[1] == 'r') { -- cgit v1.2.3 From 9b30d7293f93ec340c23448147c425c398c01db4 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 1 Apr 2010 19:27:59 +0000 Subject: Allow variable length spi messages. --- host/apps/omap_debug/usrp-e-spi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c index f7131bbe3..de1409647 100644 --- a/host/apps/omap_debug/usrp-e-spi.c +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -10,23 +10,24 @@ int main(int argc, char *argv[]) { - int fp, slave, data, ret; + int fp, slave, length, data, ret; struct usrp_e_spi spi_dat; - if (argc < 4) { - printf("Usage: usrp_e_spi w|rb slave data\n"); + if (argc < 5) { + printf("Usage: usrp_e_spi w|rb slave transfer_length data\n"); exit(-1); } slave = atoi(argv[2]); - data = atoi(argv[3]); + length = atoi(argv[3]); + data = atoi(argv[4]); fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); spi_dat.slave = slave; spi_dat.data = data; - spi_dat.length = 32; + spi_dat.length = length; spi_dat.flags = 0; if (*argv[1] == 'r') { -- cgit v1.2.3 From 38233271a2d2ab84adfc5cc8c9700601933b717a Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Thu, 1 Apr 2010 16:55:44 -0700 Subject: preliminary registers definition --- .gitignore | 1 + host/lib/usrp/usrp_e/usrp_e_regs.hpp | 131 +++++++++++++++++++++++++---------- 2 files changed, 95 insertions(+), 37 deletions(-) create mode 100644 .gitignore (limited to 'host') diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b25c15b81 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp index 219f459a5..edd87e649 100644 --- a/host/lib/usrp/usrp_e/usrp_e_regs.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -1,49 +1,106 @@ + + +//////////////////////////////////////////////////////////////// // -// Copyright 2010 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 . +// Memory map for embedded wishbone bus // +//////////////////////////////////////////////////////////////// + +// All addresses are byte addresses. All accesses are word (16-bit) accesses. +// This means that address bit 0 is usually 0. +// There are 11 bits of address for the control. + +#ifndef __USRP_E_REGS_H +#define __USRP_E_REGS_H + +///////////////////////////////////////////////////// +// Slave pointers + +#define UE_REG_SLAVE(n) ((n)<<7) + +///////////////////////////////////////////////////// +// Slave 0 -- Misc Regs + +#define UE_REG_MISC_BASE UE_REG_SLAVE(0) + +#define UE_REG_MISC_LED UE_REG_MISC_BASE + 0 +#define UE_REG_MISC_SW UE_REG_MISC_BASE + 2 +#define UE_REG_MISC_CGEN_CTRL UE_REG_MISC_BASE + 4 +#define UE_REG_MISC_CGEN_ST UE_REG_MISC_BASE + 6 +#define UE_REG_MISC_TEST UE_REG_MISC_BASE + 8 + +///////////////////////////////////////////////////// +// Slave 1 -- UART +// CLKDIV is 16 bits, others are only 8 + +#define UE_REG_UART_BASE UE_REG_SLAVE(1) -#ifndef INCLUDED_USRP_E_REGS_HPP -#define INCLUDED_USRP_E_REGS_HPP +#define UE_REG_UART_CLKDIV UE_REG_UART_BASE + 0 +#define UE_REG_UART_TXLEVEL UE_REG_UART_BASE + 2 +#define UE_REG_UART_RXLEVEL UE_REG_UART_BASE + 4 +#define UE_REG_UART_TXCHAR UE_REG_UART_BASE + 6 +#define UE_REG_UART_RXCHAR UE_REG_UART_BASE + 8 + +///////////////////////////////////////////////////// +// Slave 2 -- SPI Core +// This should be accessed through the IOCTL +// Users should not touch directly + +#define UE_REG_SPI_BASE UE_REG_SLAVE(2) -#include //////////////////////////////////////////////// -// GPIO, Slave 4 -// -// These go to the daughterboard i/o pins +// Slave 3 -- I2C Core +// This should be accessed through the IOCTL +// Users should not touch directly + +#define UE_REG_I2C_BASE UE_REG_SLAVE(3) + + +//////////////////////////////////////////////// +// Slave 4 -- GPIO -#define GPIO_BASE 0x40 +#define UE_REG_GPIO_BASE UE_REG_SLAVE(4) -struct gpio_regs_t{ - boost::uint16_t rx_io; // tx data in high 16, rx in low 16 - boost::uint16_t tx_io; - boost::uint16_t rx_ddr; // 32 bits, 1 means output. tx in high 16, rx in low 16 - boost::uint16_t tx_ddr; - boost::uint16_t tx_sel_low; // 16 2-bit fields select which source goes to TX DB - boost::uint16_t tx_sel_high; - boost::uint16_t rx_sel_low; // 16 2-bit fields select which source goes to RX DB - boost::uint16_t rx_sel_high; -}; +#define UE_REG_GPIO_RX_IO UE_REG_GPIO_BASE + 0 +#define UE_REG_GPIO_TX_IO UE_REG_GPIO_BASE + 2 +#define UE_REG_GPIO_RX_DDR UE_REG_GPIO_BASE + 4 +#define UE_REG_GPIO_TX_DDR UE_REG_GPIO_BASE + 6 +#define UE_REG_GPIO_RX_SEL UE_REG_GPIO_BASE + 8 +#define UE_REG_GPIO_TX_SEL UE_REG_GPIO_BASE + 10 +#define UE_REG_GPIO_RX_DBG UE_REG_GPIO_BASE + 12 +#define UE_REG_GPIO_TX_DBG UE_REG_GPIO_BASE + 14 // each 2-bit sel field is layed out this way -#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg -#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic -#define GPIO_SEL_DEBUG_0 2 // if pin is an output, debug lines from FPGA fabric -#define GPIO_SEL_DEBUG_1 3 // if pin is an output, debug lines from FPGA fabric +#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg +#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic +#define GPIO_SEL_DEBUG_0 0 // if pin is an output, debug lines from FPGA fabric +#define GPIO_SEL_DEBUG_1 1 // if pin is an output, debug lines from FPGA fabric + + +//////////////////////////////////////////////////// +// Slave 5 -- Settings Bus +// +// Output-only, no readback, 32 registers total +// Each register must be written 32 bits at a time +// First the address xxx_xx00 and then xxx_xx10 + +#define UE_REG_SETTINGS_BASE UE_REG_SLAVE(5) + +/////////////////////////////////////////////////// +// Slave 6 -- ATR Controller +// 16 regs + +#define UE_REG_ATR_BASE UE_REG_SLAVE(6) + +#define UE_REG_ATR_IDLE_RXSIDE UE_REG_ATR_BASE + 0 +#define UE_REG_ATR_IDLE_TXSIDE UE_REG_ATR_BASE + 2 +#define UE_REG_ATR_INTX_RXSIDE UE_REG_ATR_BASE + 4 +#define UE_REG_ATR_INTX_TXSIDE UE_REG_ATR_BASE + 6 +#define UE_REG_ATR_INRX_RXSIDE UE_REG_ATR_BASE + 8 +#define UE_REG_ATR_INRX_TXSIDE UE_REG_ATR_BASE + 10 +#define UE_REG_ATR_FULL_RXSIDE UE_REG_ATR_BASE + 12 +#define UE_REG_ATR_FULL_TXSIDE UE_REG_ATR_BASE + 14 -//#define gpio_base ((gpio_regs_t *) GPIO_BASE) +#endif -#endif /* INCLUDED_USRP_E_REGS_HPP */ -- cgit v1.2.3 From bcd80dae09776eddaf4fdf9c6fb925c0b2586a11 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 1 Apr 2010 17:32:43 +0000 Subject: added peek and poke, using in dboard interface --- host/lib/usrp/usrp_e/dboard_interface.cpp | 106 +++++++++--------------------- host/lib/usrp/usrp_e/mboard_impl.cpp | 2 +- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 48 ++++++++++++++ host/lib/usrp/usrp_e/usrp_e_impl.hpp | 6 ++ 4 files changed, 85 insertions(+), 77 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dboard_interface.cpp b/host/lib/usrp/usrp_e/dboard_interface.cpp index a343d93b8..47948f3d0 100644 --- a/host/lib/usrp/usrp_e/dboard_interface.cpp +++ b/host/lib/usrp/usrp_e/dboard_interface.cpp @@ -22,7 +22,6 @@ #include #include //std::copy #include -#include using namespace uhd::usrp; @@ -34,9 +33,8 @@ public: void write_aux_dac(unit_type_t, int, int); int read_aux_adc(unit_type_t, int); - void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t); + void set_atr_reg(gpio_bank_t, atr_reg_t, boost::uint16_t); void set_gpio_ddr(gpio_bank_t, boost::uint16_t); - void write_gpio(gpio_bank_t, boost::uint16_t); boost::uint16_t read_gpio(gpio_bank_t); void write_i2c(int, const byte_vector_t &); @@ -48,8 +46,7 @@ public: private: byte_vector_t transact_spi( spi_dev_t dev, - spi_latch_t latch, - spi_push_t push, + spi_edge_t edge, const byte_vector_t &buf, bool readback ); @@ -92,82 +89,40 @@ double usrp_e_dboard_interface::get_tx_clock_rate(void){ void usrp_e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value){ //define mapping of gpio bank to register address static const uhd::dict bank_to_addr = boost::assign::map_list_of - (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_ddr)) - (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_ddr)) + (GPIO_BANK_RX, UE_REG_GPIO_RX_DDR) + (GPIO_BANK_TX, UE_REG_GPIO_TX_DDR) ; - - //load the data struct - usrp_e_ctl16 data; - data.offset = bank_to_addr[bank]; - data.count = 1; - data.buf[0] = value; - - //call the ioctl - _impl->ioctl(USRP_E_WRITE_CTL16, &data); -} - -void usrp_e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value){ - //define mapping of gpio bank to register address - static const uhd::dict bank_to_addr = boost::assign::map_list_of - (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_io)) - (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_io)) - ; - - //load the data struct - usrp_e_ctl16 data; - data.offset = bank_to_addr[bank]; - data.count = 1; - data.buf[0] = value; - - //call the ioctl - _impl->ioctl(USRP_E_WRITE_CTL16, &data); + _impl->poke16(bank_to_addr[bank], value); } boost::uint16_t usrp_e_dboard_interface::read_gpio(gpio_bank_t bank){ //define mapping of gpio bank to register address static const uhd::dict bank_to_addr = boost::assign::map_list_of - (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_io)) - (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_io)) + (GPIO_BANK_RX, UE_REG_GPIO_RX_IO) + (GPIO_BANK_TX, UE_REG_GPIO_TX_IO) ; - - //load the data struct - usrp_e_ctl16 data; - data.offset = bank_to_addr[bank]; - data.count = 1; - - //call the ioctl - _impl->ioctl(USRP_E_READ_CTL16, &data); - - return data.buf[0]; + return _impl->peek16(bank_to_addr[bank]); } -void usrp_e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){ - //define mapping of gpio bank to register address - static const uhd::dict bank_to_addr = boost::assign::map_list_of - (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_sel_low)) - (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_sel_low)) +void usrp_e_dboard_interface::set_atr_reg(gpio_bank_t bank, atr_reg_t atr, boost::uint16_t value){ + //define mapping of bank to atr regs to register address + static const uhd::dict< + gpio_bank_t, uhd::dict + > bank_to_atr_to_addr = boost::assign::map_list_of + (GPIO_BANK_RX, boost::assign::map_list_of + (ATR_REG_IDLE, UE_REG_ATR_IDLE_RXSIDE) + (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_RXSIDE) + (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_RXSIDE) + (ATR_REG_FULL_DUPLEX, UE_REG_ATR_FULL_RXSIDE) + ) + (GPIO_BANK_TX, boost::assign::map_list_of + (ATR_REG_IDLE, UE_REG_ATR_IDLE_TXSIDE) + (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_TXSIDE) + (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_TXSIDE) + (ATR_REG_FULL_DUPLEX, UE_REG_ATR_FULL_TXSIDE) + ) ; - - //set the gpio selection mux to atr or software controlled - boost::uint16_t low_sel = 0, high_sel = 0; - for(size_t i = 0; i < 16; i++){ - boost::uint16_t code = (mask & (1 << i))? GPIO_SEL_ATR : GPIO_SEL_SW; - if(i < 8) low_sel |= code << (2*i-0); - else high_sel |= code << (2*i-8); - } - - //load the data struct - usrp_e_ctl16 data; - data.offset = bank_to_addr[bank]; - data.count = 2; - data.buf[0] = low_sel; - data.buf[1] = high_sel; - - //call the ioctl - _impl->ioctl(USRP_E_READ_CTL16, &data); - - //----------------------------------------> TODO - //TODO set the atr regs + _impl->poke16(bank_to_atr_to_addr[bank][atr], value); } /*********************************************************************** @@ -175,15 +130,14 @@ void usrp_e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_v **********************************************************************/ dboard_interface::byte_vector_t usrp_e_dboard_interface::transact_spi( spi_dev_t dev, - spi_latch_t latch, - spi_push_t push, + spi_edge_t edge, const byte_vector_t &buf, bool readback ){ //load data struct usrp_e_spi data; data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; - data.slave = (dev == SPI_RX_DEV)? UE_SPI_CTRL_RXNEG : UE_SPI_CTRL_TXNEG; + data.slave = (dev == SPI_DEV_RX)? UE_SPI_CTRL_RXNEG : UE_SPI_CTRL_TXNEG; data.length = buf.size() * 8; //bytes to bits boost::uint8_t *data_bytes = reinterpret_cast(&data.data); @@ -193,8 +147,8 @@ dboard_interface::byte_vector_t usrp_e_dboard_interface::transact_spi( //load the flags data.flags = 0; - data.flags |= (latch == SPI_LATCH_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; - data.flags |= (push == SPI_PUSH_RISE)? UE_SPI_PUSH_RISE : UE_SPI_PUSH_FALL; + data.flags |= (edge == SPI_EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (edge == SPI_EDGE_RISE)? UE_SPI_PUSH_RISE : UE_SPI_PUSH_FALL; //call the spi ioctl _impl->ioctl(USRP_E_SPI, &data); diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index 1d3f9f466..ba15c394d 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -17,7 +17,7 @@ #include "usrp_e_impl.hpp" #include -#include +#include #include using namespace uhd; diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index e821add8c..3fefd6787 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -16,12 +16,14 @@ // #include "usrp_e_impl.hpp" +#include #include #include #include #include #include //open #include //ioctl +#include using namespace uhd; using namespace uhd::usrp; @@ -113,6 +115,52 @@ void usrp_e_impl::ioctl(int request, void *mem){ } } +void usrp_e_impl::poke32(boost::uint32_t addr, boost::uint32_t value){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL32, &data); +} + +void usrp_e_impl::poke16(boost::uint32_t addr, boost::uint16_t value){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL16, &data); +} + +boost::uint32_t usrp_e_impl::peek32(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL32, &data); + + return data.buf[0]; +} + +boost::uint16_t usrp_e_impl::peek16(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL16, &data); + + return data.buf[0]; +} + /*********************************************************************** * Device Get **********************************************************************/ diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 643589754..21023ae55 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -92,6 +92,12 @@ public: */ void ioctl(int request, void *mem); + //peekers and pokers + void poke32(boost::uint32_t addr, boost::uint32_t value); + void poke16(boost::uint32_t addr, boost::uint16_t value); + boost::uint32_t peek32(boost::uint32_t addr); + boost::uint16_t peek16(boost::uint32_t addr); + private: static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); int _node_fd; -- cgit v1.2.3 From 80b2b928df6e3c1caf68dee199593a0af1cb91ae Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 2 Apr 2010 12:33:37 +0000 Subject: Handle 32 bit data to spi controller. --- host/apps/omap_debug/usrp-e-spi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c index de1409647..f693d7db1 100644 --- a/host/apps/omap_debug/usrp-e-spi.c +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -10,7 +10,8 @@ int main(int argc, char *argv[]) { - int fp, slave, length, data, ret; + int fp, slave, length, ret; + unsigned int data; struct usrp_e_spi spi_dat; if (argc < 5) { @@ -20,7 +21,9 @@ int main(int argc, char *argv[]) slave = atoi(argv[2]); length = atoi(argv[3]); - data = atoi(argv[4]); + data = atoll(argv[4]); + + printf("Data = %X\n", data); fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); -- cgit v1.2.3 From d8052db8e5614935241a4824a3f9711bfe34507d Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 2 Apr 2010 19:49:45 +0000 Subject: Convert to use register include file. Fix peek/poke16 program. Add program to cycle through LED's and test buttons. Only pushbuttons tested at the moment. --- host/apps/omap_debug/Makefile | 14 +++++++-- host/apps/omap_debug/usrp-e-button.c | 56 +++++++++++++++++++++++++++++++++++ host/apps/omap_debug/usrp-e-ctl.c | 20 ++++++------- host/apps/omap_debug/usrp-e-led.c | 35 ++++++++++++++++++++++ host/apps/omap_debug/usrp-e-uart | Bin 0 -> 7143 bytes 5 files changed, 112 insertions(+), 13 deletions(-) create mode 100644 host/apps/omap_debug/usrp-e-button.c create mode 100644 host/apps/omap_debug/usrp-e-led.c create mode 100755 host/apps/omap_debug/usrp-e-uart (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 13b834e28..f292379f4 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ -CFLAGS=-Wall +CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-spi : usrp-e-spi.c @@ -11,9 +11,17 @@ usrp-e-rw : usrp-e-rw.c usrp-e-uart : usrp-e-uart.c +usrp-e-led : usrp-e-led.c + +usrp-e-ctl : usrp-e-ctl.c + +usrp-e-button : usrp-e-button.c + clean : rm -f usrp-e-spi rm -f usrp-e-i2c rm -f usrp-e-rw rm -f usrp-e-uart - + rm -f usrp-e-led + rm -f usrp-e-ctl + rm -f usrp-e-button diff --git a/host/apps/omap_debug/usrp-e-button.c b/host/apps/omap_debug/usrp-e-button.c new file mode 100644 index 000000000..fca501833 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-button.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "usrp_e.h" +#include "usrp_e_regs.hpp" + +// Usage: usrp_e_uart + +#define PB1 (1<<8) +#define PB2 (1<<9) +#define PB3 (1<<10) +#define P1 (0) +#define P2 (0xFF) +#define P3 (0xAA) +#define P4 (0x55) + +int main(int argc, char *argv[]) +{ + int fp, ret; + struct usrp_e_ctl16 d; + int pb1=0, pb2=0, pb3=0, p1=0, p2=0, p3=0, p4=0; + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + d.offset = 6; + d.count = 1; + + do { + ret = ioctl(fp, USRP_E_READ_CTL16, &d); + if (d.buf[0] & PB1) { + pb1 = 1; + printf("Pushbutton 1 hit\n"); + } + + if (d.buf[0] & PB2) { + pb2 = 1; + printf("Pushbutton 2 hit\n"); + } + + if (d.buf[0] & PB3) { + pb3 = 1; + printf("Pushbutton 3 hit\n"); + } + + sleep(1); + + } while (!(pb1 && pb2 && pb3)); + + return 0; +} diff --git a/host/apps/omap_debug/usrp-e-ctl.c b/host/apps/omap_debug/usrp-e-ctl.c index 045e7ce19..501a4870e 100644 --- a/host/apps/omap_debug/usrp-e-ctl.c +++ b/host/apps/omap_debug/usrp-e-ctl.c @@ -2,44 +2,44 @@ #include #include #include -#include +#include -#include "usrp1_e.h" +#include "usrp_e.h" -// Usage: usrp1_e_ctl w|r offset number_of_values val1 val2 .... +// Usage: usrp_e_ctl w|r offset number_of_values val1 val2 .... int main(int argc, char *argv[]) { int fp, i, cnt, ret; - struct usrp1_e_ctl *ctl_data; + struct usrp_e_ctl16 *ctl_data; if (argc < 4) { - printf("Usage: usrp1_e_ctl w|r offset number_of_values val1 val2 ....\n"); + printf("Usage: usrp_e_ctl w|r offset number_of_values val1 val2 ....\n"); exit(-1); } cnt = atoi(argv[3]); - ctl_data = malloc(sizeof(struct usrp1_e_ctl) + cnt*2); + ctl_data = malloc(sizeof(struct usrp_e_ctl16) + cnt*2); ctl_data->offset = atoi(argv[2]); ctl_data->count = cnt; - printf("Sizeof usrp1_e_ctl struct = %d\n", sizeof(struct usrp1_e_ctl)); + printf("Sizeof usrp1_e_ctl struct = %d\n", sizeof(struct usrp_e_ctl16)); - fp = open("/dev/usrp1_e0", O_RDWR); + fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); if (*argv[1] == 'w') { for (i=0; ibuf[i] = atoi(argv[4+i]); - ret = ioctl(fp, USRP1_E_WRITE_CTL, ctl_data); + ret = ioctl(fp, USRP_E_WRITE_CTL16, ctl_data); printf("Return value from write ioctl = %d\n", ret); } if (*argv[1] == 'r') { - ret = ioctl(fp, USRP1_E_READ_CTL, ctl_data); + ret = ioctl(fp, USRP_E_READ_CTL16, ctl_data); printf("Return value from write ioctl = %d\n", ret); for (i=0; icount; i++) { diff --git a/host/apps/omap_debug/usrp-e-led.c b/host/apps/omap_debug/usrp-e-led.c new file mode 100644 index 000000000..159251c8a --- /dev/null +++ b/host/apps/omap_debug/usrp-e-led.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "usrp_e.h" +#include "usrp_e_regs.hpp" + +// Usage: usrp_e_uart + + +int main(int argc, char *argv[]) +{ + int fp, i, ret; + struct usrp_e_ctl16 d; + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + d.offset = 4; + d.count = 1; + + while (1) { + for (i=0; i<8; i++) { + d.buf[0] = i; + ret = ioctl(fp, USRP_E_WRITE_CTL16, &d); + sleep(1); + } + } + + return 0; +} diff --git a/host/apps/omap_debug/usrp-e-uart b/host/apps/omap_debug/usrp-e-uart new file mode 100755 index 000000000..5781f0db2 Binary files /dev/null and b/host/apps/omap_debug/usrp-e-uart differ -- cgit v1.2.3 From 5d7a5e66c05290c5e3957457680313a2e427af08 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 2 Apr 2010 21:16:13 +0000 Subject: Don't need to use malloc to get the correct sized struct anymore. --- host/apps/omap_debug/usrp-e-ctl.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-ctl.c b/host/apps/omap_debug/usrp-e-ctl.c index 501a4870e..69c48ee6f 100644 --- a/host/apps/omap_debug/usrp-e-ctl.c +++ b/host/apps/omap_debug/usrp-e-ctl.c @@ -11,7 +11,7 @@ int main(int argc, char *argv[]) { int fp, i, cnt, ret; - struct usrp_e_ctl16 *ctl_data; + struct usrp_e_ctl16 ctl_data; if (argc < 4) { printf("Usage: usrp_e_ctl w|r offset number_of_values val1 val2 ....\n"); @@ -20,32 +20,28 @@ int main(int argc, char *argv[]) cnt = atoi(argv[3]); - ctl_data = malloc(sizeof(struct usrp_e_ctl16) + cnt*2); - - ctl_data->offset = atoi(argv[2]); - ctl_data->count = cnt; - - printf("Sizeof usrp1_e_ctl struct = %d\n", sizeof(struct usrp_e_ctl16)); + ctl_data.offset = atoi(argv[2]); + ctl_data.count = cnt; fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); if (*argv[1] == 'w') { for (i=0; ibuf[i] = atoi(argv[4+i]); + ctl_data.buf[i] = atoi(argv[4+i]); - ret = ioctl(fp, USRP_E_WRITE_CTL16, ctl_data); + ret = ioctl(fp, USRP_E_WRITE_CTL16, &ctl_data); printf("Return value from write ioctl = %d\n", ret); } if (*argv[1] == 'r') { - ret = ioctl(fp, USRP_E_READ_CTL16, ctl_data); + ret = ioctl(fp, USRP_E_READ_CTL16, &ctl_data); printf("Return value from write ioctl = %d\n", ret); - for (i=0; icount; i++) { + for (i=0; ibuf[i]); + printf(" %5d", ctl_data.buf[i]); } printf("\n"); } -- cgit v1.2.3 From d4e9f3629021736b1330b4a9f22ee60336a53e0e Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 2 Apr 2010 21:58:55 +0000 Subject: Update to use register definitions from header file. --- host/apps/omap_debug/usrp-e-button.c | 2 +- host/apps/omap_debug/usrp-e-led.c | 2 +- host/apps/omap_debug/usrp-e-uart.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-button.c b/host/apps/omap_debug/usrp-e-button.c index fca501833..f13291491 100644 --- a/host/apps/omap_debug/usrp-e-button.c +++ b/host/apps/omap_debug/usrp-e-button.c @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); - d.offset = 6; + d.offset = UE_REG_MISC_SW; d.count = 1; do { diff --git a/host/apps/omap_debug/usrp-e-led.c b/host/apps/omap_debug/usrp-e-led.c index 159251c8a..d1b6c8996 100644 --- a/host/apps/omap_debug/usrp-e-led.c +++ b/host/apps/omap_debug/usrp-e-led.c @@ -20,7 +20,7 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); - d.offset = 4; + d.offset = UE_REG_MISC_BASE; d.count = 1; while (1) { diff --git a/host/apps/omap_debug/usrp-e-uart.c b/host/apps/omap_debug/usrp-e-uart.c index 239df9444..b0b14626a 100644 --- a/host/apps/omap_debug/usrp-e-uart.c +++ b/host/apps/omap_debug/usrp-e-uart.c @@ -6,10 +6,10 @@ #include #include "usrp_e.h" +#include "usrp_e_regs.hpp" // Usage: usrp_e_uart -#define UART_WRITE_ADDR (0x80 + 12) int main(int argc, char *argv[]) { @@ -26,7 +26,7 @@ int main(int argc, char *argv[]) printf("fp = %d\n", fp); for (i=0; i Date: Sat, 3 Apr 2010 14:54:54 +0000 Subject: Yes, I am an idiot. --- host/apps/omap_debug/usrp-e-uart | Bin 7143 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 host/apps/omap_debug/usrp-e-uart (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-uart b/host/apps/omap_debug/usrp-e-uart deleted file mode 100755 index 5781f0db2..000000000 Binary files a/host/apps/omap_debug/usrp-e-uart and /dev/null differ -- cgit v1.2.3 From 317fc2d16288dcc621761a88119f279e1cfeafd6 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sat, 3 Apr 2010 14:55:16 +0000 Subject: Add ability to change uart baud rate. (works) --- host/apps/omap_debug/usrp-e-uart.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-uart.c b/host/apps/omap_debug/usrp-e-uart.c index b0b14626a..2956c407f 100644 --- a/host/apps/omap_debug/usrp-e-uart.c +++ b/host/apps/omap_debug/usrp-e-uart.c @@ -16,15 +16,26 @@ int main(int argc, char *argv[]) int fp, i, ret; struct usrp_e_ctl16 d; char *str = argv[1]; + __u16 clkdiv; if (argc < 2) { - printf("Usage: usrp_e_uart n"); + printf("Usage: usrp_e_uart \n"); + printf("clkdiv = 278 is 230.4k \n"); + printf("clkdiv = 556 is 115.2k \n"); exit(-1); } fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); + if (argc == 3) { + clkdiv = atoi(argv[2]); + d.offset = UE_REG_UART_CLKDIV; + d.count = 1; + d.buf[0] = clkdiv; + ret = ioctl(fp, USRP_E_WRITE_CTL16, &d); + } + for (i=0; i Date: Sat, 3 Apr 2010 15:25:37 +0000 Subject: Add program to read from serial port and print to screen. (works) --- host/apps/omap_debug/Makefile | 5 +++- host/apps/omap_debug/usrp-e-uart-rx.c | 53 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 host/apps/omap_debug/usrp-e-uart-rx.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index f292379f4..4779969de 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx usrp-e-spi : usrp-e-spi.c @@ -11,6 +11,8 @@ usrp-e-rw : usrp-e-rw.c usrp-e-uart : usrp-e-uart.c +usrp-e-uart-rx : usrp-e-uart-rx.c + usrp-e-led : usrp-e-led.c usrp-e-ctl : usrp-e-ctl.c @@ -22,6 +24,7 @@ clean : rm -f usrp-e-i2c rm -f usrp-e-rw rm -f usrp-e-uart + rm -f usrp-e-uart-rx rm -f usrp-e-led rm -f usrp-e-ctl rm -f usrp-e-button diff --git a/host/apps/omap_debug/usrp-e-uart-rx.c b/host/apps/omap_debug/usrp-e-uart-rx.c new file mode 100644 index 000000000..24b417980 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-uart-rx.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#include + +#include "usrp_e.h" +#include "usrp_e_regs.hpp" + +// Usage: usrp_e_uart + + +int main(int argc, char *argv[]) +{ + int fp, ret; + struct usrp_e_ctl16 d; + __u16 clkdiv; + + if (argc == 0) { + printf("Usage: usrp-e-uart-rx \n"); + printf("clkdiv = 278 is 230.4k \n"); + printf("clkdiv = 556 is 115.2k \n"); + exit(-1); + } + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + if (argc == 2) { + clkdiv = atoi(argv[1]); + d.offset = UE_REG_UART_CLKDIV; + d.count = 1; + d.buf[0] = clkdiv; + ret = ioctl(fp, USRP_E_WRITE_CTL16, &d); + } + + while(1) { + d.offset = UE_REG_UART_RXLEVEL; + d.count = 1; + ret = ioctl(fp, USRP_E_READ_CTL16, &d); + + if (d.buf[0] > 0) { + d.offset = UE_REG_UART_RXCHAR; + d.count = 1; + ret = ioctl(fp, USRP_E_READ_CTL16, &d); + printf("%c", d.buf[0]); + fflush(stdout); + } + } + + return 0; +} -- cgit v1.2.3 From b0316af8ebc713afaddc5b6ded5c0304353a7ab6 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sat, 3 Apr 2010 16:59:44 +0000 Subject: Attempt to make scripts run inside and outside GHQ. When at GHQ: export GHQ=1 export GHQ_USER="something that can log in to astro" --- host/apps/omap_debug/Makefile | 5 ++++- host/apps/omap_debug/fetch-bin.sh | 6 +++++- host/apps/omap_debug/fetch-kernel.sh | 5 ++++- host/apps/omap_debug/fetch-module.sh | 7 +++++-- host/apps/omap_debug/fetch-u-boot.sh | 5 ++++- 5 files changed, 22 insertions(+), 6 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 4779969de..cd95d36fc 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-spi : usrp-e-spi.c @@ -19,6 +19,8 @@ usrp-e-ctl : usrp-e-ctl.c usrp-e-button : usrp-e-button.c +fpga-downloader : fpga-downloader.cc + clean : rm -f usrp-e-spi rm -f usrp-e-i2c @@ -28,3 +30,4 @@ clean : rm -f usrp-e-led rm -f usrp-e-ctl rm -f usrp-e-button + rm -f fpga-downloader diff --git a/host/apps/omap_debug/fetch-bin.sh b/host/apps/omap_debug/fetch-bin.sh index beff7ffcd..d1502f95c 100755 --- a/host/apps/omap_debug/fetch-bin.sh +++ b/host/apps/omap_debug/fetch-bin.sh @@ -1,2 +1,6 @@ -scp balister@astro:/workspace/usrp1-e-dev/u1e.bin . +if [ $GHQ ]; then + scp $GHQ_USER@astro:/workspace/usrp1-e-dev/u1e.bin . +else + scp -P 8822 balister@192.168.1.10:src/git/fpgapriv/usrp2/top/u1e/build/u1e.bin . +fi sync diff --git a/host/apps/omap_debug/fetch-kernel.sh b/host/apps/omap_debug/fetch-kernel.sh index 7023f5d28..f32666adf 100755 --- a/host/apps/omap_debug/fetch-kernel.sh +++ b/host/apps/omap_debug/fetch-kernel.sh @@ -1,3 +1,6 @@ -scp balister@192.168.1.167:src/git/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage +if [ $GHQ]; then + scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage +else + scp balister@192.168.1.167:src/git/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage sync diff --git a/host/apps/omap_debug/fetch-module.sh b/host/apps/omap_debug/fetch-module.sh index 45cf1f052..52fbd4040 100755 --- a/host/apps/omap_debug/fetch-module.sh +++ b/host/apps/omap_debug/fetch-module.sh @@ -1,3 +1,6 @@ -scp balister@192.168.1.167:src/git/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc -scp balister@192.168.1.167:src/git/kernel_usrp/include/linux/usrp_e.h . +if [ $GHQ ]; then + scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc +else + scp balister@192.168.1.167:src/git/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc +fi sync diff --git a/host/apps/omap_debug/fetch-u-boot.sh b/host/apps/omap_debug/fetch-u-boot.sh index 63d4edcf2..a2a488fb2 100755 --- a/host/apps/omap_debug/fetch-u-boot.sh +++ b/host/apps/omap_debug/fetch-u-boot.sh @@ -1,3 +1,6 @@ -scp balister@astro:/workspace/usrp1-e-dev/u-boot-overo/u-boot.bin /media/mmcblk0p1/ +if [ $GHQ ]; then + scp $GHQ_USER@astro:/workspace/usrp1-e-dev/u-boot-overo/u-boot.bin /media/mmcblk0p1/ +else + scp balister@192.168.1.167:src/git/u-boot/u-boot.bin /media/mmcblk0p1/ sync -- cgit v1.2.3 From 50780640a1b9ed6abb2abebbc727ce19711fbcb4 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 9 Apr 2010 21:41:37 +0000 Subject: Test program to verify GPIO on daughterboards. For success, connect gpios on TX to corresponding ones on RX. --- host/apps/omap_debug/Makefile | 5 +- host/apps/omap_debug/set_debug_pins.py | 13 +++--- host/apps/omap_debug/usrp-e-gpio.c | 83 ++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 host/apps/omap_debug/usrp-e-gpio.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index cd95d36fc..31229d45c 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-spi : usrp-e-spi.c @@ -21,6 +21,8 @@ usrp-e-button : usrp-e-button.c fpga-downloader : fpga-downloader.cc +usrp-e-gpio : usrp-e-gpio.c + clean : rm -f usrp-e-spi rm -f usrp-e-i2c @@ -31,3 +33,4 @@ clean : rm -f usrp-e-ctl rm -f usrp-e-button rm -f fpga-downloader + rm -f usrp-e-gpio diff --git a/host/apps/omap_debug/set_debug_pins.py b/host/apps/omap_debug/set_debug_pins.py index fdd085c9e..0f9ecd7b9 100755 --- a/host/apps/omap_debug/set_debug_pins.py +++ b/host/apps/omap_debug/set_debug_pins.py @@ -3,12 +3,12 @@ import os # Memory Map -misc_base = 0 << 7 -uart_base = 1 << 7 -spi_base = 2 << 7 -i2c_base = 3 << 7 -gpio_base = 4 << 7 -settings_base = 5 << 7 +misc_base = 0 +uart_base = 1 +spi_base = 2 +i2c_base = 3 +gpio_base = 4 * 128 +settings_base = 5 # GPIO offset gpio_pins = 0 @@ -32,3 +32,4 @@ set_reg(gpio_base+gpio_ctrl_lo, 0xAAAA) set_reg(gpio_base+gpio_ctrl_lo+2, 0xAAAA) set_reg(gpio_base+gpio_ctrl_hi, 0xAAAA) set_reg(gpio_base+gpio_ctrl_hi+2, 0xAAAA) + diff --git a/host/apps/omap_debug/usrp-e-gpio.c b/host/apps/omap_debug/usrp-e-gpio.c new file mode 100644 index 000000000..adef877d3 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-gpio.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "usrp_e.h" +#include "usrp_e_regs.hpp" + +// Usage: usrp_e_gpio + +static int fp; + +static int read_reg(__u16 reg) +{ + int ret; + struct usrp_e_ctl16 d; + + d.offset = reg; + d.count = 1; + ret = ioctl(fp, USRP_E_READ_CTL16, &d); + return d.buf[0]; +} + +static void write_reg(__u16 reg, __u16 val) +{ + int ret; + struct usrp_e_ctl16 d; + + d.offset = reg; + d.count = 1; + d.buf[0] = val; + ret = ioctl(fp, USRP_E_WRITE_CTL16, &d); +} + +int main(int argc, char *argv[]) +{ + int i, test, data_in; + + test = 0; + if (argc > 1) + test = 1; + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + write_reg(UE_REG_GPIO_TX_DDR, 0x0); + write_reg(UE_REG_GPIO_RX_DDR, 0xFFFF); + + for (i=0; i < 16; i++) { + write_reg(UE_REG_GPIO_RX_IO, 1 << i); + sleep(1); + if (test) { + data_in = read_reg(UE_REG_GPIO_TX_IO); + if (data_in != (1 << i)) + printf("Read failed, wrote: %X read: %X\n", \ + 1 << i, data_in); + } + } + + write_reg(UE_REG_GPIO_RX_DDR, 0x0); + write_reg(UE_REG_GPIO_TX_DDR, 0xFFFF); + + sleep(1); + + for (i=0; i < 16; i++) { + write_reg(UE_REG_GPIO_TX_IO, 1 << i); + sleep(1); + if (test) { + data_in = read_reg(UE_REG_GPIO_RX_IO); + if (data_in != (1 << i)) + printf("Read failed, wrote: %X read: %X\n", \ + 1 << i, data_in); + } + } + + write_reg(UE_REG_GPIO_RX_DDR, 0x0); + write_reg(UE_REG_GPIO_TX_DDR, 0x0); + + return 0; +} -- cgit v1.2.3 From 34854116a4fd287fe681222f2b7a881692e418d3 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 12 Apr 2010 13:54:50 +0000 Subject: put the dummy package back in --- host/lib/CMakeLists.txt | 7 +++++++ host/lib/usrp/usrp1e/usrp1e_none.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 host/lib/usrp/usrp1e/usrp1e_none.cpp (limited to 'host') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 9d328310f..a5345cae4 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -48,6 +48,13 @@ LIST(APPEND libuhd_sources transport/udp_zero_copy_asio.cpp ) +######################################################################## +# Conditionally add the usrp1e sources +######################################################################## +LIST(APPEND libuhd_sources + usrp/usrp1e/usrp1e_none.cpp +) + ######################################################################## # Setup defines for module loading ######################################################################## diff --git a/host/lib/usrp/usrp1e/usrp1e_none.cpp b/host/lib/usrp/usrp1e/usrp1e_none.cpp new file mode 100644 index 000000000..84fb9276c --- /dev/null +++ b/host/lib/usrp/usrp1e/usrp1e_none.cpp @@ -0,0 +1,34 @@ +// +// Copyright 2010 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 . +// + +#include + +using namespace uhd; +using namespace uhd::usrp; + +/*! + * This file defines the usrp1e discover and make functions + * when the required kernel module headers are not present. + */ + +device_addrs_t usrp1e::find(const device_addr_t &){ + return device_addrs_t(); //return empty list +} + +device::sptr usrp1e::make(const device_addr_t &){ + throw std::runtime_error("this build has no usrp1e support"); +} -- cgit v1.2.3 From b59c54e334dfc1c6ab7da81c62038444f93efe61 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 13 Apr 2010 16:37:22 +0000 Subject: Fix typo. --- host/apps/omap_debug/fetch-kernel.sh | 1 + 1 file changed, 1 insertion(+) (limited to 'host') diff --git a/host/apps/omap_debug/fetch-kernel.sh b/host/apps/omap_debug/fetch-kernel.sh index f32666adf..a3cddb339 100755 --- a/host/apps/omap_debug/fetch-kernel.sh +++ b/host/apps/omap_debug/fetch-kernel.sh @@ -2,5 +2,6 @@ if [ $GHQ]; then scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage else scp balister@192.168.1.167:src/git/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage +fi sync -- cgit v1.2.3 From 839d9c39542db356ad1b955e3a3d9e7aabb071bc Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 16 Apr 2010 12:58:42 +0000 Subject: pulled in master and got usrp-e code compiling --- host/apps/omap_debug/fetch-kernel.sh | 2 +- host/apps/omap_debug/fetch-module.sh | 2 +- host/lib/CMakeLists.txt | 3 +- host/lib/usrp/usrp_e/dboard_iface.cpp | 218 ++++++++++++++++++++++++++++++ host/lib/usrp/usrp_e/dboard_impl.cpp | 6 +- host/lib/usrp/usrp_e/dboard_interface.cpp | 212 ----------------------------- host/lib/usrp/usrp_e/mboard_impl.cpp | 4 +- host/lib/usrp/usrp_e/usrp_e_iface.cpp | 135 ++++++++++++++++++ host/lib/usrp/usrp_e/usrp_e_iface.hpp | 97 +++++++++++++ host/lib/usrp/usrp_e/usrp_e_impl.cpp | 89 ++---------- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 26 +--- 11 files changed, 478 insertions(+), 316 deletions(-) create mode 100644 host/lib/usrp/usrp_e/dboard_iface.cpp delete mode 100644 host/lib/usrp/usrp_e/dboard_interface.cpp create mode 100644 host/lib/usrp/usrp_e/usrp_e_iface.cpp create mode 100644 host/lib/usrp/usrp_e/usrp_e_iface.hpp (limited to 'host') diff --git a/host/apps/omap_debug/fetch-kernel.sh b/host/apps/omap_debug/fetch-kernel.sh index a3cddb339..f25f139fa 100755 --- a/host/apps/omap_debug/fetch-kernel.sh +++ b/host/apps/omap_debug/fetch-kernel.sh @@ -1,4 +1,4 @@ -if [ $GHQ]; then +if [ $GHQ ]; then scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage else scp balister@192.168.1.167:src/git/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage diff --git a/host/apps/omap_debug/fetch-module.sh b/host/apps/omap_debug/fetch-module.sh index 52fbd4040..0957ad7b4 100755 --- a/host/apps/omap_debug/fetch-module.sh +++ b/host/apps/omap_debug/fetch-module.sh @@ -1,5 +1,5 @@ if [ $GHQ ]; then - scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc + scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.34-rc1/kernel/drivers/misc else scp balister@192.168.1.167:src/git/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc fi diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index dfcb88ec9..ff7f2c0df 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -138,11 +138,12 @@ IF(HAVE_USRP_E_REQUIRED_HEADERS) MESSAGE(STATUS " Building usrp-e support.") LIST(APPEND libuhd_sources usrp/usrp_e/dboard_impl.cpp - usrp/usrp_e/dboard_interface.cpp + usrp/usrp_e/dboard_iface.cpp usrp/usrp_e/dsp_impl.cpp usrp/usrp_e/fpga-downloader.cc usrp/usrp_e/mboard_impl.cpp usrp/usrp_e/usrp_e_impl.cpp + usrp/usrp_e/usrp_e_iface.cpp ) ELSE(HAVE_USRP_E_REQUIRED_HEADERS) MESSAGE(STATUS " Skipping usrp-e support.") diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp new file mode 100644 index 000000000..12e8fe206 --- /dev/null +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -0,0 +1,218 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_iface.hpp" +#include "usrp_e_regs.hpp" +#include +#include +#include +#include +#include //i2c and spi constants + +using namespace uhd::usrp; + +class usrp_e_dboard_iface : public dboard_iface{ +public: + usrp_e_dboard_iface(usrp_e_iface::sptr iface); + ~usrp_e_dboard_iface(void); + + void write_aux_dac(unit_t, int, float); + float read_aux_adc(unit_t, int); + + void set_atr_reg(unit_t, atr_reg_t, boost::uint16_t); + void set_gpio_ddr(unit_t, boost::uint16_t); + boost::uint16_t read_gpio(unit_t); + + void write_i2c(int, const byte_vector_t &); + byte_vector_t read_i2c(int, size_t); + + void write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ); + + boost::uint32_t read_write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ); + + double get_clock_rate(unit_t); + void set_clock_enabled(unit_t, bool); + +private: + usrp_e_iface::sptr _iface; +}; + +/*********************************************************************** + * Make Function + **********************************************************************/ +dboard_iface::sptr make_usrp_e_dboard_iface(usrp_e_iface::sptr iface){ + return dboard_iface::sptr(new usrp_e_dboard_iface(iface)); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp_e_dboard_iface::usrp_e_dboard_iface(usrp_e_iface::sptr iface){ + _iface = iface; +} + +usrp_e_dboard_iface::~usrp_e_dboard_iface(void){ + /* NOP */ +} + +/*********************************************************************** + * Clock Rates + **********************************************************************/ +double usrp_e_dboard_iface::get_clock_rate(unit_t){ + throw std::runtime_error("not implemented"); +} + +void usrp_e_dboard_iface::set_clock_enabled(unit_t, bool){ + throw std::runtime_error("not implemented"); +} + +/*********************************************************************** + * GPIO + **********************************************************************/ +void usrp_e_dboard_iface::set_gpio_ddr(unit_t bank, boost::uint16_t value){ + //define mapping of gpio bank to register address + static const uhd::dict bank_to_addr = boost::assign::map_list_of + (UNIT_RX, UE_REG_GPIO_RX_DDR) + (UNIT_TX, UE_REG_GPIO_TX_DDR) + ; + _iface->poke16(bank_to_addr[bank], value); +} + +boost::uint16_t usrp_e_dboard_iface::read_gpio(unit_t bank){ + //define mapping of gpio bank to register address + static const uhd::dict bank_to_addr = boost::assign::map_list_of + (UNIT_RX, UE_REG_GPIO_RX_IO) + (UNIT_TX, UE_REG_GPIO_TX_IO) + ; + return _iface->peek16(bank_to_addr[bank]); +} + +void usrp_e_dboard_iface::set_atr_reg(unit_t bank, atr_reg_t atr, boost::uint16_t value){ + //define mapping of bank to atr regs to register address + static const uhd::dict< + unit_t, uhd::dict + > bank_to_atr_to_addr = boost::assign::map_list_of + (UNIT_RX, boost::assign::map_list_of + (ATR_REG_IDLE, UE_REG_ATR_IDLE_RXSIDE) + (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_RXSIDE) + (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_RXSIDE) + (ATR_REG_FULL_DUPLEX, UE_REG_ATR_FULL_RXSIDE) + ) + (UNIT_TX, boost::assign::map_list_of + (ATR_REG_IDLE, UE_REG_ATR_IDLE_TXSIDE) + (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_TXSIDE) + (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_TXSIDE) + (ATR_REG_FULL_DUPLEX, UE_REG_ATR_FULL_TXSIDE) + ) + ; + _iface->poke16(bank_to_atr_to_addr[bank][atr], value); +} + +/*********************************************************************** + * SPI + **********************************************************************/ +/*! + * Static function to convert a unit type to a spi slave device number. + * \param unit the dboard interface unit type enum + * \return the slave device number + */ +static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){ + switch(unit){ + case dboard_iface::UNIT_TX: return UE_SPI_CTRL_TXNEG; + case dboard_iface::UNIT_RX: return UE_SPI_CTRL_RXNEG; + } + throw std::invalid_argument("unknown unit type"); +} + +void usrp_e_dboard_iface::write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits +){ + _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/); +} + +boost::uint32_t usrp_e_dboard_iface::read_write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits +){ + return _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, true /*rb*/); +} + +/*********************************************************************** + * I2C + **********************************************************************/ +static const size_t max_i2c_data_bytes = 10; + +void usrp_e_dboard_iface::write_i2c(int i2c_addr, const byte_vector_t &buf){ + //allocate some memory for this transaction + ASSERT_THROW(buf.size() <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c &data = reinterpret_cast(mem); + data.addr = i2c_addr; + data.len = buf.size(); + std::copy(buf.begin(), buf.end(), data.data); + + //call the spi ioctl + _iface->ioctl(USRP_E_I2C_WRITE, &data); +} + +dboard_iface::byte_vector_t usrp_e_dboard_iface::read_i2c(int i2c_addr, size_t num_bytes){ + //allocate some memory for this transaction + ASSERT_THROW(num_bytes <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c &data = reinterpret_cast(mem); + data.addr = i2c_addr; + data.len = num_bytes; + + //call the spi ioctl + _iface->ioctl(USRP_E_I2C_READ, &data); + + //unload the data + byte_vector_t ret(data.len); + ASSERT_THROW(ret.size() == num_bytes); + std::copy(data.data, data.data+ret.size(), ret.begin()); + return ret; +} + +/*********************************************************************** + * Aux DAX/ADC + **********************************************************************/ +void usrp_e_dboard_iface::write_aux_dac(dboard_iface::unit_t unit, int which, float value){ + throw std::runtime_error("not implemented"); +} + +float usrp_e_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, int which){ + throw std::runtime_error("not implemented"); +} diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index 7c87361e0..df0f1d9a9 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -28,11 +28,11 @@ void usrp_e_impl::dboard_init(void){ dboard_id_t tx_dboard_id = dboard_id::NONE; //create a new dboard interface and manager - dboard_interface::sptr dboard_interface( - make_usrp_e_dboard_interface(this) + dboard_iface::sptr dboard_iface( + make_usrp_e_dboard_iface(_iface) ); _dboard_manager = dboard_manager::make( - rx_dboard_id, tx_dboard_id, dboard_interface + rx_dboard_id, tx_dboard_id, dboard_iface ); //setup the dboard proxies diff --git a/host/lib/usrp/usrp_e/dboard_interface.cpp b/host/lib/usrp/usrp_e/dboard_interface.cpp deleted file mode 100644 index 47948f3d0..000000000 --- a/host/lib/usrp/usrp_e/dboard_interface.cpp +++ /dev/null @@ -1,212 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" -#include -#include -#include -#include //std::copy -#include - -using namespace uhd::usrp; - -class usrp_e_dboard_interface : public dboard_interface{ -public: - usrp_e_dboard_interface(usrp_e_impl *impl); - ~usrp_e_dboard_interface(void); - - void write_aux_dac(unit_type_t, int, int); - int read_aux_adc(unit_type_t, int); - - void set_atr_reg(gpio_bank_t, atr_reg_t, boost::uint16_t); - void set_gpio_ddr(gpio_bank_t, boost::uint16_t); - boost::uint16_t read_gpio(gpio_bank_t); - - void write_i2c(int, const byte_vector_t &); - byte_vector_t read_i2c(int, size_t); - - double get_rx_clock_rate(void); - double get_tx_clock_rate(void); - -private: - byte_vector_t transact_spi( - spi_dev_t dev, - spi_edge_t edge, - const byte_vector_t &buf, - bool readback - ); - - usrp_e_impl *_impl; -}; - -/*********************************************************************** - * Make Function - **********************************************************************/ -dboard_interface::sptr make_usrp_e_dboard_interface(usrp_e_impl *impl){ - return dboard_interface::sptr(new usrp_e_dboard_interface(impl)); -} - -/*********************************************************************** - * Structors - **********************************************************************/ -usrp_e_dboard_interface::usrp_e_dboard_interface(usrp_e_impl *impl){ - _impl = impl; -} - -usrp_e_dboard_interface::~usrp_e_dboard_interface(void){ - /* NOP */ -} - -/*********************************************************************** - * Clock Rates - **********************************************************************/ -double usrp_e_dboard_interface::get_rx_clock_rate(void){ - throw std::runtime_error("not implemented"); -} - -double usrp_e_dboard_interface::get_tx_clock_rate(void){ - throw std::runtime_error("not implemented"); -} - -/*********************************************************************** - * GPIO - **********************************************************************/ -void usrp_e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value){ - //define mapping of gpio bank to register address - static const uhd::dict bank_to_addr = boost::assign::map_list_of - (GPIO_BANK_RX, UE_REG_GPIO_RX_DDR) - (GPIO_BANK_TX, UE_REG_GPIO_TX_DDR) - ; - _impl->poke16(bank_to_addr[bank], value); -} - -boost::uint16_t usrp_e_dboard_interface::read_gpio(gpio_bank_t bank){ - //define mapping of gpio bank to register address - static const uhd::dict bank_to_addr = boost::assign::map_list_of - (GPIO_BANK_RX, UE_REG_GPIO_RX_IO) - (GPIO_BANK_TX, UE_REG_GPIO_TX_IO) - ; - return _impl->peek16(bank_to_addr[bank]); -} - -void usrp_e_dboard_interface::set_atr_reg(gpio_bank_t bank, atr_reg_t atr, boost::uint16_t value){ - //define mapping of bank to atr regs to register address - static const uhd::dict< - gpio_bank_t, uhd::dict - > bank_to_atr_to_addr = boost::assign::map_list_of - (GPIO_BANK_RX, boost::assign::map_list_of - (ATR_REG_IDLE, UE_REG_ATR_IDLE_RXSIDE) - (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_RXSIDE) - (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_RXSIDE) - (ATR_REG_FULL_DUPLEX, UE_REG_ATR_FULL_RXSIDE) - ) - (GPIO_BANK_TX, boost::assign::map_list_of - (ATR_REG_IDLE, UE_REG_ATR_IDLE_TXSIDE) - (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_TXSIDE) - (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_TXSIDE) - (ATR_REG_FULL_DUPLEX, UE_REG_ATR_FULL_TXSIDE) - ) - ; - _impl->poke16(bank_to_atr_to_addr[bank][atr], value); -} - -/*********************************************************************** - * SPI - **********************************************************************/ -dboard_interface::byte_vector_t usrp_e_dboard_interface::transact_spi( - spi_dev_t dev, - spi_edge_t edge, - const byte_vector_t &buf, - bool readback -){ - //load data struct - usrp_e_spi data; - data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; - data.slave = (dev == SPI_DEV_RX)? UE_SPI_CTRL_RXNEG : UE_SPI_CTRL_TXNEG; - data.length = buf.size() * 8; //bytes to bits - boost::uint8_t *data_bytes = reinterpret_cast(&data.data); - - //load the data - ASSERT_THROW(buf.size() <= sizeof(data.data)); - std::copy(buf.begin(), buf.end(), data_bytes); - - //load the flags - data.flags = 0; - data.flags |= (edge == SPI_EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; - data.flags |= (edge == SPI_EDGE_RISE)? UE_SPI_PUSH_RISE : UE_SPI_PUSH_FALL; - - //call the spi ioctl - _impl->ioctl(USRP_E_SPI, &data); - - //unload the data - byte_vector_t ret(data.length/8); //bits to bytes - ASSERT_THROW(ret.size() <= sizeof(data.data)); - std::copy(data_bytes, data_bytes+ret.size(), ret.begin()); - return ret; -} - -/*********************************************************************** - * I2C - **********************************************************************/ -static const size_t max_i2c_data_bytes = 10; - -void usrp_e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ - //allocate some memory for this transaction - ASSERT_THROW(buf.size() <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = i2c_addr; - data.len = buf.size(); - std::copy(buf.begin(), buf.end(), data.data); - - //call the spi ioctl - _impl->ioctl(USRP_E_I2C_WRITE, &data); -} - -dboard_interface::byte_vector_t usrp_e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){ - //allocate some memory for this transaction - ASSERT_THROW(num_bytes <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = i2c_addr; - data.len = num_bytes; - - //call the spi ioctl - _impl->ioctl(USRP_E_I2C_READ, &data); - - //unload the data - byte_vector_t ret(data.len); - ASSERT_THROW(ret.size() == num_bytes); - std::copy(data.data, data.data+ret.size(), ret.begin()); - return ret; -} - -/*********************************************************************** - * Aux DAX/ADC - **********************************************************************/ -void usrp_e_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){ - throw std::runtime_error("not implemented"); -} - -int usrp_e_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){ - throw std::runtime_error("not implemented"); -} diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index ba15c394d..2d225c6ea 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -75,8 +75,8 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ val = prop_names_t(1, ""); //vector of size 1 with empty string return; - case MBOARD_PROP_CLOCK_RATE: - //val = TODO probably remove this property + case MBOARD_PROP_STREAM_CMD: + //val = TODO return; case MBOARD_PROP_RX_DSP: diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.cpp b/host/lib/usrp/usrp_e/usrp_e_iface.cpp new file mode 100644 index 000000000..d4c988211 --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_iface.cpp @@ -0,0 +1,135 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_iface.hpp" +#include //ioctl +#include //ioctl structures and constants +#include +#include + +class usrp_e_iface_impl : public usrp_e_iface{ +public: + + /******************************************************************* + * Structors + ******************************************************************/ + usrp_e_iface_impl(int node_fd){ + _node_fd = node_fd; + } + + ~usrp_e_iface_impl(void){ + /* NOP */ + } + + /******************************************************************* + * IOCTL: provides the communication base for all other calls + ******************************************************************/ + void ioctl(int request, void *mem){ + if (::ioctl(_node_fd, request, mem) < 0){ + throw std::runtime_error(str( + boost::format("ioctl failed with request %d") % request + )); + } + } + + /******************************************************************* + * Peek and Poke + ******************************************************************/ + void poke32(boost::uint32_t addr, boost::uint32_t value){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL32, &data); + } + + void poke16(boost::uint32_t addr, boost::uint16_t value){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL16, &data); + } + + boost::uint32_t peek32(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL32, &data); + + return data.buf[0]; + } + + boost::uint16_t peek16(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL16, &data); + + return data.buf[0]; + } + + /******************************************************************* + * SPI + ******************************************************************/ + boost::uint32_t transact_spi( + int which_slave, + const uhd::usrp::spi_config_t &config, + boost::uint32_t bits, + size_t num_bits, + bool readback + ){ + //load data struct + usrp_e_spi data; + data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; + data.slave = which_slave; + data.length = num_bits; + data.data = bits; + + //load the flags + data.flags = 0; + data.flags |= (config.miso_edge == uhd::usrp::spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (config.mosi_edge == uhd::usrp::spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; + + //call the spi ioctl + this->ioctl(USRP_E_SPI, &data); + + //unload the data + return data.data; + } + +private: int _node_fd; +}; + +/*********************************************************************** + * Public Make Function + **********************************************************************/ +usrp_e_iface::sptr usrp_e_iface::make(int node_fd){ + return sptr(new usrp_e_iface_impl(node_fd)); +} diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.hpp b/host/lib/usrp/usrp_e/usrp_e_iface.hpp new file mode 100644 index 000000000..4fc3bb33d --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_iface.hpp @@ -0,0 +1,97 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_USRP_E_IFACE_HPP +#define INCLUDED_USRP_E_IFACE_HPP + +#include +#include //spi config +#include +#include +#include + +/*! + * The usrp-e interface class: + * Provides a set of functions to implementation layer. + * Including spi, peek, poke, control... + */ +class usrp_e_iface : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a new usrp-e interface with the control transport. + * \param node_fd the file descriptor for the kernel module node + * \return a new usrp-e interface object + */ + static sptr make(int node_fd); + + /*! + * Perform an ioctl call on the device node file descriptor. + * This will throw when the internal ioctl call fails. + * \param request the control word + * \param mem pointer to some memory + */ + virtual void ioctl(int request, void *mem) = 0; + + /*! + * Write a register (32 bits) + * \param addr the address + * \param data the 32bit data + */ + virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; + + /*! + * Read a register (32 bits) + * \param addr the address + * \return the 32bit data + */ + virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; + + /*! + * Write a register (16 bits) + * \param addr the address + * \param data the 16bit data + */ + virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0; + + /*! + * Read a register (16 bits) + * \param addr the address + * \return the 16bit data + */ + virtual boost::uint16_t peek16(boost::uint32_t addr) = 0; + + /*! + * Perform an spi transaction. + * \param which_slave the slave device number + * \param config spi config args + * \param data the bits to write + * \param num_bits how many bits in data + * \param readback true to readback a value + * \return spi data if readback set + */ + virtual boost::uint32_t transact_spi( + int which_slave, + const uhd::usrp::spi_config_t &config, + boost::uint32_t data, + size_t num_bits, + bool readback + ) = 0; +}; + +#endif /* INCLUDED_USRP_E_IFACE_HPP */ diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 3fefd6787..4d08210e2 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -22,8 +22,6 @@ #include #include #include //open -#include //ioctl -#include using namespace uhd; using namespace uhd::usrp; @@ -43,30 +41,24 @@ static std::string abs_path(const std::string &file_path){ /*********************************************************************** * Discovery **********************************************************************/ -device_addrs_t usrp_e::find(const device_addr_t &device_addr){ +device_addrs_t usrp_e::find(const device_addr_t &hint){ device_addrs_t usrp_e_addrs; - //if a node was provided, use it and only it - if (device_addr.has_key("node")){ - if (not fs::exists(device_addr["node"])) return usrp_e_addrs; + //device node not provided, assume its 0 + if (not hint.has_key("node")){ + device_addr_t new_addr = hint; + new_addr["node"] = "/dev/usrp_e0"; + return usrp_e::find(new_addr); + } + + //use the given device node name + if (fs::exists(hint["node"])){ device_addr_t new_addr; new_addr["name"] = "USRP-E"; - new_addr["node"] = abs_path(device_addr["node"]); + new_addr["node"] = abs_path(hint["node"]); usrp_e_addrs.push_back(new_addr); } - //otherwise look for a few nodes at small indexes - else{ - for(size_t i = 0; i < 5; i++){ - std::string node = str(boost::format("/dev/usrp1_e%d") % i); - if (not fs::exists(node)) continue; - device_addr_t new_addr; - new_addr["name"] = "USRP-E"; - new_addr["node"] = abs_path(node); - usrp_e_addrs.push_back(new_addr); - } - } - return usrp_e_addrs; } @@ -88,6 +80,8 @@ usrp_e_impl::usrp_e_impl(const std::string &node){ )); } + _iface = usrp_e_iface::make(_node_fd); + //initialize the mboard mboard_init(); @@ -104,63 +98,6 @@ usrp_e_impl::~usrp_e_impl(void){ ::close(_node_fd); } -/*********************************************************************** - * Misc Methods - **********************************************************************/ -void usrp_e_impl::ioctl(int request, void *mem){ - if (::ioctl(_node_fd, request, mem) < 0){ - throw std::runtime_error(str( - boost::format("ioctl failed with request %d") % request - )); - } -} - -void usrp_e_impl::poke32(boost::uint32_t addr, boost::uint32_t value){ - //load the data struct - usrp_e_ctl32 data; - data.offset = addr; - data.count = 1; - data.buf[0] = value; - - //call the ioctl - this->ioctl(USRP_E_WRITE_CTL32, &data); -} - -void usrp_e_impl::poke16(boost::uint32_t addr, boost::uint16_t value){ - //load the data struct - usrp_e_ctl16 data; - data.offset = addr; - data.count = 1; - data.buf[0] = value; - - //call the ioctl - this->ioctl(USRP_E_WRITE_CTL16, &data); -} - -boost::uint32_t usrp_e_impl::peek32(boost::uint32_t addr){ - //load the data struct - usrp_e_ctl32 data; - data.offset = addr; - data.count = 1; - - //call the ioctl - this->ioctl(USRP_E_READ_CTL32, &data); - - return data.buf[0]; -} - -boost::uint16_t usrp_e_impl::peek16(boost::uint32_t addr){ - //load the data struct - usrp_e_ctl16 data; - data.offset = addr; - data.count = 1; - - //call the ioctl - this->ioctl(USRP_E_READ_CTL16, &data); - - return data.buf[0]; -} - /*********************************************************************** * Device Get **********************************************************************/ diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 21023ae55..08ace2ffb 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -15,21 +15,20 @@ // along with this program. If not, see . // -#include +#include "usrp_e_iface.hpp" #include +#include #include #ifndef INCLUDED_USRP_E_IMPL_HPP #define INCLUDED_USRP_E_IMPL_HPP -class usrp_e_impl; // dummy class declaration - /*! - * Make a usrp_e dboard interface. - * \param impl a pointer to the usrp_e impl object + * Make a usrp-e dboard interface. + * \param iface the usrp-e interface object * \return a sptr to a new dboard interface */ -uhd::usrp::dboard_interface::sptr make_usrp_e_dboard_interface(usrp_e_impl *impl); +uhd::usrp::dboard_iface::sptr make_usrp_e_dboard_iface(usrp_e_iface::sptr iface); /*! * Simple wax obj proxy class: @@ -84,22 +83,9 @@ public: size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &); size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &); - /*! - * Perform an ioctl call on the device node file descriptor. - * This will throw when the internal ioctl call fails. - * \param request the control word - * \param mem pointer to some memory - */ - void ioctl(int request, void *mem); - - //peekers and pokers - void poke32(boost::uint32_t addr, boost::uint32_t value); - void poke16(boost::uint32_t addr, boost::uint16_t value); - boost::uint32_t peek32(boost::uint32_t addr); - boost::uint16_t peek16(boost::uint32_t addr); - private: static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); + usrp_e_iface::sptr _iface; int _node_fd; uhd::clock_config_t _clock_config; -- cgit v1.2.3 From de668d9924b6176e8296dee5929aab1e37374d8b Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 20 Apr 2010 21:46:51 +0000 Subject: Add scripts to read and write board id info into usrp e id eeprom --- host/apps/omap_debug/read_board_id.sh | 10 ++++++++++ host/apps/omap_debug/write_board_id.sh | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100755 host/apps/omap_debug/read_board_id.sh create mode 100755 host/apps/omap_debug/write_board_id.sh (limited to 'host') diff --git a/host/apps/omap_debug/read_board_id.sh b/host/apps/omap_debug/read_board_id.sh new file mode 100755 index 000000000..96081f219 --- /dev/null +++ b/host/apps/omap_debug/read_board_id.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +i2cget -y 3 0x51 0x00 b +i2cget -y 3 0x51 0x01 b +i2cget -y 3 0x51 0x02 b +i2cget -y 3 0x51 0x03 b +i2cget -y 3 0x51 0x04 b +i2cget -y 3 0x51 0x05 b + + diff --git a/host/apps/omap_debug/write_board_id.sh b/host/apps/omap_debug/write_board_id.sh new file mode 100755 index 000000000..139394a4c --- /dev/null +++ b/host/apps/omap_debug/write_board_id.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +i2cset -y 3 0x51 0x00 0x00 +i2cset -y 3 0x51 0x01 0x03 +i2cset -y 3 0x51 0x02 0x00 +i2cset -y 3 0x51 0x03 0x00 +i2cset -y 3 0x51 0x04 0x01 +i2cset -y 3 0x51 0x05 0x00 + + -- cgit v1.2.3 From bbfb3a7a9554c06fd54c3c572eb9a716627cc50c Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 20 Apr 2010 11:06:28 +0000 Subject: Fix script to write board id eeprom. --- host/apps/omap_debug/write_board_id.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/write_board_id.sh b/host/apps/omap_debug/write_board_id.sh index 139394a4c..067269c64 100755 --- a/host/apps/omap_debug/write_board_id.sh +++ b/host/apps/omap_debug/write_board_id.sh @@ -3,8 +3,8 @@ i2cset -y 3 0x51 0x00 0x00 i2cset -y 3 0x51 0x01 0x03 i2cset -y 3 0x51 0x02 0x00 -i2cset -y 3 0x51 0x03 0x00 -i2cset -y 3 0x51 0x04 0x01 +i2cset -y 3 0x51 0x03 0x01 +i2cset -y 3 0x51 0x04 0x00 i2cset -y 3 0x51 0x05 0x00 -- cgit v1.2.3 From 0e11c5ddbcee0ca6afaf06920764a05d046df358 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 20 Apr 2010 11:07:05 +0000 Subject: Fix silly typo in script. --- host/apps/omap_debug/fetch-u-boot.sh | 1 + 1 file changed, 1 insertion(+) (limited to 'host') diff --git a/host/apps/omap_debug/fetch-u-boot.sh b/host/apps/omap_debug/fetch-u-boot.sh index a2a488fb2..5309364b8 100755 --- a/host/apps/omap_debug/fetch-u-boot.sh +++ b/host/apps/omap_debug/fetch-u-boot.sh @@ -2,5 +2,6 @@ if [ $GHQ ]; then scp $GHQ_USER@astro:/workspace/usrp1-e-dev/u-boot-overo/u-boot.bin /media/mmcblk0p1/ else scp balister@192.168.1.167:src/git/u-boot/u-boot.bin /media/mmcblk0p1/ +fi sync -- cgit v1.2.3 From dfd5bed2b32131cd398a5daae184cec81488b5de Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 20 Apr 2010 13:33:32 +0000 Subject: Always put new bin file in /home/root. --- host/apps/omap_debug/fetch-bin.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/fetch-bin.sh b/host/apps/omap_debug/fetch-bin.sh index d1502f95c..019ddaaf2 100755 --- a/host/apps/omap_debug/fetch-bin.sh +++ b/host/apps/omap_debug/fetch-bin.sh @@ -1,6 +1,6 @@ if [ $GHQ ]; then - scp $GHQ_USER@astro:/workspace/usrp1-e-dev/u1e.bin . + scp $GHQ_USER@astro:/workspace/usrp1-e-dev/u1e.bin /home/root else - scp -P 8822 balister@192.168.1.10:src/git/fpgapriv/usrp2/top/u1e/build/u1e.bin . + scp -P 8822 balister@192.168.1.10:src/git/fpgapriv/usrp2/top/u1e/build/u1e.bin /home/root fi sync -- cgit v1.2.3 From 29a3b01fb48d1c10f489103b9012b14be6f1553d Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 20 Apr 2010 13:34:24 +0000 Subject: usrp-e-i2c always uses hex arguments. --- host/apps/omap_debug/usrp-e-i2c.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-i2c.c b/host/apps/omap_debug/usrp-e-i2c.c index 19d64731b..c8fcc3f98 100644 --- a/host/apps/omap_debug/usrp-e-i2c.c +++ b/host/apps/omap_debug/usrp-e-i2c.c @@ -12,13 +12,14 @@ int main(int argc, char *argv[]) { - int fp, ret, i; + int fp, ret, i, tmp; struct usrp_e_i2c *i2c_msg; int direction, address, count; if (argc < 3) { - printf("Usage: usrp_e_i2c w address data0 data1 data2 ...\n"); - printf("Usage: usrp_e_i2c r address count\n"); + printf("Usage: usrp-e-i2c w address data0 data1 data2 ...\n"); + printf("Usage: usrp-e-i2c r address count\n"); + printf("All addresses and data in hex.\n"); exit(-1); } @@ -30,7 +31,8 @@ int main(int argc, char *argv[]) return -1; } - address = atoi(argv[2]); + sscanf(argv[2], "%X", &address); + printf("Address = %X\n", address); fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); @@ -38,8 +40,9 @@ int main(int argc, char *argv[]) if (direction) { count = argc - 3; } else { - count = atoi(argv[3]); + sscanf(argv[3], "%X", &count); } + printf("Count = %X\n", count); i2c_msg = malloc(sizeof(i2c_msg) + count * sizeof(char)); @@ -50,7 +53,8 @@ int main(int argc, char *argv[]) // Write for (i=0; idata[i] = atoi(argv[3+i]); + sscanf(argv[3+i], "%X", &tmp); + i2c_msg->data[i] = tmp; } ret = ioctl(fp, USRP_E_I2C_WRITE, i2c_msg); -- cgit v1.2.3 From c05fc634407741ce202cccc0781e937897c51361 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 20 Apr 2010 13:35:00 +0000 Subject: usrp-e-spi: change active edges around. --- host/apps/omap_debug/usrp-e-spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c index f693d7db1..caa36b3f1 100644 --- a/host/apps/omap_debug/usrp-e-spi.c +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -31,7 +31,7 @@ int main(int argc, char *argv[]) spi_dat.slave = slave; spi_dat.data = data; spi_dat.length = length; - spi_dat.flags = 0; + spi_dat.flags = UE_SPI_PUSH_FALL | UE_SPI_LATCH_RISE; if (*argv[1] == 'r') { spi_dat.readback = 1; -- cgit v1.2.3 From 4e4d8556a43f7f054e760b66749c034aa5741a7f Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 20 Apr 2010 15:53:07 +0000 Subject: Initialize data array to help show when reads fail. Report return value from ioctl --- host/apps/omap_debug/usrp-e-i2c.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-i2c.c b/host/apps/omap_debug/usrp-e-i2c.c index c8fcc3f98..575430f84 100644 --- a/host/apps/omap_debug/usrp-e-i2c.c +++ b/host/apps/omap_debug/usrp-e-i2c.c @@ -49,6 +49,10 @@ int main(int argc, char *argv[]) i2c_msg->addr = address; i2c_msg->len = count; + for (i = 0; i < count; i++) { + i2c_msg->data[i] = i; + } + if (direction) { // Write @@ -63,6 +67,7 @@ int main(int argc, char *argv[]) // Read ret = ioctl(fp, USRP_E_I2C_READ, i2c_msg); + printf("Return value from i2c_read ioctl: %d\n", ret); printf("Ioctl: %d Data read :", ret); for (i=0; i Date: Tue, 20 Apr 2010 15:54:37 +0000 Subject: Add program to setup debug pins. Add script to reload fpga and module. --- host/apps/omap_debug/Makefile | 4 +- host/apps/omap_debug/reload-fpga.sh | 7 +++ host/apps/omap_debug/usrp-e-debug-pins.c | 73 ++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100755 host/apps/omap_debug/reload-fpga.sh create mode 100644 host/apps/omap_debug/usrp-e-debug-pins.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 31229d45c..61f659b3e 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-spi : usrp-e-spi.c @@ -23,6 +23,7 @@ fpga-downloader : fpga-downloader.cc usrp-e-gpio : usrp-e-gpio.c +usrp-e-debug-pins : usrp-e-debug-pins.c clean : rm -f usrp-e-spi rm -f usrp-e-i2c @@ -34,3 +35,4 @@ clean : rm -f usrp-e-button rm -f fpga-downloader rm -f usrp-e-gpio + rm -f usrp-e-debug-pins diff --git a/host/apps/omap_debug/reload-fpga.sh b/host/apps/omap_debug/reload-fpga.sh new file mode 100755 index 000000000..2754718a4 --- /dev/null +++ b/host/apps/omap_debug/reload-fpga.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +rmmod usrp_e +fpga-downloader /home/root/u1e.bin +modprobe usrp_e +usrp-e-debug-pins 1 + diff --git a/host/apps/omap_debug/usrp-e-debug-pins.c b/host/apps/omap_debug/usrp-e-debug-pins.c new file mode 100644 index 000000000..d4e3f5223 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-debug-pins.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "usrp_e.h" +#include "usrp_e_regs.hpp" + +// Usage: usrp_e_gpio + +static int fp; + +static int read_reg(__u16 reg) +{ + int ret; + struct usrp_e_ctl16 d; + + d.offset = reg; + d.count = 1; + ret = ioctl(fp, USRP_E_READ_CTL16, &d); + return d.buf[0]; +} + +static void write_reg(__u16 reg, __u16 val) +{ + int ret; + struct usrp_e_ctl16 d; + + d.offset = reg; + d.count = 1; + d.buf[0] = val; + ret = ioctl(fp, USRP_E_WRITE_CTL16, &d); +} + +int main(int argc, char *argv[]) +{ + int test; + + test = 0; + if (argc < 2) { + printf("%s 0|1|off\n", argv[0]); + } + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + if (strcmp(argv[1], "0") == 0) { + printf("Selected 0 based on %s\n", argv[1]); + write_reg(UE_REG_GPIO_TX_DDR, 0xFFFF); + write_reg(UE_REG_GPIO_RX_DDR, 0xFFFF); + write_reg(UE_REG_GPIO_TX_SEL, 0x0); + write_reg(UE_REG_GPIO_RX_SEL, 0x0); + write_reg(UE_REG_GPIO_TX_DBG, 0xFFFF); + write_reg(UE_REG_GPIO_RX_DBG, 0xFFFF); + } else if (strcmp(argv[1], "1") == 0) { + printf("Selected 1 based on %s\n", argv[1]); + write_reg(UE_REG_GPIO_TX_DDR, 0xFFFF); + write_reg(UE_REG_GPIO_RX_DDR, 0xFFFF); + write_reg(UE_REG_GPIO_TX_SEL, 0xFFFF); + write_reg(UE_REG_GPIO_RX_SEL, 0xFFFF); + write_reg(UE_REG_GPIO_TX_DBG, 0xFFFF); + write_reg(UE_REG_GPIO_RX_DBG, 0xFFFF); + } else { + printf("Selected off based on %s\n", argv[1]); + write_reg(UE_REG_GPIO_TX_DDR, 0x0); + write_reg(UE_REG_GPIO_RX_DDR, 0x0); + } + + return 0; +} -- cgit v1.2.3 From 61d8449f95c5c9f2c21c310f298e2ef7d66afdbb Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 21 Apr 2010 15:40:59 +0000 Subject: Add register definitions for new transfer scheme. --- host/lib/usrp/usrp_e/usrp_e_regs.hpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp index edd87e649..e7f89db7b 100644 --- a/host/lib/usrp/usrp_e/usrp_e_regs.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -28,6 +28,8 @@ #define UE_REG_MISC_CGEN_CTRL UE_REG_MISC_BASE + 4 #define UE_REG_MISC_CGEN_ST UE_REG_MISC_BASE + 6 #define UE_REG_MISC_TEST UE_REG_MISC_BASE + 8 +#define UE_REG_MISC_RX_LEN UE_REG_MISC_BASE + 10 +#define UE_REG_MISC_TX_LEN UE_REG_MISC_BASE + 12 ///////////////////////////////////////////////////// // Slave 1 -- UART -- cgit v1.2.3 From eb2f38d4af5345a64cd1feb92fa5cb44433d037b Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 22 Apr 2010 15:41:42 +0000 Subject: Update transfer test program to use usrp_transfer_frame struct. --- host/apps/omap_debug/usrp-e-rw.c | 64 +++++++++++++++++++++++++++++----------- host/apps/omap_debug/usrp_e.h | 13 ++++++++ 2 files changed, 60 insertions(+), 17 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-rw.c b/host/apps/omap_debug/usrp-e-rw.c index 5607166b0..5fd73e9b6 100644 --- a/host/apps/omap_debug/usrp-e-rw.c +++ b/host/apps/omap_debug/usrp-e-rw.c @@ -4,11 +4,16 @@ #include #include #include +#include +#include "usrp_e.h" + +#define PKT_DATA_LENGTH 30 +// max length #define PKT_DATA_LENGTH 1016 struct pkt { int checksum; int seq_num; - short data[1020]; + short data[PKT_DATA_LENGTH]; }; static int fp; @@ -20,7 +25,7 @@ static int calc_checksum(struct pkt *p) i = 0; sum = 0; - for (i=0; i<1020; i++) + for (i=0; idata[i]; sum += p->seq_num; @@ -31,23 +36,35 @@ static int calc_checksum(struct pkt *p) static void *read_thread(void *threadid) { int cnt, prev_seq_num; - struct pkt rx_data; + struct usrp_transfer_frame *rx_data; + struct pkt *p; printf("Greetings from the reading thread!\n"); + rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); + //p = &(rx_data->buf[0]); + printf("Address of rx_data = %p, p = %p\n", rx_data, p); + printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); + printf("sizeof rx data = %X\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + prev_seq_num = 0; while (1) { - cnt = read(fp, &rx_data, 2048); - if (rx_data.seq_num != prev_seq_num + 1) - printf("Sequence number fail, current = %d, previous = %d\n", - rx_data.seq_num, prev_seq_num); - prev_seq_num = rx_data.seq_num; + cnt = read(fp, rx_data, 2048); + printf("Packet received, flags = %X, len = %X\n", rx_data->flags, rx_data->len); + printf("p->seq_num = %d\n", p->seq_num); + + if (p->seq_num != prev_seq_num + 1) + printf("Sequence number fail, current = %X, previous = %X\n", + p->seq_num, prev_seq_num); + prev_seq_num = p->seq_num; - if (calc_checksum(&rx_data) != rx_data.checksum) - printf("Checksum fail packet = %d, expected = %d\n", - calc_checksum(&rx_data), rx_data.checksum); + if (calc_checksum(p) != p->checksum) + printf("Checksum fail packet = %X, expected = %X\n", + calc_checksum(p), p->checksum); + printf("\n"); } } @@ -55,20 +72,31 @@ static void *read_thread(void *threadid) static void *write_thread(void *threadid) { int seq_number, i, cnt; - struct pkt tx_data; + struct usrp_transfer_frame *tx_data; + struct pkt *p; printf("Greetings from the write thread!\n"); - for (i=0; i<1020; i++) - tx_data.data[i] = random() >> 16; + tx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); + printf("Address of tx_data = %p, p = %p\n", tx_data, p); + printf("sizeof tx data = %X\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + + for (i=0; idata[i] = random() >> 16; + p->data[i] = i; + + tx_data->flags = 0xdeadbeef; + tx_data->len = 8 + PKT_DATA_LENGTH * 2; seq_number = 1; while (1) { - tx_data.seq_num = seq_number++; - tx_data.checksum = calc_checksum(&tx_data); - cnt = write(fp, &tx_data, 2048); + p->seq_num = seq_number++; + p->checksum = calc_checksum(p); + cnt = write(fp, tx_data, 2048); + sleep(1); } } @@ -86,6 +114,8 @@ int main(int argc, char *argv[]) exit(-1); } + sleep(1); + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { printf("Failed to create tx thread\n"); exit(-1); diff --git a/host/apps/omap_debug/usrp_e.h b/host/apps/omap_debug/usrp_e.h index aa8ef3d57..48a3201cb 100644 --- a/host/apps/omap_debug/usrp_e.h +++ b/host/apps/omap_debug/usrp_e.h @@ -69,4 +69,17 @@ struct usrp_e_i2c { #define USRP_E_I2C_READ _IOR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) #define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) +// Data transfer frame definition + +struct usrp_transfer_frame { + __u32 flags; + __u32 len; + __u8 buf[]; +}; + +struct ring_buffer_entry { + unsigned long dma_addr; + struct usrp_transfer_frame *frame_addr; +}; + #endif -- cgit v1.2.3 From f5b6776a0b642c0357fbecdead9d2b1ac6ece3d3 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 23 Apr 2010 14:04:37 +0000 Subject: Updates to test programs. --- host/apps/omap_debug/Makefile | 6 +- host/apps/omap_debug/usrp-e-rw-random.c | 147 ++++++++++++++++++++++++++++++++ host/apps/omap_debug/usrp-e-rw.c | 42 ++++++--- 3 files changed, 181 insertions(+), 14 deletions(-) create mode 100644 host/apps/omap_debug/usrp-e-rw-random.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 61f659b3e..b00210c4f 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-spi : usrp-e-spi.c @@ -9,6 +9,9 @@ usrp-e-i2c : usrp-e-i2c.c usrp-e-rw : usrp-e-rw.c gcc -o $@ $< -lpthread +usrp-e-rw-random : usrp-e-rw-random.c + gcc -o $@ $< -lpthread + usrp-e-uart : usrp-e-uart.c usrp-e-uart-rx : usrp-e-uart-rx.c @@ -28,6 +31,7 @@ clean : rm -f usrp-e-spi rm -f usrp-e-i2c rm -f usrp-e-rw + rm -f usrp-e-rw-random rm -f usrp-e-uart rm -f usrp-e-uart-rx rm -f usrp-e-led diff --git a/host/apps/omap_debug/usrp-e-rw-random.c b/host/apps/omap_debug/usrp-e-rw-random.c new file mode 100644 index 000000000..67d6ca803 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-rw-random.c @@ -0,0 +1,147 @@ +#include +#include +#include +#include +#include +#include +#include +#include "usrp_e.h" + +// max length #define PKT_DATA_LENGTH 1014 +static int packet_data_length; + +struct pkt { + int checksum; + int seq_num; + int len; + short data[]; +}; + +static int fp; + +static int calc_checksum(struct pkt *p) +{ + int i, sum; + + i = 0; + sum = 0; + + for (i=0; i < p->len; i++) + sum += p->data[i]; + + sum += p->seq_num; + + return sum; +} + +int randN(int n) +{ + long tmp; + + tmp = rand() % n; + + return tmp; +} + +static void *read_thread(void *threadid) +{ + int cnt, prev_seq_num; + struct usrp_transfer_frame *rx_data; + struct pkt *p; + + printf("Greetings from the reading thread!\n"); + + // IMPORTANT: must assume max length packet from fpga + rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1014 * 2)); + rx_data = malloc(2048); + p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); + //p = &(rx_data->buf[0]); + printf("Address of rx_data = %p, p = %p\n", rx_data, p); + printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); + printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + + prev_seq_num = 0; + + while (1) { + + cnt = read(fp, rx_data, 2048); +// printf("Packet received, flags = %X, len = %d\n", rx_data->flags, rx_data->len); +// printf("p->seq_num = %d\n", p->seq_num); + + if (p->seq_num != prev_seq_num + 1) + printf("Sequence number fail, current = %d, previous = %d\n", + p->seq_num, prev_seq_num); + prev_seq_num = p->seq_num; + + if (calc_checksum(p) != p->checksum) + printf("Checksum fail packet = %d, expected = %d\n", + calc_checksum(p), p->checksum); +// printf("\n"); + } + +} + +static void *write_thread(void *threadid) +{ + int seq_number, i, cnt, pkt_cnt; + struct usrp_transfer_frame *tx_data; + struct pkt *p; + + printf("Greetings from the write thread!\n"); + + // Allocate max length buffer for frame + tx_data = malloc(2048); + p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); + printf("Address of tx_data = %p, p = %p\n", tx_data, p); + + printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); + + for (i=0; i < 1014; i++) +// p->data[i] = random() >> 16; + p->data[i] = i; + + tx_data->flags = 0xdeadbeef; + tx_data->len = 8 + packet_data_length * 2; + + printf("tx_data->len = %d\n", tx_data->len); + + seq_number = 1; + + while (1) { + pkt_cnt = randN(16); + for (i = 0; i < pkt_cnt; i++) { + p->seq_num = seq_number++; + p->len = randN(1013) + 1; + p->checksum = calc_checksum(p); + tx_data->len = 12 + p->len * 2; + cnt = write(fp, tx_data, 2048); + } + sleep(random() >> 31); + } +} + + +int main(int argc, char *argv[]) +{ + pthread_t tx, rx; + long int t; + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { + printf("Failed to create rx thread\n"); + exit(-1); + } + + sleep(1); + + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { + printf("Failed to create tx thread\n"); + exit(-1); + } + + sleep(10000); + + printf("Done sleeping\n"); +} diff --git a/host/apps/omap_debug/usrp-e-rw.c b/host/apps/omap_debug/usrp-e-rw.c index 5fd73e9b6..edfcea92a 100644 --- a/host/apps/omap_debug/usrp-e-rw.c +++ b/host/apps/omap_debug/usrp-e-rw.c @@ -7,13 +7,13 @@ #include #include "usrp_e.h" -#define PKT_DATA_LENGTH 30 // max length #define PKT_DATA_LENGTH 1016 +static int packet_data_length; struct pkt { int checksum; int seq_num; - short data[PKT_DATA_LENGTH]; + short data[]; }; static int fp; @@ -25,7 +25,7 @@ static int calc_checksum(struct pkt *p) i = 0; sum = 0; - for (i=0; idata[i]; sum += p->seq_num; @@ -41,20 +41,24 @@ static void *read_thread(void *threadid) printf("Greetings from the reading thread!\n"); - rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + // IMPORTANT: must assume max length packet from fpga + rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1016 * 2)); p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); //p = &(rx_data->buf[0]); printf("Address of rx_data = %p, p = %p\n", rx_data, p); printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); - printf("sizeof rx data = %X\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); prev_seq_num = 0; while (1) { cnt = read(fp, rx_data, 2048); - printf("Packet received, flags = %X, len = %X\n", rx_data->flags, rx_data->len); - printf("p->seq_num = %d\n", p->seq_num); + if (cnt < 0) + printf("Error returned from read: %d\n", cnt); + +// printf("Packet received, flags = %X, len = %d\n", rx_data->flags, rx_data->len); +// printf("p->seq_num = %d\n", p->seq_num); if (p->seq_num != prev_seq_num + 1) printf("Sequence number fail, current = %X, previous = %X\n", @@ -64,7 +68,7 @@ static void *read_thread(void *threadid) if (calc_checksum(p) != p->checksum) printf("Checksum fail packet = %X, expected = %X\n", calc_checksum(p), p->checksum); - printf("\n"); +// printf("\n"); } } @@ -77,26 +81,31 @@ static void *write_thread(void *threadid) printf("Greetings from the write thread!\n"); - tx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + tx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (packet_data_length * 2)); p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); printf("Address of tx_data = %p, p = %p\n", tx_data, p); - printf("sizeof tx data = %X\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); - for (i=0; idata[i] = random() >> 16; p->data[i] = i; tx_data->flags = 0xdeadbeef; - tx_data->len = 8 + PKT_DATA_LENGTH * 2; + tx_data->len = 8 + packet_data_length * 2; + + printf("tx_data->len = %d\n", tx_data->len); seq_number = 1; while (1) { +// printf("tx flags = %X, len = %d\n", tx_data->flags, tx_data->len); p->seq_num = seq_number++; p->checksum = calc_checksum(p); cnt = write(fp, tx_data, 2048); - sleep(1); + if (cnt < 0) + printf("Error returned from write: %d\n", cnt); + // sleep(1); } } @@ -106,6 +115,13 @@ int main(int argc, char *argv[]) pthread_t tx, rx; long int t; + if (argc < 2) { + printf("%s data_size\n", argv[0]); + return -1; + } + + packet_data_length = atoi(argv[1]); + fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); -- cgit v1.2.3 From b317f4df86d24cc9a47b8a8191f57545875f3afe Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 25 Apr 2010 00:42:52 +0000 Subject: removed boost exception stuff that makes it incompadible with 1.36, remember this diff --- host/include/uhd/utils/assert.hpp | 4 ++++ host/include/uhd/utils/props.hpp | 4 ++++ host/include/uhd/utils/safe_main.hpp | 6 +++--- 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/include/uhd/utils/assert.hpp b/host/include/uhd/utils/assert.hpp index 01beed757..0a278312e 100644 --- a/host/include/uhd/utils/assert.hpp +++ b/host/include/uhd/utils/assert.hpp @@ -28,6 +28,10 @@ #include #include +#ifndef BOOST_THROW_EXCEPTION +#define BOOST_THROW_EXCEPTION(x) throw std::runtime_error("") +#endif + namespace uhd{ //! The exception to throw when assertions fail diff --git a/host/include/uhd/utils/props.hpp b/host/include/uhd/utils/props.hpp index 516102a5f..6c40c32e0 100644 --- a/host/include/uhd/utils/props.hpp +++ b/host/include/uhd/utils/props.hpp @@ -27,6 +27,10 @@ #include #include +#ifndef BOOST_THROW_EXCEPTION +#define BOOST_THROW_EXCEPTION(x) throw std::runtime_error("") +#endif + namespace uhd{ //! The type for a vector of property names diff --git a/host/include/uhd/utils/safe_main.hpp b/host/include/uhd/utils/safe_main.hpp index a4e4e06e8..39d2282cd 100644 --- a/host/include/uhd/utils/safe_main.hpp +++ b/host/include/uhd/utils/safe_main.hpp @@ -19,7 +19,7 @@ #define INCLUDED_UHD_UTILS_SAFE_MAIN_HPP #include -#include +//#include #include #include @@ -34,9 +34,9 @@ int main(int argc, char *argv[]){ \ try { \ return _main(argc, argv); \ - } catch(const boost::exception &e){ \ + } /*catch(const boost::exception &e){ \ std::cerr << "Error: " << boost::diagnostic_information(e) << std::endl; \ - } catch(const std::exception &e) { \ + }*/ catch(const std::exception &e) { \ std::cerr << "Error: " << e.what() << std::endl; \ } catch(...) { \ std::cerr << "Error: unknown exception" << std::endl; \ -- cgit v1.2.3 From 7953156249776ce7d45bb2a24c8ac88edb644c64 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 27 Apr 2010 08:17:46 +0000 Subject: Send only required number of bytes. Do it for longer. --- host/apps/omap_debug/usrp-e-rw-random.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-rw-random.c b/host/apps/omap_debug/usrp-e-rw-random.c index 67d6ca803..c6a838067 100644 --- a/host/apps/omap_debug/usrp-e-rw-random.c +++ b/host/apps/omap_debug/usrp-e-rw-random.c @@ -114,7 +114,7 @@ static void *write_thread(void *threadid) p->len = randN(1013) + 1; p->checksum = calc_checksum(p); tx_data->len = 12 + p->len * 2; - cnt = write(fp, tx_data, 2048); + cnt = write(fp, tx_data, tx_data->len + 8); } sleep(random() >> 31); } @@ -141,7 +141,7 @@ int main(int argc, char *argv[]) exit(-1); } - sleep(10000); + sleep(1000000000); printf("Done sleeping\n"); } -- cgit v1.2.3 From 245b46da0b603e3c12c56fdad782ff884b2a6432 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 27 Apr 2010 08:18:24 +0000 Subject: Add program to exercise interface using internal fpga data source and data sink. --- host/apps/omap_debug/Makefile | 6 +- host/apps/omap_debug/usrp-e-fpga-rw.c | 167 ++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 host/apps/omap_debug/usrp-e-fpga-rw.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index b00210c4f..f48eb9539 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-fpga-rw usrp-e-spi : usrp-e-spi.c @@ -9,6 +9,9 @@ usrp-e-i2c : usrp-e-i2c.c usrp-e-rw : usrp-e-rw.c gcc -o $@ $< -lpthread +usrp-e-fpga-rw : usrp-e-fpga-rw.c + gcc -o $@ $< -lpthread + usrp-e-rw-random : usrp-e-rw-random.c gcc -o $@ $< -lpthread @@ -31,6 +34,7 @@ clean : rm -f usrp-e-spi rm -f usrp-e-i2c rm -f usrp-e-rw + rm -f usrp-e-fpga-rw rm -f usrp-e-rw-random rm -f usrp-e-uart rm -f usrp-e-uart-rx diff --git a/host/apps/omap_debug/usrp-e-fpga-rw.c b/host/apps/omap_debug/usrp-e-fpga-rw.c new file mode 100644 index 000000000..455657203 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-fpga-rw.c @@ -0,0 +1,167 @@ +#include +#include +#include +#include +#include +#include +#include +#include "usrp_e.h" + +// max length #define PKT_DATA_LENGTH 1016 +static int packet_data_length; + +struct pkt { + int checksum; + int seq_num; + short data[]; +}; + +static int fp; + +static int calc_checksum(struct pkt *p) +{ + int i, sum; + + i = 0; + sum = 0; + + for (i=0; i < packet_data_length; i++) + sum += p->data[i]; + + sum += p->seq_num; + + return sum; +} + +static void *read_thread(void *threadid) +{ + int cnt, prev_seq_num; + struct usrp_transfer_frame *rx_data; + struct pkt *p; + + printf("Greetings from the reading thread!\n"); + + // IMPORTANT: must assume max length packet from fpga + rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1016 * 2)); + p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); + //p = &(rx_data->buf[0]); + printf("Address of rx_data = %p, p = %p\n", rx_data, p); + printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); + printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + + prev_seq_num = 0; + + while (1) { + + cnt = read(fp, rx_data, 2048); + if (cnt < 0) + printf("Error returned from read: %d\n", cnt); + +// printf("Packet received, flags = %X, len = %d\n", rx_data->flags, rx_data->len); +// printf("p->seq_num = %d\n", p->seq_num); + + if (p->seq_num != prev_seq_num + 1) + printf("Sequence number fail, current = %X, previous = %X\n", + p->seq_num, prev_seq_num); + prev_seq_num = p->seq_num; + + if (calc_checksum(p) != p->checksum) + printf("Checksum fail packet = %X, expected = %X\n", + calc_checksum(p), p->checksum); +// printf("\n"); + } + +} + +static void *write_thread(void *threadid) +{ + int seq_number, i, cnt; + struct usrp_transfer_frame *tx_data; + struct pkt *p; + + printf("Greetings from the write thread!\n"); + + tx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (packet_data_length * 2)); + p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); + printf("Address of tx_data = %p, p = %p\n", tx_data, p); + + printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); + + for (i=0; i < packet_data_length; i++) +// p->data[i] = random() >> 16; + p->data[i] = i; + + tx_data->flags = 0; + tx_data->len = 8 + packet_data_length * 2; + + printf("tx_data->len = %d\n", tx_data->len); + + seq_number = 1; + + while (1) { +// printf("tx flags = %X, len = %d\n", tx_data->flags, tx_data->len); + p->seq_num = seq_number++; + p->checksum = calc_checksum(p); + cnt = write(fp, tx_data, 2048); + if (cnt < 0) + printf("Error returned from write: %d\n", cnt); +// sleep(1); + } +} + + +int main(int argc, char *argv[]) +{ + pthread_t tx, rx; + long int t; + int fpga_config_flag ,decimation; + struct usrp_e_ctl16 d; + + if (argc < 4) { + printf("%s t|w|rw decimation data_size\n", argv[0]); + return -1; + } + + decimation = atoi(argv[2]); + packet_data_length = atoi(argv[3]); + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + fpga_config_flag = 0; + if (strcmp(argv[1], "w") == 0) + fpga_config_flag |= (1 << 15); + else if (strcmp(argv[1], "r") == 0) + fpga_config_flag |= (1 << 14); + else if (strcmp(argv[1], "rw") == 0) + fpga_config_flag |= ((1 << 15) | (1 << 14)); + + fpga_config_flag |= decimation; + + d.offset = 14; + d.count = 1; + d.buf[0] = fpga_config_flag; + ioctl(fp, USRP_E_WRITE_CTL16, &d); + + sleep(1); // in case the kernel threads need time to start. FIXME if so + + if (fpga_config_flag & (1 << 14)) { + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { + printf("Failed to create rx thread\n"); + exit(-1); + } + } + + sleep(1); + + if (fpga_config_flag & (1 << 15)) { + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { + printf("Failed to create tx thread\n"); + exit(-1); + } + } + + sleep(10000); + + printf("Done sleeping\n"); +} -- cgit v1.2.3 From 1b924876d7d7216504e604137ed0ade36460169f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 28 Apr 2010 11:25:26 -0700 Subject: usrp-e branch compiling with recent master pulled in --- host/lib/usrp/usrp_e/dboard_iface.cpp | 19 ++++++++++--------- host/lib/usrp/usrp_e/dboard_impl.cpp | 8 ++++---- host/lib/usrp/usrp_e/dsp_impl.cpp | 8 ++++---- host/lib/usrp/usrp_e/mboard_impl.cpp | 15 ++++++--------- host/lib/usrp/usrp_e/usrp_e_iface.cpp | 6 +++--- host/lib/usrp/usrp_e/usrp_e_iface.hpp | 4 ++-- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 5 +++-- 7 files changed, 32 insertions(+), 33 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp index 12e8fe206..c4784d29c 100644 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -23,6 +23,7 @@ #include #include //i2c and spi constants +using namespace uhd; using namespace uhd::usrp; class usrp_e_dboard_iface : public dboard_iface{ @@ -37,8 +38,8 @@ public: void set_gpio_ddr(unit_t, boost::uint16_t); boost::uint16_t read_gpio(unit_t); - void write_i2c(int, const byte_vector_t &); - byte_vector_t read_i2c(int, size_t); + void write_i2c(boost::uint8_t, const byte_vector_t &); + byte_vector_t read_i2c(boost::uint8_t, size_t); void write_spi( unit_t unit, @@ -171,14 +172,14 @@ boost::uint32_t usrp_e_dboard_iface::read_write_spi( **********************************************************************/ static const size_t max_i2c_data_bytes = 10; -void usrp_e_dboard_iface::write_i2c(int i2c_addr, const byte_vector_t &buf){ +void usrp_e_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &buf){ //allocate some memory for this transaction - ASSERT_THROW(buf.size() <= max_i2c_data_bytes); + UHD_ASSERT_THROW(buf.size() <= max_i2c_data_bytes); boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; //load the data struct usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = i2c_addr; + data.addr = addr; data.len = buf.size(); std::copy(buf.begin(), buf.end(), data.data); @@ -186,14 +187,14 @@ void usrp_e_dboard_iface::write_i2c(int i2c_addr, const byte_vector_t &buf){ _iface->ioctl(USRP_E_I2C_WRITE, &data); } -dboard_iface::byte_vector_t usrp_e_dboard_iface::read_i2c(int i2c_addr, size_t num_bytes){ +byte_vector_t usrp_e_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){ //allocate some memory for this transaction - ASSERT_THROW(num_bytes <= max_i2c_data_bytes); + UHD_ASSERT_THROW(num_bytes <= max_i2c_data_bytes); boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; //load the data struct usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = i2c_addr; + data.addr = addr; data.len = num_bytes; //call the spi ioctl @@ -201,7 +202,7 @@ dboard_iface::byte_vector_t usrp_e_dboard_iface::read_i2c(int i2c_addr, size_t n //unload the data byte_vector_t ret(data.len); - ASSERT_THROW(ret.size() == num_bytes); + UHD_ASSERT_THROW(ret.size() == num_bytes); std::copy(data.data, data.data+ret.size(), ret.begin()); return ret; } diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index df0f1d9a9..e87a2c0a5 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -50,26 +50,26 @@ void usrp_e_impl::dboard_init(void){ * RX Dboard Get **********************************************************************/ void usrp_e_impl::rx_dboard_get(const wax::obj &, wax::obj &){ - + UHD_THROW_PROP_GET_ERROR(); } /*********************************************************************** * RX Dboard Set **********************************************************************/ void usrp_e_impl::rx_dboard_set(const wax::obj &, const wax::obj &){ - + UHD_THROW_PROP_SET_ERROR(); } /*********************************************************************** * TX Dboard Get **********************************************************************/ void usrp_e_impl::tx_dboard_get(const wax::obj &, wax::obj &){ - + UHD_THROW_PROP_GET_ERROR(); } /*********************************************************************** * TX Dboard Set **********************************************************************/ void usrp_e_impl::tx_dboard_set(const wax::obj &, const wax::obj &){ - + UHD_THROW_PROP_SET_ERROR(); } diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp index e32c76a3d..272ac71b3 100644 --- a/host/lib/usrp/usrp_e/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -34,14 +34,14 @@ void usrp_e_impl::rx_ddc_init(void){ * RX DDC Get **********************************************************************/ void usrp_e_impl::rx_ddc_get(const wax::obj &, wax::obj &){ - + UHD_THROW_PROP_GET_ERROR(); } /*********************************************************************** * RX DDC Set **********************************************************************/ void usrp_e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){ - + UHD_THROW_PROP_SET_ERROR(); } /*********************************************************************** @@ -58,12 +58,12 @@ void usrp_e_impl::tx_duc_init(void){ * TX DUC Get **********************************************************************/ void usrp_e_impl::tx_duc_get(const wax::obj &, wax::obj &){ - + UHD_THROW_PROP_GET_ERROR(); } /*********************************************************************** * TX DUC Set **********************************************************************/ void usrp_e_impl::tx_duc_set(const wax::obj &, const wax::obj &){ - + UHD_THROW_PROP_SET_ERROR(); } diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index 2d225c6ea..00ce4b782 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -58,7 +58,7 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_RX_DBOARD: - ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(name == ""); val = _rx_dboard_proxy->get_link(); return; @@ -67,7 +67,7 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_TX_DBOARD: - ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(name == ""); val = _tx_dboard_proxy->get_link(); return; @@ -80,7 +80,7 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_RX_DSP: - ASSERT_THROW(name == "ddc0"); + UHD_ASSERT_THROW(name == "ddc0"); val = _rx_ddc_proxy->get_link(); return; @@ -89,7 +89,7 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_TX_DSP: - ASSERT_THROW(name == "duc0"); + UHD_ASSERT_THROW(name == "duc0"); val = _tx_duc_proxy->get_link(); return; @@ -101,10 +101,7 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ val = _clock_config; return; - case MBOARD_PROP_TIME_NOW: - case MBOARD_PROP_TIME_NEXT_PPS: - throw std::runtime_error("Error: trying to get write-only property on usrp-e mboard"); - + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -112,5 +109,5 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ * Mboard Set **********************************************************************/ void usrp_e_impl::mboard_set(const wax::obj &, const wax::obj &){ - + UHD_THROW_PROP_SET_ERROR(); } diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.cpp b/host/lib/usrp/usrp_e/usrp_e_iface.cpp index d4c988211..f12eee177 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.cpp @@ -100,7 +100,7 @@ public: ******************************************************************/ boost::uint32_t transact_spi( int which_slave, - const uhd::usrp::spi_config_t &config, + const uhd::spi_config_t &config, boost::uint32_t bits, size_t num_bits, bool readback @@ -114,8 +114,8 @@ public: //load the flags data.flags = 0; - data.flags |= (config.miso_edge == uhd::usrp::spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; - data.flags |= (config.mosi_edge == uhd::usrp::spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; + data.flags |= (config.miso_edge == uhd::spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (config.mosi_edge == uhd::spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; //call the spi ioctl this->ioctl(USRP_E_SPI, &data); diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.hpp b/host/lib/usrp/usrp_e/usrp_e_iface.hpp index 4fc3bb33d..850e15ac4 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.hpp @@ -19,7 +19,7 @@ #define INCLUDED_USRP_E_IFACE_HPP #include -#include //spi config +#include #include #include #include @@ -87,7 +87,7 @@ public: */ virtual boost::uint32_t transact_spi( int which_slave, - const uhd::usrp::spi_config_t &config, + const uhd::spi_config_t &config, boost::uint32_t data, size_t num_bits, bool readback diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 4d08210e2..211b939ee 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -112,7 +112,7 @@ void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ return; case DEVICE_PROP_MBOARD: - ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(name == ""); val = _mboard_proxy->get_link(); return; @@ -128,6 +128,7 @@ void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ val = size_t(_max_num_samples); return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -135,7 +136,7 @@ void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ * Device Set **********************************************************************/ void usrp_e_impl::set(const wax::obj &, const wax::obj &){ - throw std::runtime_error("Cannot set in usrp-e device"); + UHD_THROW_PROP_SET_ERROR(); } /*********************************************************************** -- cgit v1.2.3 From 1c4e9bd614dc8b7a17dc2bd95c322bbea940ca35 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 28 Apr 2010 11:33:10 -0700 Subject: moved i2c into usrp-e interface, used by dboard interface and eeprom --- host/lib/usrp/usrp_e/dboard_iface.cpp | 35 +++---------------------- host/lib/usrp/usrp_e/usrp_e_iface.cpp | 49 ++++++++++++++++++++++++++++++++--- host/lib/usrp/usrp_e/usrp_e_iface.hpp | 2 +- 3 files changed, 50 insertions(+), 36 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp index c4784d29c..f69cdd2b4 100644 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -170,41 +170,12 @@ boost::uint32_t usrp_e_dboard_iface::read_write_spi( /*********************************************************************** * I2C **********************************************************************/ -static const size_t max_i2c_data_bytes = 10; - -void usrp_e_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &buf){ - //allocate some memory for this transaction - UHD_ASSERT_THROW(buf.size() <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = addr; - data.len = buf.size(); - std::copy(buf.begin(), buf.end(), data.data); - - //call the spi ioctl - _iface->ioctl(USRP_E_I2C_WRITE, &data); +void usrp_e_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ + return _iface->write_i2c(addr, bytes); } byte_vector_t usrp_e_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){ - //allocate some memory for this transaction - UHD_ASSERT_THROW(num_bytes <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = addr; - data.len = num_bytes; - - //call the spi ioctl - _iface->ioctl(USRP_E_I2C_READ, &data); - - //unload the data - byte_vector_t ret(data.len); - UHD_ASSERT_THROW(ret.size() == num_bytes); - std::copy(data.data, data.data+ret.size(), ret.begin()); - return ret; + return _iface->read_i2c(addr, num_bytes); } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.cpp b/host/lib/usrp/usrp_e/usrp_e_iface.cpp index f12eee177..41737a716 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.cpp @@ -16,11 +16,14 @@ // #include "usrp_e_iface.hpp" +#include #include //ioctl #include //ioctl structures and constants #include #include +using namespace uhd; + class usrp_e_iface_impl : public usrp_e_iface{ public: @@ -95,12 +98,52 @@ public: return data.buf[0]; } + /******************************************************************* + * I2C + ******************************************************************/ + static const size_t max_i2c_data_bytes = 10; + + void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ + //allocate some memory for this transaction + UHD_ASSERT_THROW(bytes.size() <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c &data = reinterpret_cast(mem); + data.addr = addr; + data.len = bytes.size(); + std::copy(bytes.begin(), bytes.end(), data.data); + + //call the spi ioctl + this->ioctl(USRP_E_I2C_WRITE, &data); + } + + byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ + //allocate some memory for this transaction + UHD_ASSERT_THROW(num_bytes <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c &data = reinterpret_cast(mem); + data.addr = addr; + data.len = num_bytes; + + //call the spi ioctl + this->ioctl(USRP_E_I2C_READ, &data); + + //unload the data + byte_vector_t bytes(data.len); + UHD_ASSERT_THROW(bytes.size() == num_bytes); + std::copy(data.data, data.data+bytes.size(), bytes.begin()); + return bytes; + } + /******************************************************************* * SPI ******************************************************************/ boost::uint32_t transact_spi( int which_slave, - const uhd::spi_config_t &config, + const spi_config_t &config, boost::uint32_t bits, size_t num_bits, bool readback @@ -114,8 +157,8 @@ public: //load the flags data.flags = 0; - data.flags |= (config.miso_edge == uhd::spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; - data.flags |= (config.mosi_edge == uhd::spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; + data.flags |= (config.miso_edge == spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (config.mosi_edge == spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; //call the spi ioctl this->ioctl(USRP_E_SPI, &data); diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.hpp b/host/lib/usrp/usrp_e/usrp_e_iface.hpp index 850e15ac4..763d19581 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.hpp @@ -29,7 +29,7 @@ * Provides a set of functions to implementation layer. * Including spi, peek, poke, control... */ -class usrp_e_iface : boost::noncopyable{ +class usrp_e_iface : boost::noncopyable, public uhd::i2c_iface{ public: typedef boost::shared_ptr sptr; -- cgit v1.2.3 From f2454f90023552c00b5b25aca4e8eaa8d46c0751 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 28 Apr 2010 13:07:22 +0000 Subject: Various updates to test programs. --- host/apps/omap_debug/Makefile | 5 ++- host/apps/omap_debug/usrp-e-fpga-rw.c | 32 ++++++++++++++----- host/apps/omap_debug/usrp-e-lb-test.c | 58 +++++++++++++++++++++++++++++++++++ host/apps/omap_debug/usrp_e.h | 6 ++++ 4 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 host/apps/omap_debug/usrp-e-lb-test.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index f48eb9539..14be592ff 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-fpga-rw +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-fpga-rw usrp-e-lb-test usrp-e-spi : usrp-e-spi.c @@ -29,6 +29,8 @@ fpga-downloader : fpga-downloader.cc usrp-e-gpio : usrp-e-gpio.c +usrp-e-lb-test : usrp-e-lb-test.c + usrp-e-debug-pins : usrp-e-debug-pins.c clean : rm -f usrp-e-spi @@ -44,3 +46,4 @@ clean : rm -f fpga-downloader rm -f usrp-e-gpio rm -f usrp-e-debug-pins + rm -f usrp-e-lb-test diff --git a/host/apps/omap_debug/usrp-e-fpga-rw.c b/host/apps/omap_debug/usrp-e-fpga-rw.c index 455657203..f3fa1499a 100644 --- a/host/apps/omap_debug/usrp-e-fpga-rw.c +++ b/host/apps/omap_debug/usrp-e-fpga-rw.c @@ -38,6 +38,8 @@ static void *read_thread(void *threadid) int cnt, prev_seq_num; struct usrp_transfer_frame *rx_data; struct pkt *p; + int rx_pkt_cnt; + int i; printf("Greetings from the reading thread!\n"); @@ -51,23 +53,39 @@ static void *read_thread(void *threadid) prev_seq_num = 0; + rx_pkt_cnt = 0; + while (1) { cnt = read(fp, rx_data, 2048); if (cnt < 0) printf("Error returned from read: %d\n", cnt); + rx_pkt_cnt++; + + if (rx_pkt_cnt == 512) { + printf("."); + fflush(stdout); + rx_pkt_cnt = 0; + } + if (rx_data->flags & RB_OVERRUN) + printf("RX ring buffer overrun occurred at packet %d\n", rx_pkt_cnt); + +// for (i = 0; i < 10; i++) +// printf(" %d", p->data[i]); +// printf("\n"); + // printf("Packet received, flags = %X, len = %d\n", rx_data->flags, rx_data->len); // printf("p->seq_num = %d\n", p->seq_num); - if (p->seq_num != prev_seq_num + 1) - printf("Sequence number fail, current = %X, previous = %X\n", - p->seq_num, prev_seq_num); - prev_seq_num = p->seq_num; +// if (p->seq_num != prev_seq_num + 1) +// printf("Sequence number fail, current = %X, previous = %X\n", +// p->seq_num, prev_seq_num); +// prev_seq_num = p->seq_num; - if (calc_checksum(p) != p->checksum) - printf("Checksum fail packet = %X, expected = %X\n", - calc_checksum(p), p->checksum); +// if (calc_checksum(p) != p->checksum) +// printf("Checksum fail packet = %X, expected = %X\n", +// calc_checksum(p), p->checksum); // printf("\n"); } diff --git a/host/apps/omap_debug/usrp-e-lb-test.c b/host/apps/omap_debug/usrp-e-lb-test.c new file mode 100644 index 000000000..675de8622 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-lb-test.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include +#include +#include "usrp_e.h" + +// max length #define PKT_DATA_LENGTH 1016 + +int main(int argc, char *argv[]) +{ + struct usrp_transfer_frame *tx_data, *rx_data; + int i, fp, packet_data_length, cnt; + struct usrp_e_ctl16 d; + + if (argc < 2) { + printf("%s data_size (in bytes < 2040)\n", argv[0]); + return -1; + } + + packet_data_length = atoi(argv[1]); + + fp = open("/dev/usrp_e0", O_RDWR); + + d.offset = 14; + d.count = 1; + d.buf[0] = (1 << 13); + ioctl(fp, USRP_E_WRITE_CTL16, &d); + + tx_data = malloc(2048); + rx_data = malloc(2048); + + tx_data->flags = 0; + tx_data->len = sizeof(struct usrp_transfer_frame) + packet_data_length; + + while (1) { + + for (i = 0; i < packet_data_length; i++) { + tx_data->buf[i] = random() >> 24; + + } + + cnt = write(fp, tx_data, 2048); + cnt = read(fp, rx_data, 2048); + + if (tx_data->len != rx_data->len) + printf("Bad frame length sent %d, read %d\n", tx_data->len, rx_data->len); + + for (i = 0; i < packet_data_length; i++) { + if (tx_data->buf[i] != rx_data->buf[i]) + printf("Bad data at %d, sent %d, received %d\n", i, tx_data->buf[i], rx_data->buf[i]); + } + printf("---------------------------------------------------\n"); + sleep(1); + } +} diff --git a/host/apps/omap_debug/usrp_e.h b/host/apps/omap_debug/usrp_e.h index 48a3201cb..d4132021f 100644 --- a/host/apps/omap_debug/usrp_e.h +++ b/host/apps/omap_debug/usrp_e.h @@ -1,3 +1,4 @@ + /* * Copyright (C) 2010 Ettus Research, LLC * @@ -77,6 +78,11 @@ struct usrp_transfer_frame { __u8 buf[]; }; +// Flag defines +#define RB_USER (1 << 0) +#define RB_KERNEL (1 << 1) +#define RB_OVERRUN (1 << 2) + struct ring_buffer_entry { unsigned long dma_addr; struct usrp_transfer_frame *frame_addr; -- cgit v1.2.3 From 2de179640be9d897a63f7423f6e04399394abb8b Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 29 Apr 2010 05:26:29 +0000 Subject: Add script to setup board id info in eeprom. --- host/apps/omap_debug/setup-board-id-eeprom.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100755 host/apps/omap_debug/setup-board-id-eeprom.sh (limited to 'host') diff --git a/host/apps/omap_debug/setup-board-id-eeprom.sh b/host/apps/omap_debug/setup-board-id-eeprom.sh new file mode 100755 index 000000000..4dba1cce5 --- /dev/null +++ b/host/apps/omap_debug/setup-board-id-eeprom.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +i2cset -y 3 0x51 0x00 0x00 +i2cset -y 3 0x51 0x01 0x03 +i2cset -y 3 0x51 0x02 0x00 +i2cset -y 3 0x51 0x03 0x01 +i2cset -y 3 0x51 0x04 0x01 +i2cset -y 3 0x51 0x05 0x00 +i2cset -y 3 0x51 0x06 0x00 + +i2cget -y 3 0x51 0 b +i2cget -y 3 0x51 1 b +i2cget -y 3 0x51 2 b +i2cget -y 3 0x51 3 b +i2cget -y 3 0x51 4 b +i2cget -y 3 0x51 5 b +i2cget -y 3 0x51 6 b -- cgit v1.2.3 From 3a8577aeb3c76dce0d0dcf0c9c7ce8d9aaf0a1d8 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 29 Apr 2010 11:50:56 +0000 Subject: work on clock control init, added dummy spi slaves: must fix --- host/lib/CMakeLists.txt | 1 + host/lib/ic_reg_maps/.gitignore | 1 + host/lib/ic_reg_maps/gen_ad9522_regs.py | 4 +- host/lib/usrp/usrp_e/clock_ctrl.cpp | 129 ++++++++++++++++++++++++++++++++ host/lib/usrp/usrp_e/clock_ctrl.hpp | 55 ++++++++++++++ host/lib/usrp/usrp_e/dboard_iface.cpp | 4 +- host/lib/usrp/usrp_e/usrp_e_regs.hpp | 9 +++ 7 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 host/lib/usrp/usrp_e/clock_ctrl.cpp create mode 100644 host/lib/usrp/usrp_e/clock_ctrl.hpp (limited to 'host') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 310c81bfb..75d4ac2c4 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -177,6 +177,7 @@ CHECK_INCLUDE_FILES( IF(HAVE_USRP_E_REQUIRED_HEADERS) MESSAGE(STATUS " Building usrp-e support.") LIST(APPEND libuhd_sources + usrp/usrp_e/clock_ctrl.cpp usrp/usrp_e/dboard_impl.cpp usrp/usrp_e/dboard_iface.cpp usrp/usrp_e/dsp_impl.cpp diff --git a/host/lib/ic_reg_maps/.gitignore b/host/lib/ic_reg_maps/.gitignore index a74b07aee..053049d05 100644 --- a/host/lib/ic_reg_maps/.gitignore +++ b/host/lib/ic_reg_maps/.gitignore @@ -1 +1,2 @@ /*.pyc +/*.pyo diff --git a/host/lib/ic_reg_maps/gen_ad9522_regs.py b/host/lib/ic_reg_maps/gen_ad9522_regs.py index 63d8abe24..9da51205b 100755 --- a/host/lib/ic_reg_maps/gen_ad9522_regs.py +++ b/host/lib/ic_reg_maps/gen_ad9522_regs.py @@ -42,7 +42,7 @@ reset_all_counters 0x016[4] 0 b_counter_bypass 0x016[3] 0 normal, div1 prescaler_p 0x016[2:0] 6 div1, div2, div2_3, div4_5, div8_9, div16_17, div32_33, div3 status_pin_control 0x017[7:2] 0 -antibacklash_pulse_width 0x017[1:0] 0 2_9ns, 1_3ns, 6_0ns, 2_9ns +antibacklash_pulse_width 0x017[1:0] 0 2_9ns, 1_3ns, 6_0ns enb_cmos_ref_input_dc_off 0x018[7] 0 lock_detect_counter 0x018[6:5] 0 5cyc, 16cyc, 64cyc, 255cyc digital_lock_detect_window 0x018[4] 0 high_range, low_range @@ -60,7 +60,7 @@ enable_ref2_freq_monitor 0x01B[6] 0 enable_ref1_freq_monitor 0x01B[5] 0 refmon_pin_control 0x01B[4:0] 0 disable_switchover_deglitch 0x01C[7] 0 -select_ref2 0x01C[6] 0 ref1, ref2 +select_ref 0x01C[6] 0 ref1, ref2 use_ref_sel_pin 0x01C[5] 0 register, ref_sel enb_auto_ref_switchover 0x01C[4] 0 manual, auto stay_on_ref2 0x01C[3] 0 return_ref1, stay_ref2 diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp new file mode 100644 index 000000000..5f6fb4bfb --- /dev/null +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -0,0 +1,129 @@ +// +// Copyright 2010 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 . +// + +#include "clock_ctrl.hpp" +#include "ad9522_regs.hpp" +#include +#include "usrp_e_regs.hpp" //spi slave constants +#include +#include +#include + +using namespace uhd; + +/*********************************************************************** + * Clock Control Implementation + **********************************************************************/ +class clock_ctrl_impl : public clock_ctrl{ +public: + //structors + clock_ctrl_impl(usrp_e_iface::sptr iface); + ~clock_ctrl_impl(void); + + void enable_rx_dboard_clock(bool enb); + void enable_tx_dboard_clock(bool enb); + +private: + usrp_e_iface::sptr _iface; + ad9522_regs_t _ad9522_regs; + + void latch_regs(void){ + _ad9522_regs.io_update = 1; + this->send_reg(0x232); + } + void send_reg(boost::uint16_t addr); +}; + +/*********************************************************************** + * Clock Control Methods + **********************************************************************/ +clock_ctrl_impl::clock_ctrl_impl(usrp_e_iface::sptr iface){ + _iface = iface; + + //init the clock gen registers + //Note: out0 should already be clocking the FPGA or this isnt going to work + _ad9522_regs.sdo_active = ad9522_regs_t::SDO_ACTIVE_SDO_SDIO; + _ad9522_regs.status_pin_control = 0x1; //n divider + _ad9522_regs.ld_pin_control = 0x32; //show ref2 + _ad9522_regs.refmon_pin_control = 0x12; //show ref2 + + _ad9522_regs.enable_ref2 = 1; + _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF2; + + _ad9522_regs.r_counter_lsb = 1; + _ad9522_regs.r_counter_msb = 0; + _ad9522_regs.a_counter = 0; + _ad9522_regs.b_counter_lsb = 20; + _ad9522_regs.b_counter_msb = 0; + _ad9522_regs.prescaler_p = ad9522_regs_t::PRESCALER_P_DIV8_9; + + _ad9522_regs.pll_power_down = ad9522_regs_t::PLL_POWER_DOWN_NORMAL; + _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_3_0MA; + + _ad9522_regs.vco_calibration_now = 1; //calibrate it! + _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; + _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_VCO; + + _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS; + _ad9522_regs.divider0_low_cycles = 2; //3 low + _ad9522_regs.divider0_high_cycles = 1; //2 high + + //setup a list of register ranges to write + typedef std::pair range_t; + static const std::vector ranges = boost::assign::list_of + (range_t(0x000, 0x000)) (range_t(0x010, 0x01F)) + (range_t(0x0F0, 0x0FD)) (range_t(0x190, 0x19B)) + (range_t(0x1E0, 0x1E1)) (range_t(0x230, 0x230)) + ; + + //write initial register values and latch/update + BOOST_FOREACH(const range_t &range, ranges){ + for(boost::uint16_t addr = range.first; addr <= range.second; addr++){ + this->send_reg(addr); + } + } + this->latch_regs(); +} + +clock_ctrl_impl::~clock_ctrl_impl(void){ + this->enable_rx_dboard_clock(false); + this->enable_tx_dboard_clock(false); +} + +void clock_ctrl_impl::enable_rx_dboard_clock(bool enb){ + +} + +void clock_ctrl_impl::enable_tx_dboard_clock(bool enb){ + +} + +void clock_ctrl_impl::send_reg(boost::uint16_t addr){ + _iface->transact_spi( + UE_SPI_SS_AD9522, + spi_config_t::EDGE_RISE, + _ad9522_regs.get_write_reg(addr), + 24, false /*no rb*/ + ); +} + +/*********************************************************************** + * Clock Control Make + **********************************************************************/ +clock_ctrl::sptr clock_ctrl::make(usrp_e_iface::sptr iface){ + return sptr(new clock_ctrl_impl(iface)); +} diff --git a/host/lib/usrp/usrp_e/clock_ctrl.hpp b/host/lib/usrp/usrp_e/clock_ctrl.hpp new file mode 100644 index 000000000..d0b896a8f --- /dev/null +++ b/host/lib/usrp/usrp_e/clock_ctrl.hpp @@ -0,0 +1,55 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_USRP_E_CLOCK_CTRL_HPP +#define INCLUDED_USRP_E_CLOCK_CTRL_HPP + +#include "usrp_e_iface.hpp" +#include +#include + +/*! + * The usrp-e clock control: + * - Setup system clocks. + * - Disable/enable clock lines. + */ +class clock_ctrl : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a new clock control object. + * \param iface the usrp_e iface object + * \return the clock control object + */ + static sptr make(usrp_e_iface::sptr iface); + + /*! + * Enable/disable the rx dboard clock. + * \param enb true to enable + */ + virtual void enable_rx_dboard_clock(bool enb) = 0; + + /*! + * Enable/disable the tx dboard clock. + * \param enb true to enable + */ + virtual void enable_tx_dboard_clock(bool enb) = 0; + +}; + +#endif /* INCLUDED_USRP_E_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp index f69cdd2b4..2a3976ba1 100644 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -143,8 +143,8 @@ void usrp_e_dboard_iface::set_atr_reg(unit_t bank, atr_reg_t atr, boost::uint16_ */ static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){ switch(unit){ - case dboard_iface::UNIT_TX: return UE_SPI_CTRL_TXNEG; - case dboard_iface::UNIT_RX: return UE_SPI_CTRL_RXNEG; + case dboard_iface::UNIT_TX: return UE_SPI_SS_TX_DB; + case dboard_iface::UNIT_RX: return UE_SPI_SS_RX_DB; } throw std::invalid_argument("unknown unit type"); } diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp index e7f89db7b..46df8d089 100644 --- a/host/lib/usrp/usrp_e/usrp_e_regs.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -50,6 +50,15 @@ #define UE_REG_SPI_BASE UE_REG_SLAVE(2) +//spi slave constants (copied from usrp2, TODO FIXME) +#define UE_SPI_SS_AD9522 1 +#define UE_SPI_SS_AD9777 2 +#define UE_SPI_SS_RX_DAC 4 +#define UE_SPI_SS_RX_ADC 8 +#define UE_SPI_SS_RX_DB 16 +#define UE_SPI_SS_TX_DAC 32 +#define UE_SPI_SS_TX_ADC 64 +#define UE_SPI_SS_TX_DB 128 //////////////////////////////////////////////// // Slave 3 -- I2C Core -- cgit v1.2.3 From e526627270cf2846d0cba0d30a5947621c545be1 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sun, 2 May 2010 08:52:36 +0000 Subject: Update IP address for my home desktop. Change module version to 2.6.33. --- host/apps/omap_debug/fetch-kernel.sh | 2 +- host/apps/omap_debug/fetch-module.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/fetch-kernel.sh b/host/apps/omap_debug/fetch-kernel.sh index f25f139fa..ce420f3d2 100755 --- a/host/apps/omap_debug/fetch-kernel.sh +++ b/host/apps/omap_debug/fetch-kernel.sh @@ -1,7 +1,7 @@ if [ $GHQ ]; then scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage else - scp balister@192.168.1.167:src/git/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage + scp balister@192.168.1.10:src/git/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage fi sync diff --git a/host/apps/omap_debug/fetch-module.sh b/host/apps/omap_debug/fetch-module.sh index 0957ad7b4..e23289050 100755 --- a/host/apps/omap_debug/fetch-module.sh +++ b/host/apps/omap_debug/fetch-module.sh @@ -1,6 +1,6 @@ if [ $GHQ ]; then - scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.34-rc1/kernel/drivers/misc + scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33/kernel/drivers/misc else - scp balister@192.168.1.167:src/git/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc + scp balister@192.168.1.10:src/git/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc fi sync -- cgit v1.2.3 From 084459a16892c393af08b674ea1df7777e47423a Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sun, 2 May 2010 08:53:32 +0000 Subject: Change overrun indication. New progress indicator. Turn on RT scheduler for user space. --- host/apps/omap_debug/usrp-e-fpga-rw.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-fpga-rw.c b/host/apps/omap_debug/usrp-e-fpga-rw.c index f3fa1499a..6b585913e 100644 --- a/host/apps/omap_debug/usrp-e-fpga-rw.c +++ b/host/apps/omap_debug/usrp-e-fpga-rw.c @@ -69,7 +69,7 @@ static void *read_thread(void *threadid) } if (rx_data->flags & RB_OVERRUN) - printf("RX ring buffer overrun occurred at packet %d\n", rx_pkt_cnt); + printf("O"); // for (i = 0; i < 10; i++) // printf(" %d", p->data[i]); @@ -93,7 +93,7 @@ static void *read_thread(void *threadid) static void *write_thread(void *threadid) { - int seq_number, i, cnt; + int seq_number, i, cnt, tx_pkt_cnt; struct usrp_transfer_frame *tx_data; struct pkt *p; @@ -115,8 +115,25 @@ static void *write_thread(void *threadid) printf("tx_data->len = %d\n", tx_data->len); seq_number = 1; + tx_pkt_cnt = 0; while (1) { + + tx_pkt_cnt++; + if (tx_pkt_cnt == 512) { + printf("."); + fflush(stdout); + } + if (tx_pkt_cnt == 1024) { + printf("'"); + fflush(stdout); + } + if (tx_pkt_cnt == 1536) { + printf(":"); + fflush(stdout); + tx_pkt_cnt = 0; + } + // printf("tx flags = %X, len = %d\n", tx_data->flags, tx_data->len); p->seq_num = seq_number++; p->checksum = calc_checksum(p); @@ -134,6 +151,9 @@ int main(int argc, char *argv[]) long int t; int fpga_config_flag ,decimation; struct usrp_e_ctl16 d; + struct sched_param s = { + .sched_priority = 1 + }; if (argc < 4) { printf("%s t|w|rw decimation data_size\n", argv[0]); @@ -163,6 +183,8 @@ int main(int argc, char *argv[]) sleep(1); // in case the kernel threads need time to start. FIXME if so + sched_setscheduler(0, SCHED_RR, &s); + if (fpga_config_flag & (1 << 14)) { if (pthread_create(&rx, NULL, read_thread, (void *) t)) { printf("Failed to create rx thread\n"); -- cgit v1.2.3 From 2e222f4a77df389551d08b42a1bf947487d1442f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 3 May 2010 11:30:17 +0000 Subject: spi working, talked to ad9522 --- host/include/uhd/utils/assert.hpp | 9 ++++++++- host/lib/usrp/usrp_e/clock_ctrl.cpp | 14 ++++++++++++-- host/lib/usrp/usrp_e/dboard_impl.cpp | 6 +++--- host/lib/usrp/usrp_e/usrp_e_iface.hpp | 9 +++++++++ host/lib/usrp/usrp_e/usrp_e_impl.cpp | 6 ++++++ host/lib/usrp/usrp_e/usrp_e_impl.hpp | 3 +++ host/lib/usrp/usrp_e/usrp_e_regs.hpp | 14 +++++--------- host/test/error_test.cpp | 5 +++-- host/utils/uhd_find_devices.cpp | 2 +- 9 files changed, 50 insertions(+), 18 deletions(-) (limited to 'host') diff --git a/host/include/uhd/utils/assert.hpp b/host/include/uhd/utils/assert.hpp index 6aca64f8c..577050aff 100644 --- a/host/include/uhd/utils/assert.hpp +++ b/host/include/uhd/utils/assert.hpp @@ -29,7 +29,14 @@ #include #ifndef BOOST_THROW_EXCEPTION -#define BOOST_THROW_EXCEPTION(x) throw std::runtime_error("") + #include + #include + #define BOOST_THROW_EXCEPTION(x)\ + ::boost::throw_exception( ::boost::enable_error_info(x) <<\ + ::boost::throw_function(BOOST_CURRENT_FUNCTION) <<\ + ::boost::throw_file(__FILE__) <<\ + ::boost::throw_line((int)__LINE__) ) + #endif namespace uhd{ diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 5f6fb4bfb..fa4028cc5 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using namespace uhd; @@ -97,6 +98,14 @@ clock_ctrl_impl::clock_ctrl_impl(usrp_e_iface::sptr iface){ } } this->latch_regs(); + //test read: + //boost::uint32_t reg = _ad9522_regs.get_read_reg(0x01b); + //boost::uint32_t result = _iface->transact_spi( + // UE_SPI_SS_AD9522, + // spi_config_t::EDGE_RISE, + // reg, 24, true /*no*/ + //); + //std::cout << "result " << std::hex << result << std::endl; } clock_ctrl_impl::~clock_ctrl_impl(void){ @@ -113,11 +122,12 @@ void clock_ctrl_impl::enable_tx_dboard_clock(bool enb){ } void clock_ctrl_impl::send_reg(boost::uint16_t addr){ + boost::uint32_t reg = _ad9522_regs.get_write_reg(addr); + std::cout << "clock control write reg: " << std::hex << reg << std::endl; _iface->transact_spi( UE_SPI_SS_AD9522, spi_config_t::EDGE_RISE, - _ad9522_regs.get_write_reg(addr), - 24, false /*no rb*/ + reg, 24, false /*no rb*/ ); } diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index e87a2c0a5..00b5d77d7 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -24,15 +24,15 @@ using namespace uhd::usrp; * Dboard Initialization **********************************************************************/ void usrp_e_impl::dboard_init(void){ - dboard_id_t rx_dboard_id = dboard_id::NONE; //TODO get these from the eeprom - dboard_id_t tx_dboard_id = dboard_id::NONE; + _rx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes())); + _tx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_TX_DB, 0, dboard_eeprom_t::num_bytes())); //create a new dboard interface and manager dboard_iface::sptr dboard_iface( make_usrp_e_dboard_iface(_iface) ); _dboard_manager = dboard_manager::make( - rx_dboard_id, tx_dboard_id, dboard_iface + _rx_db_eeprom.id, _tx_db_eeprom.id, dboard_iface ); //setup the dboard proxies diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.hpp b/host/lib/usrp/usrp_e/usrp_e_iface.hpp index 763d19581..016d7448f 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.hpp @@ -24,6 +24,15 @@ #include #include +//////////////////////////////////////////////////////////////////////// +// I2C addresses +//////////////////////////////////////////////////////////////////////// +#define I2C_DEV_EEPROM 0x50 // 24LC02[45]: 7-bits 1010xxx +#define I2C_ADDR_MBOARD (I2C_DEV_EEPROM | 0x0) +#define I2C_ADDR_TX_DB (I2C_DEV_EEPROM | 0x4) +#define I2C_ADDR_RX_DB (I2C_DEV_EEPROM | 0x5) +//////////////////////////////////////////////////////////////////////// + /*! * The usrp-e interface class: * Provides a set of functions to implementation layer. diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 211b939ee..52bbcdd32 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -21,7 +21,9 @@ #include #include #include +#include #include //open +#include "clock_ctrl.hpp" using namespace uhd; using namespace uhd::usrp; @@ -73,6 +75,8 @@ device::sptr usrp_e::make(const device_addr_t &device_addr){ * Structors **********************************************************************/ usrp_e_impl::usrp_e_impl(const std::string &node){ + std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; + //open the device node and check file descriptor if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ throw std::runtime_error(str( @@ -82,6 +86,8 @@ usrp_e_impl::usrp_e_impl(const std::string &node){ _iface = usrp_e_iface::make(_node_fd); + clock_ctrl::sptr my_clk_ctrl = clock_ctrl::make(_iface); + //initialize the mboard mboard_init(); diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 08ace2ffb..23e36ed05 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -17,6 +17,7 @@ #include "usrp_e_iface.hpp" #include +#include #include #include @@ -105,11 +106,13 @@ private: uhd::usrp::dboard_manager::sptr _dboard_manager; //rx dboard functions and settings + uhd::usrp::dboard_eeprom_t _rx_db_eeprom; void rx_dboard_get(const wax::obj &, wax::obj &); void rx_dboard_set(const wax::obj &, const wax::obj &); wax_obj_proxy::sptr _rx_dboard_proxy; //tx dboard functions and settings + uhd::usrp::dboard_eeprom_t _tx_db_eeprom; void tx_dboard_get(const wax::obj &, wax::obj &); void tx_dboard_set(const wax::obj &, const wax::obj &); wax_obj_proxy::sptr _tx_dboard_proxy; diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp index 46df8d089..7f35212f4 100644 --- a/host/lib/usrp/usrp_e/usrp_e_regs.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -50,15 +50,11 @@ #define UE_REG_SPI_BASE UE_REG_SLAVE(2) -//spi slave constants (copied from usrp2, TODO FIXME) -#define UE_SPI_SS_AD9522 1 -#define UE_SPI_SS_AD9777 2 -#define UE_SPI_SS_RX_DAC 4 -#define UE_SPI_SS_RX_ADC 8 -#define UE_SPI_SS_RX_DB 16 -#define UE_SPI_SS_TX_DAC 32 -#define UE_SPI_SS_TX_ADC 64 -#define UE_SPI_SS_TX_DB 128 +//spi slave constants +#define UE_SPI_SS_AD9522 (1 << 3) +#define UE_SPI_SS_AD9862 (1 << 2) +#define UE_SPI_SS_TX_DB (1 << 1) +#define UE_SPI_SS_RX_DB (1 << 0) //////////////////////////////////////////////// // Slave 3 -- I2C Core diff --git a/host/test/error_test.cpp b/host/test/error_test.cpp index c5b0af45e..3f2479f99 100644 --- a/host/test/error_test.cpp +++ b/host/test/error_test.cpp @@ -17,7 +17,7 @@ #include #include -#include +//#include #include #include @@ -30,11 +30,12 @@ BOOST_AUTO_TEST_CASE(test_assert_has){ //verify the std::has utility BOOST_CHECK(std::has(vec, 2)); BOOST_CHECK(not std::has(vec, 1)); - +/* std::cout << "The output of the assert_has error:" << std::endl; try{ uhd::assert_has(vec, 1, "prime"); }catch(const boost::exception &e){ std::cout << boost::diagnostic_information(e) << std::endl; } +*/ } diff --git a/host/utils/uhd_find_devices.cpp b/host/utils/uhd_find_devices.cpp index b778eeb68..8281c92bc 100644 --- a/host/utils/uhd_find_devices.cpp +++ b/host/utils/uhd_find_devices.cpp @@ -53,7 +53,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << "-- UHD Device " << i << std::endl; std::cout << "--------------------------------------------------" << std::endl; std::cout << device_addrs[i].to_pp_string() << std::endl << std::endl; - //uhd::device::make(device_addrs[i]); //test make + uhd::device::make(device_addrs[i]); //test make } return 0; -- cgit v1.2.3 From a8f284d03d061a2fb9a6daf6e6bc2493daccd5d4 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 3 May 2010 12:44:41 +0000 Subject: Add a hack to work around a driver race. Remove when teh driver is fixed. --- host/apps/omap_debug/usrp-e-spi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c index caa36b3f1..264231731 100644 --- a/host/apps/omap_debug/usrp-e-spi.c +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -28,6 +28,8 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); + sleep(1); // HACK HACK + spi_dat.slave = slave; spi_dat.data = data; spi_dat.length = length; -- cgit v1.2.3 From 4c4e0f48534a735cc7f5780f4483871264a880ad Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 3 May 2010 12:51:02 +0000 Subject: Add hack to work around driver race. --- host/apps/omap_debug/usrp-e-i2c.c | 3 +++ host/apps/omap_debug/usrp-e-spi.c | 1 + 2 files changed, 4 insertions(+) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-i2c.c b/host/apps/omap_debug/usrp-e-i2c.c index 575430f84..57a3f4739 100644 --- a/host/apps/omap_debug/usrp-e-i2c.c +++ b/host/apps/omap_debug/usrp-e-i2c.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,8 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); + sleep(1); + if (direction) { count = argc - 3; } else { diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c index 264231731..47ee9369c 100644 --- a/host/apps/omap_debug/usrp-e-spi.c +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include -- cgit v1.2.3 From 31d4e1362cd222c688a3bfd3b528a2de51a4b03b Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 3 May 2010 22:36:24 +0000 Subject: Update path to put module in. --- host/apps/omap_debug/fetch-module.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host') diff --git a/host/apps/omap_debug/fetch-module.sh b/host/apps/omap_debug/fetch-module.sh index e23289050..ec28989bd 100755 --- a/host/apps/omap_debug/fetch-module.sh +++ b/host/apps/omap_debug/fetch-module.sh @@ -1,6 +1,6 @@ if [ $GHQ ]; then scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33/kernel/drivers/misc else - scp balister@192.168.1.10:src/git/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33-rc3/kernel/drivers/misc + scp balister@192.168.1.10:src/git/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33/kernel/drivers/misc fi sync -- cgit v1.2.3 From 5583cb575e45441c98480f7beecb48437842fc5c Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 3 May 2010 22:36:56 +0000 Subject: Spi data returned in struct now. --- host/apps/omap_debug/usrp-e-spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c index 47ee9369c..2fcc39b9b 100644 --- a/host/apps/omap_debug/usrp-e-spi.c +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -39,7 +39,7 @@ int main(int argc, char *argv[]) if (*argv[1] == 'r') { spi_dat.readback = 1; ret = ioctl(fp, USRP_E_SPI, &spi_dat); - printf("Data returned = %d\n", ret); + printf("Ioctl returns: %d, Data returned = %d\n", ret, spi_dat.data); } else { spi_dat.readback = 0; ioctl(fp, USRP_E_SPI, &spi_dat); -- cgit v1.2.3 From 8f21adbed40db490bec8ead6b8d50d2b3d1a4136 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 4 May 2010 09:32:38 +0000 Subject: created codec control for ad9862, wip --- host/lib/CMakeLists.txt | 1 + host/lib/ic_reg_maps/gen_ad9862_regs.py | 16 ++--- host/lib/usrp/usrp_e/clock_ctrl.cpp | 39 +++++++++- host/lib/usrp/usrp_e/codec_ctrl.cpp | 122 ++++++++++++++++++++++++++++++++ host/lib/usrp/usrp_e/codec_ctrl.hpp | 73 +++++++++++++++++++ host/lib/usrp/usrp_e/usrp_e_iface.cpp | 7 +- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 8 ++- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 8 +++ 8 files changed, 259 insertions(+), 15 deletions(-) create mode 100644 host/lib/usrp/usrp_e/codec_ctrl.cpp create mode 100644 host/lib/usrp/usrp_e/codec_ctrl.hpp (limited to 'host') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 20373cd59..be57699fc 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -185,6 +185,7 @@ IF(HAVE_USRP_E_REQUIRED_HEADERS) MESSAGE(STATUS " Building usrp-e support.") LIST(APPEND libuhd_sources usrp/usrp_e/clock_ctrl.cpp + usrp/usrp_e/codec_ctrl.cpp usrp/usrp_e/dboard_impl.cpp usrp/usrp_e/dboard_iface.cpp usrp/usrp_e/dsp_impl.cpp diff --git a/host/lib/ic_reg_maps/gen_ad9862_regs.py b/host/lib/ic_reg_maps/gen_ad9862_regs.py index fdbea5828..2094f5e4b 100755 --- a/host/lib/ic_reg_maps/gen_ad9862_regs.py +++ b/host/lib/ic_reg_maps/gen_ad9862_regs.py @@ -30,14 +30,14 @@ soft_reset 0[5] 0 ######################################################################## ## Rx Power Down ######################################################################## -pd_vref_diff 1[7] 0 -pd_vref 1[6] 0 -pd_rx_digital 1[5] 0 -pd_rx_channel_b 1[4] 0 -pd_rx_channel_a 1[3] 0 -pd_buffer_b 1[2] 0 -pd_buffer_a 1[1] 0 -pd_all_rx 1[0] 0 +vref_diff_pd 1[7] 0 +vref_pd 1[6] 0 +rx_digital_pd 1[5] 0 +rx_channel_b_pd 1[4] 0 +rx_channel_a_pd 1[3] 0 +buffer_b_pd 1[2] 0 +buffer_a_pd 1[1] 0 +all_rx_pd 1[0] 0 ######################################################################## ## Rx A and B ######################################################################## diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index fa4028cc5..2fe3c9294 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -37,6 +37,7 @@ public: void enable_rx_dboard_clock(bool enb); void enable_tx_dboard_clock(bool enb); + void enable_codec_clock(bool enb); private: usrp_e_iface::sptr _iface; @@ -79,10 +80,22 @@ clock_ctrl_impl::clock_ctrl_impl(usrp_e_iface::sptr iface){ _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_VCO; + //setup fpga master clock _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS; _ad9522_regs.divider0_low_cycles = 2; //3 low _ad9522_regs.divider0_high_cycles = 1; //2 high + //setup codec clock + _ad9522_regs.out3_format = ad9522_regs_t::OUT3_FORMAT_LVDS; + _ad9522_regs.divider1_low_cycles = 2; //3 low + _ad9522_regs.divider1_high_cycles = 1; //2 high + + //setup test clock (same divider as codec clock) + _ad9522_regs.out4_format = ad9522_regs_t::OUT4_FORMAT_CMOS; + _ad9522_regs.out4_cmos_configuration = (true)? + ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON : + ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF; + //setup a list of register ranges to write typedef std::pair range_t; static const std::vector ranges = boost::assign::list_of @@ -106,6 +119,8 @@ clock_ctrl_impl::clock_ctrl_impl(usrp_e_iface::sptr iface){ // reg, 24, true /*no*/ //); //std::cout << "result " << std::hex << result << std::endl; + this->enable_rx_dboard_clock(false); + this->enable_tx_dboard_clock(false); } clock_ctrl_impl::~clock_ctrl_impl(void){ @@ -114,16 +129,34 @@ clock_ctrl_impl::~clock_ctrl_impl(void){ } void clock_ctrl_impl::enable_rx_dboard_clock(bool enb){ - + _ad9522_regs.out9_format = ad9522_regs_t::OUT9_FORMAT_CMOS; + _ad9522_regs.out9_cmos_configuration = (enb)? + ad9522_regs_t::OUT9_CMOS_CONFIGURATION_B_ON : + ad9522_regs_t::OUT9_CMOS_CONFIGURATION_OFF; + this->send_reg(0x0F9); + + _ad9522_regs.divider3_low_cycles = 2; //3 low + _ad9522_regs.divider3_high_cycles = 1; //2 high + this->send_reg(0x199); + this->latch_regs(); } void clock_ctrl_impl::enable_tx_dboard_clock(bool enb){ - + _ad9522_regs.out6_format = ad9522_regs_t::OUT6_FORMAT_CMOS; + _ad9522_regs.out6_cmos_configuration = (enb)? + ad9522_regs_t::OUT6_CMOS_CONFIGURATION_B_ON : + ad9522_regs_t::OUT6_CMOS_CONFIGURATION_OFF; + this->send_reg(0x0F6); + + _ad9522_regs.divider2_low_cycles = 2; //3 low + _ad9522_regs.divider2_high_cycles = 1; //2 high + this->send_reg(0x196); + this->latch_regs(); } void clock_ctrl_impl::send_reg(boost::uint16_t addr){ boost::uint32_t reg = _ad9522_regs.get_write_reg(addr); - std::cout << "clock control write reg: " << std::hex << reg << std::endl; + //std::cout << "clock control write reg: " << std::hex << reg << std::endl; _iface->transact_spi( UE_SPI_SS_AD9522, spi_config_t::EDGE_RISE, diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp new file mode 100644 index 000000000..daa6ed3e3 --- /dev/null +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -0,0 +1,122 @@ +// +// Copyright 2010 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 . +// + +#include "codec_ctrl.hpp" +#include "ad9862_regs.hpp" +#include +#include "usrp_e_regs.hpp" //spi slave constants +#include +//#include +//#include +#include + + //test out codec ls dac/adc + //ad9862_regs_t ad9862_regs; + //ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC1; + //ad9862_regs.aux_dac_a = 0xff/2; + //_iface->transact_spi( + // UE_SPI_SS_AD9862, + // spi_config_t::EDGE_RISE, + // ad9862_regs.get_write_reg(34), 16, false /*no rb*/ + //); + //_iface->transact_spi( + // UE_SPI_SS_AD9862, + // spi_config_t::EDGE_RISE, + // ad9862_regs.get_write_reg(36), 16, false /*no rb*/ + //); + //boost::uint32_t val = _iface->transact_spi( + // UE_SPI_SS_AD9862, + // spi_config_t::EDGE_RISE, + // ad9862_regs.get_read_reg(29), 16, true + //); + //std::cout << "value: " << std::hex << val << std::endl; + +using namespace uhd; + +/*********************************************************************** + * Codec Control Implementation + **********************************************************************/ +class codec_ctrl_impl : public codec_ctrl{ +public: + //structors + codec_ctrl_impl(usrp_e_iface::sptr iface); + ~codec_ctrl_impl(void); + + //aux adc and dac control + float read_aux_adc(aux_adc_t which); + void read_aux_adc(aux_dac_t which, float volts); + +private: + usrp_e_iface::sptr _iface; + ad9862_regs_t _ad9862_regs; + void send_reg(boost::uint8_t addr); +}; + +/*********************************************************************** + * Codec Control Methods + **********************************************************************/ +codec_ctrl_impl::codec_ctrl_impl(usrp_e_iface::sptr iface){ + _iface = iface; + + //soft reset + _ad9862_regs.soft_reset = 1; + this->send_reg(0); + + //initialize the codec register settings + _ad9862_regs.sdio_bidir = ad9862_regs_t::SDIO_BIDIR_SDIO_SDO; + _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB; + _ad9862_regs.soft_reset = 0; + + //write the register settings to the codec + for (uint8_t addr = 0; addr <= 50; addr++){ + this->send_reg(addr); + } +} + +codec_ctrl_impl::~codec_ctrl_impl(void){ + _ad9862_regs.all_rx_pd = 1; + this->send_reg(1); + _ad9862_regs.tx_digital_pd = 1; + _ad9862_regs.tx_analog_pd = ad9862_regs_t::TX_ANALOG_PD_BOTH; + this->send_reg(8); +} + +float codec_ctrl_impl::read_aux_adc(aux_adc_t which){ + return 0; + +} + +void codec_ctrl_impl::read_aux_adc(aux_dac_t which, float volts){ + +} + +void codec_ctrl_impl::send_reg(boost::uint8_t addr){ + boost::uint32_t reg = _ad9862_regs.get_write_reg(addr); + //std::cout << "codec control write reg: " << std::hex << reg << std::endl; + _iface->transact_spi( + UE_SPI_SS_AD9862, + spi_config_t::EDGE_RISE, + reg, 24, false /*no rb*/ + ); +} + +/*********************************************************************** + * Codec Control Make + **********************************************************************/ +codec_ctrl::sptr codec_ctrl::make(usrp_e_iface::sptr iface){ + return sptr(new codec_ctrl_impl(iface)); +} diff --git a/host/lib/usrp/usrp_e/codec_ctrl.hpp b/host/lib/usrp/usrp_e/codec_ctrl.hpp new file mode 100644 index 000000000..0fe70c4a2 --- /dev/null +++ b/host/lib/usrp/usrp_e/codec_ctrl.hpp @@ -0,0 +1,73 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_USRP_E_CODEC_CTRL_HPP +#define INCLUDED_USRP_E_CODEC_CTRL_HPP + +#include "usrp_e_iface.hpp" +#include +#include + +/*! + * The usrp-e codec control: + * - Init/power down codec. + * - Read aux adc, write aux dac. + */ +class codec_ctrl : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a new clock control object. + * \param iface the usrp_e iface object + * \return the clock control object + */ + static sptr make(usrp_e_iface::sptr iface); + + //! aux adc identifier constants + enum aux_adc_t{ + AUX_ADC_A2 = 0xA2, + AUX_ADC_A1 = 0xA1, + AUX_ADC_B2 = 0xB2, + AUX_ADC_B1 = 0xB1 + }; + + /*! + * Read the aux adc. + * \param which which of the 4 adcs + * \return a value in volts + */ + virtual float read_aux_adc(aux_adc_t which) = 0; + + //! aux dac identifier constants + enum aux_dac_t{ + AUX_DAC_A = 0xA, + AUX_DAC_B = 0xB, + AUX_DAC_C = 0xC, + AUX_DAC_D = 0xD + }; + + /*! + * Write the aux dac. + * \param which which of the 4 dacs + * \param volts the level in in volts + */ + virtual void read_aux_adc(aux_dac_t which, float volts) = 0; + +}; + +#endif /* INCLUDED_USRP_E_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.cpp b/host/lib/usrp/usrp_e/usrp_e_iface.cpp index 41737a716..1dbe383fa 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.cpp @@ -20,6 +20,7 @@ #include //ioctl #include //ioctl structures and constants #include +#include //mutex #include using namespace uhd; @@ -42,6 +43,8 @@ public: * IOCTL: provides the communication base for all other calls ******************************************************************/ void ioctl(int request, void *mem){ + boost::mutex::scoped_lock lock(_ctrl_mutex); + if (::ioctl(_node_fd, request, mem) < 0){ throw std::runtime_error(str( boost::format("ioctl failed with request %d") % request @@ -167,7 +170,9 @@ public: return data.data; } -private: int _node_fd; +private: + int _node_fd; + boost::mutex _ctrl_mutex; }; /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 52bbcdd32..b6fed6a74 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -23,7 +23,6 @@ #include #include #include //open -#include "clock_ctrl.hpp" using namespace uhd; using namespace uhd::usrp; @@ -84,9 +83,12 @@ usrp_e_impl::usrp_e_impl(const std::string &node){ )); } - _iface = usrp_e_iface::make(_node_fd); + sleep(1); //FIXME sleep here until the kernel driver stops hanging - clock_ctrl::sptr my_clk_ctrl = clock_ctrl::make(_iface); + //setup various interfaces into hardware + _iface = usrp_e_iface::make(_node_fd); + _clock_ctrl = clock_ctrl::make(_iface); + _codec_ctrl = codec_ctrl::make(_iface); //initialize the mboard mboard_init(); diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 23e36ed05..6746e012a 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -16,6 +16,8 @@ // #include "usrp_e_iface.hpp" +#include "clock_ctrl.hpp" +#include "codec_ctrl.hpp" #include #include #include @@ -91,6 +93,12 @@ private: uhd::clock_config_t _clock_config; + //ad9522 clock control + clock_ctrl::sptr _clock_ctrl; + + //ad9862 codec control + codec_ctrl::sptr _codec_ctrl; + //device functions and settings void get(const wax::obj &, wax::obj &); void set(const wax::obj &, const wax::obj &); -- cgit v1.2.3 From 6929d0cba40a2bf4f4b3b81819bb915bdbb16488 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 5 May 2010 21:12:43 +0000 Subject: Remove workaround for driver hang. --- host/apps/omap_debug/usrp-e-i2c.c | 2 -- host/apps/omap_debug/usrp-e-spi.c | 2 -- host/apps/omap_debug/usrp_e.h | 4 ++-- 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-i2c.c b/host/apps/omap_debug/usrp-e-i2c.c index 57a3f4739..615dc557b 100644 --- a/host/apps/omap_debug/usrp-e-i2c.c +++ b/host/apps/omap_debug/usrp-e-i2c.c @@ -38,8 +38,6 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); - sleep(1); - if (direction) { count = argc - 3; } else { diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c index 2fcc39b9b..d2c38e524 100644 --- a/host/apps/omap_debug/usrp-e-spi.c +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -29,8 +29,6 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); - sleep(1); // HACK HACK - spi_dat.slave = slave; spi_dat.data = data; spi_dat.length = length; diff --git a/host/apps/omap_debug/usrp_e.h b/host/apps/omap_debug/usrp_e.h index d4132021f..0b582f59b 100644 --- a/host/apps/omap_debug/usrp_e.h +++ b/host/apps/omap_debug/usrp_e.h @@ -66,8 +66,8 @@ struct usrp_e_i2c { #define USRP_E_READ_CTL16 _IOWR(USRP_E_IOC_MAGIC, 0x21, struct usrp_e_ctl16) #define USRP_E_WRITE_CTL32 _IOW(USRP_E_IOC_MAGIC, 0x22, struct usrp_e_ctl32) #define USRP_E_READ_CTL32 _IOWR(USRP_E_IOC_MAGIC, 0x23, struct usrp_e_ctl32) -#define USRP_E_SPI _IOW(USRP_E_IOC_MAGIC, 0x24, struct usrp_e_spi) -#define USRP_E_I2C_READ _IOR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) +#define USRP_E_SPI _IOWR(USRP_E_IOC_MAGIC, 0x24, struct usrp_e_spi) +#define USRP_E_I2C_READ _IOWR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) #define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) // Data transfer frame definition -- cgit v1.2.3 From 77b9aaf5bdb9c50a2456f1aa5e3498ec228ab679 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 4 May 2010 09:46:02 +0000 Subject: fix files before pull --- host/include/uhd/utils/assert.hpp | 32 ++++++++++---------------------- host/include/uhd/utils/props.hpp | 17 +++-------------- host/include/uhd/utils/safe_main.hpp | 5 +---- host/test/error_test.cpp | 17 ++++++++++++----- 4 files changed, 26 insertions(+), 45 deletions(-) (limited to 'host') diff --git a/host/include/uhd/utils/assert.hpp b/host/include/uhd/utils/assert.hpp index 577050aff..2f0ed4ff1 100644 --- a/host/include/uhd/utils/assert.hpp +++ b/host/include/uhd/utils/assert.hpp @@ -19,37 +19,24 @@ #define INCLUDED_UHD_UTILS_ASSERT_HPP #include +#include #include #include #include #include -#include -#include #include #include -#ifndef BOOST_THROW_EXCEPTION - #include - #include - #define BOOST_THROW_EXCEPTION(x)\ - ::boost::throw_exception( ::boost::enable_error_info(x) <<\ - ::boost::throw_function(BOOST_CURRENT_FUNCTION) <<\ - ::boost::throw_file(__FILE__) <<\ - ::boost::throw_line((int)__LINE__) ) - -#endif - namespace uhd{ //! The exception to throw when assertions fail - struct UHD_API assert_error : virtual std::exception, virtual boost::exception{}; - - //! The assertion info, the code that failed - typedef boost::error_info assert_info; + struct UHD_API assert_error : std::runtime_error{ + assert_error(const std::string &what); + }; //! Throw an assert error with throw-site information #define UHD_ASSERT_THROW(_x) if (not (_x)) \ - BOOST_THROW_EXCEPTION(uhd::assert_error() << uhd::assert_info(#_x)) + throw uhd::assert_error(UHD_THROW_SITE_INFO("assertion failed: " + std::string(#_x))) /*! * Check that an element is found in a container. @@ -74,13 +61,14 @@ namespace uhd{ if (i++ > 0) possible_values += ", "; possible_values += boost::lexical_cast(v); } - boost::throw_exception(uhd::assert_error() << assert_info(str(boost::format( - "Error: %s is not a valid %s. " - "Possible values are: [%s]." + throw uhd::assert_error(str(boost::format( + "assertion failed:\n" + " %s is not a valid %s.\n" + " possible values are: [%s].\n" ) % boost::lexical_cast(value) % what % possible_values - ))); + )); } }//namespace uhd diff --git a/host/include/uhd/utils/props.hpp b/host/include/uhd/utils/props.hpp index 6c40c32e0..f376d2612 100644 --- a/host/include/uhd/utils/props.hpp +++ b/host/include/uhd/utils/props.hpp @@ -20,17 +20,12 @@ #include #include +#include #include -#include -#include #include #include #include -#ifndef BOOST_THROW_EXCEPTION -#define BOOST_THROW_EXCEPTION(x) throw std::runtime_error("") -#endif - namespace uhd{ //! The type for a vector of property names @@ -63,25 +58,19 @@ namespace uhd{ const std::string &name = "" ); - //! The exception to throw for property errors - struct UHD_API prop_error : virtual std::exception, virtual boost::exception{}; - - //! The property error info (verbose or message) - typedef boost::error_info prop_info; - /*! * Throw when getting a not-implemented or write-only property. * Throw-site information will be included with this error. */ #define UHD_THROW_PROP_GET_ERROR() \ - BOOST_THROW_EXCEPTION(uhd::prop_error() << uhd::prop_info("cannot get this property")) + throw std::runtime_error(UHD_THROW_SITE_INFO("cannot get this property")) /*! * Throw when setting a not-implemented or read-only property. * Throw-site information will be included with this error. */ #define UHD_THROW_PROP_SET_ERROR() \ - BOOST_THROW_EXCEPTION(uhd::prop_error() << uhd::prop_info("cannot set this property")) + throw std::runtime_error(UHD_THROW_SITE_INFO("cannot set this property")) } //namespace uhd diff --git a/host/include/uhd/utils/safe_main.hpp b/host/include/uhd/utils/safe_main.hpp index 39d2282cd..b682aa540 100644 --- a/host/include/uhd/utils/safe_main.hpp +++ b/host/include/uhd/utils/safe_main.hpp @@ -19,7 +19,6 @@ #define INCLUDED_UHD_UTILS_SAFE_MAIN_HPP #include -//#include #include #include @@ -34,9 +33,7 @@ int main(int argc, char *argv[]){ \ try { \ return _main(argc, argv); \ - } /*catch(const boost::exception &e){ \ - std::cerr << "Error: " << boost::diagnostic_information(e) << std::endl; \ - }*/ catch(const std::exception &e) { \ + } catch(const std::exception &e) { \ std::cerr << "Error: " << e.what() << std::endl; \ } catch(...) { \ std::cerr << "Error: unknown exception" << std::endl; \ diff --git a/host/test/error_test.cpp b/host/test/error_test.cpp index 3f2479f99..c76a15ab7 100644 --- a/host/test/error_test.cpp +++ b/host/test/error_test.cpp @@ -17,7 +17,6 @@ #include #include -//#include #include #include @@ -30,12 +29,20 @@ BOOST_AUTO_TEST_CASE(test_assert_has){ //verify the std::has utility BOOST_CHECK(std::has(vec, 2)); BOOST_CHECK(not std::has(vec, 1)); -/* + std::cout << "The output of the assert_has error:" << std::endl; try{ uhd::assert_has(vec, 1, "prime"); - }catch(const boost::exception &e){ - std::cout << boost::diagnostic_information(e) << std::endl; + }catch(const std::exception &e){ + std::cout << e.what() << std::endl; + } +} + +BOOST_AUTO_TEST_CASE(test_assert_throw){ + std::cout << "The output of the assert throw error:" << std::endl; + try{ + UHD_ASSERT_THROW(2 + 2 == 5); + }catch(const std::exception &e){ + std::cout << e.what() << std::endl; } -*/ } -- cgit v1.2.3 From 06bcfc6b872d8efcb94b312b963f18678a862b93 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 6 May 2010 22:00:21 +0000 Subject: moved usrp_e specific build stuff into its own cmake file --- host/lib/CMakeLists.txt | 37 +-------------------------- host/lib/usrp/usrp_e/CMakeLists.txt | 51 +++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 36 deletions(-) create mode 100644 host/lib/usrp/usrp_e/CMakeLists.txt (limited to 'host') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index f64f1dbac..6cf896db8 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -72,42 +72,7 @@ INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/transport/CMakeLists.txt) INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/CMakeLists.txt) INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/dboard/CMakeLists.txt) INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/usrp2/CMakeLists.txt) - -######################################################################## -# Conditionally add the usrp1e sources -######################################################################## -MESSAGE(STATUS "Configuring usrp-e support...") - -INCLUDE(CheckIncludeFiles) -SET(usrp_e_required_headers - linux/ioctl.h - linux/spi/spidev.h - linux/usrp_e.h -) -CHECK_INCLUDE_FILES( - "${usrp_e_required_headers}" - HAVE_USRP_E_REQUIRED_HEADERS -) - -IF(HAVE_USRP_E_REQUIRED_HEADERS) - MESSAGE(STATUS " Building usrp-e support.") - LIST(APPEND libuhd_sources - usrp/usrp_e/clock_ctrl.cpp - usrp/usrp_e/codec_ctrl.cpp - usrp/usrp_e/dboard_impl.cpp - usrp/usrp_e/dboard_iface.cpp - usrp/usrp_e/dsp_impl.cpp - usrp/usrp_e/fpga-downloader.cc - usrp/usrp_e/mboard_impl.cpp - usrp/usrp_e/usrp_e_impl.cpp - usrp/usrp_e/usrp_e_iface.cpp - ) -ELSE(HAVE_USRP_E_REQUIRED_HEADERS) - MESSAGE(STATUS " Skipping usrp-e support.") - LIST(APPEND libuhd_sources - usrp/usrp_e/usrp_e_none.cpp - ) -ENDIF(HAVE_USRP_E_REQUIRED_HEADERS) +INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/usrp_e/CMakeLists.txt) ######################################################################## # Setup defines for module loading diff --git a/host/lib/usrp/usrp_e/CMakeLists.txt b/host/lib/usrp/usrp_e/CMakeLists.txt new file mode 100644 index 000000000..2eff3147d --- /dev/null +++ b/host/lib/usrp/usrp_e/CMakeLists.txt @@ -0,0 +1,51 @@ +# +# Copyright 2010 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 . +# + +#This file will be included by cmake, use absolute paths! + +MESSAGE(STATUS "Configuring usrp-e support...") + +INCLUDE(CheckIncludeFiles) +SET(usrp_e_required_headers + linux/ioctl.h + linux/spi/spidev.h + linux/usrp_e.h +) +CHECK_INCLUDE_FILES( + "${usrp_e_required_headers}" + HAVE_USRP_E_REQUIRED_HEADERS +) + +IF(HAVE_USRP_E_REQUIRED_HEADERS) + MESSAGE(STATUS " Building usrp-e support.") + LIBUHD_APPEND_SOURCES( + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/clock_ctrl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/codec_ctrl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dboard_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dboard_iface.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dsp_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/fpga-downloader.cc + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/mboard_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_iface.cpp + ) +ELSE(HAVE_USRP_E_REQUIRED_HEADERS) + MESSAGE(STATUS " Skipping usrp-e support.") + LIBUHD_APPEND_SOURCES( + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_none.cpp + ) +ENDIF(HAVE_USRP_E_REQUIRED_HEADERS) -- cgit v1.2.3 From 272b08ce9a66b3ba1b9dc91922afff410145231f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 7 May 2010 01:02:20 +0000 Subject: work on codec control, writing aux dacs, read aux adc --- host/lib/ic_reg_maps/gen_ad9862_regs.py | 2 +- host/lib/usrp/usrp_e/CMakeLists.txt | 28 +++--- host/lib/usrp/usrp_e/clock_ctrl.cpp | 1 - host/lib/usrp/usrp_e/codec_ctrl.cpp | 145 +++++++++++++++++++++++++------- host/lib/usrp/usrp_e/codec_ctrl.hpp | 10 ++- 5 files changed, 141 insertions(+), 45 deletions(-) (limited to 'host') diff --git a/host/lib/ic_reg_maps/gen_ad9862_regs.py b/host/lib/ic_reg_maps/gen_ad9862_regs.py index 2094f5e4b..4444c6240 100755 --- a/host/lib/ic_reg_maps/gen_ad9862_regs.py +++ b/host/lib/ic_reg_maps/gen_ad9862_regs.py @@ -233,7 +233,7 @@ boost::uint16_t get_write_reg(boost::uint8_t addr){ } boost::uint16_t get_read_reg(boost::uint8_t addr){ - return (boost::uint16_t(addr) << 8) | (1 << 7); + return (boost::uint16_t(addr) << 8) | (1 << 15); } """ diff --git a/host/lib/usrp/usrp_e/CMakeLists.txt b/host/lib/usrp/usrp_e/CMakeLists.txt index 2eff3147d..c25b2cba4 100644 --- a/host/lib/usrp/usrp_e/CMakeLists.txt +++ b/host/lib/usrp/usrp_e/CMakeLists.txt @@ -17,18 +17,26 @@ #This file will be included by cmake, use absolute paths! +######################################################################## +# Helpful macro to check for required headers +######################################################################## +INCLUDE(CheckIncludeFileCXX) +SET(HAVE_USRP_E_REQUIRED_HEADERS TRUE) +MACRO(USRP_E_REQUIRE_HEADER header variable) + CHECK_INCLUDE_FILE_CXX(${header} ${variable}) + IF(NOT ${variable}) + SET(HAVE_USRP_E_REQUIRED_HEADERS FALSE) + ENDIF(NOT ${variable}) +ENDMACRO(USRP_E_REQUIRE_HEADER) + +######################################################################## +# Conditionally configure the USRP-E support +######################################################################## MESSAGE(STATUS "Configuring usrp-e support...") -INCLUDE(CheckIncludeFiles) -SET(usrp_e_required_headers - linux/ioctl.h - linux/spi/spidev.h - linux/usrp_e.h -) -CHECK_INCLUDE_FILES( - "${usrp_e_required_headers}" - HAVE_USRP_E_REQUIRED_HEADERS -) +USRP_E_REQUIRE_HEADER(linux/ioctl.h HAVE_LINUX_IOCTL_H) +USRP_E_REQUIRE_HEADER(linux/spi/spidev.h HAVE_LINUX_SPI_SPIDEV_H) +USRP_E_REQUIRE_HEADER(linux/usrp_e.h HAVE_LINUX_USRP_E_H) IF(HAVE_USRP_E_REQUIRED_HEADERS) MESSAGE(STATUS " Building usrp-e support.") diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 2fe3c9294..9c2ddf670 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -37,7 +37,6 @@ public: void enable_rx_dboard_clock(bool enb); void enable_tx_dboard_clock(bool enb); - void enable_codec_clock(bool enb); private: usrp_e_iface::sptr _iface; diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index daa6ed3e3..a430f2c6f 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -17,34 +17,16 @@ #include "codec_ctrl.hpp" #include "ad9862_regs.hpp" +#include +#include +#include #include +#include +#include #include "usrp_e_regs.hpp" //spi slave constants #include -//#include -//#include #include - //test out codec ls dac/adc - //ad9862_regs_t ad9862_regs; - //ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC1; - //ad9862_regs.aux_dac_a = 0xff/2; - //_iface->transact_spi( - // UE_SPI_SS_AD9862, - // spi_config_t::EDGE_RISE, - // ad9862_regs.get_write_reg(34), 16, false /*no rb*/ - //); - //_iface->transact_spi( - // UE_SPI_SS_AD9862, - // spi_config_t::EDGE_RISE, - // ad9862_regs.get_write_reg(36), 16, false /*no rb*/ - //); - //boost::uint32_t val = _iface->transact_spi( - // UE_SPI_SS_AD9862, - // spi_config_t::EDGE_RISE, - // ad9862_regs.get_read_reg(29), 16, true - //); - //std::cout << "value: " << std::hex << val << std::endl; - using namespace uhd; /*********************************************************************** @@ -58,16 +40,18 @@ public: //aux adc and dac control float read_aux_adc(aux_adc_t which); - void read_aux_adc(aux_dac_t which, float volts); + void write_aux_dac(aux_dac_t which, float volts); private: usrp_e_iface::sptr _iface; ad9862_regs_t _ad9862_regs; + aux_adc_t _last_aux_adc_a, _last_aux_adc_b; void send_reg(boost::uint8_t addr); + void recv_reg(boost::uint8_t addr); }; /*********************************************************************** - * Codec Control Methods + * Codec Control Structors **********************************************************************/ codec_ctrl_impl::codec_ctrl_impl(usrp_e_iface::sptr iface){ _iface = iface; @@ -88,6 +72,13 @@ codec_ctrl_impl::codec_ctrl_impl(usrp_e_iface::sptr iface){ } codec_ctrl_impl::~codec_ctrl_impl(void){ + //set aux dacs to zero + this->write_aux_dac(AUX_DAC_A, 0); + this->write_aux_dac(AUX_DAC_B, 0); + this->write_aux_dac(AUX_DAC_C, 0); + this->write_aux_dac(AUX_DAC_D, 0); + + //power down _ad9862_regs.all_rx_pd = 1; this->send_reg(1); _ad9862_regs.tx_digital_pd = 1; @@ -95,23 +86,119 @@ codec_ctrl_impl::~codec_ctrl_impl(void){ this->send_reg(8); } +/*********************************************************************** + * Codec Control AUX ADC Methods + **********************************************************************/ +static float aux_adc_to_volts(boost::uint8_t high, boost::uint8_t low){ + return float((boost::uint16_t(high) << 2) | low)*3.3/0x3ff; +} + float codec_ctrl_impl::read_aux_adc(aux_adc_t which){ - return 0; + //check to see if the switch needs to be set + bool write_switch = false; + switch(which){ + + case AUX_ADC_A1: + case AUX_ADC_A2: + if (which != _last_aux_adc_a){ + _ad9862_regs.select_a = (which == AUX_ADC_A1)? + ad9862_regs_t::SELECT_A_AUX_ADC1: ad9862_regs_t::SELECT_A_AUX_ADC2; + _last_aux_adc_a = which; + write_switch = true; + } + break; + + case AUX_ADC_B1: + case AUX_ADC_B2: + if (which != _last_aux_adc_b){ + _ad9862_regs.select_b = (which == AUX_ADC_B1)? + ad9862_regs_t::SELECT_B_AUX_ADC1: ad9862_regs_t::SELECT_B_AUX_ADC2; + _last_aux_adc_b = which; + write_switch = true; + } + break; + + } + //write the switch if it changed + if(write_switch) this->send_reg(34); + + //map aux adcs to register values to read + static const uhd::dict aux_dac_to_addr = boost::assign::map_list_of + (AUX_ADC_A2, 26) (AUX_ADC_A1, 28) + (AUX_ADC_B2, 30) (AUX_ADC_B1, 32) + ; + + //read the value + this->recv_reg(aux_dac_to_addr[which]+0); + this->recv_reg(aux_dac_to_addr[which]+1); + + //return the value scaled to volts + switch(which){ + case AUX_ADC_A1: return aux_adc_to_volts(_ad9862_regs.aux_adc_a1_9_2, _ad9862_regs.aux_adc_a1_1_0); + case AUX_ADC_A2: return aux_adc_to_volts(_ad9862_regs.aux_adc_a2_9_2, _ad9862_regs.aux_adc_a2_1_0); + case AUX_ADC_B1: return aux_adc_to_volts(_ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0); + case AUX_ADC_B2: return aux_adc_to_volts(_ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0); + } + UHD_ASSERT_THROW(false); } -void codec_ctrl_impl::read_aux_adc(aux_dac_t which, float volts){ - +/*********************************************************************** + * Codec Control AUX DAC Methods + **********************************************************************/ +void codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ + //special case for aux dac d (aka sigma delta word) + if (which == AUX_DAC_D){ + boost::uint16_t dac_word = std::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); + _ad9862_regs.sig_delt_11_4 = boost::uint8_t(dac_word >> 4); + _ad9862_regs.sig_delt_3_0 = boost::uint8_t(dac_word & 0xf); + this->send_reg(42); + this->send_reg(43); + return; + } + + //calculate the dac word for aux dac a, b, c + boost::uint8_t dac_word = std::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff); + + //setup a lookup table for the aux dac params (reg ref, reg addr) + typedef boost::tuple dac_params_t; + uhd::dict aux_dac_to_params = boost::assign::map_list_of + (AUX_DAC_A, dac_params_t(&_ad9862_regs.aux_dac_a, 36)) + (AUX_DAC_B, dac_params_t(&_ad9862_regs.aux_dac_b, 37)) + (AUX_DAC_C, dac_params_t(&_ad9862_regs.aux_dac_c, 38)) + ; + + //set the aux dac register + UHD_ASSERT_THROW(aux_dac_to_params.has_key(which)); + boost::uint8_t *reg_ref, reg_addr; + boost::tie(reg_ref, reg_addr) = aux_dac_to_params[which]; + *reg_ref = dac_word; + this->send_reg(reg_addr); } +/*********************************************************************** + * Codec Control SPI Methods + **********************************************************************/ void codec_ctrl_impl::send_reg(boost::uint8_t addr){ boost::uint32_t reg = _ad9862_regs.get_write_reg(addr); //std::cout << "codec control write reg: " << std::hex << reg << std::endl; _iface->transact_spi( UE_SPI_SS_AD9862, spi_config_t::EDGE_RISE, - reg, 24, false /*no rb*/ + reg, 16, false /*no rb*/ + ); +} + +void codec_ctrl_impl::recv_reg(boost::uint8_t addr){ + boost::uint32_t reg = _ad9862_regs.get_read_reg(addr); + //std::cout << "codec control read reg: " << std::hex << reg << std::endl; + boost::uint32_t ret = _iface->transact_spi( + UE_SPI_SS_AD9862, + spi_config_t::EDGE_RISE, + reg, 16, true /*rb*/ ); + //std::cout << "codec control read ret: " << std::hex << ret << std::endl; + _ad9862_regs.set_reg(addr, boost::uint16_t(ret)); } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/codec_ctrl.hpp b/host/lib/usrp/usrp_e/codec_ctrl.hpp index 0fe70c4a2..efdcd7142 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.hpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.hpp @@ -47,7 +47,9 @@ public: }; /*! - * Read the aux adc. + * Read an auxiliary adc: + * The internals remember which aux adc was read last. + * Therefore, the aux adc switch is only changed as needed. * \param which which of the 4 adcs * \return a value in volts */ @@ -58,15 +60,15 @@ public: AUX_DAC_A = 0xA, AUX_DAC_B = 0xB, AUX_DAC_C = 0xC, - AUX_DAC_D = 0xD + AUX_DAC_D = 0xD //really the sigma delta output }; /*! - * Write the aux dac. + * Write an auxiliary dac. * \param which which of the 4 dacs * \param volts the level in in volts */ - virtual void read_aux_adc(aux_dac_t which, float volts) = 0; + virtual void write_aux_dac(aux_dac_t which, float volts) = 0; }; -- cgit v1.2.3 From b47920906bd1b0480bbcd8427b2d703889cb78e3 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 7 May 2010 19:23:58 +0000 Subject: Print an error and exit if open fails for some programs. --- host/apps/omap_debug/usrp-e-debug-pins.c | 4 ++++ host/apps/omap_debug/usrp-e-i2c.c | 6 ++++++ host/apps/omap_debug/usrp-e-spi.c | 7 +++++++ 3 files changed, 17 insertions(+) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-debug-pins.c b/host/apps/omap_debug/usrp-e-debug-pins.c index d4e3f5223..d18bbf990 100644 --- a/host/apps/omap_debug/usrp-e-debug-pins.c +++ b/host/apps/omap_debug/usrp-e-debug-pins.c @@ -46,6 +46,10 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); + if (fp < 0) { + perror("Open failed"); + return -1; + } if (strcmp(argv[1], "0") == 0) { printf("Selected 0 based on %s\n", argv[1]); diff --git a/host/apps/omap_debug/usrp-e-i2c.c b/host/apps/omap_debug/usrp-e-i2c.c index 615dc557b..da8709ae1 100644 --- a/host/apps/omap_debug/usrp-e-i2c.c +++ b/host/apps/omap_debug/usrp-e-i2c.c @@ -37,6 +37,12 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); + if (fp < 0) { + perror("Open failed"); + return -1; + } + +// sleep(1); if (direction) { count = argc - 3; diff --git a/host/apps/omap_debug/usrp-e-spi.c b/host/apps/omap_debug/usrp-e-spi.c index d2c38e524..c353c409b 100644 --- a/host/apps/omap_debug/usrp-e-spi.c +++ b/host/apps/omap_debug/usrp-e-spi.c @@ -28,6 +28,13 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); + if (fp < 0) { + perror("Open failed"); + return -1; + } + +// sleep(1); + spi_dat.slave = slave; spi_dat.data = data; -- cgit v1.2.3 From 8df3a38c3be477a02c4b9d636a3ddd647e55e4a5 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 7 May 2010 15:45:31 -0400 Subject: First pass at data transfer program that uses CRC. --- host/apps/omap_debug/Makefile | 6 +- host/apps/omap_debug/usrp-e-crc-rw.c | 195 +++++++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 host/apps/omap_debug/usrp-e-crc-rw.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 14be592ff..9b590b9f7 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-fpga-rw usrp-e-lb-test +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-fpga-rw usrp-e-lb-test usrp-e-crc-rw usrp-e-spi : usrp-e-spi.c @@ -15,6 +15,9 @@ usrp-e-fpga-rw : usrp-e-fpga-rw.c usrp-e-rw-random : usrp-e-rw-random.c gcc -o $@ $< -lpthread +usrp-e-crc-rw : usrp-e-crc-rw.c + gcc -o $@ $< -lpthread + usrp-e-uart : usrp-e-uart.c usrp-e-uart-rx : usrp-e-uart-rx.c @@ -47,3 +50,4 @@ clean : rm -f usrp-e-gpio rm -f usrp-e-debug-pins rm -f usrp-e-lb-test + rm -f usrp-e-crc-rw diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c new file mode 100644 index 000000000..1f23c8d54 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -0,0 +1,195 @@ +#include +#include +#include +#include +#include +#include +#include +#include "usrp_e.h" + +// max length #define PKT_DATA_LENGTH 1016 +static int packet_data_length; + +static int fp; +static u_int32_t crc_tab[256]; + +// CRC code from http://www.koders.com/c/fid699AFE0A656F0022C9D6B9D1743E697B69CE5815.aspx +// GPLv2 + +static u_int32_t chksum_crc32_gentab(void) +{ + unsigned long crc, poly; + unsigned long i, j; + + poly = 0xEDB88320L; + + for (i = 0; i < 256; i++) { + crc = i; + for (j = 8; j > 0; j--) { + if (crc & 1) { + crc = (crc >> 1) ^ poly; + } else { + crc >>= 1; + } + } + crc_tab[i] = crc; + } +} + +static void *read_thread(void *threadid) +{ + int cnt; + struct usrp_transfer_frame *rx_data; + int rx_pkt_cnt; + int i; + unsigned long crc; + unsigned int rx_crc; + + printf("Greetings from the reading thread!\n"); + + // IMPORTANT: must assume max length packet from fpga + rx_data = malloc(2048); + + rx_pkt_cnt = 0; + + while (1) { + + cnt = read(fp, rx_data, 2048); + if (cnt < 0) + printf("Error returned from read: %d\n", cnt); + + rx_pkt_cnt++; + + if (rx_pkt_cnt == 512) { + printf("."); + fflush(stdout); + rx_pkt_cnt = 0; + } + + if (rx_data->flags & RB_OVERRUN) + printf("O"); + + crc = 0xFFFFFFFF; + for (i = 0; i < rx_data->len - 4; i++) { + crc = ((crc >> 8) & 0x00FFFFFF) ^ + crc_tab[(crc ^ rx_data->buf[i]) & 0xFF]; + } + + rx_crc = *((int *) &rx_data[rx_data->len - 4]); + + if (rx_crc != (crc & 0xFFFFFFFF)) { + printf("CRC Error, sent: %d, rx: %d\n", + rx_crc, (crc & 0xFFFFFFFF)); + } + + } +} + +static void *write_thread(void *threadid) +{ + int seq_number, i, cnt, tx_pkt_cnt; + int tx_len; + unsigned long crc; + struct usrp_transfer_frame *tx_data; + struct pkt *p; + + printf("Greetings from the write thread!\n"); + + tx_data = malloc(2048); + + while (1) { + + tx_pkt_cnt++; + if (tx_pkt_cnt == 512) { + printf("."); + fflush(stdout); + } + if (tx_pkt_cnt == 1024) { + printf("'"); + fflush(stdout); + } + if (tx_pkt_cnt == 1536) { + printf(":"); + fflush(stdout); + tx_pkt_cnt = 0; + } + + tx_len = 2048 - sizeof(struct usrp_transfer_frame) - sizeof(int); + crc = 0xFFFFFFFF; + for (i = 0; i < tx_len; i++) { + tx_data->buf[i] = rand() & 0xFF; + + crc = ((crc >> 8) & 0x00FFFFFF) ^ + crc_tab[(crc ^ tx_data->buf[i]) & 0xFF]; + + } + *((int *) &tx_data[tx_len]) = crc; + + cnt = write(fp, tx_data, 2048); + if (cnt < 0) + printf("Error returned from write: %d\n", cnt); +// sleep(1); + } +} + + +int main(int argc, char *argv[]) +{ + pthread_t tx, rx; + long int t; + int fpga_config_flag ,decimation; + struct usrp_e_ctl16 d; + struct sched_param s = { + .sched_priority = 1 + }; + + if (argc < 4) { + printf("%s t|w|rw decimation data_size\n", argv[0]); + return -1; + } + + decimation = atoi(argv[2]); + packet_data_length = atoi(argv[3]); + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + fpga_config_flag = 0; + if (strcmp(argv[1], "w") == 0) + fpga_config_flag |= (1 << 15); + else if (strcmp(argv[1], "r") == 0) + fpga_config_flag |= (1 << 14); + else if (strcmp(argv[1], "rw") == 0) + fpga_config_flag |= ((1 << 15) | (1 << 14)); + + fpga_config_flag |= decimation; + + d.offset = 14; + d.count = 1; + d.buf[0] = fpga_config_flag; + ioctl(fp, USRP_E_WRITE_CTL16, &d); + + sleep(1); // in case the kernel threads need time to start. FIXME if so + + sched_setscheduler(0, SCHED_RR, &s); + + if (fpga_config_flag & (1 << 14)) { + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { + printf("Failed to create rx thread\n"); + exit(-1); + } + } + + sleep(1); + + if (fpga_config_flag & (1 << 15)) { + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { + printf("Failed to create tx thread\n"); + exit(-1); + } + } + + sleep(10000); + + printf("Done sleeping\n"); +} -- cgit v1.2.3 From 6c306995a733622a0b0c3fb8c13c23dc8301d926 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 7 May 2010 16:14:28 -0400 Subject: Update usrp_e.h file from kernel header. --- host/apps/omap_debug/usrp_e.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp_e.h b/host/apps/omap_debug/usrp_e.h index 0b582f59b..fd74e6e9e 100644 --- a/host/apps/omap_debug/usrp_e.h +++ b/host/apps/omap_debug/usrp_e.h @@ -34,13 +34,8 @@ struct usrp_e_ctl32 { #define UE_SPI_TXRX 1 // Defines for spi ctrl register -#define UE_SPI_CTRL_ASS (1<<13) -#define UE_SPI_CTRL_IE (1<<12) -#define UE_SPI_CTRL_LSB (1<<11) #define UE_SPI_CTRL_TXNEG (1<<10) #define UE_SPI_CTRL_RXNEG (1<<9) -#define UE_SPI_CTRL_GO_BSY (1<<8) -#define UE_SPI_CTRL_CHAR_LEN_MASK 0x7f #define UE_SPI_PUSH_RISE 0 #define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG -- cgit v1.2.3 From 6ef09d18def4afdd6413188ab63ee38dbae4e9d8 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 7 May 2010 21:51:06 +0000 Subject: filled in dboard interface with codec and clock control --- host/lib/usrp/usrp_e/clock_ctrl.cpp | 4 ++ host/lib/usrp/usrp_e/clock_ctrl.hpp | 18 +++++++ host/lib/usrp/usrp_e/dboard_iface.cpp | 88 ++++++++++++++++++++++++----------- host/lib/usrp/usrp_e/dboard_impl.cpp | 6 ++- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 2 - host/lib/usrp/usrp_e/usrp_e_impl.hpp | 8 +++- 6 files changed, 95 insertions(+), 31 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 9c2ddf670..5f7269412 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -38,6 +38,10 @@ public: void enable_rx_dboard_clock(bool enb); void enable_tx_dboard_clock(bool enb); + double get_fpga_clock_rate(void){return 64e6;} + double get_rx_dboard_clock_rate(void){return get_fpga_clock_rate();} + double get_tx_dboard_clock_rate(void){return get_fpga_clock_rate();} + private: usrp_e_iface::sptr _iface; ad9522_regs_t _ad9522_regs; diff --git a/host/lib/usrp/usrp_e/clock_ctrl.hpp b/host/lib/usrp/usrp_e/clock_ctrl.hpp index d0b896a8f..994b83564 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.hpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.hpp @@ -38,6 +38,24 @@ public: */ static sptr make(usrp_e_iface::sptr iface); + /*! + * Get the rate of the fpga clock line. + * \return the fpga clock rate in Hz + */ + virtual double get_fpga_clock_rate(void) = 0; + + /*! + * Get the rate of the dboard clock clock line. + * \return the dboard clock rate in Hz + */ + virtual double get_rx_dboard_clock_rate(void) = 0; + + /*! + * Get the rate of the dboard clock clock line. + * \return the dboard clock rate in Hz + */ + virtual double get_tx_dboard_clock_rate(void) = 0; + /*! * Enable/disable the rx dboard clock. * \param enb true to enable diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp index 2a3976ba1..e70934b8c 100644 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -17,6 +17,8 @@ #include "usrp_e_iface.hpp" #include "usrp_e_regs.hpp" +#include "clock_ctrl.hpp" +#include "codec_ctrl.hpp" #include #include #include @@ -25,11 +27,24 @@ using namespace uhd; using namespace uhd::usrp; +using namespace boost::assign; class usrp_e_dboard_iface : public dboard_iface{ public: - usrp_e_dboard_iface(usrp_e_iface::sptr iface); - ~usrp_e_dboard_iface(void); + + usrp_e_dboard_iface( + usrp_e_iface::sptr iface, + clock_ctrl::sptr clock, + codec_ctrl::sptr codec + ){ + _iface = iface; + _clock = clock; + _codec = codec; + } + + ~usrp_e_dboard_iface(void){ + /* NOP */ + } void write_aux_dac(unit_t, int, float); float read_aux_adc(unit_t, int); @@ -60,35 +75,37 @@ public: private: usrp_e_iface::sptr _iface; + clock_ctrl::sptr _clock; + codec_ctrl::sptr _codec; }; /*********************************************************************** * Make Function **********************************************************************/ -dboard_iface::sptr make_usrp_e_dboard_iface(usrp_e_iface::sptr iface){ - return dboard_iface::sptr(new usrp_e_dboard_iface(iface)); -} - -/*********************************************************************** - * Structors - **********************************************************************/ -usrp_e_dboard_iface::usrp_e_dboard_iface(usrp_e_iface::sptr iface){ - _iface = iface; -} - -usrp_e_dboard_iface::~usrp_e_dboard_iface(void){ - /* NOP */ +dboard_iface::sptr make_usrp_e_dboard_iface( + usrp_e_iface::sptr iface, + clock_ctrl::sptr clock, + codec_ctrl::sptr codec +){ + return dboard_iface::sptr(new usrp_e_dboard_iface(iface, clock, codec)); } /*********************************************************************** * Clock Rates **********************************************************************/ -double usrp_e_dboard_iface::get_clock_rate(unit_t){ - throw std::runtime_error("not implemented"); +double usrp_e_dboard_iface::get_clock_rate(unit_t unit){ + switch(unit){ + case UNIT_RX: return _clock->get_rx_dboard_clock_rate(); + case UNIT_TX: return _clock->get_tx_dboard_clock_rate(); + } + UHD_ASSERT_THROW(false); } -void usrp_e_dboard_iface::set_clock_enabled(unit_t, bool){ - throw std::runtime_error("not implemented"); +void usrp_e_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ + switch(unit){ + case UNIT_RX: return _clock->enable_rx_dboard_clock(enb); + case UNIT_TX: return _clock->enable_tx_dboard_clock(enb); + } } /*********************************************************************** @@ -96,7 +113,7 @@ void usrp_e_dboard_iface::set_clock_enabled(unit_t, bool){ **********************************************************************/ void usrp_e_dboard_iface::set_gpio_ddr(unit_t bank, boost::uint16_t value){ //define mapping of gpio bank to register address - static const uhd::dict bank_to_addr = boost::assign::map_list_of + static const uhd::dict bank_to_addr = map_list_of (UNIT_RX, UE_REG_GPIO_RX_DDR) (UNIT_TX, UE_REG_GPIO_TX_DDR) ; @@ -105,7 +122,7 @@ void usrp_e_dboard_iface::set_gpio_ddr(unit_t bank, boost::uint16_t value){ boost::uint16_t usrp_e_dboard_iface::read_gpio(unit_t bank){ //define mapping of gpio bank to register address - static const uhd::dict bank_to_addr = boost::assign::map_list_of + static const uhd::dict bank_to_addr = map_list_of (UNIT_RX, UE_REG_GPIO_RX_IO) (UNIT_TX, UE_REG_GPIO_TX_IO) ; @@ -116,14 +133,14 @@ void usrp_e_dboard_iface::set_atr_reg(unit_t bank, atr_reg_t atr, boost::uint16_ //define mapping of bank to atr regs to register address static const uhd::dict< unit_t, uhd::dict - > bank_to_atr_to_addr = boost::assign::map_list_of - (UNIT_RX, boost::assign::map_list_of + > bank_to_atr_to_addr = map_list_of + (UNIT_RX, map_list_of (ATR_REG_IDLE, UE_REG_ATR_IDLE_RXSIDE) (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_RXSIDE) (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_RXSIDE) (ATR_REG_FULL_DUPLEX, UE_REG_ATR_FULL_RXSIDE) ) - (UNIT_TX, boost::assign::map_list_of + (UNIT_TX, map_list_of (ATR_REG_IDLE, UE_REG_ATR_IDLE_TXSIDE) (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_TXSIDE) (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_TXSIDE) @@ -181,10 +198,27 @@ byte_vector_t usrp_e_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_byte /*********************************************************************** * Aux DAX/ADC **********************************************************************/ -void usrp_e_dboard_iface::write_aux_dac(dboard_iface::unit_t unit, int which, float value){ - throw std::runtime_error("not implemented"); +void usrp_e_dboard_iface::write_aux_dac(dboard_iface::unit_t, int which, float value){ + //same aux dacs for each unit + static const uhd::dict which_to_aux_dac = map_list_of + (0, codec_ctrl::AUX_DAC_A) (1, codec_ctrl::AUX_DAC_B) + (2, codec_ctrl::AUX_DAC_C) (3, codec_ctrl::AUX_DAC_D) + ; + _codec->write_aux_dac(which_to_aux_dac[which], value); } float usrp_e_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, int which){ - throw std::runtime_error("not implemented"); + static const uhd::dict< + unit_t, uhd::dict + > unit_to_which_to_aux_adc = map_list_of + (UNIT_RX, map_list_of + (0, codec_ctrl::AUX_ADC_A1) + (1, codec_ctrl::AUX_ADC_B1) + ) + (UNIT_TX, map_list_of + (0, codec_ctrl::AUX_ADC_A2) + (1, codec_ctrl::AUX_ADC_B2) + ) + ; + return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]); } diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index 00b5d77d7..31f792306 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -17,6 +17,7 @@ #include #include "usrp_e_impl.hpp" +#include using namespace uhd::usrp; @@ -27,9 +28,12 @@ void usrp_e_impl::dboard_init(void){ _rx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes())); _tx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_TX_DB, 0, dboard_eeprom_t::num_bytes())); + std::cout << _rx_db_eeprom.id.to_pp_string() << std::endl; + std::cout << _tx_db_eeprom.id.to_pp_string() << std::endl; + //create a new dboard interface and manager dboard_iface::sptr dboard_iface( - make_usrp_e_dboard_iface(_iface) + make_usrp_e_dboard_iface(_iface, _clock_ctrl, _codec_ctrl) ); _dboard_manager = dboard_manager::make( _rx_db_eeprom.id, _tx_db_eeprom.id, dboard_iface diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index b6fed6a74..5861be102 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -83,8 +83,6 @@ usrp_e_impl::usrp_e_impl(const std::string &node){ )); } - sleep(1); //FIXME sleep here until the kernel driver stops hanging - //setup various interfaces into hardware _iface = usrp_e_iface::make(_node_fd); _clock_ctrl = clock_ctrl::make(_iface); diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 6746e012a..bde0f87c3 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -29,9 +29,15 @@ /*! * Make a usrp-e dboard interface. * \param iface the usrp-e interface object + * \param clock the clock control interface + * \param codec the codec control interface * \return a sptr to a new dboard interface */ -uhd::usrp::dboard_iface::sptr make_usrp_e_dboard_iface(usrp_e_iface::sptr iface); +uhd::usrp::dboard_iface::sptr make_usrp_e_dboard_iface( + usrp_e_iface::sptr iface, + clock_ctrl::sptr clock, + codec_ctrl::sptr codec +); /*! * Simple wax obj proxy class: -- cgit v1.2.3 From 29809e9697b052fa1d0cd2109c8bd5f9af178cfa Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 8 May 2010 01:58:10 +0000 Subject: moved open/close into iface, work on codec tx --- host/lib/usrp/usrp_e/codec_ctrl.cpp | 35 ++++++++++++++++++++++++++++++++--- host/lib/usrp/usrp_e/usrp_e_iface.cpp | 17 ++++++++++++----- host/lib/usrp/usrp_e/usrp_e_iface.hpp | 4 ++-- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 13 ++----------- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 1 - 5 files changed, 48 insertions(+), 22 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index a430f2c6f..3f3523ddf 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -29,6 +29,8 @@ using namespace uhd; +static const bool codec_debug = true; + /*********************************************************************** * Codec Control Implementation **********************************************************************/ @@ -56,6 +58,9 @@ private: codec_ctrl_impl::codec_ctrl_impl(usrp_e_iface::sptr iface){ _iface = iface; + //FIXME temp poke !!! + _iface->poke16(UE_REG_MISC_TEST, 0x0f00); + //soft reset _ad9862_regs.soft_reset = 1; this->send_reg(0); @@ -65,6 +70,28 @@ codec_ctrl_impl::codec_ctrl_impl(usrp_e_iface::sptr iface){ _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB; _ad9862_regs.soft_reset = 0; + //setup rx side of codec + _ad9862_regs.byp_buffer_a = 1; + _ad9862_regs.byp_buffer_b = 1; + _ad9862_regs.buffer_a_pd = 1; + _ad9862_regs.buffer_b_pd = 1; + _ad9862_regs.rx_pga_a = 0x1f; //TODO bring under api control + _ad9862_regs.rx_pga_b = 0x1f; //TODO bring under api control + _ad9862_regs.rx_twos_comp = 1; + _ad9862_regs.rx_hilbert = ad9862_regs_t::RX_HILBERT_DIS; + + //setup tx side of codec + _ad9862_regs.two_data_paths = ad9862_regs_t::TWO_DATA_PATHS_BOTH; + _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_SINGLE; //FIXME should be interleaved + _ad9862_regs.tx_pga_gain = 199; //TODO bring under api control + _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; + _ad9862_regs.interp = ad9862_regs_t::INTERP_4; + _ad9862_regs.tx_twos_comp = 1; + _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_BYPASS; + _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; + _ad9862_regs.dac_a_coarse_gain = 0x3; + _ad9862_regs.dac_b_coarse_gain = 0x3; + //write the register settings to the codec for (uint8_t addr = 0; addr <= 50; addr++){ this->send_reg(addr); @@ -72,6 +99,8 @@ codec_ctrl_impl::codec_ctrl_impl(usrp_e_iface::sptr iface){ } codec_ctrl_impl::~codec_ctrl_impl(void){ + return; //FIXME remove this later + //set aux dacs to zero this->write_aux_dac(AUX_DAC_A, 0); this->write_aux_dac(AUX_DAC_B, 0); @@ -181,7 +210,7 @@ void codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ **********************************************************************/ void codec_ctrl_impl::send_reg(boost::uint8_t addr){ boost::uint32_t reg = _ad9862_regs.get_write_reg(addr); - //std::cout << "codec control write reg: " << std::hex << reg << std::endl; + if (codec_debug) std::cout << "codec control write reg: " << std::hex << reg << std::endl; _iface->transact_spi( UE_SPI_SS_AD9862, spi_config_t::EDGE_RISE, @@ -191,13 +220,13 @@ void codec_ctrl_impl::send_reg(boost::uint8_t addr){ void codec_ctrl_impl::recv_reg(boost::uint8_t addr){ boost::uint32_t reg = _ad9862_regs.get_read_reg(addr); - //std::cout << "codec control read reg: " << std::hex << reg << std::endl; + if (codec_debug) std::cout << "codec control read reg: " << std::hex << reg << std::endl; boost::uint32_t ret = _iface->transact_spi( UE_SPI_SS_AD9862, spi_config_t::EDGE_RISE, reg, 16, true /*rb*/ ); - //std::cout << "codec control read ret: " << std::hex << ret << std::endl; + if (codec_debug) std::cout << "codec control read ret: " << std::hex << ret << std::endl; _ad9862_regs.set_reg(addr, boost::uint16_t(ret)); } diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.cpp b/host/lib/usrp/usrp_e/usrp_e_iface.cpp index 1dbe383fa..98d8ef478 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.cpp @@ -18,6 +18,7 @@ #include "usrp_e_iface.hpp" #include #include //ioctl +#include //open, close #include //ioctl structures and constants #include #include //mutex @@ -31,12 +32,18 @@ public: /******************************************************************* * Structors ******************************************************************/ - usrp_e_iface_impl(int node_fd){ - _node_fd = node_fd; + usrp_e_iface_impl(const std::string &node){ + //open the device node and check file descriptor + if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ + throw std::runtime_error(str( + boost::format("Failed to open %s") % node + )); + } } ~usrp_e_iface_impl(void){ - /* NOP */ + //close the device node file descriptor + ::close(_node_fd); } /******************************************************************* @@ -178,6 +185,6 @@ private: /*********************************************************************** * Public Make Function **********************************************************************/ -usrp_e_iface::sptr usrp_e_iface::make(int node_fd){ - return sptr(new usrp_e_iface_impl(node_fd)); +usrp_e_iface::sptr usrp_e_iface::make(const std::string &node){ + return sptr(new usrp_e_iface_impl(node)); } diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.hpp b/host/lib/usrp/usrp_e/usrp_e_iface.hpp index 016d7448f..6363a24b2 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.hpp @@ -44,10 +44,10 @@ public: /*! * Make a new usrp-e interface with the control transport. - * \param node_fd the file descriptor for the kernel module node + * \param node the device node name * \return a new usrp-e interface object */ - static sptr make(int node_fd); + static sptr make(const std::string &node); /*! * Perform an ioctl call on the device node file descriptor. diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 5861be102..4f7361eca 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -22,7 +22,6 @@ #include #include #include -#include //open using namespace uhd; using namespace uhd::usrp; @@ -76,15 +75,8 @@ device::sptr usrp_e::make(const device_addr_t &device_addr){ usrp_e_impl::usrp_e_impl(const std::string &node){ std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; - //open the device node and check file descriptor - if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ - throw std::runtime_error(str( - boost::format("Failed to open %s") % node - )); - } - //setup various interfaces into hardware - _iface = usrp_e_iface::make(_node_fd); + _iface = usrp_e_iface::make(node); _clock_ctrl = clock_ctrl::make(_iface); _codec_ctrl = codec_ctrl::make(_iface); @@ -100,8 +92,7 @@ usrp_e_impl::usrp_e_impl(const std::string &node){ } usrp_e_impl::~usrp_e_impl(void){ - //close the device node file descriptor - ::close(_node_fd); + /* NOP */ } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index bde0f87c3..59f80c70c 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -95,7 +95,6 @@ public: private: static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); usrp_e_iface::sptr _iface; - int _node_fd; uhd::clock_config_t _clock_config; -- cgit v1.2.3 From 3a26c45c69ea61bb1e2cc4dbfb7a605abbd7ca4b Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 10 May 2010 19:00:56 +0000 Subject: ad9862 transmit working --- host/lib/ic_reg_maps/gen_ad9862_regs.py | 2 +- host/lib/usrp/usrp_e/codec_ctrl.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/lib/ic_reg_maps/gen_ad9862_regs.py b/host/lib/ic_reg_maps/gen_ad9862_regs.py index 4444c6240..00340224c 100755 --- a/host/lib/ic_reg_maps/gen_ad9862_regs.py +++ b/host/lib/ic_reg_maps/gen_ad9862_regs.py @@ -123,7 +123,7 @@ ftw_23_16 23[0:7] 0 ######################################################################## ## DLL ######################################################################## -input_clk_ctrl 24[6] 0 external, internal +input_clk_ctrl 24[6] 0 internal, external adc_div2 24[5] 0 normal, div2 dll_mult 24[3:4] 0 1, 2, 4 dll_pd 24[2] 0 diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index 3f3523ddf..ce05ac9eb 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -82,7 +82,7 @@ codec_ctrl_impl::codec_ctrl_impl(usrp_e_iface::sptr iface){ //setup tx side of codec _ad9862_regs.two_data_paths = ad9862_regs_t::TWO_DATA_PATHS_BOTH; - _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_SINGLE; //FIXME should be interleaved + _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED; _ad9862_regs.tx_pga_gain = 199; //TODO bring under api control _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; _ad9862_regs.interp = ad9862_regs_t::INTERP_4; @@ -92,10 +92,19 @@ codec_ctrl_impl::codec_ctrl_impl(usrp_e_iface::sptr iface){ _ad9862_regs.dac_a_coarse_gain = 0x3; _ad9862_regs.dac_b_coarse_gain = 0x3; + //setup the dll + _ad9862_regs.input_clk_ctrl = ad9862_regs_t::INPUT_CLK_CTRL_EXTERNAL; + _ad9862_regs.dll_mult = ad9862_regs_t::DLL_MULT_2; + _ad9862_regs.dll_mode = ad9862_regs_t::DLL_MODE_FAST; + //write the register settings to the codec - for (uint8_t addr = 0; addr <= 50; addr++){ + for (uint8_t addr = 0; addr <= 25; addr++){ this->send_reg(addr); } + + //aux adc clock + _ad9862_regs.clk_4 = ad9862_regs_t::CLK_4_1_4; + this->send_reg(34); } codec_ctrl_impl::~codec_ctrl_impl(void){ -- cgit v1.2.3 From 019be7444989b977de9e94677bc259bad9eb6843 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 10 May 2010 21:43:43 -0400 Subject: Add program to do initial configuration of the clkgen chip. --- host/apps/omap_debug/Makefile | 5 +- host/apps/omap_debug/clkgen-config.cc | 294 ++++++++++++++++++++++++++++++++++ 2 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 host/apps/omap_debug/clkgen-config.cc (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 9b590b9f7..e2aa384f2 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-fpga-rw usrp-e-lb-test usrp-e-crc-rw +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-fpga-rw usrp-e-lb-test usrp-e-crc-rw clkgen-config usrp-e-spi : usrp-e-spi.c @@ -30,6 +30,8 @@ usrp-e-button : usrp-e-button.c fpga-downloader : fpga-downloader.cc +clkgen-config : clkgen-config.cc + usrp-e-gpio : usrp-e-gpio.c usrp-e-lb-test : usrp-e-lb-test.c @@ -51,3 +53,4 @@ clean : rm -f usrp-e-debug-pins rm -f usrp-e-lb-test rm -f usrp-e-crc-rw + rm -f clkgen-config diff --git a/host/apps/omap_debug/clkgen-config.cc b/host/apps/omap_debug/clkgen-config.cc new file mode 100644 index 000000000..c21f54a60 --- /dev/null +++ b/host/apps/omap_debug/clkgen-config.cc @@ -0,0 +1,294 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003,2004,2008,2009 Free Software Foundation, Inc. + * + * This file is part of UHD + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + + +// 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, + 0x001a32, + 0x001b12, + 0x001c44, + 0x001d00, + 0x001e00, + 0x00f062, + 0x00f162, + 0x00f262, + 0x00f362, + 0x00f462, + 0x00f562, + 0x00f662, + 0x00f762, + 0x00f862, + 0x00f962, + 0x00fa62, + 0x00fb62, + 0x00fc00, + 0x00fd00, + 0x019021, + 0x019100, + 0x019200, + 0x019333, + 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) +{ + 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 = 12000000; + int bits = 32; + + 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 = 12000000; + tr.bits_per_word = 32; + + 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++) { + + chip_select.set_value(1); + spi.send((char *)&data[i], (char *)&rbuf, 4); + chip_select.set_value(0); + + }; +} + +int main(int argc, char *argv[]) +{ + + gpio clkgen_select(CLKGEN_SELECT, OUT, true); + + send_config_to_clkgen(clkgen_select, config_data, sizeof(config_data)/sizeof(unsigned int)); +} + -- cgit v1.2.3 From 9251c115b302b7b5773e2e16bbd7a7dfd6c18b74 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 12 May 2010 14:11:10 -0400 Subject: Add calculation for data trasnfer rates. --- host/apps/omap_debug/usrp-e-crc-rw.c | 46 +++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c index 1f23c8d54..f99654781 100644 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -44,6 +44,8 @@ static void *read_thread(void *threadid) int i; unsigned long crc; unsigned int rx_crc; + unsigned long bytes_transfered, elapsed_seconds; + struct timeval start_time, finish_time; printf("Greetings from the reading thread!\n"); @@ -51,7 +53,10 @@ static void *read_thread(void *threadid) rx_data = malloc(2048); rx_pkt_cnt = 0; - + + bytes_transfered = 0; + gettimeofday(&start_time, NULL); + while (1) { cnt = read(fp, rx_data, 2048); @@ -81,7 +86,20 @@ static void *read_thread(void *threadid) printf("CRC Error, sent: %d, rx: %d\n", rx_crc, (crc & 0xFFFFFFFF)); } - + + bytes_transfered += rx_data->len; + + if (bytes_transfered > (100 * 1000000)) { + gettimeofday(&finish_time, NULL); + elapsed_seconds = start_time.tv_sec - finish_time.tv_sec; + + printf("RX data transfer rate = %f K Bps\n", + (float) bytes_transfered / (float) elapsed_seconds / 1000); + + + start_time = finish_time; + bytes_transfered = 0; + } } } @@ -91,12 +109,16 @@ static void *write_thread(void *threadid) int tx_len; unsigned long crc; struct usrp_transfer_frame *tx_data; - struct pkt *p; + unsigned long bytes_transfered, elapsed_seconds; + struct timeval start_time, finish_time; printf("Greetings from the write thread!\n"); tx_data = malloc(2048); + bytes_transfered = 0; + gettimeofday(&start_time, NULL); + while (1) { tx_pkt_cnt++; @@ -115,6 +137,8 @@ static void *write_thread(void *threadid) } tx_len = 2048 - sizeof(struct usrp_transfer_frame) - sizeof(int); + tx_data->len = tx_len + sizeof(int); + crc = 0xFFFFFFFF; for (i = 0; i < tx_len; i++) { tx_data->buf[i] = rand() & 0xFF; @@ -128,6 +152,22 @@ static void *write_thread(void *threadid) cnt = write(fp, tx_data, 2048); if (cnt < 0) printf("Error returned from write: %d\n", cnt); + + + bytes_transfered += tx_data->len; + + if (bytes_transfered > (100 * 1000000)) { + gettimeofday(&finish_time, NULL); + elapsed_seconds = start_time.tv_sec - finish_time.tv_sec; + + printf("TX data transfer rate = %f K Bps\n", + (float) bytes_transfered / (float) elapsed_seconds / 1000); + + + start_time = finish_time; + bytes_transfered = 0; + } + // sleep(1); } } -- cgit v1.2.3 From 89d6cb12a03153934b68d51e69bfdb3b9af43872 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 13 May 2010 18:25:36 +0000 Subject: Print a . for every packet received. --- host/apps/omap_debug/usrp-e-rw-random.c | 2 ++ host/apps/omap_debug/usrp-e-rw.c | 3 +++ 2 files changed, 5 insertions(+) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-rw-random.c b/host/apps/omap_debug/usrp-e-rw-random.c index c6a838067..43f1571cb 100644 --- a/host/apps/omap_debug/usrp-e-rw-random.c +++ b/host/apps/omap_debug/usrp-e-rw-random.c @@ -76,6 +76,8 @@ static void *read_thread(void *threadid) if (calc_checksum(p) != p->checksum) printf("Checksum fail packet = %d, expected = %d\n", calc_checksum(p), p->checksum); + printf("."); + fflush(stdout); // printf("\n"); } diff --git a/host/apps/omap_debug/usrp-e-rw.c b/host/apps/omap_debug/usrp-e-rw.c index edfcea92a..7fba8cd2a 100644 --- a/host/apps/omap_debug/usrp-e-rw.c +++ b/host/apps/omap_debug/usrp-e-rw.c @@ -68,6 +68,9 @@ static void *read_thread(void *threadid) if (calc_checksum(p) != p->checksum) printf("Checksum fail packet = %X, expected = %X\n", calc_checksum(p), p->checksum); + + printf("."); + fflush(stdout); // printf("\n"); } -- cgit v1.2.3 From 41928cd9ff513f1e6d753e02a74db15bda4b1ba8 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 13 May 2010 15:51:28 -0400 Subject: Change to 24 bit transfers. --- host/apps/omap_debug/clkgen-config.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/clkgen-config.cc b/host/apps/omap_debug/clkgen-config.cc index c21f54a60..70c63c6e8 100644 --- a/host/apps/omap_debug/clkgen-config.cc +++ b/host/apps/omap_debug/clkgen-config.cc @@ -239,7 +239,7 @@ spidev::spidev(std::string fname) int ret; int mode = 0; int speed = 12000000; - int bits = 32; + int bits = 24; fd = open(fname.c_str(), O_RDWR); @@ -264,7 +264,7 @@ void spidev::send(char *buf, char *rbuf, unsigned int nbytes) tr.len = nbytes; tr.delay_usecs = 0; tr.speed_hz = 12000000; - tr.bits_per_word = 32; + tr.bits_per_word = 24; ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); -- cgit v1.2.3 From d4a75cef3ed64a305b8c4ef3001ed34c9d47d287 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 13 May 2010 17:46:53 -0400 Subject: Connect enable to the correct gpio. --- host/apps/omap_debug/clkgen-config.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host') diff --git a/host/apps/omap_debug/clkgen-config.cc b/host/apps/omap_debug/clkgen-config.cc index 70c63c6e8..85371c5d1 100644 --- a/host/apps/omap_debug/clkgen-config.cc +++ b/host/apps/omap_debug/clkgen-config.cc @@ -117,7 +117,7 @@ static const unsigned int config_data[] = { }; -const unsigned int CLKGEN_SELECT = 145; +const unsigned int CLKGEN_SELECT = 127; enum gpio_direction {IN, OUT}; -- cgit v1.2.3 From bb3c5d65561bbd720085d8c0bac2ac5cb978773e Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 13 May 2010 22:49:42 +0000 Subject: got clock gen config working and tested --- host/apps/omap_debug/clkgen-config.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/clkgen-config.cc b/host/apps/omap_debug/clkgen-config.cc index 85371c5d1..e8279b4ae 100644 --- a/host/apps/omap_debug/clkgen-config.cc +++ b/host/apps/omap_debug/clkgen-config.cc @@ -50,6 +50,7 @@ static const unsigned int config_data[] = { 0x001704, 0x001807, 0x001900, + //0x001a00,//for debug 0x001a32, 0x001b12, 0x001c44, @@ -117,7 +118,7 @@ static const unsigned int config_data[] = { }; -const unsigned int CLKGEN_SELECT = 127; +const unsigned int CLKGEN_SELECT = 145; enum gpio_direction {IN, OUT}; @@ -238,7 +239,7 @@ spidev::spidev(std::string fname) { int ret; int mode = 0; - int speed = 12000000; + int speed = 12000; int bits = 24; fd = open(fname.c_str(), O_RDWR); @@ -277,9 +278,10 @@ static void send_config_to_clkgen(gpio &chip_select, const unsigned int data[], for (unsigned int i = 0; i < data_size; i++) { - chip_select.set_value(1); - spi.send((char *)&data[i], (char *)&rbuf, 4); + 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); }; } -- cgit v1.2.3 From 4d82cabe938b398bc42cab3d316983d2bbe40d06 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 14 May 2010 10:05:54 -0400 Subject: Update test program to reflect what is in the FPGA image. --- host/apps/omap_debug/usrp-e-crc-rw.c | 41 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c index f99654781..e32cf2c59 100644 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -177,43 +177,42 @@ int main(int argc, char *argv[]) { pthread_t tx, rx; long int t; - int fpga_config_flag ,decimation; struct usrp_e_ctl16 d; struct sched_param s = { .sched_priority = 1 }; + int read, write; - if (argc < 4) { - printf("%s t|w|rw decimation data_size\n", argv[0]); + if (argc < 2) { + printf("%s r|w|rw tx_data_size\n", argv[0]); return -1; } - decimation = atoi(argv[2]); - packet_data_length = atoi(argv[3]); + packet_data_length = atoi(argv[2]); - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); + if (strcmp(argv[1], "r") == 0) { + read = 1; + write = 0; + } - fpga_config_flag = 0; - if (strcmp(argv[1], "w") == 0) - fpga_config_flag |= (1 << 15); - else if (strcmp(argv[1], "r") == 0) - fpga_config_flag |= (1 << 14); - else if (strcmp(argv[1], "rw") == 0) - fpga_config_flag |= ((1 << 15) | (1 << 14)); + if (strcmp(argv[1], "w") == 0) { + read = 0; + write = 1; + } - fpga_config_flag |= decimation; + if (strcmp(argv[1], "rw") == 0) { + read = 1; + write = 1; + } - d.offset = 14; - d.count = 1; - d.buf[0] = fpga_config_flag; - ioctl(fp, USRP_E_WRITE_CTL16, &d); + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); sleep(1); // in case the kernel threads need time to start. FIXME if so sched_setscheduler(0, SCHED_RR, &s); - if (fpga_config_flag & (1 << 14)) { + if (read) { if (pthread_create(&rx, NULL, read_thread, (void *) t)) { printf("Failed to create rx thread\n"); exit(-1); @@ -222,7 +221,7 @@ int main(int argc, char *argv[]) sleep(1); - if (fpga_config_flag & (1 << 15)) { + if (write) { if (pthread_create(&tx, NULL, write_thread, (void *) t)) { printf("Failed to create tx thread\n"); exit(-1); -- cgit v1.2.3 From 7d0a98fc33c17457c9f4cd8e03eddb0d559457f0 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 18 May 2010 10:26:21 -0400 Subject: Revert "Update test program to reflect what is in the FPGA image." This reverts commit 4d82cabe938b398bc42cab3d316983d2bbe40d06. Now sure where I got the idea this image did not contain the rate setting code. --- host/apps/omap_debug/usrp-e-crc-rw.c | 41 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c index e32cf2c59..f99654781 100644 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -177,42 +177,43 @@ int main(int argc, char *argv[]) { pthread_t tx, rx; long int t; + int fpga_config_flag ,decimation; struct usrp_e_ctl16 d; struct sched_param s = { .sched_priority = 1 }; - int read, write; - if (argc < 2) { - printf("%s r|w|rw tx_data_size\n", argv[0]); + if (argc < 4) { + printf("%s t|w|rw decimation data_size\n", argv[0]); return -1; } - packet_data_length = atoi(argv[2]); + decimation = atoi(argv[2]); + packet_data_length = atoi(argv[3]); - if (strcmp(argv[1], "r") == 0) { - read = 1; - write = 0; - } + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); - if (strcmp(argv[1], "w") == 0) { - read = 0; - write = 1; - } + fpga_config_flag = 0; + if (strcmp(argv[1], "w") == 0) + fpga_config_flag |= (1 << 15); + else if (strcmp(argv[1], "r") == 0) + fpga_config_flag |= (1 << 14); + else if (strcmp(argv[1], "rw") == 0) + fpga_config_flag |= ((1 << 15) | (1 << 14)); - if (strcmp(argv[1], "rw") == 0) { - read = 1; - write = 1; - } + fpga_config_flag |= decimation; - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); + d.offset = 14; + d.count = 1; + d.buf[0] = fpga_config_flag; + ioctl(fp, USRP_E_WRITE_CTL16, &d); sleep(1); // in case the kernel threads need time to start. FIXME if so sched_setscheduler(0, SCHED_RR, &s); - if (read) { + if (fpga_config_flag & (1 << 14)) { if (pthread_create(&rx, NULL, read_thread, (void *) t)) { printf("Failed to create rx thread\n"); exit(-1); @@ -221,7 +222,7 @@ int main(int argc, char *argv[]) sleep(1); - if (write) { + if (fpga_config_flag & (1 << 15)) { if (pthread_create(&tx, NULL, write_thread, (void *) t)) { printf("Failed to create tx thread\n"); exit(-1); -- cgit v1.2.3 From 3689cdd36c43656edc93cfee25d3bee1837f8bbd Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 18 May 2010 14:27:57 +0000 Subject: Remove rand for now. Fix bug in data rate calculation. --- host/apps/omap_debug/usrp-e-crc-rw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c index f99654781..b3f8ccc90 100644 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -114,6 +114,7 @@ static void *write_thread(void *threadid) printf("Greetings from the write thread!\n"); + tx_pkt_cnt = 0; tx_data = malloc(2048); bytes_transfered = 0; @@ -141,7 +142,7 @@ static void *write_thread(void *threadid) crc = 0xFFFFFFFF; for (i = 0; i < tx_len; i++) { - tx_data->buf[i] = rand() & 0xFF; + tx_data->buf[i] = i & 0xFF; crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ tx_data->buf[i]) & 0xFF]; @@ -158,8 +159,9 @@ static void *write_thread(void *threadid) if (bytes_transfered > (100 * 1000000)) { gettimeofday(&finish_time, NULL); - elapsed_seconds = start_time.tv_sec - finish_time.tv_sec; + elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; + printf("%d bytes transfered in %d seconds.\n", bytes_transfered, elapsed_seconds); printf("TX data transfer rate = %f K Bps\n", (float) bytes_transfered / (float) elapsed_seconds / 1000); -- cgit v1.2.3 From b5dfe74e991d240f0e666dfd521726ec61128eb8 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 18 May 2010 13:56:57 -0400 Subject: Revert "Revert "Update test program to reflect what is in the FPGA image."" This reverts commit 7d0a98fc33c17457c9f4cd8e03eddb0d559457f0. Must make filenames more different. --- host/apps/omap_debug/usrp-e-crc-rw.c | 41 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c index b3f8ccc90..d47dfef5e 100644 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -179,43 +179,42 @@ int main(int argc, char *argv[]) { pthread_t tx, rx; long int t; - int fpga_config_flag ,decimation; struct usrp_e_ctl16 d; struct sched_param s = { .sched_priority = 1 }; + int read, write; - if (argc < 4) { - printf("%s t|w|rw decimation data_size\n", argv[0]); + if (argc < 2) { + printf("%s r|w|rw tx_data_size\n", argv[0]); return -1; } - decimation = atoi(argv[2]); - packet_data_length = atoi(argv[3]); + packet_data_length = atoi(argv[2]); - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); + if (strcmp(argv[1], "r") == 0) { + read = 1; + write = 0; + } - fpga_config_flag = 0; - if (strcmp(argv[1], "w") == 0) - fpga_config_flag |= (1 << 15); - else if (strcmp(argv[1], "r") == 0) - fpga_config_flag |= (1 << 14); - else if (strcmp(argv[1], "rw") == 0) - fpga_config_flag |= ((1 << 15) | (1 << 14)); + if (strcmp(argv[1], "w") == 0) { + read = 0; + write = 1; + } - fpga_config_flag |= decimation; + if (strcmp(argv[1], "rw") == 0) { + read = 1; + write = 1; + } - d.offset = 14; - d.count = 1; - d.buf[0] = fpga_config_flag; - ioctl(fp, USRP_E_WRITE_CTL16, &d); + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); sleep(1); // in case the kernel threads need time to start. FIXME if so sched_setscheduler(0, SCHED_RR, &s); - if (fpga_config_flag & (1 << 14)) { + if (read) { if (pthread_create(&rx, NULL, read_thread, (void *) t)) { printf("Failed to create rx thread\n"); exit(-1); @@ -224,7 +223,7 @@ int main(int argc, char *argv[]) sleep(1); - if (fpga_config_flag & (1 << 15)) { + if (write) { if (pthread_create(&tx, NULL, write_thread, (void *) t)) { printf("Failed to create tx thread\n"); exit(-1); -- cgit v1.2.3 From e62fd331f37f532e63bdc302236a53dc2e2021e9 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 18 May 2010 17:58:39 +0000 Subject: Comment out progress indicators. --- host/apps/omap_debug/usrp-e-crc-rw.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c index d47dfef5e..cd95761a2 100644 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -64,13 +64,15 @@ static void *read_thread(void *threadid) printf("Error returned from read: %d\n", cnt); rx_pkt_cnt++; - + +#if 0 if (rx_pkt_cnt == 512) { printf("."); fflush(stdout); rx_pkt_cnt = 0; } - +#endif + if (rx_data->flags & RB_OVERRUN) printf("O"); @@ -91,7 +93,7 @@ static void *read_thread(void *threadid) if (bytes_transfered > (100 * 1000000)) { gettimeofday(&finish_time, NULL); - elapsed_seconds = start_time.tv_sec - finish_time.tv_sec; + elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; printf("RX data transfer rate = %f K Bps\n", (float) bytes_transfered / (float) elapsed_seconds / 1000); @@ -123,6 +125,8 @@ static void *write_thread(void *threadid) while (1) { tx_pkt_cnt++; + +#if 0 if (tx_pkt_cnt == 512) { printf("."); fflush(stdout); @@ -136,6 +140,7 @@ static void *write_thread(void *threadid) fflush(stdout); tx_pkt_cnt = 0; } +#endif tx_len = 2048 - sizeof(struct usrp_transfer_frame) - sizeof(int); tx_data->len = tx_len + sizeof(int); @@ -161,7 +166,6 @@ static void *write_thread(void *threadid) gettimeofday(&finish_time, NULL); elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; - printf("%d bytes transfered in %d seconds.\n", bytes_transfered, elapsed_seconds); printf("TX data transfer rate = %f K Bps\n", (float) bytes_transfered / (float) elapsed_seconds / 1000); -- cgit v1.2.3 From ad01832ca5a52d70a5f26de9c45868626b850785 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 19 May 2010 15:01:23 +0000 Subject: Keep repo in sync with my churn ... --- host/apps/omap_debug/usrp-e-crc-rw.c | 3 ++- host/apps/omap_debug/usrp-e-rw.c | 16 ++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c index cd95761a2..e1d9bf0db 100644 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -211,12 +211,13 @@ int main(int argc, char *argv[]) write = 1; } + printf("About to open /dev/usrp_e0"); fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); sleep(1); // in case the kernel threads need time to start. FIXME if so - sched_setscheduler(0, SCHED_RR, &s); +// sched_setscheduler(0, SCHED_RR, &s); if (read) { if (pthread_create(&rx, NULL, read_thread, (void *) t)) { diff --git a/host/apps/omap_debug/usrp-e-rw.c b/host/apps/omap_debug/usrp-e-rw.c index 7fba8cd2a..1b12fa889 100644 --- a/host/apps/omap_debug/usrp-e-rw.c +++ b/host/apps/omap_debug/usrp-e-rw.c @@ -35,7 +35,7 @@ static int calc_checksum(struct pkt *p) static void *read_thread(void *threadid) { - int cnt, prev_seq_num; + int cnt, prev_seq_num, pkt_count; struct usrp_transfer_frame *rx_data; struct pkt *p; @@ -50,6 +50,7 @@ static void *read_thread(void *threadid) printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); prev_seq_num = 0; + pkt_count = 0; while (1) { @@ -60,14 +61,17 @@ static void *read_thread(void *threadid) // printf("Packet received, flags = %X, len = %d\n", rx_data->flags, rx_data->len); // printf("p->seq_num = %d\n", p->seq_num); + + pkt_count++; + if (p->seq_num != prev_seq_num + 1) - printf("Sequence number fail, current = %X, previous = %X\n", - p->seq_num, prev_seq_num); + printf("Sequence number fail, current = %X, previous = %X, pkt_count = %d\n", + p->seq_num, prev_seq_num, pkt_count); prev_seq_num = p->seq_num; if (calc_checksum(p) != p->checksum) - printf("Checksum fail packet = %X, expected = %X\n", - calc_checksum(p), p->checksum); + printf("Checksum fail packet = %X, expected = %X, pkt_count = %d\n", + calc_checksum(p), p->checksum, pkt_count); printf("."); fflush(stdout); @@ -108,7 +112,7 @@ static void *write_thread(void *threadid) cnt = write(fp, tx_data, 2048); if (cnt < 0) printf("Error returned from write: %d\n", cnt); - // sleep(1); + sleep(1); } } -- cgit v1.2.3 From 88b2a958f0a3a593230ca6b17e7c4aac3fba35e7 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 19 May 2010 13:21:45 -0400 Subject: Rename test program to match FPGA bin file name and add data rate calculation. --- host/apps/omap_debug/Makefile | 6 +- host/apps/omap_debug/usrp-e-fpga-rw.c | 207 ------------------------------- host/apps/omap_debug/usrp-e-timed.c | 227 ++++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+), 210 deletions(-) delete mode 100644 host/apps/omap_debug/usrp-e-fpga-rw.c create mode 100644 host/apps/omap_debug/usrp-e-timed.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index e2aa384f2..40e04e377 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,6 +1,6 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-fpga-rw usrp-e-lb-test usrp-e-crc-rw clkgen-config +all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-timed usrp-e-lb-test usrp-e-crc-rw clkgen-config usrp-e-spi : usrp-e-spi.c @@ -9,7 +9,7 @@ usrp-e-i2c : usrp-e-i2c.c usrp-e-rw : usrp-e-rw.c gcc -o $@ $< -lpthread -usrp-e-fpga-rw : usrp-e-fpga-rw.c +usrp-e-timed : usrp-e-timed.c gcc -o $@ $< -lpthread usrp-e-rw-random : usrp-e-rw-random.c @@ -41,7 +41,7 @@ clean : rm -f usrp-e-spi rm -f usrp-e-i2c rm -f usrp-e-rw - rm -f usrp-e-fpga-rw + rm -f usrp-e-timed rm -f usrp-e-rw-random rm -f usrp-e-uart rm -f usrp-e-uart-rx diff --git a/host/apps/omap_debug/usrp-e-fpga-rw.c b/host/apps/omap_debug/usrp-e-fpga-rw.c deleted file mode 100644 index 6b585913e..000000000 --- a/host/apps/omap_debug/usrp-e-fpga-rw.c +++ /dev/null @@ -1,207 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "usrp_e.h" - -// max length #define PKT_DATA_LENGTH 1016 -static int packet_data_length; - -struct pkt { - int checksum; - int seq_num; - short data[]; -}; - -static int fp; - -static int calc_checksum(struct pkt *p) -{ - int i, sum; - - i = 0; - sum = 0; - - for (i=0; i < packet_data_length; i++) - sum += p->data[i]; - - sum += p->seq_num; - - return sum; -} - -static void *read_thread(void *threadid) -{ - int cnt, prev_seq_num; - struct usrp_transfer_frame *rx_data; - struct pkt *p; - int rx_pkt_cnt; - int i; - - printf("Greetings from the reading thread!\n"); - - // IMPORTANT: must assume max length packet from fpga - rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1016 * 2)); - p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); - //p = &(rx_data->buf[0]); - printf("Address of rx_data = %p, p = %p\n", rx_data, p); - printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); - printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); - - prev_seq_num = 0; - - rx_pkt_cnt = 0; - - while (1) { - - cnt = read(fp, rx_data, 2048); - if (cnt < 0) - printf("Error returned from read: %d\n", cnt); - rx_pkt_cnt++; - - if (rx_pkt_cnt == 512) { - printf("."); - fflush(stdout); - rx_pkt_cnt = 0; - } - - if (rx_data->flags & RB_OVERRUN) - printf("O"); - -// for (i = 0; i < 10; i++) -// printf(" %d", p->data[i]); -// printf("\n"); - -// printf("Packet received, flags = %X, len = %d\n", rx_data->flags, rx_data->len); -// printf("p->seq_num = %d\n", p->seq_num); - -// if (p->seq_num != prev_seq_num + 1) -// printf("Sequence number fail, current = %X, previous = %X\n", -// p->seq_num, prev_seq_num); -// prev_seq_num = p->seq_num; - -// if (calc_checksum(p) != p->checksum) -// printf("Checksum fail packet = %X, expected = %X\n", -// calc_checksum(p), p->checksum); -// printf("\n"); - } - -} - -static void *write_thread(void *threadid) -{ - int seq_number, i, cnt, tx_pkt_cnt; - struct usrp_transfer_frame *tx_data; - struct pkt *p; - - printf("Greetings from the write thread!\n"); - - tx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (packet_data_length * 2)); - p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); - printf("Address of tx_data = %p, p = %p\n", tx_data, p); - - printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); - - for (i=0; i < packet_data_length; i++) -// p->data[i] = random() >> 16; - p->data[i] = i; - - tx_data->flags = 0; - tx_data->len = 8 + packet_data_length * 2; - - printf("tx_data->len = %d\n", tx_data->len); - - seq_number = 1; - tx_pkt_cnt = 0; - - while (1) { - - tx_pkt_cnt++; - if (tx_pkt_cnt == 512) { - printf("."); - fflush(stdout); - } - if (tx_pkt_cnt == 1024) { - printf("'"); - fflush(stdout); - } - if (tx_pkt_cnt == 1536) { - printf(":"); - fflush(stdout); - tx_pkt_cnt = 0; - } - -// printf("tx flags = %X, len = %d\n", tx_data->flags, tx_data->len); - p->seq_num = seq_number++; - p->checksum = calc_checksum(p); - cnt = write(fp, tx_data, 2048); - if (cnt < 0) - printf("Error returned from write: %d\n", cnt); -// sleep(1); - } -} - - -int main(int argc, char *argv[]) -{ - pthread_t tx, rx; - long int t; - int fpga_config_flag ,decimation; - struct usrp_e_ctl16 d; - struct sched_param s = { - .sched_priority = 1 - }; - - if (argc < 4) { - printf("%s t|w|rw decimation data_size\n", argv[0]); - return -1; - } - - decimation = atoi(argv[2]); - packet_data_length = atoi(argv[3]); - - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); - - fpga_config_flag = 0; - if (strcmp(argv[1], "w") == 0) - fpga_config_flag |= (1 << 15); - else if (strcmp(argv[1], "r") == 0) - fpga_config_flag |= (1 << 14); - else if (strcmp(argv[1], "rw") == 0) - fpga_config_flag |= ((1 << 15) | (1 << 14)); - - fpga_config_flag |= decimation; - - d.offset = 14; - d.count = 1; - d.buf[0] = fpga_config_flag; - ioctl(fp, USRP_E_WRITE_CTL16, &d); - - sleep(1); // in case the kernel threads need time to start. FIXME if so - - sched_setscheduler(0, SCHED_RR, &s); - - if (fpga_config_flag & (1 << 14)) { - if (pthread_create(&rx, NULL, read_thread, (void *) t)) { - printf("Failed to create rx thread\n"); - exit(-1); - } - } - - sleep(1); - - if (fpga_config_flag & (1 << 15)) { - if (pthread_create(&tx, NULL, write_thread, (void *) t)) { - printf("Failed to create tx thread\n"); - exit(-1); - } - } - - sleep(10000); - - printf("Done sleeping\n"); -} diff --git a/host/apps/omap_debug/usrp-e-timed.c b/host/apps/omap_debug/usrp-e-timed.c new file mode 100644 index 000000000..69e6c07ca --- /dev/null +++ b/host/apps/omap_debug/usrp-e-timed.c @@ -0,0 +1,227 @@ +#include +#include +#include +#include +#include +#include +#include +#include "usrp_e.h" + +// max length #define PKT_DATA_LENGTH 1016 +static int packet_data_length; + +struct pkt { + int checksum; + int seq_num; + short data[]; +}; + +static int fp; + +static int calc_checksum(struct pkt *p) +{ + int i, sum; + + i = 0; + sum = 0; + + for (i=0; i < packet_data_length; i++) + sum += p->data[i]; + + sum += p->seq_num; + + return sum; +} + +static void *read_thread(void *threadid) +{ + int cnt, prev_seq_num; + struct usrp_transfer_frame *rx_data; + struct pkt *p; + int rx_pkt_cnt; + int i; + unsigned long bytes_transfered, elapsed_seconds; + struct timeval start_time, finish_time; + + printf("Greetings from the reading thread!\n"); + + // IMPORTANT: must assume max length packet from fpga + rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1016 * 2)); + p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); + //p = &(rx_data->buf[0]); + printf("Address of rx_data = %p, p = %p\n", rx_data, p); + printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); + printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + + prev_seq_num = 0; + + rx_pkt_cnt = 0; + + while (1) { + + cnt = read(fp, rx_data, 2048); + if (cnt < 0) + printf("Error returned from read: %d\n", cnt); + rx_pkt_cnt++; + +#if 0 + if (rx_pkt_cnt == 512) { + printf("."); + fflush(stdout); + rx_pkt_cnt = 0; + } +#endif + + if (rx_data->flags & RB_OVERRUN) + printf("O"); + + bytes_transfered += rx_data->len; + + if (bytes_transfered > (100 * 1000000)) { + gettimeofday(&finish_time, NULL); + elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; + + printf("RX data transfer rate = %f K Bps\n", + (float) bytes_transfered / (float) elapsed_seconds / 1000); + + + start_time = finish_time; + bytes_transfered = 0; + } + } + +} + +static void *write_thread(void *threadid) +{ + int seq_number, i, cnt, tx_pkt_cnt; + struct usrp_transfer_frame *tx_data; + struct pkt *p; + unsigned long bytes_transfered, elapsed_seconds; + struct timeval start_time, finish_time; + + printf("Greetings from the write thread!\n"); + + tx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (packet_data_length * 2)); + p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); + printf("Address of tx_data = %p, p = %p\n", tx_data, p); + + printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); + + for (i=0; i < packet_data_length; i++) +// p->data[i] = random() >> 16; + p->data[i] = i; + + tx_data->flags = 0; + tx_data->len = 8 + packet_data_length * 2; + + printf("tx_data->len = %d\n", tx_data->len); + + seq_number = 1; + tx_pkt_cnt = 0; + + while (1) { + + tx_pkt_cnt++; + +#if 0 + if (tx_pkt_cnt == 512) { + printf("."); + fflush(stdout); + } + if (tx_pkt_cnt == 1024) { + printf("'"); + fflush(stdout); + } + if (tx_pkt_cnt == 1536) { + printf(":"); + fflush(stdout); + tx_pkt_cnt = 0; + } +#endif + +// printf("tx flags = %X, len = %d\n", tx_data->flags, tx_data->len); + p->seq_num = seq_number++; + p->checksum = calc_checksum(p); + cnt = write(fp, tx_data, 2048); + if (cnt < 0) + printf("Error returned from write: %d\n", cnt); + + bytes_transfered += tx_data->len; + + if (bytes_transfered > (100 * 1000000)) { + gettimeofday(&finish_time, NULL); + elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; + + printf("TX data transfer rate = %f K Bps\n", + (float) bytes_transfered / (float) elapsed_seconds / 1000); + + + start_time = finish_time; + bytes_transfered = 0; + } +// sleep(1); + } +} + + +int main(int argc, char *argv[]) +{ + pthread_t tx, rx; + long int t; + int fpga_config_flag ,decimation; + struct usrp_e_ctl16 d; + struct sched_param s = { + .sched_priority = 1 + }; + + if (argc < 4) { + printf("%s t|w|rw decimation data_size\n", argv[0]); + return -1; + } + + decimation = atoi(argv[2]); + packet_data_length = atoi(argv[3]); + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + fpga_config_flag = 0; + if (strcmp(argv[1], "w") == 0) + fpga_config_flag |= (1 << 15); + else if (strcmp(argv[1], "r") == 0) + fpga_config_flag |= (1 << 14); + else if (strcmp(argv[1], "rw") == 0) + fpga_config_flag |= ((1 << 15) | (1 << 14)); + + fpga_config_flag |= decimation; + + d.offset = 14; + d.count = 1; + d.buf[0] = fpga_config_flag; + ioctl(fp, USRP_E_WRITE_CTL16, &d); + + sleep(1); // in case the kernel threads need time to start. FIXME if so + + sched_setscheduler(0, SCHED_RR, &s); + + if (fpga_config_flag & (1 << 14)) { + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { + printf("Failed to create rx thread\n"); + exit(-1); + } + } + + sleep(1); + + if (fpga_config_flag & (1 << 15)) { + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { + printf("Failed to create tx thread\n"); + exit(-1); + } + } + + sleep(10000); + + printf("Done sleeping\n"); +} -- cgit v1.2.3 From d6fc36cb7aa39cbe3f6dde1b6bc4606a2e686279 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 19 May 2010 17:41:11 +0000 Subject: Fix initialization bug. --- host/apps/omap_debug/usrp-e-timed.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-timed.c b/host/apps/omap_debug/usrp-e-timed.c index 69e6c07ca..cfc70f724 100644 --- a/host/apps/omap_debug/usrp-e-timed.c +++ b/host/apps/omap_debug/usrp-e-timed.c @@ -45,6 +45,9 @@ static void *read_thread(void *threadid) printf("Greetings from the reading thread!\n"); + bytes_transfered = 0; + gettimeofday(&start_time, NULL); + // IMPORTANT: must assume max length packet from fpga rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1016 * 2)); p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); @@ -102,6 +105,9 @@ static void *write_thread(void *threadid) printf("Greetings from the write thread!\n"); + bytes_transfered = 0; + gettimeofday(&start_time, NULL); + tx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (packet_data_length * 2)); p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); printf("Address of tx_data = %p, p = %p\n", tx_data, p); -- cgit v1.2.3 From fe753af7e62e55668cb331b7b74ea14d6e45a0ec Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 19 May 2010 22:25:29 +0000 Subject: Use better optimization settings. --- host/apps/omap_debug/Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 40e04e377..295d40979 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,4 +1,5 @@ -CFLAGS=-Wall -I../../lib/usrp/usrp_e/ +CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 +CXXFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-timed usrp-e-lb-test usrp-e-crc-rw clkgen-config @@ -7,16 +8,16 @@ usrp-e-spi : usrp-e-spi.c usrp-e-i2c : usrp-e-i2c.c usrp-e-rw : usrp-e-rw.c - gcc -o $@ $< -lpthread + gcc -o $@ $< -lpthread ${CFLAGS} usrp-e-timed : usrp-e-timed.c - gcc -o $@ $< -lpthread + gcc -o $@ $< -lpthread ${CFLAGS} usrp-e-rw-random : usrp-e-rw-random.c - gcc -o $@ $< -lpthread + gcc -o $@ $< -lpthread ${CFLAGS} usrp-e-crc-rw : usrp-e-crc-rw.c - gcc -o $@ $< -lpthread + gcc -o $@ $< -lpthread ${CFLAGS} usrp-e-uart : usrp-e-uart.c -- cgit v1.2.3 From 090d066570993f068f2e3b3a6c6bd25986fc92b7 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 19 May 2010 22:26:14 +0000 Subject: Calculate received sample rate for loopback test. --- host/apps/omap_debug/usrp-e-rw.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-rw.c b/host/apps/omap_debug/usrp-e-rw.c index 1b12fa889..f96e4e25b 100644 --- a/host/apps/omap_debug/usrp-e-rw.c +++ b/host/apps/omap_debug/usrp-e-rw.c @@ -38,9 +38,14 @@ static void *read_thread(void *threadid) int cnt, prev_seq_num, pkt_count; struct usrp_transfer_frame *rx_data; struct pkt *p; + unsigned long bytes_transfered, elapsed_seconds; + struct timeval start_time, finish_time; printf("Greetings from the reading thread!\n"); + bytes_transfered = 0; + gettimeofday(&start_time, NULL); + // IMPORTANT: must assume max length packet from fpga rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1016 * 2)); p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); @@ -73,8 +78,24 @@ static void *read_thread(void *threadid) printf("Checksum fail packet = %X, expected = %X, pkt_count = %d\n", calc_checksum(p), p->checksum, pkt_count); - printf("."); - fflush(stdout); + + bytes_transfered += rx_data->len; + + if (bytes_transfered > (100 * 1000000)) { + gettimeofday(&finish_time, NULL); + elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; + + printf("RX data transfer rate = %f K Samples/second\n", + (float) bytes_transfered / (float) elapsed_seconds / 250); + + + start_time = finish_time; + bytes_transfered = 0; + } + + +// printf("."); +// fflush(stdout); // printf("\n"); } @@ -112,7 +133,7 @@ static void *write_thread(void *threadid) cnt = write(fp, tx_data, 2048); if (cnt < 0) printf("Error returned from write: %d\n", cnt); - sleep(1); +// sleep(1); } } -- cgit v1.2.3 From 3bb874f8061f203d8adf6f07e61fd50a154e9906 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 19 May 2010 22:27:06 +0000 Subject: Display data rate in samples/second and fix typo. --- host/apps/omap_debug/usrp-e-timed.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-timed.c b/host/apps/omap_debug/usrp-e-timed.c index cfc70f724..c71651741 100644 --- a/host/apps/omap_debug/usrp-e-timed.c +++ b/host/apps/omap_debug/usrp-e-timed.c @@ -84,8 +84,8 @@ static void *read_thread(void *threadid) gettimeofday(&finish_time, NULL); elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; - printf("RX data transfer rate = %f K Bps\n", - (float) bytes_transfered / (float) elapsed_seconds / 1000); + printf("RX data transfer rate = %f K Samples/second\n", + (float) bytes_transfered / (float) elapsed_seconds / 4000); start_time = finish_time; @@ -159,8 +159,8 @@ static void *write_thread(void *threadid) gettimeofday(&finish_time, NULL); elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; - printf("TX data transfer rate = %f K Bps\n", - (float) bytes_transfered / (float) elapsed_seconds / 1000); + printf("TX data transfer rate = %f K Samples/second\n", + (float) bytes_transfered / (float) elapsed_seconds / 4000); start_time = finish_time; @@ -182,7 +182,7 @@ int main(int argc, char *argv[]) }; if (argc < 4) { - printf("%s t|w|rw decimation data_size\n", argv[0]); + printf("%s r|w|rw decimation data_size\n", argv[0]); return -1; } -- cgit v1.2.3 From a9fefde874503c0c4e0c542846c1dd1c74156d07 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 20 May 2010 15:05:04 +0000 Subject: Enable realtime scheduling in loopback test to prevent overruns. --- host/apps/omap_debug/usrp-e-rw.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-rw.c b/host/apps/omap_debug/usrp-e-rw.c index f96e4e25b..798bc4b45 100644 --- a/host/apps/omap_debug/usrp-e-rw.c +++ b/host/apps/omap_debug/usrp-e-rw.c @@ -142,6 +142,9 @@ int main(int argc, char *argv[]) { pthread_t tx, rx; long int t; + struct sched_param s = { + .sched_priority = 1 + }; if (argc < 2) { printf("%s data_size\n", argv[0]); @@ -153,6 +156,8 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); + sched_setscheduler(0, SCHED_RR, &s); + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { printf("Failed to create rx thread\n"); exit(-1); -- cgit v1.2.3 From 64276eabd8d88f7d72763f8b500c13a9a689cd21 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 20 May 2010 15:10:32 +0000 Subject: Rename loopback test program to match bin file name. --- host/apps/omap_debug/Makefile | 6 +- host/apps/omap_debug/usrp-e-loopback.c | 176 +++++++++++++++++++++++++++++++++ host/apps/omap_debug/usrp-e-rw.c | 176 --------------------------------- 3 files changed, 179 insertions(+), 179 deletions(-) create mode 100644 host/apps/omap_debug/usrp-e-loopback.c delete mode 100644 host/apps/omap_debug/usrp-e-rw.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 295d40979..17a3858cf 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,13 +1,13 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 CXXFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 -all : usrp-e-spi usrp-e-i2c usrp-e-rw usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-timed usrp-e-lb-test usrp-e-crc-rw clkgen-config +all : usrp-e-spi usrp-e-i2c usrp-e-loopback usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-timed usrp-e-lb-test usrp-e-crc-rw clkgen-config usrp-e-spi : usrp-e-spi.c usrp-e-i2c : usrp-e-i2c.c -usrp-e-rw : usrp-e-rw.c +usrp-e-loopback : usrp-e-loopback.c gcc -o $@ $< -lpthread ${CFLAGS} usrp-e-timed : usrp-e-timed.c @@ -41,7 +41,7 @@ usrp-e-debug-pins : usrp-e-debug-pins.c clean : rm -f usrp-e-spi rm -f usrp-e-i2c - rm -f usrp-e-rw + rm -f usrp-e-loopback rm -f usrp-e-timed rm -f usrp-e-rw-random rm -f usrp-e-uart diff --git a/host/apps/omap_debug/usrp-e-loopback.c b/host/apps/omap_debug/usrp-e-loopback.c new file mode 100644 index 000000000..798bc4b45 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-loopback.c @@ -0,0 +1,176 @@ +#include +#include +#include +#include +#include +#include +#include +#include "usrp_e.h" + +// max length #define PKT_DATA_LENGTH 1016 +static int packet_data_length; + +struct pkt { + int checksum; + int seq_num; + short data[]; +}; + +static int fp; + +static int calc_checksum(struct pkt *p) +{ + int i, sum; + + i = 0; + sum = 0; + + for (i=0; i < packet_data_length; i++) + sum += p->data[i]; + + sum += p->seq_num; + + return sum; +} + +static void *read_thread(void *threadid) +{ + int cnt, prev_seq_num, pkt_count; + struct usrp_transfer_frame *rx_data; + struct pkt *p; + unsigned long bytes_transfered, elapsed_seconds; + struct timeval start_time, finish_time; + + printf("Greetings from the reading thread!\n"); + + bytes_transfered = 0; + gettimeofday(&start_time, NULL); + + // IMPORTANT: must assume max length packet from fpga + rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1016 * 2)); + p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); + //p = &(rx_data->buf[0]); + printf("Address of rx_data = %p, p = %p\n", rx_data, p); + printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); + printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + + prev_seq_num = 0; + pkt_count = 0; + + while (1) { + + cnt = read(fp, rx_data, 2048); + if (cnt < 0) + printf("Error returned from read: %d\n", cnt); + +// printf("Packet received, flags = %X, len = %d\n", rx_data->flags, rx_data->len); +// printf("p->seq_num = %d\n", p->seq_num); + + + pkt_count++; + + if (p->seq_num != prev_seq_num + 1) + printf("Sequence number fail, current = %X, previous = %X, pkt_count = %d\n", + p->seq_num, prev_seq_num, pkt_count); + prev_seq_num = p->seq_num; + + if (calc_checksum(p) != p->checksum) + printf("Checksum fail packet = %X, expected = %X, pkt_count = %d\n", + calc_checksum(p), p->checksum, pkt_count); + + + bytes_transfered += rx_data->len; + + if (bytes_transfered > (100 * 1000000)) { + gettimeofday(&finish_time, NULL); + elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; + + printf("RX data transfer rate = %f K Samples/second\n", + (float) bytes_transfered / (float) elapsed_seconds / 250); + + + start_time = finish_time; + bytes_transfered = 0; + } + + +// printf("."); +// fflush(stdout); +// printf("\n"); + } + +} + +static void *write_thread(void *threadid) +{ + int seq_number, i, cnt; + struct usrp_transfer_frame *tx_data; + struct pkt *p; + + printf("Greetings from the write thread!\n"); + + tx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (packet_data_length * 2)); + p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); + printf("Address of tx_data = %p, p = %p\n", tx_data, p); + + printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); + + for (i=0; i < packet_data_length; i++) +// p->data[i] = random() >> 16; + p->data[i] = i; + + tx_data->flags = 0xdeadbeef; + tx_data->len = 8 + packet_data_length * 2; + + printf("tx_data->len = %d\n", tx_data->len); + + seq_number = 1; + + while (1) { +// printf("tx flags = %X, len = %d\n", tx_data->flags, tx_data->len); + p->seq_num = seq_number++; + p->checksum = calc_checksum(p); + cnt = write(fp, tx_data, 2048); + if (cnt < 0) + printf("Error returned from write: %d\n", cnt); +// sleep(1); + } +} + + +int main(int argc, char *argv[]) +{ + pthread_t tx, rx; + long int t; + struct sched_param s = { + .sched_priority = 1 + }; + + if (argc < 2) { + printf("%s data_size\n", argv[0]); + return -1; + } + + packet_data_length = atoi(argv[1]); + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + sched_setscheduler(0, SCHED_RR, &s); + + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { + printf("Failed to create rx thread\n"); + exit(-1); + } + + sleep(1); + + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { + printf("Failed to create tx thread\n"); + exit(-1); + } + + sleep(10000); + + printf("Done sleeping\n"); +} diff --git a/host/apps/omap_debug/usrp-e-rw.c b/host/apps/omap_debug/usrp-e-rw.c deleted file mode 100644 index 798bc4b45..000000000 --- a/host/apps/omap_debug/usrp-e-rw.c +++ /dev/null @@ -1,176 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "usrp_e.h" - -// max length #define PKT_DATA_LENGTH 1016 -static int packet_data_length; - -struct pkt { - int checksum; - int seq_num; - short data[]; -}; - -static int fp; - -static int calc_checksum(struct pkt *p) -{ - int i, sum; - - i = 0; - sum = 0; - - for (i=0; i < packet_data_length; i++) - sum += p->data[i]; - - sum += p->seq_num; - - return sum; -} - -static void *read_thread(void *threadid) -{ - int cnt, prev_seq_num, pkt_count; - struct usrp_transfer_frame *rx_data; - struct pkt *p; - unsigned long bytes_transfered, elapsed_seconds; - struct timeval start_time, finish_time; - - printf("Greetings from the reading thread!\n"); - - bytes_transfered = 0; - gettimeofday(&start_time, NULL); - - // IMPORTANT: must assume max length packet from fpga - rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1016 * 2)); - p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); - //p = &(rx_data->buf[0]); - printf("Address of rx_data = %p, p = %p\n", rx_data, p); - printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); - printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); - - prev_seq_num = 0; - pkt_count = 0; - - while (1) { - - cnt = read(fp, rx_data, 2048); - if (cnt < 0) - printf("Error returned from read: %d\n", cnt); - -// printf("Packet received, flags = %X, len = %d\n", rx_data->flags, rx_data->len); -// printf("p->seq_num = %d\n", p->seq_num); - - - pkt_count++; - - if (p->seq_num != prev_seq_num + 1) - printf("Sequence number fail, current = %X, previous = %X, pkt_count = %d\n", - p->seq_num, prev_seq_num, pkt_count); - prev_seq_num = p->seq_num; - - if (calc_checksum(p) != p->checksum) - printf("Checksum fail packet = %X, expected = %X, pkt_count = %d\n", - calc_checksum(p), p->checksum, pkt_count); - - - bytes_transfered += rx_data->len; - - if (bytes_transfered > (100 * 1000000)) { - gettimeofday(&finish_time, NULL); - elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; - - printf("RX data transfer rate = %f K Samples/second\n", - (float) bytes_transfered / (float) elapsed_seconds / 250); - - - start_time = finish_time; - bytes_transfered = 0; - } - - -// printf("."); -// fflush(stdout); -// printf("\n"); - } - -} - -static void *write_thread(void *threadid) -{ - int seq_number, i, cnt; - struct usrp_transfer_frame *tx_data; - struct pkt *p; - - printf("Greetings from the write thread!\n"); - - tx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (packet_data_length * 2)); - p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); - printf("Address of tx_data = %p, p = %p\n", tx_data, p); - - printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); - - for (i=0; i < packet_data_length; i++) -// p->data[i] = random() >> 16; - p->data[i] = i; - - tx_data->flags = 0xdeadbeef; - tx_data->len = 8 + packet_data_length * 2; - - printf("tx_data->len = %d\n", tx_data->len); - - seq_number = 1; - - while (1) { -// printf("tx flags = %X, len = %d\n", tx_data->flags, tx_data->len); - p->seq_num = seq_number++; - p->checksum = calc_checksum(p); - cnt = write(fp, tx_data, 2048); - if (cnt < 0) - printf("Error returned from write: %d\n", cnt); -// sleep(1); - } -} - - -int main(int argc, char *argv[]) -{ - pthread_t tx, rx; - long int t; - struct sched_param s = { - .sched_priority = 1 - }; - - if (argc < 2) { - printf("%s data_size\n", argv[0]); - return -1; - } - - packet_data_length = atoi(argv[1]); - - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); - - sched_setscheduler(0, SCHED_RR, &s); - - if (pthread_create(&rx, NULL, read_thread, (void *) t)) { - printf("Failed to create rx thread\n"); - exit(-1); - } - - sleep(1); - - if (pthread_create(&tx, NULL, write_thread, (void *) t)) { - printf("Failed to create tx thread\n"); - exit(-1); - } - - sleep(10000); - - printf("Done sleeping\n"); -} -- cgit v1.2.3 From 96ef5b171b44956f44e02672af8a734f3c0e38c4 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 21 May 2010 10:14:03 -0400 Subject: OK, now crc uses the timed interface to set the data rate. Revert "Revert "Revert "Update test program to reflect what is in the FPGA image.""" This reverts commit b5dfe74e991d240f0e666dfd521726ec61128eb8. Conflicts: host/apps/omap_debug/usrp-e-crc-rw.c --- host/apps/omap_debug/usrp-e-crc-rw.c | 42 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c index e1d9bf0db..b0982de86 100644 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -183,43 +183,43 @@ int main(int argc, char *argv[]) { pthread_t tx, rx; long int t; + int fpga_config_flag ,decimation; struct usrp_e_ctl16 d; struct sched_param s = { .sched_priority = 1 }; - int read, write; - if (argc < 2) { - printf("%s r|w|rw tx_data_size\n", argv[0]); + if (argc < 4) { + printf("%s t|w|rw decimation data_size\n", argv[0]); return -1; } - packet_data_length = atoi(argv[2]); + decimation = atoi(argv[2]); + packet_data_length = atoi(argv[3]); - if (strcmp(argv[1], "r") == 0) { - read = 1; - write = 0; - } + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); - if (strcmp(argv[1], "w") == 0) { - read = 0; - write = 1; - } + fpga_config_flag = 0; + if (strcmp(argv[1], "w") == 0) + fpga_config_flag |= (1 << 15); + else if (strcmp(argv[1], "r") == 0) + fpga_config_flag |= (1 << 14); + else if (strcmp(argv[1], "rw") == 0) + fpga_config_flag |= ((1 << 15) | (1 << 14)); - if (strcmp(argv[1], "rw") == 0) { - read = 1; - write = 1; - } + fpga_config_flag |= decimation; - printf("About to open /dev/usrp_e0"); - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); + d.offset = 14; + d.count = 1; + d.buf[0] = fpga_config_flag; + ioctl(fp, USRP_E_WRITE_CTL16, &d); sleep(1); // in case the kernel threads need time to start. FIXME if so // sched_setscheduler(0, SCHED_RR, &s); - if (read) { + if (fpga_config_flag & (1 << 14)) { if (pthread_create(&rx, NULL, read_thread, (void *) t)) { printf("Failed to create rx thread\n"); exit(-1); @@ -228,7 +228,7 @@ int main(int argc, char *argv[]) sleep(1); - if (write) { + if (fpga_config_flag & (1 << 15)) { if (pthread_create(&tx, NULL, write_thread, (void *) t)) { printf("Failed to create tx thread\n"); exit(-1); -- cgit v1.2.3 From 85e32e298217a16102d25a455d605c55a05e369c Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 21 May 2010 21:13:25 +0000 Subject: Work on crc testing program. Currently dumps first received packet to the screen. Started to reduce teh number of warnings. --- host/apps/omap_debug/usrp-e-crc-rw.c | 46 ++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 10 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c index b0982de86..8883366ae 100644 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -1,5 +1,8 @@ #include #include +#include +#include +#include #include #include #include @@ -34,6 +37,8 @@ static u_int32_t chksum_crc32_gentab(void) } crc_tab[i] = crc; } + + return 0; } static void *read_thread(void *threadid) @@ -47,6 +52,9 @@ static void *read_thread(void *threadid) unsigned long bytes_transfered, elapsed_seconds; struct timeval start_time, finish_time; + __u8 *p; + __u32 *pi; + printf("Greetings from the reading thread!\n"); // IMPORTANT: must assume max length packet from fpga @@ -81,12 +89,24 @@ static void *read_thread(void *threadid) crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ rx_data->buf[i]) & 0xFF]; } - - rx_crc = *((int *) &rx_data[rx_data->len - 4]); - + + p = &rx_data->buf[rx_data->len - 4]; + pi = (__u32 *) p; + rx_crc = *pi; + +#if 1 + printf("rx_data->len = %d\n", rx_data->len); + printf("rx_data->flags = %d\n", rx_data->flags); + for (i = 0; i < rx_data->len; i++) + printf("idx = %d, data = %X\n", i, rx_data->buf[i]); + printf("calc crc = %lX, rx crc = %X\n", crc, rx_crc); + fflush(stdout); + break; +#endif + if (rx_crc != (crc & 0xFFFFFFFF)) { - printf("CRC Error, sent: %d, rx: %d\n", - rx_crc, (crc & 0xFFFFFFFF)); + printf("CRC Error, calc crc: %X, rx_crc: %X\n", + (crc & 0xFFFFFFFF), rx_crc); } bytes_transfered += rx_data->len; @@ -95,8 +115,9 @@ static void *read_thread(void *threadid) gettimeofday(&finish_time, NULL); elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; - printf("RX data transfer rate = %f K Bps\n", - (float) bytes_transfered / (float) elapsed_seconds / 1000); + printf("Bytes transfered = %ld, elapsed seconds = %ld\n", bytes_transfered, elapsed_seconds); + printf("RX data transfer rate = %f K Samples/second\n", + (float) bytes_transfered / (float) elapsed_seconds / 250); start_time = finish_time; @@ -166,8 +187,9 @@ static void *write_thread(void *threadid) gettimeofday(&finish_time, NULL); elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; - printf("TX data transfer rate = %f K Bps\n", - (float) bytes_transfered / (float) elapsed_seconds / 1000); + printf("Bytes transfered = %d, elapsed seconds = %d\n", bytes_transfered, elapsed_seconds); + printf("TX data transfer rate = %f K Samples/second\n", + (float) bytes_transfered / (float) elapsed_seconds / 250); start_time = finish_time; @@ -194,6 +216,8 @@ int main(int argc, char *argv[]) return -1; } + chksum_crc32_gentab(); + decimation = atoi(argv[2]); packet_data_length = atoi(argv[3]); @@ -217,7 +241,7 @@ int main(int argc, char *argv[]) sleep(1); // in case the kernel threads need time to start. FIXME if so -// sched_setscheduler(0, SCHED_RR, &s); + sched_setscheduler(0, SCHED_RR, &s); if (fpga_config_flag & (1 << 14)) { if (pthread_create(&rx, NULL, read_thread, (void *) t)) { @@ -238,4 +262,6 @@ int main(int argc, char *argv[]) sleep(10000); printf("Done sleeping\n"); + + return 0; } -- cgit v1.2.3 From f113ae17863729f05b6ada815b9817cd16001211 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sun, 23 May 2010 12:58:58 +0000 Subject: Divide by 4 to convert byts/sec to samples/sec. Multiply by 4 is right out. --- host/apps/omap_debug/usrp-e-loopback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-loopback.c b/host/apps/omap_debug/usrp-e-loopback.c index 798bc4b45..177394947 100644 --- a/host/apps/omap_debug/usrp-e-loopback.c +++ b/host/apps/omap_debug/usrp-e-loopback.c @@ -86,7 +86,7 @@ static void *read_thread(void *threadid) elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; printf("RX data transfer rate = %f K Samples/second\n", - (float) bytes_transfered / (float) elapsed_seconds / 250); + (float) bytes_transfered / (float) elapsed_seconds / 4000); start_time = finish_time; -- cgit v1.2.3 From ac62d187cc7a4adde65c1e6fb1807ec5a967f966 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 28 May 2010 17:41:01 +0000 Subject: reverted usrp-e-led sorry --- host/apps/omap_debug/usrp-e-led.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-led.c b/host/apps/omap_debug/usrp-e-led.c index 30fbb66e0..d1b6c8996 100644 --- a/host/apps/omap_debug/usrp-e-led.c +++ b/host/apps/omap_debug/usrp-e-led.c @@ -20,16 +20,16 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); - d.offset = UE_REG_MISC_BASE+14; + d.offset = UE_REG_MISC_BASE; d.count = 1; - d.buf[0] = 0x4020; - ret = ioctl(fp, USRP_E_WRITE_CTL16, &d); - - sleep(10); - - d.buf[0] = 0x0; - ret = ioctl(fp, USRP_E_WRITE_CTL16, &d); + while (1) { + for (i=0; i<8; i++) { + d.buf[0] = i; + ret = ioctl(fp, USRP_E_WRITE_CTL16, &d); + sleep(1); + } + } return 0; } -- cgit v1.2.3 From 66deed6015f2a2bc67f17f6630ca62a41b596090 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 1 Jun 2010 18:50:15 -0700 Subject: added sr registers to u1e --- host/lib/usrp/usrp_e/usrp_e_regs.hpp | 78 +++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp index 51a47f061..67c174208 100644 --- a/host/lib/usrp/usrp_e/usrp_e_regs.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -17,6 +17,7 @@ // Slave pointers #define UE_REG_SLAVE(n) ((n)<<7) +#define UE_REG_SR_ADDR(n) ((UE_REG_SLAVE(5)) + (4*(n))) ///////////////////////////////////////////////////// // Slave 0 -- Misc Regs @@ -102,8 +103,8 @@ #define UE_REG_ATR_BASE UE_REG_SLAVE(6) -#define UE_REG_ATR_IDLE_RXSIDE UE_REG_ATR_BASE + 0 -#define UE_REG_ATR_IDLE_TXSIDE UE_REG_ATR_BASE + 2 +#define UE_REG_ATR_IDLE_RXSIDE UE_REG_ATR_BASE + 0 +#define UE_REG_ATR_IDLE_TXSIDE UE_REG_ATR_BASE + 2 #define UE_REG_ATR_INTX_RXSIDE UE_REG_ATR_BASE + 4 #define UE_REG_ATR_INTX_TXSIDE UE_REG_ATR_BASE + 6 #define UE_REG_ATR_INRX_RXSIDE UE_REG_ATR_BASE + 8 @@ -111,5 +112,78 @@ #define UE_REG_ATR_FULL_RXSIDE UE_REG_ATR_BASE + 12 #define UE_REG_ATR_FULL_TXSIDE UE_REG_ATR_BASE + 14 +///////////////////////////////////////////////// +// DSP RX Regs +//////////////////////////////////////////////// +#define UE_REG_DSP_RX_FREQ UE_REG_SR_ADDR(0) +#define UE_REG_DSP_RX_SCALE_IQ UE_REG_SR_ADDR(1) // {scale_i,scale_q} +#define UE_REG_DSP_RX_DECIM_RATE UE_REG_SR_ADDR(2) // hb and decim rate +#define UE_REG_DSP_RX_DCOFFSET_I UE_REG_SR_ADDR(3) // Bit 31 high sets fixed offset mode, using lower 14 bits, // otherwise it is automatic +#define UE_REG_DSP_RX_DCOFFSET_Q UE_REG_SR_ADDR(4) // Bit 31 high sets fixed offset mode, using lower 14 bits +#define UE_REG_DSP_RX_MUX UE_REG_SR_ADDR(5) + +/////////////////////////////////////////////////// +// VITA RX CTRL regs +/////////////////////////////////////////////////// +// The following 3 are logically a single command register. +// They are clocked into the underlying fifo when time_ticks is written. +#define UE_REG_CTRL_RX_STREAM_CMD UE_REG_SR_ADDR(8) // {now, chain, num_samples(30) +#define UE_REG_CTRL_RX_TIME_SECS UE_REG_SR_ADDR(9) +#define UE_REG_CTRL_RX_TIME_TICKS UE_REG_SR_ADDR(10) +#define UE_REG_CTRL_RX_CLEAR_OVERRUN UE_REG_SR_ADDR(11) // write anything to clear overrun +#define UE_REG_CTRL_RX_VRT_HEADER UE_REG_SR_ADDR(12) // word 0 of packet. FPGA fills in packet counter +#define UE_REG_CTRL_RX_VRT_STREAM_ID UE_REG_SR_ADDR(13) // word 1 of packet. +#define UE_REG_CTRL_RX_VRT_TRAILER UE_REG_SR_ADDR(14) +#define UE_REG_CTRL_RX_NSAMPS_PER_PKT UE_REG_SR_ADDR(15) +#define UE_REG_CTRL_RX_NCHANNELS UE_REG_SR_ADDR(16) // 1 in basic case, up to 4 for vector sources + +///////////////////////////////////////////////// +// DSP TX Regs +//////////////////////////////////////////////// +#define UE_REG_DSP_TX_FREQ UE_REG_SR_ADDR(17) +#define UE_REG_DSP_TX_SCALE_IQ UE_REG_SR_ADDR(18) // {scale_i,scale_q} +#define UE_REG_DSP_TX_INTERP_RATE UE_REG_SR_ADDR(19) +#define UE_REG_DSP_TX_UNUSED UE_REG_SR_ADDR(20) +#define UE_REG_DSP_TX_MUX UE_REG_SR_ADDR(21) + +///////////////////////////////////////////////// +// VITA TX CTRL regs +//////////////////////////////////////////////// +#define UE_REG_CTRL_TX_NCHANNELS UE_REG_SR_ADDR(24) +#define UE_REG_CTRL_TX_CLEAR_UNDERRUN UE_REG_SR_ADDR(25) + +///////////////////////////////////////////////// +// VITA49 64 bit time (write only) +//////////////////////////////////////////////// + /*! + * \brief Time 64 flags + * + *
+   *
+   *    3                   2                   1
+   *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   * +-----------------------------------------------------------+-+-+
+   * |                                                           |S|P|
+   * +-----------------------------------------------------------+-+-+
+   *
+   * P - PPS edge selection (0=negedge, 1=posedge, default=0)
+   * S - Source (0=sma, 1=mimo, 0=default)
+   *
+   * 
+ */ +#define UE_REG_TIME64_SECS UE_REG_SR_ADDR(28) // value to set absolute secs to on next PPS +#define UE_REG_TIME64_TICKS UE_REG_SR_ADDR(29) // value to set absolute ticks to on next PPS +#define UE_REG_TIME64_FLAGS UE_REG_SR_ADDR(30) // flags - see chart above +#define UE_REG_TIME64_IMM UE_REG_SR_ADDR(31) // set immediate (0=latch on next pps, 1=latch immediate, default=0) + +//pps flags (see above) +#define UE_FLAG_TIME64_PPS_NEGEDGE (0 << 0) +#define UE_FLAG_TIME64_PPS_POSEDGE (1 << 0) +#define UE_FLAG_TIME64_PPS_SMA (0 << 1) +#define UE_FLAG_TIME64_PPS_MIMO (1 << 1) + +#define UE_FLAG_TIME64_LATCH_NOW 1 +#define UE_FLAG_TIME64_LATCH_NEXT_PPS 0 + #endif -- cgit v1.2.3 From f1529463174883f6c830acbfd52cd52ed4755971 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 3 Jun 2010 17:09:06 +0000 Subject: added headers to cmakelists for completeness --- host/lib/usrp/usrp_e/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/CMakeLists.txt b/host/lib/usrp/usrp_e/CMakeLists.txt index c25b2cba4..6035d4ff2 100644 --- a/host/lib/usrp/usrp_e/CMakeLists.txt +++ b/host/lib/usrp/usrp_e/CMakeLists.txt @@ -42,14 +42,19 @@ IF(HAVE_USRP_E_REQUIRED_HEADERS) MESSAGE(STATUS " Building usrp-e support.") LIBUHD_APPEND_SOURCES( ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/clock_ctrl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/clock_ctrl.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/codec_ctrl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/codec_ctrl.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dboard_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dboard_iface.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dsp_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/fpga-downloader.cc ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/mboard_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_impl.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_iface.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_iface.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_regs.hpp ) ELSE(HAVE_USRP_E_REQUIRED_HEADERS) MESSAGE(STATUS " Skipping usrp-e support.") -- cgit v1.2.3 From 551426b72672379faa56302eb3d3e19d12c41aec Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 3 Jun 2010 19:30:00 +0000 Subject: work on io impl for usrp-e using read/write --- host/lib/usrp/usrp_e/CMakeLists.txt | 1 + host/lib/usrp/usrp_e/io_impl.cpp | 137 ++++++++++++++++++++++++++++++++++ host/lib/usrp/usrp_e/usrp_e_iface.cpp | 4 + host/lib/usrp/usrp_e/usrp_e_iface.hpp | 6 ++ host/lib/usrp/usrp_e/usrp_e_impl.cpp | 30 +------- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 35 ++++----- 6 files changed, 166 insertions(+), 47 deletions(-) create mode 100644 host/lib/usrp/usrp_e/io_impl.cpp (limited to 'host') diff --git a/host/lib/usrp/usrp_e/CMakeLists.txt b/host/lib/usrp/usrp_e/CMakeLists.txt index 6035d4ff2..568fbd132 100644 --- a/host/lib/usrp/usrp_e/CMakeLists.txt +++ b/host/lib/usrp/usrp_e/CMakeLists.txt @@ -49,6 +49,7 @@ IF(HAVE_USRP_E_REQUIRED_HEADERS) ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dboard_iface.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dsp_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/fpga-downloader.cc + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/io_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/mboard_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_impl.hpp diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp new file mode 100644 index 000000000..5bb40723e --- /dev/null +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -0,0 +1,137 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_impl.hpp" +#include "../../transport/vrt_packet_handler.hpp" +#include +#include //read, write +#include //transfer frame struct +#include //offsetof + +using namespace uhd; + +/*********************************************************************** + * Data Transport (phony zero-copy with read/write) + **********************************************************************/ +class data_transport: + public transport::phony_zero_copy_recv_if, + public transport::phony_zero_copy_send_if +{ +public: + data_transport(int fd): + transport::phony_zero_copy_recv_if(2048), //FIXME magic # + transport::phony_zero_copy_send_if(2048), //FIXME magic # + _fd(fd) + { + /* NOP */ + } + + size_t get_num_recv_frames(void) const{ + return 10; //FIXME no idea! + } + + size_t get_num_send_frames(void) const{ + return 10; //FIXME no idea! + } + +private: + int _fd; + size_t send(const boost::asio::const_buffer &buff){ + return write( + _fd, + boost::asio::buffer_cast(buff), + boost::asio::buffer_size(buff) + ); + } + size_t recv(const boost::asio::mutable_buffer &buff){ + return read( + _fd, + boost::asio::buffer_cast(buff), + boost::asio::buffer_size(buff) + ); + } +}; + +/*********************************************************************** + * IO Implementation Details + **********************************************************************/ +struct usrp_e_impl::io_impl{ + vrt_packet_handler::recv_state recv_state; + vrt_packet_handler::send_state send_state; + data_transport transport; + io_impl(int fd): transport(fd){} +}; + +void usrp_e_impl::io_init(void){ + _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface->get_file_descriptor())); +} + +/*********************************************************************** + * Data Send + **********************************************************************/ +size_t usrp_e_impl::send( + const boost::asio::const_buffer &buff, + const uhd::tx_metadata_t &metadata, + const io_type_t & io_type, + send_mode_t send_mode +){ + otw_type_t send_otw_type; + send_otw_type.width = 16; + send_otw_type.shift = 0; + send_otw_type.byteorder = otw_type_t::BO_NATIVE; + + return vrt_packet_handler::send( + _io_impl->send_state, + buff, + metadata, + send_mode, + io_type, + send_otw_type, //TODO + 64e6, //TODO + boost::bind(&data_transport::get_send_buff, &_io_impl->transport), + _max_num_samples, //TODO + offsetof(usrp_transfer_frame, buf) + //TODO probably need callback to fill in frame size + ); +} + +/*********************************************************************** + * Data Recv + **********************************************************************/ +size_t usrp_e_impl::recv( + const boost::asio::mutable_buffer &buff, + uhd::rx_metadata_t &metadata, + const io_type_t &io_type, + recv_mode_t recv_mode +){ + otw_type_t recv_otw_type; + recv_otw_type.width = 16; + recv_otw_type.shift = 0; + recv_otw_type.byteorder = otw_type_t::BO_NATIVE; + + return vrt_packet_handler::recv( + _io_impl->recv_state, + buff, + metadata, + recv_mode, + io_type, + recv_otw_type, //TODO + 64e6, //TODO + boost::bind(&data_transport::get_recv_buff, &_io_impl->transport), + offsetof(usrp_transfer_frame, buf) + ); +} diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.cpp b/host/lib/usrp/usrp_e/usrp_e_iface.cpp index 98d8ef478..21e91452f 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.cpp @@ -29,6 +29,10 @@ using namespace uhd; class usrp_e_iface_impl : public usrp_e_iface{ public: + int get_file_descriptor(void){ + return _node_fd; + } + /******************************************************************* * Structors ******************************************************************/ diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.hpp b/host/lib/usrp/usrp_e/usrp_e_iface.hpp index 6363a24b2..59aac43d9 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.hpp @@ -49,6 +49,12 @@ public: */ static sptr make(const std::string &node); + /*! + * Get the underlying file descriptor. + * \return the file descriptor + */ + virtual int get_file_descriptor(void) = 0; + /*! * Perform an ioctl call on the device node file descriptor. * This will throw when the internal ioctl call fails. diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 4a398e21c..f9af36887 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -89,6 +89,9 @@ usrp_e_impl::usrp_e_impl(const std::string &node){ //initialize the dsps rx_ddc_init(); tx_duc_init(); + + //init the io send/recv + io_init(); } usrp_e_impl::~usrp_e_impl(void){ @@ -127,30 +130,3 @@ void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ void usrp_e_impl::set(const wax::obj &, const wax::obj &){ UHD_THROW_PROP_SET_ERROR(); } - -/*********************************************************************** - * Device IO (TODO) - **********************************************************************/ -size_t usrp_e_impl::send( - const boost::asio::const_buffer &, - const uhd::tx_metadata_t &, - const io_type_t &, - send_mode_t -){ - if (true){ - throw std::runtime_error(str(boost::format("usrp-e send: cannot handle type \"%s\"") % "")); - } - return 0; -} - -size_t usrp_e_impl::recv( - const boost::asio::mutable_buffer &, - uhd::rx_metadata_t &, - const io_type_t &, - recv_mode_t -){ - if (true){ - throw std::runtime_error(str(boost::format("usrp-e recv: cannot handle type \"%s\"") % "")); - } - return 0; -} diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index a2cdbc31e..12d4c9d9e 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -18,6 +18,7 @@ #include "usrp_e_iface.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" +#include #include #include #include @@ -55,26 +56,11 @@ public: return sptr(new wax_obj_proxy(get, set)); } - ~wax_obj_proxy(void){ - /* NOP */ - } - private: - get_t _get; - set_t _set; - - wax_obj_proxy(const get_t &get, const set_t &set){ - _get = get; - _set = set; - }; - - void get(const wax::obj &key, wax::obj &val){ - return _get(key, val); - } - - void set(const wax::obj &key, const wax::obj &val){ - return _set(key, val); - } + get_t _get; set_t _set; + wax_obj_proxy(const get_t &get, const set_t &set): _get(get), _set(set){}; + void get(const wax::obj &key, wax::obj &val){return _get(key, val);} + void set(const wax::obj &key, const wax::obj &val){return _set(key, val);} }; /*! @@ -95,10 +81,19 @@ public: size_t get_max_recv_samps_per_packet(void) const{return _max_num_samples;} private: - static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); + //interface to ioctls and file descriptor usrp_e_iface::sptr _iface; + //FIXME fetch from ioctl? + static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); + + //handle io stuff + UHD_PIMPL_DECL(io_impl) _io_impl; + void io_init(void); + + //configuration shadows uhd::clock_config_t _clock_config; + //TODO otw type recv/send //ad9522 clock control clock_ctrl::sptr _clock_ctrl; -- cgit v1.2.3 From fcdbea4f089db2405820ad598979e639cf131ff5 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 4 Jun 2010 01:58:12 +0000 Subject: io impl tweaks, renamed clock control and codec control implementation to avoid collision with usrp2 (those need to be renamed as well) --- host/lib/usrp/usrp_e/clock_ctrl.cpp | 18 +++++++++--------- host/lib/usrp/usrp_e/codec_ctrl.cpp | 20 ++++++++++---------- host/lib/usrp/usrp_e/dsp_impl.cpp | 24 ++++++++++++++++++++++++ host/lib/usrp/usrp_e/io_impl.cpp | 16 ++++++++++++---- 4 files changed, 55 insertions(+), 23 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 5f7269412..7947930a0 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -29,11 +29,11 @@ using namespace uhd; /*********************************************************************** * Clock Control Implementation **********************************************************************/ -class clock_ctrl_impl : public clock_ctrl{ +class usrp_e_clock_ctrl_impl : public clock_ctrl{ public: //structors - clock_ctrl_impl(usrp_e_iface::sptr iface); - ~clock_ctrl_impl(void); + usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface); + ~usrp_e_clock_ctrl_impl(void); void enable_rx_dboard_clock(bool enb); void enable_tx_dboard_clock(bool enb); @@ -56,7 +56,7 @@ private: /*********************************************************************** * Clock Control Methods **********************************************************************/ -clock_ctrl_impl::clock_ctrl_impl(usrp_e_iface::sptr iface){ +usrp_e_clock_ctrl_impl::usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface){ _iface = iface; //init the clock gen registers @@ -126,12 +126,12 @@ clock_ctrl_impl::clock_ctrl_impl(usrp_e_iface::sptr iface){ this->enable_tx_dboard_clock(false); } -clock_ctrl_impl::~clock_ctrl_impl(void){ +usrp_e_clock_ctrl_impl::~usrp_e_clock_ctrl_impl(void){ this->enable_rx_dboard_clock(false); this->enable_tx_dboard_clock(false); } -void clock_ctrl_impl::enable_rx_dboard_clock(bool enb){ +void usrp_e_clock_ctrl_impl::enable_rx_dboard_clock(bool enb){ _ad9522_regs.out9_format = ad9522_regs_t::OUT9_FORMAT_CMOS; _ad9522_regs.out9_cmos_configuration = (enb)? ad9522_regs_t::OUT9_CMOS_CONFIGURATION_B_ON : @@ -144,7 +144,7 @@ void clock_ctrl_impl::enable_rx_dboard_clock(bool enb){ this->latch_regs(); } -void clock_ctrl_impl::enable_tx_dboard_clock(bool enb){ +void usrp_e_clock_ctrl_impl::enable_tx_dboard_clock(bool enb){ _ad9522_regs.out6_format = ad9522_regs_t::OUT6_FORMAT_CMOS; _ad9522_regs.out6_cmos_configuration = (enb)? ad9522_regs_t::OUT6_CMOS_CONFIGURATION_B_ON : @@ -157,7 +157,7 @@ void clock_ctrl_impl::enable_tx_dboard_clock(bool enb){ this->latch_regs(); } -void clock_ctrl_impl::send_reg(boost::uint16_t addr){ +void usrp_e_clock_ctrl_impl::send_reg(boost::uint16_t addr){ boost::uint32_t reg = _ad9522_regs.get_write_reg(addr); //std::cout << "clock control write reg: " << std::hex << reg << std::endl; _iface->transact_spi( @@ -171,5 +171,5 @@ void clock_ctrl_impl::send_reg(boost::uint16_t addr){ * Clock Control Make **********************************************************************/ clock_ctrl::sptr clock_ctrl::make(usrp_e_iface::sptr iface){ - return sptr(new clock_ctrl_impl(iface)); + return sptr(new usrp_e_clock_ctrl_impl(iface)); } diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index ce05ac9eb..e86fde346 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -34,11 +34,11 @@ static const bool codec_debug = true; /*********************************************************************** * Codec Control Implementation **********************************************************************/ -class codec_ctrl_impl : public codec_ctrl{ +class usrp_e_codec_ctrl_impl : public codec_ctrl{ public: //structors - codec_ctrl_impl(usrp_e_iface::sptr iface); - ~codec_ctrl_impl(void); + usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface); + ~usrp_e_codec_ctrl_impl(void); //aux adc and dac control float read_aux_adc(aux_adc_t which); @@ -55,7 +55,7 @@ private: /*********************************************************************** * Codec Control Structors **********************************************************************/ -codec_ctrl_impl::codec_ctrl_impl(usrp_e_iface::sptr iface){ +usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ _iface = iface; //FIXME temp poke !!! @@ -107,7 +107,7 @@ codec_ctrl_impl::codec_ctrl_impl(usrp_e_iface::sptr iface){ this->send_reg(34); } -codec_ctrl_impl::~codec_ctrl_impl(void){ +usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){ return; //FIXME remove this later //set aux dacs to zero @@ -131,7 +131,7 @@ static float aux_adc_to_volts(boost::uint8_t high, boost::uint8_t low){ return float((boost::uint16_t(high) << 2) | low)*3.3/0x3ff; } -float codec_ctrl_impl::read_aux_adc(aux_adc_t which){ +float usrp_e_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ //check to see if the switch needs to be set bool write_switch = false; switch(which){ @@ -184,7 +184,7 @@ float codec_ctrl_impl::read_aux_adc(aux_adc_t which){ /*********************************************************************** * Codec Control AUX DAC Methods **********************************************************************/ -void codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ +void usrp_e_codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ //special case for aux dac d (aka sigma delta word) if (which == AUX_DAC_D){ boost::uint16_t dac_word = std::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); @@ -217,7 +217,7 @@ void codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ /*********************************************************************** * Codec Control SPI Methods **********************************************************************/ -void codec_ctrl_impl::send_reg(boost::uint8_t addr){ +void usrp_e_codec_ctrl_impl::send_reg(boost::uint8_t addr){ boost::uint32_t reg = _ad9862_regs.get_write_reg(addr); if (codec_debug) std::cout << "codec control write reg: " << std::hex << reg << std::endl; _iface->transact_spi( @@ -227,7 +227,7 @@ void codec_ctrl_impl::send_reg(boost::uint8_t addr){ ); } -void codec_ctrl_impl::recv_reg(boost::uint8_t addr){ +void usrp_e_codec_ctrl_impl::recv_reg(boost::uint8_t addr){ boost::uint32_t reg = _ad9862_regs.get_read_reg(addr); if (codec_debug) std::cout << "codec control read reg: " << std::hex << reg << std::endl; boost::uint32_t ret = _iface->transact_spi( @@ -243,5 +243,5 @@ void codec_ctrl_impl::recv_reg(boost::uint8_t addr){ * Codec Control Make **********************************************************************/ codec_ctrl::sptr codec_ctrl::make(usrp_e_iface::sptr iface){ - return sptr(new codec_ctrl_impl(iface)); + return sptr(new usrp_e_codec_ctrl_impl(iface)); } diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp index 272ac71b3..e61f529ab 100644 --- a/host/lib/usrp/usrp_e/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -20,6 +20,30 @@ using namespace uhd::usrp; +/*********************************************************************** + * Helper Functions + **********************************************************************/ +// Check if requested decim/interp rate is: +// multiple of 4, enable two halfband filters +// multiple of 2, enable one halfband filter +// handle remainder in CIC +static boost::uint32_t calculate_cic_word(size_t rate){ + int hb0 = 0, hb1 = 0; + if (not (rate & 0x1)){ + hb0 = 1; + rate /= 2; + } + if (not (rate & 0x1)){ + hb1 = 1; + rate /= 2; + } + return (hb1 << 9) | (hb0 << 8) | (rate & 0xff); +} + +static boost::uint32_t calculate_iq_scale_word(boost::int16_t i, boost::int16_t q){ + return (boost::uint16_t(i) << 16) | (boost::uint16_t(q) << 0); +} + /*********************************************************************** * RX DDC Initialization **********************************************************************/ diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 5bb40723e..f83829cb8 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -24,6 +24,8 @@ using namespace uhd; +static const size_t MAX_BUFF_SIZE = 2048; + /*********************************************************************** * Data Transport (phony zero-copy with read/write) **********************************************************************/ @@ -33,8 +35,8 @@ class data_transport: { public: data_transport(int fd): - transport::phony_zero_copy_recv_if(2048), //FIXME magic # - transport::phony_zero_copy_send_if(2048), //FIXME magic # + transport::phony_zero_copy_recv_if(MAX_BUFF_SIZE), + transport::phony_zero_copy_send_if(MAX_BUFF_SIZE), _fd(fd) { /* NOP */ @@ -51,6 +53,13 @@ public: private: int _fd; size_t send(const boost::asio::const_buffer &buff){ + //Set the frame length in the frame header. + //This is technically bad to write to a const buffer, + //but this will go away when the ring gets implemented, + //and the send buffer commit method will set the length. + const_cast( + boost::asio::buffer_cast(buff) + )->len = boost::asio::buffer_size(buff); return write( _fd, boost::asio::buffer_cast(buff), @@ -103,9 +112,8 @@ size_t usrp_e_impl::send( send_otw_type, //TODO 64e6, //TODO boost::bind(&data_transport::get_send_buff, &_io_impl->transport), - _max_num_samples, //TODO + (MAX_BUFF_SIZE - sizeof(usrp_transfer_frame))/send_otw_type.get_sample_size(), offsetof(usrp_transfer_frame, buf) - //TODO probably need callback to fill in frame size ); } -- cgit v1.2.3 From 685cf432a373ee7556db507f7958f51e6ccf581a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 4 Jun 2010 21:13:27 +0000 Subject: prefixed helper classes with usrp_e to avoid collision --- host/lib/usrp/usrp_e/clock_ctrl.cpp | 4 ++-- host/lib/usrp/usrp_e/clock_ctrl.hpp | 4 ++-- host/lib/usrp/usrp_e/codec_ctrl.cpp | 4 ++-- host/lib/usrp/usrp_e/codec_ctrl.hpp | 4 ++-- host/lib/usrp/usrp_e/dboard_iface.cpp | 28 ++++++++++++++-------------- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 4 ++-- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 8 ++++---- 7 files changed, 28 insertions(+), 28 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 7947930a0..e37b17a54 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -29,7 +29,7 @@ using namespace uhd; /*********************************************************************** * Clock Control Implementation **********************************************************************/ -class usrp_e_clock_ctrl_impl : public clock_ctrl{ +class usrp_e_clock_ctrl_impl : public usrp_e_clock_ctrl{ public: //structors usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface); @@ -170,6 +170,6 @@ void usrp_e_clock_ctrl_impl::send_reg(boost::uint16_t addr){ /*********************************************************************** * Clock Control Make **********************************************************************/ -clock_ctrl::sptr clock_ctrl::make(usrp_e_iface::sptr iface){ +usrp_e_clock_ctrl::sptr usrp_e_clock_ctrl::make(usrp_e_iface::sptr iface){ return sptr(new usrp_e_clock_ctrl_impl(iface)); } diff --git a/host/lib/usrp/usrp_e/clock_ctrl.hpp b/host/lib/usrp/usrp_e/clock_ctrl.hpp index 994b83564..692b9eb0e 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.hpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.hpp @@ -27,9 +27,9 @@ * - Setup system clocks. * - Disable/enable clock lines. */ -class clock_ctrl : boost::noncopyable{ +class usrp_e_clock_ctrl : boost::noncopyable{ public: - typedef boost::shared_ptr sptr; + typedef boost::shared_ptr sptr; /*! * Make a new clock control object. diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index e86fde346..b19606020 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -34,7 +34,7 @@ static const bool codec_debug = true; /*********************************************************************** * Codec Control Implementation **********************************************************************/ -class usrp_e_codec_ctrl_impl : public codec_ctrl{ +class usrp_e_codec_ctrl_impl : public usrp_e_codec_ctrl{ public: //structors usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface); @@ -242,6 +242,6 @@ void usrp_e_codec_ctrl_impl::recv_reg(boost::uint8_t addr){ /*********************************************************************** * Codec Control Make **********************************************************************/ -codec_ctrl::sptr codec_ctrl::make(usrp_e_iface::sptr iface){ +usrp_e_codec_ctrl::sptr usrp_e_codec_ctrl::make(usrp_e_iface::sptr iface){ return sptr(new usrp_e_codec_ctrl_impl(iface)); } diff --git a/host/lib/usrp/usrp_e/codec_ctrl.hpp b/host/lib/usrp/usrp_e/codec_ctrl.hpp index efdcd7142..b9005a82d 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.hpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.hpp @@ -27,9 +27,9 @@ * - Init/power down codec. * - Read aux adc, write aux dac. */ -class codec_ctrl : boost::noncopyable{ +class usrp_e_codec_ctrl : boost::noncopyable{ public: - typedef boost::shared_ptr sptr; + typedef boost::shared_ptr sptr; /*! * Make a new clock control object. diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp index 23255b58c..594f2a23e 100644 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -34,8 +34,8 @@ public: usrp_e_dboard_iface( usrp_e_iface::sptr iface, - clock_ctrl::sptr clock, - codec_ctrl::sptr codec + usrp_e_clock_ctrl::sptr clock, + usrp_e_codec_ctrl::sptr codec ){ _iface = iface; _clock = clock; @@ -77,8 +77,8 @@ public: private: usrp_e_iface::sptr _iface; - clock_ctrl::sptr _clock; - codec_ctrl::sptr _codec; + usrp_e_clock_ctrl::sptr _clock; + usrp_e_codec_ctrl::sptr _codec; }; /*********************************************************************** @@ -86,8 +86,8 @@ private: **********************************************************************/ dboard_iface::sptr make_usrp_e_dboard_iface( usrp_e_iface::sptr iface, - clock_ctrl::sptr clock, - codec_ctrl::sptr codec + usrp_e_clock_ctrl::sptr clock, + usrp_e_codec_ctrl::sptr codec ){ return dboard_iface::sptr(new usrp_e_dboard_iface(iface, clock, codec)); } @@ -214,24 +214,24 @@ byte_vector_t usrp_e_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_byte **********************************************************************/ void usrp_e_dboard_iface::write_aux_dac(dboard_iface::unit_t, int which, float value){ //same aux dacs for each unit - static const uhd::dict which_to_aux_dac = map_list_of - (0, codec_ctrl::AUX_DAC_A) (1, codec_ctrl::AUX_DAC_B) - (2, codec_ctrl::AUX_DAC_C) (3, codec_ctrl::AUX_DAC_D) + static const uhd::dict which_to_aux_dac = map_list_of + (0, usrp_e_codec_ctrl::AUX_DAC_A) (1, usrp_e_codec_ctrl::AUX_DAC_B) + (2, usrp_e_codec_ctrl::AUX_DAC_C) (3, usrp_e_codec_ctrl::AUX_DAC_D) ; _codec->write_aux_dac(which_to_aux_dac[which], value); } float usrp_e_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, int which){ static const uhd::dict< - unit_t, uhd::dict + unit_t, uhd::dict > unit_to_which_to_aux_adc = map_list_of (UNIT_RX, map_list_of - (0, codec_ctrl::AUX_ADC_A1) - (1, codec_ctrl::AUX_ADC_B1) + (0, usrp_e_codec_ctrl::AUX_ADC_A1) + (1, usrp_e_codec_ctrl::AUX_ADC_B1) ) (UNIT_TX, map_list_of - (0, codec_ctrl::AUX_ADC_A2) - (1, codec_ctrl::AUX_ADC_B2) + (0, usrp_e_codec_ctrl::AUX_ADC_A2) + (1, usrp_e_codec_ctrl::AUX_ADC_B2) ) ; return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]); diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index f9af36887..226825510 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -77,8 +77,8 @@ usrp_e_impl::usrp_e_impl(const std::string &node){ //setup various interfaces into hardware _iface = usrp_e_iface::make(node); - _clock_ctrl = clock_ctrl::make(_iface); - _codec_ctrl = codec_ctrl::make(_iface); + _clock_ctrl = usrp_e_clock_ctrl::make(_iface); + _codec_ctrl = usrp_e_codec_ctrl::make(_iface); //initialize the mboard mboard_init(); diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 12d4c9d9e..bdb1a675b 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -36,8 +36,8 @@ */ uhd::usrp::dboard_iface::sptr make_usrp_e_dboard_iface( usrp_e_iface::sptr iface, - clock_ctrl::sptr clock, - codec_ctrl::sptr codec + usrp_e_clock_ctrl::sptr clock, + usrp_e_codec_ctrl::sptr codec ); /*! @@ -96,10 +96,10 @@ private: //TODO otw type recv/send //ad9522 clock control - clock_ctrl::sptr _clock_ctrl; + usrp_e_clock_ctrl::sptr _clock_ctrl; //ad9862 codec control - codec_ctrl::sptr _codec_ctrl; + usrp_e_codec_ctrl::sptr _codec_ctrl; //device functions and settings void get(const wax::obj &, wax::obj &); -- cgit v1.2.3 From a5dca07971587e3b20e57924227c020f13bfd700 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 4 Jun 2010 22:44:06 +0000 Subject: implemented dsp and rx control --- host/lib/usrp/usrp_e/dsp_impl.cpp | 137 ++++++++++++++++++++++++++++++++--- host/lib/usrp/usrp_e/io_impl.cpp | 40 +++++++++- host/lib/usrp/usrp_e/mboard_impl.cpp | 12 ++- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 6 ++ 4 files changed, 182 insertions(+), 13 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp index e61f529ab..11d22d15f 100644 --- a/host/lib/usrp/usrp_e/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -15,14 +15,34 @@ // along with this program. If not, see . // -#include #include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" +#include +#include +#include +#include + +#define rint boost::math::iround +using namespace uhd; using namespace uhd::usrp; /*********************************************************************** * Helper Functions **********************************************************************/ +static boost::uint32_t calculate_freq_word_and_update_actual_freq(double &freq, double clock_freq){ + UHD_ASSERT_THROW(std::abs(freq) < clock_freq/2.0); + static const double scale_factor = std::pow(2.0, 32); + + //calculate the freq register word + boost::uint32_t freq_word = rint((freq / clock_freq) * scale_factor); + + //update the actual frequency + freq = (double(freq_word) / scale_factor) * clock_freq; + + return freq_word; +} + // Check if requested decim/interp rate is: // multiple of 4, enable two halfband filters // multiple of 2, enable one halfband filter @@ -57,15 +77,62 @@ void usrp_e_impl::rx_ddc_init(void){ /*********************************************************************** * RX DDC Get **********************************************************************/ -void usrp_e_impl::rx_ddc_get(const wax::obj &, wax::obj &){ - UHD_THROW_PROP_GET_ERROR(); +void usrp_e_impl::rx_ddc_get(const wax::obj &key, wax::obj &val){ + switch(key.as()){ + case DSP_PROP_NAME: + val = std::string("usrp-e ddc0"); + return; + + case DSP_PROP_OTHERS: + val = prop_names_t(); //empty + return; + + case DSP_PROP_FREQ_SHIFT: + val = _ddc_freq; + return; + + case DSP_PROP_CODEC_RATE: + val = MASTER_CLOCK_RATE; + return; + + case DSP_PROP_HOST_RATE: + val = MASTER_CLOCK_RATE/_ddc_decim; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } } /*********************************************************************** * RX DDC Set **********************************************************************/ -void usrp_e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); +void usrp_e_impl::rx_ddc_set(const wax::obj &key, const wax::obj &val){ + switch(key.as()){ + + case DSP_PROP_FREQ_SHIFT:{ + double new_freq = val.as(); + _iface->poke32(UE_REG_DSP_RX_FREQ, + calculate_freq_word_and_update_actual_freq(new_freq, MASTER_CLOCK_RATE) + ); + _ddc_freq = new_freq; //shadow + } + return; + + case DSP_PROP_HOST_RATE:{ + //set the decimation + _ddc_decim = rint(MASTER_CLOCK_RATE/val.as()); + _iface->poke32(UE_REG_DSP_RX_DECIM_RATE, calculate_cic_word(_ddc_decim)); + + //set the scaling + static const boost::int16_t default_rx_scale_iq = 1024; + _iface->poke32(UE_REG_DSP_RX_SCALE_IQ, + calculate_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq) + ); + } + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } } /*********************************************************************** @@ -81,13 +148,65 @@ void usrp_e_impl::tx_duc_init(void){ /*********************************************************************** * TX DUC Get **********************************************************************/ -void usrp_e_impl::tx_duc_get(const wax::obj &, wax::obj &){ - UHD_THROW_PROP_GET_ERROR(); +void usrp_e_impl::tx_duc_get(const wax::obj &key, wax::obj &val){ + switch(key.as()){ + case DSP_PROP_NAME: + val = std::string("usrp-e duc0"); + return; + + case DSP_PROP_OTHERS: + val = prop_names_t(); //empty + return; + + case DSP_PROP_FREQ_SHIFT: + val = _duc_freq; + return; + + case DSP_PROP_CODEC_RATE: + val = MASTER_CLOCK_RATE; + return; + + case DSP_PROP_HOST_RATE: + val = MASTER_CLOCK_RATE/_duc_interp; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } } /*********************************************************************** * TX DUC Set **********************************************************************/ -void usrp_e_impl::tx_duc_set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); +void usrp_e_impl::tx_duc_set(const wax::obj &key, const wax::obj &val){ + switch(key.as()){ + + case DSP_PROP_FREQ_SHIFT:{ + double new_freq = val.as(); + _iface->poke32(UE_REG_DSP_TX_FREQ, + calculate_freq_word_and_update_actual_freq(new_freq, MASTER_CLOCK_RATE) + ); + _duc_freq = new_freq; //shadow + } + return; + + case DSP_PROP_HOST_RATE:{ + _duc_interp = rint(MASTER_CLOCK_RATE/val.as()); + + // Calculate CIC interpolation (i.e., without halfband interpolators) + size_t tmp_interp = calculate_cic_word(_duc_interp) & 0xff; + + // Calculate closest multiplier constant to reverse gain absent scale multipliers + double interp_cubed = std::pow(double(tmp_interp), 3); + boost::int16_t scale = rint((4096*std::pow(2, ceil(log2(interp_cubed))))/(1.65*interp_cubed)); + + //set the interpolation + _iface->poke32(UE_REG_DSP_TX_INTERP_RATE, calculate_cic_word(_duc_interp)); + + //set the scaling + _iface->poke32(UE_REG_DSP_TX_SCALE_IQ, calculate_iq_scale_word(scale, scale)); + } + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } } diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index f83829cb8..5914bc613 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -16,6 +16,7 @@ // #include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" #include "../../transport/vrt_packet_handler.hpp" #include #include //read, write @@ -86,9 +87,44 @@ struct usrp_e_impl::io_impl{ }; void usrp_e_impl::io_init(void){ + //setup rx data path + _iface->poke32(UE_REG_CTRL_RX_NSAMPS_PER_PKT, 1000); //FIXME magic number + _iface->poke32(UE_REG_CTRL_RX_NCHANNELS, 1); + _iface->poke32(UE_REG_CTRL_RX_CLEAR_OVERRUN, 1); //reset + _iface->poke32(UE_REG_CTRL_RX_VRT_HEADER, 0 + | (0x1 << 28) //if data with stream id + | (0x1 << 26) //has trailer + | (0x3 << 22) //integer time other + | (0x1 << 20) //fractional time sample count + ); + _iface->poke32(UE_REG_CTRL_RX_VRT_STREAM_ID, 0); + _iface->poke32(UE_REG_CTRL_RX_VRT_TRAILER, 0); + _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface->get_file_descriptor())); } +static boost::uint32_t make_stream_cmd(bool now, bool chain, boost::uint32_t nsamps){ + return (((now)? 1 : 0) << 31) | (((chain)? 1 : 0) << 30) | nsamps; +} + +void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ + boost::uint32_t cmd = 0; + switch(stream_cmd.stream_mode){ + case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE: + cmd = make_stream_cmd(stream_cmd.stream_now, false, stream_cmd.num_samps); + break; + + case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE: + cmd = make_stream_cmd(stream_cmd.stream_now, true, stream_cmd.num_samps); + break; + + default: throw std::runtime_error("stream mode not implemented"); + } + _iface->poke32(UE_REG_CTRL_RX_STREAM_CMD, cmd); + _iface->poke32(UE_REG_CTRL_RX_TIME_SECS, stream_cmd.time_spec.secs); + _iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_ticks(MASTER_CLOCK_RATE)); +} + /*********************************************************************** * Data Send **********************************************************************/ @@ -110,7 +146,7 @@ size_t usrp_e_impl::send( send_mode, io_type, send_otw_type, //TODO - 64e6, //TODO + MASTER_CLOCK_RATE, boost::bind(&data_transport::get_send_buff, &_io_impl->transport), (MAX_BUFF_SIZE - sizeof(usrp_transfer_frame))/send_otw_type.get_sample_size(), offsetof(usrp_transfer_frame, buf) @@ -138,7 +174,7 @@ size_t usrp_e_impl::recv( recv_mode, io_type, recv_otw_type, //TODO - 64e6, //TODO + MASTER_CLOCK_RATE, boost::bind(&data_transport::get_recv_buff, &_io_impl->transport), offsetof(usrp_transfer_frame, buf) ); diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index 00ce4b782..efbde38ce 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -108,6 +108,14 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * Mboard Set **********************************************************************/ -void usrp_e_impl::mboard_set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); +void usrp_e_impl::mboard_set(const wax::obj &key, const wax::obj &val){ + //handle the get request conditioned on the key + switch(key.as()){ + + case MBOARD_PROP_STREAM_CMD: + issue_stream_cmd(val.as()); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } } diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index bdb1a675b..a9fd856fe 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -22,11 +22,14 @@ #include #include #include +#include #include #ifndef INCLUDED_USRP_E_IMPL_HPP #define INCLUDED_USRP_E_IMPL_HPP +static const double MASTER_CLOCK_RATE = 64e6; + /*! * Make a usrp-e dboard interface. * \param iface the usrp-e interface object @@ -90,6 +93,7 @@ private: //handle io stuff UHD_PIMPL_DECL(io_impl) _io_impl; void io_init(void); + void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd); //configuration shadows uhd::clock_config_t _clock_config; @@ -131,12 +135,14 @@ private: void rx_ddc_init(void); void rx_ddc_get(const wax::obj &, wax::obj &); void rx_ddc_set(const wax::obj &, const wax::obj &); + double _ddc_freq; size_t _ddc_decim; wax_obj_proxy::sptr _rx_ddc_proxy; //tx duc functions and settings void tx_duc_init(void); void tx_duc_get(const wax::obj &, wax::obj &); void tx_duc_set(const wax::obj &, const wax::obj &); + double _duc_freq; size_t _duc_interp; wax_obj_proxy::sptr _tx_duc_proxy; }; -- cgit v1.2.3 From a5cdd7a311edcb3afdc9673bd7f6ec84bf8e7b6c Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 5 Jun 2010 00:24:16 +0000 Subject: usrp-e more implementation, rx timed samples runs w/o error (no workie though) --- host/lib/usrp/usrp_e/dboard_impl.cpp | 116 +++++++++++++++++++++++++++++++---- host/lib/usrp/usrp_e/io_impl.cpp | 5 ++ host/lib/usrp/usrp_e/mboard_impl.cpp | 23 ++++--- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 3 + 4 files changed, 128 insertions(+), 19 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index 31f792306..22c4ac8b7 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -17,8 +17,11 @@ #include #include "usrp_e_impl.hpp" +#include +#include #include +using namespace uhd; using namespace uhd::usrp; /*********************************************************************** @@ -32,11 +35,11 @@ void usrp_e_impl::dboard_init(void){ std::cout << _tx_db_eeprom.id.to_pp_string() << std::endl; //create a new dboard interface and manager - dboard_iface::sptr dboard_iface( - make_usrp_e_dboard_iface(_iface, _clock_ctrl, _codec_ctrl) + _dboard_iface = make_usrp_e_dboard_iface( + _iface, _clock_ctrl, _codec_ctrl ); _dboard_manager = dboard_manager::make( - _rx_db_eeprom.id, _tx_db_eeprom.id, dboard_iface + _rx_db_eeprom.id, _tx_db_eeprom.id, _dboard_iface ); //setup the dboard proxies @@ -48,32 +51,123 @@ void usrp_e_impl::dboard_init(void){ boost::bind(&usrp_e_impl::tx_dboard_get, this, _1, _2), boost::bind(&usrp_e_impl::tx_dboard_set, this, _1, _2) ); + + //init the subdevs in use (use the first subdevice) + _rx_subdevs_in_use = prop_names_t(1, _dboard_manager->get_rx_subdev_names().at(0)); + //TODO update_rx_mux_config(); + + _tx_subdevs_in_use = prop_names_t(1, _dboard_manager->get_tx_subdev_names().at(0)); + //TODO update_tx_mux_config(); } /*********************************************************************** * RX Dboard Get **********************************************************************/ -void usrp_e_impl::rx_dboard_get(const wax::obj &, wax::obj &){ - UHD_THROW_PROP_GET_ERROR(); +void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case DBOARD_PROP_NAME: + val = std::string("usrp-e dboard (rx unit)"); + return; + + case DBOARD_PROP_SUBDEV: + val = _dboard_manager->get_rx_subdev(name); + return; + + case DBOARD_PROP_SUBDEV_NAMES: + val = _dboard_manager->get_rx_subdev_names(); + return; + + case DBOARD_PROP_USED_SUBDEVS: + val = _rx_subdevs_in_use; + return; + + case DBOARD_PROP_DBOARD_ID: + val = _rx_db_eeprom.id; + return; + + case DBOARD_PROP_DBOARD_IFACE: + val = _dboard_iface; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } } /*********************************************************************** * RX Dboard Set **********************************************************************/ -void usrp_e_impl::rx_dboard_set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); +void usrp_e_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ + switch(key.as()){ + case DBOARD_PROP_USED_SUBDEVS: + _rx_subdevs_in_use = val.as(); + //TODO update_rx_mux_config(); //if the val is bad, this will throw + return; + + case DBOARD_PROP_DBOARD_ID: + _rx_db_eeprom.id = val.as(); + _iface->write_eeprom(I2C_ADDR_RX_DB, 0, _rx_db_eeprom.get_eeprom_bytes()); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } } /*********************************************************************** * TX Dboard Get **********************************************************************/ -void usrp_e_impl::tx_dboard_get(const wax::obj &, wax::obj &){ - UHD_THROW_PROP_GET_ERROR(); +void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case DBOARD_PROP_NAME: + val = std::string("usrp-e dboard (tx unit)"); + return; + + case DBOARD_PROP_SUBDEV: + val = _dboard_manager->get_tx_subdev(name); + return; + + case DBOARD_PROP_SUBDEV_NAMES: + val = _dboard_manager->get_tx_subdev_names(); + return; + + case DBOARD_PROP_USED_SUBDEVS: + val = _tx_subdevs_in_use; + return; + + case DBOARD_PROP_DBOARD_ID: + val = _tx_db_eeprom.id; + return; + + case DBOARD_PROP_DBOARD_IFACE: + val = _dboard_iface; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } } /*********************************************************************** * TX Dboard Set **********************************************************************/ -void usrp_e_impl::tx_dboard_set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); +void usrp_e_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ + switch(key.as()){ + case DBOARD_PROP_USED_SUBDEVS: + _tx_subdevs_in_use = val.as(); + //TODO update_tx_mux_config(); //if the val is bad, this will throw + return; + + case DBOARD_PROP_DBOARD_ID: + _tx_db_eeprom.id = val.as(); + _iface->write_eeprom(I2C_ADDR_TX_DB, 0, _tx_db_eeprom.get_eeprom_bytes()); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } } diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 5914bc613..9ebc5b560 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -22,6 +22,8 @@ #include //read, write #include //transfer frame struct #include //offsetof +#include +#include using namespace uhd; @@ -68,6 +70,9 @@ private: ); } size_t recv(const boost::asio::mutable_buffer &buff){ + std::cout << boost::format( + "calling read on fd %d, buff size is %d" + ) % _fd % boost::asio::buffer_size(buff) << std::endl; return read( _fd, boost::asio::buffer_cast(buff), diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index efbde38ce..e4a0e81af 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -16,6 +16,7 @@ // #include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" #include #include #include @@ -75,26 +76,22 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ val = prop_names_t(1, ""); //vector of size 1 with empty string return; - case MBOARD_PROP_STREAM_CMD: - //val = TODO - return; - case MBOARD_PROP_RX_DSP: - UHD_ASSERT_THROW(name == "ddc0"); + UHD_ASSERT_THROW(name == ""); val = _rx_ddc_proxy->get_link(); return; case MBOARD_PROP_RX_DSP_NAMES: - val = prop_names_t(1, "ddc0"); + val = prop_names_t(1, ""); return; case MBOARD_PROP_TX_DSP: - UHD_ASSERT_THROW(name == "duc0"); + UHD_ASSERT_THROW(name == ""); val = _tx_duc_proxy->get_link(); return; case MBOARD_PROP_TX_DSP_NAMES: - val = prop_names_t(1, "duc0"); + val = prop_names_t(1, ""); return; case MBOARD_PROP_CLOCK_CONFIG: @@ -116,6 +113,16 @@ void usrp_e_impl::mboard_set(const wax::obj &key, const wax::obj &val){ issue_stream_cmd(val.as()); return; + case MBOARD_PROP_TIME_NOW: + case MBOARD_PROP_TIME_NEXT_PPS:{ + time_spec_t time_spec = val.as(); + _iface->poke32(UE_REG_TIME64_TICKS, time_spec.get_ticks(MASTER_CLOCK_RATE)); + boost::uint32_t imm_flags = (key.as() == MBOARD_PROP_TIME_NOW)? 1 : 0; + _iface->poke32(UE_REG_TIME64_IMM, imm_flags); + _iface->poke32(UE_REG_TIME64_SECS, time_spec.secs); + } + return; + default: UHD_THROW_PROP_SET_ERROR(); } } diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index a9fd856fe..657d2d225 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -118,17 +118,20 @@ private: //xx dboard functions and settings void dboard_init(void); uhd::usrp::dboard_manager::sptr _dboard_manager; + uhd::usrp::dboard_iface::sptr _dboard_iface; //rx dboard functions and settings uhd::usrp::dboard_eeprom_t _rx_db_eeprom; void rx_dboard_get(const wax::obj &, wax::obj &); void rx_dboard_set(const wax::obj &, const wax::obj &); + uhd::prop_names_t _rx_subdevs_in_use; wax_obj_proxy::sptr _rx_dboard_proxy; //tx dboard functions and settings uhd::usrp::dboard_eeprom_t _tx_db_eeprom; void tx_dboard_get(const wax::obj &, wax::obj &); void tx_dboard_set(const wax::obj &, const wax::obj &); + uhd::prop_names_t _tx_subdevs_in_use; wax_obj_proxy::sptr _tx_dboard_proxy; //rx ddc functions and settings -- cgit v1.2.3 From 7332fc3198a81d9f747ea2a033c1cca168858944 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 5 Jun 2010 01:35:19 +0000 Subject: recv giving me something, bad vrt headers though... --- host/lib/usrp/usrp_e/io_impl.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 9ebc5b560..7c451a75f 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -73,11 +73,14 @@ private: std::cout << boost::format( "calling read on fd %d, buff size is %d" ) % _fd % boost::asio::buffer_size(buff) << std::endl; - return read( + ssize_t ret = read( _fd, boost::asio::buffer_cast(buff), boost::asio::buffer_size(buff) ); + if (ret < ssize_t(sizeof(usrp_transfer_frame))) return 0; + std::cout << "len " << int(boost::asio::buffer_cast(buff)->len) << std::endl; + return boost::asio::buffer_cast(buff)->len; } }; @@ -93,7 +96,7 @@ struct usrp_e_impl::io_impl{ void usrp_e_impl::io_init(void){ //setup rx data path - _iface->poke32(UE_REG_CTRL_RX_NSAMPS_PER_PKT, 1000); //FIXME magic number + _iface->poke32(UE_REG_CTRL_RX_NSAMPS_PER_PKT, 300); //FIXME magic number _iface->poke32(UE_REG_CTRL_RX_NCHANNELS, 1); _iface->poke32(UE_REG_CTRL_RX_CLEAR_OVERRUN, 1); //reset _iface->poke32(UE_REG_CTRL_RX_VRT_HEADER, 0 @@ -142,7 +145,7 @@ size_t usrp_e_impl::send( otw_type_t send_otw_type; send_otw_type.width = 16; send_otw_type.shift = 0; - send_otw_type.byteorder = otw_type_t::BO_NATIVE; + send_otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN; return vrt_packet_handler::send( _io_impl->send_state, @@ -170,7 +173,7 @@ size_t usrp_e_impl::recv( otw_type_t recv_otw_type; recv_otw_type.width = 16; recv_otw_type.shift = 0; - recv_otw_type.byteorder = otw_type_t::BO_NATIVE; + recv_otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN; return vrt_packet_handler::recv( _io_impl->recv_state, -- cgit v1.2.3 From cd84a19214ea03a3615b5ac7997f33fcfc9870ae Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 7 Jun 2010 22:51:02 +0000 Subject: usrp-e: working vrt recv, implemented dsp utils in usrp-e dsp --- host/lib/usrp/usrp_e/codec_ctrl.cpp | 2 +- host/lib/usrp/usrp_e/dsp_impl.cpp | 59 +++++-------------------------------- host/lib/usrp/usrp_e/io_impl.cpp | 27 ++++++++++++----- 3 files changed, 28 insertions(+), 60 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index b19606020..ce3458827 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -29,7 +29,7 @@ using namespace uhd; -static const bool codec_debug = true; +static const bool codec_debug = false; /*********************************************************************** * Codec Control Implementation diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp index 11d22d15f..a87a41ca6 100644 --- a/host/lib/usrp/usrp_e/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -17,53 +17,15 @@ #include "usrp_e_impl.hpp" #include "usrp_e_regs.hpp" +#include "../dsp_utils.hpp" #include -#include #include -#include #define rint boost::math::iround using namespace uhd; using namespace uhd::usrp; -/*********************************************************************** - * Helper Functions - **********************************************************************/ -static boost::uint32_t calculate_freq_word_and_update_actual_freq(double &freq, double clock_freq){ - UHD_ASSERT_THROW(std::abs(freq) < clock_freq/2.0); - static const double scale_factor = std::pow(2.0, 32); - - //calculate the freq register word - boost::uint32_t freq_word = rint((freq / clock_freq) * scale_factor); - - //update the actual frequency - freq = (double(freq_word) / scale_factor) * clock_freq; - - return freq_word; -} - -// Check if requested decim/interp rate is: -// multiple of 4, enable two halfband filters -// multiple of 2, enable one halfband filter -// handle remainder in CIC -static boost::uint32_t calculate_cic_word(size_t rate){ - int hb0 = 0, hb1 = 0; - if (not (rate & 0x1)){ - hb0 = 1; - rate /= 2; - } - if (not (rate & 0x1)){ - hb1 = 1; - rate /= 2; - } - return (hb1 << 9) | (hb0 << 8) | (rate & 0xff); -} - -static boost::uint32_t calculate_iq_scale_word(boost::int16_t i, boost::int16_t q){ - return (boost::uint16_t(i) << 16) | (boost::uint16_t(q) << 0); -} - /*********************************************************************** * RX DDC Initialization **********************************************************************/ @@ -112,7 +74,7 @@ void usrp_e_impl::rx_ddc_set(const wax::obj &key, const wax::obj &val){ case DSP_PROP_FREQ_SHIFT:{ double new_freq = val.as(); _iface->poke32(UE_REG_DSP_RX_FREQ, - calculate_freq_word_and_update_actual_freq(new_freq, MASTER_CLOCK_RATE) + dsp_type1::calc_cordic_word_and_update(new_freq, MASTER_CLOCK_RATE) ); _ddc_freq = new_freq; //shadow } @@ -121,12 +83,12 @@ void usrp_e_impl::rx_ddc_set(const wax::obj &key, const wax::obj &val){ case DSP_PROP_HOST_RATE:{ //set the decimation _ddc_decim = rint(MASTER_CLOCK_RATE/val.as()); - _iface->poke32(UE_REG_DSP_RX_DECIM_RATE, calculate_cic_word(_ddc_decim)); + _iface->poke32(UE_REG_DSP_RX_DECIM_RATE, dsp_type1::calc_cic_filter_word(_ddc_decim)); //set the scaling static const boost::int16_t default_rx_scale_iq = 1024; _iface->poke32(UE_REG_DSP_RX_SCALE_IQ, - calculate_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq) + dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq) ); } return; @@ -183,7 +145,7 @@ void usrp_e_impl::tx_duc_set(const wax::obj &key, const wax::obj &val){ case DSP_PROP_FREQ_SHIFT:{ double new_freq = val.as(); _iface->poke32(UE_REG_DSP_TX_FREQ, - calculate_freq_word_and_update_actual_freq(new_freq, MASTER_CLOCK_RATE) + dsp_type1::calc_cordic_word_and_update(new_freq, MASTER_CLOCK_RATE) ); _duc_freq = new_freq; //shadow } @@ -192,18 +154,11 @@ void usrp_e_impl::tx_duc_set(const wax::obj &key, const wax::obj &val){ case DSP_PROP_HOST_RATE:{ _duc_interp = rint(MASTER_CLOCK_RATE/val.as()); - // Calculate CIC interpolation (i.e., without halfband interpolators) - size_t tmp_interp = calculate_cic_word(_duc_interp) & 0xff; - - // Calculate closest multiplier constant to reverse gain absent scale multipliers - double interp_cubed = std::pow(double(tmp_interp), 3); - boost::int16_t scale = rint((4096*std::pow(2, ceil(log2(interp_cubed))))/(1.65*interp_cubed)); - //set the interpolation - _iface->poke32(UE_REG_DSP_TX_INTERP_RATE, calculate_cic_word(_duc_interp)); + _iface->poke32(UE_REG_DSP_TX_INTERP_RATE, dsp_type1::calc_cic_filter_word(_duc_interp)); //set the scaling - _iface->poke32(UE_REG_DSP_TX_SCALE_IQ, calculate_iq_scale_word(scale, scale)); + _iface->poke32(UE_REG_DSP_TX_SCALE_IQ, dsp_type1::calc_iq_scale_word(_duc_interp)); } return; diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 7c451a75f..d26f113f5 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -29,6 +29,8 @@ using namespace uhd; static const size_t MAX_BUFF_SIZE = 2048; +static const size_t vrt_header_offset_words32 = offsetof(usrp_transfer_frame, buf)/sizeof(boost::uint32_t); + /*********************************************************************** * Data Transport (phony zero-copy with read/write) **********************************************************************/ @@ -70,17 +72,26 @@ private: ); } size_t recv(const boost::asio::mutable_buffer &buff){ - std::cout << boost::format( - "calling read on fd %d, buff size is %d" - ) % _fd % boost::asio::buffer_size(buff) << std::endl; + //std::cout << boost::format( + // "calling read on fd %d, buff size is %d" + //) % _fd % boost::asio::buffer_size(buff) << std::endl; ssize_t ret = read( _fd, boost::asio::buffer_cast(buff), boost::asio::buffer_size(buff) ); if (ret < ssize_t(sizeof(usrp_transfer_frame))) return 0; - std::cout << "len " << int(boost::asio::buffer_cast(buff)->len) << std::endl; - return boost::asio::buffer_cast(buff)->len; + //overwrite the vrt header length with the transfer frame length + size_t frame_size = boost::asio::buffer_cast(buff)->len; + boost::uint32_t *vrt_header = boost::asio::buffer_cast(buff) + vrt_header_offset_words32; + vrt_header[0] = (vrt_header[0] & ~0xffff) | ((frame_size/sizeof(boost::uint32_t)) & 0xffff); + + //std::cout << "len " << int(boost::asio::buffer_cast(buff)->len) << std::endl; + //for (size_t i = 0; i < 7; i++){ + // std::cout << boost::format(" 0x%08x") % boost::asio::buffer_cast(buff)[i] << std::endl; + //} + + return frame_size; } }; @@ -155,9 +166,10 @@ size_t usrp_e_impl::send( io_type, send_otw_type, //TODO MASTER_CLOCK_RATE, + uhd::transport::vrt::pack_le, boost::bind(&data_transport::get_send_buff, &_io_impl->transport), (MAX_BUFF_SIZE - sizeof(usrp_transfer_frame))/send_otw_type.get_sample_size(), - offsetof(usrp_transfer_frame, buf) + vrt_header_offset_words32 ); } @@ -183,7 +195,8 @@ size_t usrp_e_impl::recv( io_type, recv_otw_type, //TODO MASTER_CLOCK_RATE, + uhd::transport::vrt::unpack_le, boost::bind(&data_transport::get_recv_buff, &_io_impl->transport), - offsetof(usrp_transfer_frame, buf) + vrt_header_offset_words32 ); } -- cgit v1.2.3 From c8e2670b63ec4e7dbec1549dbc452dfeacecf07d Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 9 Jun 2010 01:05:14 +0000 Subject: usrp-e: switched otw type to little endian (works now) --- host/lib/usrp/usrp_e/io_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index d26f113f5..a94275b78 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -156,7 +156,7 @@ size_t usrp_e_impl::send( otw_type_t send_otw_type; send_otw_type.width = 16; send_otw_type.shift = 0; - send_otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN; + send_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; return vrt_packet_handler::send( _io_impl->send_state, @@ -185,7 +185,7 @@ size_t usrp_e_impl::recv( otw_type_t recv_otw_type; recv_otw_type.width = 16; recv_otw_type.shift = 0; - recv_otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN; + recv_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; return vrt_packet_handler::recv( _io_impl->recv_state, -- cgit v1.2.3 From 71783634c4394e739bbc13a9bb3df7d6ab75c147 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 10 Jun 2010 18:25:42 +0000 Subject: installed mux setting and initing the duc and ddc --- host/lib/usrp/usrp_e/dboard_impl.cpp | 40 ++++++++++++++++++++++-------------- host/lib/usrp/usrp_e/dsp_impl.cpp | 8 ++++++++ host/lib/usrp/usrp_e/usrp_e_regs.hpp | 3 ++- 3 files changed, 35 insertions(+), 16 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index 22c4ac8b7..a384c71a0 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -15,10 +15,13 @@ // along with this program. If not, see . // -#include #include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" +#include "../dsp_utils.hpp" #include #include +#include +#include #include using namespace uhd; @@ -31,9 +34,6 @@ void usrp_e_impl::dboard_init(void){ _rx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes())); _tx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_TX_DB, 0, dboard_eeprom_t::num_bytes())); - std::cout << _rx_db_eeprom.id.to_pp_string() << std::endl; - std::cout << _tx_db_eeprom.id.to_pp_string() << std::endl; - //create a new dboard interface and manager _dboard_iface = make_usrp_e_dboard_iface( _iface, _clock_ctrl, _codec_ctrl @@ -53,11 +53,8 @@ void usrp_e_impl::dboard_init(void){ ); //init the subdevs in use (use the first subdevice) - _rx_subdevs_in_use = prop_names_t(1, _dboard_manager->get_rx_subdev_names().at(0)); - //TODO update_rx_mux_config(); - - _tx_subdevs_in_use = prop_names_t(1, _dboard_manager->get_tx_subdev_names().at(0)); - //TODO update_tx_mux_config(); + rx_dboard_set(DBOARD_PROP_USED_SUBDEVS, prop_names_t(1, _dboard_manager->get_rx_subdev_names().at(0))); + tx_dboard_set(DBOARD_PROP_USED_SUBDEVS, prop_names_t(1, _dboard_manager->get_tx_subdev_names().at(0))); } /*********************************************************************** @@ -102,9 +99,16 @@ void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ **********************************************************************/ void usrp_e_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ switch(key.as()){ - case DBOARD_PROP_USED_SUBDEVS: - _rx_subdevs_in_use = val.as(); - //TODO update_rx_mux_config(); //if the val is bad, this will throw + case DBOARD_PROP_USED_SUBDEVS:{ + _rx_subdevs_in_use = val.as(); + UHD_ASSERT_THROW(_rx_subdevs_in_use.size() == 1); + wax::obj rx_subdev = _dboard_manager->get_rx_subdev(_rx_subdevs_in_use.at(0)); + std::cout << "Using: " << rx_subdev[SUBDEV_PROP_NAME].as() << std::endl; + _iface->poke32(UE_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word( + rx_subdev[SUBDEV_PROP_QUADRATURE].as(), + rx_subdev[SUBDEV_PROP_IQ_SWAPPED].as() + )); + } return; case DBOARD_PROP_DBOARD_ID: @@ -158,9 +162,15 @@ void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ **********************************************************************/ void usrp_e_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ switch(key.as()){ - case DBOARD_PROP_USED_SUBDEVS: - _tx_subdevs_in_use = val.as(); - //TODO update_tx_mux_config(); //if the val is bad, this will throw + case DBOARD_PROP_USED_SUBDEVS:{ + _tx_subdevs_in_use = val.as(); + UHD_ASSERT_THROW(_tx_subdevs_in_use.size() == 1); + wax::obj tx_subdev = _dboard_manager->get_tx_subdev(_tx_subdevs_in_use.at(0)); + std::cout << "Using: " << tx_subdev[SUBDEV_PROP_NAME].as() << std::endl; + _iface->poke32(UE_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word( + tx_subdev[SUBDEV_PROP_IQ_SWAPPED].as() + )); + } return; case DBOARD_PROP_DBOARD_ID: diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp index a87a41ca6..58a58706d 100644 --- a/host/lib/usrp/usrp_e/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -34,6 +34,10 @@ void usrp_e_impl::rx_ddc_init(void){ boost::bind(&usrp_e_impl::rx_ddc_get, this, _1, _2), boost::bind(&usrp_e_impl::rx_ddc_set, this, _1, _2) ); + + //initial config and update + rx_ddc_set(DSP_PROP_FREQ_SHIFT, double(0)); + rx_ddc_set(DSP_PROP_HOST_RATE, double(64e6/10)); } /*********************************************************************** @@ -105,6 +109,10 @@ void usrp_e_impl::tx_duc_init(void){ boost::bind(&usrp_e_impl::tx_duc_get, this, _1, _2), boost::bind(&usrp_e_impl::tx_duc_set, this, _1, _2) ); + + //initial config and update + tx_duc_set(DSP_PROP_FREQ_SHIFT, double(0)); + tx_duc_set(DSP_PROP_HOST_RATE, double(64e6/10)); } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp index 67c174208..41cbfa1e2 100644 --- a/host/lib/usrp/usrp_e/usrp_e_regs.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -174,7 +174,8 @@ #define UE_REG_TIME64_SECS UE_REG_SR_ADDR(28) // value to set absolute secs to on next PPS #define UE_REG_TIME64_TICKS UE_REG_SR_ADDR(29) // value to set absolute ticks to on next PPS #define UE_REG_TIME64_FLAGS UE_REG_SR_ADDR(30) // flags - see chart above -#define UE_REG_TIME64_IMM UE_REG_SR_ADDR(31) // set immediate (0=latch on next pps, 1=latch immediate, default=0) +#define UE_REG_TIME64_IMM UE_REG_SR_ADDR(31) // set immediate (0=latch on next pps, 1=latch immediate, default=0) +#define UE_REG_TIME64_TPS UE_REG_SR_ADDR(31) // clock ticks per second (counter rollover) //pps flags (see above) #define UE_FLAG_TIME64_PPS_NEGEDGE (0 << 0) -- cgit v1.2.3 From 8869208ea8d8dfdd5fe86adc1637b93c4b390c0c Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 28 May 2010 11:26:40 +0000 Subject: Update usrp_e.h file. Change programs to use struct element status instead of flags. --- host/apps/omap_debug/usrp-e-crc-rw.c | 15 +++++++++++---- host/apps/omap_debug/usrp-e-lb-test.c | 2 +- host/apps/omap_debug/usrp-e-loopback.c | 6 +++--- host/apps/omap_debug/usrp-e-rw-random.c | 4 ++-- host/apps/omap_debug/usrp-e-timed.c | 6 +++--- host/apps/omap_debug/usrp_e.h | 16 +++++++++------- 6 files changed, 29 insertions(+), 20 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c index 8883366ae..c3ae45cc1 100644 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -81,13 +81,20 @@ static void *read_thread(void *threadid) } #endif - if (rx_data->flags & RB_OVERRUN) + if (rx_data->status & RB_OVERRUN) printf("O"); - + + printf("rx_data->len = %d\n", rx_data->len); + + crc = 0xFFFFFFFF; - for (i = 0; i < rx_data->len - 4; i++) { + for (i = 0; i < rx_data->len - 4; i+=2) { + crc = ((crc >> 8) & 0x00FFFFFF) ^ + crc_tab[(crc ^ rx_data->buf[i+1]) & 0xFF]; +printf("idx = %d, data = %X, crc = %X\n", i, rx_data->buf[i+1],crc); crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ rx_data->buf[i]) & 0xFF]; +printf("idx = %d, data = %X, crc = %X\n", i, rx_data->buf[i],crc); } p = &rx_data->buf[rx_data->len - 4]; @@ -96,7 +103,7 @@ static void *read_thread(void *threadid) #if 1 printf("rx_data->len = %d\n", rx_data->len); - printf("rx_data->flags = %d\n", rx_data->flags); + printf("rx_data->status = %d\n", rx_data->status); for (i = 0; i < rx_data->len; i++) printf("idx = %d, data = %X\n", i, rx_data->buf[i]); printf("calc crc = %lX, rx crc = %X\n", crc, rx_crc); diff --git a/host/apps/omap_debug/usrp-e-lb-test.c b/host/apps/omap_debug/usrp-e-lb-test.c index 675de8622..68848064e 100644 --- a/host/apps/omap_debug/usrp-e-lb-test.c +++ b/host/apps/omap_debug/usrp-e-lb-test.c @@ -32,7 +32,7 @@ int main(int argc, char *argv[]) tx_data = malloc(2048); rx_data = malloc(2048); - tx_data->flags = 0; + tx_data->status = 0; tx_data->len = sizeof(struct usrp_transfer_frame) + packet_data_length; while (1) { diff --git a/host/apps/omap_debug/usrp-e-loopback.c b/host/apps/omap_debug/usrp-e-loopback.c index 177394947..535ce1025 100644 --- a/host/apps/omap_debug/usrp-e-loopback.c +++ b/host/apps/omap_debug/usrp-e-loopback.c @@ -63,7 +63,7 @@ static void *read_thread(void *threadid) if (cnt < 0) printf("Error returned from read: %d\n", cnt); -// printf("Packet received, flags = %X, len = %d\n", rx_data->flags, rx_data->len); +// printf("Packet received, status = %X, len = %d\n", rx_data->status, rx_data->len); // printf("p->seq_num = %d\n", p->seq_num); @@ -119,7 +119,7 @@ static void *write_thread(void *threadid) // p->data[i] = random() >> 16; p->data[i] = i; - tx_data->flags = 0xdeadbeef; + tx_data->status = 0xdeadbeef; tx_data->len = 8 + packet_data_length * 2; printf("tx_data->len = %d\n", tx_data->len); @@ -127,7 +127,7 @@ static void *write_thread(void *threadid) seq_number = 1; while (1) { -// printf("tx flags = %X, len = %d\n", tx_data->flags, tx_data->len); +// printf("tx status = %X, len = %d\n", tx_data->status, tx_data->len); p->seq_num = seq_number++; p->checksum = calc_checksum(p); cnt = write(fp, tx_data, 2048); diff --git a/host/apps/omap_debug/usrp-e-rw-random.c b/host/apps/omap_debug/usrp-e-rw-random.c index 43f1571cb..5960b8fbd 100644 --- a/host/apps/omap_debug/usrp-e-rw-random.c +++ b/host/apps/omap_debug/usrp-e-rw-random.c @@ -65,7 +65,7 @@ static void *read_thread(void *threadid) while (1) { cnt = read(fp, rx_data, 2048); -// printf("Packet received, flags = %X, len = %d\n", rx_data->flags, rx_data->len); +// printf("Packet received, status = %X, len = %d\n", rx_data->status, rx_data->len); // printf("p->seq_num = %d\n", p->seq_num); if (p->seq_num != prev_seq_num + 1) @@ -102,7 +102,7 @@ static void *write_thread(void *threadid) // p->data[i] = random() >> 16; p->data[i] = i; - tx_data->flags = 0xdeadbeef; + tx_data->status = 0xdeadbeef; tx_data->len = 8 + packet_data_length * 2; printf("tx_data->len = %d\n", tx_data->len); diff --git a/host/apps/omap_debug/usrp-e-timed.c b/host/apps/omap_debug/usrp-e-timed.c index c71651741..3cb33ce2d 100644 --- a/host/apps/omap_debug/usrp-e-timed.c +++ b/host/apps/omap_debug/usrp-e-timed.c @@ -75,7 +75,7 @@ static void *read_thread(void *threadid) } #endif - if (rx_data->flags & RB_OVERRUN) + if (rx_data->status & RB_OVERRUN) printf("O"); bytes_transfered += rx_data->len; @@ -118,7 +118,7 @@ static void *write_thread(void *threadid) // p->data[i] = random() >> 16; p->data[i] = i; - tx_data->flags = 0; + tx_data->status = 0; tx_data->len = 8 + packet_data_length * 2; printf("tx_data->len = %d\n", tx_data->len); @@ -146,7 +146,7 @@ static void *write_thread(void *threadid) } #endif -// printf("tx flags = %X, len = %d\n", tx_data->flags, tx_data->len); +// printf("tx status = %X, len = %d\n", tx_data->status, tx_data->len); p->seq_num = seq_number++; p->checksum = calc_checksum(p); cnt = write(fp, tx_data, 2048); diff --git a/host/apps/omap_debug/usrp_e.h b/host/apps/omap_debug/usrp_e.h index fd74e6e9e..b098ad114 100644 --- a/host/apps/omap_debug/usrp_e.h +++ b/host/apps/omap_debug/usrp_e.h @@ -28,14 +28,14 @@ struct usrp_e_ctl32 { __u32 buf[10]; }; -// SPI interface +/* SPI interface */ #define UE_SPI_TXONLY 0 #define UE_SPI_TXRX 1 -// Defines for spi ctrl register -#define UE_SPI_CTRL_TXNEG (1<<10) -#define UE_SPI_CTRL_RXNEG (1<<9) +/* Defines for spi ctrl register */ +#define UE_SPI_CTRL_TXNEG (1 << 10) +#define UE_SPI_CTRL_RXNEG (1 << 9) #define UE_SPI_PUSH_RISE 0 #define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG @@ -65,20 +65,22 @@ struct usrp_e_i2c { #define USRP_E_I2C_READ _IOWR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) #define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) -// Data transfer frame definition +/* Data transfer frame definition */ struct usrp_transfer_frame { - __u32 flags; + __u32 status; __u32 len; __u8 buf[]; }; -// Flag defines +/* Flag defines */ #define RB_USER (1 << 0) #define RB_KERNEL (1 << 1) #define RB_OVERRUN (1 << 2) +#define RB_DMA_ACTIVE (1 << 3) struct ring_buffer_entry { + unsigned int flags; unsigned long dma_addr; struct usrp_transfer_frame *frame_addr; }; -- cgit v1.2.3 From 7edefe21d6476e0570313a0bbdeada38ea835b9a Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sat, 5 Jun 2010 11:43:15 +0000 Subject: Exit on errors. Run until an error occurs. Alloq for up to 2 sequence number errors so program can start with "dirty" fpga contents. --- host/apps/omap_debug/usrp-e-loopback.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-loopback.c b/host/apps/omap_debug/usrp-e-loopback.c index 535ce1025..929d65604 100644 --- a/host/apps/omap_debug/usrp-e-loopback.c +++ b/host/apps/omap_debug/usrp-e-loopback.c @@ -9,6 +9,7 @@ // max length #define PKT_DATA_LENGTH 1016 static int packet_data_length; +static int error; struct pkt { int checksum; @@ -35,7 +36,7 @@ static int calc_checksum(struct pkt *p) static void *read_thread(void *threadid) { - int cnt, prev_seq_num, pkt_count; + int cnt, prev_seq_num, pkt_count, seq_num_failure; struct usrp_transfer_frame *rx_data; struct pkt *p; unsigned long bytes_transfered, elapsed_seconds; @@ -56,12 +57,13 @@ static void *read_thread(void *threadid) prev_seq_num = 0; pkt_count = 0; + seq_num_failure = 0; while (1) { cnt = read(fp, rx_data, 2048); if (cnt < 0) - printf("Error returned from read: %d\n", cnt); + printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); // printf("Packet received, status = %X, len = %d\n", rx_data->status, rx_data->len); // printf("p->seq_num = %d\n", p->seq_num); @@ -69,15 +71,22 @@ static void *read_thread(void *threadid) pkt_count++; - if (p->seq_num != prev_seq_num + 1) + if (p->seq_num != prev_seq_num + 1) { printf("Sequence number fail, current = %X, previous = %X, pkt_count = %d\n", p->seq_num, prev_seq_num, pkt_count); + + seq_num_failure ++; + if (seq_num_failure > 2) + error = 1; + } + prev_seq_num = p->seq_num; - if (calc_checksum(p) != p->checksum) + if (calc_checksum(p) != p->checksum) { printf("Checksum fail packet = %X, expected = %X, pkt_count = %d\n", calc_checksum(p), p->checksum, pkt_count); - + error = 1; + } bytes_transfered += rx_data->len; @@ -157,6 +166,7 @@ int main(int argc, char *argv[]) printf("fp = %d\n", fp); sched_setscheduler(0, SCHED_RR, &s); + error = 0; if (pthread_create(&rx, NULL, read_thread, (void *) t)) { printf("Failed to create rx thread\n"); @@ -170,7 +180,8 @@ int main(int argc, char *argv[]) exit(-1); } - sleep(10000); + while (!error) + sleep(1); printf("Done sleeping\n"); } -- cgit v1.2.3 From 617488fd6a4f6a2efa0c966a07d6ac1b6201c3aa Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 7 Jun 2010 14:46:14 +0000 Subject: Rename loopback of random length packets test program so we know it needs loopback fpga image. Needs debug. --- host/apps/omap_debug/Makefile | 4 +- host/apps/omap_debug/usrp-e-random-loopback.c | 149 ++++++++++++++++++++++++++ host/apps/omap_debug/usrp-e-rw-random.c | 149 -------------------------- 3 files changed, 151 insertions(+), 151 deletions(-) create mode 100644 host/apps/omap_debug/usrp-e-random-loopback.c delete mode 100644 host/apps/omap_debug/usrp-e-rw-random.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 17a3858cf..c11609bdd 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,7 +1,7 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 CXXFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 -all : usrp-e-spi usrp-e-i2c usrp-e-loopback usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-rw-random usrp-e-timed usrp-e-lb-test usrp-e-crc-rw clkgen-config +all : usrp-e-spi usrp-e-i2c usrp-e-loopback usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-random-loopback usrp-e-timed usrp-e-lb-test usrp-e-crc-rw clkgen-config usrp-e-spi : usrp-e-spi.c @@ -13,7 +13,7 @@ usrp-e-loopback : usrp-e-loopback.c usrp-e-timed : usrp-e-timed.c gcc -o $@ $< -lpthread ${CFLAGS} -usrp-e-rw-random : usrp-e-rw-random.c +usrp-e-random-loopback : usrp-e-random-loopback.c gcc -o $@ $< -lpthread ${CFLAGS} usrp-e-crc-rw : usrp-e-crc-rw.c diff --git a/host/apps/omap_debug/usrp-e-random-loopback.c b/host/apps/omap_debug/usrp-e-random-loopback.c new file mode 100644 index 000000000..5960b8fbd --- /dev/null +++ b/host/apps/omap_debug/usrp-e-random-loopback.c @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include +#include +#include +#include "usrp_e.h" + +// max length #define PKT_DATA_LENGTH 1014 +static int packet_data_length; + +struct pkt { + int checksum; + int seq_num; + int len; + short data[]; +}; + +static int fp; + +static int calc_checksum(struct pkt *p) +{ + int i, sum; + + i = 0; + sum = 0; + + for (i=0; i < p->len; i++) + sum += p->data[i]; + + sum += p->seq_num; + + return sum; +} + +int randN(int n) +{ + long tmp; + + tmp = rand() % n; + + return tmp; +} + +static void *read_thread(void *threadid) +{ + int cnt, prev_seq_num; + struct usrp_transfer_frame *rx_data; + struct pkt *p; + + printf("Greetings from the reading thread!\n"); + + // IMPORTANT: must assume max length packet from fpga + rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1014 * 2)); + rx_data = malloc(2048); + p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); + //p = &(rx_data->buf[0]); + printf("Address of rx_data = %p, p = %p\n", rx_data, p); + printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); + printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + + prev_seq_num = 0; + + while (1) { + + cnt = read(fp, rx_data, 2048); +// printf("Packet received, status = %X, len = %d\n", rx_data->status, rx_data->len); +// printf("p->seq_num = %d\n", p->seq_num); + + if (p->seq_num != prev_seq_num + 1) + printf("Sequence number fail, current = %d, previous = %d\n", + p->seq_num, prev_seq_num); + prev_seq_num = p->seq_num; + + if (calc_checksum(p) != p->checksum) + printf("Checksum fail packet = %d, expected = %d\n", + calc_checksum(p), p->checksum); + printf("."); + fflush(stdout); +// printf("\n"); + } + +} + +static void *write_thread(void *threadid) +{ + int seq_number, i, cnt, pkt_cnt; + struct usrp_transfer_frame *tx_data; + struct pkt *p; + + printf("Greetings from the write thread!\n"); + + // Allocate max length buffer for frame + tx_data = malloc(2048); + p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); + printf("Address of tx_data = %p, p = %p\n", tx_data, p); + + printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); + + for (i=0; i < 1014; i++) +// p->data[i] = random() >> 16; + p->data[i] = i; + + tx_data->status = 0xdeadbeef; + tx_data->len = 8 + packet_data_length * 2; + + printf("tx_data->len = %d\n", tx_data->len); + + seq_number = 1; + + while (1) { + pkt_cnt = randN(16); + for (i = 0; i < pkt_cnt; i++) { + p->seq_num = seq_number++; + p->len = randN(1013) + 1; + p->checksum = calc_checksum(p); + tx_data->len = 12 + p->len * 2; + cnt = write(fp, tx_data, tx_data->len + 8); + } + sleep(random() >> 31); + } +} + + +int main(int argc, char *argv[]) +{ + pthread_t tx, rx; + long int t; + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { + printf("Failed to create rx thread\n"); + exit(-1); + } + + sleep(1); + + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { + printf("Failed to create tx thread\n"); + exit(-1); + } + + sleep(1000000000); + + printf("Done sleeping\n"); +} diff --git a/host/apps/omap_debug/usrp-e-rw-random.c b/host/apps/omap_debug/usrp-e-rw-random.c deleted file mode 100644 index 5960b8fbd..000000000 --- a/host/apps/omap_debug/usrp-e-rw-random.c +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "usrp_e.h" - -// max length #define PKT_DATA_LENGTH 1014 -static int packet_data_length; - -struct pkt { - int checksum; - int seq_num; - int len; - short data[]; -}; - -static int fp; - -static int calc_checksum(struct pkt *p) -{ - int i, sum; - - i = 0; - sum = 0; - - for (i=0; i < p->len; i++) - sum += p->data[i]; - - sum += p->seq_num; - - return sum; -} - -int randN(int n) -{ - long tmp; - - tmp = rand() % n; - - return tmp; -} - -static void *read_thread(void *threadid) -{ - int cnt, prev_seq_num; - struct usrp_transfer_frame *rx_data; - struct pkt *p; - - printf("Greetings from the reading thread!\n"); - - // IMPORTANT: must assume max length packet from fpga - rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1014 * 2)); - rx_data = malloc(2048); - p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); - //p = &(rx_data->buf[0]); - printf("Address of rx_data = %p, p = %p\n", rx_data, p); - printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); - printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); - - prev_seq_num = 0; - - while (1) { - - cnt = read(fp, rx_data, 2048); -// printf("Packet received, status = %X, len = %d\n", rx_data->status, rx_data->len); -// printf("p->seq_num = %d\n", p->seq_num); - - if (p->seq_num != prev_seq_num + 1) - printf("Sequence number fail, current = %d, previous = %d\n", - p->seq_num, prev_seq_num); - prev_seq_num = p->seq_num; - - if (calc_checksum(p) != p->checksum) - printf("Checksum fail packet = %d, expected = %d\n", - calc_checksum(p), p->checksum); - printf("."); - fflush(stdout); -// printf("\n"); - } - -} - -static void *write_thread(void *threadid) -{ - int seq_number, i, cnt, pkt_cnt; - struct usrp_transfer_frame *tx_data; - struct pkt *p; - - printf("Greetings from the write thread!\n"); - - // Allocate max length buffer for frame - tx_data = malloc(2048); - p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); - printf("Address of tx_data = %p, p = %p\n", tx_data, p); - - printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); - - for (i=0; i < 1014; i++) -// p->data[i] = random() >> 16; - p->data[i] = i; - - tx_data->status = 0xdeadbeef; - tx_data->len = 8 + packet_data_length * 2; - - printf("tx_data->len = %d\n", tx_data->len); - - seq_number = 1; - - while (1) { - pkt_cnt = randN(16); - for (i = 0; i < pkt_cnt; i++) { - p->seq_num = seq_number++; - p->len = randN(1013) + 1; - p->checksum = calc_checksum(p); - tx_data->len = 12 + p->len * 2; - cnt = write(fp, tx_data, tx_data->len + 8); - } - sleep(random() >> 31); - } -} - - -int main(int argc, char *argv[]) -{ - pthread_t tx, rx; - long int t; - - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); - - if (pthread_create(&rx, NULL, read_thread, (void *) t)) { - printf("Failed to create rx thread\n"); - exit(-1); - } - - sleep(1); - - if (pthread_create(&tx, NULL, write_thread, (void *) t)) { - printf("Failed to create tx thread\n"); - exit(-1); - } - - sleep(1000000000); - - printf("Done sleeping\n"); -} -- cgit v1.2.3 From ec451d811c335af672d7a8ffbcfd3d0a1a645b2b Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 14 Jun 2010 22:32:54 +0000 Subject: file option for rx timed samples, misc fixes --- host/examples/rx_timed_samples.cpp | 21 ++++++++++++++++----- host/lib/usrp/usrp_e/codec_ctrl.cpp | 11 +++-------- host/lib/usrp/usrp_e/io_impl.cpp | 4 ++-- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 4 ++-- 4 files changed, 23 insertions(+), 17 deletions(-) (limited to 'host') diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 64da260d5..eb7ef7251 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -20,13 +20,14 @@ #include #include #include +#include #include namespace po = boost::program_options; int UHD_SAFE_MAIN(int argc, char *argv[]){ //variables to be set by po - std::string args; + std::string args, file_path; int seconds_in_future; size_t total_num_samps; double rx_rate, freq; @@ -40,6 +41,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to receive") ("rxrate", po::value(&rx_rate)->default_value(100e6/16), "rate of incoming samples") ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") + ("file", po::value(&file_path)->default_value(""), "write samps to output file") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -76,14 +78,20 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); sdev->issue_stream_cmd(stream_cmd); + std::ofstream outfile; + if(file_path != "") outfile.open (file_path.c_str(), std::ios::out | std::ios::binary); + + //setup recv buffer, io type, and metadata for recv + uhd::rx_metadata_t md; + uhd::io_type_t io_type(uhd::io_type_t::COMPLEX_INT16); + std::vector > recv_mem(dev->get_max_recv_samps_per_packet()); + boost::asio::mutable_buffer buff(boost::asio::buffer(recv_mem)); + //loop until total number of samples reached size_t num_acc_samps = 0; //number of accumulated samples while(num_acc_samps < total_num_samps){ - uhd::rx_metadata_t md; - std::vector > buff(dev->get_max_recv_samps_per_packet()); size_t num_rx_samps = dev->recv( - boost::asio::buffer(buff), - md, uhd::io_type_t::COMPLEX_FLOAT32, + buff, md, io_type, uhd::device::RECV_MODE_ONE_PACKET ); if (num_rx_samps == 0 and num_acc_samps > 0){ @@ -95,11 +103,14 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << boost::format("Got packet: %u samples, %u secs, %u nsecs") % num_rx_samps % md.time_spec.secs % md.time_spec.nsecs << std::endl; + if(file_path != "") outfile.write(boost::asio::buffer_cast(buff), num_rx_samps*io_type.size); + num_acc_samps += num_rx_samps; } //finished std::cout << std::endl << "Done!" << std::endl << std::endl; + if(file_path != "") outfile.close(); return 0; } diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index ce3458827..ac61bc6b4 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -58,9 +58,6 @@ private: usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ _iface = iface; - //FIXME temp poke !!! - _iface->poke16(UE_REG_MISC_TEST, 0x0f00); - //soft reset _ad9862_regs.soft_reset = 1; this->send_reg(0); @@ -75,8 +72,8 @@ usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ _ad9862_regs.byp_buffer_b = 1; _ad9862_regs.buffer_a_pd = 1; _ad9862_regs.buffer_b_pd = 1; - _ad9862_regs.rx_pga_a = 0x1f; //TODO bring under api control - _ad9862_regs.rx_pga_b = 0x1f; //TODO bring under api control + _ad9862_regs.rx_pga_a = 0;//0x1f; //TODO bring under api control + _ad9862_regs.rx_pga_b = 0;//0x1f; //TODO bring under api control _ad9862_regs.rx_twos_comp = 1; _ad9862_regs.rx_hilbert = ad9862_regs_t::RX_HILBERT_DIS; @@ -85,7 +82,7 @@ usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED; _ad9862_regs.tx_pga_gain = 199; //TODO bring under api control _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; - _ad9862_regs.interp = ad9862_regs_t::INTERP_4; + _ad9862_regs.interp = ad9862_regs_t::INTERP_2; _ad9862_regs.tx_twos_comp = 1; _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_BYPASS; _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; @@ -108,8 +105,6 @@ usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ } usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){ - return; //FIXME remove this later - //set aux dacs to zero this->write_aux_dac(AUX_DAC_A, 0); this->write_aux_dac(AUX_DAC_B, 0); diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index a94275b78..e1c1fe80b 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -107,7 +107,7 @@ struct usrp_e_impl::io_impl{ void usrp_e_impl::io_init(void){ //setup rx data path - _iface->poke32(UE_REG_CTRL_RX_NSAMPS_PER_PKT, 300); //FIXME magic number + _iface->poke32(UE_REG_CTRL_RX_NSAMPS_PER_PKT, get_max_recv_samps_per_packet()); _iface->poke32(UE_REG_CTRL_RX_NCHANNELS, 1); _iface->poke32(UE_REG_CTRL_RX_CLEAR_OVERRUN, 1); //reset _iface->poke32(UE_REG_CTRL_RX_VRT_HEADER, 0 @@ -168,7 +168,7 @@ size_t usrp_e_impl::send( MASTER_CLOCK_RATE, uhd::transport::vrt::pack_le, boost::bind(&data_transport::get_send_buff, &_io_impl->transport), - (MAX_BUFF_SIZE - sizeof(usrp_transfer_frame))/send_otw_type.get_sample_size(), + get_max_send_samps_per_packet(), vrt_header_offset_words32 ); } diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 657d2d225..487e295cb 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -80,8 +80,8 @@ public: //the io interface size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t); size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t); - size_t get_max_send_samps_per_packet(void) const{return _max_num_samples;} - size_t get_max_recv_samps_per_packet(void) const{return _max_num_samples;} + size_t get_max_send_samps_per_packet(void) const{return 300;} + size_t get_max_recv_samps_per_packet(void) const{return 300;} private: //interface to ioctls and file descriptor -- cgit v1.2.3 From 6d43a4e83814c5c325caefb35eb1e07b415d8d37 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 14 Jun 2010 23:15:58 +0000 Subject: fix type, it was supposed to be complex float --- host/examples/rx_timed_samples.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host') diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index eb7ef7251..a7212eba3 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -83,7 +83,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //setup recv buffer, io type, and metadata for recv uhd::rx_metadata_t md; - uhd::io_type_t io_type(uhd::io_type_t::COMPLEX_INT16); + uhd::io_type_t io_type(uhd::io_type_t::COMPLEX_FLOAT32); std::vector > recv_mem(dev->get_max_recv_samps_per_packet()); boost::asio::mutable_buffer buff(boost::asio::buffer(recv_mem)); -- cgit v1.2.3 From b4b80f1f6e59fa02d508af860f1a572c9224b975 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 15 Jun 2010 01:23:00 +0000 Subject: usrp-e: added poll(...) call before read(...) call --- host/lib/usrp/usrp_e/io_impl.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index e1c1fe80b..829e923b5 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -22,6 +22,7 @@ #include //read, write #include //transfer frame struct #include //offsetof +#include #include #include @@ -75,12 +76,22 @@ private: //std::cout << boost::format( // "calling read on fd %d, buff size is %d" //) % _fd % boost::asio::buffer_size(buff) << std::endl; + + //setup and call poll on the file descriptor + //return 0 and do not read when poll times out + pollfd pfd; + pfd.fd = _fd; + pfd.events = POLLIN; + if (poll(&pfd, 1, 100 /*ms*/) <= 0) return 0; //timeout + + //perform the blocking read(...) ssize_t ret = read( _fd, boost::asio::buffer_cast(buff), boost::asio::buffer_size(buff) ); if (ret < ssize_t(sizeof(usrp_transfer_frame))) return 0; + //overwrite the vrt header length with the transfer frame length size_t frame_size = boost::asio::buffer_cast(buff)->len; boost::uint32_t *vrt_header = boost::asio::buffer_cast(buff) + vrt_header_offset_words32; -- cgit v1.2.3 From cd537e846af8547b83c4b8f8ca30de4860c7fefb Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 15 Jun 2010 20:53:28 +0000 Subject: Add gitignore file. --- host/apps/omap_debug/.gitignore | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 host/apps/omap_debug/.gitignore (limited to 'host') diff --git a/host/apps/omap_debug/.gitignore b/host/apps/omap_debug/.gitignore new file mode 100644 index 000000000..5d6b1c6f5 --- /dev/null +++ b/host/apps/omap_debug/.gitignore @@ -0,0 +1,19 @@ +.gitignore +clkgen-config +fpga-downloader +usrp-e-button +usrp-e-crc-rw +usrp-e-ctl +usrp-e-debug-pins +usrp-e-fpga-rw +usrp-e-gpio +usrp-e-i2c +usrp-e-lb-test +usrp-e-led +usrp-e-loopback +usrp-e-random-loopback +usrp-e-rw +usrp-e-spi +usrp-e-timed +usrp-e-uart +usrp-e-uart-rx -- cgit v1.2.3 From e18a963fb5c35ba9ccf03986e8c82adfe44f0b89 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 16 Jun 2010 17:35:20 +0000 Subject: usrp-e: added type device address argument to usrp-e --- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 226825510..a534c74b2 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -44,6 +44,9 @@ static std::string abs_path(const std::string &file_path){ device_addrs_t usrp_e::find(const device_addr_t &hint){ device_addrs_t usrp_e_addrs; + //return an empty list of addresses when type is set to non-usrp-e + if (hint.has_key("type") and hint["type"] != "usrp-e") return usrp_e_addrs; + //device node not provided, assume its 0 if (not hint.has_key("node")){ device_addr_t new_addr = hint; @@ -54,7 +57,7 @@ device_addrs_t usrp_e::find(const device_addr_t &hint){ //use the given device node name if (fs::exists(hint["node"])){ device_addr_t new_addr; - new_addr["name"] = "USRP-E"; + new_addr["type"] = "usrp-e"; new_addr["node"] = abs_path(hint["node"]); usrp_e_addrs.push_back(new_addr); } -- cgit v1.2.3 From 2f9b6d5530df140a5a03120adc98a5ad32a69cc4 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 17 Jun 2010 22:33:32 +0000 Subject: usrp-e: added verbose for bad poll and read values --- host/lib/usrp/usrp_e/io_impl.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 829e923b5..c168d6304 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -28,9 +28,13 @@ using namespace uhd; +/*********************************************************************** + * Constants + **********************************************************************/ static const size_t MAX_BUFF_SIZE = 2048; - static const size_t vrt_header_offset_words32 = offsetof(usrp_transfer_frame, buf)/sizeof(boost::uint32_t); +static const bool usrp_e_io_impl_verbose = true; +static const size_t recv_timeout_ms = 100; /*********************************************************************** * Data Transport (phony zero-copy with read/write) @@ -82,15 +86,28 @@ private: pollfd pfd; pfd.fd = _fd; pfd.events = POLLIN; - if (poll(&pfd, 1, 100 /*ms*/) <= 0) return 0; //timeout + ssize_t poll_ret = poll(&pfd, 1, recv_timeout_ms); + if (poll_ret <= 0){ + if (usrp_e_io_impl_verbose) std::cerr << boost::format( + "usrp-e io impl recv(): poll() returned non-positive value: %d\n" + " -> return 0 for timeout" + ) % poll_ret << std::endl; + return 0; //timeout + } //perform the blocking read(...) - ssize_t ret = read( + ssize_t read_ret = read( _fd, boost::asio::buffer_cast(buff), boost::asio::buffer_size(buff) ); - if (ret < ssize_t(sizeof(usrp_transfer_frame))) return 0; + if (read_ret < ssize_t(sizeof(usrp_transfer_frame))){ + if (usrp_e_io_impl_verbose) std::cerr << boost::format( + "usrp-e io impl recv(): read() returned small value: %d\n" + " -> return 0 for error" + ) % read_ret << std::endl; + return 0; + } //overwrite the vrt header length with the transfer frame length size_t frame_size = boost::asio::buffer_cast(buff)->len; -- cgit v1.2.3 From df6cc603fd5e9dc34665385ac84b94eadf074074 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 21 Jun 2010 19:39:15 +0000 Subject: usrp-e: added clock rate control to dboard iface and clock control impl --- host/lib/usrp/usrp_e/clock_ctrl.cpp | 290 ++++++++++++++++++++-------------- host/lib/usrp/usrp_e/clock_ctrl.hpp | 27 +++- host/lib/usrp/usrp_e/dboard_iface.cpp | 53 +++++-- 3 files changed, 226 insertions(+), 144 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index e37b17a54..36799ef63 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -17,6 +17,7 @@ #include "clock_ctrl.hpp" #include "ad9522_regs.hpp" +#include #include #include "usrp_e_regs.hpp" //spi slave constants #include @@ -26,21 +27,171 @@ using namespace uhd; +template static void set_clock_divider( + size_t divider, div_type &low, div_type &high +){ + high = divider/2; + low = divider-high; +} + +/*********************************************************************** + * Constants + **********************************************************************/ +static const double master_clock_rate = 320e6; +static const size_t fpga_clock_divider = 5; //64 MHz +static const size_t codec_clock_divider = 5; //64 MHz + /*********************************************************************** * Clock Control Implementation **********************************************************************/ class usrp_e_clock_ctrl_impl : public usrp_e_clock_ctrl{ public: - //structors - usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface); - ~usrp_e_clock_ctrl_impl(void); + usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface){ + _iface = iface; + + //init the clock gen registers + //Note: out0 should already be clocking the FPGA or this isnt going to work + _ad9522_regs.sdo_active = ad9522_regs_t::SDO_ACTIVE_SDO_SDIO; + _ad9522_regs.status_pin_control = 0x1; //n divider + _ad9522_regs.ld_pin_control = 0x32; //show ref2 + _ad9522_regs.refmon_pin_control = 0x12; //show ref2 + + _ad9522_regs.enable_ref2 = 1; + _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF2; + + _ad9522_regs.r_counter_lsb = 1; + _ad9522_regs.r_counter_msb = 0; + _ad9522_regs.a_counter = 0; + _ad9522_regs.b_counter_lsb = 20; + _ad9522_regs.b_counter_msb = 0; + _ad9522_regs.prescaler_p = ad9522_regs_t::PRESCALER_P_DIV8_9; + + _ad9522_regs.pll_power_down = ad9522_regs_t::PLL_POWER_DOWN_NORMAL; + _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_3_0MA; + + _ad9522_regs.vco_calibration_now = 1; //calibrate it! + _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; + _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_VCO; + + //setup fpga master clock + _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS; + set_clock_divider(fpga_clock_divider, + _ad9522_regs.divider0_low_cycles, + _ad9522_regs.divider0_high_cycles + ); + + //setup codec clock + _ad9522_regs.out3_format = ad9522_regs_t::OUT3_FORMAT_LVDS; + set_clock_divider(codec_clock_divider, + _ad9522_regs.divider1_low_cycles, + _ad9522_regs.divider1_high_cycles + ); + + //setup test clock (same divider as codec clock) + _ad9522_regs.out4_format = ad9522_regs_t::OUT4_FORMAT_CMOS; + _ad9522_regs.out4_cmos_configuration = (true)? + ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON : + ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF; + + //setup a list of register ranges to write + typedef std::pair range_t; + static const std::vector ranges = boost::assign::list_of + (range_t(0x000, 0x000)) (range_t(0x010, 0x01F)) + (range_t(0x0F0, 0x0FD)) (range_t(0x190, 0x19B)) + (range_t(0x1E0, 0x1E1)) (range_t(0x230, 0x230)) + ; + + //write initial register values and latch/update + BOOST_FOREACH(const range_t &range, ranges){ + for(boost::uint16_t addr = range.first; addr <= range.second; addr++){ + this->send_reg(addr); + } + } + this->latch_regs(); + //test read: + //boost::uint32_t reg = _ad9522_regs.get_read_reg(0x01b); + //boost::uint32_t result = _iface->transact_spi( + // UE_SPI_SS_AD9522, + // spi_config_t::EDGE_RISE, + // reg, 24, true /*no*/ + //); + //std::cout << "result " << std::hex << result << std::endl; + this->enable_rx_dboard_clock(false); + this->enable_tx_dboard_clock(false); + } + + ~usrp_e_clock_ctrl_impl(void){ + this->enable_rx_dboard_clock(false); + this->enable_tx_dboard_clock(false); + } - void enable_rx_dboard_clock(bool enb); - void enable_tx_dboard_clock(bool enb); + double get_fpga_clock_rate(void){ + return master_clock_rate/fpga_clock_divider; + } - double get_fpga_clock_rate(void){return 64e6;} - double get_rx_dboard_clock_rate(void){return get_fpga_clock_rate();} - double get_tx_dboard_clock_rate(void){return get_fpga_clock_rate();} + /*********************************************************************** + * RX Dboard Clock Control (output 9, divider 3) + **********************************************************************/ + void enable_rx_dboard_clock(bool enb){ + _ad9522_regs.out9_format = ad9522_regs_t::OUT9_FORMAT_CMOS; + _ad9522_regs.out9_cmos_configuration = (enb)? + ad9522_regs_t::OUT9_CMOS_CONFIGURATION_B_ON : + ad9522_regs_t::OUT9_CMOS_CONFIGURATION_OFF; + this->send_reg(0x0F9); + this->latch_regs(); + } + + std::vector get_rx_dboard_clock_rates(void){ + std::vector rates; + for(size_t div = 1; div <= 16+16; div++) rates.push_back(master_clock_rate/div); + return rates; + } + + void set_rx_dboard_clock_rate(double rate){ + assert_has(get_rx_dboard_clock_rates(), rate, "rx dboard clock rate"); + size_t divider = size_t(rate/master_clock_rate); + //bypass when the divider ratio is one + _ad9522_regs.divider3_bypass = (divider == 1)? 1 : 0; + this->send_reg(0x19a); + //set the divider registers + set_clock_divider(divider, + _ad9522_regs.divider3_low_cycles, + _ad9522_regs.divider3_high_cycles + ); + this->send_reg(0x199); + this->latch_regs(); + } + + /*********************************************************************** + * TX Dboard Clock Control (output 6, divider 2) + **********************************************************************/ + void enable_tx_dboard_clock(bool enb){ + _ad9522_regs.out6_format = ad9522_regs_t::OUT6_FORMAT_CMOS; + _ad9522_regs.out6_cmos_configuration = (enb)? + ad9522_regs_t::OUT6_CMOS_CONFIGURATION_B_ON : + ad9522_regs_t::OUT6_CMOS_CONFIGURATION_OFF; + this->send_reg(0x0F6); + this->latch_regs(); + } + + std::vector get_tx_dboard_clock_rates(void){ + return get_rx_dboard_clock_rates(); //same master clock, same dividers... + } + + void set_tx_dboard_clock_rate(double rate){ + assert_has(get_tx_dboard_clock_rates(), rate, "tx dboard clock rate"); + size_t divider = size_t(rate/master_clock_rate); + //bypass when the divider ratio is one + _ad9522_regs.divider2_bypass = (divider == 1)? 1 : 0; + this->send_reg(0x197); + //set the divider registers + set_clock_divider(divider, + _ad9522_regs.divider2_low_cycles, + _ad9522_regs.divider2_high_cycles + ); + this->send_reg(0x196); + this->latch_regs(); + } private: usrp_e_iface::sptr _iface; @@ -50,122 +201,17 @@ private: _ad9522_regs.io_update = 1; this->send_reg(0x232); } - void send_reg(boost::uint16_t addr); -}; -/*********************************************************************** - * Clock Control Methods - **********************************************************************/ -usrp_e_clock_ctrl_impl::usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface){ - _iface = iface; - - //init the clock gen registers - //Note: out0 should already be clocking the FPGA or this isnt going to work - _ad9522_regs.sdo_active = ad9522_regs_t::SDO_ACTIVE_SDO_SDIO; - _ad9522_regs.status_pin_control = 0x1; //n divider - _ad9522_regs.ld_pin_control = 0x32; //show ref2 - _ad9522_regs.refmon_pin_control = 0x12; //show ref2 - - _ad9522_regs.enable_ref2 = 1; - _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF2; - - _ad9522_regs.r_counter_lsb = 1; - _ad9522_regs.r_counter_msb = 0; - _ad9522_regs.a_counter = 0; - _ad9522_regs.b_counter_lsb = 20; - _ad9522_regs.b_counter_msb = 0; - _ad9522_regs.prescaler_p = ad9522_regs_t::PRESCALER_P_DIV8_9; - - _ad9522_regs.pll_power_down = ad9522_regs_t::PLL_POWER_DOWN_NORMAL; - _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_3_0MA; - - _ad9522_regs.vco_calibration_now = 1; //calibrate it! - _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; - _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_VCO; - - //setup fpga master clock - _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS; - _ad9522_regs.divider0_low_cycles = 2; //3 low - _ad9522_regs.divider0_high_cycles = 1; //2 high - - //setup codec clock - _ad9522_regs.out3_format = ad9522_regs_t::OUT3_FORMAT_LVDS; - _ad9522_regs.divider1_low_cycles = 2; //3 low - _ad9522_regs.divider1_high_cycles = 1; //2 high - - //setup test clock (same divider as codec clock) - _ad9522_regs.out4_format = ad9522_regs_t::OUT4_FORMAT_CMOS; - _ad9522_regs.out4_cmos_configuration = (true)? - ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON : - ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF; - - //setup a list of register ranges to write - typedef std::pair range_t; - static const std::vector ranges = boost::assign::list_of - (range_t(0x000, 0x000)) (range_t(0x010, 0x01F)) - (range_t(0x0F0, 0x0FD)) (range_t(0x190, 0x19B)) - (range_t(0x1E0, 0x1E1)) (range_t(0x230, 0x230)) - ; - - //write initial register values and latch/update - BOOST_FOREACH(const range_t &range, ranges){ - for(boost::uint16_t addr = range.first; addr <= range.second; addr++){ - this->send_reg(addr); - } + void send_reg(boost::uint16_t addr){ + boost::uint32_t reg = _ad9522_regs.get_write_reg(addr); + //std::cout << "clock control write reg: " << std::hex << reg << std::endl; + _iface->transact_spi( + UE_SPI_SS_AD9522, + spi_config_t::EDGE_RISE, + reg, 24, false /*no rb*/ + ); } - this->latch_regs(); - //test read: - //boost::uint32_t reg = _ad9522_regs.get_read_reg(0x01b); - //boost::uint32_t result = _iface->transact_spi( - // UE_SPI_SS_AD9522, - // spi_config_t::EDGE_RISE, - // reg, 24, true /*no*/ - //); - //std::cout << "result " << std::hex << result << std::endl; - this->enable_rx_dboard_clock(false); - this->enable_tx_dboard_clock(false); -} - -usrp_e_clock_ctrl_impl::~usrp_e_clock_ctrl_impl(void){ - this->enable_rx_dboard_clock(false); - this->enable_tx_dboard_clock(false); -} - -void usrp_e_clock_ctrl_impl::enable_rx_dboard_clock(bool enb){ - _ad9522_regs.out9_format = ad9522_regs_t::OUT9_FORMAT_CMOS; - _ad9522_regs.out9_cmos_configuration = (enb)? - ad9522_regs_t::OUT9_CMOS_CONFIGURATION_B_ON : - ad9522_regs_t::OUT9_CMOS_CONFIGURATION_OFF; - this->send_reg(0x0F9); - - _ad9522_regs.divider3_low_cycles = 2; //3 low - _ad9522_regs.divider3_high_cycles = 1; //2 high - this->send_reg(0x199); - this->latch_regs(); -} - -void usrp_e_clock_ctrl_impl::enable_tx_dboard_clock(bool enb){ - _ad9522_regs.out6_format = ad9522_regs_t::OUT6_FORMAT_CMOS; - _ad9522_regs.out6_cmos_configuration = (enb)? - ad9522_regs_t::OUT6_CMOS_CONFIGURATION_B_ON : - ad9522_regs_t::OUT6_CMOS_CONFIGURATION_OFF; - this->send_reg(0x0F6); - - _ad9522_regs.divider2_low_cycles = 2; //3 low - _ad9522_regs.divider2_high_cycles = 1; //2 high - this->send_reg(0x196); - this->latch_regs(); -} - -void usrp_e_clock_ctrl_impl::send_reg(boost::uint16_t addr){ - boost::uint32_t reg = _ad9522_regs.get_write_reg(addr); - //std::cout << "clock control write reg: " << std::hex << reg << std::endl; - _iface->transact_spi( - UE_SPI_SS_AD9522, - spi_config_t::EDGE_RISE, - reg, 24, false /*no rb*/ - ); -} +}; /*********************************************************************** * Clock Control Make diff --git a/host/lib/usrp/usrp_e/clock_ctrl.hpp b/host/lib/usrp/usrp_e/clock_ctrl.hpp index 692b9eb0e..3b5103ed1 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.hpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.hpp @@ -21,6 +21,7 @@ #include "usrp_e_iface.hpp" #include #include +#include /*! * The usrp-e clock control: @@ -45,16 +46,30 @@ public: virtual double get_fpga_clock_rate(void) = 0; /*! - * Get the rate of the dboard clock clock line. - * \return the dboard clock rate in Hz + * Get the possible rates of the rx dboard clock. + * \return a vector of clock rates in Hz */ - virtual double get_rx_dboard_clock_rate(void) = 0; + virtual std::vector get_rx_dboard_clock_rates(void) = 0; /*! - * Get the rate of the dboard clock clock line. - * \return the dboard clock rate in Hz + * Get the possible rates of the tx dboard clock. + * \return a vector of clock rates in Hz */ - virtual double get_tx_dboard_clock_rate(void) = 0; + virtual std::vector get_tx_dboard_clock_rates(void) = 0; + + /*! + * Set the rx dboard clock rate to a possible rate. + * \param rate the new clock rate in Hz + * \throw exception when rate cannot be achieved + */ + virtual void set_rx_dboard_clock_rate(double rate) = 0; + + /*! + * Set the tx dboard clock rate to a possible rate. + * \param rate the new clock rate in Hz + * \throw exception when rate cannot be achieved + */ + virtual void set_tx_dboard_clock_rate(double rate) = 0; /*! * Enable/disable the rx dboard clock. diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp index 594f2a23e..ce00cd40d 100644 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -40,14 +40,18 @@ public: _iface = iface; _clock = clock; _codec = codec; + + //init the clock rate shadows + this->set_clock_rate(UNIT_RX, _clock->get_fpga_clock_rate()); + this->set_clock_rate(UNIT_TX, _clock->get_fpga_clock_rate()); } ~usrp_e_dboard_iface(void){ /* NOP */ } - void write_aux_dac(unit_t, int, float); - float read_aux_adc(unit_t, int); + void write_aux_dac(unit_t, aux_dac_t, float); + float read_aux_adc(unit_t, aux_adc_t); void set_pin_ctrl(unit_t, boost::uint16_t); void set_atr_reg(unit_t, atr_reg_t, boost::uint16_t); @@ -72,6 +76,8 @@ public: size_t num_bits ); + void set_clock_rate(unit_t, double); + std::vector get_clock_rates(unit_t); double get_clock_rate(unit_t); void set_clock_enabled(unit_t, bool); @@ -79,6 +85,7 @@ private: usrp_e_iface::sptr _iface; usrp_e_clock_ctrl::sptr _clock; usrp_e_codec_ctrl::sptr _codec; + uhd::dict _clock_rates; }; /*********************************************************************** @@ -95,12 +102,24 @@ dboard_iface::sptr make_usrp_e_dboard_iface( /*********************************************************************** * Clock Rates **********************************************************************/ -double usrp_e_dboard_iface::get_clock_rate(unit_t unit){ +void usrp_e_dboard_iface::set_clock_rate(unit_t unit, double rate){ + _clock_rates[unit] = rate; switch(unit){ - case UNIT_RX: return _clock->get_rx_dboard_clock_rate(); - case UNIT_TX: return _clock->get_tx_dboard_clock_rate(); + case UNIT_RX: return _clock->set_rx_dboard_clock_rate(rate); + case UNIT_TX: return _clock->set_tx_dboard_clock_rate(rate); } - UHD_ASSERT_THROW(false); +} + +std::vector usrp_e_dboard_iface::get_clock_rates(unit_t unit){ + switch(unit){ + case UNIT_RX: return _clock->get_rx_dboard_clock_rates(); + case UNIT_TX: return _clock->get_tx_dboard_clock_rates(); + default: UHD_THROW_INVALID_CODE_PATH(); + } +} + +double usrp_e_dboard_iface::get_clock_rate(unit_t unit){ + return _clock_rates[unit]; } void usrp_e_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ @@ -212,26 +231,28 @@ byte_vector_t usrp_e_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_byte /*********************************************************************** * Aux DAX/ADC **********************************************************************/ -void usrp_e_dboard_iface::write_aux_dac(dboard_iface::unit_t, int which, float value){ +void usrp_e_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, float value){ //same aux dacs for each unit - static const uhd::dict which_to_aux_dac = map_list_of - (0, usrp_e_codec_ctrl::AUX_DAC_A) (1, usrp_e_codec_ctrl::AUX_DAC_B) - (2, usrp_e_codec_ctrl::AUX_DAC_C) (3, usrp_e_codec_ctrl::AUX_DAC_D) + static const uhd::dict which_to_aux_dac = map_list_of + (AUX_DAC_A, usrp_e_codec_ctrl::AUX_DAC_A) + (AUX_DAC_B, usrp_e_codec_ctrl::AUX_DAC_B) + (AUX_DAC_C, usrp_e_codec_ctrl::AUX_DAC_C) + (AUX_DAC_D, usrp_e_codec_ctrl::AUX_DAC_D) ; _codec->write_aux_dac(which_to_aux_dac[which], value); } -float usrp_e_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, int which){ +float usrp_e_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which){ static const uhd::dict< - unit_t, uhd::dict + unit_t, uhd::dict > unit_to_which_to_aux_adc = map_list_of (UNIT_RX, map_list_of - (0, usrp_e_codec_ctrl::AUX_ADC_A1) - (1, usrp_e_codec_ctrl::AUX_ADC_B1) + (AUX_ADC_A, usrp_e_codec_ctrl::AUX_ADC_A1) + (AUX_ADC_B, usrp_e_codec_ctrl::AUX_ADC_B1) ) (UNIT_TX, map_list_of - (0, usrp_e_codec_ctrl::AUX_ADC_A2) - (1, usrp_e_codec_ctrl::AUX_ADC_B2) + (AUX_ADC_A, usrp_e_codec_ctrl::AUX_ADC_A2) + (AUX_ADC_B, usrp_e_codec_ctrl::AUX_ADC_B2) ) ; return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]); -- cgit v1.2.3 From e6aed138b08100fe81355771fc62d4ff2f7556d0 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 23 Jun 2010 00:16:59 +0000 Subject: usrp-e: clock divider calculation fix --- host/lib/usrp/usrp_e/clock_ctrl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 36799ef63..bf38db8a6 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -30,8 +30,8 @@ using namespace uhd; template static void set_clock_divider( size_t divider, div_type &low, div_type &high ){ - high = divider/2; - low = divider-high; + high = divider/2 - 1; + low = divider - high - 2; } /*********************************************************************** -- cgit v1.2.3 From 2ff1a854669a0fe5c8029f0c013e38faade6b826 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 23 Jun 2010 01:43:25 +0000 Subject: usrp-e: clock control constants to easily change dividers and counters, tweaks to ic reg maps common --- host/lib/ic_reg_maps/common.py | 4 +-- host/lib/ic_reg_maps/gen_ad9522_regs.py | 2 ++ host/lib/usrp/usrp_e/clock_ctrl.cpp | 50 ++++++++++++++++++++------------- 3 files changed, 34 insertions(+), 22 deletions(-) (limited to 'host') diff --git a/host/lib/ic_reg_maps/common.py b/host/lib/ic_reg_maps/common.py index 173186eb1..47325a7e3 100644 --- a/host/lib/ic_reg_maps/common.py +++ b/host/lib/ic_reg_maps/common.py @@ -59,7 +59,7 @@ public: delete _state; } -$body + $body void save_state(void){ if (_state == NULL) _state = new $(name)_t(); @@ -181,7 +181,7 @@ def generate(name, regs_tmpl, body_tmpl='', file=__file__): else: regs.append(reg(entry)) #evaluate the body template with the list of registers - body = parse_tmpl(body_tmpl, regs=regs).replace('\n', '\n ').strip() + body = '\n '.join(parse_tmpl(body_tmpl, regs=regs).splitlines()) #evaluate the code template with the parsed registers and arguments code = parse_tmpl(COMMON_TMPL, diff --git a/host/lib/ic_reg_maps/gen_ad9522_regs.py b/host/lib/ic_reg_maps/gen_ad9522_regs.py index 9da51205b..ed6b5f48d 100755 --- a/host/lib/ic_reg_maps/gen_ad9522_regs.py +++ b/host/lib/ic_reg_maps/gen_ad9522_regs.py @@ -32,9 +32,11 @@ cp_mode 0x010[3:2] 3 high_imp, force pll_power_down 0x010[1:0] 1 normal=0, async=1, sync=3 r_counter_lsb 0x011[7:0] 1 r_counter_msb 0x012[5:0] 0 +~r_counter r_counter_lsb, r_counter_msb a_counter 0x013[5:0] 0 b_counter_lsb 0x014[7:0] 3 b_counter_msb 0x015[4:0] 0 +~b_counter b_counter_lsb, b_counter_msb set_cp_pin_to_vcp_2 0x016[7] 0 normal, vcp_2 reset_r_counter 0x016[6] 0 reset_a_and_b_counters 0x016[5] 0 diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index bf38db8a6..0b18763a4 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -27,19 +27,31 @@ using namespace uhd; -template static void set_clock_divider( - size_t divider, div_type &low, div_type &high +template static void set_clock_divider( + size_t divider, div_type &low, div_type &high, bypass_type &bypass ){ high = divider/2 - 1; low = divider - high - 2; + bypass = (divider == 1)? 1 : 0; } /*********************************************************************** * Constants **********************************************************************/ -static const double master_clock_rate = 320e6; -static const size_t fpga_clock_divider = 5; //64 MHz -static const size_t codec_clock_divider = 5; //64 MHz +static const double ref_clock_rate = 10e6; + +static const size_t r_counter = 1; +static const size_t a_counter = 0; +static const size_t b_counter = 20; +static const size_t prescaler = 8; //set below with enum +static const size_t vco_divider = 5; //set below with enum + +static const size_t n_counter = prescaler * b_counter + a_counter; +static const size_t vco_clock_rate = ref_clock_rate/r_counter * n_counter; +static const double master_clock_rate = vco_clock_rate/vco_divider; + +static const size_t fpga_clock_divider = size_t(master_clock_rate/64e6); +static const size_t codec_clock_divider = size_t(master_clock_rate/64e6); /*********************************************************************** * Clock Control Implementation @@ -59,11 +71,9 @@ public: _ad9522_regs.enable_ref2 = 1; _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF2; - _ad9522_regs.r_counter_lsb = 1; - _ad9522_regs.r_counter_msb = 0; - _ad9522_regs.a_counter = 0; - _ad9522_regs.b_counter_lsb = 20; - _ad9522_regs.b_counter_msb = 0; + _ad9522_regs.set_r_counter(r_counter); + _ad9522_regs.a_counter = a_counter; + _ad9522_regs.set_b_counter(b_counter); _ad9522_regs.prescaler_p = ad9522_regs_t::PRESCALER_P_DIV8_9; _ad9522_regs.pll_power_down = ad9522_regs_t::PLL_POWER_DOWN_NORMAL; @@ -77,14 +87,16 @@ public: _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS; set_clock_divider(fpga_clock_divider, _ad9522_regs.divider0_low_cycles, - _ad9522_regs.divider0_high_cycles + _ad9522_regs.divider0_high_cycles, + _ad9522_regs.divider0_bypass ); //setup codec clock _ad9522_regs.out3_format = ad9522_regs_t::OUT3_FORMAT_LVDS; set_clock_divider(codec_clock_divider, _ad9522_regs.divider1_low_cycles, - _ad9522_regs.divider1_high_cycles + _ad9522_regs.divider1_high_cycles, + _ad9522_regs.divider1_bypass ); //setup test clock (same divider as codec clock) @@ -150,15 +162,14 @@ public: void set_rx_dboard_clock_rate(double rate){ assert_has(get_rx_dboard_clock_rates(), rate, "rx dboard clock rate"); size_t divider = size_t(rate/master_clock_rate); - //bypass when the divider ratio is one - _ad9522_regs.divider3_bypass = (divider == 1)? 1 : 0; - this->send_reg(0x19a); //set the divider registers set_clock_divider(divider, _ad9522_regs.divider3_low_cycles, - _ad9522_regs.divider3_high_cycles + _ad9522_regs.divider3_high_cycles, + _ad9522_regs.divider3_bypass ); this->send_reg(0x199); + this->send_reg(0x19a); this->latch_regs(); } @@ -181,15 +192,14 @@ public: void set_tx_dboard_clock_rate(double rate){ assert_has(get_tx_dboard_clock_rates(), rate, "tx dboard clock rate"); size_t divider = size_t(rate/master_clock_rate); - //bypass when the divider ratio is one - _ad9522_regs.divider2_bypass = (divider == 1)? 1 : 0; - this->send_reg(0x197); //set the divider registers set_clock_divider(divider, _ad9522_regs.divider2_low_cycles, - _ad9522_regs.divider2_high_cycles + _ad9522_regs.divider2_high_cycles, + _ad9522_regs.divider2_bypass ); this->send_reg(0x196); + this->send_reg(0x197); this->latch_regs(); } -- cgit v1.2.3 From 89a22c7dd531b1754f2401037a4a5c971139bd97 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Jul 2010 01:58:30 +0000 Subject: usrp-e: tweaks to clock control logic --- host/lib/usrp/usrp_e/clock_ctrl.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 0b18763a4..df649cee6 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -43,11 +43,11 @@ static const double ref_clock_rate = 10e6; static const size_t r_counter = 1; static const size_t a_counter = 0; static const size_t b_counter = 20; -static const size_t prescaler = 8; //set below with enum -static const size_t vco_divider = 5; //set below with enum +static const size_t prescaler = 8; //set below with enum, set to 8 when input is under 2400 MHz +static const size_t vco_divider = 1; //set below with enum static const size_t n_counter = prescaler * b_counter + a_counter; -static const size_t vco_clock_rate = ref_clock_rate/r_counter * n_counter; +static const size_t vco_clock_rate = ref_clock_rate/r_counter * n_counter; //between 1400 and 1800 MHz static const double master_clock_rate = vco_clock_rate/vco_divider; static const size_t fpga_clock_divider = size_t(master_clock_rate/64e6); @@ -60,15 +60,18 @@ class usrp_e_clock_ctrl_impl : public usrp_e_clock_ctrl{ public: usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface){ _iface = iface; + std::cout << "master_clock_rate: " << (master_clock_rate/1e6) << " MHz" << std::endl; //init the clock gen registers //Note: out0 should already be clocking the FPGA or this isnt going to work _ad9522_regs.sdo_active = ad9522_regs_t::SDO_ACTIVE_SDO_SDIO; + _ad9522_regs.enb_stat_eeprom_at_stat_pin = 0; //use status pin _ad9522_regs.status_pin_control = 0x1; //n divider - _ad9522_regs.ld_pin_control = 0x32; //show ref2 + _ad9522_regs.ld_pin_control = 0x00; //dld _ad9522_regs.refmon_pin_control = 0x12; //show ref2 _ad9522_regs.enable_ref2 = 1; + _ad9522_regs.enable_ref1 = 0; _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF2; _ad9522_regs.set_r_counter(r_counter); @@ -80,7 +83,7 @@ public: _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_3_0MA; _ad9522_regs.vco_calibration_now = 1; //calibrate it! - _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; + _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV1; _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_VCO; //setup fpga master clock -- cgit v1.2.3 From 998fee6ef064f1d53a61dd0eec79276d1e85291e Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Jul 2010 02:19:20 +0000 Subject: usrp-e: removed top level header for usrp-e and fpga burner app, were not going to do it that way... --- host/include/uhd/usrp/CMakeLists.txt | 4 --- host/include/uhd/usrp/usrp_e.hpp | 54 --------------------------------- host/lib/usrp/usrp_e/CMakeLists.txt | 3 -- host/lib/usrp/usrp_e/fpga-downloader.cc | 3 +- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 16 +++++----- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 7 +++-- host/lib/usrp/usrp_e/usrp_e_none.cpp | 38 ----------------------- host/utils/CMakeLists.txt | 4 --- host/utils/usrp_e_load_fpga.cpp | 47 ---------------------------- 9 files changed, 14 insertions(+), 162 deletions(-) delete mode 100644 host/include/uhd/usrp/usrp_e.hpp delete mode 100644 host/lib/usrp/usrp_e/usrp_e_none.cpp delete mode 100644 host/utils/usrp_e_load_fpga.cpp (limited to 'host') diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt index ff2636d8c..58aa8588a 100644 --- a/host/include/uhd/usrp/CMakeLists.txt +++ b/host/include/uhd/usrp/CMakeLists.txt @@ -31,10 +31,6 @@ INSTALL(FILES dboard_iface.hpp dboard_manager.hpp - ### usrp headers ### - usrp_e.hpp - usrp2.hpp - ### utilities ### tune_helper.hpp simple_usrp.hpp diff --git a/host/include/uhd/usrp/usrp_e.hpp b/host/include/uhd/usrp/usrp_e.hpp deleted file mode 100644 index 557058261..000000000 --- a/host/include/uhd/usrp/usrp_e.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2010 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 . -// - -#ifndef INCLUDED_UHD_USRP_USRP_E_HPP -#define INCLUDED_UHD_USRP_USRP_E_HPP - -#include -#include - -namespace uhd{ namespace usrp{ - -/*! - * The USRP-Embedded device class. - */ -class UHD_API usrp_e : public device{ -public: - /*! - * Find usrp_e devices on the system via the device node. - * \param hint a device addr with the usrp_e address filled in - * \return a vector of device addresses for all usrp-e's found - */ - static device_addrs_t find(const device_addr_t &hint); - - /*! - * Make a usrp_e from a device address. - * \param addr the device address - * \return a device sptr to a new usrp_e - */ - static device::sptr make(const device_addr_t &addr); - - /*! - * Load the FPGA with an image file. - * \param bin_file the name of the fpga image file - */ - static void load_fpga(const std::string &bin_file); -}; - -}} //namespace - -#endif /* INCLUDED_UHD_USRP_USRP_E_HPP */ diff --git a/host/lib/usrp/usrp_e/CMakeLists.txt b/host/lib/usrp/usrp_e/CMakeLists.txt index 568fbd132..db6d162d4 100644 --- a/host/lib/usrp/usrp_e/CMakeLists.txt +++ b/host/lib/usrp/usrp_e/CMakeLists.txt @@ -59,7 +59,4 @@ IF(HAVE_USRP_E_REQUIRED_HEADERS) ) ELSE(HAVE_USRP_E_REQUIRED_HEADERS) MESSAGE(STATUS " Skipping usrp-e support.") - LIBUHD_APPEND_SOURCES( - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_none.cpp - ) ENDIF(HAVE_USRP_E_REQUIRED_HEADERS) diff --git a/host/lib/usrp/usrp_e/fpga-downloader.cc b/host/lib/usrp/usrp_e/fpga-downloader.cc index 4429786a9..ff8671e98 100644 --- a/host/lib/usrp/usrp_e/fpga-downloader.cc +++ b/host/lib/usrp/usrp_e/fpga-downloader.cc @@ -246,8 +246,7 @@ int main(int argc, char *argv[]) } */ -#include -void uhd::usrp::usrp_e::load_fpga(const std::string &bin_file){ +void usrp_e_load_fpga(const std::string &bin_file){ gpio gpio_prog_b(PROG_B, OUT); gpio gpio_init_b(INIT_B, IN); gpio gpio_done (DONE, IN); diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index a534c74b2..76c77af15 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -27,10 +27,6 @@ using namespace uhd; using namespace uhd::usrp; namespace fs = boost::filesystem; -UHD_STATIC_BLOCK(register_usrp_e_device){ - device::register_device(&usrp_e::find, &usrp_e::make); -} - /*********************************************************************** * Helper Functions **********************************************************************/ @@ -41,7 +37,7 @@ static std::string abs_path(const std::string &file_path){ /*********************************************************************** * Discovery **********************************************************************/ -device_addrs_t usrp_e::find(const device_addr_t &hint){ +static device_addrs_t usrp_e_find(const device_addr_t &hint){ device_addrs_t usrp_e_addrs; //return an empty list of addresses when type is set to non-usrp-e @@ -51,7 +47,7 @@ device_addrs_t usrp_e::find(const device_addr_t &hint){ if (not hint.has_key("node")){ device_addr_t new_addr = hint; new_addr["node"] = "/dev/usrp_e0"; - return usrp_e::find(new_addr); + return usrp_e_find(new_addr); } //use the given device node name @@ -68,8 +64,12 @@ device_addrs_t usrp_e::find(const device_addr_t &hint){ /*********************************************************************** * Make **********************************************************************/ -device::sptr usrp_e::make(const device_addr_t &device_addr){ - return sptr(new usrp_e_impl(device_addr["node"])); +static device::sptr usrp_e_make(const device_addr_t &device_addr){ + return device::sptr(new usrp_e_impl(device_addr["node"])); +} + +UHD_STATIC_BLOCK(register_usrp_e_device){ + device::register_device(&usrp_e_find, &usrp_e_make); } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 487e295cb..e6bea1358 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -18,8 +18,8 @@ #include "usrp_e_iface.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" +#include #include -#include #include #include #include @@ -28,7 +28,10 @@ #ifndef INCLUDED_USRP_E_IMPL_HPP #define INCLUDED_USRP_E_IMPL_HPP -static const double MASTER_CLOCK_RATE = 64e6; +static const double MASTER_CLOCK_RATE = 64e6; //TODO get from clock control + +//! load an fpga image from a bin file into the usrp-e fpga +extern void usrp_e_load_fpga(const std::string &bin_file); /*! * Make a usrp-e dboard interface. diff --git a/host/lib/usrp/usrp_e/usrp_e_none.cpp b/host/lib/usrp/usrp_e/usrp_e_none.cpp deleted file mode 100644 index 09a3c6946..000000000 --- a/host/lib/usrp/usrp_e/usrp_e_none.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include - -using namespace uhd; -using namespace uhd::usrp; - -/*! - * This file defines the usrp1e discover and make functions - * when the required kernel module headers are not present. - */ - -device_addrs_t usrp_e::find(const device_addr_t &){ - return device_addrs_t(); //return empty list -} - -device::sptr usrp_e::make(const device_addr_t &){ - throw std::runtime_error("this build has no usrp1e support"); -} - -void usrp_e::load_fpga(const std::string &){ - throw std::runtime_error("this build has no usrp1e support"); -} diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index cf056e135..8d260c06c 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -19,10 +19,6 @@ ADD_EXECUTABLE(uhd_find_devices uhd_find_devices.cpp) TARGET_LINK_LIBRARIES(uhd_find_devices uhd) INSTALL(TARGETS uhd_find_devices RUNTIME DESTINATION ${RUNTIME_DIR}) -ADD_EXECUTABLE(usrp_e_load_fpga usrp_e_load_fpga.cpp) -TARGET_LINK_LIBRARIES(usrp_e_load_fpga uhd) -INSTALL(TARGETS usrp_e_load_fpga RUNTIME DESTINATION ${PKG_DATA_DIR}/utils) - ADD_EXECUTABLE(uhd_usrp_probe uhd_usrp_probe.cpp) TARGET_LINK_LIBRARIES(uhd_usrp_probe uhd) INSTALL(TARGETS uhd_usrp_probe RUNTIME DESTINATION ${RUNTIME_DIR}) diff --git a/host/utils/usrp_e_load_fpga.cpp b/host/utils/usrp_e_load_fpga.cpp deleted file mode 100644 index 403130b53..000000000 --- a/host/utils/usrp_e_load_fpga.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include -#include -#include -#include - -namespace po = boost::program_options; - -int main(int argc, char *argv[]){ - po::options_description desc("Allowed options"); - desc.add_options() - ("help", "help message") - ("file", po::value(), "path to fpga bin file") - ; - - po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - - //print the help message - if (vm.count("help") or vm.count("file") == 0){ - std::cout << boost::format("USRP1E Load FPGA %s") % desc << std::endl; - return ~0; - } - - //load the fpga - std::string file = vm["file"].as(); - uhd::usrp::usrp_e::load_fpga(file); - - return 0; -} -- cgit v1.2.3 From 416f720e56ff4542d5ba4b8c9c145f0a09bf341b Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Jul 2010 03:40:25 +0000 Subject: uhd: updated code to build with latest api, not tested --- host/lib/usrp/usrp_e/io_impl.cpp | 112 ++++++++++++++++++++++------------- host/lib/usrp/usrp_e/mboard_impl.cpp | 4 +- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 4 +- 3 files changed, 74 insertions(+), 46 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index c168d6304..a77a73b38 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -24,6 +24,7 @@ #include //offsetof #include #include +#include #include using namespace uhd; @@ -127,10 +128,11 @@ private: * IO Implementation Details **********************************************************************/ struct usrp_e_impl::io_impl{ - vrt_packet_handler::recv_state recv_state; - vrt_packet_handler::send_state send_state; + //state management for the vrt packet handler code + vrt_packet_handler::recv_state packet_handler_recv_state; + vrt_packet_handler::send_state packet_handler_send_state; data_transport transport; - io_impl(int fd): transport(fd){} + io_impl(int fd): packet_handler_recv_state(1), transport(fd){} }; void usrp_e_impl::io_init(void){ @@ -150,35 +152,56 @@ void usrp_e_impl::io_init(void){ _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface->get_file_descriptor())); } -static boost::uint32_t make_stream_cmd(bool now, bool chain, boost::uint32_t nsamps){ - return (((now)? 1 : 0) << 31) | (((chain)? 1 : 0) << 30) | nsamps; +static boost::uint32_t make_stream_cmd(bool now, bool chain, bool reload, boost::uint32_t nsamps){ + return (((now)? 1 : 0) << 31) | (((chain)? 1 : 0) << 30) | (((reload)? 1 : 0) << 29) | nsamps; } void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ - boost::uint32_t cmd = 0; - switch(stream_cmd.stream_mode){ - case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE: - cmd = make_stream_cmd(stream_cmd.stream_now, false, stream_cmd.num_samps); - break; + UHD_ASSERT_THROW(stream_cmd.num_samps <= 0x3fffffff); - case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE: - cmd = make_stream_cmd(stream_cmd.stream_now, true, stream_cmd.num_samps); - break; + //setup the mode to instruction flags + typedef boost::tuple inst_t; + static const uhd::dict mode_to_inst = boost::assign::map_list_of + //reload, chain, samps + (stream_cmd_t::STREAM_MODE_START_CONTINUOUS, inst_t(true, true, false)) + (stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS, inst_t(false, false, false)) + (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE, inst_t(false, false, true)) + (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE, inst_t(false, true, true)) + ; + + //setup the instruction flag values + bool inst_reload, inst_chain, inst_samps; + boost::tie(inst_reload, inst_chain, inst_samps) = mode_to_inst[stream_cmd.stream_mode]; + + //issue the stream command + _iface->poke32(UE_REG_CTRL_RX_STREAM_CMD, make_stream_cmd( + (inst_samps)? stream_cmd.num_samps : ((inst_chain)? get_max_recv_samps_per_packet() : 1), + (stream_cmd.stream_now)? 1 : 0, + (inst_chain)? 1 : 0, + (inst_reload)? 1 : 0 + )); + _iface->poke32(UE_REG_CTRL_RX_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); + _iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_tick_count(MASTER_CLOCK_RATE)); - default: throw std::runtime_error("stream mode not implemented"); - } - _iface->poke32(UE_REG_CTRL_RX_STREAM_CMD, cmd); - _iface->poke32(UE_REG_CTRL_RX_TIME_SECS, stream_cmd.time_spec.secs); - _iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_ticks(MASTER_CLOCK_RATE)); } /*********************************************************************** * Data Send **********************************************************************/ +bool get_send_buffs( + data_transport *trans, + vrt_packet_handler::managed_send_buffs_t &buffs +){ + UHD_ASSERT_THROW(buffs.size() == 1); + buffs[0] = trans->get_send_buff(); + return buffs[0].get() != NULL; +} + size_t usrp_e_impl::send( - const boost::asio::const_buffer &buff, - const uhd::tx_metadata_t &metadata, - const io_type_t & io_type, + const std::vector &buffs, + size_t num_samps, + const tx_metadata_t &metadata, + const io_type_t &io_type, send_mode_t send_mode ){ otw_type_t send_otw_type; @@ -187,15 +210,13 @@ size_t usrp_e_impl::send( send_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; return vrt_packet_handler::send( - _io_impl->send_state, - buff, - metadata, - send_mode, - io_type, - send_otw_type, //TODO - MASTER_CLOCK_RATE, - uhd::transport::vrt::pack_le, - boost::bind(&data_transport::get_send_buff, &_io_impl->transport), + _io_impl->packet_handler_send_state, //last state of the send handler + buffs, num_samps, //buffer to fill + metadata, send_mode, //samples metadata + io_type, send_otw_type, //input and output types to convert + MASTER_CLOCK_RATE, //master clock tick rate + uhd::transport::vrt::if_hdr_pack_le, + boost::bind(&get_send_buffs, &_io_impl->transport, _1), get_max_send_samps_per_packet(), vrt_header_offset_words32 ); @@ -204,9 +225,19 @@ size_t usrp_e_impl::send( /*********************************************************************** * Data Recv **********************************************************************/ +bool get_recv_buffs( + data_transport *trans, + vrt_packet_handler::managed_recv_buffs_t &buffs +){ + UHD_ASSERT_THROW(buffs.size() == 1); + buffs[0] = trans->get_recv_buff(); + return buffs[0].get() != NULL; +} + size_t usrp_e_impl::recv( - const boost::asio::mutable_buffer &buff, - uhd::rx_metadata_t &metadata, + const std::vector &buffs, + size_t num_samps, + rx_metadata_t &metadata, const io_type_t &io_type, recv_mode_t recv_mode ){ @@ -216,15 +247,12 @@ size_t usrp_e_impl::recv( recv_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; return vrt_packet_handler::recv( - _io_impl->recv_state, - buff, - metadata, - recv_mode, - io_type, - recv_otw_type, //TODO - MASTER_CLOCK_RATE, - uhd::transport::vrt::unpack_le, - boost::bind(&data_transport::get_recv_buff, &_io_impl->transport), - vrt_header_offset_words32 + _io_impl->packet_handler_recv_state, //last state of the recv handler + buffs, num_samps, //buffer to fill + metadata, recv_mode, //samples metadata + io_type, recv_otw_type, //input and output types to convert + MASTER_CLOCK_RATE, //master clock tick rate + uhd::transport::vrt::if_hdr_unpack_le, + boost::bind(get_recv_buffs, &_io_impl->transport, _1) ); } diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index e4a0e81af..e27c1964a 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -116,10 +116,10 @@ void usrp_e_impl::mboard_set(const wax::obj &key, const wax::obj &val){ case MBOARD_PROP_TIME_NOW: case MBOARD_PROP_TIME_NEXT_PPS:{ time_spec_t time_spec = val.as(); - _iface->poke32(UE_REG_TIME64_TICKS, time_spec.get_ticks(MASTER_CLOCK_RATE)); + _iface->poke32(UE_REG_TIME64_TICKS, time_spec.get_tick_count(MASTER_CLOCK_RATE)); boost::uint32_t imm_flags = (key.as() == MBOARD_PROP_TIME_NOW)? 1 : 0; _iface->poke32(UE_REG_TIME64_IMM, imm_flags); - _iface->poke32(UE_REG_TIME64_SECS, time_spec.secs); + _iface->poke32(UE_REG_TIME64_SECS, time_spec.get_full_secs()); } return; diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index e6bea1358..c0e302bd8 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -81,8 +81,8 @@ public: ~usrp_e_impl(void); //the io interface - size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t); - size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t); + size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t); + size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t); size_t get_max_send_samps_per_packet(void) const{return 300;} size_t get_max_recv_samps_per_packet(void) const{return 300;} -- cgit v1.2.3 From 7c2e17b549fefb5a667cf77dd7d86ed55f7ebe13 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Jul 2010 18:44:16 +0000 Subject: usrp-e: replaced stream cmd logic with common dsp type1 logic --- host/lib/usrp/usrp_e/io_impl.cpp | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index a77a73b38..9ebd55eac 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -17,6 +17,7 @@ #include "usrp_e_impl.hpp" #include "usrp_e_regs.hpp" +#include "../dsp_utils.hpp" #include "../../transport/vrt_packet_handler.hpp" #include #include //read, write @@ -24,10 +25,10 @@ #include //offsetof #include #include -#include #include using namespace uhd; +using namespace uhd::usrp; /*********************************************************************** * Constants @@ -152,33 +153,9 @@ void usrp_e_impl::io_init(void){ _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface->get_file_descriptor())); } -static boost::uint32_t make_stream_cmd(bool now, bool chain, bool reload, boost::uint32_t nsamps){ - return (((now)? 1 : 0) << 31) | (((chain)? 1 : 0) << 30) | (((reload)? 1 : 0) << 29) | nsamps; -} - void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ - UHD_ASSERT_THROW(stream_cmd.num_samps <= 0x3fffffff); - - //setup the mode to instruction flags - typedef boost::tuple inst_t; - static const uhd::dict mode_to_inst = boost::assign::map_list_of - //reload, chain, samps - (stream_cmd_t::STREAM_MODE_START_CONTINUOUS, inst_t(true, true, false)) - (stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS, inst_t(false, false, false)) - (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE, inst_t(false, false, true)) - (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE, inst_t(false, true, true)) - ; - - //setup the instruction flag values - bool inst_reload, inst_chain, inst_samps; - boost::tie(inst_reload, inst_chain, inst_samps) = mode_to_inst[stream_cmd.stream_mode]; - - //issue the stream command - _iface->poke32(UE_REG_CTRL_RX_STREAM_CMD, make_stream_cmd( - (inst_samps)? stream_cmd.num_samps : ((inst_chain)? get_max_recv_samps_per_packet() : 1), - (stream_cmd.stream_now)? 1 : 0, - (inst_chain)? 1 : 0, - (inst_reload)? 1 : 0 + _iface->poke32(UE_REG_CTRL_RX_STREAM_CMD, dsp_type1::calc_stream_cmd_word( + stream_cmd, get_max_recv_samps_per_packet() )); _iface->poke32(UE_REG_CTRL_RX_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); _iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_tick_count(MASTER_CLOCK_RATE)); -- cgit v1.2.3 From b285d23f5eba9b65f9baf799fee3f1389c132632 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Jul 2010 22:55:14 +0000 Subject: usrp-e: fixed send and recv logic in io impl to deal with frame length correctly --- host/lib/usrp/usrp_e/io_impl.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 9ebd55eac..8bcff1352 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -22,7 +22,6 @@ #include #include //read, write #include //transfer frame struct -#include //offsetof #include #include #include @@ -34,7 +33,7 @@ using namespace uhd::usrp; * Constants **********************************************************************/ static const size_t MAX_BUFF_SIZE = 2048; -static const size_t vrt_header_offset_words32 = offsetof(usrp_transfer_frame, buf)/sizeof(boost::uint32_t); +static const size_t vrt_header_offset_words32 = sizeof(usrp_transfer_frame)/sizeof(boost::uint32_t); static const bool usrp_e_io_impl_verbose = true; static const size_t recv_timeout_ms = 100; @@ -71,7 +70,7 @@ private: //and the send buffer commit method will set the length. const_cast( boost::asio::buffer_cast(buff) - )->len = boost::asio::buffer_size(buff); + )->len = boost::asio::buffer_size(buff) - sizeof(usrp_transfer_frame); return write( _fd, boost::asio::buffer_cast(buff), @@ -112,16 +111,16 @@ private: } //overwrite the vrt header length with the transfer frame length - size_t frame_size = boost::asio::buffer_cast(buff)->len; - boost::uint32_t *vrt_header = boost::asio::buffer_cast(buff) + vrt_header_offset_words32; - vrt_header[0] = (vrt_header[0] & ~0xffff) | ((frame_size/sizeof(boost::uint32_t)) & 0xffff); + usrp_transfer_frame *frame = boost::asio::buffer_cast(buff); + boost::uint32_t *vrt_header = reinterpret_cast(frame->buf); + vrt_header[0] = (vrt_header[0] & ~0xffff) | ((frame->len/sizeof(boost::uint32_t)) & 0xffff); - //std::cout << "len " << int(boost::asio::buffer_cast(buff)->len) << std::endl; + //std::cout << "len " << int(frame->len) << std::endl; //for (size_t i = 0; i < 7; i++){ // std::cout << boost::format(" 0x%08x") % boost::asio::buffer_cast(buff)[i] << std::endl; //} - return frame_size; + return read_ret; } }; @@ -230,6 +229,7 @@ size_t usrp_e_impl::recv( io_type, recv_otw_type, //input and output types to convert MASTER_CLOCK_RATE, //master clock tick rate uhd::transport::vrt::if_hdr_unpack_le, - boost::bind(get_recv_buffs, &_io_impl->transport, _1) + boost::bind(get_recv_buffs, &_io_impl->transport, _1), + vrt_header_offset_words32 ); } -- cgit v1.2.3 From ead865c28690deb1566ce6a20f54cfb43484ad01 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 10 Jul 2010 06:13:47 +0000 Subject: usrp-e: added io_impl handle overrun --- host/lib/usrp/usrp_e/io_impl.cpp | 26 ++++++++++++++++++-------- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 1 + 2 files changed, 19 insertions(+), 8 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 8bcff1352..d1a00bf25 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -63,7 +63,7 @@ public: private: int _fd; - size_t send(const boost::asio::const_buffer &buff){ + ssize_t send(const boost::asio::const_buffer &buff){ //Set the frame length in the frame header. //This is technically bad to write to a const buffer, //but this will go away when the ring gets implemented, @@ -77,7 +77,7 @@ private: boost::asio::buffer_size(buff) ); } - size_t recv(const boost::asio::mutable_buffer &buff){ + ssize_t recv(const boost::asio::mutable_buffer &buff){ //std::cout << boost::format( // "calling read on fd %d, buff size is %d" //) % _fd % boost::asio::buffer_size(buff) << std::endl; @@ -105,9 +105,9 @@ private: if (read_ret < ssize_t(sizeof(usrp_transfer_frame))){ if (usrp_e_io_impl_verbose) std::cerr << boost::format( "usrp-e io impl recv(): read() returned small value: %d\n" - " -> return 0 for error" + " -> return -1 for error" ) % read_ret << std::endl; - return 0; + return -1; } //overwrite the vrt header length with the transfer frame length @@ -116,7 +116,7 @@ private: vrt_header[0] = (vrt_header[0] & ~0xffff) | ((frame->len/sizeof(boost::uint32_t)) & 0xffff); //std::cout << "len " << int(frame->len) << std::endl; - //for (size_t i = 0; i < 7; i++){ + //for (size_t i = 0; i < 9; i++){ // std::cout << boost::format(" 0x%08x") % boost::asio::buffer_cast(buff)[i] << std::endl; //} @@ -132,6 +132,7 @@ struct usrp_e_impl::io_impl{ vrt_packet_handler::recv_state packet_handler_recv_state; vrt_packet_handler::send_state packet_handler_send_state; data_transport transport; + bool continuous_streaming; io_impl(int fd): packet_handler_recv_state(1), transport(fd){} }; @@ -153,12 +154,20 @@ void usrp_e_impl::io_init(void){ } void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ + _io_impl->continuous_streaming = (stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS); _iface->poke32(UE_REG_CTRL_RX_STREAM_CMD, dsp_type1::calc_stream_cmd_word( stream_cmd, get_max_recv_samps_per_packet() )); _iface->poke32(UE_REG_CTRL_RX_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); _iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_tick_count(MASTER_CLOCK_RATE)); +} +void usrp_e_impl::handle_overrun(size_t){ + std::cerr << "O"; //the famous OOOOOOOOOOO + _iface->poke32(UE_REG_CTRL_RX_CLEAR_OVERRUN, 0); + if (_io_impl->continuous_streaming){ + this->issue_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + } } /*********************************************************************** @@ -170,7 +179,7 @@ bool get_send_buffs( ){ UHD_ASSERT_THROW(buffs.size() == 1); buffs[0] = trans->get_send_buff(); - return buffs[0].get() != NULL; + return buffs[0].get(); } size_t usrp_e_impl::send( @@ -207,7 +216,7 @@ bool get_recv_buffs( ){ UHD_ASSERT_THROW(buffs.size() == 1); buffs[0] = trans->get_recv_buff(); - return buffs[0].get() != NULL; + return buffs[0].get(); } size_t usrp_e_impl::recv( @@ -229,7 +238,8 @@ size_t usrp_e_impl::recv( io_type, recv_otw_type, //input and output types to convert MASTER_CLOCK_RATE, //master clock tick rate uhd::transport::vrt::if_hdr_unpack_le, - boost::bind(get_recv_buffs, &_io_impl->transport, _1), + boost::bind(&get_recv_buffs, &_io_impl->transport, _1), + boost::bind(&usrp_e_impl::handle_overrun, this, _1), vrt_header_offset_words32 ); } diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index c0e302bd8..4a63a6d21 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -97,6 +97,7 @@ private: UHD_PIMPL_DECL(io_impl) _io_impl; void io_init(void); void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd); + void handle_overrun(size_t); //configuration shadows uhd::clock_config_t _clock_config; -- cgit v1.2.3 From d9b7d9f2f9c6ebe27b6cfd4085f4a5c524363a1f Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 14 Jul 2010 22:16:52 +0000 Subject: Convert basic test programs to use shorts in the GPP to avoid using short to float code in uhd. --- host/examples/rx_timed_samples.cpp | 6 +++--- host/examples/tx_timed_samples.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'host') diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 3b9acbb2c..a72e1ec81 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -84,12 +84,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //loop until total number of samples reached size_t num_acc_samps = 0; //number of accumulated samples + uhd::rx_metadata_t md; + std::vector > buff(dev->get_max_recv_samps_per_packet()); while(num_acc_samps < total_num_samps){ - uhd::rx_metadata_t md; - std::vector > buff(dev->get_max_recv_samps_per_packet()); size_t num_rx_samps = dev->recv( &buff.front(), buff.size(), md, - uhd::io_type_t::COMPLEX_FLOAT32, + uhd::io_type_t::COMPLEX_INT16, uhd::device::RECV_MODE_ONE_PACKET ); diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index 5b72bd72f..ceae58a22 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -77,13 +77,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ sdev->set_time_now(uhd::time_spec_t(0.0)); //allocate data to send - std::vector > buff(samps_per_packet, std::complex(ampl, ampl)); + std::vector > buff(samps_per_packet, std::complex(ampl, ampl)); + uhd::tx_metadata_t md; //send the data in multiple packets size_t num_packets = (total_num_samps+samps_per_packet-1)/samps_per_packet; for (size_t i = 0; i < num_packets; i++){ //setup the metadata flags and time spec - uhd::tx_metadata_t md; md.start_of_burst = true; //always SOB (good for continuous streaming) md.end_of_burst = (i == num_packets-1); //only last packet has EOB md.has_time_spec = (i == 0); //only first packet has time @@ -94,7 +94,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //send the entire packet (driver fragments internally) size_t num_tx_samps = dev->send( &buff.front(), samps_to_send, md, - uhd::io_type_t::COMPLEX_FLOAT32, + uhd::io_type_t::COMPLEX_INT16, uhd::device::SEND_MODE_FULL_BUFF ); if(verbose) std::cout << std::endl << boost::format("Sent %d samples") % num_tx_samps << std::endl; -- cgit v1.2.3 From 624eb248cd5ee2343cb0f4f24f60916ea51b60fd Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 14 Jul 2010 22:17:35 +0000 Subject: Use largest possible packets for transfers. --- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 4a63a6d21..efbf9f68f 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -83,8 +83,8 @@ public: //the io interface size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t); size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t); - size_t get_max_send_samps_per_packet(void) const{return 300;} - size_t get_max_recv_samps_per_packet(void) const{return 300;} + size_t get_max_send_samps_per_packet(void) const{return 503;} + size_t get_max_recv_samps_per_packet(void) const{return 503;} private: //interface to ioctls and file descriptor -- cgit v1.2.3 From a47e75c84099081a7f7b2a13e11c3615bed22a5c Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 16 Jul 2010 07:22:11 +0000 Subject: usrp-e: removed vrt header rewrite in io impl, its not in vrt packet parser stuff --- host/lib/usrp/usrp_e/io_impl.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index d1a00bf25..ecde9ca27 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -110,11 +110,7 @@ private: return -1; } - //overwrite the vrt header length with the transfer frame length - usrp_transfer_frame *frame = boost::asio::buffer_cast(buff); - boost::uint32_t *vrt_header = reinterpret_cast(frame->buf); - vrt_header[0] = (vrt_header[0] & ~0xffff) | ((frame->len/sizeof(boost::uint32_t)) & 0xffff); - + //usrp_transfer_frame *frame = boost::asio::buffer_cast(buff); //std::cout << "len " << int(frame->len) << std::endl; //for (size_t i = 0; i < 9; i++){ // std::cout << boost::format(" 0x%08x") % boost::asio::buffer_cast(buff)[i] << std::endl; -- cgit v1.2.3 From 1301d665d621358ec6eccb41a020a4689cb0b566 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 3 Aug 2010 17:57:39 -0700 Subject: usrp-e: fixed clock div calculation bug --- host/lib/usrp/usrp_e/clock_ctrl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index df649cee6..8a5bd1c6b 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -164,7 +164,7 @@ public: void set_rx_dboard_clock_rate(double rate){ assert_has(get_rx_dboard_clock_rates(), rate, "rx dboard clock rate"); - size_t divider = size_t(rate/master_clock_rate); + size_t divider = size_t(master_clock_rate/rate); //set the divider registers set_clock_divider(divider, _ad9522_regs.divider3_low_cycles, @@ -194,7 +194,7 @@ public: void set_tx_dboard_clock_rate(double rate){ assert_has(get_tx_dboard_clock_rates(), rate, "tx dboard clock rate"); - size_t divider = size_t(rate/master_clock_rate); + size_t divider = size_t(master_clock_rate/rate); //set the divider registers set_clock_divider(divider, _ad9522_regs.divider2_low_cycles, -- cgit v1.2.3 From cb92934527964b8fda924925dbc12b18d5ae7fad Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 11 Aug 2010 01:05:47 +0000 Subject: Loopback test now supports variable size and works with mmapable ring buffer. --- host/apps/omap_debug/Makefile | 6 +- host/apps/omap_debug/usrp-e-loopback.c | 39 ++++-- host/apps/omap_debug/usrp-e-mm-loopback.c | 194 ++++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+), 12 deletions(-) create mode 100644 host/apps/omap_debug/usrp-e-mm-loopback.c (limited to 'host') diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index c11609bdd..46d4714a8 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,7 +1,7 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 CXXFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 -all : usrp-e-spi usrp-e-i2c usrp-e-loopback usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-random-loopback usrp-e-timed usrp-e-lb-test usrp-e-crc-rw clkgen-config +all : usrp-e-spi usrp-e-i2c usrp-e-loopback usrp-e-mm-loopback usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-random-loopback usrp-e-timed usrp-e-lb-test usrp-e-crc-rw clkgen-config usrp-e-spi : usrp-e-spi.c @@ -10,6 +10,9 @@ usrp-e-i2c : usrp-e-i2c.c usrp-e-loopback : usrp-e-loopback.c gcc -o $@ $< -lpthread ${CFLAGS} +usrp-e-mm-loopback : usrp-e-mm-loopback.c + gcc -o $@ $< -lpthread ${CFLAGS} + usrp-e-timed : usrp-e-timed.c gcc -o $@ $< -lpthread ${CFLAGS} @@ -42,6 +45,7 @@ clean : rm -f usrp-e-spi rm -f usrp-e-i2c rm -f usrp-e-loopback + rm -f usrp-e-mm-loopback rm -f usrp-e-timed rm -f usrp-e-rw-random rm -f usrp-e-uart diff --git a/host/apps/omap_debug/usrp-e-loopback.c b/host/apps/omap_debug/usrp-e-loopback.c index 929d65604..c463e774d 100644 --- a/host/apps/omap_debug/usrp-e-loopback.c +++ b/host/apps/omap_debug/usrp-e-loopback.c @@ -14,6 +14,7 @@ static int error; struct pkt { int checksum; int seq_num; + int len; short data[]; }; @@ -26,10 +27,11 @@ static int calc_checksum(struct pkt *p) i = 0; sum = 0; - for (i=0; i < packet_data_length; i++) + for (i=0; i < p->len; i++) sum += p->data[i]; sum += p->seq_num; + sum += p->len; return sum; } @@ -48,7 +50,7 @@ static void *read_thread(void *threadid) gettimeofday(&start_time, NULL); // IMPORTANT: must assume max length packet from fpga - rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1016 * 2)); + rx_data = malloc(2048); p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); //p = &(rx_data->buf[0]); printf("Address of rx_data = %p, p = %p\n", rx_data, p); @@ -60,14 +62,16 @@ static void *read_thread(void *threadid) seq_num_failure = 0; while (1) { - cnt = read(fp, rx_data, 2048); if (cnt < 0) printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); // printf("Packet received, status = %X, len = %d\n", rx_data->status, rx_data->len); -// printf("p->seq_num = %d\n", p->seq_num); +// printf("p->seq_num = %d, p->len = %d\n", p->seq_num, p->len); + + if (rx_data->len != (p->len*2 + 12)) + printf("rx_data->len = %d, p->len*2 + 12 = %d\n", rx_data->len, p->len*2 + 12); pkt_count++; @@ -83,8 +87,8 @@ static void *read_thread(void *threadid) prev_seq_num = p->seq_num; if (calc_checksum(p) != p->checksum) { - printf("Checksum fail packet = %X, expected = %X, pkt_count = %d\n", - calc_checksum(p), p->checksum, pkt_count); + printf("Cksum fail rx = %X, tx = %X, dif = %d, count = %d, len = %d, rx->len = %d\n", + calc_checksum(p), p->checksum, p->checksum - calc_checksum(p), pkt_count, p->len, rx_data->len); error = 1; } @@ -112,24 +116,23 @@ static void *read_thread(void *threadid) static void *write_thread(void *threadid) { - int seq_number, i, cnt; + int seq_number, i, cnt, data_length; struct usrp_transfer_frame *tx_data; struct pkt *p; printf("Greetings from the write thread!\n"); - tx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (packet_data_length * 2)); + tx_data = malloc(2048); p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); printf("Address of tx_data = %p, p = %p\n", tx_data, p); printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); - for (i=0; i < packet_data_length; i++) + for (i=0; i < 2048; i++) // p->data[i] = random() >> 16; p->data[i] = i; tx_data->status = 0xdeadbeef; - tx_data->len = 8 + packet_data_length * 2; printf("tx_data->len = %d\n", tx_data->len); @@ -137,9 +140,23 @@ static void *write_thread(void *threadid) while (1) { // printf("tx status = %X, len = %d\n", tx_data->status, tx_data->len); + if (packet_data_length > 0) + data_length = packet_data_length; + else + data_length = (random() & 0x1ff) + (1004 - 512); + +// printf("data_length = %d\n", data_length); + p->seq_num = seq_number++; + p->len = data_length; p->checksum = calc_checksum(p); - cnt = write(fp, tx_data, 2048); + tx_data->len = 12 + p->len * 2; + +// printf("tx status = %X, len = %d, p->len = %d\n", tx_data->status, tx_data->len, p->len); + + cnt = write(fp, tx_data, sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + 2 * p->len); +// cnt = write(fp, tx_data, 2048); + if (cnt < 0) printf("Error returned from write: %d\n", cnt); // sleep(1); diff --git a/host/apps/omap_debug/usrp-e-mm-loopback.c b/host/apps/omap_debug/usrp-e-mm-loopback.c new file mode 100644 index 000000000..d11cf7d09 --- /dev/null +++ b/host/apps/omap_debug/usrp-e-mm-loopback.c @@ -0,0 +1,194 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "usrp_e.h" + +// max length #define PKT_DATA_LENGTH 1016 +static int packet_data_length; +static int error; + +struct pkt { + int len; + int checksum; + int seq_num; + short data[]; +}; + +static int fp; + +static int calc_checksum(struct pkt *p) +{ + int i, sum; + + i = 0; + sum = 0; + + for (i=0; i < p->len; i++) + sum += p->data[i]; + + sum += p->seq_num; + sum += p->len; + + return sum; +} + +static void *read_thread(void *threadid) +{ + char *rx_data; + int cnt, prev_seq_num, pkt_count, seq_num_failure; + struct pkt *p; + unsigned long bytes_transfered, elapsed_seconds; + struct timeval start_time, finish_time; + + printf("Greetings from the reading thread!\n"); + + bytes_transfered = 0; + gettimeofday(&start_time, NULL); + + // IMPORTANT: must assume max length packet from fpga + rx_data = malloc(2048); + p = (struct pkt *) ((void *)rx_data); + + prev_seq_num = 0; + pkt_count = 0; + seq_num_failure = 0; + + while (1) { + + cnt = read(fp, rx_data, 2048); + if (cnt < 0) + printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); + +// printf("p->seq_num = %d\n", p->seq_num); + + + pkt_count++; + + if (p->seq_num != prev_seq_num + 1) { + printf("Sequence number fail, current = %d, previous = %d, pkt_count = %d\n", + p->seq_num, prev_seq_num, pkt_count); + + seq_num_failure ++; + if (seq_num_failure > 2) + error = 1; + } + + prev_seq_num = p->seq_num; + + if (calc_checksum(p) != p->checksum) { + printf("Checksum fail packet = %X, expected = %X, pkt_count = %d\n", + calc_checksum(p), p->checksum, pkt_count); + error = 1; + } + + bytes_transfered += cnt; + + if (bytes_transfered > (100 * 1000000)) { + gettimeofday(&finish_time, NULL); + elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; + + printf("RX data transfer rate = %f K Samples/second\n", + (float) bytes_transfered / (float) elapsed_seconds / 4000); + + + start_time = finish_time; + bytes_transfered = 0; + } + + +// printf("."); +// fflush(stdout); +// printf("\n"); + } + +} + +static void *write_thread(void *threadid) +{ + int seq_number, i, cnt; + void *tx_data; + struct pkt *p; + + printf("Greetings from the write thread!\n"); + + tx_data = malloc(2048); + p = (struct pkt *) ((void *)tx_data); + + for (i=0; i < packet_data_length; i++) +// p->data[i] = random() >> 16; + p->data[i] = i; + + seq_number = 1; + + while (1) { + p->seq_num = seq_number++; + + if (packet_data_length > 0) + p->len = packet_data_length; + else + p->len = (random() & 0x1ff) + (1004 - 512); + + p->checksum = calc_checksum(p); + + cnt = write(fp, tx_data, p->len * 2 + 12); + if (cnt < 0) + printf("Error returned from write: %d\n", cnt); +// sleep(1); + } +} + + +int main(int argc, char *argv[]) +{ + pthread_t tx, rx; + long int t; + struct sched_param s = { + .sched_priority = 1 + }; + void *rb; + struct usrp_transfer_frame *tx_rb, *rx_rb; + + if (argc < 2) { + printf("%s data_size\n", argv[0]); + return -1; + } + + packet_data_length = atoi(argv[1]); + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + rb = mmap(0, 202 * 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); + if (!rb) { + printf("mmap failed\n"); + exit; + } + + + sched_setscheduler(0, SCHED_RR, &s); + error = 0; + +#if 1 + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { + printf("Failed to create rx thread\n"); + exit(-1); + } + + sleep(1); +#endif + + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { + printf("Failed to create tx thread\n"); + exit(-1); + } + +// while (!error) + sleep(1000000000); + + printf("Done sleeping\n"); +} -- cgit v1.2.3 From 9e87ebda07dda14e5b0ab4c64b6adc9800358baa Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 11 Aug 2010 00:16:34 -0700 Subject: usrp-e: fixed warnings and errors, missing subdev spec stuff --- host/include/uhd/utils/pimpl.hpp | 3 +-- host/lib/usrp/usrp_e/dboard_iface.cpp | 2 ++ host/lib/usrp/usrp_e/dboard_impl.cpp | 37 +---------------------------------- host/lib/usrp/usrp_e/io_impl.cpp | 18 +++++++++++++++-- host/lib/usrp/usrp_e/usrp_e_iface.cpp | 22 ++++++++++----------- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 5 ++--- 6 files changed, 33 insertions(+), 54 deletions(-) (limited to 'host') diff --git a/host/include/uhd/utils/pimpl.hpp b/host/include/uhd/utils/pimpl.hpp index 18454f0c4..09bf0c0a2 100644 --- a/host/include/uhd/utils/pimpl.hpp +++ b/host/include/uhd/utils/pimpl.hpp @@ -20,7 +20,6 @@ #include #include -#include /*! \file pimpl.hpp * "Pimpl idiom" (pointer to implementation idiom). @@ -51,6 +50,6 @@ * \param _args the constructor args for the pimpl */ #define UHD_PIMPL_MAKE(_name, _args) \ - boost::make_shared<_name> _args + boost::shared_ptr<_name>(new _name _args) #endif /* INCLUDED_UHD_UTILS_PIMPL_HPP */ diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp index ce00cd40d..d5ec10d84 100644 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -50,6 +50,8 @@ public: /* NOP */ } + std::string get_mboard_name(void){return "usrp-e";} + void write_aux_dac(unit_t, aux_dac_t, float); float read_aux_adc(unit_t, aux_adc_t); diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index a384c71a0..4d3f70dfe 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -51,10 +51,6 @@ void usrp_e_impl::dboard_init(void){ boost::bind(&usrp_e_impl::tx_dboard_get, this, _1, _2), boost::bind(&usrp_e_impl::tx_dboard_set, this, _1, _2) ); - - //init the subdevs in use (use the first subdevice) - rx_dboard_set(DBOARD_PROP_USED_SUBDEVS, prop_names_t(1, _dboard_manager->get_rx_subdev_names().at(0))); - tx_dboard_set(DBOARD_PROP_USED_SUBDEVS, prop_names_t(1, _dboard_manager->get_tx_subdev_names().at(0))); } /*********************************************************************** @@ -78,10 +74,6 @@ void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ val = _dboard_manager->get_rx_subdev_names(); return; - case DBOARD_PROP_USED_SUBDEVS: - val = _rx_subdevs_in_use; - return; - case DBOARD_PROP_DBOARD_ID: val = _rx_db_eeprom.id; return; @@ -99,18 +91,6 @@ void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ **********************************************************************/ void usrp_e_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ switch(key.as()){ - case DBOARD_PROP_USED_SUBDEVS:{ - _rx_subdevs_in_use = val.as(); - UHD_ASSERT_THROW(_rx_subdevs_in_use.size() == 1); - wax::obj rx_subdev = _dboard_manager->get_rx_subdev(_rx_subdevs_in_use.at(0)); - std::cout << "Using: " << rx_subdev[SUBDEV_PROP_NAME].as() << std::endl; - _iface->poke32(UE_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word( - rx_subdev[SUBDEV_PROP_QUADRATURE].as(), - rx_subdev[SUBDEV_PROP_IQ_SWAPPED].as() - )); - } - return; - case DBOARD_PROP_DBOARD_ID: _rx_db_eeprom.id = val.as(); _iface->write_eeprom(I2C_ADDR_RX_DB, 0, _rx_db_eeprom.get_eeprom_bytes()); @@ -141,10 +121,6 @@ void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ val = _dboard_manager->get_tx_subdev_names(); return; - case DBOARD_PROP_USED_SUBDEVS: - val = _tx_subdevs_in_use; - return; - case DBOARD_PROP_DBOARD_ID: val = _tx_db_eeprom.id; return; @@ -161,18 +137,7 @@ void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ * TX Dboard Set **********************************************************************/ void usrp_e_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ - switch(key.as()){ - case DBOARD_PROP_USED_SUBDEVS:{ - _tx_subdevs_in_use = val.as(); - UHD_ASSERT_THROW(_tx_subdevs_in_use.size() == 1); - wax::obj tx_subdev = _dboard_manager->get_tx_subdev(_tx_subdevs_in_use.at(0)); - std::cout << "Using: " << tx_subdev[SUBDEV_PROP_NAME].as() << std::endl; - _iface->poke32(UE_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word( - tx_subdev[SUBDEV_PROP_IQ_SWAPPED].as() - )); - } - return; - + switch(key.as()){ case DBOARD_PROP_DBOARD_ID: _tx_db_eeprom.id = val.as(); _iface->write_eeprom(I2C_ADDR_TX_DB, 0, _tx_db_eeprom.get_eeprom_bytes()); diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index ecde9ca27..0742c4514 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -24,6 +24,7 @@ #include //transfer frame struct #include #include +#include #include using namespace uhd; @@ -35,7 +36,6 @@ using namespace uhd::usrp; static const size_t MAX_BUFF_SIZE = 2048; static const size_t vrt_header_offset_words32 = sizeof(usrp_transfer_frame)/sizeof(boost::uint32_t); static const bool usrp_e_io_impl_verbose = true; -static const size_t recv_timeout_ms = 100; /*********************************************************************** * Data Transport (phony zero-copy with read/write) @@ -61,6 +61,8 @@ public: return 10; //FIXME no idea! } + size_t recv_timeout_ms; + private: int _fd; ssize_t send(const boost::asio::const_buffer &buff){ @@ -220,13 +222,17 @@ size_t usrp_e_impl::recv( size_t num_samps, rx_metadata_t &metadata, const io_type_t &io_type, - recv_mode_t recv_mode + recv_mode_t recv_mode, + size_t timeout_ms ){ otw_type_t recv_otw_type; recv_otw_type.width = 16; recv_otw_type.shift = 0; recv_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; + //hand-off the timeout to the transport + _io_impl->transport.recv_timeout_ms = timeout_ms; + return vrt_packet_handler::recv( _io_impl->packet_handler_recv_state, //last state of the recv handler buffs, num_samps, //buffer to fill @@ -239,3 +245,11 @@ size_t usrp_e_impl::recv( vrt_header_offset_words32 ); } + +/*********************************************************************** + * Dummy Async Recv + **********************************************************************/ +bool usrp_e_impl::recv_async_msg(async_metadata_t &, size_t timeout_ms){ + boost::this_thread::sleep(boost::posix_time::milliseconds(timeout_ms)); + return false; +} diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.cpp b/host/lib/usrp/usrp_e/usrp_e_iface.cpp index 21e91452f..f00e92946 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.cpp @@ -123,13 +123,13 @@ public: boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; //load the data struct - usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = addr; - data.len = bytes.size(); - std::copy(bytes.begin(), bytes.end(), data.data); + usrp_e_i2c *data = reinterpret_cast(mem); + data->addr = addr; + data->len = bytes.size(); + std::copy(bytes.begin(), bytes.end(), data->data); //call the spi ioctl - this->ioctl(USRP_E_I2C_WRITE, &data); + this->ioctl(USRP_E_I2C_WRITE, data); } byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ @@ -138,17 +138,17 @@ public: boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; //load the data struct - usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = addr; - data.len = num_bytes; + usrp_e_i2c *data = reinterpret_cast(mem); + data->addr = addr; + data->len = num_bytes; //call the spi ioctl - this->ioctl(USRP_E_I2C_READ, &data); + this->ioctl(USRP_E_I2C_READ, data); //unload the data - byte_vector_t bytes(data.len); + byte_vector_t bytes(data->len); UHD_ASSERT_THROW(bytes.size() == num_bytes); - std::copy(data.data, data.data+bytes.size(), bytes.begin()); + std::copy(data->data, data->data+bytes.size(), bytes.begin()); return bytes; } diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index efbf9f68f..4bbe100c1 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -82,7 +82,8 @@ public: //the io interface size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t); - size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t); + size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, size_t); + bool recv_async_msg(uhd::async_metadata_t &, size_t); size_t get_max_send_samps_per_packet(void) const{return 503;} size_t get_max_recv_samps_per_packet(void) const{return 503;} @@ -128,14 +129,12 @@ private: uhd::usrp::dboard_eeprom_t _rx_db_eeprom; void rx_dboard_get(const wax::obj &, wax::obj &); void rx_dboard_set(const wax::obj &, const wax::obj &); - uhd::prop_names_t _rx_subdevs_in_use; wax_obj_proxy::sptr _rx_dboard_proxy; //tx dboard functions and settings uhd::usrp::dboard_eeprom_t _tx_db_eeprom; void tx_dboard_get(const wax::obj &, wax::obj &); void tx_dboard_set(const wax::obj &, const wax::obj &); - uhd::prop_names_t _tx_subdevs_in_use; wax_obj_proxy::sptr _tx_dboard_proxy; //rx ddc functions and settings -- cgit v1.2.3 From 6ce879c36aedc7d69ceadbecd8878fa3856547f0 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 11 Aug 2010 17:23:42 +0000 Subject: Add usrp-e-mm-loopback to .gitignore. --- host/apps/omap_debug/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'host') diff --git a/host/apps/omap_debug/.gitignore b/host/apps/omap_debug/.gitignore index 5d6b1c6f5..008a23138 100644 --- a/host/apps/omap_debug/.gitignore +++ b/host/apps/omap_debug/.gitignore @@ -17,3 +17,4 @@ usrp-e-spi usrp-e-timed usrp-e-uart usrp-e-uart-rx +usrp-e-mm-loopback -- cgit v1.2.3 From 74e5238d08c780e96f617c86bea848a05f76988c Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 11 Aug 2010 17:53:53 +0000 Subject: Convert non-mmaped loopback test program to use new simple read/write api. Done by copying from the -mm version, which will be used to test mmaped ring buffer. --- host/apps/omap_debug/usrp-e-loopback.c | 76 +++++++++++++++------------------- 1 file changed, 33 insertions(+), 43 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-loopback.c b/host/apps/omap_debug/usrp-e-loopback.c index c463e774d..d11cf7d09 100644 --- a/host/apps/omap_debug/usrp-e-loopback.c +++ b/host/apps/omap_debug/usrp-e-loopback.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "usrp_e.h" // max length #define PKT_DATA_LENGTH 1016 @@ -12,9 +13,9 @@ static int packet_data_length; static int error; struct pkt { + int len; int checksum; int seq_num; - int len; short data[]; }; @@ -38,8 +39,8 @@ static int calc_checksum(struct pkt *p) static void *read_thread(void *threadid) { + char *rx_data; int cnt, prev_seq_num, pkt_count, seq_num_failure; - struct usrp_transfer_frame *rx_data; struct pkt *p; unsigned long bytes_transfered, elapsed_seconds; struct timeval start_time, finish_time; @@ -51,32 +52,25 @@ static void *read_thread(void *threadid) // IMPORTANT: must assume max length packet from fpga rx_data = malloc(2048); - p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); - //p = &(rx_data->buf[0]); - printf("Address of rx_data = %p, p = %p\n", rx_data, p); - printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); - printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); + p = (struct pkt *) ((void *)rx_data); prev_seq_num = 0; pkt_count = 0; seq_num_failure = 0; while (1) { + cnt = read(fp, rx_data, 2048); if (cnt < 0) printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); -// printf("Packet received, status = %X, len = %d\n", rx_data->status, rx_data->len); -// printf("p->seq_num = %d, p->len = %d\n", p->seq_num, p->len); - +// printf("p->seq_num = %d\n", p->seq_num); - if (rx_data->len != (p->len*2 + 12)) - printf("rx_data->len = %d, p->len*2 + 12 = %d\n", rx_data->len, p->len*2 + 12); pkt_count++; if (p->seq_num != prev_seq_num + 1) { - printf("Sequence number fail, current = %X, previous = %X, pkt_count = %d\n", + printf("Sequence number fail, current = %d, previous = %d, pkt_count = %d\n", p->seq_num, prev_seq_num, pkt_count); seq_num_failure ++; @@ -87,12 +81,12 @@ static void *read_thread(void *threadid) prev_seq_num = p->seq_num; if (calc_checksum(p) != p->checksum) { - printf("Cksum fail rx = %X, tx = %X, dif = %d, count = %d, len = %d, rx->len = %d\n", - calc_checksum(p), p->checksum, p->checksum - calc_checksum(p), pkt_count, p->len, rx_data->len); + printf("Checksum fail packet = %X, expected = %X, pkt_count = %d\n", + calc_checksum(p), p->checksum, pkt_count); error = 1; } - bytes_transfered += rx_data->len; + bytes_transfered += cnt; if (bytes_transfered > (100 * 1000000)) { gettimeofday(&finish_time, NULL); @@ -116,47 +110,32 @@ static void *read_thread(void *threadid) static void *write_thread(void *threadid) { - int seq_number, i, cnt, data_length; - struct usrp_transfer_frame *tx_data; + int seq_number, i, cnt; + void *tx_data; struct pkt *p; printf("Greetings from the write thread!\n"); tx_data = malloc(2048); - p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); - printf("Address of tx_data = %p, p = %p\n", tx_data, p); + p = (struct pkt *) ((void *)tx_data); - printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); - - for (i=0; i < 2048; i++) + for (i=0; i < packet_data_length; i++) // p->data[i] = random() >> 16; p->data[i] = i; - tx_data->status = 0xdeadbeef; - - printf("tx_data->len = %d\n", tx_data->len); - seq_number = 1; while (1) { -// printf("tx status = %X, len = %d\n", tx_data->status, tx_data->len); - if (packet_data_length > 0) - data_length = packet_data_length; - else - data_length = (random() & 0x1ff) + (1004 - 512); - -// printf("data_length = %d\n", data_length); - p->seq_num = seq_number++; - p->len = data_length; - p->checksum = calc_checksum(p); - tx_data->len = 12 + p->len * 2; -// printf("tx status = %X, len = %d, p->len = %d\n", tx_data->status, tx_data->len, p->len); + if (packet_data_length > 0) + p->len = packet_data_length; + else + p->len = (random() & 0x1ff) + (1004 - 512); - cnt = write(fp, tx_data, sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + 2 * p->len); -// cnt = write(fp, tx_data, 2048); + p->checksum = calc_checksum(p); + cnt = write(fp, tx_data, p->len * 2 + 12); if (cnt < 0) printf("Error returned from write: %d\n", cnt); // sleep(1); @@ -171,6 +150,8 @@ int main(int argc, char *argv[]) struct sched_param s = { .sched_priority = 1 }; + void *rb; + struct usrp_transfer_frame *tx_rb, *rx_rb; if (argc < 2) { printf("%s data_size\n", argv[0]); @@ -182,23 +163,32 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); + rb = mmap(0, 202 * 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); + if (!rb) { + printf("mmap failed\n"); + exit; + } + + sched_setscheduler(0, SCHED_RR, &s); error = 0; +#if 1 if (pthread_create(&rx, NULL, read_thread, (void *) t)) { printf("Failed to create rx thread\n"); exit(-1); } sleep(1); +#endif if (pthread_create(&tx, NULL, write_thread, (void *) t)) { printf("Failed to create tx thread\n"); exit(-1); } - while (!error) - sleep(1); +// while (!error) + sleep(1000000000); printf("Done sleeping\n"); } -- cgit v1.2.3 From 3f25b6fee4a7788ffea0224cb79bb6334b621992 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 11 Aug 2010 12:32:57 -0700 Subject: usrp-e: filled in properties and logic for subdev spec --- host/lib/usrp/usrp_e/dboard_impl.cpp | 1 - host/lib/usrp/usrp_e/mboard_impl.cpp | 36 ++++++++++++++++++++++++++++++++++++ host/lib/usrp/usrp_e/usrp_e_impl.hpp | 2 ++ 3 files changed, 38 insertions(+), 1 deletion(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index 4d3f70dfe..809b6f06b 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -17,7 +17,6 @@ #include "usrp_e_impl.hpp" #include "usrp_e_regs.hpp" -#include "../dsp_utils.hpp" #include #include #include diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index e27c1964a..822f1571d 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -17,6 +17,8 @@ #include "usrp_e_impl.hpp" #include "usrp_e_regs.hpp" +#include "../dsp_utils.hpp" +#include "../misc_utils.hpp" #include #include #include @@ -38,6 +40,10 @@ void usrp_e_impl::mboard_init(void){ _clock_config.pps_source = clock_config_t::PPS_SMA; //TODO poke the clock config regs + + //set default subdev specs + this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t()); + this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t()); } /*********************************************************************** @@ -98,6 +104,14 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ val = _clock_config; return; + case MBOARD_PROP_RX_SUBDEV_SPEC: + val = _rx_subdev_spec; + return; + + case MBOARD_PROP_TX_SUBDEV_SPEC: + val = _tx_subdev_spec; + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -123,6 +137,28 @@ void usrp_e_impl::mboard_set(const wax::obj &key, const wax::obj &val){ } return; + case MBOARD_PROP_RX_SUBDEV_SPEC: + _rx_subdev_spec = val.as(); + verify_rx_subdev_spec(_rx_subdev_spec, this->get_link()); + //sanity check + UHD_ASSERT_THROW(_rx_subdev_spec.size() == 1); + //set the mux + _iface->poke32(UE_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word( + _dboard_manager->get_rx_subdev(_rx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as() + )); + return; + + case MBOARD_PROP_TX_SUBDEV_SPEC: + _tx_subdev_spec = val.as(); + verify_tx_subdev_spec(_tx_subdev_spec, this->get_link()); + //sanity check + UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1); + //set the mux + _iface->poke32(UE_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word( + _dboard_manager->get_tx_subdev(_tx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as() + )); + return; + default: UHD_THROW_PROP_SET_ERROR(); } } diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 4bbe100c1..e3249e9de 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -20,6 +20,7 @@ #include "codec_ctrl.hpp" #include #include +#include #include #include #include @@ -119,6 +120,7 @@ private: void mboard_get(const wax::obj &, wax::obj &); void mboard_set(const wax::obj &, const wax::obj &); wax_obj_proxy::sptr _mboard_proxy; + uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec; //xx dboard functions and settings void dboard_init(void); -- cgit v1.2.3 From a58b90ef219746e927a777efba919db15d139e84 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 11 Aug 2010 22:23:40 +0000 Subject: Convert to use mmaped rx ring buffer. --- host/apps/omap_debug/usrp-e-mm-loopback.c | 63 ++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 13 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-mm-loopback.c b/host/apps/omap_debug/usrp-e-mm-loopback.c index d11cf7d09..722d09825 100644 --- a/host/apps/omap_debug/usrp-e-mm-loopback.c +++ b/host/apps/omap_debug/usrp-e-mm-loopback.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "usrp_e.h" // max length #define PKT_DATA_LENGTH 1016 @@ -16,9 +17,20 @@ struct pkt { int len; int checksum; int seq_num; - short data[]; + short data[1024-6]; }; +/* delete after usrp_e.h updated */ +struct ring_buffer_info { + int flags; + int len; +}; + +struct ring_buffer_info (*rxi)[]; +struct ring_buffer_info (*txi)[]; +struct pkt (*rx_buf)[200]; +struct pkt (*tx_buf)[200]; + static int fp; static int calc_checksum(struct pkt *p) @@ -39,32 +51,44 @@ static int calc_checksum(struct pkt *p) static void *read_thread(void *threadid) { - char *rx_data; int cnt, prev_seq_num, pkt_count, seq_num_failure; struct pkt *p; unsigned long bytes_transfered, elapsed_seconds; struct timeval start_time, finish_time; + int rb_read; printf("Greetings from the reading thread!\n"); + printf("sizeof pkt = %d\n", sizeof(struct pkt)); + + rb_read = 0; bytes_transfered = 0; gettimeofday(&start_time, NULL); - // IMPORTANT: must assume max length packet from fpga - rx_data = malloc(2048); - p = (struct pkt *) ((void *)rx_data); - prev_seq_num = 0; pkt_count = 0; seq_num_failure = 0; while (1) { - cnt = read(fp, rx_data, 2048); - if (cnt < 0) - printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); + if (!((*rxi)[rb_read].flags & RB_USER)) { + printf("Waiting for data\n"); + struct pollfd pfd; + pfd.fd = fp; + pfd.events = POLLIN; + ssize_t ret = poll(&pfd, 1, -1); + } -// printf("p->seq_num = %d\n", p->seq_num); + printf("pkt received, rb_read = %d\n", rb_read); + + cnt = (*rxi)[rb_read].len; + p = &(*rx_buf)[rb_read]; + +// cnt = read(fp, rx_data, 2048); +// if (cnt < 0) +// printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); + + printf("p = %X, p->seq_num = %d p->len = %d\n", p, p->seq_num, p->len); pkt_count++; @@ -86,6 +110,12 @@ static void *read_thread(void *threadid) error = 1; } + (*rxi)[rb_read].flags = RB_KERNEL; + + rb_read++; + if (rb_read == 200) + rb_read = 0; + bytes_transfered += cnt; if (bytes_transfered > (100 * 1000000)) { @@ -151,7 +181,6 @@ int main(int argc, char *argv[]) .sched_priority = 1 }; void *rb; - struct usrp_transfer_frame *tx_rb, *rx_rb; if (argc < 2) { printf("%s data_size\n", argv[0]); @@ -164,11 +193,19 @@ int main(int argc, char *argv[]) printf("fp = %d\n", fp); rb = mmap(0, 202 * 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); - if (!rb) { - printf("mmap failed\n"); + if (rb == MAP_FAILED) { + perror("mmap failed"); exit; } + printf("rb = %X\n", rb); + + rxi = rb; + rx_buf = rb + 4096; + txi = rb + 4096 + 4096 * 200; + tx_buf = rb + 4096 * 2 + 4096 * 200; + + printf("rxi = %X, rx_buf = %X, txi = %X, tx_buf = %X\n", rxi, rx_buf, txi, tx_buf); sched_setscheduler(0, SCHED_RR, &s); error = 0; -- cgit v1.2.3 From 8e5040a9ec0639bc7b110ba96e256c48e5a62df7 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 11 Aug 2010 15:33:12 -0700 Subject: usrp-e: removed transfer frameness --- host/lib/usrp/usrp_e/io_impl.cpp | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 0742c4514..bbc3f5215 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -21,7 +21,6 @@ #include "../../transport/vrt_packet_handler.hpp" #include #include //read, write -#include //transfer frame struct #include #include #include @@ -34,7 +33,6 @@ using namespace uhd::usrp; * Constants **********************************************************************/ static const size_t MAX_BUFF_SIZE = 2048; -static const size_t vrt_header_offset_words32 = sizeof(usrp_transfer_frame)/sizeof(boost::uint32_t); static const bool usrp_e_io_impl_verbose = true; /*********************************************************************** @@ -66,15 +64,7 @@ public: private: int _fd; ssize_t send(const boost::asio::const_buffer &buff){ - //Set the frame length in the frame header. - //This is technically bad to write to a const buffer, - //but this will go away when the ring gets implemented, - //and the send buffer commit method will set the length. - const_cast( - boost::asio::buffer_cast(buff) - )->len = boost::asio::buffer_size(buff) - sizeof(usrp_transfer_frame); - return write( - _fd, + return write(_fd, boost::asio::buffer_cast(buff), boost::asio::buffer_size(buff) ); @@ -99,12 +89,11 @@ private: } //perform the blocking read(...) - ssize_t read_ret = read( - _fd, + ssize_t read_ret = read(_fd, boost::asio::buffer_cast(buff), boost::asio::buffer_size(buff) ); - if (read_ret < ssize_t(sizeof(usrp_transfer_frame))){ + if (read_ret < 0){ if (usrp_e_io_impl_verbose) std::cerr << boost::format( "usrp-e io impl recv(): read() returned small value: %d\n" " -> return -1 for error" @@ -112,8 +101,7 @@ private: return -1; } - //usrp_transfer_frame *frame = boost::asio::buffer_cast(buff); - //std::cout << "len " << int(frame->len) << std::endl; + //std::cout << "len " << int(read_ret) << std::endl; //for (size_t i = 0; i < 9; i++){ // std::cout << boost::format(" 0x%08x") % boost::asio::buffer_cast(buff)[i] << std::endl; //} @@ -200,8 +188,7 @@ size_t usrp_e_impl::send( MASTER_CLOCK_RATE, //master clock tick rate uhd::transport::vrt::if_hdr_pack_le, boost::bind(&get_send_buffs, &_io_impl->transport, _1), - get_max_send_samps_per_packet(), - vrt_header_offset_words32 + get_max_send_samps_per_packet() ); } @@ -241,8 +228,7 @@ size_t usrp_e_impl::recv( MASTER_CLOCK_RATE, //master clock tick rate uhd::transport::vrt::if_hdr_unpack_le, boost::bind(&get_recv_buffs, &_io_impl->transport, _1), - boost::bind(&usrp_e_impl::handle_overrun, this, _1), - vrt_header_offset_words32 + boost::bind(&usrp_e_impl::handle_overrun, this, _1) ); } -- cgit v1.2.3 From 2ce128a2cf9ea8bea23e2cea28d0729719b42968 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 12 Aug 2010 03:49:37 +0000 Subject: uhd: avoid segfaults - use CPP macros for paths and dont split empty string --- host/lib/constants.hpp.in | 7 ++++--- host/lib/utils/paths.cpp | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'host') diff --git a/host/lib/constants.hpp.in b/host/lib/constants.hpp.in index 295c8f16c..aa51e558c 100644 --- a/host/lib/constants.hpp.in +++ b/host/lib/constants.hpp.in @@ -21,8 +21,9 @@ #include #include -static const std::string UHD_VERSION_STRING = "@CPACK_PACKAGE_VERSION@"; -static const std::string UHD_INSTALL_PREFIX = "@CMAKE_INSTALL_PREFIX@"; -static const std::string UHD_PKG_DATA_DIR = "@PKG_DATA_DIR@"; +//these should be pre-processor macros to avoid static initialization issues +#define UHD_VERSION_STRING "@CPACK_PACKAGE_VERSION@" +#define UHD_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@" +#define UHD_PKG_DATA_DIR "@PKG_DATA_DIR@" #endif /* INCLUDED_LIBUHD_CONSTANTS_HPP */ diff --git a/host/lib/utils/paths.cpp b/host/lib/utils/paths.cpp index 0805a44fe..4029bd989 100644 --- a/host/lib/utils/paths.cpp +++ b/host/lib/utils/paths.cpp @@ -60,12 +60,14 @@ static std::vector get_env_paths(const std::string &var_name){ //split the path at the path separators std::vector path_strings; - boost::split(path_strings, var_value, boost::is_any_of(env_path_sep)); + if (not var_value.empty()) boost::split(//dont split empty strings + path_strings, var_value, boost::is_any_of(env_path_sep) + ); //convert to filesystem path, filter blank paths std::vector paths; BOOST_FOREACH(std::string &path_string, path_strings){ - if (path_string.size() == 0) continue; + if (path_string.empty()) continue; paths.push_back(fs::system_complete(path_string)); } return paths; @@ -74,17 +76,15 @@ static std::vector get_env_paths(const std::string &var_name){ /*********************************************************************** * Get a list of special purpose paths **********************************************************************/ -static const fs::path pkg_data_path = fs::path(UHD_INSTALL_PREFIX) / UHD_PKG_DATA_DIR; - std::vector get_image_paths(void){ std::vector paths = get_env_paths("UHD_IMAGE_PATH"); - paths.push_back(pkg_data_path / "images"); + paths.push_back(fs::path(UHD_INSTALL_PREFIX) / UHD_PKG_DATA_DIR / "images"); return paths; } std::vector get_module_paths(void){ std::vector paths = get_env_paths("UHD_MODULE_PATH"); - paths.push_back(pkg_data_path / "modules"); + paths.push_back(fs::path(UHD_INSTALL_PREFIX) / UHD_PKG_DATA_DIR / "modules"); return paths; } -- cgit v1.2.3 From 68a65581db6455bfd4652576eeb6795e3c1ca68b Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 12 Aug 2010 18:17:37 +0000 Subject: usrp-e: fix typo in verify subdev spec --- host/lib/usrp/usrp_e/mboard_impl.cpp | 4 ++-- host/utils/uhd_find_devices.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index 822f1571d..4914bd3b7 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -139,7 +139,7 @@ void usrp_e_impl::mboard_set(const wax::obj &key, const wax::obj &val){ case MBOARD_PROP_RX_SUBDEV_SPEC: _rx_subdev_spec = val.as(); - verify_rx_subdev_spec(_rx_subdev_spec, this->get_link()); + verify_rx_subdev_spec(_rx_subdev_spec, _mboard_proxy->get_link()); //sanity check UHD_ASSERT_THROW(_rx_subdev_spec.size() == 1); //set the mux @@ -150,7 +150,7 @@ void usrp_e_impl::mboard_set(const wax::obj &key, const wax::obj &val){ case MBOARD_PROP_TX_SUBDEV_SPEC: _tx_subdev_spec = val.as(); - verify_tx_subdev_spec(_tx_subdev_spec, this->get_link()); + verify_tx_subdev_spec(_tx_subdev_spec, _mboard_proxy->get_link()); //sanity check UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1); //set the mux diff --git a/host/utils/uhd_find_devices.cpp b/host/utils/uhd_find_devices.cpp index 8281c92bc..b778eeb68 100644 --- a/host/utils/uhd_find_devices.cpp +++ b/host/utils/uhd_find_devices.cpp @@ -53,7 +53,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << "-- UHD Device " << i << std::endl; std::cout << "--------------------------------------------------" << std::endl; std::cout << device_addrs[i].to_pp_string() << std::endl << std::endl; - uhd::device::make(device_addrs[i]); //test make + //uhd::device::make(device_addrs[i]); //test make } return 0; -- cgit v1.2.3 From 8c676eeb973593caecb7270a6106e8592f73a352 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 12 Aug 2010 21:28:26 +0000 Subject: usrp-e: added codec impl, probe works --- host/lib/usrp/usrp_e/CMakeLists.txt | 1 + host/lib/usrp/usrp_e/codec_impl.cpp | 96 ++++++++++++++++++++++++++++++++++++ host/lib/usrp/usrp_e/dboard_impl.cpp | 8 +++ host/lib/usrp/usrp_e/mboard_impl.cpp | 5 +- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 8 +++ host/lib/usrp/usrp_e/usrp_e_impl.hpp | 8 +++ 6 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 host/lib/usrp/usrp_e/codec_impl.cpp (limited to 'host') diff --git a/host/lib/usrp/usrp_e/CMakeLists.txt b/host/lib/usrp/usrp_e/CMakeLists.txt index 1d64d29d2..f0c125f26 100644 --- a/host/lib/usrp/usrp_e/CMakeLists.txt +++ b/host/lib/usrp/usrp_e/CMakeLists.txt @@ -32,6 +32,7 @@ IF(HAVE_LINUX_USRP_E_H) ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/clock_ctrl.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/codec_ctrl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/codec_ctrl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/codec_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dboard_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dboard_iface.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dsp_impl.cpp diff --git a/host/lib/usrp/usrp_e/codec_impl.cpp b/host/lib/usrp/usrp_e/codec_impl.cpp new file mode 100644 index 000000000..51f7b02b8 --- /dev/null +++ b/host/lib/usrp/usrp_e/codec_impl.cpp @@ -0,0 +1,96 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_impl.hpp" +#include +#include + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * Helper Methods + **********************************************************************/ +void usrp_e_impl::codec_init(void){ + //make proxies + _rx_codec_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::rx_codec_get, this, _1, _2), + boost::bind(&usrp_e_impl::rx_codec_set, this, _1, _2) + ); + _tx_codec_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::tx_codec_get, this, _1, _2), + boost::bind(&usrp_e_impl::tx_codec_set, this, _1, _2) + ); +} + +/*********************************************************************** + * RX Codec Properties + **********************************************************************/ +void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case CODEC_PROP_NAME: + val = std::string("usrp-e adc - ad9522"); + return; + + case CODEC_PROP_OTHERS: + val = prop_names_t(); + return; + + case CODEC_PROP_GAIN_NAMES: + val = prop_names_t(); //no gain elements to be controlled + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +void usrp_e_impl::rx_codec_set(const wax::obj &, const wax::obj &){ + UHD_THROW_PROP_SET_ERROR(); +} + +/*********************************************************************** + * TX Codec Properties + **********************************************************************/ +void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case CODEC_PROP_NAME: + val = std::string("usrp-e dac - ad9522"); + return; + + case CODEC_PROP_OTHERS: + val = prop_names_t(); + return; + + case CODEC_PROP_GAIN_NAMES: + val = prop_names_t(); //no gain elements to be controlled + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +void usrp_e_impl::tx_codec_set(const wax::obj &, const wax::obj &){ + UHD_THROW_PROP_SET_ERROR(); +} diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index 809b6f06b..8aaf16c51 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -81,6 +81,10 @@ void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ val = _dboard_iface; return; + case DBOARD_PROP_CODEC: + val = _rx_codec_proxy->get_link(); + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -128,6 +132,10 @@ void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ val = _dboard_iface; return; + case DBOARD_PROP_CODEC: + val = _tx_codec_proxy->get_link(); + return; + default: UHD_THROW_PROP_GET_ERROR(); } } diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index 4914bd3b7..88e16a6f5 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using namespace uhd; using namespace uhd::usrp; @@ -40,10 +41,6 @@ void usrp_e_impl::mboard_init(void){ _clock_config.pps_source = clock_config_t::PPS_SMA; //TODO poke the clock config regs - - //set default subdev specs - this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t()); - this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t()); } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 76c77af15..0566cfd59 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -17,6 +17,7 @@ #include "usrp_e_impl.hpp" #include +#include #include #include #include @@ -93,8 +94,15 @@ usrp_e_impl::usrp_e_impl(const std::string &node){ rx_ddc_init(); tx_duc_init(); + //init the codec properties + codec_init(); + //init the io send/recv io_init(); + + //set default subdev specs + this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t()); + this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t()); } usrp_e_impl::~usrp_e_impl(void){ diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index e3249e9de..2457e27cc 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -152,6 +152,14 @@ private: void tx_duc_set(const wax::obj &, const wax::obj &); double _duc_freq; size_t _duc_interp; wax_obj_proxy::sptr _tx_duc_proxy; + + //codec functions and settings + void codec_init(void); + void rx_codec_get(const wax::obj &, wax::obj &); + void rx_codec_set(const wax::obj &, const wax::obj &); + void tx_codec_get(const wax::obj &, wax::obj &); + void tx_codec_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _rx_codec_proxy, _tx_codec_proxy; }; #endif /* INCLUDED_USRP_E_IMPL_HPP */ -- cgit v1.2.3 From ac85d2b38c26fd6d31ba0a997d033b159d51769d Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 13 Aug 2010 01:09:45 +0000 Subject: usrp-e: codec gain control from properties interface --- host/lib/usrp/usrp_e/clock_ctrl.cpp | 1 - host/lib/usrp/usrp_e/codec_ctrl.cpp | 48 ++++++++++++++++++++++++++ host/lib/usrp/usrp_e/codec_ctrl.hpp | 19 ++++++++-- host/lib/usrp/usrp_e/codec_impl.cpp | 69 +++++++++++++++++++++++++++++++++---- 4 files changed, 128 insertions(+), 9 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 8a5bd1c6b..b53e880a2 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -60,7 +60,6 @@ class usrp_e_clock_ctrl_impl : public usrp_e_clock_ctrl{ public: usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface){ _iface = iface; - std::cout << "master_clock_rate: " << (master_clock_rate/1e6) << " MHz" << std::endl; //init the clock gen registers //Note: out0 should already be clocking the FPGA or this isnt going to work diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index ac61bc6b4..5322f94bd 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -31,6 +31,9 @@ using namespace uhd; static const bool codec_debug = false; +const gain_range_t usrp_e_codec_ctrl::tx_pga_gain_range(-20, 0, float(0.1)); +const gain_range_t usrp_e_codec_ctrl::rx_pga_gain_range(0, 20, 1); + /*********************************************************************** * Codec Control Implementation **********************************************************************/ @@ -44,6 +47,12 @@ public: float read_aux_adc(aux_adc_t which); void write_aux_dac(aux_dac_t which, float volts); + //pga gain control + void set_tx_pga_gain(float); + float get_tx_pga_gain(void); + void set_rx_pga_gain(float, char); + float get_rx_pga_gain(char); + private: usrp_e_iface::sptr _iface; ad9862_regs_t _ad9862_regs; @@ -119,6 +128,45 @@ usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){ this->send_reg(8); } +/*********************************************************************** + * Codec Control Gain Control Methods + **********************************************************************/ +void usrp_e_codec_ctrl_impl::set_tx_pga_gain(float gain){ + int gain_word = int(63*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); + _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, 63); + this->send_reg(16); +} + +float usrp_e_codec_ctrl_impl::get_tx_pga_gain(void){ + return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.max - tx_pga_gain_range.min)/63) + tx_pga_gain_range.min; +} + +void usrp_e_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ + int gain_word = int(0x14*(gain - rx_pga_gain_range.min)/(rx_pga_gain_range.max - rx_pga_gain_range.min)); + gain_word = std::clip(gain_word, 0, 0x14); + switch(which){ + case 'A': + _ad9862_regs.rx_pga_a = gain_word; + this->send_reg(2); + return; + case 'B': + _ad9862_regs.rx_pga_b = gain_word; + this->send_reg(3); + return; + default: UHD_THROW_INVALID_CODE_PATH(); + } +} + +float usrp_e_codec_ctrl_impl::get_rx_pga_gain(char which){ + int gain_word; + switch(which){ + case 'A': gain_word = _ad9862_regs.rx_pga_a; break; + case 'B': gain_word = _ad9862_regs.rx_pga_b; break; + default: UHD_THROW_INVALID_CODE_PATH(); + } + return (gain_word*(rx_pga_gain_range.max - rx_pga_gain_range.min)/0x14) + rx_pga_gain_range.min; +} + /*********************************************************************** * Codec Control AUX ADC Methods **********************************************************************/ diff --git a/host/lib/usrp/usrp_e/codec_ctrl.hpp b/host/lib/usrp/usrp_e/codec_ctrl.hpp index b9005a82d..87b6ff951 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.hpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.hpp @@ -19,6 +19,7 @@ #define INCLUDED_USRP_E_CODEC_CTRL_HPP #include "usrp_e_iface.hpp" +#include #include #include @@ -31,10 +32,13 @@ class usrp_e_codec_ctrl : boost::noncopyable{ public: typedef boost::shared_ptr sptr; + static const uhd::gain_range_t tx_pga_gain_range; + static const uhd::gain_range_t rx_pga_gain_range; + /*! - * Make a new clock control object. + * Make a new codec control object. * \param iface the usrp_e iface object - * \return the clock control object + * \return the codec control object */ static sptr make(usrp_e_iface::sptr iface); @@ -70,6 +74,17 @@ public: */ virtual void write_aux_dac(aux_dac_t which, float volts) = 0; + //! Set the TX PGA gain + virtual void set_tx_pga_gain(float gain) = 0; + + //! Get the TX PGA gain + virtual float get_tx_pga_gain(void) = 0; + + //! Set the RX PGA gain ('A' or 'B') + virtual void set_rx_pga_gain(float gain, char which) = 0; + + //! Get the RX PGA gain ('A' or 'B') + virtual float get_rx_pga_gain(char which) = 0; }; #endif /* INCLUDED_USRP_E_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e/codec_impl.cpp b/host/lib/usrp/usrp_e/codec_impl.cpp index 51f7b02b8..84f8bd37f 100644 --- a/host/lib/usrp/usrp_e/codec_impl.cpp +++ b/host/lib/usrp/usrp_e/codec_impl.cpp @@ -16,6 +16,7 @@ // #include "usrp_e_impl.hpp" +#include #include #include @@ -40,6 +41,8 @@ void usrp_e_impl::codec_init(void){ /*********************************************************************** * RX Codec Properties **********************************************************************/ +static const std::string ad9862_pga_gain_name = "ad9862 pga"; + void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ wax::obj key; std::string name; boost::tie(key, name) = extract_named_prop(key_); @@ -55,15 +58,46 @@ void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ return; case CODEC_PROP_GAIN_NAMES: - val = prop_names_t(); //no gain elements to be controlled + val = prop_names_t(1, ad9862_pga_gain_name); + return; + + case CODEC_PROP_GAIN_RANGE: + UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + val = usrp_e_codec_ctrl::rx_pga_gain_range; + return; + + case CODEC_PROP_GAIN_I: + UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + val = _codec_ctrl->get_rx_pga_gain('A'); + return; + + case CODEC_PROP_GAIN_Q: + UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + val = _codec_ctrl->get_rx_pga_gain('B'); return; default: UHD_THROW_PROP_GET_ERROR(); } } -void usrp_e_impl::rx_codec_set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); +void usrp_e_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the set request conditioned on the key + switch(key.as()){ + case CODEC_PROP_GAIN_I: + UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + _codec_ctrl->set_rx_pga_gain(val.as(), 'A'); + return; + + case CODEC_PROP_GAIN_Q: + UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + _codec_ctrl->set_rx_pga_gain(val.as(), 'B'); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } } /*********************************************************************** @@ -84,13 +118,36 @@ void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ return; case CODEC_PROP_GAIN_NAMES: - val = prop_names_t(); //no gain elements to be controlled + val = prop_names_t(1, ad9862_pga_gain_name); + return; + + case CODEC_PROP_GAIN_RANGE: + UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + val = usrp_e_codec_ctrl::tx_pga_gain_range; + return; + + case CODEC_PROP_GAIN_I: //only one gain for I and Q + case CODEC_PROP_GAIN_Q: + UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + val = _codec_ctrl->get_tx_pga_gain(); return; default: UHD_THROW_PROP_GET_ERROR(); } } -void usrp_e_impl::tx_codec_set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); +void usrp_e_impl::tx_codec_set(const wax::obj &key_, const wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the set request conditioned on the key + switch(key.as()){ + case CODEC_PROP_GAIN_I: //only one gain for I and Q + case CODEC_PROP_GAIN_Q: + UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + _codec_ctrl->set_tx_pga_gain(val.as()); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } } -- cgit v1.2.3 From a340b9fb5ffe0e43a746ce8ce051b08444a1a713 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 13 Aug 2010 19:30:32 +0000 Subject: usrp-e: clock settings, ref doubler, disable test clock, lower cp current --- host/lib/usrp/usrp_e/clock_ctrl.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index b53e880a2..22578a933 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -38,11 +38,13 @@ template static void set_clock_divider /*********************************************************************** * Constants **********************************************************************/ -static const double ref_clock_rate = 10e6; +static const bool enable_test_clock = false; +static const double ref_clock_doubler = 2; //enabled below +static const double ref_clock_rate = 10e6 * ref_clock_doubler; static const size_t r_counter = 1; static const size_t a_counter = 0; -static const size_t b_counter = 20; +static const size_t b_counter = 20 / ref_clock_doubler; static const size_t prescaler = 8; //set below with enum, set to 8 when input is under 2400 MHz static const size_t vco_divider = 1; //set below with enum @@ -64,6 +66,7 @@ public: //init the clock gen registers //Note: out0 should already be clocking the FPGA or this isnt going to work _ad9522_regs.sdo_active = ad9522_regs_t::SDO_ACTIVE_SDO_SDIO; + _ad9522_regs.enable_clock_doubler = 1; //enable ref clock doubler _ad9522_regs.enb_stat_eeprom_at_stat_pin = 0; //use status pin _ad9522_regs.status_pin_control = 0x1; //n divider _ad9522_regs.ld_pin_control = 0x00; //dld @@ -79,7 +82,7 @@ public: _ad9522_regs.prescaler_p = ad9522_regs_t::PRESCALER_P_DIV8_9; _ad9522_regs.pll_power_down = ad9522_regs_t::PLL_POWER_DOWN_NORMAL; - _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_3_0MA; + _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_1_2MA; _ad9522_regs.vco_calibration_now = 1; //calibrate it! _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV1; @@ -103,7 +106,7 @@ public: //setup test clock (same divider as codec clock) _ad9522_regs.out4_format = ad9522_regs_t::OUT4_FORMAT_CMOS; - _ad9522_regs.out4_cmos_configuration = (true)? + _ad9522_regs.out4_cmos_configuration = (enable_test_clock)? ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON : ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF; -- cgit v1.2.3 From 1b47702245f0c1f4dda3e0eff487bbe664d48855 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 17 Aug 2010 17:16:31 +0000 Subject: usrp-e: misc code tweaks --- host/examples/tx_timed_samples.cpp | 2 +- host/lib/usrp/usrp_e/clock_ctrl.cpp | 2 +- host/lib/usrp/usrp_e/codec_ctrl.cpp | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index ceae58a22..aa22d3465 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -77,7 +77,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ sdev->set_time_now(uhd::time_spec_t(0.0)); //allocate data to send - std::vector > buff(samps_per_packet, std::complex(ampl, ampl)); + std::vector > buff(samps_per_packet, std::complex(ampl, ampl)); uhd::tx_metadata_t md; //send the data in multiple packets diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 22578a933..62807aec2 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -39,7 +39,7 @@ template static void set_clock_divider * Constants **********************************************************************/ static const bool enable_test_clock = false; -static const double ref_clock_doubler = 2; //enabled below +static const size_t ref_clock_doubler = 2; //enabled below static const double ref_clock_rate = 10e6 * ref_clock_doubler; static const size_t r_counter = 1; diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index 5322f94bd..2bdbc0f1c 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -97,6 +97,7 @@ usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; _ad9862_regs.dac_a_coarse_gain = 0x3; _ad9862_regs.dac_b_coarse_gain = 0x3; + _ad9862_regs.edges = ad9862_regs_t::EDGES_BOTH; //setup the dll _ad9862_regs.input_clk_ctrl = ad9862_regs_t::INPUT_CLK_CTRL_EXTERNAL; -- cgit v1.2.3 From 1e28ae518de1268efa370eb8b4b206b7d5a49b03 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 17 Aug 2010 19:23:56 +0000 Subject: usrp-e: building off of next branch --- host/config/Version.cmake | 2 +- host/lib/usrp/usrp_e/clock_ctrl.cpp | 3 ++- host/lib/usrp/usrp_e/codec_impl.cpp | 28 ++++++++++++---------------- host/lib/usrp/usrp_e/dboard_iface.cpp | 7 ++++++- host/lib/usrp/usrp_e/dboard_impl.cpp | 10 ++++------ host/lib/usrp/usrp_e/dsp_impl.cpp | 3 ++- host/lib/usrp/usrp_e/io_impl.cpp | 2 +- host/lib/usrp/usrp_e/mboard_impl.cpp | 16 +++++++--------- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 5 ++--- 9 files changed, 37 insertions(+), 39 deletions(-) (limited to 'host') diff --git a/host/config/Version.cmake b/host/config/Version.cmake index a592a4565..9e4b6b306 100644 --- a/host/config/Version.cmake +++ b/host/config/Version.cmake @@ -42,7 +42,7 @@ ELSE(${GIT} STREQUAL "GIT-NOTFOUND") #extract the timestamp from the git log entry EXECUTE_PROCESS( WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - COMMAND ${PYTHON_EXECUTABLE} -c "import re; print re.match('^.*Date:\\s*(\\d*).*$', '''${_git_log}''', re.MULTILINE | re.DOTALL).groups()[0]" + COMMAND ${PYTHON_EXECUTABLE} -c "import re; print re.match('^.*Date:\\s*(\\d*).*$', ''' ${_git_log} ''', re.MULTILINE | re.DOTALL).groups()[0]" OUTPUT_VARIABLE _git_timestamp OUTPUT_STRIP_TRAILING_WHITESPACE ) diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 62807aec2..10f263e1d 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -160,7 +160,8 @@ public: std::vector get_rx_dboard_clock_rates(void){ std::vector rates; - for(size_t div = 1; div <= 16+16; div++) rates.push_back(master_clock_rate/div); + for(size_t div = 2/*vco div == 1*/; div <= 16+16; div++) + rates.push_back(master_clock_rate/div); return rates; } diff --git a/host/lib/usrp/usrp_e/codec_impl.cpp b/host/lib/usrp/usrp_e/codec_impl.cpp index 84f8bd37f..696fb37ec 100644 --- a/host/lib/usrp/usrp_e/codec_impl.cpp +++ b/host/lib/usrp/usrp_e/codec_impl.cpp @@ -44,8 +44,7 @@ void usrp_e_impl::codec_init(void){ static const std::string ad9862_pga_gain_name = "ad9862 pga"; void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()){ @@ -62,17 +61,17 @@ void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ return; case CODEC_PROP_GAIN_RANGE: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); val = usrp_e_codec_ctrl::rx_pga_gain_range; return; case CODEC_PROP_GAIN_I: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); val = _codec_ctrl->get_rx_pga_gain('A'); return; case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); val = _codec_ctrl->get_rx_pga_gain('B'); return; @@ -81,18 +80,17 @@ void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ } void usrp_e_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the set request conditioned on the key switch(key.as()){ case CODEC_PROP_GAIN_I: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); _codec_ctrl->set_rx_pga_gain(val.as(), 'A'); return; case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); _codec_ctrl->set_rx_pga_gain(val.as(), 'B'); return; @@ -104,8 +102,7 @@ void usrp_e_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ * TX Codec Properties **********************************************************************/ void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()){ @@ -122,13 +119,13 @@ void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ return; case CODEC_PROP_GAIN_RANGE: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); val = usrp_e_codec_ctrl::tx_pga_gain_range; return; case CODEC_PROP_GAIN_I: //only one gain for I and Q case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); val = _codec_ctrl->get_tx_pga_gain(); return; @@ -137,14 +134,13 @@ void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ } void usrp_e_impl::tx_codec_set(const wax::obj &key_, const wax::obj &val){ - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the set request conditioned on the key switch(key.as()){ case CODEC_PROP_GAIN_I: //only one gain for I and Q case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); _codec_ctrl->set_tx_pga_gain(val.as()); return; diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp index d5ec10d84..a9831ebc4 100644 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -50,7 +50,12 @@ public: /* NOP */ } - std::string get_mboard_name(void){return "usrp-e";} + special_props_t get_special_props(void){ + special_props_t props; + props.soft_clock_divider = false; + props.mangle_i2c_addrs = false; + return props; + } void write_aux_dac(unit_t, aux_dac_t, float); float read_aux_adc(unit_t, aux_adc_t); diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index 8aaf16c51..79ff54c9d 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -56,8 +56,7 @@ void usrp_e_impl::dboard_init(void){ * RX Dboard Get **********************************************************************/ void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()){ @@ -66,7 +65,7 @@ void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ return; case DBOARD_PROP_SUBDEV: - val = _dboard_manager->get_rx_subdev(name); + val = _dboard_manager->get_rx_subdev(key.name); return; case DBOARD_PROP_SUBDEV_NAMES: @@ -107,8 +106,7 @@ void usrp_e_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ * TX Dboard Get **********************************************************************/ void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()){ @@ -117,7 +115,7 @@ void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ return; case DBOARD_PROP_SUBDEV: - val = _dboard_manager->get_tx_subdev(name); + val = _dboard_manager->get_tx_subdev(key.name); return; case DBOARD_PROP_SUBDEV_NAMES: diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp index 58a58706d..c133eafae 100644 --- a/host/lib/usrp/usrp_e/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -17,8 +17,9 @@ #include "usrp_e_impl.hpp" #include "usrp_e_regs.hpp" -#include "../dsp_utils.hpp" +#include #include +#include #include #define rint boost::math::iround diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index bbc3f5215..eaa45d60c 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -17,7 +17,7 @@ #include "usrp_e_impl.hpp" #include "usrp_e_regs.hpp" -#include "../dsp_utils.hpp" +#include #include "../../transport/vrt_packet_handler.hpp" #include #include //read, write diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index 88e16a6f5..3d4cef069 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -17,8 +17,8 @@ #include "usrp_e_impl.hpp" #include "usrp_e_regs.hpp" -#include "../dsp_utils.hpp" -#include "../misc_utils.hpp" +#include +#include #include #include #include @@ -47,9 +47,7 @@ void usrp_e_impl::mboard_init(void){ * Mboard Get **********************************************************************/ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); - + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()){ @@ -62,7 +60,7 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_RX_DBOARD: - UHD_ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(key.name == ""); val = _rx_dboard_proxy->get_link(); return; @@ -71,7 +69,7 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_TX_DBOARD: - UHD_ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(key.name == ""); val = _tx_dboard_proxy->get_link(); return; @@ -80,7 +78,7 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_RX_DSP: - UHD_ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(key.name == ""); val = _rx_ddc_proxy->get_link(); return; @@ -89,7 +87,7 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_TX_DSP: - UHD_ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(key.name == ""); val = _tx_duc_proxy->get_link(); return; diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 0566cfd59..5c0e1dbb0 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -113,8 +113,7 @@ usrp_e_impl::~usrp_e_impl(void){ * Device Get **********************************************************************/ void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()){ @@ -123,7 +122,7 @@ void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ return; case DEVICE_PROP_MBOARD: - UHD_ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(key.name == ""); val = _mboard_proxy->get_link(); return; -- cgit v1.2.3 From 270fb931f11b23a0119a8fe836bbd712d9a50c60 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 17 Aug 2010 23:38:39 +0000 Subject: Merging my work back to usrp_e branch. --- host/examples/rx_to_file.cpp | 138 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 host/examples/rx_to_file.cpp (limited to 'host') diff --git a/host/examples/rx_to_file.cpp b/host/examples/rx_to_file.cpp new file mode 100644 index 000000000..cb8c42acc --- /dev/null +++ b/host/examples/rx_to_file.cpp @@ -0,0 +1,138 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace po = boost::program_options; + + +int UHD_SAFE_MAIN(int argc, char *argv[]){ + uhd::set_thread_priority_safe(); + + //variables to be set by po + std::string args; + time_t seconds_in_future; + size_t total_num_samps; + double rx_rate, freq; + + //setup the program options + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("args", po::value(&args)->default_value(""), "simple uhd device address args") + ("secs", po::value(&seconds_in_future)->default_value(3), "number of seconds in the future to receive") + ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to receive") + ("rxrate", po::value(&rx_rate)->default_value(100e6/16), "rate of incoming samples") + ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") + ("dilv", "specify to disable inner-loop verbose") + ; + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")){ + std::cout << boost::format("UHD RX Timed Samples %s") % desc << std::endl; + return ~0; + } + + bool verbose = vm.count("dilv") == 0; + + //create a usrp device + std::cout << std::endl; + std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; + uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args); + uhd::device::sptr dev = sdev->get_device(); + std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; + + //set properties on the device + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate/1e6) << std::endl; + sdev->set_rx_rate(rx_rate); + std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl; + std::cout << boost::format("Setting device timestamp to 0...") << std::endl; + sdev->set_rx_freq(freq); + sdev->set_time_now(uhd::time_spec_t(0.0)); + + sleep(1); + std::cout << "LO Locked = " << sdev->get_rx_lo_locked() << std::endl; + + //setup streaming + std::cout << std::endl; + std::cout << boost::format( + "Begin streaming %u samples, %d seconds in the future..." + ) % total_num_samps % seconds_in_future << std::endl; + uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = total_num_samps; + stream_cmd.stream_now = false; + stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); + sdev->issue_stream_cmd(stream_cmd); + + //loop until total number of samples reached + size_t num_acc_samps = 0; //number of accumulated samples + uhd::rx_metadata_t md; + std::vector > buff(dev->get_max_recv_samps_per_packet()); + std::ofstream outfile("out.dat", std::ofstream::binary); + + while(num_acc_samps < total_num_samps){ + size_t num_rx_samps = dev->recv( + &buff.front(), buff.size(), md, + uhd::io_type_t::COMPLEX_INT16, + uhd::device::RECV_MODE_ONE_PACKET + ); + + //handle the error codes + switch(md.error_code){ + case uhd::rx_metadata_t::ERROR_CODE_NONE: + break; + + case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: + if (num_acc_samps == 0) continue; + std::cout << boost::format( + "Got timeout before all samples received, possible packet loss, exiting loop..." + ) << std::endl; + goto done_loop; + + default: + std::cout << boost::format( + "Got error code 0x%x, exiting loop..." + ) % md.error_code << std::endl; + goto done_loop; + } + + outfile.write((const char*)&buff[0], num_rx_samps * sizeof(std::complex)); + + if(verbose) std::cout << boost::format( + "Got packet: %u samples, %u full secs, %f frac secs" + ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl; + + num_acc_samps += num_rx_samps; + } done_loop: + + outfile.close(); + + //finished + std::cout << std::endl << "Done!" << std::endl << std::endl; + + return 0; +} -- cgit v1.2.3 From e48dfb211609e26230c2e7c165ad3aa5d5b0ecfc Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 17 Aug 2010 23:39:36 +0000 Subject: Fix to create 90 phase shift on TX. --- host/lib/usrp/usrp_e/codec_ctrl.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index 2bdbc0f1c..45063894e 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -89,6 +89,7 @@ usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ //setup tx side of codec _ad9862_regs.two_data_paths = ad9862_regs_t::TWO_DATA_PATHS_BOTH; _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED; + _ad9862_regs.tx_retime = ad9862_regs_t::TX_RETIME_CLKOUT2; _ad9862_regs.tx_pga_gain = 199; //TODO bring under api control _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; _ad9862_regs.interp = ad9862_regs_t::INTERP_2; -- cgit v1.2.3 From f7fab232e5b6124b0bda821736ac309ccc0cab94 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 18 Aug 2010 00:41:41 +0000 Subject: Really fix TX IQ phase offset. --- host/lib/usrp/usrp_e/codec_ctrl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index 45063894e..837219759 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -29,7 +29,7 @@ using namespace uhd; -static const bool codec_debug = false; +static const bool codec_debug = true; const gain_range_t usrp_e_codec_ctrl::tx_pga_gain_range(-20, 0, float(0.1)); const gain_range_t usrp_e_codec_ctrl::rx_pga_gain_range(0, 20, 1); @@ -98,7 +98,7 @@ usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; _ad9862_regs.dac_a_coarse_gain = 0x3; _ad9862_regs.dac_b_coarse_gain = 0x3; - _ad9862_regs.edges = ad9862_regs_t::EDGES_BOTH; + _ad9862_regs.edges = ad9862_regs_t::EDGES_NORMAL; //setup the dll _ad9862_regs.input_clk_ctrl = ad9862_regs_t::INPUT_CLK_CTRL_EXTERNAL; -- cgit v1.2.3 From c3fc2010bffbb74414c029910347c6aa28c2b8d4 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 18 Aug 2010 00:53:58 +0000 Subject: usrp-e: added gain group property --- host/lib/usrp/usrp_e/dboard_iface.cpp | 5 ++++- host/lib/usrp/usrp_e/dboard_impl.cpp | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp index a9831ebc4..c9efd0c9e 100644 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -44,6 +44,9 @@ public: //init the clock rate shadows this->set_clock_rate(UNIT_RX, _clock->get_fpga_clock_rate()); this->set_clock_rate(UNIT_TX, _clock->get_fpga_clock_rate()); + + _iface->poke16(UE_REG_GPIO_RX_DBG, 0); + _iface->poke16(UE_REG_GPIO_TX_DBG, 0); } ~usrp_e_dboard_iface(void){ @@ -165,8 +168,8 @@ boost::uint16_t usrp_e_dboard_iface::read_gpio(unit_t unit){ switch(unit){ case UNIT_RX: return _iface->peek16(UE_REG_GPIO_RX_IO); case UNIT_TX: return _iface->peek16(UE_REG_GPIO_TX_IO); + default: UHD_THROW_INVALID_CODE_PATH(); } - UHD_ASSERT_THROW(false); } void usrp_e_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){ diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index 79ff54c9d..d4a27cb72 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -84,6 +85,14 @@ void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ val = _rx_codec_proxy->get_link(); return; + case DBOARD_PROP_GAIN_GROUP: + val = make_gain_group( + _dboard_manager->get_rx_subdev(key.name), + _rx_codec_proxy->get_link(), + GAIN_GROUP_POLICY_RX + ); + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -134,6 +143,14 @@ void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ val = _tx_codec_proxy->get_link(); return; + case DBOARD_PROP_GAIN_GROUP: + val = make_gain_group( + _dboard_manager->get_tx_subdev(key.name), + _tx_codec_proxy->get_link(), + GAIN_GROUP_POLICY_TX + ); + return; + default: UHD_THROW_PROP_GET_ERROR(); } } -- cgit v1.2.3 From 50b70be92442c05f8cebb63f51333dab2568ca71 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 18 Aug 2010 22:07:09 +0000 Subject: Build rx_to_file example. --- host/examples/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'host') diff --git a/host/examples/CMakeLists.txt b/host/examples/CMakeLists.txt index 10a9a833a..70e74a9a8 100644 --- a/host/examples/CMakeLists.txt +++ b/host/examples/CMakeLists.txt @@ -25,6 +25,9 @@ TARGET_LINK_LIBRARIES(benchmark_rx_rate uhd) ADD_EXECUTABLE(rx_timed_samples rx_timed_samples.cpp) TARGET_LINK_LIBRARIES(rx_timed_samples uhd) +ADD_EXECUTABLE(rx_to_file rx_to_file.cpp) +TARGET_LINK_LIBRARIES(rx_to_file uhd) + ADD_EXECUTABLE(tx_timed_samples tx_timed_samples.cpp) TARGET_LINK_LIBRARIES(tx_timed_samples uhd) -- cgit v1.2.3 From b0a2f23bb66fce362b70117efe7b4e967e891c14 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 19 Aug 2010 16:25:03 +0000 Subject: Add program to transmit samples from a file. --- host/examples/CMakeLists.txt | 5 ++ host/examples/tx_from_file.cpp | 123 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 host/examples/tx_from_file.cpp (limited to 'host') diff --git a/host/examples/CMakeLists.txt b/host/examples/CMakeLists.txt index 70e74a9a8..cad01a7cc 100644 --- a/host/examples/CMakeLists.txt +++ b/host/examples/CMakeLists.txt @@ -31,10 +31,15 @@ TARGET_LINK_LIBRARIES(rx_to_file uhd) ADD_EXECUTABLE(tx_timed_samples tx_timed_samples.cpp) TARGET_LINK_LIBRARIES(tx_timed_samples uhd) +ADD_EXECUTABLE(tx_from_file tx_from_file.cpp) +TARGET_LINK_LIBRARIES(tx_from_file uhd) + INSTALL(TARGETS tx_continuous_samples benchmark_rx_rate rx_timed_samples tx_timed_samples + tx_from_file + rx_to_file RUNTIME DESTINATION ${PKG_DATA_DIR}/examples ) diff --git a/host/examples/tx_from_file.cpp b/host/examples/tx_from_file.cpp new file mode 100644 index 000000000..df6446c0c --- /dev/null +++ b/host/examples/tx_from_file.cpp @@ -0,0 +1,123 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace po = boost::program_options; + +int UHD_SAFE_MAIN(int argc, char *argv[]){ + uhd::set_thread_priority_safe(); + + //variables to be set by po + std::string args; + time_t seconds_in_future; + size_t total_num_samps; + size_t samps_per_packet; + double tx_rate, freq; + float ampl; + + //setup the program options + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("args", po::value(&args)->default_value(""), "simple uhd device address args") + ("secs", po::value(&seconds_in_future)->default_value(3), "number of seconds in the future to transmit") + ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to transmit") + ("txrate", po::value(&tx_rate)->default_value(100e6/16), "rate of outgoing samples") + ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") + ("ampl", po::value(&l)->default_value(float(0.3)), "amplitude of each sample") + ("dilv", "specify to disable inner-loop verbose") + ; + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")){ + std::cout << boost::format("UHD TX Timed Samples %s") % desc << std::endl; + return ~0; + } + + bool verbose = vm.count("dilv") == 0; + + //create a usrp device + std::cout << std::endl; + std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; + uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args); + uhd::device::sptr dev = sdev->get_device(); + std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; + + //set properties on the device + std::cout << boost::format("Setting TX Rate: %f Msps...") % (tx_rate/1e6) << std::endl; + sdev->set_tx_rate(tx_rate); + std::cout << boost::format("Actual TX Rate: %f Msps...") % (sdev->get_tx_rate()/1e6) << std::endl; + std::cout << boost::format("Setting device timestamp to 0...") << std::endl; + sdev->set_tx_freq(freq); + sdev->set_time_now(uhd::time_spec_t(0.0)); + + sdev->set_tx_gain(0); + + //allocate data to send + std::vector > buff; + uhd::tx_metadata_t md; + + std::cout << "Read data to send from file: in.dat" << std::endl; + std::ifstream infile("in.dat", std::ifstream::binary); + while (!infile.eof()) { + std::complex c; + infile.read((char *)&c, sizeof(std::complex)); + if (!((c.real() == 0) && (c.imag() == 0))) { + buff.push_back(c); +//std::cout << "C = " << c << std::endl; + } + } + samps_per_packet = buff.size(); + infile.close(); + std::cout << "Number of samples in file: " << samps_per_packet << std::endl; + + //send the data in multiple packets + size_t num_packets = (total_num_samps+samps_per_packet-1)/samps_per_packet; + for (size_t i = 0; i < num_packets; i++){ + //setup the metadata flags and time spec + md.start_of_burst = true; //always SOB (good for continuous streaming) + md.end_of_burst = (i == num_packets-1); //only last packet has EOB + md.has_time_spec = (i == 0); //only first packet has time + md.time_spec = uhd::time_spec_t(seconds_in_future); + + size_t samps_to_send = std::min(total_num_samps - samps_per_packet*i, samps_per_packet); + + //send the entire packet (driver fragments internally) + size_t num_tx_samps = dev->send( + &buff.front(), samps_to_send, md, + uhd::io_type_t::COMPLEX_INT16, + uhd::device::SEND_MODE_FULL_BUFF + ); + if(verbose) std::cout << std::endl << boost::format("Sent %d samples") % num_tx_samps << std::endl; + } + + //finished + std::cout << std::endl << "Done!" << std::endl << std::endl; + + return 0; +} -- cgit v1.2.3 From 2ef82f57b815a9e53685617f1b779d4cbdf7fb31 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 19 Aug 2010 16:26:37 +0000 Subject: Add get setting to the rx_to_file program. --- host/examples/rx_to_file.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'host') diff --git a/host/examples/rx_to_file.cpp b/host/examples/rx_to_file.cpp index cb8c42acc..79d3e9d8b 100644 --- a/host/examples/rx_to_file.cpp +++ b/host/examples/rx_to_file.cpp @@ -74,6 +74,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ sdev->set_rx_freq(freq); sdev->set_time_now(uhd::time_spec_t(0.0)); + uhd::gain_range_t rx_gain = sdev->get_rx_gain_range(); + std::cout << "Setting RX Gain to: " << rx_gain.max << std::endl; + sdev->set_rx_gain(rx_gain.max); + sleep(1); std::cout << "LO Locked = " << sdev->get_rx_lo_locked() << std::endl; -- cgit v1.2.3 From f568f651c423fca8c9cf607655ea50ac4cfab524 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 19 Aug 2010 16:27:51 +0000 Subject: Add gain setting to tx_timed_samples program. --- host/examples/tx_timed_samples.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'host') diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index aa22d3465..fa5bf4b2b 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -75,6 +75,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << boost::format("Setting device timestamp to 0...") << std::endl; sdev->set_tx_freq(freq); sdev->set_time_now(uhd::time_spec_t(0.0)); + sdev->set_tx_gain(0); //allocate data to send std::vector > buff(samps_per_packet, std::complex(ampl, ampl)); -- cgit v1.2.3 From 38722979512f0f6d57db9fd5e314b94cad1f188e Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 19 Aug 2010 20:34:56 +0000 Subject: Add gain command line parameter. --- host/examples/tx_timed_samples.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'host') diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index fa5bf4b2b..f7d7ea2ca 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -35,6 +35,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ size_t samps_per_packet; double tx_rate, freq; float ampl; + float tx_gain; //setup the program options po::options_description desc("Allowed options"); @@ -47,6 +48,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("txrate", po::value(&tx_rate)->default_value(100e6/16), "rate of outgoing samples") ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") ("ampl", po::value(&l)->default_value(float(0.3)), "amplitude of each sample") + ("gain", po::value(&tx_gain)->default_value(float(0)), "TX Gain setting") ("dilv", "specify to disable inner-loop verbose") ; po::variables_map vm; @@ -75,7 +77,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << boost::format("Setting device timestamp to 0...") << std::endl; sdev->set_tx_freq(freq); sdev->set_time_now(uhd::time_spec_t(0.0)); - sdev->set_tx_gain(0); + sdev->set_tx_gain(tx_gain); //allocate data to send std::vector > buff(samps_per_packet, std::complex(ampl, ampl)); -- cgit v1.2.3 From 6be4654073523d0666be552eee28445eb5f72297 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 19 Aug 2010 22:23:01 +0000 Subject: Change clock dividers so DBSRX board locks. --- host/lib/usrp/usrp_e/clock_ctrl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 10f263e1d..9d4625305 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -46,7 +46,7 @@ static const size_t r_counter = 1; static const size_t a_counter = 0; static const size_t b_counter = 20 / ref_clock_doubler; static const size_t prescaler = 8; //set below with enum, set to 8 when input is under 2400 MHz -static const size_t vco_divider = 1; //set below with enum +static const size_t vco_divider = 5; //set below with enum static const size_t n_counter = prescaler * b_counter + a_counter; static const size_t vco_clock_rate = ref_clock_rate/r_counter * n_counter; //between 1400 and 1800 MHz @@ -85,7 +85,7 @@ public: _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_1_2MA; _ad9522_regs.vco_calibration_now = 1; //calibrate it! - _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV1; + _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_VCO; //setup fpga master clock @@ -160,7 +160,7 @@ public: std::vector get_rx_dboard_clock_rates(void){ std::vector rates; - for(size_t div = 2/*vco div == 1*/; div <= 16+16; div++) + for(size_t div = 1; div <= 16+16; div++) rates.push_back(master_clock_rate/div); return rates; } -- cgit v1.2.3 From ee20f8eb4f64d3fd8c34ef9cde5d125bd5a14816 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 18 Aug 2010 23:59:58 +0000 Subject: Change TX PGA gain scaling to match gnuradio scaling --- host/lib/usrp/usrp_e/codec_ctrl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index 837219759..17262d358 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -134,8 +134,8 @@ usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){ * Codec Control Gain Control Methods **********************************************************************/ void usrp_e_codec_ctrl_impl::set_tx_pga_gain(float gain){ - int gain_word = int(63*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); - _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, 63); + int gain_word = int(255*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); + _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, 255); this->send_reg(16); } -- cgit v1.2.3 From d3501cda50407143db85f7ea5eb894c71ecd8aac Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 24 Aug 2010 18:11:46 +0000 Subject: usrp-e: added dboard iface set gpio debug call --- host/lib/usrp/usrp_e/dboard_iface.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp index c9efd0c9e..1bd177f60 100644 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -67,6 +67,7 @@ public: void set_atr_reg(unit_t, atr_reg_t, boost::uint16_t); void set_gpio_ddr(unit_t, boost::uint16_t); void write_gpio(unit_t, boost::uint16_t); + void set_gpio_debug(unit_t, int); boost::uint16_t read_gpio(unit_t); void write_i2c(boost::uint8_t, const byte_vector_t &); @@ -193,6 +194,29 @@ void usrp_e_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_ _iface->poke16(unit_to_atr_to_addr[unit][atr], value); } +void usrp_e_dboard_iface::set_gpio_debug(unit_t unit, int which){ + //set this unit to all outputs + this->set_gpio_ddr(unit, 0xffff); + + //calculate the debug selections + boost::uint32_t dbg_sels = 0x0; + int sel = (which == 0)? GPIO_SEL_DEBUG_0 : GPIO_SEL_DEBUG_1; + for(size_t i = 0; i < 16; i++) dbg_sels |= sel << i; + + //set the debug on and which debug selection + switch(unit){ + case UNIT_RX: + _iface->poke16(UE_REG_GPIO_RX_DBG, 0xffff); + _iface->poke16(UE_REG_GPIO_RX_SEL, dbg_sels); + return; + + case UNIT_TX: + _iface->poke16(UE_REG_GPIO_TX_DBG, 0xffff); + _iface->poke16(UE_REG_GPIO_TX_SEL, dbg_sels); + return; + } +} + /*********************************************************************** * SPI **********************************************************************/ -- cgit v1.2.3 From 65821027b8d41e9c736bc7e29a4fa1f84dc890ba Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 24 Aug 2010 19:26:15 +0000 Subject: usrp-e: fixed codec control gain calculation error, added tx policy registers, set to next packet --- host/lib/usrp/usrp_e/codec_ctrl.cpp | 18 +++++++++++------- host/lib/usrp/usrp_e/io_impl.cpp | 2 +- host/lib/usrp/usrp_e/mboard_impl.cpp | 4 ++++ host/lib/usrp/usrp_e/usrp_e_regs.hpp | 6 ++++++ 4 files changed, 22 insertions(+), 8 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index 17262d358..a728d7e46 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -29,7 +29,7 @@ using namespace uhd; -static const bool codec_debug = true; +static const bool codec_debug = false; const gain_range_t usrp_e_codec_ctrl::tx_pga_gain_range(-20, 0, float(0.1)); const gain_range_t usrp_e_codec_ctrl::rx_pga_gain_range(0, 20, 1); @@ -133,19 +133,23 @@ usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){ /*********************************************************************** * Codec Control Gain Control Methods **********************************************************************/ +static const int mtpgw = 255; //maximum tx pga gain word + void usrp_e_codec_ctrl_impl::set_tx_pga_gain(float gain){ - int gain_word = int(255*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); - _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, 255); + int gain_word = int(mtpgw*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); + _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw); this->send_reg(16); } float usrp_e_codec_ctrl_impl::get_tx_pga_gain(void){ - return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.max - tx_pga_gain_range.min)/63) + tx_pga_gain_range.min; + return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.max - tx_pga_gain_range.min)/mtpgw) + tx_pga_gain_range.min; } +static const int mrpgw = 0x14; //maximum rx pga gain word + void usrp_e_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ - int gain_word = int(0x14*(gain - rx_pga_gain_range.min)/(rx_pga_gain_range.max - rx_pga_gain_range.min)); - gain_word = std::clip(gain_word, 0, 0x14); + int gain_word = int(mrpgw*(gain - rx_pga_gain_range.min)/(rx_pga_gain_range.max - rx_pga_gain_range.min)); + gain_word = std::clip(gain_word, 0, mrpgw); switch(which){ case 'A': _ad9862_regs.rx_pga_a = gain_word; @@ -166,7 +170,7 @@ float usrp_e_codec_ctrl_impl::get_rx_pga_gain(char which){ case 'B': gain_word = _ad9862_regs.rx_pga_b; break; default: UHD_THROW_INVALID_CODE_PATH(); } - return (gain_word*(rx_pga_gain_range.max - rx_pga_gain_range.min)/0x14) + rx_pga_gain_range.min; + return (gain_word*(rx_pga_gain_range.max - rx_pga_gain_range.min)/mrpgw) + rx_pga_gain_range.min; } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index eaa45d60c..1bb67d9aa 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -33,7 +33,7 @@ using namespace uhd::usrp; * Constants **********************************************************************/ static const size_t MAX_BUFF_SIZE = 2048; -static const bool usrp_e_io_impl_verbose = true; +static const bool usrp_e_io_impl_verbose = false; /*********************************************************************** * Data Transport (phony zero-copy with read/write) diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index 3d4cef069..047db3f7c 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -41,6 +41,10 @@ void usrp_e_impl::mboard_init(void){ _clock_config.pps_source = clock_config_t::PPS_SMA; //TODO poke the clock config regs + + //setup the tx policy + _iface->poke32(UE_REG_CTRL_TX_REPORT_SID, 1); + _iface->poke32(UE_REG_CTRL_TX_POLICY, UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET); } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp index 41cbfa1e2..a4f42093e 100644 --- a/host/lib/usrp/usrp_e/usrp_e_regs.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -151,6 +151,12 @@ //////////////////////////////////////////////// #define UE_REG_CTRL_TX_NCHANNELS UE_REG_SR_ADDR(24) #define UE_REG_CTRL_TX_CLEAR_UNDERRUN UE_REG_SR_ADDR(25) +#define UE_REG_CTRL_TX_REPORT_SID UE_REG_SR_ADDR(26) +#define UE_REG_CTRL_TX_POLICY UE_REG_SR_ADDR(27) + +#define UE_FLAG_CTRL_TX_POLICY_WAIT (0x1 << 0) +#define UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET (0x1 << 1) +#define UE_FLAG_CTRL_TX_POLICY_NEXT_BURST (0x1 << 2) ///////////////////////////////////////////////// // VITA49 64 bit time (write only) -- cgit v1.2.3 From 924914beaac3dd3a2d9fe40c9067ad4f9147a4f6 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 25 Aug 2010 21:10:41 +0000 Subject: usrp-e: implemented tx policy and handling of async messages --- host/lib/usrp/usrp_e/io_impl.cpp | 129 +++++++++++++++++++++++++++++++---- host/lib/usrp/usrp_e/mboard_impl.cpp | 4 -- 2 files changed, 114 insertions(+), 19 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 1bb67d9aa..31ea4c6c0 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -18,6 +18,8 @@ #include "usrp_e_impl.hpp" #include "usrp_e_regs.hpp" #include +#include +#include #include "../../transport/vrt_packet_handler.hpp" #include #include //read, write @@ -28,12 +30,15 @@ using namespace uhd; using namespace uhd::usrp; +using namespace uhd::transport; /*********************************************************************** * Constants **********************************************************************/ static const size_t MAX_BUFF_SIZE = 2048; static const bool usrp_e_io_impl_verbose = false; +static const size_t tx_async_report_sid = 1; +static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET; /*********************************************************************** * Data Transport (phony zero-copy with read/write) @@ -52,15 +57,15 @@ public: } size_t get_num_recv_frames(void) const{ - return 10; //FIXME no idea! + return 100; //FIXME no idea! + //this will be an important number when packet ring gets implemented } size_t get_num_send_frames(void) const{ - return 10; //FIXME no idea! + return 100; //FIXME no idea! + //this will be an important number when packet ring gets implemented } - size_t recv_timeout_ms; - private: int _fd; ssize_t send(const boost::asio::const_buffer &buff){ @@ -79,7 +84,7 @@ private: pollfd pfd; pfd.fd = _fd; pfd.events = POLLIN; - ssize_t poll_ret = poll(&pfd, 1, recv_timeout_ms); + ssize_t poll_ret = poll(&pfd, 1, 100/*ms*/); if (poll_ret <= 0){ if (usrp_e_io_impl_verbose) std::cerr << boost::format( "usrp-e io impl recv(): poll() returned non-positive value: %d\n" @@ -111,7 +116,11 @@ private: }; /*********************************************************************** - * IO Implementation Details + * io impl details (internal to this file) + * - pirate crew of 1 + * - bounded buffer + * - thread loop + * - vrt packet handler states **********************************************************************/ struct usrp_e_impl::io_impl{ //state management for the vrt packet handler code @@ -119,9 +128,88 @@ struct usrp_e_impl::io_impl{ vrt_packet_handler::send_state packet_handler_send_state; data_transport transport; bool continuous_streaming; - io_impl(int fd): packet_handler_recv_state(1), transport(fd){} + io_impl(int fd): + transport(fd), + recv_pirate_booty(recv_booty_type::make(transport.get_num_recv_frames())), + async_msg_fifo(bounded_buffer::make(100/*messages deep*/)) + { + /* NOP */ + } + + ~io_impl(void){ + recv_pirate_crew_raiding = false; + recv_pirate_crew.interrupt_all(); + recv_pirate_crew.join_all(); + } + + bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs, size_t timeout_ms){ + UHD_ASSERT_THROW(buffs.size() == 1); + boost::this_thread::disable_interruption di; //disable because the wait can throw + return recv_pirate_booty->pop_with_timed_wait(buffs.front(), boost::posix_time::milliseconds(timeout_ms)); + } + + //a pirate's life is the life for me! + void recv_pirate_loop(); + typedef bounded_buffer recv_booty_type; + recv_booty_type::sptr recv_pirate_booty; + bounded_buffer::sptr async_msg_fifo; + boost::thread_group recv_pirate_crew; + bool recv_pirate_crew_raiding; }; +/*********************************************************************** + * Receive Pirate Loop + * - while raiding, loot for recv buffers + * - put booty into the alignment buffer + **********************************************************************/ +void usrp_e_impl::io_impl::recv_pirate_loop( + +){ + set_thread_priority_safe(); + recv_pirate_crew_raiding = true; + //size_t next_packet_seq = 0; + + while(recv_pirate_crew_raiding){ + managed_recv_buffer::sptr buff = this->transport.get_recv_buff(); + if (not buff.get()) continue; //ignore timeout/error buffers + + try{ + //extract the vrt header packet info + vrt::if_packet_info_t if_packet_info; + if_packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t); + const boost::uint32_t *vrt_hdr = buff->cast(); + vrt::if_hdr_unpack_le(vrt_hdr, if_packet_info); + + //handle a tx async report message + if (if_packet_info.sid == tx_async_report_sid and if_packet_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){ + + //fill in the async metadata + async_metadata_t metadata; + metadata.channel = 0; + metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf; + metadata.time_spec = time_spec_t( + time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), MASTER_CLOCK_RATE + ); + metadata.event_code = vrt_packet_handler::get_context_code(vrt_hdr, if_packet_info); + + //print the famous U, and push the metadata into the message queue + if (metadata.event_code & underflow_flags) std::cerr << "U" << std::flush; + async_msg_fifo->push_with_pop_on_full(metadata); + continue; + } + + }catch(const std::exception &e){ + std::cerr << "Error (usrp-e recv pirate loop): " << e.what() << std::endl; + } + + //usrp-e back-pressures on receive: push with wait + recv_pirate_booty->push_with_wait(buff); + } +} + +/*********************************************************************** + * Helper Functions + **********************************************************************/ void usrp_e_impl::io_init(void){ //setup rx data path _iface->poke32(UE_REG_CTRL_RX_NSAMPS_PER_PKT, get_max_recv_samps_per_packet()); @@ -136,7 +224,16 @@ void usrp_e_impl::io_init(void){ _iface->poke32(UE_REG_CTRL_RX_VRT_STREAM_ID, 0); _iface->poke32(UE_REG_CTRL_RX_VRT_TRAILER, 0); + //setup the tx policy + _iface->poke32(UE_REG_CTRL_TX_REPORT_SID, tx_async_report_sid); + _iface->poke32(UE_REG_CTRL_TX_POLICY, UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET); + _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface->get_file_descriptor())); + + //spawn a pirate, yarrr! + _io_impl->recv_pirate_crew.create_thread(boost::bind( + &usrp_e_impl::io_impl::recv_pirate_loop, _io_impl.get() + )); } void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ @@ -217,9 +314,6 @@ size_t usrp_e_impl::recv( recv_otw_type.shift = 0; recv_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; - //hand-off the timeout to the transport - _io_impl->transport.recv_timeout_ms = timeout_ms; - return vrt_packet_handler::recv( _io_impl->packet_handler_recv_state, //last state of the recv handler buffs, num_samps, //buffer to fill @@ -227,15 +321,20 @@ size_t usrp_e_impl::recv( io_type, recv_otw_type, //input and output types to convert MASTER_CLOCK_RATE, //master clock tick rate uhd::transport::vrt::if_hdr_unpack_le, - boost::bind(&get_recv_buffs, &_io_impl->transport, _1), + boost::bind(&usrp_e_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout_ms), boost::bind(&usrp_e_impl::handle_overrun, this, _1) ); } /*********************************************************************** - * Dummy Async Recv + * Async Recv **********************************************************************/ -bool usrp_e_impl::recv_async_msg(async_metadata_t &, size_t timeout_ms){ - boost::this_thread::sleep(boost::posix_time::milliseconds(timeout_ms)); - return false; +bool usrp_e_impl::recv_async_msg( + async_metadata_t &async_metadata, + size_t timeout_ms +){ + boost::this_thread::disable_interruption di; //disable because the wait can throw + return _io_impl->async_msg_fifo->pop_with_timed_wait( + async_metadata, boost::posix_time::milliseconds(timeout_ms) + ); } diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index 047db3f7c..3d4cef069 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -41,10 +41,6 @@ void usrp_e_impl::mboard_init(void){ _clock_config.pps_source = clock_config_t::PPS_SMA; //TODO poke the clock config regs - - //setup the tx policy - _iface->poke32(UE_REG_CTRL_TX_REPORT_SID, 1); - _iface->poke32(UE_REG_CTRL_TX_POLICY, UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET); } /*********************************************************************** -- cgit v1.2.3 From 63a07eb9c8ba49657a815e62e8937c65e2a8362a Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sat, 28 Aug 2010 15:23:31 -0400 Subject: Add support for building c programs. Remove -pedantic and -ansi flags. --- host/CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'host') diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index ceea5d024..78948d9bd 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -16,7 +16,7 @@ # CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(UHD CXX) +PROJECT(UHD CXX C) ENABLE_TESTING() ######################################################################## @@ -61,8 +61,6 @@ ENDIF(NOT CMAKE_BUILD_TYPE) IF(CMAKE_COMPILER_IS_GNUCXX) ADD_DEFINITIONS(-Wall) ADD_DEFINITIONS(-Wextra) - ADD_DEFINITIONS(-pedantic) - ADD_DEFINITIONS(-ansi) #only export symbols that are declared to be part of the uhd api: UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN) ENDIF(CMAKE_COMPILER_IS_GNUCXX) -- cgit v1.2.3 From a79d320d7691fea82c9194d59a5d4dc7bbb40317 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sat, 28 Aug 2010 15:30:38 -0400 Subject: Move fpga-downloader and usrp-e-loopback into utils so they get packaged for installation on the USRP Embedded. --- host/utils/CMakeLists.txt | 8 ++ host/utils/fpga-downloader.cpp | 251 +++++++++++++++++++++++++++++++++++++++++ host/utils/usrp-e-loopback.c | 194 +++++++++++++++++++++++++++++++ 3 files changed, 453 insertions(+) create mode 100644 host/utils/fpga-downloader.cpp create mode 100644 host/utils/usrp-e-loopback.c (limited to 'host') diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index c349a9018..0e3f81d0a 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -24,9 +24,17 @@ TARGET_LINK_LIBRARIES(uhd_find_devices uhd) ADD_EXECUTABLE(uhd_usrp_probe uhd_usrp_probe.cpp) TARGET_LINK_LIBRARIES(uhd_usrp_probe uhd) +ADD_EXECUTABLE(fpga-downloader fpga-downloader.cpp) +TARGET_LINK_LIBRARIES(fpga-downloader) + +ADD_EXECUTABLE(usrp-e-loopback usrp-e-loopback.c) +TARGET_LINK_LIBRARIES(usrp-e-loopback pthread) + INSTALL(TARGETS uhd_find_devices uhd_usrp_probe + fpga-downloader + usrp-e-loopback RUNTIME DESTINATION ${RUNTIME_DIR} ) diff --git a/host/utils/fpga-downloader.cpp b/host/utils/fpga-downloader.cpp new file mode 100644 index 000000000..fb96b64a3 --- /dev/null +++ b/host/utils/fpga-downloader.cpp @@ -0,0 +1,251 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003,2004,2008,2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* + * Configuration connections + * + * CCK - MCSPI1_CLK + * DIN - MCSPI1_MOSI + * PROG_B - GPIO_175 - output (change mux) + * DONE - GPIO_173 - input (change mux) + * INIT_B - GPIO_114 - input (change mux) + * +*/ + +const unsigned int PROG_B = 175; +const unsigned int DONE = 173; +const unsigned int INIT_B = 114; + +static std::string bit_file = "safe_u1e.bin"; + +const int BUF_SIZE = 4096; + +enum gpio_direction {IN, OUT}; + +class gpio { + public: + + gpio(unsigned int gpio_num, gpio_direction pin_direction); + + bool get_value(); + void set_value(bool state); + + private: + + std::stringstream base_path; + std::fstream value_file; +}; + +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) +{ + std::fstream export_file; + + 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::fstream direction_file; + 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; +} + +static void prepare_fpga_for_configuration(gpio &prog, gpio &init) +{ + + prog.set_value(true); + prog.set_value(false); + prog.set_value(true); + +#if 0 + bool ready_to_program(false); + unsigned int count(0); + do { + ready_to_program = init.get_value(); + count++; + + sleep(1); + } while (count < 10 && !ready_to_program); + + if (count == 10) { + std::cout << "FPGA not ready for programming." << std::endl; + exit(-1); + } +#endif +} + +spidev::spidev(std::string fname) +{ + int ret; + int mode = 0; + int speed = 12000000; + int bits = 8; + + 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 = 48000000; + tr.bits_per_word = 8; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + +} + +static void send_file_to_fpga(std::string &file_name, gpio &error, gpio &done) +{ + std::ifstream bitstream; + + std::cout << "File name - " << file_name.c_str() << std::endl; + + bitstream.open(file_name.c_str(), std::ios::binary); + if (!bitstream.is_open()) + std::cout << "File " << file_name << " not opened succesfully." << std::endl; + + spidev spi("/dev/spidev1.0"); + char buf[BUF_SIZE]; + char rbuf[BUF_SIZE]; + + do { + bitstream.read(buf, BUF_SIZE); + spi.send(buf, rbuf, bitstream.gcount()); + + if (error.get_value()) + std::cout << "INIT_B went high, error occured." << std::endl; + + if (!done.get_value()) + std::cout << "Configuration complete." << std::endl; + + } while (bitstream.gcount() == BUF_SIZE); +} + +int main(int argc, char *argv[]) +{ + + gpio gpio_prog_b(PROG_B, OUT); + gpio gpio_init_b(INIT_B, IN); + gpio gpio_done (DONE, IN); + + if (argc == 2) + bit_file = argv[1]; + + std::cout << "FPGA config file: " << bit_file << std::endl; + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "Done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bit_file, gpio_init_b, gpio_done); +} + diff --git a/host/utils/usrp-e-loopback.c b/host/utils/usrp-e-loopback.c new file mode 100644 index 000000000..f400fe0be --- /dev/null +++ b/host/utils/usrp-e-loopback.c @@ -0,0 +1,194 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// max length #define PKT_DATA_LENGTH 1016 +static int packet_data_length; +static int error; + +struct pkt { + int len; + int checksum; + int seq_num; + short data[]; +}; + +static int fp; + +static int calc_checksum(struct pkt *p) +{ + int i, sum; + + i = 0; + sum = 0; + + for (i=0; i < p->len; i++) + sum += p->data[i]; + + sum += p->seq_num; + sum += p->len; + + return sum; +} + +static void *read_thread(void *threadid) +{ + char *rx_data; + int cnt, prev_seq_num, pkt_count, seq_num_failure; + struct pkt *p; + unsigned long bytes_transfered, elapsed_seconds; + struct timeval start_time, finish_time; + + printf("Greetings from the reading thread!\n"); + + bytes_transfered = 0; + gettimeofday(&start_time, NULL); + + // IMPORTANT: must assume max length packet from fpga + rx_data = malloc(2048); + p = (struct pkt *) ((void *)rx_data); + + prev_seq_num = 0; + pkt_count = 0; + seq_num_failure = 0; + + while (1) { + + cnt = read(fp, rx_data, 2048); + if (cnt < 0) + printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); + +// printf("p->seq_num = %d\n", p->seq_num); + + + pkt_count++; + + if (p->seq_num != prev_seq_num + 1) { + printf("Sequence number fail, current = %d, previous = %d, pkt_count = %d\n", + p->seq_num, prev_seq_num, pkt_count); + + seq_num_failure ++; + if (seq_num_failure > 2) + error = 1; + } + + prev_seq_num = p->seq_num; + + if (calc_checksum(p) != p->checksum) { + printf("Checksum fail packet = %X, expected = %X, pkt_count = %d\n", + calc_checksum(p), p->checksum, pkt_count); + error = 1; + } + + bytes_transfered += cnt; + + if (bytes_transfered > (100 * 1000000)) { + gettimeofday(&finish_time, NULL); + elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; + + printf("RX data transfer rate = %f K Samples/second\n", + (float) bytes_transfered / (float) elapsed_seconds / 4000); + + + start_time = finish_time; + bytes_transfered = 0; + } + + +// printf("."); +// fflush(stdout); +// printf("\n"); + } + +} + +static void *write_thread(void *threadid) +{ + int seq_number, i, cnt; + void *tx_data; + struct pkt *p; + + printf("Greetings from the write thread!\n"); + + tx_data = malloc(2048); + p = (struct pkt *) ((void *)tx_data); + + for (i=0; i < packet_data_length; i++) +// p->data[i] = random() >> 16; + p->data[i] = i; + + seq_number = 1; + + while (1) { + p->seq_num = seq_number++; + + if (packet_data_length > 0) + p->len = packet_data_length; + else + p->len = (random() & 0x1ff) + (1004 - 512); + + p->checksum = calc_checksum(p); + + cnt = write(fp, tx_data, p->len * 2 + 12); + if (cnt < 0) + printf("Error returned from write: %d\n", cnt); +// sleep(1); + } +} + + +int main(int argc, char *argv[]) +{ + pthread_t tx, rx; + long int t; + struct sched_param s = { + .sched_priority = 1 + }; + void *rb; + struct usrp_transfer_frame *tx_rb, *rx_rb; + + if (argc < 2) { + printf("%s data_size\n", argv[0]); + return -1; + } + + packet_data_length = atoi(argv[1]); + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + rb = mmap(0, 202 * 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); + if (!rb) { + printf("mmap failed\n"); + exit; + } + + + sched_setscheduler(0, SCHED_RR, &s); + error = 0; + +#if 1 + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { + printf("Failed to create rx thread\n"); + exit(-1); + } + + sleep(1); +#endif + + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { + printf("Failed to create tx thread\n"); + exit(-1); + } + +// while (!error) + sleep(1000000000); + + printf("Done sleeping\n"); +} -- cgit v1.2.3 From ee44eecc3e2047b1514794add99203c4d2d3c7cc Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sat, 28 Aug 2010 19:54:03 -0400 Subject: Test if usrp_e kernel module is loaded before trying to load the FPGA. Do not load the the fpga if the kernel module is loaded. --- host/utils/fpga-downloader.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'host') diff --git a/host/utils/fpga-downloader.cpp b/host/utils/fpga-downloader.cpp index fb96b64a3..80ee71600 100644 --- a/host/utils/fpga-downloader.cpp +++ b/host/utils/fpga-downloader.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -240,6 +241,21 @@ int main(int argc, char *argv[]) if (argc == 2) bit_file = argv[1]; + bool module_found(false); + std::ifstream mod_file("/proc/modules"); + while (!mod_file.eof()) { + std::string line; + getline(mod_file, line); + if (line.find("usrp_e") != std::string::npos) + module_found = true; + } + mod_file.close(); + + if (module_found) { + std::cout << "USRP Embedded kernel module loaded, not loading FPGA." << std::endl; + return -1; + } + std::cout << "FPGA config file: " << bit_file << std::endl; prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); -- cgit v1.2.3 From cd84e9dbfcc12584eba890a6618d38832e5d8dba Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sun, 29 Aug 2010 08:16:00 -0400 Subject: Add usrp-e-debug-pins to utils. This is the wrong place for the regs header file. --- host/utils/CMakeLists.txt | 4 + host/utils/usrp-e-debug-pins.c | 77 ++++++++++++++++ host/utils/usrp_e_regs.hpp | 196 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 277 insertions(+) create mode 100644 host/utils/usrp-e-debug-pins.c create mode 100644 host/utils/usrp_e_regs.hpp (limited to 'host') diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index 0e3f81d0a..6515048eb 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -30,11 +30,15 @@ TARGET_LINK_LIBRARIES(fpga-downloader) ADD_EXECUTABLE(usrp-e-loopback usrp-e-loopback.c) TARGET_LINK_LIBRARIES(usrp-e-loopback pthread) +ADD_EXECUTABLE(usrp-e-debug-pins usrp-e-debug-pins.c) +TARGET_LINK_LIBRARIES(usrp-e-debug-pins) + INSTALL(TARGETS uhd_find_devices uhd_usrp_probe fpga-downloader usrp-e-loopback + usrp-e-debug-pins RUNTIME DESTINATION ${RUNTIME_DIR} ) diff --git a/host/utils/usrp-e-debug-pins.c b/host/utils/usrp-e-debug-pins.c new file mode 100644 index 000000000..1ed2c8983 --- /dev/null +++ b/host/utils/usrp-e-debug-pins.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include "usrp_e_regs.hpp" + +// Usage: usrp_e_gpio + +static int fp; + +static int read_reg(__u16 reg) +{ + int ret; + struct usrp_e_ctl16 d; + + d.offset = reg; + d.count = 1; + ret = ioctl(fp, USRP_E_READ_CTL16, &d); + return d.buf[0]; +} + +static void write_reg(__u16 reg, __u16 val) +{ + int ret; + struct usrp_e_ctl16 d; + + d.offset = reg; + d.count = 1; + d.buf[0] = val; + ret = ioctl(fp, USRP_E_WRITE_CTL16, &d); +} + +int main(int argc, char *argv[]) +{ + int test; + + test = 0; + if (argc < 2) { + printf("%s 0|1|off\n", argv[0]); + } + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + if (fp < 0) { + perror("Open failed"); + return -1; + } + + if (strcmp(argv[1], "0") == 0) { + printf("Selected 0 based on %s\n", argv[1]); + write_reg(UE_REG_GPIO_TX_DDR, 0xFFFF); + write_reg(UE_REG_GPIO_RX_DDR, 0xFFFF); + write_reg(UE_REG_GPIO_TX_SEL, 0x0); + write_reg(UE_REG_GPIO_RX_SEL, 0x0); + write_reg(UE_REG_GPIO_TX_DBG, 0xFFFF); + write_reg(UE_REG_GPIO_RX_DBG, 0xFFFF); + } else if (strcmp(argv[1], "1") == 0) { + printf("Selected 1 based on %s\n", argv[1]); + write_reg(UE_REG_GPIO_TX_DDR, 0xFFFF); + write_reg(UE_REG_GPIO_RX_DDR, 0xFFFF); + write_reg(UE_REG_GPIO_TX_SEL, 0xFFFF); + write_reg(UE_REG_GPIO_RX_SEL, 0xFFFF); + write_reg(UE_REG_GPIO_TX_DBG, 0xFFFF); + write_reg(UE_REG_GPIO_RX_DBG, 0xFFFF); + } else { + printf("Selected off based on %s\n", argv[1]); + write_reg(UE_REG_GPIO_TX_DDR, 0x0); + write_reg(UE_REG_GPIO_RX_DDR, 0x0); + } + + return 0; +} diff --git a/host/utils/usrp_e_regs.hpp b/host/utils/usrp_e_regs.hpp new file mode 100644 index 000000000..a4f42093e --- /dev/null +++ b/host/utils/usrp_e_regs.hpp @@ -0,0 +1,196 @@ + + +//////////////////////////////////////////////////////////////// +// +// Memory map for embedded wishbone bus +// +//////////////////////////////////////////////////////////////// + +// All addresses are byte addresses. All accesses are word (16-bit) accesses. +// This means that address bit 0 is usually 0. +// There are 11 bits of address for the control. + +#ifndef __USRP_E_REGS_H +#define __USRP_E_REGS_H + +///////////////////////////////////////////////////// +// Slave pointers + +#define UE_REG_SLAVE(n) ((n)<<7) +#define UE_REG_SR_ADDR(n) ((UE_REG_SLAVE(5)) + (4*(n))) + +///////////////////////////////////////////////////// +// Slave 0 -- Misc Regs + +#define UE_REG_MISC_BASE UE_REG_SLAVE(0) + +#define UE_REG_MISC_LED UE_REG_MISC_BASE + 0 +#define UE_REG_MISC_SW UE_REG_MISC_BASE + 2 +#define UE_REG_MISC_CGEN_CTRL UE_REG_MISC_BASE + 4 +#define UE_REG_MISC_CGEN_ST UE_REG_MISC_BASE + 6 +#define UE_REG_MISC_TEST UE_REG_MISC_BASE + 8 +#define UE_REG_MISC_RX_LEN UE_REG_MISC_BASE + 10 +#define UE_REG_MISC_TX_LEN UE_REG_MISC_BASE + 12 + +///////////////////////////////////////////////////// +// Slave 1 -- UART +// CLKDIV is 16 bits, others are only 8 + +#define UE_REG_UART_BASE UE_REG_SLAVE(1) + +#define UE_REG_UART_CLKDIV UE_REG_UART_BASE + 0 +#define UE_REG_UART_TXLEVEL UE_REG_UART_BASE + 2 +#define UE_REG_UART_RXLEVEL UE_REG_UART_BASE + 4 +#define UE_REG_UART_TXCHAR UE_REG_UART_BASE + 6 +#define UE_REG_UART_RXCHAR UE_REG_UART_BASE + 8 + +///////////////////////////////////////////////////// +// Slave 2 -- SPI Core +// This should be accessed through the IOCTL +// Users should not touch directly + +#define UE_REG_SPI_BASE UE_REG_SLAVE(2) + +//spi slave constants +#define UE_SPI_SS_AD9522 (1 << 3) +#define UE_SPI_SS_AD9862 (1 << 2) +#define UE_SPI_SS_TX_DB (1 << 1) +#define UE_SPI_SS_RX_DB (1 << 0) + +//////////////////////////////////////////////// +// Slave 3 -- I2C Core +// This should be accessed through the IOCTL +// Users should not touch directly + +#define UE_REG_I2C_BASE UE_REG_SLAVE(3) + + +//////////////////////////////////////////////// +// Slave 4 -- GPIO + +#define UE_REG_GPIO_BASE UE_REG_SLAVE(4) + +#define UE_REG_GPIO_RX_IO UE_REG_GPIO_BASE + 0 +#define UE_REG_GPIO_TX_IO UE_REG_GPIO_BASE + 2 +#define UE_REG_GPIO_RX_DDR UE_REG_GPIO_BASE + 4 +#define UE_REG_GPIO_TX_DDR UE_REG_GPIO_BASE + 6 +#define UE_REG_GPIO_RX_SEL UE_REG_GPIO_BASE + 8 +#define UE_REG_GPIO_TX_SEL UE_REG_GPIO_BASE + 10 +#define UE_REG_GPIO_RX_DBG UE_REG_GPIO_BASE + 12 +#define UE_REG_GPIO_TX_DBG UE_REG_GPIO_BASE + 14 + +//possible bit values for sel when dbg is 0: +#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg +#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic + +//possible bit values for sel when dbg is 1: +#define GPIO_SEL_DEBUG_0 0 // if pin is an output, debug lines from FPGA fabric +#define GPIO_SEL_DEBUG_1 1 // if pin is an output, debug lines from FPGA fabric + + +//////////////////////////////////////////////////// +// Slave 5 -- Settings Bus +// +// Output-only, no readback, 32 registers total +// Each register must be written 32 bits at a time +// First the address xxx_xx00 and then xxx_xx10 + +#define UE_REG_SETTINGS_BASE UE_REG_SLAVE(5) + +/////////////////////////////////////////////////// +// Slave 6 -- ATR Controller +// 16 regs + +#define UE_REG_ATR_BASE UE_REG_SLAVE(6) + +#define UE_REG_ATR_IDLE_RXSIDE UE_REG_ATR_BASE + 0 +#define UE_REG_ATR_IDLE_TXSIDE UE_REG_ATR_BASE + 2 +#define UE_REG_ATR_INTX_RXSIDE UE_REG_ATR_BASE + 4 +#define UE_REG_ATR_INTX_TXSIDE UE_REG_ATR_BASE + 6 +#define UE_REG_ATR_INRX_RXSIDE UE_REG_ATR_BASE + 8 +#define UE_REG_ATR_INRX_TXSIDE UE_REG_ATR_BASE + 10 +#define UE_REG_ATR_FULL_RXSIDE UE_REG_ATR_BASE + 12 +#define UE_REG_ATR_FULL_TXSIDE UE_REG_ATR_BASE + 14 + +///////////////////////////////////////////////// +// DSP RX Regs +//////////////////////////////////////////////// +#define UE_REG_DSP_RX_FREQ UE_REG_SR_ADDR(0) +#define UE_REG_DSP_RX_SCALE_IQ UE_REG_SR_ADDR(1) // {scale_i,scale_q} +#define UE_REG_DSP_RX_DECIM_RATE UE_REG_SR_ADDR(2) // hb and decim rate +#define UE_REG_DSP_RX_DCOFFSET_I UE_REG_SR_ADDR(3) // Bit 31 high sets fixed offset mode, using lower 14 bits, // otherwise it is automatic +#define UE_REG_DSP_RX_DCOFFSET_Q UE_REG_SR_ADDR(4) // Bit 31 high sets fixed offset mode, using lower 14 bits +#define UE_REG_DSP_RX_MUX UE_REG_SR_ADDR(5) + +/////////////////////////////////////////////////// +// VITA RX CTRL regs +/////////////////////////////////////////////////// +// The following 3 are logically a single command register. +// They are clocked into the underlying fifo when time_ticks is written. +#define UE_REG_CTRL_RX_STREAM_CMD UE_REG_SR_ADDR(8) // {now, chain, num_samples(30) +#define UE_REG_CTRL_RX_TIME_SECS UE_REG_SR_ADDR(9) +#define UE_REG_CTRL_RX_TIME_TICKS UE_REG_SR_ADDR(10) +#define UE_REG_CTRL_RX_CLEAR_OVERRUN UE_REG_SR_ADDR(11) // write anything to clear overrun +#define UE_REG_CTRL_RX_VRT_HEADER UE_REG_SR_ADDR(12) // word 0 of packet. FPGA fills in packet counter +#define UE_REG_CTRL_RX_VRT_STREAM_ID UE_REG_SR_ADDR(13) // word 1 of packet. +#define UE_REG_CTRL_RX_VRT_TRAILER UE_REG_SR_ADDR(14) +#define UE_REG_CTRL_RX_NSAMPS_PER_PKT UE_REG_SR_ADDR(15) +#define UE_REG_CTRL_RX_NCHANNELS UE_REG_SR_ADDR(16) // 1 in basic case, up to 4 for vector sources + +///////////////////////////////////////////////// +// DSP TX Regs +//////////////////////////////////////////////// +#define UE_REG_DSP_TX_FREQ UE_REG_SR_ADDR(17) +#define UE_REG_DSP_TX_SCALE_IQ UE_REG_SR_ADDR(18) // {scale_i,scale_q} +#define UE_REG_DSP_TX_INTERP_RATE UE_REG_SR_ADDR(19) +#define UE_REG_DSP_TX_UNUSED UE_REG_SR_ADDR(20) +#define UE_REG_DSP_TX_MUX UE_REG_SR_ADDR(21) + +///////////////////////////////////////////////// +// VITA TX CTRL regs +//////////////////////////////////////////////// +#define UE_REG_CTRL_TX_NCHANNELS UE_REG_SR_ADDR(24) +#define UE_REG_CTRL_TX_CLEAR_UNDERRUN UE_REG_SR_ADDR(25) +#define UE_REG_CTRL_TX_REPORT_SID UE_REG_SR_ADDR(26) +#define UE_REG_CTRL_TX_POLICY UE_REG_SR_ADDR(27) + +#define UE_FLAG_CTRL_TX_POLICY_WAIT (0x1 << 0) +#define UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET (0x1 << 1) +#define UE_FLAG_CTRL_TX_POLICY_NEXT_BURST (0x1 << 2) + +///////////////////////////////////////////////// +// VITA49 64 bit time (write only) +//////////////////////////////////////////////// + /*! + * \brief Time 64 flags + * + *
+   *
+   *    3                   2                   1
+   *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   * +-----------------------------------------------------------+-+-+
+   * |                                                           |S|P|
+   * +-----------------------------------------------------------+-+-+
+   *
+   * P - PPS edge selection (0=negedge, 1=posedge, default=0)
+   * S - Source (0=sma, 1=mimo, 0=default)
+   *
+   * 
+ */ +#define UE_REG_TIME64_SECS UE_REG_SR_ADDR(28) // value to set absolute secs to on next PPS +#define UE_REG_TIME64_TICKS UE_REG_SR_ADDR(29) // value to set absolute ticks to on next PPS +#define UE_REG_TIME64_FLAGS UE_REG_SR_ADDR(30) // flags - see chart above +#define UE_REG_TIME64_IMM UE_REG_SR_ADDR(31) // set immediate (0=latch on next pps, 1=latch immediate, default=0) +#define UE_REG_TIME64_TPS UE_REG_SR_ADDR(31) // clock ticks per second (counter rollover) + +//pps flags (see above) +#define UE_FLAG_TIME64_PPS_NEGEDGE (0 << 0) +#define UE_FLAG_TIME64_PPS_POSEDGE (1 << 0) +#define UE_FLAG_TIME64_PPS_SMA (0 << 1) +#define UE_FLAG_TIME64_PPS_MIMO (1 << 1) + +#define UE_FLAG_TIME64_LATCH_NOW 1 +#define UE_FLAG_TIME64_LATCH_NEXT_PPS 0 + +#endif + -- cgit v1.2.3 From d2d5be27b09faee1481a763ce25e7b95460a46c9 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 9 Sep 2010 10:02:10 -0400 Subject: Add clkgen-config, usrp-e-i2c and usrp-e-spi to the installed utils. --- host/utils/CMakeLists.txt | 12 ++ host/utils/clkgen-config.cpp | 296 +++++++++++++++++++++++++++++++++++++++++++ host/utils/usrp-e-i2c.c | 87 +++++++++++++ host/utils/usrp-e-spi.c | 54 ++++++++ 4 files changed, 449 insertions(+) create mode 100644 host/utils/clkgen-config.cpp create mode 100644 host/utils/usrp-e-i2c.c create mode 100644 host/utils/usrp-e-spi.c (limited to 'host') diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index 6515048eb..ff0ca895a 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -27,18 +27,30 @@ TARGET_LINK_LIBRARIES(uhd_usrp_probe uhd) ADD_EXECUTABLE(fpga-downloader fpga-downloader.cpp) TARGET_LINK_LIBRARIES(fpga-downloader) +ADD_EXECUTABLE(clkgen-config clkgen-config.cpp) +TARGET_LINK_LIBRARIES(clkgen-config) + ADD_EXECUTABLE(usrp-e-loopback usrp-e-loopback.c) TARGET_LINK_LIBRARIES(usrp-e-loopback pthread) ADD_EXECUTABLE(usrp-e-debug-pins usrp-e-debug-pins.c) TARGET_LINK_LIBRARIES(usrp-e-debug-pins) +ADD_EXECUTABLE(usrp-e-i2c usrp-e-i2c.c) +TARGET_LINK_LIBRARIES(usrp-e-i2c) + +ADD_EXECUTABLE(usrp-e-spi usrp-e-spi.c) +TARGET_LINK_LIBRARIES(usrp-e-spi) + INSTALL(TARGETS uhd_find_devices uhd_usrp_probe fpga-downloader usrp-e-loopback usrp-e-debug-pins + usrp-e-spi + usrp-e-i2c + clkgen-config RUNTIME DESTINATION ${RUNTIME_DIR} ) diff --git a/host/utils/clkgen-config.cpp b/host/utils/clkgen-config.cpp new file mode 100644 index 000000000..e8279b4ae --- /dev/null +++ b/host/utils/clkgen-config.cpp @@ -0,0 +1,296 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003,2004,2008,2009 Free Software Foundation, Inc. + * + * This file is part of UHD + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + + +// 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, + 0x019333, + 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) +{ + 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 = 12000000; + 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); + + }; +} + +int main(int argc, char *argv[]) +{ + + gpio clkgen_select(CLKGEN_SELECT, OUT, true); + + send_config_to_clkgen(clkgen_select, config_data, sizeof(config_data)/sizeof(unsigned int)); +} + diff --git a/host/utils/usrp-e-i2c.c b/host/utils/usrp-e-i2c.c new file mode 100644 index 000000000..c6fd4c632 --- /dev/null +++ b/host/utils/usrp-e-i2c.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +// Usage: usrp_e_i2c w address data0 data1 data 2 .... +// Usage: usrp_e_i2c r address count + +int main(int argc, char *argv[]) +{ + int fp, ret, i, tmp; + struct usrp_e_i2c *i2c_msg; + int direction, address, count; + + if (argc < 3) { + printf("Usage: usrp-e-i2c w address data0 data1 data2 ...\n"); + printf("Usage: usrp-e-i2c r address count\n"); + printf("All addresses and data in hex.\n"); + exit(-1); + } + + if (strcmp(argv[1], "r") == 0) { + direction = 0; + } else if (strcmp(argv[1], "w") == 0) { + direction = 1; + } else { + return -1; + } + + sscanf(argv[2], "%X", &address); + printf("Address = %X\n", address); + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + if (fp < 0) { + perror("Open failed"); + return -1; + } + +// sleep(1); + + if (direction) { + count = argc - 3; + } else { + sscanf(argv[3], "%X", &count); + } + printf("Count = %X\n", count); + + i2c_msg = malloc(sizeof(i2c_msg) + count * sizeof(char)); + + i2c_msg->addr = address; + i2c_msg->len = count; + + for (i = 0; i < count; i++) { + i2c_msg->data[i] = i; + } + + if (direction) { + // Write + + for (i=0; idata[i] = tmp; + } + + ret = ioctl(fp, USRP_E_I2C_WRITE, i2c_msg); + printf("Return value from i2c_write ioctl: %d\n", ret); + } else { + // Read + + ret = ioctl(fp, USRP_E_I2C_READ, i2c_msg); + printf("Return value from i2c_read ioctl: %d\n", ret); + + printf("Ioctl: %d Data read :", ret); + for (i=0; idata[i]); + } + printf("\n"); + + } + return 0; +} diff --git a/host/utils/usrp-e-spi.c b/host/utils/usrp-e-spi.c new file mode 100644 index 000000000..5203f56a8 --- /dev/null +++ b/host/utils/usrp-e-spi.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include + +#include + +// Usage: usrp_e_spi w|rb slave data + +int main(int argc, char *argv[]) +{ + int fp, slave, length, ret; + unsigned int data; + struct usrp_e_spi spi_dat; + + if (argc < 5) { + printf("Usage: usrp_e_spi w|rb slave transfer_length data\n"); + exit(-1); + } + + slave = atoi(argv[2]); + length = atoi(argv[3]); + data = atoll(argv[4]); + + printf("Data = %X\n", data); + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + if (fp < 0) { + perror("Open failed"); + return -1; + } + +// sleep(1); + + + spi_dat.slave = slave; + spi_dat.data = data; + spi_dat.length = length; + spi_dat.flags = UE_SPI_PUSH_FALL | UE_SPI_LATCH_RISE; + + if (*argv[1] == 'r') { + spi_dat.readback = 1; + ret = ioctl(fp, USRP_E_SPI, &spi_dat); + printf("Ioctl returns: %d, Data returned = %d\n", ret, spi_dat.data); + } else { + spi_dat.readback = 0; + ioctl(fp, USRP_E_SPI, &spi_dat); + } + + return 0; +} -- cgit v1.2.3 From 4a757e64cbb513e6461e547f4d095b0539ae0b09 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 9 Sep 2010 15:55:35 -0400 Subject: Convert fc32_to_item32_nswap to use ARM NEON if available. --- host/lib/transport/CMakeLists.txt | 6 ++++++ host/lib/transport/convert_types_impl.hpp | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) (limited to 'host') diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt index 753fd5e85..43449d732 100644 --- a/host/lib/transport/CMakeLists.txt +++ b/host/lib/transport/CMakeLists.txt @@ -45,6 +45,12 @@ IF(HAVE_EMMINTRIN_H) ADD_DEFINITIONS(-DHAVE_EMMINTRIN_H) ENDIF(HAVE_EMMINTRIN_H) +INCLUDE(CheckIncludeFileCXX) +CHECK_INCLUDE_FILE_CXX(arm_neon.h HAVE_ARM_NEON_H) + +IF(HAVE_ARM_NEON_H) + ADD_DEFINITIONS(-DHAVE_ARM_NEON_H) +ENDIF(HAVE_ARM_NEON_H) ######################################################################## # Setup defines for interface address discovery ######################################################################## diff --git a/host/lib/transport/convert_types_impl.hpp b/host/lib/transport/convert_types_impl.hpp index 90618dec6..6cfc8fed6 100644 --- a/host/lib/transport/convert_types_impl.hpp +++ b/host/lib/transport/convert_types_impl.hpp @@ -32,6 +32,14 @@ #include #endif +#ifdef HAVE_ARM_NEON_H + #define USE_ARM_NEON_H +#endif + +#if defined(USE_ARM_NEON_H) + #include +#endif + /*********************************************************************** * Typedefs **********************************************************************/ @@ -135,6 +143,22 @@ static UHD_INLINE void fc32_to_item32_nswap( } } +#elif defined(USE_ARM_NEON_H) +static UHD_INLINE void fc32_to_item32_nswap( + const fc32_t *input, item32_t *output, size_t nsamps) +{ + size_t i; + + float32x4_t Q0 = vdupq_n_f32(shorts_per_float); + for (i=0; i < (nsamps & ~0x03); i+=4) { + float32x4_t Q1 = vld1q_f32(reinterpret_cast(&input[i])); + float32x4_t Q2 = vmulq_f32(Q1, Q0); + int32x4_t Q3 = vcvtq_s32_f32(Q2); + int16x4_t D8 = vmovn_s32(Q3); + vst1_s16((reinterpret_cast(&output[i])), D8); + } +} + #else static UHD_INLINE void fc32_to_item32_nswap( const fc32_t *input, item32_t *output, size_t nsamps -- cgit v1.2.3 From f0db419b8c6366503542c3e97f8556bbb6ca94cd Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 9 Sep 2010 16:27:53 -0700 Subject: usrp-e: typo fix for ad9522 regs size --- host/lib/ic_reg_maps/gen_ad9522_regs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/lib/ic_reg_maps/gen_ad9522_regs.py b/host/lib/ic_reg_maps/gen_ad9522_regs.py index ed6b5f48d..a5debe568 100755 --- a/host/lib/ic_reg_maps/gen_ad9522_regs.py +++ b/host/lib/ic_reg_maps/gen_ad9522_regs.py @@ -134,8 +134,8 @@ reg2eeprom 0xB03[0] 0 # Template for methods in the body of the struct ######################################################################## BODY_TMPL="""\ -boost::uint8_t get_reg(boost::uint16_t addr){ - boost::uint8_t reg = 0; +boost::uint32_t get_reg(boost::uint16_t addr){ + boost::uint32_t reg = 0; switch(addr){ #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) case $addr: @@ -154,7 +154,7 @@ boost::uint8_t get_reg(boost::uint16_t addr){ return reg; } -void set_reg(boost::uint8_t addr, boost::uint32_t reg){ +void set_reg(boost::uint16_t addr, boost::uint32_t reg){ switch(addr){ #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) case $addr: -- cgit v1.2.3 From bc824badaa981c1785d8c76d7cf56274d7c582b8 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 9 Sep 2010 16:28:37 -0700 Subject: usrp-e: configure flag option for usrp-e support --- host/lib/usrp/usrp_e/CMakeLists.txt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/CMakeLists.txt b/host/lib/usrp/usrp_e/CMakeLists.txt index f0c125f26..da759d931 100644 --- a/host/lib/usrp/usrp_e/CMakeLists.txt +++ b/host/lib/usrp/usrp_e/CMakeLists.txt @@ -25,7 +25,18 @@ MESSAGE(STATUS "Configuring usrp-e support...") INCLUDE(CheckIncludeFileCXX) CHECK_INCLUDE_FILE_CXX(linux/usrp_e.h HAVE_LINUX_USRP_E_H) -IF(HAVE_LINUX_USRP_E_H) +IF(DEFINED ENABLE_USRP_E) + IF(ENABLE_USRP_E) + MESSAGE(STATUS "USRP-E support enabled by configure flag") + ELSE(ENABLE_USRP_E) + MESSAGE(STATUS "USRP-E support disabled by configure flag") + ENDIF(ENABLE_USRP_E) +ELSE(DEFINED ENABLE_USRP_E) #not defined: automatic enabling of component + SET(ENABLE_USRP_E ${HAVE_LINUX_USRP_E_H}) +ENDIF(DEFINED ENABLE_USRP_E) +SET(ENABLE_USRP_E ${ENABLE_USRP_E} CACHE BOOL "enable USRP-E support") + +IF(ENABLE_USRP_E) MESSAGE(STATUS " Building usrp-e support.") LIBUHD_APPEND_SOURCES( ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/clock_ctrl.cpp @@ -45,6 +56,6 @@ IF(HAVE_LINUX_USRP_E_H) ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_iface.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_regs.hpp ) -ELSE(HAVE_LINUX_USRP_E_H) +ELSE(ENABLE_USRP_E) MESSAGE(STATUS " Skipping usrp-e support.") -ENDIF(HAVE_LINUX_USRP_E_H) +ENDIF(ENABLE_USRP_E) -- cgit v1.2.3 From d1a327862292d52d659b117aef28e37d9f60fb4b Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 9 Sep 2010 19:30:02 -0400 Subject: Restore tx and rx timed smaple programs to the versions in master. They use floating point. --- host/examples/rx_timed_samples.cpp | 6 +++--- host/examples/tx_timed_samples.cpp | 9 +++------ 2 files changed, 6 insertions(+), 9 deletions(-) (limited to 'host') diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 5fbf8b6c5..4856f6779 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -85,12 +85,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //loop until total number of samples reached size_t num_acc_samps = 0; //number of accumulated samples - uhd::rx_metadata_t md; - std::vector > buff(dev->get_max_recv_samps_per_packet()); while(num_acc_samps < total_num_samps){ + uhd::rx_metadata_t md; + std::vector > buff(dev->get_max_recv_samps_per_packet()); size_t num_rx_samps = dev->recv( &buff.front(), buff.size(), md, - uhd::io_type_t::COMPLEX_INT16, + uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::RECV_MODE_ONE_PACKET ); diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index f7d7ea2ca..5b72bd72f 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -35,7 +35,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ size_t samps_per_packet; double tx_rate, freq; float ampl; - float tx_gain; //setup the program options po::options_description desc("Allowed options"); @@ -48,7 +47,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("txrate", po::value(&tx_rate)->default_value(100e6/16), "rate of outgoing samples") ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") ("ampl", po::value(&l)->default_value(float(0.3)), "amplitude of each sample") - ("gain", po::value(&tx_gain)->default_value(float(0)), "TX Gain setting") ("dilv", "specify to disable inner-loop verbose") ; po::variables_map vm; @@ -77,16 +75,15 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << boost::format("Setting device timestamp to 0...") << std::endl; sdev->set_tx_freq(freq); sdev->set_time_now(uhd::time_spec_t(0.0)); - sdev->set_tx_gain(tx_gain); //allocate data to send - std::vector > buff(samps_per_packet, std::complex(ampl, ampl)); - uhd::tx_metadata_t md; + std::vector > buff(samps_per_packet, std::complex(ampl, ampl)); //send the data in multiple packets size_t num_packets = (total_num_samps+samps_per_packet-1)/samps_per_packet; for (size_t i = 0; i < num_packets; i++){ //setup the metadata flags and time spec + uhd::tx_metadata_t md; md.start_of_burst = true; //always SOB (good for continuous streaming) md.end_of_burst = (i == num_packets-1); //only last packet has EOB md.has_time_spec = (i == 0); //only first packet has time @@ -97,7 +94,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //send the entire packet (driver fragments internally) size_t num_tx_samps = dev->send( &buff.front(), samps_to_send, md, - uhd::io_type_t::COMPLEX_INT16, + uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::SEND_MODE_FULL_BUFF ); if(verbose) std::cout << std::endl << boost::format("Sent %d samples") % num_tx_samps << std::endl; -- cgit v1.2.3 From 93b77c39985f63dffcca3ef569aee8ee45708a1f Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 9 Sep 2010 19:30:50 -0400 Subject: Allow programs to find usrp_e.h header, even if it is not installed in /usr/include/linux. --- host/include/linux/usrp_e.h | 88 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 host/include/linux/usrp_e.h (limited to 'host') diff --git a/host/include/linux/usrp_e.h b/host/include/linux/usrp_e.h new file mode 100644 index 000000000..b098ad114 --- /dev/null +++ b/host/include/linux/usrp_e.h @@ -0,0 +1,88 @@ + +/* + * Copyright (C) 2010 Ettus Research, LLC + * + * Written by Philip Balister + * + * 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 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __USRP_E_H +#define __USRP_E_H + +#include +#include + +struct usrp_e_ctl16 { + __u32 offset; + __u32 count; + __u16 buf[20]; +}; + +struct usrp_e_ctl32 { + __u32 offset; + __u32 count; + __u32 buf[10]; +}; + +/* SPI interface */ + +#define UE_SPI_TXONLY 0 +#define UE_SPI_TXRX 1 + +/* Defines for spi ctrl register */ +#define UE_SPI_CTRL_TXNEG (1 << 10) +#define UE_SPI_CTRL_RXNEG (1 << 9) + +#define UE_SPI_PUSH_RISE 0 +#define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG +#define UE_SPI_LATCH_RISE 0 +#define UE_SPI_LATCH_FALL UE_SPI_CTRL_RXNEG + +struct usrp_e_spi { + __u8 readback; + __u32 slave; + __u32 data; + __u32 length; + __u32 flags; +}; + +struct usrp_e_i2c { + __u8 addr; + __u32 len; + __u8 data[]; +}; + +#define USRP_E_IOC_MAGIC 'u' +#define USRP_E_WRITE_CTL16 _IOW(USRP_E_IOC_MAGIC, 0x20, struct usrp_e_ctl16) +#define USRP_E_READ_CTL16 _IOWR(USRP_E_IOC_MAGIC, 0x21, struct usrp_e_ctl16) +#define USRP_E_WRITE_CTL32 _IOW(USRP_E_IOC_MAGIC, 0x22, struct usrp_e_ctl32) +#define USRP_E_READ_CTL32 _IOWR(USRP_E_IOC_MAGIC, 0x23, struct usrp_e_ctl32) +#define USRP_E_SPI _IOWR(USRP_E_IOC_MAGIC, 0x24, struct usrp_e_spi) +#define USRP_E_I2C_READ _IOWR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) +#define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) + +/* Data transfer frame definition */ + +struct usrp_transfer_frame { + __u32 status; + __u32 len; + __u8 buf[]; +}; + +/* Flag defines */ +#define RB_USER (1 << 0) +#define RB_KERNEL (1 << 1) +#define RB_OVERRUN (1 << 2) +#define RB_DMA_ACTIVE (1 << 3) + +struct ring_buffer_entry { + unsigned int flags; + unsigned long dma_addr; + struct usrp_transfer_frame *frame_addr; +}; + +#endif -- cgit v1.2.3 From 09a1b77a65202e6c569be7e1b31d9d453ef388a2 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 9 Sep 2010 20:40:55 -0400 Subject: Fix errors. --- host/lib/transport/convert_types_impl.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'host') diff --git a/host/lib/transport/convert_types_impl.hpp b/host/lib/transport/convert_types_impl.hpp index 6cfc8fed6..04e6fc81a 100644 --- a/host/lib/transport/convert_types_impl.hpp +++ b/host/lib/transport/convert_types_impl.hpp @@ -150,13 +150,16 @@ static UHD_INLINE void fc32_to_item32_nswap( size_t i; float32x4_t Q0 = vdupq_n_f32(shorts_per_float); - for (i=0; i < (nsamps & ~0x03); i+=4) { + for (i=0; i < (nsamps & ~0x03); i+=2) { float32x4_t Q1 = vld1q_f32(reinterpret_cast(&input[i])); float32x4_t Q2 = vmulq_f32(Q1, Q0); int32x4_t Q3 = vcvtq_s32_f32(Q2); int16x4_t D8 = vmovn_s32(Q3); vst1_s16((reinterpret_cast(&output[i])), D8); } + + for (; i < nsamps; i++) + output[i] = fc32_to_item32(input[i]); } #else -- cgit v1.2.3 From 136e507182085fc5e666c08a0099103caba19c24 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 10 Sep 2010 10:07:37 -0400 Subject: Install main_test so we can test cross compiled uhd. --- host/test/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'host') diff --git a/host/test/CMakeLists.txt b/host/test/CMakeLists.txt index c620fd641..0d4607f68 100644 --- a/host/test/CMakeLists.txt +++ b/host/test/CMakeLists.txt @@ -40,3 +40,8 @@ ADD_TEST(test main_test) # demo of a loadable module ######################################################################## ADD_LIBRARY(module_test MODULE module_test.cpp) + +INSTALL(TARGETS + main_test + RUNTIME DESTINATION ${PKG_DATA_DIR}/tests +) -- cgit v1.2.3 From a845814e3e648e5625649c2f34f462bc29641fa7 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 10 Sep 2010 15:47:20 -0400 Subject: Reverse I and Q on the wire. --- host/lib/transport/convert_types_impl.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'host') diff --git a/host/lib/transport/convert_types_impl.hpp b/host/lib/transport/convert_types_impl.hpp index 04e6fc81a..b9a47eb0e 100644 --- a/host/lib/transport/convert_types_impl.hpp +++ b/host/lib/transport/convert_types_impl.hpp @@ -155,7 +155,8 @@ static UHD_INLINE void fc32_to_item32_nswap( float32x4_t Q2 = vmulq_f32(Q1, Q0); int32x4_t Q3 = vcvtq_s32_f32(Q2); int16x4_t D8 = vmovn_s32(Q3); - vst1_s16((reinterpret_cast(&output[i])), D8); + int16x4_t D9 = vrev32_s16(D8); + vst1_s16((reinterpret_cast(&output[i])), D9); } for (; i < nsamps; i++) -- cgit v1.2.3 From 7888b861d51fc612abe4c28a2f05c83df7ec1cb1 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 20 Sep 2010 20:31:52 +0000 Subject: Fix really dumb mistake in rad ring buffer code. Add/comment debug lines. --- host/apps/omap_debug/usrp-e-mm-loopback.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-mm-loopback.c b/host/apps/omap_debug/usrp-e-mm-loopback.c index 722d09825..7a1747f9b 100644 --- a/host/apps/omap_debug/usrp-e-mm-loopback.c +++ b/host/apps/omap_debug/usrp-e-mm-loopback.c @@ -72,14 +72,14 @@ static void *read_thread(void *threadid) while (1) { if (!((*rxi)[rb_read].flags & RB_USER)) { - printf("Waiting for data\n"); +// printf("Waiting for data\n"); struct pollfd pfd; pfd.fd = fp; pfd.events = POLLIN; ssize_t ret = poll(&pfd, 1, -1); } - printf("pkt received, rb_read = %d\n", rb_read); +// printf("pkt received, rb_read = %d\n", rb_read); cnt = (*rxi)[rb_read].len; p = &(*rx_buf)[rb_read]; @@ -88,7 +88,7 @@ static void *read_thread(void *threadid) // if (cnt < 0) // printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); - printf("p = %X, p->seq_num = %d p->len = %d\n", p, p->seq_num, p->len); +// printf("p = %X, p->seq_num = %d p->len = %d\n", p, p->seq_num, p->len); pkt_count++; @@ -96,6 +96,8 @@ static void *read_thread(void *threadid) if (p->seq_num != prev_seq_num + 1) { printf("Sequence number fail, current = %d, previous = %d, pkt_count = %d\n", p->seq_num, prev_seq_num, pkt_count); + printf("pkt received, rb_read = %d\n", rb_read); + printf("p = %X, p->seq_num = %d p->len = %d\n", p, p->seq_num, p->len); seq_num_failure ++; if (seq_num_failure > 2) @@ -113,7 +115,7 @@ static void *read_thread(void *threadid) (*rxi)[rb_read].flags = RB_KERNEL; rb_read++; - if (rb_read == 200) + if (rb_read == 100) rb_read = 0; bytes_transfered += cnt; -- cgit v1.2.3 From d4a80a2b93a13dc371ef100df962ba99c53a9bb9 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 21 Sep 2010 13:33:51 +0000 Subject: Fix ring buffer size calculation. --- host/apps/omap_debug/usrp-e-mm-loopback.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-mm-loopback.c b/host/apps/omap_debug/usrp-e-mm-loopback.c index 7a1747f9b..71519d535 100644 --- a/host/apps/omap_debug/usrp-e-mm-loopback.c +++ b/host/apps/omap_debug/usrp-e-mm-loopback.c @@ -194,18 +194,18 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); - rb = mmap(0, 202 * 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); + rb = mmap(0, 102 * 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); if (rb == MAP_FAILED) { perror("mmap failed"); - exit; + return -1; } printf("rb = %X\n", rb); rxi = rb; rx_buf = rb + 4096; - txi = rb + 4096 + 4096 * 200; - tx_buf = rb + 4096 * 2 + 4096 * 200; + txi = rb + 4096 + 4096 * 100; + tx_buf = rb + 4096 * 2 + 4096 * 100; printf("rxi = %X, rx_buf = %X, txi = %X, tx_buf = %X\n", rxi, rx_buf, txi, tx_buf); -- cgit v1.2.3 From d6c4fbb29e818aec79864d25a0d308decb0db92d Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 21 Sep 2010 18:07:25 +0000 Subject: Read the ring buffer size from the kernel and use that to set up the structures that read and write the ring buffer. --- host/apps/omap_debug/usrp-e-mm-loopback.c | 27 +++++++++++++++--------- host/apps/omap_debug/usrp_e.h | 35 +++++++++++++++---------------- host/include/linux/usrp_e.h | 35 +++++++++++++++---------------- 3 files changed, 51 insertions(+), 46 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-mm-loopback.c b/host/apps/omap_debug/usrp-e-mm-loopback.c index 71519d535..a1da926a2 100644 --- a/host/apps/omap_debug/usrp-e-mm-loopback.c +++ b/host/apps/omap_debug/usrp-e-mm-loopback.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -20,12 +21,6 @@ struct pkt { short data[1024-6]; }; -/* delete after usrp_e.h updated */ -struct ring_buffer_info { - int flags; - int len; -}; - struct ring_buffer_info (*rxi)[]; struct ring_buffer_info (*txi)[]; struct pkt (*rx_buf)[200]; @@ -182,6 +177,8 @@ int main(int argc, char *argv[]) struct sched_param s = { .sched_priority = 1 }; + struct usrp_e_ring_buffer_size_t rb_size; + int ret, map_size, page_size; void *rb; if (argc < 2) { @@ -194,7 +191,14 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); - rb = mmap(0, 102 * 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); + page_size = getpagesize(); + + ret = ioctl(fp, USRP_E_GET_RB_INFO, &rb_size); + + map_size = (rb_size.num_pages_rx_flags + rb_size.num_pages_tx_flags) * page_size + + (rb_size.num_rx_frames + rb_size.num_tx_frames) * (page_size >> 1); + + rb = mmap(0, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); if (rb == MAP_FAILED) { perror("mmap failed"); return -1; @@ -203,9 +207,12 @@ int main(int argc, char *argv[]) printf("rb = %X\n", rb); rxi = rb; - rx_buf = rb + 4096; - txi = rb + 4096 + 4096 * 100; - tx_buf = rb + 4096 * 2 + 4096 * 100; + rx_buf = rb + (rb_size.num_pages_rx_flags * page_size); + txi = rb + (rb_size.num_pages_rx_flags * page_size) + + (rb_size.num_rx_frames * page_size >> 1); + tx_buf = rb + (rb_size.num_pages_rx_flags * page_size) + + (rb_size.num_rx_frames * page_size >> 1) + + (rb_size.num_pages_tx_flags * page_size); printf("rxi = %X, rx_buf = %X, txi = %X, tx_buf = %X\n", rxi, rx_buf, txi, tx_buf); diff --git a/host/apps/omap_debug/usrp_e.h b/host/apps/omap_debug/usrp_e.h index b098ad114..fd38027d4 100644 --- a/host/apps/omap_debug/usrp_e.h +++ b/host/apps/omap_debug/usrp_e.h @@ -34,8 +34,8 @@ struct usrp_e_ctl32 { #define UE_SPI_TXRX 1 /* Defines for spi ctrl register */ -#define UE_SPI_CTRL_TXNEG (1 << 10) -#define UE_SPI_CTRL_RXNEG (1 << 9) +#define UE_SPI_CTRL_TXNEG (BIT(10)) +#define UE_SPI_CTRL_RXNEG (BIT(9)) #define UE_SPI_PUSH_RISE 0 #define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG @@ -64,25 +64,24 @@ struct usrp_e_i2c { #define USRP_E_SPI _IOWR(USRP_E_IOC_MAGIC, 0x24, struct usrp_e_spi) #define USRP_E_I2C_READ _IOWR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) #define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) +#define USRP_E_GET_RB_INFO _IOR(USRP_E_IOC_MAGIC, 0x27, struct usrp_e_ring_buffer_size_t) -/* Data transfer frame definition */ - -struct usrp_transfer_frame { - __u32 status; - __u32 len; - __u8 buf[]; +/* Flag defines */ +#define RB_USER (1<<0) +#define RB_KERNEL (1<<1) +#define RB_OVERRUN (1<<2) +#define RB_DMA_ACTIVE (1<<3) + +struct ring_buffer_info { + int flags; + int len; }; -/* Flag defines */ -#define RB_USER (1 << 0) -#define RB_KERNEL (1 << 1) -#define RB_OVERRUN (1 << 2) -#define RB_DMA_ACTIVE (1 << 3) - -struct ring_buffer_entry { - unsigned int flags; - unsigned long dma_addr; - struct usrp_transfer_frame *frame_addr; +struct usrp_e_ring_buffer_size_t { + int num_pages_rx_flags; + int num_rx_frames; + int num_pages_tx_flags; + int num_tx_frames; }; #endif diff --git a/host/include/linux/usrp_e.h b/host/include/linux/usrp_e.h index b098ad114..fd38027d4 100644 --- a/host/include/linux/usrp_e.h +++ b/host/include/linux/usrp_e.h @@ -34,8 +34,8 @@ struct usrp_e_ctl32 { #define UE_SPI_TXRX 1 /* Defines for spi ctrl register */ -#define UE_SPI_CTRL_TXNEG (1 << 10) -#define UE_SPI_CTRL_RXNEG (1 << 9) +#define UE_SPI_CTRL_TXNEG (BIT(10)) +#define UE_SPI_CTRL_RXNEG (BIT(9)) #define UE_SPI_PUSH_RISE 0 #define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG @@ -64,25 +64,24 @@ struct usrp_e_i2c { #define USRP_E_SPI _IOWR(USRP_E_IOC_MAGIC, 0x24, struct usrp_e_spi) #define USRP_E_I2C_READ _IOWR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) #define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) +#define USRP_E_GET_RB_INFO _IOR(USRP_E_IOC_MAGIC, 0x27, struct usrp_e_ring_buffer_size_t) -/* Data transfer frame definition */ - -struct usrp_transfer_frame { - __u32 status; - __u32 len; - __u8 buf[]; +/* Flag defines */ +#define RB_USER (1<<0) +#define RB_KERNEL (1<<1) +#define RB_OVERRUN (1<<2) +#define RB_DMA_ACTIVE (1<<3) + +struct ring_buffer_info { + int flags; + int len; }; -/* Flag defines */ -#define RB_USER (1 << 0) -#define RB_KERNEL (1 << 1) -#define RB_OVERRUN (1 << 2) -#define RB_DMA_ACTIVE (1 << 3) - -struct ring_buffer_entry { - unsigned int flags; - unsigned long dma_addr; - struct usrp_transfer_frame *frame_addr; +struct usrp_e_ring_buffer_size_t { + int num_pages_rx_flags; + int num_rx_frames; + int num_pages_tx_flags; + int num_tx_frames; }; #endif -- cgit v1.2.3 From 380889798a9a9b5319e708743c5bb216405f77f4 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 21 Sep 2010 19:47:32 +0000 Subject: Convert write to use the mmap interface. --- host/apps/omap_debug/usrp-e-mm-loopback.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-mm-loopback.c b/host/apps/omap_debug/usrp-e-mm-loopback.c index a1da926a2..81bdb410a 100644 --- a/host/apps/omap_debug/usrp-e-mm-loopback.c +++ b/host/apps/omap_debug/usrp-e-mm-loopback.c @@ -137,7 +137,7 @@ static void *read_thread(void *threadid) static void *write_thread(void *threadid) { - int seq_number, i, cnt; + int seq_number, i, cnt, rb_write; void *tx_data; struct pkt *p; @@ -151,6 +151,7 @@ static void *write_thread(void *threadid) p->data[i] = i; seq_number = 1; + rb_write = 0; while (1) { p->seq_num = seq_number++; @@ -162,9 +163,26 @@ static void *write_thread(void *threadid) p->checksum = calc_checksum(p); - cnt = write(fp, tx_data, p->len * 2 + 12); - if (cnt < 0) - printf("Error returned from write: %d\n", cnt); + if (!((*txi)[rb_write].flags & RB_KERNEL)) { +// printf("Waiting for space\n"); + struct pollfd pfd; + pfd.fd = fp; + pfd.events = POLLOUT; + ssize_t ret = poll(&pfd, 1, -1); + } + + memcpy(&(*tx_buf)[rb_write], tx_data, p->len * 2 + 12); + + (*txi)[rb_write].len = p->len * 2 + 12; + (*txi)[rb_write].flags = RB_USER; + + rb_write++; + if (rb_write == 100) + rb_write = 0; + +// cnt = write(fp, tx_data, p->len * 2 + 12); +// if (cnt < 0) +// printf("Error returned from write: %d\n", cnt); // sleep(1); } } -- cgit v1.2.3 From 943bfa271c97b36dcba74f1d65220e6f66f50c7f Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 21 Sep 2010 19:59:02 +0000 Subject: Use the ring buffer sizes read from the kernel. --- host/apps/omap_debug/usrp-e-mm-loopback.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-mm-loopback.c b/host/apps/omap_debug/usrp-e-mm-loopback.c index 81bdb410a..053f60b60 100644 --- a/host/apps/omap_debug/usrp-e-mm-loopback.c +++ b/host/apps/omap_debug/usrp-e-mm-loopback.c @@ -27,6 +27,7 @@ struct pkt (*rx_buf)[200]; struct pkt (*tx_buf)[200]; static int fp; +static struct usrp_e_ring_buffer_size_t rb_size; static int calc_checksum(struct pkt *p) { @@ -110,7 +111,7 @@ static void *read_thread(void *threadid) (*rxi)[rb_read].flags = RB_KERNEL; rb_read++; - if (rb_read == 100) + if (rb_read == rb_size.num_rx_frames) rb_read = 0; bytes_transfered += cnt; @@ -177,7 +178,7 @@ static void *write_thread(void *threadid) (*txi)[rb_write].flags = RB_USER; rb_write++; - if (rb_write == 100) + if (rb_write == rb_size.num_tx_frames) rb_write = 0; // cnt = write(fp, tx_data, p->len * 2 + 12); @@ -195,7 +196,6 @@ int main(int argc, char *argv[]) struct sched_param s = { .sched_priority = 1 }; - struct usrp_e_ring_buffer_size_t rb_size; int ret, map_size, page_size; void *rb; -- cgit v1.2.3 From 77cdb4a9695e71e64e1d87cfad2cb4d8717f971e Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 21 Sep 2010 20:06:43 +0000 Subject: Use a dummy write to start DMA transfers when sending data to the FPGA. Poll will also start data transfers. --- host/apps/omap_debug/usrp-e-mm-loopback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host') diff --git a/host/apps/omap_debug/usrp-e-mm-loopback.c b/host/apps/omap_debug/usrp-e-mm-loopback.c index 053f60b60..f5fc83c87 100644 --- a/host/apps/omap_debug/usrp-e-mm-loopback.c +++ b/host/apps/omap_debug/usrp-e-mm-loopback.c @@ -181,7 +181,7 @@ static void *write_thread(void *threadid) if (rb_write == rb_size.num_tx_frames) rb_write = 0; -// cnt = write(fp, tx_data, p->len * 2 + 12); + cnt = write(fp, NULL, 0); // if (cnt < 0) // printf("Error returned from write: %d\n", cnt); // sleep(1); -- cgit v1.2.3 From 082715d0c90b615874fe6bbe93069fa696b3d47a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 24 Sep 2010 15:56:52 -0700 Subject: usrp-e: updated dsp for multiple shift properties --- host/lib/usrp/usrp_e/dsp_impl.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp index c133eafae..9312bb603 100644 --- a/host/lib/usrp/usrp_e/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -44,7 +44,9 @@ void usrp_e_impl::rx_ddc_init(void){ /*********************************************************************** * RX DDC Get **********************************************************************/ -void usrp_e_impl::rx_ddc_get(const wax::obj &key, wax::obj &val){ +void usrp_e_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + switch(key.as()){ case DSP_PROP_NAME: val = std::string("usrp-e ddc0"); @@ -58,6 +60,10 @@ void usrp_e_impl::rx_ddc_get(const wax::obj &key, wax::obj &val){ val = _ddc_freq; return; + case DSP_PROP_FREQ_SHIFT_NAMES: + val = prop_names_t(1, ""); + return; + case DSP_PROP_CODEC_RATE: val = MASTER_CLOCK_RATE; return; @@ -73,7 +79,9 @@ void usrp_e_impl::rx_ddc_get(const wax::obj &key, wax::obj &val){ /*********************************************************************** * RX DDC Set **********************************************************************/ -void usrp_e_impl::rx_ddc_set(const wax::obj &key, const wax::obj &val){ +void usrp_e_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + switch(key.as()){ case DSP_PROP_FREQ_SHIFT:{ @@ -119,7 +127,9 @@ void usrp_e_impl::tx_duc_init(void){ /*********************************************************************** * TX DUC Get **********************************************************************/ -void usrp_e_impl::tx_duc_get(const wax::obj &key, wax::obj &val){ +void usrp_e_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + switch(key.as()){ case DSP_PROP_NAME: val = std::string("usrp-e duc0"); @@ -133,6 +143,10 @@ void usrp_e_impl::tx_duc_get(const wax::obj &key, wax::obj &val){ val = _duc_freq; return; + case DSP_PROP_FREQ_SHIFT_NAMES: + val = prop_names_t(1, ""); + return; + case DSP_PROP_CODEC_RATE: val = MASTER_CLOCK_RATE; return; @@ -148,7 +162,9 @@ void usrp_e_impl::tx_duc_get(const wax::obj &key, wax::obj &val){ /*********************************************************************** * TX DUC Set **********************************************************************/ -void usrp_e_impl::tx_duc_set(const wax::obj &key, const wax::obj &val){ +void usrp_e_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + switch(key.as()){ case DSP_PROP_FREQ_SHIFT:{ -- cgit v1.2.3 From c75286df4689369aa9a3f4148b964d66109e085e Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sat, 25 Sep 2010 11:51:04 -0400 Subject: Add more NEON for type conversion. --- host/lib/transport/convert_types_impl.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'host') diff --git a/host/lib/transport/convert_types_impl.hpp b/host/lib/transport/convert_types_impl.hpp index b9a47eb0e..48ff99725 100644 --- a/host/lib/transport/convert_types_impl.hpp +++ b/host/lib/transport/convert_types_impl.hpp @@ -266,6 +266,26 @@ static UHD_INLINE void item32_to_fc32_nswap( } } +#elif defined(USE_ARM_NEON_H) +static UHD_INLINE void item32_to_fc32_nswap( + const item32_t *input, fc32_t *output, size_t nsamps) +{ + size_t i; + + float32x4_t Q1 = vdupq_n_f32(floats_per_short); + for (i=0; i < (nsamps & ~0x03); i+=2) { + int16x4_t D0 = vld1_s16(reinterpret_cast(&input[i])); + int16x4_t D1 = vrev32_s16(D0); + int32x4_t Q2 = vmovl_s16(D1); + float32x4_t Q3 = vcvtq_f32_s32(Q2); + float32x4_t Q4 = vmulq_f32(Q3, Q1); + vst1q_f32((reinterpret_cast(&output[i])), Q4); + } + + for (; i < nsamps; i++) + output[i] = item32_to_fc32(input[i]); +} + #else static UHD_INLINE void item32_to_fc32_nswap( const item32_t *input, fc32_t *output, size_t nsamps -- cgit v1.2.3 From 018813d46def4d25ec5a937da2235d7f2adce5b3 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sun, 26 Sep 2010 21:21:37 -0400 Subject: Add define so uusrp_e support is enabled. --- host/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host') diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 89487c86b..6c96706a5 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -64,7 +64,7 @@ IF(CMAKE_COMPILER_IS_GNUCXX) #causes trouble when compiling libusb1.0 on macintosh #comment out until mac ports libusb gets its act together #ADD_DEFINITIONS(-pedantic) - ADD_DEFINITIONS(-ansi) + #ADD_DEFINITIONS(-ansi) #only export symbols that are declared to be part of the uhd api: UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN) ENDIF(CMAKE_COMPILER_IS_GNUCXX) -- cgit v1.2.3 From 507283b3d43d653bf7ff1b2aa04f3d642297c9b1 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sun, 26 Sep 2010 21:22:07 -0400 Subject: Remove BIT macro --- host/include/linux/usrp_e.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/include/linux/usrp_e.h b/host/include/linux/usrp_e.h index fd38027d4..80f3a287b 100644 --- a/host/include/linux/usrp_e.h +++ b/host/include/linux/usrp_e.h @@ -34,8 +34,8 @@ struct usrp_e_ctl32 { #define UE_SPI_TXRX 1 /* Defines for spi ctrl register */ -#define UE_SPI_CTRL_TXNEG (BIT(10)) -#define UE_SPI_CTRL_RXNEG (BIT(9)) +#define UE_SPI_CTRL_TXNEG (1<<10) +#define UE_SPI_CTRL_RXNEG (1<<9) #define UE_SPI_PUSH_RISE 0 #define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG -- cgit v1.2.3 From 20c364cb6e2d175525c1885c8ac122187853dc95 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Sun, 26 Sep 2010 21:22:51 -0400 Subject: Really enable usrp_e support. Previous commit commented out the ansi flag so C++ comments in C compile. --- host/lib/usrp/usrp_e/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/CMakeLists.txt b/host/lib/usrp/usrp_e/CMakeLists.txt index da759d931..fbcd19276 100644 --- a/host/lib/usrp/usrp_e/CMakeLists.txt +++ b/host/lib/usrp/usrp_e/CMakeLists.txt @@ -25,6 +25,8 @@ MESSAGE(STATUS "Configuring usrp-e support...") INCLUDE(CheckIncludeFileCXX) CHECK_INCLUDE_FILE_CXX(linux/usrp_e.h HAVE_LINUX_USRP_E_H) +SET(ENABLE_USRP_E TRUE) + IF(DEFINED ENABLE_USRP_E) IF(ENABLE_USRP_E) MESSAGE(STATUS "USRP-E support enabled by configure flag") -- cgit v1.2.3 From dd9f9c340a8def560235d737df446454ea75dadc Mon Sep 17 00:00:00 2001 From: root Date: Thu, 30 Sep 2010 18:25:24 +0000 Subject: Ignore direction for GPIO 114 since it is always an input. --- host/apps/omap_debug/fpga-downloader.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/fpga-downloader.cc b/host/apps/omap_debug/fpga-downloader.cc index fb96b64a3..4e475b5c1 100644 --- a/host/apps/omap_debug/fpga-downloader.cc +++ b/host/apps/omap_debug/fpga-downloader.cc @@ -97,15 +97,17 @@ gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction) std::fstream direction_file; 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; + if (gpio_num != 114) { + 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; -- cgit v1.2.3 From 7f8d7b0e2fef1b2d5bb9c8047380dcf958c0c49c Mon Sep 17 00:00:00 2001 From: root Date: Thu, 30 Sep 2010 18:25:24 +0000 Subject: Ignore direction for GPIO 114 since it is always an input. --- host/apps/omap_debug/fpga-downloader.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/fpga-downloader.cc b/host/apps/omap_debug/fpga-downloader.cc index fb96b64a3..4e475b5c1 100644 --- a/host/apps/omap_debug/fpga-downloader.cc +++ b/host/apps/omap_debug/fpga-downloader.cc @@ -97,15 +97,17 @@ gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction) std::fstream direction_file; 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; + if (gpio_num != 114) { + 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; -- cgit v1.2.3 From cc97c6ee0b3dbc8e0ed6bfae01505fcb209d13cb Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 30 Sep 2010 15:12:30 -0700 Subject: usrp-e: update to build with the master --- host/lib/usrp/usrp_e/dboard_iface.cpp | 5 +++++ host/lib/usrp/usrp_e/io_impl.cpp | 18 +++++------------- 2 files changed, 10 insertions(+), 13 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp index 1bd177f60..6898df8df 100644 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e/dboard_iface.cpp @@ -91,6 +91,7 @@ public: std::vector get_clock_rates(unit_t); double get_clock_rate(unit_t); void set_clock_enabled(unit_t, bool); + double get_codec_rate(unit_t); private: usrp_e_iface::sptr _iface; @@ -140,6 +141,10 @@ void usrp_e_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ } } +double usrp_e_dboard_iface::get_codec_rate(unit_t){ + return _clock->get_fpga_clock_rate(); +} + /*********************************************************************** * GPIO **********************************************************************/ diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 31ea4c6c0..e57d6ce35 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -39,6 +39,7 @@ static const size_t MAX_BUFF_SIZE = 2048; static const bool usrp_e_io_impl_verbose = false; static const size_t tx_async_report_sid = 1; static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET; +static const double recv_timeout_ms = 100; /*********************************************************************** * Data Transport (phony zero-copy with read/write) @@ -74,7 +75,7 @@ private: boost::asio::buffer_size(buff) ); } - ssize_t recv(const boost::asio::mutable_buffer &buff){ + ssize_t recv(const boost::asio::mutable_buffer &buff, size_t to_ms){ //std::cout << boost::format( // "calling read on fd %d, buff size is %d" //) % _fd % boost::asio::buffer_size(buff) << std::endl; @@ -84,7 +85,7 @@ private: pollfd pfd; pfd.fd = _fd; pfd.events = POLLIN; - ssize_t poll_ret = poll(&pfd, 1, 100/*ms*/); + ssize_t poll_ret = poll(&pfd, 1, to_ms); if (poll_ret <= 0){ if (usrp_e_io_impl_verbose) std::cerr << boost::format( "usrp-e io impl recv(): poll() returned non-positive value: %d\n" @@ -170,7 +171,7 @@ void usrp_e_impl::io_impl::recv_pirate_loop( //size_t next_packet_seq = 0; while(recv_pirate_crew_raiding){ - managed_recv_buffer::sptr buff = this->transport.get_recv_buff(); + managed_recv_buffer::sptr buff = this->transport.get_recv_buff(recv_timeout_ms); if (not buff.get()) continue; //ignore timeout/error buffers try{ @@ -262,7 +263,7 @@ bool get_send_buffs( ){ UHD_ASSERT_THROW(buffs.size() == 1); buffs[0] = trans->get_send_buff(); - return buffs[0].get(); + return buffs[0].get() != NULL; } size_t usrp_e_impl::send( @@ -292,15 +293,6 @@ size_t usrp_e_impl::send( /*********************************************************************** * Data Recv **********************************************************************/ -bool get_recv_buffs( - data_transport *trans, - vrt_packet_handler::managed_recv_buffs_t &buffs -){ - UHD_ASSERT_THROW(buffs.size() == 1); - buffs[0] = trans->get_recv_buff(); - return buffs[0].get(); -} - size_t usrp_e_impl::recv( const std::vector &buffs, size_t num_samps, -- cgit v1.2.3 From 46d2fc423d2fdcf32454621c6f41e555d2496702 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 30 Sep 2010 17:56:36 -0700 Subject: usrp-e: untested attempt at zero copy iface for mmap --- host/lib/usrp/usrp_e/CMakeLists.txt | 1 + host/lib/usrp/usrp_e/io_impl.cpp | 97 ++---------- host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp | 201 +++++++++++++++++++++++++ 3 files changed, 212 insertions(+), 87 deletions(-) create mode 100644 host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp (limited to 'host') diff --git a/host/lib/usrp/usrp_e/CMakeLists.txt b/host/lib/usrp/usrp_e/CMakeLists.txt index da759d931..bab868f90 100644 --- a/host/lib/usrp/usrp_e/CMakeLists.txt +++ b/host/lib/usrp/usrp_e/CMakeLists.txt @@ -54,6 +54,7 @@ IF(ENABLE_USRP_E) ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_impl.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_iface.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_iface.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_regs.hpp ) ELSE(ENABLE_USRP_E) diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index e57d6ce35..0b5fa054b 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -22,8 +22,6 @@ #include #include "../../transport/vrt_packet_handler.hpp" #include -#include //read, write -#include #include #include #include @@ -32,90 +30,15 @@ using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; +zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface); + /*********************************************************************** * Constants **********************************************************************/ -static const size_t MAX_BUFF_SIZE = 2048; -static const bool usrp_e_io_impl_verbose = false; static const size_t tx_async_report_sid = 1; static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET; static const double recv_timeout_ms = 100; -/*********************************************************************** - * Data Transport (phony zero-copy with read/write) - **********************************************************************/ -class data_transport: - public transport::phony_zero_copy_recv_if, - public transport::phony_zero_copy_send_if -{ -public: - data_transport(int fd): - transport::phony_zero_copy_recv_if(MAX_BUFF_SIZE), - transport::phony_zero_copy_send_if(MAX_BUFF_SIZE), - _fd(fd) - { - /* NOP */ - } - - size_t get_num_recv_frames(void) const{ - return 100; //FIXME no idea! - //this will be an important number when packet ring gets implemented - } - - size_t get_num_send_frames(void) const{ - return 100; //FIXME no idea! - //this will be an important number when packet ring gets implemented - } - -private: - int _fd; - ssize_t send(const boost::asio::const_buffer &buff){ - return write(_fd, - boost::asio::buffer_cast(buff), - boost::asio::buffer_size(buff) - ); - } - ssize_t recv(const boost::asio::mutable_buffer &buff, size_t to_ms){ - //std::cout << boost::format( - // "calling read on fd %d, buff size is %d" - //) % _fd % boost::asio::buffer_size(buff) << std::endl; - - //setup and call poll on the file descriptor - //return 0 and do not read when poll times out - pollfd pfd; - pfd.fd = _fd; - pfd.events = POLLIN; - ssize_t poll_ret = poll(&pfd, 1, to_ms); - if (poll_ret <= 0){ - if (usrp_e_io_impl_verbose) std::cerr << boost::format( - "usrp-e io impl recv(): poll() returned non-positive value: %d\n" - " -> return 0 for timeout" - ) % poll_ret << std::endl; - return 0; //timeout - } - - //perform the blocking read(...) - ssize_t read_ret = read(_fd, - boost::asio::buffer_cast(buff), - boost::asio::buffer_size(buff) - ); - if (read_ret < 0){ - if (usrp_e_io_impl_verbose) std::cerr << boost::format( - "usrp-e io impl recv(): read() returned small value: %d\n" - " -> return -1 for error" - ) % read_ret << std::endl; - return -1; - } - - //std::cout << "len " << int(read_ret) << std::endl; - //for (size_t i = 0; i < 9; i++){ - // std::cout << boost::format(" 0x%08x") % boost::asio::buffer_cast(buff)[i] << std::endl; - //} - - return read_ret; - } -}; - /*********************************************************************** * io impl details (internal to this file) * - pirate crew of 1 @@ -127,11 +50,11 @@ struct usrp_e_impl::io_impl{ //state management for the vrt packet handler code vrt_packet_handler::recv_state packet_handler_recv_state; vrt_packet_handler::send_state packet_handler_send_state; - data_transport transport; + zero_copy_if::sptr data_xport; bool continuous_streaming; - io_impl(int fd): - transport(fd), - recv_pirate_booty(recv_booty_type::make(transport.get_num_recv_frames())), + io_impl(usrp_e_iface::sptr iface): + data_xport(usrp_e_make_mmap_zero_copy(iface)), + recv_pirate_booty(recv_booty_type::make(data_xport->get_num_recv_frames())), async_msg_fifo(bounded_buffer::make(100/*messages deep*/)) { /* NOP */ @@ -171,7 +94,7 @@ void usrp_e_impl::io_impl::recv_pirate_loop( //size_t next_packet_seq = 0; while(recv_pirate_crew_raiding){ - managed_recv_buffer::sptr buff = this->transport.get_recv_buff(recv_timeout_ms); + managed_recv_buffer::sptr buff = this->data_xport->get_recv_buff(recv_timeout_ms); if (not buff.get()) continue; //ignore timeout/error buffers try{ @@ -229,7 +152,7 @@ void usrp_e_impl::io_init(void){ _iface->poke32(UE_REG_CTRL_TX_REPORT_SID, tx_async_report_sid); _iface->poke32(UE_REG_CTRL_TX_POLICY, UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET); - _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface->get_file_descriptor())); + _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface)); //spawn a pirate, yarrr! _io_impl->recv_pirate_crew.create_thread(boost::bind( @@ -258,7 +181,7 @@ void usrp_e_impl::handle_overrun(size_t){ * Data Send **********************************************************************/ bool get_send_buffs( - data_transport *trans, + zero_copy_if::sptr trans, vrt_packet_handler::managed_send_buffs_t &buffs ){ UHD_ASSERT_THROW(buffs.size() == 1); @@ -285,7 +208,7 @@ size_t usrp_e_impl::send( io_type, send_otw_type, //input and output types to convert MASTER_CLOCK_RATE, //master clock tick rate uhd::transport::vrt::if_hdr_pack_le, - boost::bind(&get_send_buffs, &_io_impl->transport, _1), + boost::bind(&get_send_buffs, _io_impl->data_xport, _1), get_max_send_samps_per_packet() ); } diff --git a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp new file mode 100644 index 000000000..0910caa6f --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp @@ -0,0 +1,201 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include +#include //mmap +#include //getpagesize +#include //poll +#include +#include "usrp_e_iface.hpp" + +using namespace uhd; +using namespace uhd::transport; + +static const bool debug_verbose = false; + +/*********************************************************************** + * The managed receive buffer implementation + **********************************************************************/ +class usrp_e_mmap_managed_recv_buffer : public managed_recv_buffer{ +public: + usrp_e_mmap_managed_recv_buffer( + const void *mem, size_t len, ring_buffer_info *info + ): + _buff(mem, len), _info(info) + { + /* NOP */ + } + + ~usrp_e_mmap_managed_recv_buffer(void){ + _info->flags = RB_KERNEL; + } + +private: + const boost::asio::const_buffer &get(void) const{ + return _buff; + } + + const boost::asio::const_buffer _buff; + ring_buffer_info *_info; +}; + +/*********************************************************************** + * The managed send buffer implementation + **********************************************************************/ +class usrp_e_mmap_managed_send_buffer : public managed_send_buffer{ +public: + usrp_e_mmap_managed_send_buffer( + void *mem, size_t len, ring_buffer_info *info, int fd + ): + _buff(mem, len), _info(info), _fd(fd), _commited(false) + { + /* NOP */ + } + + ~usrp_e_mmap_managed_send_buffer(void){ + if (not _commited) this->commit(0); + } + + ssize_t commit(size_t num_bytes){ + _commited = true; + _info->len = num_bytes; + _info->flags = RB_USER; + ssize_t ret = ::write(_fd, NULL, 0); + return (ret < 0)? ret : num_bytes; + } + +private: + const boost::asio::mutable_buffer &get(void) const{ + return _buff; + } + + const boost::asio::mutable_buffer _buff; + ring_buffer_info *_info; + int _fd; + bool _commited; +}; + +/*********************************************************************** + * The zero copy interface implementation + **********************************************************************/ +class usrp_e_mmap_zero_copy_impl : public zero_copy_if{ +public: + usrp_e_mmap_zero_copy_impl(usrp_e_iface::sptr iface): + _fd(iface->get_file_descriptor()), _recv_index(0), _send_index(0) + { + //get system sizes + iface->ioctl(USRP_E_GET_RB_INFO, &_rb_size); + size_t page_size = getpagesize(); + _frame_size = page_size/2; + + //calculate the memory size + size_t map_size = + (_rb_size.num_pages_rx_flags + _rb_size.num_pages_tx_flags) * page_size + + (_rb_size.num_rx_frames + _rb_size.num_tx_frames) * _frame_size; + + //call mmap to get the memory + void *ring_buffer = mmap( + NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0 + ); + UHD_ASSERT_THROW(ring_buffer != MAP_FAILED); + + //calculate the memory offsets for info and buffers + size_t recv_info_off = 0; + size_t recv_buff_off = recv_info_off + (_rb_size.num_pages_rx_flags * page_size); + size_t send_info_off = recv_buff_off + (_rb_size.num_rx_frames * _frame_size); + size_t send_buff_off = send_info_off + (_rb_size.num_pages_tx_flags * page_size); + + //set the internal pointers for info and buffers + typedef ring_buffer_info (*rbi_pta)[]; + boost::uint8_t *rb_ptr = reinterpret_cast(ring_buffer); + _recv_info = reinterpret_cast(rb_ptr + recv_info_off); + _recv_buff = rb_ptr + recv_buff_off; + _send_info = reinterpret_cast(rb_ptr + send_info_off); + _send_buff = rb_ptr + send_buff_off; + } + + managed_recv_buffer::sptr get_recv_buff(size_t timeout_ms){ + //grab pointers to the info and buffer + ring_buffer_info *info = (*_recv_info) + _recv_index; + void *mem = _recv_buff + _frame_size*_recv_index; + + //poll/wait for a ready frame + if (not (info->flags & RB_USER)){ + pollfd pfd; + pfd.fd = _fd; + pfd.events = POLLIN; + ssize_t poll_ret = poll(&pfd, 1, timeout_ms); + if (poll_ret <= 0) return managed_recv_buffer::sptr(); + } + + //increment the index for the next call + if (++_recv_index == size_t(_rb_size.num_rx_frames)) _recv_index = 0; + + //return the managed buffer for this frame + return managed_recv_buffer::sptr( + new usrp_e_mmap_managed_recv_buffer(mem, info->len, info) + ); + } + + size_t get_num_recv_frames(void) const{ + return _rb_size.num_rx_frames; + } + + managed_send_buffer::sptr get_send_buff(void){ + //grab pointers to the info and buffer + ring_buffer_info *info = (*_send_info) + _send_index; + void *mem = _send_buff + _frame_size*_send_index; + + //poll/wait for a ready frame + if (not (info->flags & RB_KERNEL)){ + pollfd pfd; + pfd.fd = _fd; + pfd.events = POLLOUT; + ssize_t poll_ret = poll(&pfd, 1, -1 /*forever*/); + if (poll_ret <= 0) return managed_send_buffer::sptr(); + } + + //increment the index for the next call + if (++_send_index == size_t(_rb_size.num_tx_frames)) _send_index = 0; + + //return the managed buffer for this frame + return managed_send_buffer::sptr( + new usrp_e_mmap_managed_send_buffer(mem, _frame_size, info, _fd) + ); + } + + size_t get_num_send_frames(void) const{ + return _rb_size.num_tx_frames; + } + +private: + int _fd; + usrp_e_ring_buffer_size_t _rb_size; + size_t _frame_size; + ring_buffer_info (*_recv_info)[], (*_send_info)[]; + boost::uint8_t *_recv_buff, *_send_buff; + size_t _recv_index, _send_index; +}; + +/*********************************************************************** + * The zero copy interface make function + **********************************************************************/ +zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface){ + return zero_copy_if::sptr(new usrp_e_mmap_zero_copy_impl(iface)); +} -- cgit v1.2.3 From c0e03bb2edea4645f46f25afcc9be8b7b03f68df Mon Sep 17 00:00:00 2001 From: root Date: Thu, 30 Sep 2010 18:25:24 +0000 Subject: Ignore direction for GPIO 114 since it is always an input. --- host/apps/omap_debug/fpga-downloader.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'host') diff --git a/host/apps/omap_debug/fpga-downloader.cc b/host/apps/omap_debug/fpga-downloader.cc index fb96b64a3..4e475b5c1 100644 --- a/host/apps/omap_debug/fpga-downloader.cc +++ b/host/apps/omap_debug/fpga-downloader.cc @@ -97,15 +97,17 @@ gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction) std::fstream direction_file; 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; + if (gpio_num != 114) { + 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; -- cgit v1.2.3 From b34af3c910a54d8afd4b1f00f1254c3ab762c82a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 4 Oct 2010 11:17:01 -0700 Subject: usrp-e: implemented mmap with new zero_copy timeout work, added much debug verbosity --- host/lib/usrp/usrp_e/io_impl.cpp | 48 ++++---- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 6 +- host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp | 161 ++++++++++++------------- 3 files changed, 107 insertions(+), 108 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 0b5fa054b..1e577a4df 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -37,7 +37,7 @@ zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface); **********************************************************************/ static const size_t tx_async_report_sid = 1; static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET; -static const double recv_timeout_ms = 100; +static const bool recv_debug = true; /*********************************************************************** * io impl details (internal to this file) @@ -66,10 +66,10 @@ struct usrp_e_impl::io_impl{ recv_pirate_crew.join_all(); } - bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs, size_t timeout_ms){ + bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs, double timeout){ UHD_ASSERT_THROW(buffs.size() == 1); boost::this_thread::disable_interruption di; //disable because the wait can throw - return recv_pirate_booty->pop_with_timed_wait(buffs.front(), boost::posix_time::milliseconds(timeout_ms)); + return recv_pirate_booty->pop_with_timed_wait(buffs.front(), timeout); } //a pirate's life is the life for me! @@ -94,9 +94,17 @@ void usrp_e_impl::io_impl::recv_pirate_loop( //size_t next_packet_seq = 0; while(recv_pirate_crew_raiding){ - managed_recv_buffer::sptr buff = this->data_xport->get_recv_buff(recv_timeout_ms); + managed_recv_buffer::sptr buff = this->data_xport->get_recv_buff(); if (not buff.get()) continue; //ignore timeout/error buffers + if (recv_debug){ + std::cout << "len " << buff->size() << std::endl; + for (size_t i = 0; i < 9; i++){ + std::cout << boost::format(" 0x%08x") % buff->cast()[i] << std::endl; + } + std::cout << std::endl << std::endl; + } + try{ //extract the vrt header packet info vrt::if_packet_info_t if_packet_info; @@ -181,20 +189,18 @@ void usrp_e_impl::handle_overrun(size_t){ * Data Send **********************************************************************/ bool get_send_buffs( - zero_copy_if::sptr trans, + zero_copy_if::sptr trans, double timeout, vrt_packet_handler::managed_send_buffs_t &buffs ){ UHD_ASSERT_THROW(buffs.size() == 1); - buffs[0] = trans->get_send_buff(); + buffs[0] = trans->get_send_buff(timeout); return buffs[0].get() != NULL; } size_t usrp_e_impl::send( - const std::vector &buffs, - size_t num_samps, - const tx_metadata_t &metadata, - const io_type_t &io_type, - send_mode_t send_mode + const std::vector &buffs, size_t num_samps, + const tx_metadata_t &metadata, const io_type_t &io_type, + send_mode_t send_mode, double timeout ){ otw_type_t send_otw_type; send_otw_type.width = 16; @@ -208,7 +214,7 @@ size_t usrp_e_impl::send( io_type, send_otw_type, //input and output types to convert MASTER_CLOCK_RATE, //master clock tick rate uhd::transport::vrt::if_hdr_pack_le, - boost::bind(&get_send_buffs, _io_impl->data_xport, _1), + boost::bind(&get_send_buffs, _io_impl->data_xport, timeout, _1), get_max_send_samps_per_packet() ); } @@ -217,12 +223,9 @@ size_t usrp_e_impl::send( * Data Recv **********************************************************************/ size_t usrp_e_impl::recv( - const std::vector &buffs, - size_t num_samps, - rx_metadata_t &metadata, - const io_type_t &io_type, - recv_mode_t recv_mode, - size_t timeout_ms + const std::vector &buffs, size_t num_samps, + rx_metadata_t &metadata, const io_type_t &io_type, + recv_mode_t recv_mode, double timeout ){ otw_type_t recv_otw_type; recv_otw_type.width = 16; @@ -236,7 +239,7 @@ size_t usrp_e_impl::recv( io_type, recv_otw_type, //input and output types to convert MASTER_CLOCK_RATE, //master clock tick rate uhd::transport::vrt::if_hdr_unpack_le, - boost::bind(&usrp_e_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout_ms), + boost::bind(&usrp_e_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout), boost::bind(&usrp_e_impl::handle_overrun, this, _1) ); } @@ -245,11 +248,8 @@ size_t usrp_e_impl::recv( * Async Recv **********************************************************************/ bool usrp_e_impl::recv_async_msg( - async_metadata_t &async_metadata, - size_t timeout_ms + async_metadata_t &async_metadata, double timeout ){ boost::this_thread::disable_interruption di; //disable because the wait can throw - return _io_impl->async_msg_fifo->pop_with_timed_wait( - async_metadata, boost::posix_time::milliseconds(timeout_ms) - ); + return _io_impl->async_msg_fifo->pop_with_timed_wait(async_metadata, timeout); } diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 2457e27cc..49912050e 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -82,9 +82,9 @@ public: ~usrp_e_impl(void); //the io interface - size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t); - size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, size_t); - bool recv_async_msg(uhd::async_metadata_t &, size_t); + size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t, double); + size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, double); + bool recv_async_msg(uhd::async_metadata_t &, double); size_t get_max_send_samps_per_packet(void) const{return 503;} size_t get_max_recv_samps_per_packet(void) const{return 503;} diff --git a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp index 0910caa6f..e62205a3f 100644 --- a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp @@ -15,86 +15,27 @@ // along with this program. If not, see . // +#include "usrp_e_iface.hpp" #include #include #include #include //mmap #include //getpagesize #include //poll -#include -#include "usrp_e_iface.hpp" +#include +#include +#include using namespace uhd; using namespace uhd::transport; -static const bool debug_verbose = false; - -/*********************************************************************** - * The managed receive buffer implementation - **********************************************************************/ -class usrp_e_mmap_managed_recv_buffer : public managed_recv_buffer{ -public: - usrp_e_mmap_managed_recv_buffer( - const void *mem, size_t len, ring_buffer_info *info - ): - _buff(mem, len), _info(info) - { - /* NOP */ - } - - ~usrp_e_mmap_managed_recv_buffer(void){ - _info->flags = RB_KERNEL; - } - -private: - const boost::asio::const_buffer &get(void) const{ - return _buff; - } - - const boost::asio::const_buffer _buff; - ring_buffer_info *_info; -}; - -/*********************************************************************** - * The managed send buffer implementation - **********************************************************************/ -class usrp_e_mmap_managed_send_buffer : public managed_send_buffer{ -public: - usrp_e_mmap_managed_send_buffer( - void *mem, size_t len, ring_buffer_info *info, int fd - ): - _buff(mem, len), _info(info), _fd(fd), _commited(false) - { - /* NOP */ - } - - ~usrp_e_mmap_managed_send_buffer(void){ - if (not _commited) this->commit(0); - } - - ssize_t commit(size_t num_bytes){ - _commited = true; - _info->len = num_bytes; - _info->flags = RB_USER; - ssize_t ret = ::write(_fd, NULL, 0); - return (ret < 0)? ret : num_bytes; - } - -private: - const boost::asio::mutable_buffer &get(void) const{ - return _buff; - } - - const boost::asio::mutable_buffer _buff; - ring_buffer_info *_info; - int _fd; - bool _commited; -}; +static const bool fp_verbose = true; //fast-path verbose +static const bool sp_verbose = true; //slow-path verbose /*********************************************************************** * The zero copy interface implementation **********************************************************************/ -class usrp_e_mmap_zero_copy_impl : public zero_copy_if{ +class usrp_e_mmap_zero_copy_impl : public zero_copy_if, public boost::enable_shared_from_this { public: usrp_e_mmap_zero_copy_impl(usrp_e_iface::sptr iface): _fd(iface->get_file_descriptor()), _recv_index(0), _send_index(0) @@ -105,15 +46,26 @@ public: _frame_size = page_size/2; //calculate the memory size - size_t map_size = + _map_size = (_rb_size.num_pages_rx_flags + _rb_size.num_pages_tx_flags) * page_size + (_rb_size.num_rx_frames + _rb_size.num_tx_frames) * _frame_size; + //print sizes summary + if (sp_verbose){ + std::cout << "page_size: " << page_size << std::endl; + std::cout << "frame_size: " << _frame_size << std::endl; + std::cout << "num_pages_rx_flags: " << _rb_size.num_pages_rx_flags << std::endl; + std::cout << "num_rx_frames: " << _rb_size.num_rx_frames << std::endl; + std::cout << "num_pages_tx_flags: " << _rb_size.num_pages_tx_flags << std::endl; + std::cout << "num_tx_frames: " << _rb_size.num_tx_frames << std::endl; + std::cout << "map_size: " << _map_size << std::endl; + } + //call mmap to get the memory - void *ring_buffer = mmap( - NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0 + _mapped_mem = ::mmap( + NULL, _map_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0 ); - UHD_ASSERT_THROW(ring_buffer != MAP_FAILED); + UHD_ASSERT_THROW(_mapped_mem != MAP_FAILED); //calculate the memory offsets for info and buffers size_t recv_info_off = 0; @@ -121,16 +73,31 @@ public: size_t send_info_off = recv_buff_off + (_rb_size.num_rx_frames * _frame_size); size_t send_buff_off = send_info_off + (_rb_size.num_pages_tx_flags * page_size); + //print offset summary + if (sp_verbose){ + std::cout << "recv_info_off: " << recv_info_off << std::endl; + std::cout << "recv_buff_off: " << recv_buff_off << std::endl; + std::cout << "send_info_off: " << send_info_off << std::endl; + std::cout << "send_buff_off: " << send_buff_off << std::endl; + } + //set the internal pointers for info and buffers typedef ring_buffer_info (*rbi_pta)[]; - boost::uint8_t *rb_ptr = reinterpret_cast(ring_buffer); + char *rb_ptr = reinterpret_cast(_mapped_mem); _recv_info = reinterpret_cast(rb_ptr + recv_info_off); _recv_buff = rb_ptr + recv_buff_off; _send_info = reinterpret_cast(rb_ptr + send_info_off); _send_buff = rb_ptr + send_buff_off; } - managed_recv_buffer::sptr get_recv_buff(size_t timeout_ms){ + ~usrp_e_mmap_zero_copy_impl(void){ + if (sp_verbose) std::cout << "cleanup: munmap" << std::endl; + ::munmap(_mapped_mem, _map_size); + } + + managed_recv_buffer::sptr get_recv_buff(double timeout){ + if (fp_verbose) std::cout << "get_recv_buff: " << _recv_index << std::endl; + //grab pointers to the info and buffer ring_buffer_info *info = (*_recv_info) + _recv_index; void *mem = _recv_buff + _frame_size*_recv_index; @@ -140,7 +107,8 @@ public: pollfd pfd; pfd.fd = _fd; pfd.events = POLLIN; - ssize_t poll_ret = poll(&pfd, 1, timeout_ms); + ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3)); + if (fp_verbose) std::cout << " POLLIN: " << poll_ret << std::endl; if (poll_ret <= 0) return managed_recv_buffer::sptr(); } @@ -148,8 +116,10 @@ public: if (++_recv_index == size_t(_rb_size.num_rx_frames)) _recv_index = 0; //return the managed buffer for this frame - return managed_recv_buffer::sptr( - new usrp_e_mmap_managed_recv_buffer(mem, info->len, info) + if (fp_verbose) std::cout << " make_recv_buff: " << info->len << std::endl; + return managed_recv_buffer::make_safe( + boost::asio::const_buffer(mem, info->len), + boost::bind(&usrp_e_mmap_zero_copy_impl::release, shared_from_this(), info) ); } @@ -157,7 +127,9 @@ public: return _rb_size.num_rx_frames; } - managed_send_buffer::sptr get_send_buff(void){ + managed_send_buffer::sptr get_send_buff(double timeout){ + if (fp_verbose) std::cout << "get_send_buff: " << _send_index << std::endl; + //grab pointers to the info and buffer ring_buffer_info *info = (*_send_info) + _send_index; void *mem = _send_buff + _frame_size*_send_index; @@ -167,7 +139,8 @@ public: pollfd pfd; pfd.fd = _fd; pfd.events = POLLOUT; - ssize_t poll_ret = poll(&pfd, 1, -1 /*forever*/); + ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3)); + if (fp_verbose) std::cout << " POLLOUT: " << poll_ret << std::endl; if (poll_ret <= 0) return managed_send_buffer::sptr(); } @@ -175,8 +148,10 @@ public: if (++_send_index == size_t(_rb_size.num_tx_frames)) _send_index = 0; //return the managed buffer for this frame - return managed_send_buffer::sptr( - new usrp_e_mmap_managed_send_buffer(mem, _frame_size, info, _fd) + if (fp_verbose) std::cout << " make_send_buff: " << _frame_size << std::endl; + return managed_send_buffer::make_safe( + boost::asio::mutable_buffer(mem, _frame_size), + boost::bind(&usrp_e_mmap_zero_copy_impl::commit, shared_from_this(), info, _1) ); } @@ -185,11 +160,35 @@ public: } private: + + void release(ring_buffer_info *info){ + if (fp_verbose) std::cout << "recv buff: release" << std::endl; + info->flags = RB_KERNEL; + } + + void commit(ring_buffer_info *info, size_t len){ + if (fp_verbose) std::cout << "send buff: commit " << len << std::endl; + info->len = len; + info->flags = RB_USER; + if (::write(_fd, NULL, 0) < 0){ + std::cerr << UHD_THROW_SITE_INFO("write error") << std::endl; + } + } + int _fd; + + //the mapped memory itself + void *_mapped_mem; + + //mapped memory sizes usrp_e_ring_buffer_size_t _rb_size; - size_t _frame_size; + size_t _frame_size, _map_size; + + //pointers to sections in the mapped memory ring_buffer_info (*_recv_info)[], (*_send_info)[]; - boost::uint8_t *_recv_buff, *_send_buff; + char *_recv_buff, *_send_buff; + + //indexes into sub-sections of mapped memory size_t _recv_index, _send_index; }; -- cgit v1.2.3 From f642942dc364c1d26a9128c1ba631d3604d0671a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 4 Oct 2010 15:17:57 -0700 Subject: usrp-e: check if flags are ready after poll --- host/lib/usrp/usrp_e/io_impl.cpp | 6 +++--- host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 1e577a4df..2802a6b87 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -130,12 +130,12 @@ void usrp_e_impl::io_impl::recv_pirate_loop( continue; } + //same number of frames as the data transport -> always immediate + recv_pirate_booty->push_with_wait(buff); + }catch(const std::exception &e){ std::cerr << "Error (usrp-e recv pirate loop): " << e.what() << std::endl; } - - //usrp-e back-pressures on receive: push with wait - recv_pirate_booty->push_with_wait(buff); } } diff --git a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp index e62205a3f..9e25ed088 100644 --- a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp @@ -112,6 +112,12 @@ public: if (poll_ret <= 0) return managed_recv_buffer::sptr(); } + //check that the frame is really ready + if (not (info->flags & RB_USER)){ + if (fp_verbose) std::cout << " flags: not ready" << std::endl; + return managed_recv_buffer::sptr(); + } + //increment the index for the next call if (++_recv_index == size_t(_rb_size.num_rx_frames)) _recv_index = 0; @@ -144,6 +150,12 @@ public: if (poll_ret <= 0) return managed_send_buffer::sptr(); } + //check that the frame is really ready + if (not (info->flags & RB_KERNEL)){ + if (fp_verbose) std::cout << " flags: not ready" << std::endl; + return managed_send_buffer::sptr(); + } + //increment the index for the next call if (++_send_index == size_t(_rb_size.num_tx_frames)) _send_index = 0; -- cgit v1.2.3 From 12901b055f021acf1b02f4bc7e9c3c8d1aa426e5 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 6 Oct 2010 18:48:03 -0400 Subject: Add flag that indicates userspace has started processing a frame. --- host/include/linux/usrp_e.h | 1 + 1 file changed, 1 insertion(+) (limited to 'host') diff --git a/host/include/linux/usrp_e.h b/host/include/linux/usrp_e.h index 80f3a287b..cb62d940d 100644 --- a/host/include/linux/usrp_e.h +++ b/host/include/linux/usrp_e.h @@ -71,6 +71,7 @@ struct usrp_e_i2c { #define RB_KERNEL (1<<1) #define RB_OVERRUN (1<<2) #define RB_DMA_ACTIVE (1<<3) +#define RB_USER_PROCESS (1<<4) struct ring_buffer_info { int flags; -- cgit v1.2.3 From d5a0960455560e9f6077aa45d52aa01c469769dd Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 6 Oct 2010 16:26:35 -0700 Subject: usrp-e: implemented the USER_PROCESS flag and CTM poll technique --- host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp | 33 +++++++++++--------------- 1 file changed, 14 insertions(+), 19 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp index 9e25ed088..4e10bcc48 100644 --- a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp @@ -31,6 +31,7 @@ using namespace uhd::transport; static const bool fp_verbose = true; //fast-path verbose static const bool sp_verbose = true; //slow-path verbose +static const size_t poll_breakout = 10; //how many poll timeouts constitute a full timeout /*********************************************************************** * The zero copy interface implementation @@ -104,19 +105,19 @@ public: //poll/wait for a ready frame if (not (info->flags & RB_USER)){ - pollfd pfd; - pfd.fd = _fd; - pfd.events = POLLIN; - ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3)); - if (fp_verbose) std::cout << " POLLIN: " << poll_ret << std::endl; - if (poll_ret <= 0) return managed_recv_buffer::sptr(); - } - - //check that the frame is really ready - if (not (info->flags & RB_USER)){ - if (fp_verbose) std::cout << " flags: not ready" << std::endl; - return managed_recv_buffer::sptr(); - } + for (size_t i = 0; i < poll_breakout; i++){ + pollfd pfd; + pfd.fd = _fd; + pfd.events = POLLIN; + ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3/poll_breakout)); + if (fp_verbose) std::cout << " POLLIN: " << poll_ret << std::endl; + if (poll_ret > 0) goto found_user_frame; //good poll, continue on + } + return managed_recv_buffer::sptr(); //timed-out for real + } found_user_frame: + + //the process has claimed the frame + info->flags = RB_USER_PROCESS; //increment the index for the next call if (++_recv_index == size_t(_rb_size.num_rx_frames)) _recv_index = 0; @@ -150,12 +151,6 @@ public: if (poll_ret <= 0) return managed_send_buffer::sptr(); } - //check that the frame is really ready - if (not (info->flags & RB_KERNEL)){ - if (fp_verbose) std::cout << " flags: not ready" << std::endl; - return managed_send_buffer::sptr(); - } - //increment the index for the next call if (++_send_index == size_t(_rb_size.num_tx_frames)) _send_index = 0; -- cgit v1.2.3 From be6a6b291400dde7b2b3b935e2eedd8d892e54f8 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 7 Oct 2010 10:27:30 -0700 Subject: usrp-e: use frame size to calculate the max samples per packet --- host/lib/usrp/usrp_e/io_impl.cpp | 43 ++++++++++++++++++-------- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 6 ++-- host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp | 8 +++++ 3 files changed, 42 insertions(+), 15 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 2802a6b87..406b7269f 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -91,7 +91,6 @@ void usrp_e_impl::io_impl::recv_pirate_loop( ){ set_thread_priority_safe(); recv_pirate_crew_raiding = true; - //size_t next_packet_seq = 0; while(recv_pirate_crew_raiding){ managed_recv_buffer::sptr buff = this->data_xport->get_recv_buff(); @@ -143,6 +142,15 @@ void usrp_e_impl::io_impl::recv_pirate_loop( * Helper Functions **********************************************************************/ void usrp_e_impl::io_init(void){ + //setup otw types + _send_otw_type.width = 16; + _send_otw_type.shift = 0; + _send_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; + + _recv_otw_type.width = 16; + _recv_otw_type.shift = 0; + _recv_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; + //setup rx data path _iface->poke32(UE_REG_CTRL_RX_NSAMPS_PER_PKT, get_max_recv_samps_per_packet()); _iface->poke32(UE_REG_CTRL_RX_NCHANNELS, 1); @@ -197,21 +205,25 @@ bool get_send_buffs( return buffs[0].get() != NULL; } +size_t usrp_e_impl::get_max_send_samps_per_packet(void) const{ + static const size_t hdr_size = 0 + + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + - sizeof(vrt::if_packet_info_t().cid) //no class id ever used + ; + size_t bpp = _io_impl->data_xport->get_send_frame_size() - hdr_size; + return bpp/_send_otw_type.get_sample_size(); +} + size_t usrp_e_impl::send( const std::vector &buffs, size_t num_samps, const tx_metadata_t &metadata, const io_type_t &io_type, send_mode_t send_mode, double timeout ){ - otw_type_t send_otw_type; - send_otw_type.width = 16; - send_otw_type.shift = 0; - send_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; - return vrt_packet_handler::send( _io_impl->packet_handler_send_state, //last state of the send handler buffs, num_samps, //buffer to fill metadata, send_mode, //samples metadata - io_type, send_otw_type, //input and output types to convert + io_type, _send_otw_type, //input and output types to convert MASTER_CLOCK_RATE, //master clock tick rate uhd::transport::vrt::if_hdr_pack_le, boost::bind(&get_send_buffs, _io_impl->data_xport, timeout, _1), @@ -222,21 +234,26 @@ size_t usrp_e_impl::send( /*********************************************************************** * Data Recv **********************************************************************/ +size_t usrp_e_impl::get_max_recv_samps_per_packet(void) const{ + static const size_t hdr_size = 0 + + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer + - sizeof(vrt::if_packet_info_t().cid) //no class id ever used + ; + size_t bpp = _io_impl->data_xport->get_recv_frame_size() - hdr_size; + return bpp/_recv_otw_type.get_sample_size(); +} + size_t usrp_e_impl::recv( const std::vector &buffs, size_t num_samps, rx_metadata_t &metadata, const io_type_t &io_type, recv_mode_t recv_mode, double timeout ){ - otw_type_t recv_otw_type; - recv_otw_type.width = 16; - recv_otw_type.shift = 0; - recv_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; - return vrt_packet_handler::recv( _io_impl->packet_handler_recv_state, //last state of the recv handler buffs, num_samps, //buffer to fill metadata, recv_mode, //samples metadata - io_type, recv_otw_type, //input and output types to convert + io_type, _recv_otw_type, //input and output types to convert MASTER_CLOCK_RATE, //master clock tick rate uhd::transport::vrt::if_hdr_unpack_le, boost::bind(&usrp_e_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout), diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 49912050e..95d80fed5 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -85,8 +86,8 @@ public: size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t, double); size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, double); bool recv_async_msg(uhd::async_metadata_t &, double); - size_t get_max_send_samps_per_packet(void) const{return 503;} - size_t get_max_recv_samps_per_packet(void) const{return 503;} + size_t get_max_send_samps_per_packet(void) const; + size_t get_max_recv_samps_per_packet(void) const; private: //interface to ioctls and file descriptor @@ -97,6 +98,7 @@ private: //handle io stuff UHD_PIMPL_DECL(io_impl) _io_impl; + uhd::otw_type_t _send_otw_type, _recv_otw_type; void io_init(void); void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd); void handle_overrun(size_t); diff --git a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp index 4e10bcc48..bc18c490b 100644 --- a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp @@ -134,6 +134,10 @@ public: return _rb_size.num_rx_frames; } + size_t get_recv_frame_size(void) const{ + return _frame_size; + } + managed_send_buffer::sptr get_send_buff(double timeout){ if (fp_verbose) std::cout << "get_send_buff: " << _send_index << std::endl; @@ -166,6 +170,10 @@ public: return _rb_size.num_tx_frames; } + size_t get_send_frame_size(void) const{ + return _frame_size; + } + private: void release(ring_buffer_info *info){ -- cgit v1.2.3 From c830a0d2c491fb61c2b401db94ed0a147bca4a24 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 13 Oct 2010 23:00:20 +0000 Subject: USRP-E: updated the loopback tester for length checking. Checks lengths by pushing them into a circular buffer and popping them out. Protected by mutex so it doesn't go chewing on itself. --- host/utils/usrp-e-loopback.c | 47 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) (limited to 'host') diff --git a/host/utils/usrp-e-loopback.c b/host/utils/usrp-e-loopback.c index f400fe0be..454d81ba7 100644 --- a/host/utils/usrp-e-loopback.c +++ b/host/utils/usrp-e-loopback.c @@ -8,7 +8,7 @@ #include #include -// max length #define PKT_DATA_LENGTH 1016 +#define MAX_PACKET_SIZE 1016 static int packet_data_length; static int error; @@ -19,6 +19,30 @@ struct pkt { short data[]; }; +static int length_array[2048]; +static int length_array_tail = 0; +static int length_array_head = 0; + +pthread_mutex_t length_array_mutex; //gotta lock the index to keep it from getting hosed + +//yes this is a circular buffer that does not check empty +//no i don't want to hear about it +void push_length_array(int length) { + pthread_mutex_lock(&length_array_mutex); + if(length_array_tail > 2047) length_array_tail = 0; + length_array[length_array_tail++] = length; + pthread_mutex_unlock(&length_array_mutex); +} + +int pop_length_array(void) { + int retval; + pthread_mutex_lock(&length_array_mutex); + if(length_array_head > 2047) length_array_head = 0; + retval = length_array[length_array_head++]; + pthread_mutex_unlock(&length_array_mutex); + return retval; +} + static int fp; static int calc_checksum(struct pkt *p) @@ -29,10 +53,10 @@ static int calc_checksum(struct pkt *p) sum = 0; for (i=0; i < p->len; i++) - sum += p->data[i]; + sum ^= p->data[i]; - sum += p->seq_num; - sum += p->len; + sum ^= p->seq_num; + sum ^= p->len; return sum; } @@ -44,6 +68,7 @@ static void *read_thread(void *threadid) struct pkt *p; unsigned long bytes_transfered, elapsed_seconds; struct timeval start_time, finish_time; + int expected_count; printf("Greetings from the reading thread!\n"); @@ -78,6 +103,11 @@ static void *read_thread(void *threadid) error = 1; } + expected_count = pop_length_array()*2+12; + if(cnt != expected_count) { + printf("Received %d bytes, expected %d\n", cnt, expected_count); + } + prev_seq_num = p->seq_num; if (calc_checksum(p) != p->checksum) { @@ -131,7 +161,9 @@ static void *write_thread(void *threadid) if (packet_data_length > 0) p->len = packet_data_length; else - p->len = (random() & 0x1ff) + (1004 - 512); + p->len = (random()<<1 & 0x1ff) + (1004 - 512); + + push_length_array(p->len); p->checksum = calc_checksum(p); @@ -146,6 +178,7 @@ static void *write_thread(void *threadid) int main(int argc, char *argv[]) { pthread_t tx, rx; + pthread_mutex_init(&length_array_mutex, 0); long int t; struct sched_param s = { .sched_priority = 1 @@ -159,6 +192,10 @@ int main(int argc, char *argv[]) } packet_data_length = atoi(argv[1]); + if(packet_data_length > MAX_PACKET_SIZE) { + printf("Packet size must be smaller than %i\n", MAX_PACKET_SIZE); + exit(-1); + } fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); -- cgit v1.2.3 From 0582d9f5bc4793aa0ce609933e8cc108255903e8 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 14 Oct 2010 16:52:48 +0000 Subject: USRP-E: brought loopback test updates in from usrp_e branch. --- host/utils/usrp-e-loopback.c | 47 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) (limited to 'host') diff --git a/host/utils/usrp-e-loopback.c b/host/utils/usrp-e-loopback.c index f400fe0be..454d81ba7 100644 --- a/host/utils/usrp-e-loopback.c +++ b/host/utils/usrp-e-loopback.c @@ -8,7 +8,7 @@ #include #include -// max length #define PKT_DATA_LENGTH 1016 +#define MAX_PACKET_SIZE 1016 static int packet_data_length; static int error; @@ -19,6 +19,30 @@ struct pkt { short data[]; }; +static int length_array[2048]; +static int length_array_tail = 0; +static int length_array_head = 0; + +pthread_mutex_t length_array_mutex; //gotta lock the index to keep it from getting hosed + +//yes this is a circular buffer that does not check empty +//no i don't want to hear about it +void push_length_array(int length) { + pthread_mutex_lock(&length_array_mutex); + if(length_array_tail > 2047) length_array_tail = 0; + length_array[length_array_tail++] = length; + pthread_mutex_unlock(&length_array_mutex); +} + +int pop_length_array(void) { + int retval; + pthread_mutex_lock(&length_array_mutex); + if(length_array_head > 2047) length_array_head = 0; + retval = length_array[length_array_head++]; + pthread_mutex_unlock(&length_array_mutex); + return retval; +} + static int fp; static int calc_checksum(struct pkt *p) @@ -29,10 +53,10 @@ static int calc_checksum(struct pkt *p) sum = 0; for (i=0; i < p->len; i++) - sum += p->data[i]; + sum ^= p->data[i]; - sum += p->seq_num; - sum += p->len; + sum ^= p->seq_num; + sum ^= p->len; return sum; } @@ -44,6 +68,7 @@ static void *read_thread(void *threadid) struct pkt *p; unsigned long bytes_transfered, elapsed_seconds; struct timeval start_time, finish_time; + int expected_count; printf("Greetings from the reading thread!\n"); @@ -78,6 +103,11 @@ static void *read_thread(void *threadid) error = 1; } + expected_count = pop_length_array()*2+12; + if(cnt != expected_count) { + printf("Received %d bytes, expected %d\n", cnt, expected_count); + } + prev_seq_num = p->seq_num; if (calc_checksum(p) != p->checksum) { @@ -131,7 +161,9 @@ static void *write_thread(void *threadid) if (packet_data_length > 0) p->len = packet_data_length; else - p->len = (random() & 0x1ff) + (1004 - 512); + p->len = (random()<<1 & 0x1ff) + (1004 - 512); + + push_length_array(p->len); p->checksum = calc_checksum(p); @@ -146,6 +178,7 @@ static void *write_thread(void *threadid) int main(int argc, char *argv[]) { pthread_t tx, rx; + pthread_mutex_init(&length_array_mutex, 0); long int t; struct sched_param s = { .sched_priority = 1 @@ -159,6 +192,10 @@ int main(int argc, char *argv[]) } packet_data_length = atoi(argv[1]); + if(packet_data_length > MAX_PACKET_SIZE) { + printf("Packet size must be smaller than %i\n", MAX_PACKET_SIZE); + exit(-1); + } fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); -- cgit v1.2.3 From 9348c2764dbbdf01e34a3ec7b5c8e74964b355e0 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 14 Oct 2010 21:41:14 -0400 Subject: usrp_e: back out dynamic send/recv samples calculation. --- host/lib/usrp/usrp_e/io_impl.cpp | 6 +++++- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 406b7269f..d89a7db07 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -37,7 +37,7 @@ zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface); **********************************************************************/ static const size_t tx_async_report_sid = 1; static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET; -static const bool recv_debug = true; +static const bool recv_debug = false; /*********************************************************************** * io impl details (internal to this file) @@ -205,6 +205,7 @@ bool get_send_buffs( return buffs[0].get() != NULL; } +#if 0 size_t usrp_e_impl::get_max_send_samps_per_packet(void) const{ static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) @@ -213,6 +214,7 @@ size_t usrp_e_impl::get_max_send_samps_per_packet(void) const{ size_t bpp = _io_impl->data_xport->get_send_frame_size() - hdr_size; return bpp/_send_otw_type.get_sample_size(); } +#endif size_t usrp_e_impl::send( const std::vector &buffs, size_t num_samps, @@ -234,6 +236,7 @@ size_t usrp_e_impl::send( /*********************************************************************** * Data Recv **********************************************************************/ +#if 0 size_t usrp_e_impl::get_max_recv_samps_per_packet(void) const{ static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) @@ -243,6 +246,7 @@ size_t usrp_e_impl::get_max_recv_samps_per_packet(void) const{ size_t bpp = _io_impl->data_xport->get_recv_frame_size() - hdr_size; return bpp/_recv_otw_type.get_sample_size(); } +#endif size_t usrp_e_impl::recv( const std::vector &buffs, size_t num_samps, diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 95d80fed5..9799cd645 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -86,8 +86,13 @@ public: size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t, double); size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, double); bool recv_async_msg(uhd::async_metadata_t &, double); +#if 0 size_t get_max_send_samps_per_packet(void) const; size_t get_max_recv_samps_per_packet(void) const; +#else + size_t get_max_send_samps_per_packet(void) const{return 503;} + size_t get_max_recv_samps_per_packet(void) const{return 503;} +#endif private: //interface to ioctls and file descriptor -- cgit v1.2.3 From 6b203950d9583ab882628311402e26cf40838aa0 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 14 Oct 2010 21:42:10 -0400 Subject: usrp_e: Disable debug. --- host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp index bc18c490b..274bb043e 100644 --- a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp @@ -29,8 +29,8 @@ using namespace uhd; using namespace uhd::transport; -static const bool fp_verbose = true; //fast-path verbose -static const bool sp_verbose = true; //slow-path verbose +static const bool fp_verbose = false; //fast-path verbose +static const bool sp_verbose = false; //slow-path verbose static const size_t poll_breakout = 10; //how many poll timeouts constitute a full timeout /*********************************************************************** -- cgit v1.2.3 From c347ad973f4b51b00f66d7422cd03e8790de9be3 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 21 Oct 2010 13:57:50 -0400 Subject: usrp_e: Do not install main_test anymore. --- host/test/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) (limited to 'host') diff --git a/host/test/CMakeLists.txt b/host/test/CMakeLists.txt index 59a550f98..2cc987f0c 100644 --- a/host/test/CMakeLists.txt +++ b/host/test/CMakeLists.txt @@ -52,6 +52,5 @@ ENDFOREACH(test_source) ADD_LIBRARY(module_test MODULE module_test.cpp) INSTALL(TARGETS - main_test RUNTIME DESTINATION ${PKG_DATA_DIR}/tests ) -- cgit v1.2.3 From 3dc06cddaf0a0cf32f76be7077d1427ff4b71a7e Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 14 Oct 2010 14:47:34 -0400 Subject: usrp-e: Add example that reads data from uhd and sends it over a udp socket. --- host/examples/CMakeLists.txt | 4 ++ host/examples/rx_to_udp.cpp | 167 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 host/examples/rx_to_udp.cpp (limited to 'host') diff --git a/host/examples/CMakeLists.txt b/host/examples/CMakeLists.txt index fb7777d42..3b36f3e71 100644 --- a/host/examples/CMakeLists.txt +++ b/host/examples/CMakeLists.txt @@ -25,6 +25,9 @@ TARGET_LINK_LIBRARIES(rx_timed_samples uhd) ADD_EXECUTABLE(rx_to_file rx_to_file.cpp) TARGET_LINK_LIBRARIES(rx_to_file uhd) +ADD_EXECUTABLE(rx_to_udp rx_to_udp.cpp) +TARGET_LINK_LIBRARIES(rx_to_udp uhd) + ADD_EXECUTABLE(test_async_messages test_async_messages.cpp) TARGET_LINK_LIBRARIES(test_async_messages uhd) @@ -48,6 +51,7 @@ INSTALL(TARGETS tx_timed_samples tx_from_file rx_to_file + rx_to_udp tx_waveforms RUNTIME DESTINATION ${PKG_DATA_DIR}/examples ) diff --git a/host/examples/rx_to_udp.cpp b/host/examples/rx_to_udp.cpp new file mode 100644 index 000000000..34b278599 --- /dev/null +++ b/host/examples/rx_to_udp.cpp @@ -0,0 +1,167 @@ +// +// Copyright 2010 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 . +// + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sys/types.h" +#include "sys/socket.h" +#include "arpa/inet.h" + +namespace po = boost::program_options; + + +int UHD_SAFE_MAIN(int argc, char *argv[]){ + uhd::set_thread_priority_safe(); + + //variables to be set by po + std::string args; + time_t seconds_in_future; + size_t total_num_samps; + double rx_rate, freq; + short srv_port; + std::string srv_ip; + + //setup the program options + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("args", po::value(&args)->default_value(""), "simple uhd device address args") + ("secs", po::value(&seconds_in_future)->default_value(3), "number of seconds in the future to receive") + ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to receive") + ("rxrate", po::value(&rx_rate)->default_value(100e6/16), "rate of incoming samples") + ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") + ("port", po::value(&srv_port)->default_value(7124), "server port") + ("ip", po::value(&srv_ip)->default_value("192.168.1.10"), "server ip") + ("dilv", "specify to disable inner-loop verbose") + ; + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")){ + std::cout << boost::format("UHD RX Timed Samples %s") % desc << std::endl; + return ~0; + } + + bool verbose = vm.count("dilv") == 0; + + //create a usrp device + std::cout << std::endl; + std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; + uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args); + uhd::device::sptr dev = sdev->get_device(); + std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; + + //set properties on the device + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate/1e6) << std::endl; + sdev->set_rx_rate(rx_rate); + std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl; + std::cout << boost::format("Setting device timestamp to 0...") << std::endl; + sdev->set_rx_freq(freq); + sdev->set_time_now(uhd::time_spec_t(0.0)); + + uhd::gain_range_t rx_gain = sdev->get_rx_gain_range(); + std::cout << "Setting RX Gain to: " << rx_gain.max << std::endl; + sdev->set_rx_gain(rx_gain.max); + + sleep(1); + std::cout << "LO Locked = " << sdev->get_rx_lo_locked() << std::endl; + + //setup streaming + std::cout << std::endl; + std::cout << boost::format( + "Begin streaming %u samples, %d seconds in the future..." + ) % total_num_samps % seconds_in_future << std::endl; + uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = total_num_samps; + stream_cmd.stream_now = false; + stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); + sdev->issue_stream_cmd(stream_cmd); + + //loop until total number of samples reached + size_t num_acc_samps = 0; //number of accumulated samples + uhd::rx_metadata_t md; + std::vector > buff(368); + std::ofstream outfile("out.dat", std::ofstream::binary); + + int s; + struct sockaddr_in si_other; + if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { + std::cout << "Failid to open socket." << std::endl; + return -1; + } + + memset((char *) &si_other, 0, sizeof(si_other)); + si_other.sin_family = AF_INET; + si_other.sin_port = htons(srv_port); + if (inet_aton(srv_ip.c_str(), &si_other.sin_addr) == 0) { + std::cout << "Bad inet addr: " << srv_ip << std::endl; + return -1; + } + + while(num_acc_samps < total_num_samps){ + size_t num_rx_samps = dev->recv( + &buff.front(), buff.size(), md, + uhd::io_type_t::COMPLEX_FLOAT32, + uhd::device::RECV_MODE_ONE_PACKET + ); + + //handle the error codes + switch(md.error_code){ + case uhd::rx_metadata_t::ERROR_CODE_NONE: + break; + + case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: + if (num_acc_samps == 0) continue; + std::cout << boost::format( + "Got timeout before all samples received, possible packet loss, exiting loop..." + ) << std::endl; + goto done_loop; + + default: + std::cout << boost::format( + "Got error code 0x%x, exiting loop..." + ) % md.error_code << std::endl; + goto done_loop; + } + +// outfile.write((const char*)&buff[0], num_rx_samps * sizeof(std::complex)); + if (sendto(s, (const char *)&buff[0], num_rx_samps * sizeof(std::complex), 0 , (const sockaddr *)&si_other, sizeof(si_other)) == -1) + std::cout << "Sendto failed." << std::endl; + + if(verbose) std::cout << boost::format( + "Got packet: %u samples, %u full secs, %f frac secs" + ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl; + + num_acc_samps += num_rx_samps; + } done_loop: + + outfile.close(); + + //finished + std::cout << std::endl << "Done!" << std::endl << std::endl; + + return 0; +} -- cgit v1.2.3 From db0e3e574e9058ad51cacea91ccc42f0baed95fa Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 21 Oct 2010 22:26:53 -0400 Subject: usrp_e: Add driver compatibility ioctl to header file. --- host/apps/omap_debug/usrp_e.h | 3 +++ host/include/linux/usrp_e.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'host') diff --git a/host/apps/omap_debug/usrp_e.h b/host/apps/omap_debug/usrp_e.h index fd38027d4..f96706c4a 100644 --- a/host/apps/omap_debug/usrp_e.h +++ b/host/apps/omap_debug/usrp_e.h @@ -41,6 +41,9 @@ struct usrp_e_ctl32 { #define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG #define UE_SPI_LATCH_RISE 0 #define UE_SPI_LATCH_FALL UE_SPI_CTRL_RXNEG +#define USRP_E_GET_COMPAT_NUMBER _IO(USRP_E_IOC_MAGIC, 0x28) + +#define USRP_E_COMPAT_NUMBER 1 struct usrp_e_spi { __u8 readback; diff --git a/host/include/linux/usrp_e.h b/host/include/linux/usrp_e.h index cb62d940d..4c6a5dd89 100644 --- a/host/include/linux/usrp_e.h +++ b/host/include/linux/usrp_e.h @@ -65,6 +65,9 @@ struct usrp_e_i2c { #define USRP_E_I2C_READ _IOWR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) #define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) #define USRP_E_GET_RB_INFO _IOR(USRP_E_IOC_MAGIC, 0x27, struct usrp_e_ring_buffer_size_t) +#define USRP_E_GET_COMPAT_NUMBER _IO(USRP_E_IOC_MAGIC, 0x28) + +#define USRP_E_COMPAT_NUMBER 1 /* Flag defines */ #define RB_USER (1<<0) -- cgit v1.2.3 From fa689c7202a0cab6bf0debc3524f1f46636a7ba0 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 27 Oct 2010 08:31:01 -0700 Subject: usrp_e: fix to get compiling with next branch --- host/lib/usrp/usrp_e/dboard_impl.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index d4a27cb72..f2840dcfc 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -87,6 +87,7 @@ void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ case DBOARD_PROP_GAIN_GROUP: val = make_gain_group( + _rx_db_eeprom.id, _dboard_manager->get_rx_subdev(key.name), _rx_codec_proxy->get_link(), GAIN_GROUP_POLICY_RX @@ -145,6 +146,7 @@ void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ case DBOARD_PROP_GAIN_GROUP: val = make_gain_group( + _tx_db_eeprom.id, _dboard_manager->get_tx_subdev(key.name), _tx_codec_proxy->get_link(), GAIN_GROUP_POLICY_TX -- cgit v1.2.3 From fa7704be20005a705efdc96aa785d80911638107 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 27 Oct 2010 13:10:48 -0700 Subject: usrp-e: implemented fpga loading and compat checking --- host/examples/rx_to_file.cpp | 8 ++-- host/examples/rx_to_udp.cpp | 8 ++-- host/lib/usrp/usrp_e/fpga-downloader.cc | 30 ++++++++------ host/lib/usrp/usrp_e/usrp_e_impl.cpp | 69 ++++++++++++++++++++++++++++++--- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 4 +- host/lib/usrp/usrp_e/usrp_e_regs.hpp | 2 +- 6 files changed, 94 insertions(+), 27 deletions(-) (limited to 'host') diff --git a/host/examples/rx_to_file.cpp b/host/examples/rx_to_file.cpp index 79d3e9d8b..f08f7cee3 100644 --- a/host/examples/rx_to_file.cpp +++ b/host/examples/rx_to_file.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include @@ -40,7 +40,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") - ("args", po::value(&args)->default_value(""), "simple uhd device address args") + ("args", po::value(&args)->default_value(""), "single uhd device address args") ("secs", po::value(&seconds_in_future)->default_value(3), "number of seconds in the future to receive") ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to receive") ("rxrate", po::value(&rx_rate)->default_value(100e6/16), "rate of incoming samples") @@ -53,7 +53,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //print the help message if (vm.count("help")){ - std::cout << boost::format("UHD RX Timed Samples %s") % desc << std::endl; + std::cout << boost::format("UHD RX to File %s") % desc << std::endl; return ~0; } @@ -62,7 +62,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //create a usrp device std::cout << std::endl; std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; - uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args); + uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); uhd::device::sptr dev = sdev->get_device(); std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; diff --git a/host/examples/rx_to_udp.cpp b/host/examples/rx_to_udp.cpp index 34b278599..c8b3d506b 100644 --- a/host/examples/rx_to_udp.cpp +++ b/host/examples/rx_to_udp.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include @@ -46,7 +46,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") - ("args", po::value(&args)->default_value(""), "simple uhd device address args") + ("args", po::value(&args)->default_value(""), "single uhd device address args") ("secs", po::value(&seconds_in_future)->default_value(3), "number of seconds in the future to receive") ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to receive") ("rxrate", po::value(&rx_rate)->default_value(100e6/16), "rate of incoming samples") @@ -61,7 +61,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //print the help message if (vm.count("help")){ - std::cout << boost::format("UHD RX Timed Samples %s") % desc << std::endl; + std::cout << boost::format("UHD RX to UDP %s") % desc << std::endl; return ~0; } @@ -70,7 +70,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //create a usrp device std::cout << std::endl; std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; - uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args); + uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); uhd::device::sptr dev = sdev->get_device(); std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; diff --git a/host/lib/usrp/usrp_e/fpga-downloader.cc b/host/lib/usrp/usrp_e/fpga-downloader.cc index ff8671e98..b0d56e856 100644 --- a/host/lib/usrp/usrp_e/fpga-downloader.cc +++ b/host/lib/usrp/usrp_e/fpga-downloader.cc @@ -15,11 +15,14 @@ // along with this program. If not, see . // +#include + #include #include #include #include #include +#include #include #include @@ -82,8 +85,9 @@ gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction) std::fstream export_file; 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; + if (not export_file.is_open()) throw std::runtime_error( + "Failed to open gpio export file." + ); export_file << gpio_num << std::endl; @@ -92,15 +96,17 @@ gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction) std::fstream direction_file; std::string direction_file_name; - direction_file_name = base_path.str() + "/direction"; + if (gpio_num != 114) { + 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; + 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; @@ -251,11 +257,11 @@ void usrp_e_load_fpga(const std::string &bin_file){ gpio gpio_init_b(INIT_B, IN); gpio gpio_done (DONE, IN); - std::cout << "FPGA config file: " << bin_file << std::endl; + std::cout << "Loading FPGA image: " << bin_file << "... " << std::flush; prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); - std::cout << "Done = " << gpio_done.get_value() << std::endl; + std::cout << "done = " << gpio_done.get_value() << std::endl; send_file_to_fpga(bin_file, gpio_init_b, gpio_done); } diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 5c0e1dbb0..0a7295ff9 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -16,13 +16,17 @@ // #include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" #include #include #include #include +#include #include #include +#include #include +#include using namespace uhd; using namespace uhd::usrp; @@ -66,7 +70,64 @@ static device_addrs_t usrp_e_find(const device_addr_t &hint){ * Make **********************************************************************/ static device::sptr usrp_e_make(const device_addr_t &device_addr){ - return device::sptr(new usrp_e_impl(device_addr["node"])); + + //The fpga is loaded when: + // 1) The compatibility number matches. + // 2) The hash in the hash-file matches. + + //setup the main interface into fpga + std::string node = device_addr["node"]; + std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; + usrp_e_iface::sptr iface = usrp_e_iface::make(node); + + //------------------------------------------------------------------ + //-- Handle the FPGA loading... + //-- The image can be confimed as already loaded when: + //-- 1) The compatibility number matches. + //-- 2) The hash in the hash-file matches. + //------------------------------------------------------------------ + + //extract the fpga path for usrp-e + std::string usrp_e_fpga_image = find_image_path( + device_addr.has_key("fpga")? device_addr["fpga"] : "usrp_e100_fpga.bin" + ); + + //calculate a hash of the fpga file + size_t fpga_hash = 0; + { + std::ifstream file(usrp_e_fpga_image.c_str()); + if (not file.good()) throw std::runtime_error( + "cannot open fpga file for read: " + usrp_e_fpga_image + ); + do{ + boost::hash_combine(fpga_hash, file.get()); + } while (file.good()); + file.close(); + } + + //read the compatibility number + boost::uint16_t fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); + + //read the hash in the hash-file + size_t loaded_hash = 0; + try{std::ifstream(hash_file_path) >> loaded_hash;}catch(...){} + + //if not loaded: load the fpga image and write the hash-file + if (fpga_compat_num != USRP_E_COMPAT_NUM or loaded_hash != fpga_hash){ + usrp_e_load_fpga(usrp_e_fpga_image); + try{std::ofstream(hash_file_path) << fpga_hash;}catch(...){} + } + + //check that the compatibility is correct + fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); + if (fpga_compat_num != USRP_E_COMPAT_NUM){ + throw std::runtime_error(str(boost::format( + "Expected fpga compatibility number 0x%x, but got 0x%x:\n" + "The fpga build is not compatible with the host code build." + ) % USRP_E_COMPAT_NUM % fpga_compat_num)); + } + + return device::sptr(new usrp_e_impl(iface)); } UHD_STATIC_BLOCK(register_usrp_e_device){ @@ -76,11 +137,9 @@ UHD_STATIC_BLOCK(register_usrp_e_device){ /*********************************************************************** * Structors **********************************************************************/ -usrp_e_impl::usrp_e_impl(const std::string &node){ - std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; +usrp_e_impl::usrp_e_impl(usrp_e_iface::sptr iface): _iface(iface){ - //setup various interfaces into hardware - _iface = usrp_e_iface::make(node); + //setup interfaces into hardware _clock_ctrl = usrp_e_clock_ctrl::make(_iface); _codec_ctrl = usrp_e_codec_ctrl::make(_iface); diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 9799cd645..421a9623d 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -31,6 +31,8 @@ #define INCLUDED_USRP_E_IMPL_HPP static const double MASTER_CLOCK_RATE = 64e6; //TODO get from clock control +static const char *hash_file_path = "/tmp/usrp_e100_hash"; +static const boost::uint16_t USRP_E_COMPAT_NUM = 0x02; //! load an fpga image from a bin file into the usrp-e fpga extern void usrp_e_load_fpga(const std::string &bin_file); @@ -79,7 +81,7 @@ private: class usrp_e_impl : public uhd::device{ public: //structors - usrp_e_impl(const std::string &node); + usrp_e_impl(usrp_e_iface::sptr); ~usrp_e_impl(void); //the io interface diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp index a4f42093e..f74358f00 100644 --- a/host/lib/usrp/usrp_e/usrp_e_regs.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -30,7 +30,7 @@ #define UE_REG_MISC_CGEN_ST UE_REG_MISC_BASE + 6 #define UE_REG_MISC_TEST UE_REG_MISC_BASE + 8 #define UE_REG_MISC_RX_LEN UE_REG_MISC_BASE + 10 -#define UE_REG_MISC_TX_LEN UE_REG_MISC_BASE + 12 +#define UE_REG_MISC_COMPAT UE_REG_MISC_BASE + 12 ///////////////////////////////////////////////////// // Slave 1 -- UART -- cgit v1.2.3 From 0208b28e58e3719dc4dfb8df73fe5ae49e4a6306 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 27 Oct 2010 15:57:35 -0700 Subject: usrp-e: use clock control to get clock rate, removed temporary constant --- host/lib/usrp/usrp_e/dsp_impl.cpp | 16 ++++++++-------- host/lib/usrp/usrp_e/io_impl.cpp | 17 ++++++++--------- host/lib/usrp/usrp_e/mboard_impl.cpp | 2 +- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 5 +---- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 5 ----- 5 files changed, 18 insertions(+), 27 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp index 9312bb603..97f173c1a 100644 --- a/host/lib/usrp/usrp_e/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -65,11 +65,11 @@ void usrp_e_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){ return; case DSP_PROP_CODEC_RATE: - val = MASTER_CLOCK_RATE; + val = _clock_ctrl->get_fpga_clock_rate(); return; case DSP_PROP_HOST_RATE: - val = MASTER_CLOCK_RATE/_ddc_decim; + val = _clock_ctrl->get_fpga_clock_rate()/_ddc_decim; return; default: UHD_THROW_PROP_GET_ERROR(); @@ -87,7 +87,7 @@ void usrp_e_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ case DSP_PROP_FREQ_SHIFT:{ double new_freq = val.as(); _iface->poke32(UE_REG_DSP_RX_FREQ, - dsp_type1::calc_cordic_word_and_update(new_freq, MASTER_CLOCK_RATE) + dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate()) ); _ddc_freq = new_freq; //shadow } @@ -95,7 +95,7 @@ void usrp_e_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ case DSP_PROP_HOST_RATE:{ //set the decimation - _ddc_decim = rint(MASTER_CLOCK_RATE/val.as()); + _ddc_decim = rint(_clock_ctrl->get_fpga_clock_rate()/val.as()); _iface->poke32(UE_REG_DSP_RX_DECIM_RATE, dsp_type1::calc_cic_filter_word(_ddc_decim)); //set the scaling @@ -148,11 +148,11 @@ void usrp_e_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){ return; case DSP_PROP_CODEC_RATE: - val = MASTER_CLOCK_RATE; + val = _clock_ctrl->get_fpga_clock_rate(); return; case DSP_PROP_HOST_RATE: - val = MASTER_CLOCK_RATE/_duc_interp; + val = _clock_ctrl->get_fpga_clock_rate()/_duc_interp; return; default: UHD_THROW_PROP_GET_ERROR(); @@ -170,14 +170,14 @@ void usrp_e_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){ case DSP_PROP_FREQ_SHIFT:{ double new_freq = val.as(); _iface->poke32(UE_REG_DSP_TX_FREQ, - dsp_type1::calc_cordic_word_and_update(new_freq, MASTER_CLOCK_RATE) + dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate()) ); _duc_freq = new_freq; //shadow } return; case DSP_PROP_HOST_RATE:{ - _duc_interp = rint(MASTER_CLOCK_RATE/val.as()); + _duc_interp = rint(_clock_ctrl->get_fpga_clock_rate()/val.as()); //set the interpolation _iface->poke32(UE_REG_DSP_TX_INTERP_RATE, dsp_type1::calc_cic_filter_word(_duc_interp)); diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index d89a7db07..9996e7172 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -73,7 +73,7 @@ struct usrp_e_impl::io_impl{ } //a pirate's life is the life for me! - void recv_pirate_loop(); + void recv_pirate_loop(usrp_e_clock_ctrl::sptr); typedef bounded_buffer recv_booty_type; recv_booty_type::sptr recv_pirate_booty; bounded_buffer::sptr async_msg_fifo; @@ -86,9 +86,8 @@ struct usrp_e_impl::io_impl{ * - while raiding, loot for recv buffers * - put booty into the alignment buffer **********************************************************************/ -void usrp_e_impl::io_impl::recv_pirate_loop( - -){ +void usrp_e_impl::io_impl::recv_pirate_loop(usrp_e_clock_ctrl::sptr clock_ctrl) +{ set_thread_priority_safe(); recv_pirate_crew_raiding = true; @@ -119,7 +118,7 @@ void usrp_e_impl::io_impl::recv_pirate_loop( metadata.channel = 0; metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf; metadata.time_spec = time_spec_t( - time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), MASTER_CLOCK_RATE + time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), clock_ctrl->get_fpga_clock_rate() ); metadata.event_code = vrt_packet_handler::get_context_code(vrt_hdr, if_packet_info); @@ -172,7 +171,7 @@ void usrp_e_impl::io_init(void){ //spawn a pirate, yarrr! _io_impl->recv_pirate_crew.create_thread(boost::bind( - &usrp_e_impl::io_impl::recv_pirate_loop, _io_impl.get() + &usrp_e_impl::io_impl::recv_pirate_loop, _io_impl.get(), _clock_ctrl )); } @@ -182,7 +181,7 @@ void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ stream_cmd, get_max_recv_samps_per_packet() )); _iface->poke32(UE_REG_CTRL_RX_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); - _iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_tick_count(MASTER_CLOCK_RATE)); + _iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_tick_count(_clock_ctrl->get_fpga_clock_rate())); } void usrp_e_impl::handle_overrun(size_t){ @@ -226,7 +225,7 @@ size_t usrp_e_impl::send( buffs, num_samps, //buffer to fill metadata, send_mode, //samples metadata io_type, _send_otw_type, //input and output types to convert - MASTER_CLOCK_RATE, //master clock tick rate + _clock_ctrl->get_fpga_clock_rate(), //master clock tick rate uhd::transport::vrt::if_hdr_pack_le, boost::bind(&get_send_buffs, _io_impl->data_xport, timeout, _1), get_max_send_samps_per_packet() @@ -258,7 +257,7 @@ size_t usrp_e_impl::recv( buffs, num_samps, //buffer to fill metadata, recv_mode, //samples metadata io_type, _recv_otw_type, //input and output types to convert - MASTER_CLOCK_RATE, //master clock tick rate + _clock_ctrl->get_fpga_clock_rate(), //master clock tick rate uhd::transport::vrt::if_hdr_unpack_le, boost::bind(&usrp_e_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout), boost::bind(&usrp_e_impl::handle_overrun, this, _1) diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index 3d4cef069..f0118aa4b 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -125,7 +125,7 @@ void usrp_e_impl::mboard_set(const wax::obj &key, const wax::obj &val){ case MBOARD_PROP_TIME_NOW: case MBOARD_PROP_TIME_NEXT_PPS:{ time_spec_t time_spec = val.as(); - _iface->poke32(UE_REG_TIME64_TICKS, time_spec.get_tick_count(MASTER_CLOCK_RATE)); + _iface->poke32(UE_REG_TIME64_TICKS, time_spec.get_tick_count(_clock_ctrl->get_fpga_clock_rate())); boost::uint32_t imm_flags = (key.as() == MBOARD_PROP_TIME_NOW)? 1 : 0; _iface->poke32(UE_REG_TIME64_IMM, imm_flags); _iface->poke32(UE_REG_TIME64_SECS, time_spec.get_full_secs()); diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 0a7295ff9..1b71c0a52 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -71,10 +71,6 @@ static device_addrs_t usrp_e_find(const device_addr_t &hint){ **********************************************************************/ static device::sptr usrp_e_make(const device_addr_t &device_addr){ - //The fpga is loaded when: - // 1) The compatibility number matches. - // 2) The hash in the hash-file matches. - //setup the main interface into fpga std::string node = device_addr["node"]; std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; @@ -86,6 +82,7 @@ static device::sptr usrp_e_make(const device_addr_t &device_addr){ //-- 1) The compatibility number matches. //-- 2) The hash in the hash-file matches. //------------------------------------------------------------------ + static const char *hash_file_path = "/tmp/usrp_e100_hash"; //extract the fpga path for usrp-e std::string usrp_e_fpga_image = find_image_path( diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 421a9623d..e55b46b80 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -30,8 +30,6 @@ #ifndef INCLUDED_USRP_E_IMPL_HPP #define INCLUDED_USRP_E_IMPL_HPP -static const double MASTER_CLOCK_RATE = 64e6; //TODO get from clock control -static const char *hash_file_path = "/tmp/usrp_e100_hash"; static const boost::uint16_t USRP_E_COMPAT_NUM = 0x02; //! load an fpga image from a bin file into the usrp-e fpga @@ -100,9 +98,6 @@ private: //interface to ioctls and file descriptor usrp_e_iface::sptr _iface; - //FIXME fetch from ioctl? - static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); - //handle io stuff UHD_PIMPL_DECL(io_impl) _io_impl; uhd::otw_type_t _send_otw_type, _recv_otw_type; -- cgit v1.2.3 From a8fcdba5f76d08212835c5966be67248428fe9fa Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 4 Nov 2010 17:43:30 -0400 Subject: usrp_e: Comment out fpga loading until we unload module during load. --- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 1b71c0a52..cd39dbb07 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -111,7 +111,8 @@ static device::sptr usrp_e_make(const device_addr_t &device_addr){ //if not loaded: load the fpga image and write the hash-file if (fpga_compat_num != USRP_E_COMPAT_NUM or loaded_hash != fpga_hash){ - usrp_e_load_fpga(usrp_e_fpga_image); +// usrp_e_load_fpga(usrp_e_fpga_image); +std::cout << "Here is where I load the fpga" << std::endl; try{std::ofstream(hash_file_path) << fpga_hash;}catch(...){} } -- cgit v1.2.3 From bab641f4fdf954d6023904ca18c4bb4f6a362e47 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 4 Nov 2010 17:44:08 -0400 Subject: usrp_e : Fix register definitions for COMPAT and others. --- host/lib/usrp/usrp_e/usrp_e_regs.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp index f74358f00..8bfb08b6f 100644 --- a/host/lib/usrp/usrp_e/usrp_e_regs.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -30,7 +30,9 @@ #define UE_REG_MISC_CGEN_ST UE_REG_MISC_BASE + 6 #define UE_REG_MISC_TEST UE_REG_MISC_BASE + 8 #define UE_REG_MISC_RX_LEN UE_REG_MISC_BASE + 10 -#define UE_REG_MISC_COMPAT UE_REG_MISC_BASE + 12 +#define UE_REG_MISC_TX_LEN UE_REG_MISC_BASE + 12 +#define UE_REG_MISC_XFER_RATE UE_REG_MISC_BASE + 14 +#define UE_REG_MISC_COMPAT UE_REG_MISC_BASE + 16 ///////////////////////////////////////////////////// // Slave 1 -- UART -- cgit v1.2.3 From 7824f130bd1296c78f5b0311d1c253f0476c6cab Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 9 Nov 2010 18:13:25 -0800 Subject: usrp_e : Unload the module before loading the FPGA. Reload after the fpga is loaded. --- host/lib/usrp/usrp_e/fpga-downloader.cc | 6 ++++++ host/lib/usrp/usrp_e/usrp_e_impl.cpp | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/fpga-downloader.cc b/host/lib/usrp/usrp_e/fpga-downloader.cc index b0d56e856..5fd2c8dd0 100644 --- a/host/lib/usrp/usrp_e/fpga-downloader.cc +++ b/host/lib/usrp/usrp_e/fpga-downloader.cc @@ -259,9 +259,15 @@ void usrp_e_load_fpga(const std::string &bin_file){ std::cout << "Loading FPGA image: " << bin_file << "... " << std::flush; + system("/sbin/rmmod usrp_e"); + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); std::cout << "done = " << gpio_done.get_value() << std::endl; send_file_to_fpga(bin_file, gpio_init_b, gpio_done); + + system("/sbin/modprobe usrp_e"); + } + diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index cd39dbb07..70cc399fb 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -111,8 +111,10 @@ static device::sptr usrp_e_make(const device_addr_t &device_addr){ //if not loaded: load the fpga image and write the hash-file if (fpga_compat_num != USRP_E_COMPAT_NUM or loaded_hash != fpga_hash){ -// usrp_e_load_fpga(usrp_e_fpga_image); -std::cout << "Here is where I load the fpga" << std::endl; + iface.reset(); + usrp_e_load_fpga(usrp_e_fpga_image); + std::cout << boost::format("re-Opening USRP-E on %s") % node << std::endl; + iface = usrp_e_iface::make(node); try{std::ofstream(hash_file_path) << fpga_hash;}catch(...){} } -- cgit v1.2.3 From 073518083f2c7044d4b0c16948a192c5623d0752 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 9 Nov 2010 18:38:27 -0800 Subject: usrp_e: use the transport to calculate the max spp (with a fix to init the xport first) --- host/lib/usrp/usrp_e/io_impl.cpp | 9 +++------ host/lib/usrp/usrp_e/usrp_e_impl.hpp | 5 ----- 2 files changed, 3 insertions(+), 11 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp index 9996e7172..e863944e8 100644 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ b/host/lib/usrp/usrp_e/io_impl.cpp @@ -150,6 +150,9 @@ void usrp_e_impl::io_init(void){ _recv_otw_type.shift = 0; _recv_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; + //setup before the registers (transport called to calculate max spp) + _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface)); + //setup rx data path _iface->poke32(UE_REG_CTRL_RX_NSAMPS_PER_PKT, get_max_recv_samps_per_packet()); _iface->poke32(UE_REG_CTRL_RX_NCHANNELS, 1); @@ -167,8 +170,6 @@ void usrp_e_impl::io_init(void){ _iface->poke32(UE_REG_CTRL_TX_REPORT_SID, tx_async_report_sid); _iface->poke32(UE_REG_CTRL_TX_POLICY, UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET); - _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface)); - //spawn a pirate, yarrr! _io_impl->recv_pirate_crew.create_thread(boost::bind( &usrp_e_impl::io_impl::recv_pirate_loop, _io_impl.get(), _clock_ctrl @@ -204,7 +205,6 @@ bool get_send_buffs( return buffs[0].get() != NULL; } -#if 0 size_t usrp_e_impl::get_max_send_samps_per_packet(void) const{ static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) @@ -213,7 +213,6 @@ size_t usrp_e_impl::get_max_send_samps_per_packet(void) const{ size_t bpp = _io_impl->data_xport->get_send_frame_size() - hdr_size; return bpp/_send_otw_type.get_sample_size(); } -#endif size_t usrp_e_impl::send( const std::vector &buffs, size_t num_samps, @@ -235,7 +234,6 @@ size_t usrp_e_impl::send( /*********************************************************************** * Data Recv **********************************************************************/ -#if 0 size_t usrp_e_impl::get_max_recv_samps_per_packet(void) const{ static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) @@ -245,7 +243,6 @@ size_t usrp_e_impl::get_max_recv_samps_per_packet(void) const{ size_t bpp = _io_impl->data_xport->get_recv_frame_size() - hdr_size; return bpp/_recv_otw_type.get_sample_size(); } -#endif size_t usrp_e_impl::recv( const std::vector &buffs, size_t num_samps, diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index e55b46b80..b5f21810d 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -86,13 +86,8 @@ public: size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t, double); size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, double); bool recv_async_msg(uhd::async_metadata_t &, double); -#if 0 size_t get_max_send_samps_per_packet(void) const; size_t get_max_recv_samps_per_packet(void) const; -#else - size_t get_max_send_samps_per_packet(void) const{return 503;} - size_t get_max_recv_samps_per_packet(void) const{return 503;} -#endif private: //interface to ioctls and file descriptor -- cgit v1.2.3 From 61d9cda7f64e10d8039bf7b6de5ca8068f11e5bb Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 9 Nov 2010 18:44:39 -0800 Subject: usrp-e: check the return code on system call, also removes warnings --- host/lib/usrp/usrp_e/fpga-downloader.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e/fpga-downloader.cc b/host/lib/usrp/usrp_e/fpga-downloader.cc index 5fd2c8dd0..4dc537919 100644 --- a/host/lib/usrp/usrp_e/fpga-downloader.cc +++ b/host/lib/usrp/usrp_e/fpga-downloader.cc @@ -16,6 +16,7 @@ // #include +#include #include #include @@ -259,7 +260,7 @@ void usrp_e_load_fpga(const std::string &bin_file){ std::cout << "Loading FPGA image: " << bin_file << "... " << std::flush; - system("/sbin/rmmod usrp_e"); + UHD_ASSERT_THROW(std::system("/sbin/rmmod usrp_e") == 0); prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); @@ -267,7 +268,7 @@ void usrp_e_load_fpga(const std::string &bin_file){ send_file_to_fpga(bin_file, gpio_init_b, gpio_done); - system("/sbin/modprobe usrp_e"); + UHD_ASSERT_THROW(std::system("/sbin/modprobe usrp_e") == 0); } -- cgit v1.2.3 From d33a6cab6646692e06ef34317f6c831ac9c91148 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 9 Nov 2010 18:48:54 -0800 Subject: usrp_e: renamed directory to usrp_e100 to reflect product name --- host/lib/usrp/CMakeLists.txt | 2 +- host/lib/usrp/usrp_e/CMakeLists.txt | 64 ----- host/lib/usrp/usrp_e/clock_ctrl.cpp | 237 ----------------- host/lib/usrp/usrp_e/clock_ctrl.hpp | 88 ------- host/lib/usrp/usrp_e/codec_ctrl.cpp | 296 --------------------- host/lib/usrp/usrp_e/codec_ctrl.hpp | 90 ------- host/lib/usrp/usrp_e/codec_impl.cpp | 149 ----------- host/lib/usrp/usrp_e/dboard_iface.cpp | 298 ---------------------- host/lib/usrp/usrp_e/dboard_impl.cpp | 172 ------------- host/lib/usrp/usrp_e/dsp_impl.cpp | 192 -------------- host/lib/usrp/usrp_e/fpga-downloader.cc | 274 -------------------- host/lib/usrp/usrp_e/io_impl.cpp | 272 -------------------- host/lib/usrp/usrp_e/mboard_impl.cpp | 159 ------------ host/lib/usrp/usrp_e/usrp_e_iface.cpp | 194 -------------- host/lib/usrp/usrp_e/usrp_e_iface.hpp | 112 -------- host/lib/usrp/usrp_e/usrp_e_impl.cpp | 201 --------------- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 164 ------------ host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp | 215 ---------------- host/lib/usrp/usrp_e/usrp_e_regs.hpp | 198 -------------- host/lib/usrp/usrp_e100/CMakeLists.txt | 64 +++++ host/lib/usrp/usrp_e100/clock_ctrl.cpp | 237 +++++++++++++++++ host/lib/usrp/usrp_e100/clock_ctrl.hpp | 88 +++++++ host/lib/usrp/usrp_e100/codec_ctrl.cpp | 296 +++++++++++++++++++++ host/lib/usrp/usrp_e100/codec_ctrl.hpp | 90 +++++++ host/lib/usrp/usrp_e100/codec_impl.cpp | 149 +++++++++++ host/lib/usrp/usrp_e100/dboard_iface.cpp | 298 ++++++++++++++++++++++ host/lib/usrp/usrp_e100/dboard_impl.cpp | 172 +++++++++++++ host/lib/usrp/usrp_e100/dsp_impl.cpp | 192 ++++++++++++++ host/lib/usrp/usrp_e100/fpga-downloader.cc | 274 ++++++++++++++++++++ host/lib/usrp/usrp_e100/io_impl.cpp | 272 ++++++++++++++++++++ host/lib/usrp/usrp_e100/mboard_impl.cpp | 159 ++++++++++++ host/lib/usrp/usrp_e100/usrp_e_iface.cpp | 194 ++++++++++++++ host/lib/usrp/usrp_e100/usrp_e_iface.hpp | 112 ++++++++ host/lib/usrp/usrp_e100/usrp_e_impl.cpp | 201 +++++++++++++++ host/lib/usrp/usrp_e100/usrp_e_impl.hpp | 164 ++++++++++++ host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp | 215 ++++++++++++++++ host/lib/usrp/usrp_e100/usrp_e_regs.hpp | 198 ++++++++++++++ 37 files changed, 3376 insertions(+), 3376 deletions(-) delete mode 100644 host/lib/usrp/usrp_e/CMakeLists.txt delete mode 100644 host/lib/usrp/usrp_e/clock_ctrl.cpp delete mode 100644 host/lib/usrp/usrp_e/clock_ctrl.hpp delete mode 100644 host/lib/usrp/usrp_e/codec_ctrl.cpp delete mode 100644 host/lib/usrp/usrp_e/codec_ctrl.hpp delete mode 100644 host/lib/usrp/usrp_e/codec_impl.cpp delete mode 100644 host/lib/usrp/usrp_e/dboard_iface.cpp delete mode 100644 host/lib/usrp/usrp_e/dboard_impl.cpp delete mode 100644 host/lib/usrp/usrp_e/dsp_impl.cpp delete mode 100644 host/lib/usrp/usrp_e/fpga-downloader.cc delete mode 100644 host/lib/usrp/usrp_e/io_impl.cpp delete mode 100644 host/lib/usrp/usrp_e/mboard_impl.cpp delete mode 100644 host/lib/usrp/usrp_e/usrp_e_iface.cpp delete mode 100644 host/lib/usrp/usrp_e/usrp_e_iface.hpp delete mode 100644 host/lib/usrp/usrp_e/usrp_e_impl.cpp delete mode 100644 host/lib/usrp/usrp_e/usrp_e_impl.hpp delete mode 100644 host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp delete mode 100644 host/lib/usrp/usrp_e/usrp_e_regs.hpp create mode 100644 host/lib/usrp/usrp_e100/CMakeLists.txt create mode 100644 host/lib/usrp/usrp_e100/clock_ctrl.cpp create mode 100644 host/lib/usrp/usrp_e100/clock_ctrl.hpp create mode 100644 host/lib/usrp/usrp_e100/codec_ctrl.cpp create mode 100644 host/lib/usrp/usrp_e100/codec_ctrl.hpp create mode 100644 host/lib/usrp/usrp_e100/codec_impl.cpp create mode 100644 host/lib/usrp/usrp_e100/dboard_iface.cpp create mode 100644 host/lib/usrp/usrp_e100/dboard_impl.cpp create mode 100644 host/lib/usrp/usrp_e100/dsp_impl.cpp create mode 100644 host/lib/usrp/usrp_e100/fpga-downloader.cc create mode 100644 host/lib/usrp/usrp_e100/io_impl.cpp create mode 100644 host/lib/usrp/usrp_e100/mboard_impl.cpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e_iface.cpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e_iface.hpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e_impl.cpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e_impl.hpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e_regs.hpp (limited to 'host') diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt index bb7e83214..073b3c80b 100644 --- a/host/lib/usrp/CMakeLists.txt +++ b/host/lib/usrp/CMakeLists.txt @@ -35,4 +35,4 @@ LIBUHD_APPEND_SOURCES( INCLUDE(${CMAKE_SOURCE_DIR}/lib/usrp/dboard/CMakeLists.txt) INCLUDE(${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/CMakeLists.txt) INCLUDE(${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/CMakeLists.txt) -INCLUDE(${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/CMakeLists.txt) +INCLUDE(${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/CMakeLists.txt) diff --git a/host/lib/usrp/usrp_e/CMakeLists.txt b/host/lib/usrp/usrp_e/CMakeLists.txt deleted file mode 100644 index 6c5d281dd..000000000 --- a/host/lib/usrp/usrp_e/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -# -# Copyright 2010 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 . -# - -#This file will be included by cmake, use absolute paths! - -######################################################################## -# Conditionally configure the USRP-E support -######################################################################## -MESSAGE(STATUS "Configuring usrp-e support...") - -INCLUDE(CheckIncludeFileCXX) -CHECK_INCLUDE_FILE_CXX(linux/usrp_e.h HAVE_LINUX_USRP_E_H) - -SET(ENABLE_USRP_E TRUE) - -IF(DEFINED ENABLE_USRP_E) - IF(ENABLE_USRP_E) - MESSAGE(STATUS "USRP-E support enabled by configure flag") - ELSE(ENABLE_USRP_E) - MESSAGE(STATUS "USRP-E support disabled by configure flag") - ENDIF(ENABLE_USRP_E) -ELSE(DEFINED ENABLE_USRP_E) #not defined: automatic enabling of component - SET(ENABLE_USRP_E ${HAVE_LINUX_USRP_E_H}) -ENDIF(DEFINED ENABLE_USRP_E) -SET(ENABLE_USRP_E ${ENABLE_USRP_E} CACHE BOOL "enable USRP-E support") - -IF(ENABLE_USRP_E) - MESSAGE(STATUS " Building usrp-e support.") - LIBUHD_APPEND_SOURCES( - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/clock_ctrl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/clock_ctrl.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/codec_ctrl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/codec_ctrl.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/codec_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dboard_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dboard_iface.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dsp_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/fpga-downloader.cc - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/io_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/mboard_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_impl.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_iface.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_iface.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_regs.hpp - ) -ELSE(ENABLE_USRP_E) - MESSAGE(STATUS " Skipping usrp-e support.") -ENDIF(ENABLE_USRP_E) diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp deleted file mode 100644 index 9d4625305..000000000 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ /dev/null @@ -1,237 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "clock_ctrl.hpp" -#include "ad9522_regs.hpp" -#include -#include -#include "usrp_e_regs.hpp" //spi slave constants -#include -#include -#include -#include - -using namespace uhd; - -template static void set_clock_divider( - size_t divider, div_type &low, div_type &high, bypass_type &bypass -){ - high = divider/2 - 1; - low = divider - high - 2; - bypass = (divider == 1)? 1 : 0; -} - -/*********************************************************************** - * Constants - **********************************************************************/ -static const bool enable_test_clock = false; -static const size_t ref_clock_doubler = 2; //enabled below -static const double ref_clock_rate = 10e6 * ref_clock_doubler; - -static const size_t r_counter = 1; -static const size_t a_counter = 0; -static const size_t b_counter = 20 / ref_clock_doubler; -static const size_t prescaler = 8; //set below with enum, set to 8 when input is under 2400 MHz -static const size_t vco_divider = 5; //set below with enum - -static const size_t n_counter = prescaler * b_counter + a_counter; -static const size_t vco_clock_rate = ref_clock_rate/r_counter * n_counter; //between 1400 and 1800 MHz -static const double master_clock_rate = vco_clock_rate/vco_divider; - -static const size_t fpga_clock_divider = size_t(master_clock_rate/64e6); -static const size_t codec_clock_divider = size_t(master_clock_rate/64e6); - -/*********************************************************************** - * Clock Control Implementation - **********************************************************************/ -class usrp_e_clock_ctrl_impl : public usrp_e_clock_ctrl{ -public: - usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface){ - _iface = iface; - - //init the clock gen registers - //Note: out0 should already be clocking the FPGA or this isnt going to work - _ad9522_regs.sdo_active = ad9522_regs_t::SDO_ACTIVE_SDO_SDIO; - _ad9522_regs.enable_clock_doubler = 1; //enable ref clock doubler - _ad9522_regs.enb_stat_eeprom_at_stat_pin = 0; //use status pin - _ad9522_regs.status_pin_control = 0x1; //n divider - _ad9522_regs.ld_pin_control = 0x00; //dld - _ad9522_regs.refmon_pin_control = 0x12; //show ref2 - - _ad9522_regs.enable_ref2 = 1; - _ad9522_regs.enable_ref1 = 0; - _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF2; - - _ad9522_regs.set_r_counter(r_counter); - _ad9522_regs.a_counter = a_counter; - _ad9522_regs.set_b_counter(b_counter); - _ad9522_regs.prescaler_p = ad9522_regs_t::PRESCALER_P_DIV8_9; - - _ad9522_regs.pll_power_down = ad9522_regs_t::PLL_POWER_DOWN_NORMAL; - _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_1_2MA; - - _ad9522_regs.vco_calibration_now = 1; //calibrate it! - _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; - _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_VCO; - - //setup fpga master clock - _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS; - set_clock_divider(fpga_clock_divider, - _ad9522_regs.divider0_low_cycles, - _ad9522_regs.divider0_high_cycles, - _ad9522_regs.divider0_bypass - ); - - //setup codec clock - _ad9522_regs.out3_format = ad9522_regs_t::OUT3_FORMAT_LVDS; - set_clock_divider(codec_clock_divider, - _ad9522_regs.divider1_low_cycles, - _ad9522_regs.divider1_high_cycles, - _ad9522_regs.divider1_bypass - ); - - //setup test clock (same divider as codec clock) - _ad9522_regs.out4_format = ad9522_regs_t::OUT4_FORMAT_CMOS; - _ad9522_regs.out4_cmos_configuration = (enable_test_clock)? - ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON : - ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF; - - //setup a list of register ranges to write - typedef std::pair range_t; - static const std::vector ranges = boost::assign::list_of - (range_t(0x000, 0x000)) (range_t(0x010, 0x01F)) - (range_t(0x0F0, 0x0FD)) (range_t(0x190, 0x19B)) - (range_t(0x1E0, 0x1E1)) (range_t(0x230, 0x230)) - ; - - //write initial register values and latch/update - BOOST_FOREACH(const range_t &range, ranges){ - for(boost::uint16_t addr = range.first; addr <= range.second; addr++){ - this->send_reg(addr); - } - } - this->latch_regs(); - //test read: - //boost::uint32_t reg = _ad9522_regs.get_read_reg(0x01b); - //boost::uint32_t result = _iface->transact_spi( - // UE_SPI_SS_AD9522, - // spi_config_t::EDGE_RISE, - // reg, 24, true /*no*/ - //); - //std::cout << "result " << std::hex << result << std::endl; - this->enable_rx_dboard_clock(false); - this->enable_tx_dboard_clock(false); - } - - ~usrp_e_clock_ctrl_impl(void){ - this->enable_rx_dboard_clock(false); - this->enable_tx_dboard_clock(false); - } - - double get_fpga_clock_rate(void){ - return master_clock_rate/fpga_clock_divider; - } - - /*********************************************************************** - * RX Dboard Clock Control (output 9, divider 3) - **********************************************************************/ - void enable_rx_dboard_clock(bool enb){ - _ad9522_regs.out9_format = ad9522_regs_t::OUT9_FORMAT_CMOS; - _ad9522_regs.out9_cmos_configuration = (enb)? - ad9522_regs_t::OUT9_CMOS_CONFIGURATION_B_ON : - ad9522_regs_t::OUT9_CMOS_CONFIGURATION_OFF; - this->send_reg(0x0F9); - this->latch_regs(); - } - - std::vector get_rx_dboard_clock_rates(void){ - std::vector rates; - for(size_t div = 1; div <= 16+16; div++) - rates.push_back(master_clock_rate/div); - return rates; - } - - void set_rx_dboard_clock_rate(double rate){ - assert_has(get_rx_dboard_clock_rates(), rate, "rx dboard clock rate"); - size_t divider = size_t(master_clock_rate/rate); - //set the divider registers - set_clock_divider(divider, - _ad9522_regs.divider3_low_cycles, - _ad9522_regs.divider3_high_cycles, - _ad9522_regs.divider3_bypass - ); - this->send_reg(0x199); - this->send_reg(0x19a); - this->latch_regs(); - } - - /*********************************************************************** - * TX Dboard Clock Control (output 6, divider 2) - **********************************************************************/ - void enable_tx_dboard_clock(bool enb){ - _ad9522_regs.out6_format = ad9522_regs_t::OUT6_FORMAT_CMOS; - _ad9522_regs.out6_cmos_configuration = (enb)? - ad9522_regs_t::OUT6_CMOS_CONFIGURATION_B_ON : - ad9522_regs_t::OUT6_CMOS_CONFIGURATION_OFF; - this->send_reg(0x0F6); - this->latch_regs(); - } - - std::vector get_tx_dboard_clock_rates(void){ - return get_rx_dboard_clock_rates(); //same master clock, same dividers... - } - - void set_tx_dboard_clock_rate(double rate){ - assert_has(get_tx_dboard_clock_rates(), rate, "tx dboard clock rate"); - size_t divider = size_t(master_clock_rate/rate); - //set the divider registers - set_clock_divider(divider, - _ad9522_regs.divider2_low_cycles, - _ad9522_regs.divider2_high_cycles, - _ad9522_regs.divider2_bypass - ); - this->send_reg(0x196); - this->send_reg(0x197); - this->latch_regs(); - } - -private: - usrp_e_iface::sptr _iface; - ad9522_regs_t _ad9522_regs; - - void latch_regs(void){ - _ad9522_regs.io_update = 1; - this->send_reg(0x232); - } - - void send_reg(boost::uint16_t addr){ - boost::uint32_t reg = _ad9522_regs.get_write_reg(addr); - //std::cout << "clock control write reg: " << std::hex << reg << std::endl; - _iface->transact_spi( - UE_SPI_SS_AD9522, - spi_config_t::EDGE_RISE, - reg, 24, false /*no rb*/ - ); - } -}; - -/*********************************************************************** - * Clock Control Make - **********************************************************************/ -usrp_e_clock_ctrl::sptr usrp_e_clock_ctrl::make(usrp_e_iface::sptr iface){ - return sptr(new usrp_e_clock_ctrl_impl(iface)); -} diff --git a/host/lib/usrp/usrp_e/clock_ctrl.hpp b/host/lib/usrp/usrp_e/clock_ctrl.hpp deleted file mode 100644 index 3b5103ed1..000000000 --- a/host/lib/usrp/usrp_e/clock_ctrl.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// -// Copyright 2010 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 . -// - -#ifndef INCLUDED_USRP_E_CLOCK_CTRL_HPP -#define INCLUDED_USRP_E_CLOCK_CTRL_HPP - -#include "usrp_e_iface.hpp" -#include -#include -#include - -/*! - * The usrp-e clock control: - * - Setup system clocks. - * - Disable/enable clock lines. - */ -class usrp_e_clock_ctrl : boost::noncopyable{ -public: - typedef boost::shared_ptr sptr; - - /*! - * Make a new clock control object. - * \param iface the usrp_e iface object - * \return the clock control object - */ - static sptr make(usrp_e_iface::sptr iface); - - /*! - * Get the rate of the fpga clock line. - * \return the fpga clock rate in Hz - */ - virtual double get_fpga_clock_rate(void) = 0; - - /*! - * Get the possible rates of the rx dboard clock. - * \return a vector of clock rates in Hz - */ - virtual std::vector get_rx_dboard_clock_rates(void) = 0; - - /*! - * Get the possible rates of the tx dboard clock. - * \return a vector of clock rates in Hz - */ - virtual std::vector get_tx_dboard_clock_rates(void) = 0; - - /*! - * Set the rx dboard clock rate to a possible rate. - * \param rate the new clock rate in Hz - * \throw exception when rate cannot be achieved - */ - virtual void set_rx_dboard_clock_rate(double rate) = 0; - - /*! - * Set the tx dboard clock rate to a possible rate. - * \param rate the new clock rate in Hz - * \throw exception when rate cannot be achieved - */ - virtual void set_tx_dboard_clock_rate(double rate) = 0; - - /*! - * Enable/disable the rx dboard clock. - * \param enb true to enable - */ - virtual void enable_rx_dboard_clock(bool enb) = 0; - - /*! - * Enable/disable the tx dboard clock. - * \param enb true to enable - */ - virtual void enable_tx_dboard_clock(bool enb) = 0; - -}; - -#endif /* INCLUDED_USRP_E_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp deleted file mode 100644 index a728d7e46..000000000 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ /dev/null @@ -1,296 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "codec_ctrl.hpp" -#include "ad9862_regs.hpp" -#include -#include -#include -#include -#include -#include -#include "usrp_e_regs.hpp" //spi slave constants -#include -#include - -using namespace uhd; - -static const bool codec_debug = false; - -const gain_range_t usrp_e_codec_ctrl::tx_pga_gain_range(-20, 0, float(0.1)); -const gain_range_t usrp_e_codec_ctrl::rx_pga_gain_range(0, 20, 1); - -/*********************************************************************** - * Codec Control Implementation - **********************************************************************/ -class usrp_e_codec_ctrl_impl : public usrp_e_codec_ctrl{ -public: - //structors - usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface); - ~usrp_e_codec_ctrl_impl(void); - - //aux adc and dac control - float read_aux_adc(aux_adc_t which); - void write_aux_dac(aux_dac_t which, float volts); - - //pga gain control - void set_tx_pga_gain(float); - float get_tx_pga_gain(void); - void set_rx_pga_gain(float, char); - float get_rx_pga_gain(char); - -private: - usrp_e_iface::sptr _iface; - ad9862_regs_t _ad9862_regs; - aux_adc_t _last_aux_adc_a, _last_aux_adc_b; - void send_reg(boost::uint8_t addr); - void recv_reg(boost::uint8_t addr); -}; - -/*********************************************************************** - * Codec Control Structors - **********************************************************************/ -usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ - _iface = iface; - - //soft reset - _ad9862_regs.soft_reset = 1; - this->send_reg(0); - - //initialize the codec register settings - _ad9862_regs.sdio_bidir = ad9862_regs_t::SDIO_BIDIR_SDIO_SDO; - _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB; - _ad9862_regs.soft_reset = 0; - - //setup rx side of codec - _ad9862_regs.byp_buffer_a = 1; - _ad9862_regs.byp_buffer_b = 1; - _ad9862_regs.buffer_a_pd = 1; - _ad9862_regs.buffer_b_pd = 1; - _ad9862_regs.rx_pga_a = 0;//0x1f; //TODO bring under api control - _ad9862_regs.rx_pga_b = 0;//0x1f; //TODO bring under api control - _ad9862_regs.rx_twos_comp = 1; - _ad9862_regs.rx_hilbert = ad9862_regs_t::RX_HILBERT_DIS; - - //setup tx side of codec - _ad9862_regs.two_data_paths = ad9862_regs_t::TWO_DATA_PATHS_BOTH; - _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED; - _ad9862_regs.tx_retime = ad9862_regs_t::TX_RETIME_CLKOUT2; - _ad9862_regs.tx_pga_gain = 199; //TODO bring under api control - _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; - _ad9862_regs.interp = ad9862_regs_t::INTERP_2; - _ad9862_regs.tx_twos_comp = 1; - _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_BYPASS; - _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; - _ad9862_regs.dac_a_coarse_gain = 0x3; - _ad9862_regs.dac_b_coarse_gain = 0x3; - _ad9862_regs.edges = ad9862_regs_t::EDGES_NORMAL; - - //setup the dll - _ad9862_regs.input_clk_ctrl = ad9862_regs_t::INPUT_CLK_CTRL_EXTERNAL; - _ad9862_regs.dll_mult = ad9862_regs_t::DLL_MULT_2; - _ad9862_regs.dll_mode = ad9862_regs_t::DLL_MODE_FAST; - - //write the register settings to the codec - for (uint8_t addr = 0; addr <= 25; addr++){ - this->send_reg(addr); - } - - //aux adc clock - _ad9862_regs.clk_4 = ad9862_regs_t::CLK_4_1_4; - this->send_reg(34); -} - -usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){ - //set aux dacs to zero - this->write_aux_dac(AUX_DAC_A, 0); - this->write_aux_dac(AUX_DAC_B, 0); - this->write_aux_dac(AUX_DAC_C, 0); - this->write_aux_dac(AUX_DAC_D, 0); - - //power down - _ad9862_regs.all_rx_pd = 1; - this->send_reg(1); - _ad9862_regs.tx_digital_pd = 1; - _ad9862_regs.tx_analog_pd = ad9862_regs_t::TX_ANALOG_PD_BOTH; - this->send_reg(8); -} - -/*********************************************************************** - * Codec Control Gain Control Methods - **********************************************************************/ -static const int mtpgw = 255; //maximum tx pga gain word - -void usrp_e_codec_ctrl_impl::set_tx_pga_gain(float gain){ - int gain_word = int(mtpgw*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); - _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw); - this->send_reg(16); -} - -float usrp_e_codec_ctrl_impl::get_tx_pga_gain(void){ - return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.max - tx_pga_gain_range.min)/mtpgw) + tx_pga_gain_range.min; -} - -static const int mrpgw = 0x14; //maximum rx pga gain word - -void usrp_e_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ - int gain_word = int(mrpgw*(gain - rx_pga_gain_range.min)/(rx_pga_gain_range.max - rx_pga_gain_range.min)); - gain_word = std::clip(gain_word, 0, mrpgw); - switch(which){ - case 'A': - _ad9862_regs.rx_pga_a = gain_word; - this->send_reg(2); - return; - case 'B': - _ad9862_regs.rx_pga_b = gain_word; - this->send_reg(3); - return; - default: UHD_THROW_INVALID_CODE_PATH(); - } -} - -float usrp_e_codec_ctrl_impl::get_rx_pga_gain(char which){ - int gain_word; - switch(which){ - case 'A': gain_word = _ad9862_regs.rx_pga_a; break; - case 'B': gain_word = _ad9862_regs.rx_pga_b; break; - default: UHD_THROW_INVALID_CODE_PATH(); - } - return (gain_word*(rx_pga_gain_range.max - rx_pga_gain_range.min)/mrpgw) + rx_pga_gain_range.min; -} - -/*********************************************************************** - * Codec Control AUX ADC Methods - **********************************************************************/ -static float aux_adc_to_volts(boost::uint8_t high, boost::uint8_t low){ - return float((boost::uint16_t(high) << 2) | low)*3.3/0x3ff; -} - -float usrp_e_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ - //check to see if the switch needs to be set - bool write_switch = false; - switch(which){ - - case AUX_ADC_A1: - case AUX_ADC_A2: - if (which != _last_aux_adc_a){ - _ad9862_regs.select_a = (which == AUX_ADC_A1)? - ad9862_regs_t::SELECT_A_AUX_ADC1: ad9862_regs_t::SELECT_A_AUX_ADC2; - _last_aux_adc_a = which; - write_switch = true; - } - break; - - case AUX_ADC_B1: - case AUX_ADC_B2: - if (which != _last_aux_adc_b){ - _ad9862_regs.select_b = (which == AUX_ADC_B1)? - ad9862_regs_t::SELECT_B_AUX_ADC1: ad9862_regs_t::SELECT_B_AUX_ADC2; - _last_aux_adc_b = which; - write_switch = true; - } - break; - - } - - //write the switch if it changed - if(write_switch) this->send_reg(34); - - //map aux adcs to register values to read - static const uhd::dict aux_dac_to_addr = boost::assign::map_list_of - (AUX_ADC_A2, 26) (AUX_ADC_A1, 28) - (AUX_ADC_B2, 30) (AUX_ADC_B1, 32) - ; - - //read the value - this->recv_reg(aux_dac_to_addr[which]+0); - this->recv_reg(aux_dac_to_addr[which]+1); - - //return the value scaled to volts - switch(which){ - case AUX_ADC_A1: return aux_adc_to_volts(_ad9862_regs.aux_adc_a1_9_2, _ad9862_regs.aux_adc_a1_1_0); - case AUX_ADC_A2: return aux_adc_to_volts(_ad9862_regs.aux_adc_a2_9_2, _ad9862_regs.aux_adc_a2_1_0); - case AUX_ADC_B1: return aux_adc_to_volts(_ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0); - case AUX_ADC_B2: return aux_adc_to_volts(_ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0); - } - UHD_ASSERT_THROW(false); -} - -/*********************************************************************** - * Codec Control AUX DAC Methods - **********************************************************************/ -void usrp_e_codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ - //special case for aux dac d (aka sigma delta word) - if (which == AUX_DAC_D){ - boost::uint16_t dac_word = std::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); - _ad9862_regs.sig_delt_11_4 = boost::uint8_t(dac_word >> 4); - _ad9862_regs.sig_delt_3_0 = boost::uint8_t(dac_word & 0xf); - this->send_reg(42); - this->send_reg(43); - return; - } - - //calculate the dac word for aux dac a, b, c - boost::uint8_t dac_word = std::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff); - - //setup a lookup table for the aux dac params (reg ref, reg addr) - typedef boost::tuple dac_params_t; - uhd::dict aux_dac_to_params = boost::assign::map_list_of - (AUX_DAC_A, dac_params_t(&_ad9862_regs.aux_dac_a, 36)) - (AUX_DAC_B, dac_params_t(&_ad9862_regs.aux_dac_b, 37)) - (AUX_DAC_C, dac_params_t(&_ad9862_regs.aux_dac_c, 38)) - ; - - //set the aux dac register - UHD_ASSERT_THROW(aux_dac_to_params.has_key(which)); - boost::uint8_t *reg_ref, reg_addr; - boost::tie(reg_ref, reg_addr) = aux_dac_to_params[which]; - *reg_ref = dac_word; - this->send_reg(reg_addr); -} - -/*********************************************************************** - * Codec Control SPI Methods - **********************************************************************/ -void usrp_e_codec_ctrl_impl::send_reg(boost::uint8_t addr){ - boost::uint32_t reg = _ad9862_regs.get_write_reg(addr); - if (codec_debug) std::cout << "codec control write reg: " << std::hex << reg << std::endl; - _iface->transact_spi( - UE_SPI_SS_AD9862, - spi_config_t::EDGE_RISE, - reg, 16, false /*no rb*/ - ); -} - -void usrp_e_codec_ctrl_impl::recv_reg(boost::uint8_t addr){ - boost::uint32_t reg = _ad9862_regs.get_read_reg(addr); - if (codec_debug) std::cout << "codec control read reg: " << std::hex << reg << std::endl; - boost::uint32_t ret = _iface->transact_spi( - UE_SPI_SS_AD9862, - spi_config_t::EDGE_RISE, - reg, 16, true /*rb*/ - ); - if (codec_debug) std::cout << "codec control read ret: " << std::hex << ret << std::endl; - _ad9862_regs.set_reg(addr, boost::uint16_t(ret)); -} - -/*********************************************************************** - * Codec Control Make - **********************************************************************/ -usrp_e_codec_ctrl::sptr usrp_e_codec_ctrl::make(usrp_e_iface::sptr iface){ - return sptr(new usrp_e_codec_ctrl_impl(iface)); -} diff --git a/host/lib/usrp/usrp_e/codec_ctrl.hpp b/host/lib/usrp/usrp_e/codec_ctrl.hpp deleted file mode 100644 index 87b6ff951..000000000 --- a/host/lib/usrp/usrp_e/codec_ctrl.hpp +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright 2010 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 . -// - -#ifndef INCLUDED_USRP_E_CODEC_CTRL_HPP -#define INCLUDED_USRP_E_CODEC_CTRL_HPP - -#include "usrp_e_iface.hpp" -#include -#include -#include - -/*! - * The usrp-e codec control: - * - Init/power down codec. - * - Read aux adc, write aux dac. - */ -class usrp_e_codec_ctrl : boost::noncopyable{ -public: - typedef boost::shared_ptr sptr; - - static const uhd::gain_range_t tx_pga_gain_range; - static const uhd::gain_range_t rx_pga_gain_range; - - /*! - * Make a new codec control object. - * \param iface the usrp_e iface object - * \return the codec control object - */ - static sptr make(usrp_e_iface::sptr iface); - - //! aux adc identifier constants - enum aux_adc_t{ - AUX_ADC_A2 = 0xA2, - AUX_ADC_A1 = 0xA1, - AUX_ADC_B2 = 0xB2, - AUX_ADC_B1 = 0xB1 - }; - - /*! - * Read an auxiliary adc: - * The internals remember which aux adc was read last. - * Therefore, the aux adc switch is only changed as needed. - * \param which which of the 4 adcs - * \return a value in volts - */ - virtual float read_aux_adc(aux_adc_t which) = 0; - - //! aux dac identifier constants - enum aux_dac_t{ - AUX_DAC_A = 0xA, - AUX_DAC_B = 0xB, - AUX_DAC_C = 0xC, - AUX_DAC_D = 0xD //really the sigma delta output - }; - - /*! - * Write an auxiliary dac. - * \param which which of the 4 dacs - * \param volts the level in in volts - */ - virtual void write_aux_dac(aux_dac_t which, float volts) = 0; - - //! Set the TX PGA gain - virtual void set_tx_pga_gain(float gain) = 0; - - //! Get the TX PGA gain - virtual float get_tx_pga_gain(void) = 0; - - //! Set the RX PGA gain ('A' or 'B') - virtual void set_rx_pga_gain(float gain, char which) = 0; - - //! Get the RX PGA gain ('A' or 'B') - virtual float get_rx_pga_gain(char which) = 0; -}; - -#endif /* INCLUDED_USRP_E_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e/codec_impl.cpp b/host/lib/usrp/usrp_e/codec_impl.cpp deleted file mode 100644 index 696fb37ec..000000000 --- a/host/lib/usrp/usrp_e/codec_impl.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_impl.hpp" -#include -#include -#include - -using namespace uhd; -using namespace uhd::usrp; - -/*********************************************************************** - * Helper Methods - **********************************************************************/ -void usrp_e_impl::codec_init(void){ - //make proxies - _rx_codec_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::rx_codec_get, this, _1, _2), - boost::bind(&usrp_e_impl::rx_codec_set, this, _1, _2) - ); - _tx_codec_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::tx_codec_get, this, _1, _2), - boost::bind(&usrp_e_impl::tx_codec_set, this, _1, _2) - ); -} - -/*********************************************************************** - * RX Codec Properties - **********************************************************************/ -static const std::string ad9862_pga_gain_name = "ad9862 pga"; - -void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - //handle the get request conditioned on the key - switch(key.as()){ - case CODEC_PROP_NAME: - val = std::string("usrp-e adc - ad9522"); - return; - - case CODEC_PROP_OTHERS: - val = prop_names_t(); - return; - - case CODEC_PROP_GAIN_NAMES: - val = prop_names_t(1, ad9862_pga_gain_name); - return; - - case CODEC_PROP_GAIN_RANGE: - UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - val = usrp_e_codec_ctrl::rx_pga_gain_range; - return; - - case CODEC_PROP_GAIN_I: - UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - val = _codec_ctrl->get_rx_pga_gain('A'); - return; - - case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - val = _codec_ctrl->get_rx_pga_gain('B'); - return; - - default: UHD_THROW_PROP_GET_ERROR(); - } -} - -void usrp_e_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - //handle the set request conditioned on the key - switch(key.as()){ - case CODEC_PROP_GAIN_I: - UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - _codec_ctrl->set_rx_pga_gain(val.as(), 'A'); - return; - - case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - _codec_ctrl->set_rx_pga_gain(val.as(), 'B'); - return; - - default: UHD_THROW_PROP_SET_ERROR(); - } -} - -/*********************************************************************** - * TX Codec Properties - **********************************************************************/ -void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - //handle the get request conditioned on the key - switch(key.as()){ - case CODEC_PROP_NAME: - val = std::string("usrp-e dac - ad9522"); - return; - - case CODEC_PROP_OTHERS: - val = prop_names_t(); - return; - - case CODEC_PROP_GAIN_NAMES: - val = prop_names_t(1, ad9862_pga_gain_name); - return; - - case CODEC_PROP_GAIN_RANGE: - UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - val = usrp_e_codec_ctrl::tx_pga_gain_range; - return; - - case CODEC_PROP_GAIN_I: //only one gain for I and Q - case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - val = _codec_ctrl->get_tx_pga_gain(); - return; - - default: UHD_THROW_PROP_GET_ERROR(); - } -} - -void usrp_e_impl::tx_codec_set(const wax::obj &key_, const wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - //handle the set request conditioned on the key - switch(key.as()){ - case CODEC_PROP_GAIN_I: //only one gain for I and Q - case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - _codec_ctrl->set_tx_pga_gain(val.as()); - return; - - default: UHD_THROW_PROP_SET_ERROR(); - } -} diff --git a/host/lib/usrp/usrp_e/dboard_iface.cpp b/host/lib/usrp/usrp_e/dboard_iface.cpp deleted file mode 100644 index 6898df8df..000000000 --- a/host/lib/usrp/usrp_e/dboard_iface.cpp +++ /dev/null @@ -1,298 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_iface.hpp" -#include "usrp_e_regs.hpp" -#include "clock_ctrl.hpp" -#include "codec_ctrl.hpp" -#include -#include -#include -#include -#include //i2c and spi constants - -using namespace uhd; -using namespace uhd::usrp; -using namespace boost::assign; - -class usrp_e_dboard_iface : public dboard_iface{ -public: - - usrp_e_dboard_iface( - usrp_e_iface::sptr iface, - usrp_e_clock_ctrl::sptr clock, - usrp_e_codec_ctrl::sptr codec - ){ - _iface = iface; - _clock = clock; - _codec = codec; - - //init the clock rate shadows - this->set_clock_rate(UNIT_RX, _clock->get_fpga_clock_rate()); - this->set_clock_rate(UNIT_TX, _clock->get_fpga_clock_rate()); - - _iface->poke16(UE_REG_GPIO_RX_DBG, 0); - _iface->poke16(UE_REG_GPIO_TX_DBG, 0); - } - - ~usrp_e_dboard_iface(void){ - /* NOP */ - } - - special_props_t get_special_props(void){ - special_props_t props; - props.soft_clock_divider = false; - props.mangle_i2c_addrs = false; - return props; - } - - void write_aux_dac(unit_t, aux_dac_t, float); - float read_aux_adc(unit_t, aux_adc_t); - - void set_pin_ctrl(unit_t, boost::uint16_t); - void set_atr_reg(unit_t, atr_reg_t, boost::uint16_t); - void set_gpio_ddr(unit_t, boost::uint16_t); - void write_gpio(unit_t, boost::uint16_t); - void set_gpio_debug(unit_t, int); - boost::uint16_t read_gpio(unit_t); - - void write_i2c(boost::uint8_t, const byte_vector_t &); - byte_vector_t read_i2c(boost::uint8_t, size_t); - - void write_spi( - unit_t unit, - const spi_config_t &config, - boost::uint32_t data, - size_t num_bits - ); - - boost::uint32_t read_write_spi( - unit_t unit, - const spi_config_t &config, - boost::uint32_t data, - size_t num_bits - ); - - void set_clock_rate(unit_t, double); - std::vector get_clock_rates(unit_t); - double get_clock_rate(unit_t); - void set_clock_enabled(unit_t, bool); - double get_codec_rate(unit_t); - -private: - usrp_e_iface::sptr _iface; - usrp_e_clock_ctrl::sptr _clock; - usrp_e_codec_ctrl::sptr _codec; - uhd::dict _clock_rates; -}; - -/*********************************************************************** - * Make Function - **********************************************************************/ -dboard_iface::sptr make_usrp_e_dboard_iface( - usrp_e_iface::sptr iface, - usrp_e_clock_ctrl::sptr clock, - usrp_e_codec_ctrl::sptr codec -){ - return dboard_iface::sptr(new usrp_e_dboard_iface(iface, clock, codec)); -} - -/*********************************************************************** - * Clock Rates - **********************************************************************/ -void usrp_e_dboard_iface::set_clock_rate(unit_t unit, double rate){ - _clock_rates[unit] = rate; - switch(unit){ - case UNIT_RX: return _clock->set_rx_dboard_clock_rate(rate); - case UNIT_TX: return _clock->set_tx_dboard_clock_rate(rate); - } -} - -std::vector usrp_e_dboard_iface::get_clock_rates(unit_t unit){ - switch(unit){ - case UNIT_RX: return _clock->get_rx_dboard_clock_rates(); - case UNIT_TX: return _clock->get_tx_dboard_clock_rates(); - default: UHD_THROW_INVALID_CODE_PATH(); - } -} - -double usrp_e_dboard_iface::get_clock_rate(unit_t unit){ - return _clock_rates[unit]; -} - -void usrp_e_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ - switch(unit){ - case UNIT_RX: return _clock->enable_rx_dboard_clock(enb); - case UNIT_TX: return _clock->enable_tx_dboard_clock(enb); - } -} - -double usrp_e_dboard_iface::get_codec_rate(unit_t){ - return _clock->get_fpga_clock_rate(); -} - -/*********************************************************************** - * GPIO - **********************************************************************/ -void usrp_e_dboard_iface::set_pin_ctrl(unit_t unit, boost::uint16_t value){ - UHD_ASSERT_THROW(GPIO_SEL_ATR == 1); //make this assumption - switch(unit){ - case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_SEL, value); return; - case UNIT_TX: _iface->poke16(UE_REG_GPIO_TX_SEL, value); return; - } -} - -void usrp_e_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value){ - switch(unit){ - case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_DDR, value); return; - case UNIT_TX: _iface->poke16(UE_REG_GPIO_TX_DDR, value); return; - } -} - -void usrp_e_dboard_iface::write_gpio(unit_t unit, boost::uint16_t value){ - switch(unit){ - case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_IO, value); return; - case UNIT_TX: _iface->poke16(UE_REG_GPIO_TX_IO, value); return; - } -} - -boost::uint16_t usrp_e_dboard_iface::read_gpio(unit_t unit){ - switch(unit){ - case UNIT_RX: return _iface->peek16(UE_REG_GPIO_RX_IO); - case UNIT_TX: return _iface->peek16(UE_REG_GPIO_TX_IO); - default: UHD_THROW_INVALID_CODE_PATH(); - } -} - -void usrp_e_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){ - //define mapping of unit to atr regs to register address - static const uhd::dict< - unit_t, uhd::dict - > unit_to_atr_to_addr = map_list_of - (UNIT_RX, map_list_of - (ATR_REG_IDLE, UE_REG_ATR_IDLE_RXSIDE) - (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_RXSIDE) - (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_RXSIDE) - (ATR_REG_FULL_DUPLEX, UE_REG_ATR_FULL_RXSIDE) - ) - (UNIT_TX, map_list_of - (ATR_REG_IDLE, UE_REG_ATR_IDLE_TXSIDE) - (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_TXSIDE) - (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_TXSIDE) - (ATR_REG_FULL_DUPLEX, UE_REG_ATR_FULL_TXSIDE) - ) - ; - _iface->poke16(unit_to_atr_to_addr[unit][atr], value); -} - -void usrp_e_dboard_iface::set_gpio_debug(unit_t unit, int which){ - //set this unit to all outputs - this->set_gpio_ddr(unit, 0xffff); - - //calculate the debug selections - boost::uint32_t dbg_sels = 0x0; - int sel = (which == 0)? GPIO_SEL_DEBUG_0 : GPIO_SEL_DEBUG_1; - for(size_t i = 0; i < 16; i++) dbg_sels |= sel << i; - - //set the debug on and which debug selection - switch(unit){ - case UNIT_RX: - _iface->poke16(UE_REG_GPIO_RX_DBG, 0xffff); - _iface->poke16(UE_REG_GPIO_RX_SEL, dbg_sels); - return; - - case UNIT_TX: - _iface->poke16(UE_REG_GPIO_TX_DBG, 0xffff); - _iface->poke16(UE_REG_GPIO_TX_SEL, dbg_sels); - return; - } -} - -/*********************************************************************** - * SPI - **********************************************************************/ -/*! - * Static function to convert a unit type to a spi slave device number. - * \param unit the dboard interface unit type enum - * \return the slave device number - */ -static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){ - switch(unit){ - case dboard_iface::UNIT_TX: return UE_SPI_SS_TX_DB; - case dboard_iface::UNIT_RX: return UE_SPI_SS_RX_DB; - } - throw std::invalid_argument("unknown unit type"); -} - -void usrp_e_dboard_iface::write_spi( - unit_t unit, - const spi_config_t &config, - boost::uint32_t data, - size_t num_bits -){ - _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/); -} - -boost::uint32_t usrp_e_dboard_iface::read_write_spi( - unit_t unit, - const spi_config_t &config, - boost::uint32_t data, - size_t num_bits -){ - return _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, true /*rb*/); -} - -/*********************************************************************** - * I2C - **********************************************************************/ -void usrp_e_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ - return _iface->write_i2c(addr, bytes); -} - -byte_vector_t usrp_e_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){ - return _iface->read_i2c(addr, num_bytes); -} - -/*********************************************************************** - * Aux DAX/ADC - **********************************************************************/ -void usrp_e_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, float value){ - //same aux dacs for each unit - static const uhd::dict which_to_aux_dac = map_list_of - (AUX_DAC_A, usrp_e_codec_ctrl::AUX_DAC_A) - (AUX_DAC_B, usrp_e_codec_ctrl::AUX_DAC_B) - (AUX_DAC_C, usrp_e_codec_ctrl::AUX_DAC_C) - (AUX_DAC_D, usrp_e_codec_ctrl::AUX_DAC_D) - ; - _codec->write_aux_dac(which_to_aux_dac[which], value); -} - -float usrp_e_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which){ - static const uhd::dict< - unit_t, uhd::dict - > unit_to_which_to_aux_adc = map_list_of - (UNIT_RX, map_list_of - (AUX_ADC_A, usrp_e_codec_ctrl::AUX_ADC_A1) - (AUX_ADC_B, usrp_e_codec_ctrl::AUX_ADC_B1) - ) - (UNIT_TX, map_list_of - (AUX_ADC_A, usrp_e_codec_ctrl::AUX_ADC_A2) - (AUX_ADC_B, usrp_e_codec_ctrl::AUX_ADC_B2) - ) - ; - return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]); -} diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp deleted file mode 100644 index f2840dcfc..000000000 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ /dev/null @@ -1,172 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" -#include -#include -#include -#include -#include -#include - -using namespace uhd; -using namespace uhd::usrp; - -/*********************************************************************** - * Dboard Initialization - **********************************************************************/ -void usrp_e_impl::dboard_init(void){ - _rx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes())); - _tx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_TX_DB, 0, dboard_eeprom_t::num_bytes())); - - //create a new dboard interface and manager - _dboard_iface = make_usrp_e_dboard_iface( - _iface, _clock_ctrl, _codec_ctrl - ); - _dboard_manager = dboard_manager::make( - _rx_db_eeprom.id, _tx_db_eeprom.id, _dboard_iface - ); - - //setup the dboard proxies - _rx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::rx_dboard_get, this, _1, _2), - boost::bind(&usrp_e_impl::rx_dboard_set, this, _1, _2) - ); - _tx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::tx_dboard_get, this, _1, _2), - boost::bind(&usrp_e_impl::tx_dboard_set, this, _1, _2) - ); -} - -/*********************************************************************** - * RX Dboard Get - **********************************************************************/ -void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - //handle the get request conditioned on the key - switch(key.as()){ - case DBOARD_PROP_NAME: - val = std::string("usrp-e dboard (rx unit)"); - return; - - case DBOARD_PROP_SUBDEV: - val = _dboard_manager->get_rx_subdev(key.name); - return; - - case DBOARD_PROP_SUBDEV_NAMES: - val = _dboard_manager->get_rx_subdev_names(); - return; - - case DBOARD_PROP_DBOARD_ID: - val = _rx_db_eeprom.id; - return; - - case DBOARD_PROP_DBOARD_IFACE: - val = _dboard_iface; - return; - - case DBOARD_PROP_CODEC: - val = _rx_codec_proxy->get_link(); - return; - - case DBOARD_PROP_GAIN_GROUP: - val = make_gain_group( - _rx_db_eeprom.id, - _dboard_manager->get_rx_subdev(key.name), - _rx_codec_proxy->get_link(), - GAIN_GROUP_POLICY_RX - ); - return; - - default: UHD_THROW_PROP_GET_ERROR(); - } -} - -/*********************************************************************** - * RX Dboard Set - **********************************************************************/ -void usrp_e_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ - switch(key.as()){ - case DBOARD_PROP_DBOARD_ID: - _rx_db_eeprom.id = val.as(); - _iface->write_eeprom(I2C_ADDR_RX_DB, 0, _rx_db_eeprom.get_eeprom_bytes()); - return; - - default: UHD_THROW_PROP_SET_ERROR(); - } -} - -/*********************************************************************** - * TX Dboard Get - **********************************************************************/ -void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - //handle the get request conditioned on the key - switch(key.as()){ - case DBOARD_PROP_NAME: - val = std::string("usrp-e dboard (tx unit)"); - return; - - case DBOARD_PROP_SUBDEV: - val = _dboard_manager->get_tx_subdev(key.name); - return; - - case DBOARD_PROP_SUBDEV_NAMES: - val = _dboard_manager->get_tx_subdev_names(); - return; - - case DBOARD_PROP_DBOARD_ID: - val = _tx_db_eeprom.id; - return; - - case DBOARD_PROP_DBOARD_IFACE: - val = _dboard_iface; - return; - - case DBOARD_PROP_CODEC: - val = _tx_codec_proxy->get_link(); - return; - - case DBOARD_PROP_GAIN_GROUP: - val = make_gain_group( - _tx_db_eeprom.id, - _dboard_manager->get_tx_subdev(key.name), - _tx_codec_proxy->get_link(), - GAIN_GROUP_POLICY_TX - ); - return; - - default: UHD_THROW_PROP_GET_ERROR(); - } -} - -/*********************************************************************** - * TX Dboard Set - **********************************************************************/ -void usrp_e_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ - switch(key.as()){ - case DBOARD_PROP_DBOARD_ID: - _tx_db_eeprom.id = val.as(); - _iface->write_eeprom(I2C_ADDR_TX_DB, 0, _tx_db_eeprom.get_eeprom_bytes()); - return; - - default: UHD_THROW_PROP_SET_ERROR(); - } -} diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp deleted file mode 100644 index 97f173c1a..000000000 --- a/host/lib/usrp/usrp_e/dsp_impl.cpp +++ /dev/null @@ -1,192 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" -#include -#include -#include -#include - -#define rint boost::math::iround - -using namespace uhd; -using namespace uhd::usrp; - -/*********************************************************************** - * RX DDC Initialization - **********************************************************************/ -void usrp_e_impl::rx_ddc_init(void){ - _rx_ddc_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::rx_ddc_get, this, _1, _2), - boost::bind(&usrp_e_impl::rx_ddc_set, this, _1, _2) - ); - - //initial config and update - rx_ddc_set(DSP_PROP_FREQ_SHIFT, double(0)); - rx_ddc_set(DSP_PROP_HOST_RATE, double(64e6/10)); -} - -/*********************************************************************** - * RX DDC Get - **********************************************************************/ -void usrp_e_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - switch(key.as()){ - case DSP_PROP_NAME: - val = std::string("usrp-e ddc0"); - return; - - case DSP_PROP_OTHERS: - val = prop_names_t(); //empty - return; - - case DSP_PROP_FREQ_SHIFT: - val = _ddc_freq; - return; - - case DSP_PROP_FREQ_SHIFT_NAMES: - val = prop_names_t(1, ""); - return; - - case DSP_PROP_CODEC_RATE: - val = _clock_ctrl->get_fpga_clock_rate(); - return; - - case DSP_PROP_HOST_RATE: - val = _clock_ctrl->get_fpga_clock_rate()/_ddc_decim; - return; - - default: UHD_THROW_PROP_GET_ERROR(); - } -} - -/*********************************************************************** - * RX DDC Set - **********************************************************************/ -void usrp_e_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - switch(key.as()){ - - case DSP_PROP_FREQ_SHIFT:{ - double new_freq = val.as(); - _iface->poke32(UE_REG_DSP_RX_FREQ, - dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate()) - ); - _ddc_freq = new_freq; //shadow - } - return; - - case DSP_PROP_HOST_RATE:{ - //set the decimation - _ddc_decim = rint(_clock_ctrl->get_fpga_clock_rate()/val.as()); - _iface->poke32(UE_REG_DSP_RX_DECIM_RATE, dsp_type1::calc_cic_filter_word(_ddc_decim)); - - //set the scaling - static const boost::int16_t default_rx_scale_iq = 1024; - _iface->poke32(UE_REG_DSP_RX_SCALE_IQ, - dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq) - ); - } - return; - - default: UHD_THROW_PROP_SET_ERROR(); - } -} - -/*********************************************************************** - * TX DUC Initialization - **********************************************************************/ -void usrp_e_impl::tx_duc_init(void){ - _tx_duc_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::tx_duc_get, this, _1, _2), - boost::bind(&usrp_e_impl::tx_duc_set, this, _1, _2) - ); - - //initial config and update - tx_duc_set(DSP_PROP_FREQ_SHIFT, double(0)); - tx_duc_set(DSP_PROP_HOST_RATE, double(64e6/10)); -} - -/*********************************************************************** - * TX DUC Get - **********************************************************************/ -void usrp_e_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - switch(key.as()){ - case DSP_PROP_NAME: - val = std::string("usrp-e duc0"); - return; - - case DSP_PROP_OTHERS: - val = prop_names_t(); //empty - return; - - case DSP_PROP_FREQ_SHIFT: - val = _duc_freq; - return; - - case DSP_PROP_FREQ_SHIFT_NAMES: - val = prop_names_t(1, ""); - return; - - case DSP_PROP_CODEC_RATE: - val = _clock_ctrl->get_fpga_clock_rate(); - return; - - case DSP_PROP_HOST_RATE: - val = _clock_ctrl->get_fpga_clock_rate()/_duc_interp; - return; - - default: UHD_THROW_PROP_GET_ERROR(); - } -} - -/*********************************************************************** - * TX DUC Set - **********************************************************************/ -void usrp_e_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - switch(key.as()){ - - case DSP_PROP_FREQ_SHIFT:{ - double new_freq = val.as(); - _iface->poke32(UE_REG_DSP_TX_FREQ, - dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate()) - ); - _duc_freq = new_freq; //shadow - } - return; - - case DSP_PROP_HOST_RATE:{ - _duc_interp = rint(_clock_ctrl->get_fpga_clock_rate()/val.as()); - - //set the interpolation - _iface->poke32(UE_REG_DSP_TX_INTERP_RATE, dsp_type1::calc_cic_filter_word(_duc_interp)); - - //set the scaling - _iface->poke32(UE_REG_DSP_TX_SCALE_IQ, dsp_type1::calc_iq_scale_word(_duc_interp)); - } - return; - - default: UHD_THROW_PROP_SET_ERROR(); - } -} diff --git a/host/lib/usrp/usrp_e/fpga-downloader.cc b/host/lib/usrp/usrp_e/fpga-downloader.cc deleted file mode 100644 index 4dc537919..000000000 --- a/host/lib/usrp/usrp_e/fpga-downloader.cc +++ /dev/null @@ -1,274 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -/* - * Configuration connections - * - * CCK - MCSPI1_CLK - * DIN - MCSPI1_MOSI - * PROG_B - GPIO_175 - output (change mux) - * DONE - GPIO_173 - input (change mux) - * INIT_B - GPIO_114 - input (change mux) - * -*/ - -const unsigned int PROG_B = 175; -const unsigned int DONE = 173; -const unsigned int INIT_B = 114; - -//static std::string bit_file = "safe_u1e.bin"; - -const int BUF_SIZE = 4096; - -enum gpio_direction {IN, OUT}; - -class gpio { - public: - - gpio(unsigned int gpio_num, gpio_direction pin_direction); - - bool get_value(); - void set_value(bool state); - - private: - - std::stringstream base_path; - std::fstream value_file; -}; - -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) -{ - std::fstream export_file; - - export_file.open("/sys/class/gpio/export", std::ios::out); - if (not export_file.is_open()) throw std::runtime_error( - "Failed to open gpio export file." - ); - - export_file << gpio_num << std::endl; - - base_path << "/sys/class/gpio/gpio" << gpio_num << std::flush; - - std::fstream direction_file; - std::string direction_file_name; - - if (gpio_num != 114) { - 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; -} - -static void prepare_fpga_for_configuration(gpio &prog, gpio &)//init) -{ - - prog.set_value(true); - prog.set_value(false); - prog.set_value(true); - -#if 0 - bool ready_to_program(false); - unsigned int count(0); - do { - ready_to_program = init.get_value(); - count++; - - sleep(1); - } while (count < 10 && !ready_to_program); - - if (count == 10) { - std::cout << "FPGA not ready for programming." << std::endl; - exit(-1); - } -#endif -} - -spidev::spidev(std::string fname) -{ - int ret; - int mode = 0; - int speed = 12000000; - int bits = 8; - - 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 = 48000000; - tr.bits_per_word = 8; - - ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); - -} - -static void send_file_to_fpga(const std::string &file_name, gpio &error, gpio &done) -{ - std::ifstream bitstream; - - std::cout << "File name - " << file_name.c_str() << std::endl; - - bitstream.open(file_name.c_str(), std::ios::binary); - if (!bitstream.is_open()) - std::cout << "File " << file_name << " not opened succesfully." << std::endl; - - spidev spi("/dev/spidev1.0"); - char buf[BUF_SIZE]; - char rbuf[BUF_SIZE]; - - do { - bitstream.read(buf, BUF_SIZE); - spi.send(buf, rbuf, bitstream.gcount()); - - if (error.get_value()) - std::cout << "INIT_B went high, error occured." << std::endl; - - if (!done.get_value()) - std::cout << "Configuration complete." << std::endl; - - } while (bitstream.gcount() == BUF_SIZE); -} - -/* -int main(int argc, char *argv[]) -{ - - gpio gpio_prog_b(PROG_B, OUT); - gpio gpio_init_b(INIT_B, IN); - gpio gpio_done (DONE, IN); - - if (argc == 2) - bit_file = argv[1]; - - std::cout << "FPGA config file: " << bit_file << std::endl; - - prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); - - std::cout << "Done = " << gpio_done.get_value() << std::endl; - - send_file_to_fpga(bit_file, gpio_init_b, gpio_done); -} -*/ - -void usrp_e_load_fpga(const std::string &bin_file){ - gpio gpio_prog_b(PROG_B, OUT); - gpio gpio_init_b(INIT_B, IN); - gpio gpio_done (DONE, IN); - - std::cout << "Loading FPGA image: " << bin_file << "... " << std::flush; - - UHD_ASSERT_THROW(std::system("/sbin/rmmod usrp_e") == 0); - - prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); - - std::cout << "done = " << gpio_done.get_value() << std::endl; - - send_file_to_fpga(bin_file, gpio_init_b, gpio_done); - - UHD_ASSERT_THROW(std::system("/sbin/modprobe usrp_e") == 0); - -} - diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp deleted file mode 100644 index e863944e8..000000000 --- a/host/lib/usrp/usrp_e/io_impl.cpp +++ /dev/null @@ -1,272 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" -#include -#include -#include -#include "../../transport/vrt_packet_handler.hpp" -#include -#include -#include -#include - -using namespace uhd; -using namespace uhd::usrp; -using namespace uhd::transport; - -zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface); - -/*********************************************************************** - * Constants - **********************************************************************/ -static const size_t tx_async_report_sid = 1; -static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET; -static const bool recv_debug = false; - -/*********************************************************************** - * io impl details (internal to this file) - * - pirate crew of 1 - * - bounded buffer - * - thread loop - * - vrt packet handler states - **********************************************************************/ -struct usrp_e_impl::io_impl{ - //state management for the vrt packet handler code - vrt_packet_handler::recv_state packet_handler_recv_state; - vrt_packet_handler::send_state packet_handler_send_state; - zero_copy_if::sptr data_xport; - bool continuous_streaming; - io_impl(usrp_e_iface::sptr iface): - data_xport(usrp_e_make_mmap_zero_copy(iface)), - recv_pirate_booty(recv_booty_type::make(data_xport->get_num_recv_frames())), - async_msg_fifo(bounded_buffer::make(100/*messages deep*/)) - { - /* NOP */ - } - - ~io_impl(void){ - recv_pirate_crew_raiding = false; - recv_pirate_crew.interrupt_all(); - recv_pirate_crew.join_all(); - } - - bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs, double timeout){ - UHD_ASSERT_THROW(buffs.size() == 1); - boost::this_thread::disable_interruption di; //disable because the wait can throw - return recv_pirate_booty->pop_with_timed_wait(buffs.front(), timeout); - } - - //a pirate's life is the life for me! - void recv_pirate_loop(usrp_e_clock_ctrl::sptr); - typedef bounded_buffer recv_booty_type; - recv_booty_type::sptr recv_pirate_booty; - bounded_buffer::sptr async_msg_fifo; - boost::thread_group recv_pirate_crew; - bool recv_pirate_crew_raiding; -}; - -/*********************************************************************** - * Receive Pirate Loop - * - while raiding, loot for recv buffers - * - put booty into the alignment buffer - **********************************************************************/ -void usrp_e_impl::io_impl::recv_pirate_loop(usrp_e_clock_ctrl::sptr clock_ctrl) -{ - set_thread_priority_safe(); - recv_pirate_crew_raiding = true; - - while(recv_pirate_crew_raiding){ - managed_recv_buffer::sptr buff = this->data_xport->get_recv_buff(); - if (not buff.get()) continue; //ignore timeout/error buffers - - if (recv_debug){ - std::cout << "len " << buff->size() << std::endl; - for (size_t i = 0; i < 9; i++){ - std::cout << boost::format(" 0x%08x") % buff->cast()[i] << std::endl; - } - std::cout << std::endl << std::endl; - } - - try{ - //extract the vrt header packet info - vrt::if_packet_info_t if_packet_info; - if_packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t); - const boost::uint32_t *vrt_hdr = buff->cast(); - vrt::if_hdr_unpack_le(vrt_hdr, if_packet_info); - - //handle a tx async report message - if (if_packet_info.sid == tx_async_report_sid and if_packet_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){ - - //fill in the async metadata - async_metadata_t metadata; - metadata.channel = 0; - metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf; - metadata.time_spec = time_spec_t( - time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), clock_ctrl->get_fpga_clock_rate() - ); - metadata.event_code = vrt_packet_handler::get_context_code(vrt_hdr, if_packet_info); - - //print the famous U, and push the metadata into the message queue - if (metadata.event_code & underflow_flags) std::cerr << "U" << std::flush; - async_msg_fifo->push_with_pop_on_full(metadata); - continue; - } - - //same number of frames as the data transport -> always immediate - recv_pirate_booty->push_with_wait(buff); - - }catch(const std::exception &e){ - std::cerr << "Error (usrp-e recv pirate loop): " << e.what() << std::endl; - } - } -} - -/*********************************************************************** - * Helper Functions - **********************************************************************/ -void usrp_e_impl::io_init(void){ - //setup otw types - _send_otw_type.width = 16; - _send_otw_type.shift = 0; - _send_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; - - _recv_otw_type.width = 16; - _recv_otw_type.shift = 0; - _recv_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; - - //setup before the registers (transport called to calculate max spp) - _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface)); - - //setup rx data path - _iface->poke32(UE_REG_CTRL_RX_NSAMPS_PER_PKT, get_max_recv_samps_per_packet()); - _iface->poke32(UE_REG_CTRL_RX_NCHANNELS, 1); - _iface->poke32(UE_REG_CTRL_RX_CLEAR_OVERRUN, 1); //reset - _iface->poke32(UE_REG_CTRL_RX_VRT_HEADER, 0 - | (0x1 << 28) //if data with stream id - | (0x1 << 26) //has trailer - | (0x3 << 22) //integer time other - | (0x1 << 20) //fractional time sample count - ); - _iface->poke32(UE_REG_CTRL_RX_VRT_STREAM_ID, 0); - _iface->poke32(UE_REG_CTRL_RX_VRT_TRAILER, 0); - - //setup the tx policy - _iface->poke32(UE_REG_CTRL_TX_REPORT_SID, tx_async_report_sid); - _iface->poke32(UE_REG_CTRL_TX_POLICY, UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET); - - //spawn a pirate, yarrr! - _io_impl->recv_pirate_crew.create_thread(boost::bind( - &usrp_e_impl::io_impl::recv_pirate_loop, _io_impl.get(), _clock_ctrl - )); -} - -void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ - _io_impl->continuous_streaming = (stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - _iface->poke32(UE_REG_CTRL_RX_STREAM_CMD, dsp_type1::calc_stream_cmd_word( - stream_cmd, get_max_recv_samps_per_packet() - )); - _iface->poke32(UE_REG_CTRL_RX_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); - _iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_tick_count(_clock_ctrl->get_fpga_clock_rate())); -} - -void usrp_e_impl::handle_overrun(size_t){ - std::cerr << "O"; //the famous OOOOOOOOOOO - _iface->poke32(UE_REG_CTRL_RX_CLEAR_OVERRUN, 0); - if (_io_impl->continuous_streaming){ - this->issue_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - } -} - -/*********************************************************************** - * Data Send - **********************************************************************/ -bool get_send_buffs( - zero_copy_if::sptr trans, double timeout, - vrt_packet_handler::managed_send_buffs_t &buffs -){ - UHD_ASSERT_THROW(buffs.size() == 1); - buffs[0] = trans->get_send_buff(timeout); - return buffs[0].get() != NULL; -} - -size_t usrp_e_impl::get_max_send_samps_per_packet(void) const{ - static const size_t hdr_size = 0 - + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) - - sizeof(vrt::if_packet_info_t().cid) //no class id ever used - ; - size_t bpp = _io_impl->data_xport->get_send_frame_size() - hdr_size; - return bpp/_send_otw_type.get_sample_size(); -} - -size_t usrp_e_impl::send( - const std::vector &buffs, size_t num_samps, - const tx_metadata_t &metadata, const io_type_t &io_type, - send_mode_t send_mode, double timeout -){ - return vrt_packet_handler::send( - _io_impl->packet_handler_send_state, //last state of the send handler - buffs, num_samps, //buffer to fill - metadata, send_mode, //samples metadata - io_type, _send_otw_type, //input and output types to convert - _clock_ctrl->get_fpga_clock_rate(), //master clock tick rate - uhd::transport::vrt::if_hdr_pack_le, - boost::bind(&get_send_buffs, _io_impl->data_xport, timeout, _1), - get_max_send_samps_per_packet() - ); -} - -/*********************************************************************** - * Data Recv - **********************************************************************/ -size_t usrp_e_impl::get_max_recv_samps_per_packet(void) const{ - static const size_t hdr_size = 0 - + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) - + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer - - sizeof(vrt::if_packet_info_t().cid) //no class id ever used - ; - size_t bpp = _io_impl->data_xport->get_recv_frame_size() - hdr_size; - return bpp/_recv_otw_type.get_sample_size(); -} - -size_t usrp_e_impl::recv( - const std::vector &buffs, size_t num_samps, - rx_metadata_t &metadata, const io_type_t &io_type, - recv_mode_t recv_mode, double timeout -){ - return vrt_packet_handler::recv( - _io_impl->packet_handler_recv_state, //last state of the recv handler - buffs, num_samps, //buffer to fill - metadata, recv_mode, //samples metadata - io_type, _recv_otw_type, //input and output types to convert - _clock_ctrl->get_fpga_clock_rate(), //master clock tick rate - uhd::transport::vrt::if_hdr_unpack_le, - boost::bind(&usrp_e_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout), - boost::bind(&usrp_e_impl::handle_overrun, this, _1) - ); -} - -/*********************************************************************** - * Async Recv - **********************************************************************/ -bool usrp_e_impl::recv_async_msg( - async_metadata_t &async_metadata, double timeout -){ - boost::this_thread::disable_interruption di; //disable because the wait can throw - return _io_impl->async_msg_fifo->pop_with_timed_wait(async_metadata, timeout); -} diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp deleted file mode 100644 index f0118aa4b..000000000 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" -#include -#include -#include -#include -#include -#include - -using namespace uhd; -using namespace uhd::usrp; - -/*********************************************************************** - * Mboard Initialization - **********************************************************************/ -void usrp_e_impl::mboard_init(void){ - _mboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::mboard_get, this, _1, _2), - boost::bind(&usrp_e_impl::mboard_set, this, _1, _2) - ); - - //init the clock config - _clock_config.ref_source = clock_config_t::REF_AUTO; - _clock_config.pps_source = clock_config_t::PPS_SMA; - - //TODO poke the clock config regs -} - -/*********************************************************************** - * Mboard Get - **********************************************************************/ -void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - //handle the get request conditioned on the key - switch(key.as()){ - case MBOARD_PROP_NAME: - val = std::string("usrp-e mboard"); - return; - - case MBOARD_PROP_OTHERS: - val = prop_names_t(); - return; - - case MBOARD_PROP_RX_DBOARD: - UHD_ASSERT_THROW(key.name == ""); - val = _rx_dboard_proxy->get_link(); - return; - - case MBOARD_PROP_RX_DBOARD_NAMES: - val = prop_names_t(1, ""); //vector of size 1 with empty string - return; - - case MBOARD_PROP_TX_DBOARD: - UHD_ASSERT_THROW(key.name == ""); - val = _tx_dboard_proxy->get_link(); - return; - - case MBOARD_PROP_TX_DBOARD_NAMES: - val = prop_names_t(1, ""); //vector of size 1 with empty string - return; - - case MBOARD_PROP_RX_DSP: - UHD_ASSERT_THROW(key.name == ""); - val = _rx_ddc_proxy->get_link(); - return; - - case MBOARD_PROP_RX_DSP_NAMES: - val = prop_names_t(1, ""); - return; - - case MBOARD_PROP_TX_DSP: - UHD_ASSERT_THROW(key.name == ""); - val = _tx_duc_proxy->get_link(); - return; - - case MBOARD_PROP_TX_DSP_NAMES: - val = prop_names_t(1, ""); - return; - - case MBOARD_PROP_CLOCK_CONFIG: - val = _clock_config; - return; - - case MBOARD_PROP_RX_SUBDEV_SPEC: - val = _rx_subdev_spec; - return; - - case MBOARD_PROP_TX_SUBDEV_SPEC: - val = _tx_subdev_spec; - return; - - default: UHD_THROW_PROP_GET_ERROR(); - } -} - -/*********************************************************************** - * Mboard Set - **********************************************************************/ -void usrp_e_impl::mboard_set(const wax::obj &key, const wax::obj &val){ - //handle the get request conditioned on the key - switch(key.as()){ - - case MBOARD_PROP_STREAM_CMD: - issue_stream_cmd(val.as()); - return; - - case MBOARD_PROP_TIME_NOW: - case MBOARD_PROP_TIME_NEXT_PPS:{ - time_spec_t time_spec = val.as(); - _iface->poke32(UE_REG_TIME64_TICKS, time_spec.get_tick_count(_clock_ctrl->get_fpga_clock_rate())); - boost::uint32_t imm_flags = (key.as() == MBOARD_PROP_TIME_NOW)? 1 : 0; - _iface->poke32(UE_REG_TIME64_IMM, imm_flags); - _iface->poke32(UE_REG_TIME64_SECS, time_spec.get_full_secs()); - } - return; - - case MBOARD_PROP_RX_SUBDEV_SPEC: - _rx_subdev_spec = val.as(); - verify_rx_subdev_spec(_rx_subdev_spec, _mboard_proxy->get_link()); - //sanity check - UHD_ASSERT_THROW(_rx_subdev_spec.size() == 1); - //set the mux - _iface->poke32(UE_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word( - _dboard_manager->get_rx_subdev(_rx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as() - )); - return; - - case MBOARD_PROP_TX_SUBDEV_SPEC: - _tx_subdev_spec = val.as(); - verify_tx_subdev_spec(_tx_subdev_spec, _mboard_proxy->get_link()); - //sanity check - UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1); - //set the mux - _iface->poke32(UE_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word( - _dboard_manager->get_tx_subdev(_tx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as() - )); - return; - - default: UHD_THROW_PROP_SET_ERROR(); - } -} diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.cpp b/host/lib/usrp/usrp_e/usrp_e_iface.cpp deleted file mode 100644 index f00e92946..000000000 --- a/host/lib/usrp/usrp_e/usrp_e_iface.cpp +++ /dev/null @@ -1,194 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_iface.hpp" -#include -#include //ioctl -#include //open, close -#include //ioctl structures and constants -#include -#include //mutex -#include - -using namespace uhd; - -class usrp_e_iface_impl : public usrp_e_iface{ -public: - - int get_file_descriptor(void){ - return _node_fd; - } - - /******************************************************************* - * Structors - ******************************************************************/ - usrp_e_iface_impl(const std::string &node){ - //open the device node and check file descriptor - if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ - throw std::runtime_error(str( - boost::format("Failed to open %s") % node - )); - } - } - - ~usrp_e_iface_impl(void){ - //close the device node file descriptor - ::close(_node_fd); - } - - /******************************************************************* - * IOCTL: provides the communication base for all other calls - ******************************************************************/ - void ioctl(int request, void *mem){ - boost::mutex::scoped_lock lock(_ctrl_mutex); - - if (::ioctl(_node_fd, request, mem) < 0){ - throw std::runtime_error(str( - boost::format("ioctl failed with request %d") % request - )); - } - } - - /******************************************************************* - * Peek and Poke - ******************************************************************/ - void poke32(boost::uint32_t addr, boost::uint32_t value){ - //load the data struct - usrp_e_ctl32 data; - data.offset = addr; - data.count = 1; - data.buf[0] = value; - - //call the ioctl - this->ioctl(USRP_E_WRITE_CTL32, &data); - } - - void poke16(boost::uint32_t addr, boost::uint16_t value){ - //load the data struct - usrp_e_ctl16 data; - data.offset = addr; - data.count = 1; - data.buf[0] = value; - - //call the ioctl - this->ioctl(USRP_E_WRITE_CTL16, &data); - } - - boost::uint32_t peek32(boost::uint32_t addr){ - //load the data struct - usrp_e_ctl32 data; - data.offset = addr; - data.count = 1; - - //call the ioctl - this->ioctl(USRP_E_READ_CTL32, &data); - - return data.buf[0]; - } - - boost::uint16_t peek16(boost::uint32_t addr){ - //load the data struct - usrp_e_ctl16 data; - data.offset = addr; - data.count = 1; - - //call the ioctl - this->ioctl(USRP_E_READ_CTL16, &data); - - return data.buf[0]; - } - - /******************************************************************* - * I2C - ******************************************************************/ - static const size_t max_i2c_data_bytes = 10; - - void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ - //allocate some memory for this transaction - UHD_ASSERT_THROW(bytes.size() <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c *data = reinterpret_cast(mem); - data->addr = addr; - data->len = bytes.size(); - std::copy(bytes.begin(), bytes.end(), data->data); - - //call the spi ioctl - this->ioctl(USRP_E_I2C_WRITE, data); - } - - byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ - //allocate some memory for this transaction - UHD_ASSERT_THROW(num_bytes <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c *data = reinterpret_cast(mem); - data->addr = addr; - data->len = num_bytes; - - //call the spi ioctl - this->ioctl(USRP_E_I2C_READ, data); - - //unload the data - byte_vector_t bytes(data->len); - UHD_ASSERT_THROW(bytes.size() == num_bytes); - std::copy(data->data, data->data+bytes.size(), bytes.begin()); - return bytes; - } - - /******************************************************************* - * SPI - ******************************************************************/ - boost::uint32_t transact_spi( - int which_slave, - const spi_config_t &config, - boost::uint32_t bits, - size_t num_bits, - bool readback - ){ - //load data struct - usrp_e_spi data; - data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; - data.slave = which_slave; - data.length = num_bits; - data.data = bits; - - //load the flags - data.flags = 0; - data.flags |= (config.miso_edge == spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; - data.flags |= (config.mosi_edge == spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; - - //call the spi ioctl - this->ioctl(USRP_E_SPI, &data); - - //unload the data - return data.data; - } - -private: - int _node_fd; - boost::mutex _ctrl_mutex; -}; - -/*********************************************************************** - * Public Make Function - **********************************************************************/ -usrp_e_iface::sptr usrp_e_iface::make(const std::string &node){ - return sptr(new usrp_e_iface_impl(node)); -} diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.hpp b/host/lib/usrp/usrp_e/usrp_e_iface.hpp deleted file mode 100644 index 59aac43d9..000000000 --- a/host/lib/usrp/usrp_e/usrp_e_iface.hpp +++ /dev/null @@ -1,112 +0,0 @@ -// -// Copyright 2010 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 . -// - -#ifndef INCLUDED_USRP_E_IFACE_HPP -#define INCLUDED_USRP_E_IFACE_HPP - -#include -#include -#include -#include -#include - -//////////////////////////////////////////////////////////////////////// -// I2C addresses -//////////////////////////////////////////////////////////////////////// -#define I2C_DEV_EEPROM 0x50 // 24LC02[45]: 7-bits 1010xxx -#define I2C_ADDR_MBOARD (I2C_DEV_EEPROM | 0x0) -#define I2C_ADDR_TX_DB (I2C_DEV_EEPROM | 0x4) -#define I2C_ADDR_RX_DB (I2C_DEV_EEPROM | 0x5) -//////////////////////////////////////////////////////////////////////// - -/*! - * The usrp-e interface class: - * Provides a set of functions to implementation layer. - * Including spi, peek, poke, control... - */ -class usrp_e_iface : boost::noncopyable, public uhd::i2c_iface{ -public: - typedef boost::shared_ptr sptr; - - /*! - * Make a new usrp-e interface with the control transport. - * \param node the device node name - * \return a new usrp-e interface object - */ - static sptr make(const std::string &node); - - /*! - * Get the underlying file descriptor. - * \return the file descriptor - */ - virtual int get_file_descriptor(void) = 0; - - /*! - * Perform an ioctl call on the device node file descriptor. - * This will throw when the internal ioctl call fails. - * \param request the control word - * \param mem pointer to some memory - */ - virtual void ioctl(int request, void *mem) = 0; - - /*! - * Write a register (32 bits) - * \param addr the address - * \param data the 32bit data - */ - virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; - - /*! - * Read a register (32 bits) - * \param addr the address - * \return the 32bit data - */ - virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; - - /*! - * Write a register (16 bits) - * \param addr the address - * \param data the 16bit data - */ - virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0; - - /*! - * Read a register (16 bits) - * \param addr the address - * \return the 16bit data - */ - virtual boost::uint16_t peek16(boost::uint32_t addr) = 0; - - /*! - * Perform an spi transaction. - * \param which_slave the slave device number - * \param config spi config args - * \param data the bits to write - * \param num_bits how many bits in data - * \param readback true to readback a value - * \return spi data if readback set - */ - virtual boost::uint32_t transact_spi( - int which_slave, - const uhd::spi_config_t &config, - boost::uint32_t data, - size_t num_bits, - bool readback - ) = 0; -}; - -#endif /* INCLUDED_USRP_E_IFACE_HPP */ diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp deleted file mode 100644 index 70cc399fb..000000000 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ /dev/null @@ -1,201 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace uhd; -using namespace uhd::usrp; -namespace fs = boost::filesystem; - -/*********************************************************************** - * Helper Functions - **********************************************************************/ -static std::string abs_path(const std::string &file_path){ - return fs::system_complete(fs::path(file_path)).file_string(); -} - -/*********************************************************************** - * Discovery - **********************************************************************/ -static device_addrs_t usrp_e_find(const device_addr_t &hint){ - device_addrs_t usrp_e_addrs; - - //return an empty list of addresses when type is set to non-usrp-e - if (hint.has_key("type") and hint["type"] != "usrp-e") return usrp_e_addrs; - - //device node not provided, assume its 0 - if (not hint.has_key("node")){ - device_addr_t new_addr = hint; - new_addr["node"] = "/dev/usrp_e0"; - return usrp_e_find(new_addr); - } - - //use the given device node name - if (fs::exists(hint["node"])){ - device_addr_t new_addr; - new_addr["type"] = "usrp-e"; - new_addr["node"] = abs_path(hint["node"]); - usrp_e_addrs.push_back(new_addr); - } - - return usrp_e_addrs; -} - -/*********************************************************************** - * Make - **********************************************************************/ -static device::sptr usrp_e_make(const device_addr_t &device_addr){ - - //setup the main interface into fpga - std::string node = device_addr["node"]; - std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; - usrp_e_iface::sptr iface = usrp_e_iface::make(node); - - //------------------------------------------------------------------ - //-- Handle the FPGA loading... - //-- The image can be confimed as already loaded when: - //-- 1) The compatibility number matches. - //-- 2) The hash in the hash-file matches. - //------------------------------------------------------------------ - static const char *hash_file_path = "/tmp/usrp_e100_hash"; - - //extract the fpga path for usrp-e - std::string usrp_e_fpga_image = find_image_path( - device_addr.has_key("fpga")? device_addr["fpga"] : "usrp_e100_fpga.bin" - ); - - //calculate a hash of the fpga file - size_t fpga_hash = 0; - { - std::ifstream file(usrp_e_fpga_image.c_str()); - if (not file.good()) throw std::runtime_error( - "cannot open fpga file for read: " + usrp_e_fpga_image - ); - do{ - boost::hash_combine(fpga_hash, file.get()); - } while (file.good()); - file.close(); - } - - //read the compatibility number - boost::uint16_t fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); - - //read the hash in the hash-file - size_t loaded_hash = 0; - try{std::ifstream(hash_file_path) >> loaded_hash;}catch(...){} - - //if not loaded: load the fpga image and write the hash-file - if (fpga_compat_num != USRP_E_COMPAT_NUM or loaded_hash != fpga_hash){ - iface.reset(); - usrp_e_load_fpga(usrp_e_fpga_image); - std::cout << boost::format("re-Opening USRP-E on %s") % node << std::endl; - iface = usrp_e_iface::make(node); - try{std::ofstream(hash_file_path) << fpga_hash;}catch(...){} - } - - //check that the compatibility is correct - fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); - if (fpga_compat_num != USRP_E_COMPAT_NUM){ - throw std::runtime_error(str(boost::format( - "Expected fpga compatibility number 0x%x, but got 0x%x:\n" - "The fpga build is not compatible with the host code build." - ) % USRP_E_COMPAT_NUM % fpga_compat_num)); - } - - return device::sptr(new usrp_e_impl(iface)); -} - -UHD_STATIC_BLOCK(register_usrp_e_device){ - device::register_device(&usrp_e_find, &usrp_e_make); -} - -/*********************************************************************** - * Structors - **********************************************************************/ -usrp_e_impl::usrp_e_impl(usrp_e_iface::sptr iface): _iface(iface){ - - //setup interfaces into hardware - _clock_ctrl = usrp_e_clock_ctrl::make(_iface); - _codec_ctrl = usrp_e_codec_ctrl::make(_iface); - - //initialize the mboard - mboard_init(); - - //initialize the dboards - dboard_init(); - - //initialize the dsps - rx_ddc_init(); - tx_duc_init(); - - //init the codec properties - codec_init(); - - //init the io send/recv - io_init(); - - //set default subdev specs - this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t()); - this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t()); -} - -usrp_e_impl::~usrp_e_impl(void){ - /* NOP */ -} - -/*********************************************************************** - * Device Get - **********************************************************************/ -void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - //handle the get request conditioned on the key - switch(key.as()){ - case DEVICE_PROP_NAME: - val = std::string("usrp-e device"); - return; - - case DEVICE_PROP_MBOARD: - UHD_ASSERT_THROW(key.name == ""); - val = _mboard_proxy->get_link(); - return; - - case DEVICE_PROP_MBOARD_NAMES: - val = prop_names_t(1, ""); //vector of size 1 with empty string - return; - - default: UHD_THROW_PROP_GET_ERROR(); - } -} - -/*********************************************************************** - * Device Set - **********************************************************************/ -void usrp_e_impl::set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); -} diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp deleted file mode 100644 index b5f21810d..000000000 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ /dev/null @@ -1,164 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_iface.hpp" -#include "clock_ctrl.hpp" -#include "codec_ctrl.hpp" -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef INCLUDED_USRP_E_IMPL_HPP -#define INCLUDED_USRP_E_IMPL_HPP - -static const boost::uint16_t USRP_E_COMPAT_NUM = 0x02; - -//! load an fpga image from a bin file into the usrp-e fpga -extern void usrp_e_load_fpga(const std::string &bin_file); - -/*! - * Make a usrp-e dboard interface. - * \param iface the usrp-e interface object - * \param clock the clock control interface - * \param codec the codec control interface - * \return a sptr to a new dboard interface - */ -uhd::usrp::dboard_iface::sptr make_usrp_e_dboard_iface( - usrp_e_iface::sptr iface, - usrp_e_clock_ctrl::sptr clock, - usrp_e_codec_ctrl::sptr codec -); - -/*! - * Simple wax obj proxy class: - * Provides a wax obj interface for a set and a get function. - * This allows us to create nested properties structures - * while maintaining flattened code within the implementation. - */ -class wax_obj_proxy : public wax::obj{ -public: - typedef boost::function get_t; - typedef boost::function set_t; - typedef boost::shared_ptr sptr; - - static sptr make(const get_t &get, const set_t &set){ - return sptr(new wax_obj_proxy(get, set)); - } - -private: - get_t _get; set_t _set; - wax_obj_proxy(const get_t &get, const set_t &set): _get(get), _set(set){}; - void get(const wax::obj &key, wax::obj &val){return _get(key, val);} - void set(const wax::obj &key, const wax::obj &val){return _set(key, val);} -}; - -/*! - * USRP1E implementation guts: - * The implementation details are encapsulated here. - * Handles properties on the mboard, dboard, dsps... - */ -class usrp_e_impl : public uhd::device{ -public: - //structors - usrp_e_impl(usrp_e_iface::sptr); - ~usrp_e_impl(void); - - //the io interface - size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t, double); - size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, double); - bool recv_async_msg(uhd::async_metadata_t &, double); - size_t get_max_send_samps_per_packet(void) const; - size_t get_max_recv_samps_per_packet(void) const; - -private: - //interface to ioctls and file descriptor - usrp_e_iface::sptr _iface; - - //handle io stuff - UHD_PIMPL_DECL(io_impl) _io_impl; - uhd::otw_type_t _send_otw_type, _recv_otw_type; - void io_init(void); - void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd); - void handle_overrun(size_t); - - //configuration shadows - uhd::clock_config_t _clock_config; - //TODO otw type recv/send - - //ad9522 clock control - usrp_e_clock_ctrl::sptr _clock_ctrl; - - //ad9862 codec control - usrp_e_codec_ctrl::sptr _codec_ctrl; - - //device functions and settings - void get(const wax::obj &, wax::obj &); - void set(const wax::obj &, const wax::obj &); - - //mboard functions and settings - void mboard_init(void); - void mboard_get(const wax::obj &, wax::obj &); - void mboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _mboard_proxy; - uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec; - - //xx dboard functions and settings - void dboard_init(void); - uhd::usrp::dboard_manager::sptr _dboard_manager; - uhd::usrp::dboard_iface::sptr _dboard_iface; - - //rx dboard functions and settings - uhd::usrp::dboard_eeprom_t _rx_db_eeprom; - void rx_dboard_get(const wax::obj &, wax::obj &); - void rx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _rx_dboard_proxy; - - //tx dboard functions and settings - uhd::usrp::dboard_eeprom_t _tx_db_eeprom; - void tx_dboard_get(const wax::obj &, wax::obj &); - void tx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _tx_dboard_proxy; - - //rx ddc functions and settings - void rx_ddc_init(void); - void rx_ddc_get(const wax::obj &, wax::obj &); - void rx_ddc_set(const wax::obj &, const wax::obj &); - double _ddc_freq; size_t _ddc_decim; - wax_obj_proxy::sptr _rx_ddc_proxy; - - //tx duc functions and settings - void tx_duc_init(void); - void tx_duc_get(const wax::obj &, wax::obj &); - void tx_duc_set(const wax::obj &, const wax::obj &); - double _duc_freq; size_t _duc_interp; - wax_obj_proxy::sptr _tx_duc_proxy; - - //codec functions and settings - void codec_init(void); - void rx_codec_get(const wax::obj &, wax::obj &); - void rx_codec_set(const wax::obj &, const wax::obj &); - void tx_codec_get(const wax::obj &, wax::obj &); - void tx_codec_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _rx_codec_proxy, _tx_codec_proxy; -}; - -#endif /* INCLUDED_USRP_E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp deleted file mode 100644 index 274bb043e..000000000 --- a/host/lib/usrp/usrp_e/usrp_e_mmap_zero_copy.cpp +++ /dev/null @@ -1,215 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_iface.hpp" -#include -#include -#include -#include //mmap -#include //getpagesize -#include //poll -#include -#include -#include - -using namespace uhd; -using namespace uhd::transport; - -static const bool fp_verbose = false; //fast-path verbose -static const bool sp_verbose = false; //slow-path verbose -static const size_t poll_breakout = 10; //how many poll timeouts constitute a full timeout - -/*********************************************************************** - * The zero copy interface implementation - **********************************************************************/ -class usrp_e_mmap_zero_copy_impl : public zero_copy_if, public boost::enable_shared_from_this { -public: - usrp_e_mmap_zero_copy_impl(usrp_e_iface::sptr iface): - _fd(iface->get_file_descriptor()), _recv_index(0), _send_index(0) - { - //get system sizes - iface->ioctl(USRP_E_GET_RB_INFO, &_rb_size); - size_t page_size = getpagesize(); - _frame_size = page_size/2; - - //calculate the memory size - _map_size = - (_rb_size.num_pages_rx_flags + _rb_size.num_pages_tx_flags) * page_size + - (_rb_size.num_rx_frames + _rb_size.num_tx_frames) * _frame_size; - - //print sizes summary - if (sp_verbose){ - std::cout << "page_size: " << page_size << std::endl; - std::cout << "frame_size: " << _frame_size << std::endl; - std::cout << "num_pages_rx_flags: " << _rb_size.num_pages_rx_flags << std::endl; - std::cout << "num_rx_frames: " << _rb_size.num_rx_frames << std::endl; - std::cout << "num_pages_tx_flags: " << _rb_size.num_pages_tx_flags << std::endl; - std::cout << "num_tx_frames: " << _rb_size.num_tx_frames << std::endl; - std::cout << "map_size: " << _map_size << std::endl; - } - - //call mmap to get the memory - _mapped_mem = ::mmap( - NULL, _map_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0 - ); - UHD_ASSERT_THROW(_mapped_mem != MAP_FAILED); - - //calculate the memory offsets for info and buffers - size_t recv_info_off = 0; - size_t recv_buff_off = recv_info_off + (_rb_size.num_pages_rx_flags * page_size); - size_t send_info_off = recv_buff_off + (_rb_size.num_rx_frames * _frame_size); - size_t send_buff_off = send_info_off + (_rb_size.num_pages_tx_flags * page_size); - - //print offset summary - if (sp_verbose){ - std::cout << "recv_info_off: " << recv_info_off << std::endl; - std::cout << "recv_buff_off: " << recv_buff_off << std::endl; - std::cout << "send_info_off: " << send_info_off << std::endl; - std::cout << "send_buff_off: " << send_buff_off << std::endl; - } - - //set the internal pointers for info and buffers - typedef ring_buffer_info (*rbi_pta)[]; - char *rb_ptr = reinterpret_cast(_mapped_mem); - _recv_info = reinterpret_cast(rb_ptr + recv_info_off); - _recv_buff = rb_ptr + recv_buff_off; - _send_info = reinterpret_cast(rb_ptr + send_info_off); - _send_buff = rb_ptr + send_buff_off; - } - - ~usrp_e_mmap_zero_copy_impl(void){ - if (sp_verbose) std::cout << "cleanup: munmap" << std::endl; - ::munmap(_mapped_mem, _map_size); - } - - managed_recv_buffer::sptr get_recv_buff(double timeout){ - if (fp_verbose) std::cout << "get_recv_buff: " << _recv_index << std::endl; - - //grab pointers to the info and buffer - ring_buffer_info *info = (*_recv_info) + _recv_index; - void *mem = _recv_buff + _frame_size*_recv_index; - - //poll/wait for a ready frame - if (not (info->flags & RB_USER)){ - for (size_t i = 0; i < poll_breakout; i++){ - pollfd pfd; - pfd.fd = _fd; - pfd.events = POLLIN; - ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3/poll_breakout)); - if (fp_verbose) std::cout << " POLLIN: " << poll_ret << std::endl; - if (poll_ret > 0) goto found_user_frame; //good poll, continue on - } - return managed_recv_buffer::sptr(); //timed-out for real - } found_user_frame: - - //the process has claimed the frame - info->flags = RB_USER_PROCESS; - - //increment the index for the next call - if (++_recv_index == size_t(_rb_size.num_rx_frames)) _recv_index = 0; - - //return the managed buffer for this frame - if (fp_verbose) std::cout << " make_recv_buff: " << info->len << std::endl; - return managed_recv_buffer::make_safe( - boost::asio::const_buffer(mem, info->len), - boost::bind(&usrp_e_mmap_zero_copy_impl::release, shared_from_this(), info) - ); - } - - size_t get_num_recv_frames(void) const{ - return _rb_size.num_rx_frames; - } - - size_t get_recv_frame_size(void) const{ - return _frame_size; - } - - managed_send_buffer::sptr get_send_buff(double timeout){ - if (fp_verbose) std::cout << "get_send_buff: " << _send_index << std::endl; - - //grab pointers to the info and buffer - ring_buffer_info *info = (*_send_info) + _send_index; - void *mem = _send_buff + _frame_size*_send_index; - - //poll/wait for a ready frame - if (not (info->flags & RB_KERNEL)){ - pollfd pfd; - pfd.fd = _fd; - pfd.events = POLLOUT; - ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3)); - if (fp_verbose) std::cout << " POLLOUT: " << poll_ret << std::endl; - if (poll_ret <= 0) return managed_send_buffer::sptr(); - } - - //increment the index for the next call - if (++_send_index == size_t(_rb_size.num_tx_frames)) _send_index = 0; - - //return the managed buffer for this frame - if (fp_verbose) std::cout << " make_send_buff: " << _frame_size << std::endl; - return managed_send_buffer::make_safe( - boost::asio::mutable_buffer(mem, _frame_size), - boost::bind(&usrp_e_mmap_zero_copy_impl::commit, shared_from_this(), info, _1) - ); - } - - size_t get_num_send_frames(void) const{ - return _rb_size.num_tx_frames; - } - - size_t get_send_frame_size(void) const{ - return _frame_size; - } - -private: - - void release(ring_buffer_info *info){ - if (fp_verbose) std::cout << "recv buff: release" << std::endl; - info->flags = RB_KERNEL; - } - - void commit(ring_buffer_info *info, size_t len){ - if (fp_verbose) std::cout << "send buff: commit " << len << std::endl; - info->len = len; - info->flags = RB_USER; - if (::write(_fd, NULL, 0) < 0){ - std::cerr << UHD_THROW_SITE_INFO("write error") << std::endl; - } - } - - int _fd; - - //the mapped memory itself - void *_mapped_mem; - - //mapped memory sizes - usrp_e_ring_buffer_size_t _rb_size; - size_t _frame_size, _map_size; - - //pointers to sections in the mapped memory - ring_buffer_info (*_recv_info)[], (*_send_info)[]; - char *_recv_buff, *_send_buff; - - //indexes into sub-sections of mapped memory - size_t _recv_index, _send_index; -}; - -/*********************************************************************** - * The zero copy interface make function - **********************************************************************/ -zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface){ - return zero_copy_if::sptr(new usrp_e_mmap_zero_copy_impl(iface)); -} diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp deleted file mode 100644 index 8bfb08b6f..000000000 --- a/host/lib/usrp/usrp_e/usrp_e_regs.hpp +++ /dev/null @@ -1,198 +0,0 @@ - - -//////////////////////////////////////////////////////////////// -// -// Memory map for embedded wishbone bus -// -//////////////////////////////////////////////////////////////// - -// All addresses are byte addresses. All accesses are word (16-bit) accesses. -// This means that address bit 0 is usually 0. -// There are 11 bits of address for the control. - -#ifndef __USRP_E_REGS_H -#define __USRP_E_REGS_H - -///////////////////////////////////////////////////// -// Slave pointers - -#define UE_REG_SLAVE(n) ((n)<<7) -#define UE_REG_SR_ADDR(n) ((UE_REG_SLAVE(5)) + (4*(n))) - -///////////////////////////////////////////////////// -// Slave 0 -- Misc Regs - -#define UE_REG_MISC_BASE UE_REG_SLAVE(0) - -#define UE_REG_MISC_LED UE_REG_MISC_BASE + 0 -#define UE_REG_MISC_SW UE_REG_MISC_BASE + 2 -#define UE_REG_MISC_CGEN_CTRL UE_REG_MISC_BASE + 4 -#define UE_REG_MISC_CGEN_ST UE_REG_MISC_BASE + 6 -#define UE_REG_MISC_TEST UE_REG_MISC_BASE + 8 -#define UE_REG_MISC_RX_LEN UE_REG_MISC_BASE + 10 -#define UE_REG_MISC_TX_LEN UE_REG_MISC_BASE + 12 -#define UE_REG_MISC_XFER_RATE UE_REG_MISC_BASE + 14 -#define UE_REG_MISC_COMPAT UE_REG_MISC_BASE + 16 - -///////////////////////////////////////////////////// -// Slave 1 -- UART -// CLKDIV is 16 bits, others are only 8 - -#define UE_REG_UART_BASE UE_REG_SLAVE(1) - -#define UE_REG_UART_CLKDIV UE_REG_UART_BASE + 0 -#define UE_REG_UART_TXLEVEL UE_REG_UART_BASE + 2 -#define UE_REG_UART_RXLEVEL UE_REG_UART_BASE + 4 -#define UE_REG_UART_TXCHAR UE_REG_UART_BASE + 6 -#define UE_REG_UART_RXCHAR UE_REG_UART_BASE + 8 - -///////////////////////////////////////////////////// -// Slave 2 -- SPI Core -// This should be accessed through the IOCTL -// Users should not touch directly - -#define UE_REG_SPI_BASE UE_REG_SLAVE(2) - -//spi slave constants -#define UE_SPI_SS_AD9522 (1 << 3) -#define UE_SPI_SS_AD9862 (1 << 2) -#define UE_SPI_SS_TX_DB (1 << 1) -#define UE_SPI_SS_RX_DB (1 << 0) - -//////////////////////////////////////////////// -// Slave 3 -- I2C Core -// This should be accessed through the IOCTL -// Users should not touch directly - -#define UE_REG_I2C_BASE UE_REG_SLAVE(3) - - -//////////////////////////////////////////////// -// Slave 4 -- GPIO - -#define UE_REG_GPIO_BASE UE_REG_SLAVE(4) - -#define UE_REG_GPIO_RX_IO UE_REG_GPIO_BASE + 0 -#define UE_REG_GPIO_TX_IO UE_REG_GPIO_BASE + 2 -#define UE_REG_GPIO_RX_DDR UE_REG_GPIO_BASE + 4 -#define UE_REG_GPIO_TX_DDR UE_REG_GPIO_BASE + 6 -#define UE_REG_GPIO_RX_SEL UE_REG_GPIO_BASE + 8 -#define UE_REG_GPIO_TX_SEL UE_REG_GPIO_BASE + 10 -#define UE_REG_GPIO_RX_DBG UE_REG_GPIO_BASE + 12 -#define UE_REG_GPIO_TX_DBG UE_REG_GPIO_BASE + 14 - -//possible bit values for sel when dbg is 0: -#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg -#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic - -//possible bit values for sel when dbg is 1: -#define GPIO_SEL_DEBUG_0 0 // if pin is an output, debug lines from FPGA fabric -#define GPIO_SEL_DEBUG_1 1 // if pin is an output, debug lines from FPGA fabric - - -//////////////////////////////////////////////////// -// Slave 5 -- Settings Bus -// -// Output-only, no readback, 32 registers total -// Each register must be written 32 bits at a time -// First the address xxx_xx00 and then xxx_xx10 - -#define UE_REG_SETTINGS_BASE UE_REG_SLAVE(5) - -/////////////////////////////////////////////////// -// Slave 6 -- ATR Controller -// 16 regs - -#define UE_REG_ATR_BASE UE_REG_SLAVE(6) - -#define UE_REG_ATR_IDLE_RXSIDE UE_REG_ATR_BASE + 0 -#define UE_REG_ATR_IDLE_TXSIDE UE_REG_ATR_BASE + 2 -#define UE_REG_ATR_INTX_RXSIDE UE_REG_ATR_BASE + 4 -#define UE_REG_ATR_INTX_TXSIDE UE_REG_ATR_BASE + 6 -#define UE_REG_ATR_INRX_RXSIDE UE_REG_ATR_BASE + 8 -#define UE_REG_ATR_INRX_TXSIDE UE_REG_ATR_BASE + 10 -#define UE_REG_ATR_FULL_RXSIDE UE_REG_ATR_BASE + 12 -#define UE_REG_ATR_FULL_TXSIDE UE_REG_ATR_BASE + 14 - -///////////////////////////////////////////////// -// DSP RX Regs -//////////////////////////////////////////////// -#define UE_REG_DSP_RX_FREQ UE_REG_SR_ADDR(0) -#define UE_REG_DSP_RX_SCALE_IQ UE_REG_SR_ADDR(1) // {scale_i,scale_q} -#define UE_REG_DSP_RX_DECIM_RATE UE_REG_SR_ADDR(2) // hb and decim rate -#define UE_REG_DSP_RX_DCOFFSET_I UE_REG_SR_ADDR(3) // Bit 31 high sets fixed offset mode, using lower 14 bits, // otherwise it is automatic -#define UE_REG_DSP_RX_DCOFFSET_Q UE_REG_SR_ADDR(4) // Bit 31 high sets fixed offset mode, using lower 14 bits -#define UE_REG_DSP_RX_MUX UE_REG_SR_ADDR(5) - -/////////////////////////////////////////////////// -// VITA RX CTRL regs -/////////////////////////////////////////////////// -// The following 3 are logically a single command register. -// They are clocked into the underlying fifo when time_ticks is written. -#define UE_REG_CTRL_RX_STREAM_CMD UE_REG_SR_ADDR(8) // {now, chain, num_samples(30) -#define UE_REG_CTRL_RX_TIME_SECS UE_REG_SR_ADDR(9) -#define UE_REG_CTRL_RX_TIME_TICKS UE_REG_SR_ADDR(10) -#define UE_REG_CTRL_RX_CLEAR_OVERRUN UE_REG_SR_ADDR(11) // write anything to clear overrun -#define UE_REG_CTRL_RX_VRT_HEADER UE_REG_SR_ADDR(12) // word 0 of packet. FPGA fills in packet counter -#define UE_REG_CTRL_RX_VRT_STREAM_ID UE_REG_SR_ADDR(13) // word 1 of packet. -#define UE_REG_CTRL_RX_VRT_TRAILER UE_REG_SR_ADDR(14) -#define UE_REG_CTRL_RX_NSAMPS_PER_PKT UE_REG_SR_ADDR(15) -#define UE_REG_CTRL_RX_NCHANNELS UE_REG_SR_ADDR(16) // 1 in basic case, up to 4 for vector sources - -///////////////////////////////////////////////// -// DSP TX Regs -//////////////////////////////////////////////// -#define UE_REG_DSP_TX_FREQ UE_REG_SR_ADDR(17) -#define UE_REG_DSP_TX_SCALE_IQ UE_REG_SR_ADDR(18) // {scale_i,scale_q} -#define UE_REG_DSP_TX_INTERP_RATE UE_REG_SR_ADDR(19) -#define UE_REG_DSP_TX_UNUSED UE_REG_SR_ADDR(20) -#define UE_REG_DSP_TX_MUX UE_REG_SR_ADDR(21) - -///////////////////////////////////////////////// -// VITA TX CTRL regs -//////////////////////////////////////////////// -#define UE_REG_CTRL_TX_NCHANNELS UE_REG_SR_ADDR(24) -#define UE_REG_CTRL_TX_CLEAR_UNDERRUN UE_REG_SR_ADDR(25) -#define UE_REG_CTRL_TX_REPORT_SID UE_REG_SR_ADDR(26) -#define UE_REG_CTRL_TX_POLICY UE_REG_SR_ADDR(27) - -#define UE_FLAG_CTRL_TX_POLICY_WAIT (0x1 << 0) -#define UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET (0x1 << 1) -#define UE_FLAG_CTRL_TX_POLICY_NEXT_BURST (0x1 << 2) - -///////////////////////////////////////////////// -// VITA49 64 bit time (write only) -//////////////////////////////////////////////// - /*! - * \brief Time 64 flags - * - *
-   *
-   *    3                   2                   1
-   *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
-   * +-----------------------------------------------------------+-+-+
-   * |                                                           |S|P|
-   * +-----------------------------------------------------------+-+-+
-   *
-   * P - PPS edge selection (0=negedge, 1=posedge, default=0)
-   * S - Source (0=sma, 1=mimo, 0=default)
-   *
-   * 
- */ -#define UE_REG_TIME64_SECS UE_REG_SR_ADDR(28) // value to set absolute secs to on next PPS -#define UE_REG_TIME64_TICKS UE_REG_SR_ADDR(29) // value to set absolute ticks to on next PPS -#define UE_REG_TIME64_FLAGS UE_REG_SR_ADDR(30) // flags - see chart above -#define UE_REG_TIME64_IMM UE_REG_SR_ADDR(31) // set immediate (0=latch on next pps, 1=latch immediate, default=0) -#define UE_REG_TIME64_TPS UE_REG_SR_ADDR(31) // clock ticks per second (counter rollover) - -//pps flags (see above) -#define UE_FLAG_TIME64_PPS_NEGEDGE (0 << 0) -#define UE_FLAG_TIME64_PPS_POSEDGE (1 << 0) -#define UE_FLAG_TIME64_PPS_SMA (0 << 1) -#define UE_FLAG_TIME64_PPS_MIMO (1 << 1) - -#define UE_FLAG_TIME64_LATCH_NOW 1 -#define UE_FLAG_TIME64_LATCH_NEXT_PPS 0 - -#endif - diff --git a/host/lib/usrp/usrp_e100/CMakeLists.txt b/host/lib/usrp/usrp_e100/CMakeLists.txt new file mode 100644 index 000000000..17ef53152 --- /dev/null +++ b/host/lib/usrp/usrp_e100/CMakeLists.txt @@ -0,0 +1,64 @@ +# +# Copyright 2010 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 . +# + +#This file will be included by cmake, use absolute paths! + +######################################################################## +# Conditionally configure the USRP-E100 support +######################################################################## +MESSAGE(STATUS "Configuring USRP-E100 support...") + +INCLUDE(CheckIncludeFileCXX) +CHECK_INCLUDE_FILE_CXX(linux/usrp_e.h HAVE_LINUX_USRP_E_H) + +SET(ENABLE_USRP_E TRUE) + +IF(DEFINED ENABLE_USRP_E100) + IF(ENABLE_USRP_E100) + MESSAGE(STATUS "USRP-E100 support enabled by configure flag") + ELSE(ENABLE_USRP_E100) + MESSAGE(STATUS "USRP-E100 support disabled by configure flag") + ENDIF(ENABLE_USRP_E100) +ELSE(DEFINED ENABLE_USRP_E100) #not defined: automatic enabling of component + SET(ENABLE_USRP_E100 ${HAVE_LINUX_USRP_E_H}) +ENDIF(DEFINED ENABLE_USRP_E100) +SET(ENABLE_USRP_E100 ${ENABLE_USRP_E100} CACHE BOOL "enable USRP-E100 support") + +IF(ENABLE_USRP_E100) + MESSAGE(STATUS " Building USRP-E100 support.") + LIBUHD_APPEND_SOURCES( + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/clock_ctrl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/clock_ctrl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/codec_ctrl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/codec_ctrl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/codec_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/dboard_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/dboard_iface.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/dsp_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/fpga-downloader.cc + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/io_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/mboard_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_impl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_iface.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_iface.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_regs.hpp + ) +ELSE(ENABLE_USRP_E100) + MESSAGE(STATUS " Skipping USRP-E100 support.") +ENDIF(ENABLE_USRP_E100) diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.cpp b/host/lib/usrp/usrp_e100/clock_ctrl.cpp new file mode 100644 index 000000000..9d4625305 --- /dev/null +++ b/host/lib/usrp/usrp_e100/clock_ctrl.cpp @@ -0,0 +1,237 @@ +// +// Copyright 2010 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 . +// + +#include "clock_ctrl.hpp" +#include "ad9522_regs.hpp" +#include +#include +#include "usrp_e_regs.hpp" //spi slave constants +#include +#include +#include +#include + +using namespace uhd; + +template static void set_clock_divider( + size_t divider, div_type &low, div_type &high, bypass_type &bypass +){ + high = divider/2 - 1; + low = divider - high - 2; + bypass = (divider == 1)? 1 : 0; +} + +/*********************************************************************** + * Constants + **********************************************************************/ +static const bool enable_test_clock = false; +static const size_t ref_clock_doubler = 2; //enabled below +static const double ref_clock_rate = 10e6 * ref_clock_doubler; + +static const size_t r_counter = 1; +static const size_t a_counter = 0; +static const size_t b_counter = 20 / ref_clock_doubler; +static const size_t prescaler = 8; //set below with enum, set to 8 when input is under 2400 MHz +static const size_t vco_divider = 5; //set below with enum + +static const size_t n_counter = prescaler * b_counter + a_counter; +static const size_t vco_clock_rate = ref_clock_rate/r_counter * n_counter; //between 1400 and 1800 MHz +static const double master_clock_rate = vco_clock_rate/vco_divider; + +static const size_t fpga_clock_divider = size_t(master_clock_rate/64e6); +static const size_t codec_clock_divider = size_t(master_clock_rate/64e6); + +/*********************************************************************** + * Clock Control Implementation + **********************************************************************/ +class usrp_e_clock_ctrl_impl : public usrp_e_clock_ctrl{ +public: + usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface){ + _iface = iface; + + //init the clock gen registers + //Note: out0 should already be clocking the FPGA or this isnt going to work + _ad9522_regs.sdo_active = ad9522_regs_t::SDO_ACTIVE_SDO_SDIO; + _ad9522_regs.enable_clock_doubler = 1; //enable ref clock doubler + _ad9522_regs.enb_stat_eeprom_at_stat_pin = 0; //use status pin + _ad9522_regs.status_pin_control = 0x1; //n divider + _ad9522_regs.ld_pin_control = 0x00; //dld + _ad9522_regs.refmon_pin_control = 0x12; //show ref2 + + _ad9522_regs.enable_ref2 = 1; + _ad9522_regs.enable_ref1 = 0; + _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF2; + + _ad9522_regs.set_r_counter(r_counter); + _ad9522_regs.a_counter = a_counter; + _ad9522_regs.set_b_counter(b_counter); + _ad9522_regs.prescaler_p = ad9522_regs_t::PRESCALER_P_DIV8_9; + + _ad9522_regs.pll_power_down = ad9522_regs_t::PLL_POWER_DOWN_NORMAL; + _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_1_2MA; + + _ad9522_regs.vco_calibration_now = 1; //calibrate it! + _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; + _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_VCO; + + //setup fpga master clock + _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS; + set_clock_divider(fpga_clock_divider, + _ad9522_regs.divider0_low_cycles, + _ad9522_regs.divider0_high_cycles, + _ad9522_regs.divider0_bypass + ); + + //setup codec clock + _ad9522_regs.out3_format = ad9522_regs_t::OUT3_FORMAT_LVDS; + set_clock_divider(codec_clock_divider, + _ad9522_regs.divider1_low_cycles, + _ad9522_regs.divider1_high_cycles, + _ad9522_regs.divider1_bypass + ); + + //setup test clock (same divider as codec clock) + _ad9522_regs.out4_format = ad9522_regs_t::OUT4_FORMAT_CMOS; + _ad9522_regs.out4_cmos_configuration = (enable_test_clock)? + ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON : + ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF; + + //setup a list of register ranges to write + typedef std::pair range_t; + static const std::vector ranges = boost::assign::list_of + (range_t(0x000, 0x000)) (range_t(0x010, 0x01F)) + (range_t(0x0F0, 0x0FD)) (range_t(0x190, 0x19B)) + (range_t(0x1E0, 0x1E1)) (range_t(0x230, 0x230)) + ; + + //write initial register values and latch/update + BOOST_FOREACH(const range_t &range, ranges){ + for(boost::uint16_t addr = range.first; addr <= range.second; addr++){ + this->send_reg(addr); + } + } + this->latch_regs(); + //test read: + //boost::uint32_t reg = _ad9522_regs.get_read_reg(0x01b); + //boost::uint32_t result = _iface->transact_spi( + // UE_SPI_SS_AD9522, + // spi_config_t::EDGE_RISE, + // reg, 24, true /*no*/ + //); + //std::cout << "result " << std::hex << result << std::endl; + this->enable_rx_dboard_clock(false); + this->enable_tx_dboard_clock(false); + } + + ~usrp_e_clock_ctrl_impl(void){ + this->enable_rx_dboard_clock(false); + this->enable_tx_dboard_clock(false); + } + + double get_fpga_clock_rate(void){ + return master_clock_rate/fpga_clock_divider; + } + + /*********************************************************************** + * RX Dboard Clock Control (output 9, divider 3) + **********************************************************************/ + void enable_rx_dboard_clock(bool enb){ + _ad9522_regs.out9_format = ad9522_regs_t::OUT9_FORMAT_CMOS; + _ad9522_regs.out9_cmos_configuration = (enb)? + ad9522_regs_t::OUT9_CMOS_CONFIGURATION_B_ON : + ad9522_regs_t::OUT9_CMOS_CONFIGURATION_OFF; + this->send_reg(0x0F9); + this->latch_regs(); + } + + std::vector get_rx_dboard_clock_rates(void){ + std::vector rates; + for(size_t div = 1; div <= 16+16; div++) + rates.push_back(master_clock_rate/div); + return rates; + } + + void set_rx_dboard_clock_rate(double rate){ + assert_has(get_rx_dboard_clock_rates(), rate, "rx dboard clock rate"); + size_t divider = size_t(master_clock_rate/rate); + //set the divider registers + set_clock_divider(divider, + _ad9522_regs.divider3_low_cycles, + _ad9522_regs.divider3_high_cycles, + _ad9522_regs.divider3_bypass + ); + this->send_reg(0x199); + this->send_reg(0x19a); + this->latch_regs(); + } + + /*********************************************************************** + * TX Dboard Clock Control (output 6, divider 2) + **********************************************************************/ + void enable_tx_dboard_clock(bool enb){ + _ad9522_regs.out6_format = ad9522_regs_t::OUT6_FORMAT_CMOS; + _ad9522_regs.out6_cmos_configuration = (enb)? + ad9522_regs_t::OUT6_CMOS_CONFIGURATION_B_ON : + ad9522_regs_t::OUT6_CMOS_CONFIGURATION_OFF; + this->send_reg(0x0F6); + this->latch_regs(); + } + + std::vector get_tx_dboard_clock_rates(void){ + return get_rx_dboard_clock_rates(); //same master clock, same dividers... + } + + void set_tx_dboard_clock_rate(double rate){ + assert_has(get_tx_dboard_clock_rates(), rate, "tx dboard clock rate"); + size_t divider = size_t(master_clock_rate/rate); + //set the divider registers + set_clock_divider(divider, + _ad9522_regs.divider2_low_cycles, + _ad9522_regs.divider2_high_cycles, + _ad9522_regs.divider2_bypass + ); + this->send_reg(0x196); + this->send_reg(0x197); + this->latch_regs(); + } + +private: + usrp_e_iface::sptr _iface; + ad9522_regs_t _ad9522_regs; + + void latch_regs(void){ + _ad9522_regs.io_update = 1; + this->send_reg(0x232); + } + + void send_reg(boost::uint16_t addr){ + boost::uint32_t reg = _ad9522_regs.get_write_reg(addr); + //std::cout << "clock control write reg: " << std::hex << reg << std::endl; + _iface->transact_spi( + UE_SPI_SS_AD9522, + spi_config_t::EDGE_RISE, + reg, 24, false /*no rb*/ + ); + } +}; + +/*********************************************************************** + * Clock Control Make + **********************************************************************/ +usrp_e_clock_ctrl::sptr usrp_e_clock_ctrl::make(usrp_e_iface::sptr iface){ + return sptr(new usrp_e_clock_ctrl_impl(iface)); +} diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.hpp b/host/lib/usrp/usrp_e100/clock_ctrl.hpp new file mode 100644 index 000000000..3b5103ed1 --- /dev/null +++ b/host/lib/usrp/usrp_e100/clock_ctrl.hpp @@ -0,0 +1,88 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_USRP_E_CLOCK_CTRL_HPP +#define INCLUDED_USRP_E_CLOCK_CTRL_HPP + +#include "usrp_e_iface.hpp" +#include +#include +#include + +/*! + * The usrp-e clock control: + * - Setup system clocks. + * - Disable/enable clock lines. + */ +class usrp_e_clock_ctrl : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a new clock control object. + * \param iface the usrp_e iface object + * \return the clock control object + */ + static sptr make(usrp_e_iface::sptr iface); + + /*! + * Get the rate of the fpga clock line. + * \return the fpga clock rate in Hz + */ + virtual double get_fpga_clock_rate(void) = 0; + + /*! + * Get the possible rates of the rx dboard clock. + * \return a vector of clock rates in Hz + */ + virtual std::vector get_rx_dboard_clock_rates(void) = 0; + + /*! + * Get the possible rates of the tx dboard clock. + * \return a vector of clock rates in Hz + */ + virtual std::vector get_tx_dboard_clock_rates(void) = 0; + + /*! + * Set the rx dboard clock rate to a possible rate. + * \param rate the new clock rate in Hz + * \throw exception when rate cannot be achieved + */ + virtual void set_rx_dboard_clock_rate(double rate) = 0; + + /*! + * Set the tx dboard clock rate to a possible rate. + * \param rate the new clock rate in Hz + * \throw exception when rate cannot be achieved + */ + virtual void set_tx_dboard_clock_rate(double rate) = 0; + + /*! + * Enable/disable the rx dboard clock. + * \param enb true to enable + */ + virtual void enable_rx_dboard_clock(bool enb) = 0; + + /*! + * Enable/disable the tx dboard clock. + * \param enb true to enable + */ + virtual void enable_tx_dboard_clock(bool enb) = 0; + +}; + +#endif /* INCLUDED_USRP_E_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e100/codec_ctrl.cpp b/host/lib/usrp/usrp_e100/codec_ctrl.cpp new file mode 100644 index 000000000..a728d7e46 --- /dev/null +++ b/host/lib/usrp/usrp_e100/codec_ctrl.cpp @@ -0,0 +1,296 @@ +// +// Copyright 2010 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 . +// + +#include "codec_ctrl.hpp" +#include "ad9862_regs.hpp" +#include +#include +#include +#include +#include +#include +#include "usrp_e_regs.hpp" //spi slave constants +#include +#include + +using namespace uhd; + +static const bool codec_debug = false; + +const gain_range_t usrp_e_codec_ctrl::tx_pga_gain_range(-20, 0, float(0.1)); +const gain_range_t usrp_e_codec_ctrl::rx_pga_gain_range(0, 20, 1); + +/*********************************************************************** + * Codec Control Implementation + **********************************************************************/ +class usrp_e_codec_ctrl_impl : public usrp_e_codec_ctrl{ +public: + //structors + usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface); + ~usrp_e_codec_ctrl_impl(void); + + //aux adc and dac control + float read_aux_adc(aux_adc_t which); + void write_aux_dac(aux_dac_t which, float volts); + + //pga gain control + void set_tx_pga_gain(float); + float get_tx_pga_gain(void); + void set_rx_pga_gain(float, char); + float get_rx_pga_gain(char); + +private: + usrp_e_iface::sptr _iface; + ad9862_regs_t _ad9862_regs; + aux_adc_t _last_aux_adc_a, _last_aux_adc_b; + void send_reg(boost::uint8_t addr); + void recv_reg(boost::uint8_t addr); +}; + +/*********************************************************************** + * Codec Control Structors + **********************************************************************/ +usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ + _iface = iface; + + //soft reset + _ad9862_regs.soft_reset = 1; + this->send_reg(0); + + //initialize the codec register settings + _ad9862_regs.sdio_bidir = ad9862_regs_t::SDIO_BIDIR_SDIO_SDO; + _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB; + _ad9862_regs.soft_reset = 0; + + //setup rx side of codec + _ad9862_regs.byp_buffer_a = 1; + _ad9862_regs.byp_buffer_b = 1; + _ad9862_regs.buffer_a_pd = 1; + _ad9862_regs.buffer_b_pd = 1; + _ad9862_regs.rx_pga_a = 0;//0x1f; //TODO bring under api control + _ad9862_regs.rx_pga_b = 0;//0x1f; //TODO bring under api control + _ad9862_regs.rx_twos_comp = 1; + _ad9862_regs.rx_hilbert = ad9862_regs_t::RX_HILBERT_DIS; + + //setup tx side of codec + _ad9862_regs.two_data_paths = ad9862_regs_t::TWO_DATA_PATHS_BOTH; + _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED; + _ad9862_regs.tx_retime = ad9862_regs_t::TX_RETIME_CLKOUT2; + _ad9862_regs.tx_pga_gain = 199; //TODO bring under api control + _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS; + _ad9862_regs.interp = ad9862_regs_t::INTERP_2; + _ad9862_regs.tx_twos_comp = 1; + _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_BYPASS; + _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS; + _ad9862_regs.dac_a_coarse_gain = 0x3; + _ad9862_regs.dac_b_coarse_gain = 0x3; + _ad9862_regs.edges = ad9862_regs_t::EDGES_NORMAL; + + //setup the dll + _ad9862_regs.input_clk_ctrl = ad9862_regs_t::INPUT_CLK_CTRL_EXTERNAL; + _ad9862_regs.dll_mult = ad9862_regs_t::DLL_MULT_2; + _ad9862_regs.dll_mode = ad9862_regs_t::DLL_MODE_FAST; + + //write the register settings to the codec + for (uint8_t addr = 0; addr <= 25; addr++){ + this->send_reg(addr); + } + + //aux adc clock + _ad9862_regs.clk_4 = ad9862_regs_t::CLK_4_1_4; + this->send_reg(34); +} + +usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){ + //set aux dacs to zero + this->write_aux_dac(AUX_DAC_A, 0); + this->write_aux_dac(AUX_DAC_B, 0); + this->write_aux_dac(AUX_DAC_C, 0); + this->write_aux_dac(AUX_DAC_D, 0); + + //power down + _ad9862_regs.all_rx_pd = 1; + this->send_reg(1); + _ad9862_regs.tx_digital_pd = 1; + _ad9862_regs.tx_analog_pd = ad9862_regs_t::TX_ANALOG_PD_BOTH; + this->send_reg(8); +} + +/*********************************************************************** + * Codec Control Gain Control Methods + **********************************************************************/ +static const int mtpgw = 255; //maximum tx pga gain word + +void usrp_e_codec_ctrl_impl::set_tx_pga_gain(float gain){ + int gain_word = int(mtpgw*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); + _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw); + this->send_reg(16); +} + +float usrp_e_codec_ctrl_impl::get_tx_pga_gain(void){ + return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.max - tx_pga_gain_range.min)/mtpgw) + tx_pga_gain_range.min; +} + +static const int mrpgw = 0x14; //maximum rx pga gain word + +void usrp_e_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ + int gain_word = int(mrpgw*(gain - rx_pga_gain_range.min)/(rx_pga_gain_range.max - rx_pga_gain_range.min)); + gain_word = std::clip(gain_word, 0, mrpgw); + switch(which){ + case 'A': + _ad9862_regs.rx_pga_a = gain_word; + this->send_reg(2); + return; + case 'B': + _ad9862_regs.rx_pga_b = gain_word; + this->send_reg(3); + return; + default: UHD_THROW_INVALID_CODE_PATH(); + } +} + +float usrp_e_codec_ctrl_impl::get_rx_pga_gain(char which){ + int gain_word; + switch(which){ + case 'A': gain_word = _ad9862_regs.rx_pga_a; break; + case 'B': gain_word = _ad9862_regs.rx_pga_b; break; + default: UHD_THROW_INVALID_CODE_PATH(); + } + return (gain_word*(rx_pga_gain_range.max - rx_pga_gain_range.min)/mrpgw) + rx_pga_gain_range.min; +} + +/*********************************************************************** + * Codec Control AUX ADC Methods + **********************************************************************/ +static float aux_adc_to_volts(boost::uint8_t high, boost::uint8_t low){ + return float((boost::uint16_t(high) << 2) | low)*3.3/0x3ff; +} + +float usrp_e_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ + //check to see if the switch needs to be set + bool write_switch = false; + switch(which){ + + case AUX_ADC_A1: + case AUX_ADC_A2: + if (which != _last_aux_adc_a){ + _ad9862_regs.select_a = (which == AUX_ADC_A1)? + ad9862_regs_t::SELECT_A_AUX_ADC1: ad9862_regs_t::SELECT_A_AUX_ADC2; + _last_aux_adc_a = which; + write_switch = true; + } + break; + + case AUX_ADC_B1: + case AUX_ADC_B2: + if (which != _last_aux_adc_b){ + _ad9862_regs.select_b = (which == AUX_ADC_B1)? + ad9862_regs_t::SELECT_B_AUX_ADC1: ad9862_regs_t::SELECT_B_AUX_ADC2; + _last_aux_adc_b = which; + write_switch = true; + } + break; + + } + + //write the switch if it changed + if(write_switch) this->send_reg(34); + + //map aux adcs to register values to read + static const uhd::dict aux_dac_to_addr = boost::assign::map_list_of + (AUX_ADC_A2, 26) (AUX_ADC_A1, 28) + (AUX_ADC_B2, 30) (AUX_ADC_B1, 32) + ; + + //read the value + this->recv_reg(aux_dac_to_addr[which]+0); + this->recv_reg(aux_dac_to_addr[which]+1); + + //return the value scaled to volts + switch(which){ + case AUX_ADC_A1: return aux_adc_to_volts(_ad9862_regs.aux_adc_a1_9_2, _ad9862_regs.aux_adc_a1_1_0); + case AUX_ADC_A2: return aux_adc_to_volts(_ad9862_regs.aux_adc_a2_9_2, _ad9862_regs.aux_adc_a2_1_0); + case AUX_ADC_B1: return aux_adc_to_volts(_ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0); + case AUX_ADC_B2: return aux_adc_to_volts(_ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0); + } + UHD_ASSERT_THROW(false); +} + +/*********************************************************************** + * Codec Control AUX DAC Methods + **********************************************************************/ +void usrp_e_codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ + //special case for aux dac d (aka sigma delta word) + if (which == AUX_DAC_D){ + boost::uint16_t dac_word = std::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); + _ad9862_regs.sig_delt_11_4 = boost::uint8_t(dac_word >> 4); + _ad9862_regs.sig_delt_3_0 = boost::uint8_t(dac_word & 0xf); + this->send_reg(42); + this->send_reg(43); + return; + } + + //calculate the dac word for aux dac a, b, c + boost::uint8_t dac_word = std::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff); + + //setup a lookup table for the aux dac params (reg ref, reg addr) + typedef boost::tuple dac_params_t; + uhd::dict aux_dac_to_params = boost::assign::map_list_of + (AUX_DAC_A, dac_params_t(&_ad9862_regs.aux_dac_a, 36)) + (AUX_DAC_B, dac_params_t(&_ad9862_regs.aux_dac_b, 37)) + (AUX_DAC_C, dac_params_t(&_ad9862_regs.aux_dac_c, 38)) + ; + + //set the aux dac register + UHD_ASSERT_THROW(aux_dac_to_params.has_key(which)); + boost::uint8_t *reg_ref, reg_addr; + boost::tie(reg_ref, reg_addr) = aux_dac_to_params[which]; + *reg_ref = dac_word; + this->send_reg(reg_addr); +} + +/*********************************************************************** + * Codec Control SPI Methods + **********************************************************************/ +void usrp_e_codec_ctrl_impl::send_reg(boost::uint8_t addr){ + boost::uint32_t reg = _ad9862_regs.get_write_reg(addr); + if (codec_debug) std::cout << "codec control write reg: " << std::hex << reg << std::endl; + _iface->transact_spi( + UE_SPI_SS_AD9862, + spi_config_t::EDGE_RISE, + reg, 16, false /*no rb*/ + ); +} + +void usrp_e_codec_ctrl_impl::recv_reg(boost::uint8_t addr){ + boost::uint32_t reg = _ad9862_regs.get_read_reg(addr); + if (codec_debug) std::cout << "codec control read reg: " << std::hex << reg << std::endl; + boost::uint32_t ret = _iface->transact_spi( + UE_SPI_SS_AD9862, + spi_config_t::EDGE_RISE, + reg, 16, true /*rb*/ + ); + if (codec_debug) std::cout << "codec control read ret: " << std::hex << ret << std::endl; + _ad9862_regs.set_reg(addr, boost::uint16_t(ret)); +} + +/*********************************************************************** + * Codec Control Make + **********************************************************************/ +usrp_e_codec_ctrl::sptr usrp_e_codec_ctrl::make(usrp_e_iface::sptr iface){ + return sptr(new usrp_e_codec_ctrl_impl(iface)); +} diff --git a/host/lib/usrp/usrp_e100/codec_ctrl.hpp b/host/lib/usrp/usrp_e100/codec_ctrl.hpp new file mode 100644 index 000000000..87b6ff951 --- /dev/null +++ b/host/lib/usrp/usrp_e100/codec_ctrl.hpp @@ -0,0 +1,90 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_USRP_E_CODEC_CTRL_HPP +#define INCLUDED_USRP_E_CODEC_CTRL_HPP + +#include "usrp_e_iface.hpp" +#include +#include +#include + +/*! + * The usrp-e codec control: + * - Init/power down codec. + * - Read aux adc, write aux dac. + */ +class usrp_e_codec_ctrl : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + static const uhd::gain_range_t tx_pga_gain_range; + static const uhd::gain_range_t rx_pga_gain_range; + + /*! + * Make a new codec control object. + * \param iface the usrp_e iface object + * \return the codec control object + */ + static sptr make(usrp_e_iface::sptr iface); + + //! aux adc identifier constants + enum aux_adc_t{ + AUX_ADC_A2 = 0xA2, + AUX_ADC_A1 = 0xA1, + AUX_ADC_B2 = 0xB2, + AUX_ADC_B1 = 0xB1 + }; + + /*! + * Read an auxiliary adc: + * The internals remember which aux adc was read last. + * Therefore, the aux adc switch is only changed as needed. + * \param which which of the 4 adcs + * \return a value in volts + */ + virtual float read_aux_adc(aux_adc_t which) = 0; + + //! aux dac identifier constants + enum aux_dac_t{ + AUX_DAC_A = 0xA, + AUX_DAC_B = 0xB, + AUX_DAC_C = 0xC, + AUX_DAC_D = 0xD //really the sigma delta output + }; + + /*! + * Write an auxiliary dac. + * \param which which of the 4 dacs + * \param volts the level in in volts + */ + virtual void write_aux_dac(aux_dac_t which, float volts) = 0; + + //! Set the TX PGA gain + virtual void set_tx_pga_gain(float gain) = 0; + + //! Get the TX PGA gain + virtual float get_tx_pga_gain(void) = 0; + + //! Set the RX PGA gain ('A' or 'B') + virtual void set_rx_pga_gain(float gain, char which) = 0; + + //! Get the RX PGA gain ('A' or 'B') + virtual float get_rx_pga_gain(char which) = 0; +}; + +#endif /* INCLUDED_USRP_E_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e100/codec_impl.cpp b/host/lib/usrp/usrp_e100/codec_impl.cpp new file mode 100644 index 000000000..696fb37ec --- /dev/null +++ b/host/lib/usrp/usrp_e100/codec_impl.cpp @@ -0,0 +1,149 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_impl.hpp" +#include +#include +#include + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * Helper Methods + **********************************************************************/ +void usrp_e_impl::codec_init(void){ + //make proxies + _rx_codec_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::rx_codec_get, this, _1, _2), + boost::bind(&usrp_e_impl::rx_codec_set, this, _1, _2) + ); + _tx_codec_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::tx_codec_get, this, _1, _2), + boost::bind(&usrp_e_impl::tx_codec_set, this, _1, _2) + ); +} + +/*********************************************************************** + * RX Codec Properties + **********************************************************************/ +static const std::string ad9862_pga_gain_name = "ad9862 pga"; + +void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case CODEC_PROP_NAME: + val = std::string("usrp-e adc - ad9522"); + return; + + case CODEC_PROP_OTHERS: + val = prop_names_t(); + return; + + case CODEC_PROP_GAIN_NAMES: + val = prop_names_t(1, ad9862_pga_gain_name); + return; + + case CODEC_PROP_GAIN_RANGE: + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); + val = usrp_e_codec_ctrl::rx_pga_gain_range; + return; + + case CODEC_PROP_GAIN_I: + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); + val = _codec_ctrl->get_rx_pga_gain('A'); + return; + + case CODEC_PROP_GAIN_Q: + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); + val = _codec_ctrl->get_rx_pga_gain('B'); + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +void usrp_e_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + //handle the set request conditioned on the key + switch(key.as()){ + case CODEC_PROP_GAIN_I: + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); + _codec_ctrl->set_rx_pga_gain(val.as(), 'A'); + return; + + case CODEC_PROP_GAIN_Q: + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); + _codec_ctrl->set_rx_pga_gain(val.as(), 'B'); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } +} + +/*********************************************************************** + * TX Codec Properties + **********************************************************************/ +void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case CODEC_PROP_NAME: + val = std::string("usrp-e dac - ad9522"); + return; + + case CODEC_PROP_OTHERS: + val = prop_names_t(); + return; + + case CODEC_PROP_GAIN_NAMES: + val = prop_names_t(1, ad9862_pga_gain_name); + return; + + case CODEC_PROP_GAIN_RANGE: + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); + val = usrp_e_codec_ctrl::tx_pga_gain_range; + return; + + case CODEC_PROP_GAIN_I: //only one gain for I and Q + case CODEC_PROP_GAIN_Q: + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); + val = _codec_ctrl->get_tx_pga_gain(); + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +void usrp_e_impl::tx_codec_set(const wax::obj &key_, const wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + //handle the set request conditioned on the key + switch(key.as()){ + case CODEC_PROP_GAIN_I: //only one gain for I and Q + case CODEC_PROP_GAIN_Q: + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); + _codec_ctrl->set_tx_pga_gain(val.as()); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } +} diff --git a/host/lib/usrp/usrp_e100/dboard_iface.cpp b/host/lib/usrp/usrp_e100/dboard_iface.cpp new file mode 100644 index 000000000..6898df8df --- /dev/null +++ b/host/lib/usrp/usrp_e100/dboard_iface.cpp @@ -0,0 +1,298 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_iface.hpp" +#include "usrp_e_regs.hpp" +#include "clock_ctrl.hpp" +#include "codec_ctrl.hpp" +#include +#include +#include +#include +#include //i2c and spi constants + +using namespace uhd; +using namespace uhd::usrp; +using namespace boost::assign; + +class usrp_e_dboard_iface : public dboard_iface{ +public: + + usrp_e_dboard_iface( + usrp_e_iface::sptr iface, + usrp_e_clock_ctrl::sptr clock, + usrp_e_codec_ctrl::sptr codec + ){ + _iface = iface; + _clock = clock; + _codec = codec; + + //init the clock rate shadows + this->set_clock_rate(UNIT_RX, _clock->get_fpga_clock_rate()); + this->set_clock_rate(UNIT_TX, _clock->get_fpga_clock_rate()); + + _iface->poke16(UE_REG_GPIO_RX_DBG, 0); + _iface->poke16(UE_REG_GPIO_TX_DBG, 0); + } + + ~usrp_e_dboard_iface(void){ + /* NOP */ + } + + special_props_t get_special_props(void){ + special_props_t props; + props.soft_clock_divider = false; + props.mangle_i2c_addrs = false; + return props; + } + + void write_aux_dac(unit_t, aux_dac_t, float); + float read_aux_adc(unit_t, aux_adc_t); + + void set_pin_ctrl(unit_t, boost::uint16_t); + void set_atr_reg(unit_t, atr_reg_t, boost::uint16_t); + void set_gpio_ddr(unit_t, boost::uint16_t); + void write_gpio(unit_t, boost::uint16_t); + void set_gpio_debug(unit_t, int); + boost::uint16_t read_gpio(unit_t); + + void write_i2c(boost::uint8_t, const byte_vector_t &); + byte_vector_t read_i2c(boost::uint8_t, size_t); + + void write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ); + + boost::uint32_t read_write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ); + + void set_clock_rate(unit_t, double); + std::vector get_clock_rates(unit_t); + double get_clock_rate(unit_t); + void set_clock_enabled(unit_t, bool); + double get_codec_rate(unit_t); + +private: + usrp_e_iface::sptr _iface; + usrp_e_clock_ctrl::sptr _clock; + usrp_e_codec_ctrl::sptr _codec; + uhd::dict _clock_rates; +}; + +/*********************************************************************** + * Make Function + **********************************************************************/ +dboard_iface::sptr make_usrp_e_dboard_iface( + usrp_e_iface::sptr iface, + usrp_e_clock_ctrl::sptr clock, + usrp_e_codec_ctrl::sptr codec +){ + return dboard_iface::sptr(new usrp_e_dboard_iface(iface, clock, codec)); +} + +/*********************************************************************** + * Clock Rates + **********************************************************************/ +void usrp_e_dboard_iface::set_clock_rate(unit_t unit, double rate){ + _clock_rates[unit] = rate; + switch(unit){ + case UNIT_RX: return _clock->set_rx_dboard_clock_rate(rate); + case UNIT_TX: return _clock->set_tx_dboard_clock_rate(rate); + } +} + +std::vector usrp_e_dboard_iface::get_clock_rates(unit_t unit){ + switch(unit){ + case UNIT_RX: return _clock->get_rx_dboard_clock_rates(); + case UNIT_TX: return _clock->get_tx_dboard_clock_rates(); + default: UHD_THROW_INVALID_CODE_PATH(); + } +} + +double usrp_e_dboard_iface::get_clock_rate(unit_t unit){ + return _clock_rates[unit]; +} + +void usrp_e_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ + switch(unit){ + case UNIT_RX: return _clock->enable_rx_dboard_clock(enb); + case UNIT_TX: return _clock->enable_tx_dboard_clock(enb); + } +} + +double usrp_e_dboard_iface::get_codec_rate(unit_t){ + return _clock->get_fpga_clock_rate(); +} + +/*********************************************************************** + * GPIO + **********************************************************************/ +void usrp_e_dboard_iface::set_pin_ctrl(unit_t unit, boost::uint16_t value){ + UHD_ASSERT_THROW(GPIO_SEL_ATR == 1); //make this assumption + switch(unit){ + case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_SEL, value); return; + case UNIT_TX: _iface->poke16(UE_REG_GPIO_TX_SEL, value); return; + } +} + +void usrp_e_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value){ + switch(unit){ + case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_DDR, value); return; + case UNIT_TX: _iface->poke16(UE_REG_GPIO_TX_DDR, value); return; + } +} + +void usrp_e_dboard_iface::write_gpio(unit_t unit, boost::uint16_t value){ + switch(unit){ + case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_IO, value); return; + case UNIT_TX: _iface->poke16(UE_REG_GPIO_TX_IO, value); return; + } +} + +boost::uint16_t usrp_e_dboard_iface::read_gpio(unit_t unit){ + switch(unit){ + case UNIT_RX: return _iface->peek16(UE_REG_GPIO_RX_IO); + case UNIT_TX: return _iface->peek16(UE_REG_GPIO_TX_IO); + default: UHD_THROW_INVALID_CODE_PATH(); + } +} + +void usrp_e_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){ + //define mapping of unit to atr regs to register address + static const uhd::dict< + unit_t, uhd::dict + > unit_to_atr_to_addr = map_list_of + (UNIT_RX, map_list_of + (ATR_REG_IDLE, UE_REG_ATR_IDLE_RXSIDE) + (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_RXSIDE) + (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_RXSIDE) + (ATR_REG_FULL_DUPLEX, UE_REG_ATR_FULL_RXSIDE) + ) + (UNIT_TX, map_list_of + (ATR_REG_IDLE, UE_REG_ATR_IDLE_TXSIDE) + (ATR_REG_TX_ONLY, UE_REG_ATR_INTX_TXSIDE) + (ATR_REG_RX_ONLY, UE_REG_ATR_INRX_TXSIDE) + (ATR_REG_FULL_DUPLEX, UE_REG_ATR_FULL_TXSIDE) + ) + ; + _iface->poke16(unit_to_atr_to_addr[unit][atr], value); +} + +void usrp_e_dboard_iface::set_gpio_debug(unit_t unit, int which){ + //set this unit to all outputs + this->set_gpio_ddr(unit, 0xffff); + + //calculate the debug selections + boost::uint32_t dbg_sels = 0x0; + int sel = (which == 0)? GPIO_SEL_DEBUG_0 : GPIO_SEL_DEBUG_1; + for(size_t i = 0; i < 16; i++) dbg_sels |= sel << i; + + //set the debug on and which debug selection + switch(unit){ + case UNIT_RX: + _iface->poke16(UE_REG_GPIO_RX_DBG, 0xffff); + _iface->poke16(UE_REG_GPIO_RX_SEL, dbg_sels); + return; + + case UNIT_TX: + _iface->poke16(UE_REG_GPIO_TX_DBG, 0xffff); + _iface->poke16(UE_REG_GPIO_TX_SEL, dbg_sels); + return; + } +} + +/*********************************************************************** + * SPI + **********************************************************************/ +/*! + * Static function to convert a unit type to a spi slave device number. + * \param unit the dboard interface unit type enum + * \return the slave device number + */ +static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){ + switch(unit){ + case dboard_iface::UNIT_TX: return UE_SPI_SS_TX_DB; + case dboard_iface::UNIT_RX: return UE_SPI_SS_RX_DB; + } + throw std::invalid_argument("unknown unit type"); +} + +void usrp_e_dboard_iface::write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits +){ + _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/); +} + +boost::uint32_t usrp_e_dboard_iface::read_write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits +){ + return _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, true /*rb*/); +} + +/*********************************************************************** + * I2C + **********************************************************************/ +void usrp_e_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ + return _iface->write_i2c(addr, bytes); +} + +byte_vector_t usrp_e_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){ + return _iface->read_i2c(addr, num_bytes); +} + +/*********************************************************************** + * Aux DAX/ADC + **********************************************************************/ +void usrp_e_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, float value){ + //same aux dacs for each unit + static const uhd::dict which_to_aux_dac = map_list_of + (AUX_DAC_A, usrp_e_codec_ctrl::AUX_DAC_A) + (AUX_DAC_B, usrp_e_codec_ctrl::AUX_DAC_B) + (AUX_DAC_C, usrp_e_codec_ctrl::AUX_DAC_C) + (AUX_DAC_D, usrp_e_codec_ctrl::AUX_DAC_D) + ; + _codec->write_aux_dac(which_to_aux_dac[which], value); +} + +float usrp_e_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which){ + static const uhd::dict< + unit_t, uhd::dict + > unit_to_which_to_aux_adc = map_list_of + (UNIT_RX, map_list_of + (AUX_ADC_A, usrp_e_codec_ctrl::AUX_ADC_A1) + (AUX_ADC_B, usrp_e_codec_ctrl::AUX_ADC_B1) + ) + (UNIT_TX, map_list_of + (AUX_ADC_A, usrp_e_codec_ctrl::AUX_ADC_A2) + (AUX_ADC_B, usrp_e_codec_ctrl::AUX_ADC_B2) + ) + ; + return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]); +} diff --git a/host/lib/usrp/usrp_e100/dboard_impl.cpp b/host/lib/usrp/usrp_e100/dboard_impl.cpp new file mode 100644 index 000000000..f2840dcfc --- /dev/null +++ b/host/lib/usrp/usrp_e100/dboard_impl.cpp @@ -0,0 +1,172 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" +#include +#include +#include +#include +#include +#include + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * Dboard Initialization + **********************************************************************/ +void usrp_e_impl::dboard_init(void){ + _rx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes())); + _tx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_TX_DB, 0, dboard_eeprom_t::num_bytes())); + + //create a new dboard interface and manager + _dboard_iface = make_usrp_e_dboard_iface( + _iface, _clock_ctrl, _codec_ctrl + ); + _dboard_manager = dboard_manager::make( + _rx_db_eeprom.id, _tx_db_eeprom.id, _dboard_iface + ); + + //setup the dboard proxies + _rx_dboard_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::rx_dboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::rx_dboard_set, this, _1, _2) + ); + _tx_dboard_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::tx_dboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::tx_dboard_set, this, _1, _2) + ); +} + +/*********************************************************************** + * RX Dboard Get + **********************************************************************/ +void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case DBOARD_PROP_NAME: + val = std::string("usrp-e dboard (rx unit)"); + return; + + case DBOARD_PROP_SUBDEV: + val = _dboard_manager->get_rx_subdev(key.name); + return; + + case DBOARD_PROP_SUBDEV_NAMES: + val = _dboard_manager->get_rx_subdev_names(); + return; + + case DBOARD_PROP_DBOARD_ID: + val = _rx_db_eeprom.id; + return; + + case DBOARD_PROP_DBOARD_IFACE: + val = _dboard_iface; + return; + + case DBOARD_PROP_CODEC: + val = _rx_codec_proxy->get_link(); + return; + + case DBOARD_PROP_GAIN_GROUP: + val = make_gain_group( + _rx_db_eeprom.id, + _dboard_manager->get_rx_subdev(key.name), + _rx_codec_proxy->get_link(), + GAIN_GROUP_POLICY_RX + ); + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +/*********************************************************************** + * RX Dboard Set + **********************************************************************/ +void usrp_e_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ + switch(key.as()){ + case DBOARD_PROP_DBOARD_ID: + _rx_db_eeprom.id = val.as(); + _iface->write_eeprom(I2C_ADDR_RX_DB, 0, _rx_db_eeprom.get_eeprom_bytes()); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } +} + +/*********************************************************************** + * TX Dboard Get + **********************************************************************/ +void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case DBOARD_PROP_NAME: + val = std::string("usrp-e dboard (tx unit)"); + return; + + case DBOARD_PROP_SUBDEV: + val = _dboard_manager->get_tx_subdev(key.name); + return; + + case DBOARD_PROP_SUBDEV_NAMES: + val = _dboard_manager->get_tx_subdev_names(); + return; + + case DBOARD_PROP_DBOARD_ID: + val = _tx_db_eeprom.id; + return; + + case DBOARD_PROP_DBOARD_IFACE: + val = _dboard_iface; + return; + + case DBOARD_PROP_CODEC: + val = _tx_codec_proxy->get_link(); + return; + + case DBOARD_PROP_GAIN_GROUP: + val = make_gain_group( + _tx_db_eeprom.id, + _dboard_manager->get_tx_subdev(key.name), + _tx_codec_proxy->get_link(), + GAIN_GROUP_POLICY_TX + ); + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +/*********************************************************************** + * TX Dboard Set + **********************************************************************/ +void usrp_e_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ + switch(key.as()){ + case DBOARD_PROP_DBOARD_ID: + _tx_db_eeprom.id = val.as(); + _iface->write_eeprom(I2C_ADDR_TX_DB, 0, _tx_db_eeprom.get_eeprom_bytes()); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } +} diff --git a/host/lib/usrp/usrp_e100/dsp_impl.cpp b/host/lib/usrp/usrp_e100/dsp_impl.cpp new file mode 100644 index 000000000..97f173c1a --- /dev/null +++ b/host/lib/usrp/usrp_e100/dsp_impl.cpp @@ -0,0 +1,192 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" +#include +#include +#include +#include + +#define rint boost::math::iround + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * RX DDC Initialization + **********************************************************************/ +void usrp_e_impl::rx_ddc_init(void){ + _rx_ddc_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::rx_ddc_get, this, _1, _2), + boost::bind(&usrp_e_impl::rx_ddc_set, this, _1, _2) + ); + + //initial config and update + rx_ddc_set(DSP_PROP_FREQ_SHIFT, double(0)); + rx_ddc_set(DSP_PROP_HOST_RATE, double(64e6/10)); +} + +/*********************************************************************** + * RX DDC Get + **********************************************************************/ +void usrp_e_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + switch(key.as()){ + case DSP_PROP_NAME: + val = std::string("usrp-e ddc0"); + return; + + case DSP_PROP_OTHERS: + val = prop_names_t(); //empty + return; + + case DSP_PROP_FREQ_SHIFT: + val = _ddc_freq; + return; + + case DSP_PROP_FREQ_SHIFT_NAMES: + val = prop_names_t(1, ""); + return; + + case DSP_PROP_CODEC_RATE: + val = _clock_ctrl->get_fpga_clock_rate(); + return; + + case DSP_PROP_HOST_RATE: + val = _clock_ctrl->get_fpga_clock_rate()/_ddc_decim; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +/*********************************************************************** + * RX DDC Set + **********************************************************************/ +void usrp_e_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + switch(key.as()){ + + case DSP_PROP_FREQ_SHIFT:{ + double new_freq = val.as(); + _iface->poke32(UE_REG_DSP_RX_FREQ, + dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate()) + ); + _ddc_freq = new_freq; //shadow + } + return; + + case DSP_PROP_HOST_RATE:{ + //set the decimation + _ddc_decim = rint(_clock_ctrl->get_fpga_clock_rate()/val.as()); + _iface->poke32(UE_REG_DSP_RX_DECIM_RATE, dsp_type1::calc_cic_filter_word(_ddc_decim)); + + //set the scaling + static const boost::int16_t default_rx_scale_iq = 1024; + _iface->poke32(UE_REG_DSP_RX_SCALE_IQ, + dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq) + ); + } + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } +} + +/*********************************************************************** + * TX DUC Initialization + **********************************************************************/ +void usrp_e_impl::tx_duc_init(void){ + _tx_duc_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::tx_duc_get, this, _1, _2), + boost::bind(&usrp_e_impl::tx_duc_set, this, _1, _2) + ); + + //initial config and update + tx_duc_set(DSP_PROP_FREQ_SHIFT, double(0)); + tx_duc_set(DSP_PROP_HOST_RATE, double(64e6/10)); +} + +/*********************************************************************** + * TX DUC Get + **********************************************************************/ +void usrp_e_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + switch(key.as()){ + case DSP_PROP_NAME: + val = std::string("usrp-e duc0"); + return; + + case DSP_PROP_OTHERS: + val = prop_names_t(); //empty + return; + + case DSP_PROP_FREQ_SHIFT: + val = _duc_freq; + return; + + case DSP_PROP_FREQ_SHIFT_NAMES: + val = prop_names_t(1, ""); + return; + + case DSP_PROP_CODEC_RATE: + val = _clock_ctrl->get_fpga_clock_rate(); + return; + + case DSP_PROP_HOST_RATE: + val = _clock_ctrl->get_fpga_clock_rate()/_duc_interp; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +/*********************************************************************** + * TX DUC Set + **********************************************************************/ +void usrp_e_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + switch(key.as()){ + + case DSP_PROP_FREQ_SHIFT:{ + double new_freq = val.as(); + _iface->poke32(UE_REG_DSP_TX_FREQ, + dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate()) + ); + _duc_freq = new_freq; //shadow + } + return; + + case DSP_PROP_HOST_RATE:{ + _duc_interp = rint(_clock_ctrl->get_fpga_clock_rate()/val.as()); + + //set the interpolation + _iface->poke32(UE_REG_DSP_TX_INTERP_RATE, dsp_type1::calc_cic_filter_word(_duc_interp)); + + //set the scaling + _iface->poke32(UE_REG_DSP_TX_SCALE_IQ, dsp_type1::calc_iq_scale_word(_duc_interp)); + } + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } +} diff --git a/host/lib/usrp/usrp_e100/fpga-downloader.cc b/host/lib/usrp/usrp_e100/fpga-downloader.cc new file mode 100644 index 000000000..4dc537919 --- /dev/null +++ b/host/lib/usrp/usrp_e100/fpga-downloader.cc @@ -0,0 +1,274 @@ +// +// Copyright 2010 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 . +// + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* + * Configuration connections + * + * CCK - MCSPI1_CLK + * DIN - MCSPI1_MOSI + * PROG_B - GPIO_175 - output (change mux) + * DONE - GPIO_173 - input (change mux) + * INIT_B - GPIO_114 - input (change mux) + * +*/ + +const unsigned int PROG_B = 175; +const unsigned int DONE = 173; +const unsigned int INIT_B = 114; + +//static std::string bit_file = "safe_u1e.bin"; + +const int BUF_SIZE = 4096; + +enum gpio_direction {IN, OUT}; + +class gpio { + public: + + gpio(unsigned int gpio_num, gpio_direction pin_direction); + + bool get_value(); + void set_value(bool state); + + private: + + std::stringstream base_path; + std::fstream value_file; +}; + +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) +{ + std::fstream export_file; + + export_file.open("/sys/class/gpio/export", std::ios::out); + if (not export_file.is_open()) throw std::runtime_error( + "Failed to open gpio export file." + ); + + export_file << gpio_num << std::endl; + + base_path << "/sys/class/gpio/gpio" << gpio_num << std::flush; + + std::fstream direction_file; + std::string direction_file_name; + + if (gpio_num != 114) { + 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; +} + +static void prepare_fpga_for_configuration(gpio &prog, gpio &)//init) +{ + + prog.set_value(true); + prog.set_value(false); + prog.set_value(true); + +#if 0 + bool ready_to_program(false); + unsigned int count(0); + do { + ready_to_program = init.get_value(); + count++; + + sleep(1); + } while (count < 10 && !ready_to_program); + + if (count == 10) { + std::cout << "FPGA not ready for programming." << std::endl; + exit(-1); + } +#endif +} + +spidev::spidev(std::string fname) +{ + int ret; + int mode = 0; + int speed = 12000000; + int bits = 8; + + 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 = 48000000; + tr.bits_per_word = 8; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + +} + +static void send_file_to_fpga(const std::string &file_name, gpio &error, gpio &done) +{ + std::ifstream bitstream; + + std::cout << "File name - " << file_name.c_str() << std::endl; + + bitstream.open(file_name.c_str(), std::ios::binary); + if (!bitstream.is_open()) + std::cout << "File " << file_name << " not opened succesfully." << std::endl; + + spidev spi("/dev/spidev1.0"); + char buf[BUF_SIZE]; + char rbuf[BUF_SIZE]; + + do { + bitstream.read(buf, BUF_SIZE); + spi.send(buf, rbuf, bitstream.gcount()); + + if (error.get_value()) + std::cout << "INIT_B went high, error occured." << std::endl; + + if (!done.get_value()) + std::cout << "Configuration complete." << std::endl; + + } while (bitstream.gcount() == BUF_SIZE); +} + +/* +int main(int argc, char *argv[]) +{ + + gpio gpio_prog_b(PROG_B, OUT); + gpio gpio_init_b(INIT_B, IN); + gpio gpio_done (DONE, IN); + + if (argc == 2) + bit_file = argv[1]; + + std::cout << "FPGA config file: " << bit_file << std::endl; + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "Done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bit_file, gpio_init_b, gpio_done); +} +*/ + +void usrp_e_load_fpga(const std::string &bin_file){ + gpio gpio_prog_b(PROG_B, OUT); + gpio gpio_init_b(INIT_B, IN); + gpio gpio_done (DONE, IN); + + std::cout << "Loading FPGA image: " << bin_file << "... " << std::flush; + + UHD_ASSERT_THROW(std::system("/sbin/rmmod usrp_e") == 0); + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bin_file, gpio_init_b, gpio_done); + + UHD_ASSERT_THROW(std::system("/sbin/modprobe usrp_e") == 0); + +} + diff --git a/host/lib/usrp/usrp_e100/io_impl.cpp b/host/lib/usrp/usrp_e100/io_impl.cpp new file mode 100644 index 000000000..e863944e8 --- /dev/null +++ b/host/lib/usrp/usrp_e100/io_impl.cpp @@ -0,0 +1,272 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" +#include +#include +#include +#include "../../transport/vrt_packet_handler.hpp" +#include +#include +#include +#include + +using namespace uhd; +using namespace uhd::usrp; +using namespace uhd::transport; + +zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface); + +/*********************************************************************** + * Constants + **********************************************************************/ +static const size_t tx_async_report_sid = 1; +static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET; +static const bool recv_debug = false; + +/*********************************************************************** + * io impl details (internal to this file) + * - pirate crew of 1 + * - bounded buffer + * - thread loop + * - vrt packet handler states + **********************************************************************/ +struct usrp_e_impl::io_impl{ + //state management for the vrt packet handler code + vrt_packet_handler::recv_state packet_handler_recv_state; + vrt_packet_handler::send_state packet_handler_send_state; + zero_copy_if::sptr data_xport; + bool continuous_streaming; + io_impl(usrp_e_iface::sptr iface): + data_xport(usrp_e_make_mmap_zero_copy(iface)), + recv_pirate_booty(recv_booty_type::make(data_xport->get_num_recv_frames())), + async_msg_fifo(bounded_buffer::make(100/*messages deep*/)) + { + /* NOP */ + } + + ~io_impl(void){ + recv_pirate_crew_raiding = false; + recv_pirate_crew.interrupt_all(); + recv_pirate_crew.join_all(); + } + + bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs, double timeout){ + UHD_ASSERT_THROW(buffs.size() == 1); + boost::this_thread::disable_interruption di; //disable because the wait can throw + return recv_pirate_booty->pop_with_timed_wait(buffs.front(), timeout); + } + + //a pirate's life is the life for me! + void recv_pirate_loop(usrp_e_clock_ctrl::sptr); + typedef bounded_buffer recv_booty_type; + recv_booty_type::sptr recv_pirate_booty; + bounded_buffer::sptr async_msg_fifo; + boost::thread_group recv_pirate_crew; + bool recv_pirate_crew_raiding; +}; + +/*********************************************************************** + * Receive Pirate Loop + * - while raiding, loot for recv buffers + * - put booty into the alignment buffer + **********************************************************************/ +void usrp_e_impl::io_impl::recv_pirate_loop(usrp_e_clock_ctrl::sptr clock_ctrl) +{ + set_thread_priority_safe(); + recv_pirate_crew_raiding = true; + + while(recv_pirate_crew_raiding){ + managed_recv_buffer::sptr buff = this->data_xport->get_recv_buff(); + if (not buff.get()) continue; //ignore timeout/error buffers + + if (recv_debug){ + std::cout << "len " << buff->size() << std::endl; + for (size_t i = 0; i < 9; i++){ + std::cout << boost::format(" 0x%08x") % buff->cast()[i] << std::endl; + } + std::cout << std::endl << std::endl; + } + + try{ + //extract the vrt header packet info + vrt::if_packet_info_t if_packet_info; + if_packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t); + const boost::uint32_t *vrt_hdr = buff->cast(); + vrt::if_hdr_unpack_le(vrt_hdr, if_packet_info); + + //handle a tx async report message + if (if_packet_info.sid == tx_async_report_sid and if_packet_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){ + + //fill in the async metadata + async_metadata_t metadata; + metadata.channel = 0; + metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf; + metadata.time_spec = time_spec_t( + time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), clock_ctrl->get_fpga_clock_rate() + ); + metadata.event_code = vrt_packet_handler::get_context_code(vrt_hdr, if_packet_info); + + //print the famous U, and push the metadata into the message queue + if (metadata.event_code & underflow_flags) std::cerr << "U" << std::flush; + async_msg_fifo->push_with_pop_on_full(metadata); + continue; + } + + //same number of frames as the data transport -> always immediate + recv_pirate_booty->push_with_wait(buff); + + }catch(const std::exception &e){ + std::cerr << "Error (usrp-e recv pirate loop): " << e.what() << std::endl; + } + } +} + +/*********************************************************************** + * Helper Functions + **********************************************************************/ +void usrp_e_impl::io_init(void){ + //setup otw types + _send_otw_type.width = 16; + _send_otw_type.shift = 0; + _send_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; + + _recv_otw_type.width = 16; + _recv_otw_type.shift = 0; + _recv_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; + + //setup before the registers (transport called to calculate max spp) + _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface)); + + //setup rx data path + _iface->poke32(UE_REG_CTRL_RX_NSAMPS_PER_PKT, get_max_recv_samps_per_packet()); + _iface->poke32(UE_REG_CTRL_RX_NCHANNELS, 1); + _iface->poke32(UE_REG_CTRL_RX_CLEAR_OVERRUN, 1); //reset + _iface->poke32(UE_REG_CTRL_RX_VRT_HEADER, 0 + | (0x1 << 28) //if data with stream id + | (0x1 << 26) //has trailer + | (0x3 << 22) //integer time other + | (0x1 << 20) //fractional time sample count + ); + _iface->poke32(UE_REG_CTRL_RX_VRT_STREAM_ID, 0); + _iface->poke32(UE_REG_CTRL_RX_VRT_TRAILER, 0); + + //setup the tx policy + _iface->poke32(UE_REG_CTRL_TX_REPORT_SID, tx_async_report_sid); + _iface->poke32(UE_REG_CTRL_TX_POLICY, UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET); + + //spawn a pirate, yarrr! + _io_impl->recv_pirate_crew.create_thread(boost::bind( + &usrp_e_impl::io_impl::recv_pirate_loop, _io_impl.get(), _clock_ctrl + )); +} + +void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ + _io_impl->continuous_streaming = (stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + _iface->poke32(UE_REG_CTRL_RX_STREAM_CMD, dsp_type1::calc_stream_cmd_word( + stream_cmd, get_max_recv_samps_per_packet() + )); + _iface->poke32(UE_REG_CTRL_RX_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); + _iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_tick_count(_clock_ctrl->get_fpga_clock_rate())); +} + +void usrp_e_impl::handle_overrun(size_t){ + std::cerr << "O"; //the famous OOOOOOOOOOO + _iface->poke32(UE_REG_CTRL_RX_CLEAR_OVERRUN, 0); + if (_io_impl->continuous_streaming){ + this->issue_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + } +} + +/*********************************************************************** + * Data Send + **********************************************************************/ +bool get_send_buffs( + zero_copy_if::sptr trans, double timeout, + vrt_packet_handler::managed_send_buffs_t &buffs +){ + UHD_ASSERT_THROW(buffs.size() == 1); + buffs[0] = trans->get_send_buff(timeout); + return buffs[0].get() != NULL; +} + +size_t usrp_e_impl::get_max_send_samps_per_packet(void) const{ + static const size_t hdr_size = 0 + + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + - sizeof(vrt::if_packet_info_t().cid) //no class id ever used + ; + size_t bpp = _io_impl->data_xport->get_send_frame_size() - hdr_size; + return bpp/_send_otw_type.get_sample_size(); +} + +size_t usrp_e_impl::send( + const std::vector &buffs, size_t num_samps, + const tx_metadata_t &metadata, const io_type_t &io_type, + send_mode_t send_mode, double timeout +){ + return vrt_packet_handler::send( + _io_impl->packet_handler_send_state, //last state of the send handler + buffs, num_samps, //buffer to fill + metadata, send_mode, //samples metadata + io_type, _send_otw_type, //input and output types to convert + _clock_ctrl->get_fpga_clock_rate(), //master clock tick rate + uhd::transport::vrt::if_hdr_pack_le, + boost::bind(&get_send_buffs, _io_impl->data_xport, timeout, _1), + get_max_send_samps_per_packet() + ); +} + +/*********************************************************************** + * Data Recv + **********************************************************************/ +size_t usrp_e_impl::get_max_recv_samps_per_packet(void) const{ + static const size_t hdr_size = 0 + + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer + - sizeof(vrt::if_packet_info_t().cid) //no class id ever used + ; + size_t bpp = _io_impl->data_xport->get_recv_frame_size() - hdr_size; + return bpp/_recv_otw_type.get_sample_size(); +} + +size_t usrp_e_impl::recv( + const std::vector &buffs, size_t num_samps, + rx_metadata_t &metadata, const io_type_t &io_type, + recv_mode_t recv_mode, double timeout +){ + return vrt_packet_handler::recv( + _io_impl->packet_handler_recv_state, //last state of the recv handler + buffs, num_samps, //buffer to fill + metadata, recv_mode, //samples metadata + io_type, _recv_otw_type, //input and output types to convert + _clock_ctrl->get_fpga_clock_rate(), //master clock tick rate + uhd::transport::vrt::if_hdr_unpack_le, + boost::bind(&usrp_e_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout), + boost::bind(&usrp_e_impl::handle_overrun, this, _1) + ); +} + +/*********************************************************************** + * Async Recv + **********************************************************************/ +bool usrp_e_impl::recv_async_msg( + async_metadata_t &async_metadata, double timeout +){ + boost::this_thread::disable_interruption di; //disable because the wait can throw + return _io_impl->async_msg_fifo->pop_with_timed_wait(async_metadata, timeout); +} diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp new file mode 100644 index 000000000..f0118aa4b --- /dev/null +++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp @@ -0,0 +1,159 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" +#include +#include +#include +#include +#include +#include + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * Mboard Initialization + **********************************************************************/ +void usrp_e_impl::mboard_init(void){ + _mboard_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::mboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::mboard_set, this, _1, _2) + ); + + //init the clock config + _clock_config.ref_source = clock_config_t::REF_AUTO; + _clock_config.pps_source = clock_config_t::PPS_SMA; + + //TODO poke the clock config regs +} + +/*********************************************************************** + * Mboard Get + **********************************************************************/ +void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case MBOARD_PROP_NAME: + val = std::string("usrp-e mboard"); + return; + + case MBOARD_PROP_OTHERS: + val = prop_names_t(); + return; + + case MBOARD_PROP_RX_DBOARD: + UHD_ASSERT_THROW(key.name == ""); + val = _rx_dboard_proxy->get_link(); + return; + + case MBOARD_PROP_RX_DBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + case MBOARD_PROP_TX_DBOARD: + UHD_ASSERT_THROW(key.name == ""); + val = _tx_dboard_proxy->get_link(); + return; + + case MBOARD_PROP_TX_DBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + case MBOARD_PROP_RX_DSP: + UHD_ASSERT_THROW(key.name == ""); + val = _rx_ddc_proxy->get_link(); + return; + + case MBOARD_PROP_RX_DSP_NAMES: + val = prop_names_t(1, ""); + return; + + case MBOARD_PROP_TX_DSP: + UHD_ASSERT_THROW(key.name == ""); + val = _tx_duc_proxy->get_link(); + return; + + case MBOARD_PROP_TX_DSP_NAMES: + val = prop_names_t(1, ""); + return; + + case MBOARD_PROP_CLOCK_CONFIG: + val = _clock_config; + return; + + case MBOARD_PROP_RX_SUBDEV_SPEC: + val = _rx_subdev_spec; + return; + + case MBOARD_PROP_TX_SUBDEV_SPEC: + val = _tx_subdev_spec; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +/*********************************************************************** + * Mboard Set + **********************************************************************/ +void usrp_e_impl::mboard_set(const wax::obj &key, const wax::obj &val){ + //handle the get request conditioned on the key + switch(key.as()){ + + case MBOARD_PROP_STREAM_CMD: + issue_stream_cmd(val.as()); + return; + + case MBOARD_PROP_TIME_NOW: + case MBOARD_PROP_TIME_NEXT_PPS:{ + time_spec_t time_spec = val.as(); + _iface->poke32(UE_REG_TIME64_TICKS, time_spec.get_tick_count(_clock_ctrl->get_fpga_clock_rate())); + boost::uint32_t imm_flags = (key.as() == MBOARD_PROP_TIME_NOW)? 1 : 0; + _iface->poke32(UE_REG_TIME64_IMM, imm_flags); + _iface->poke32(UE_REG_TIME64_SECS, time_spec.get_full_secs()); + } + return; + + case MBOARD_PROP_RX_SUBDEV_SPEC: + _rx_subdev_spec = val.as(); + verify_rx_subdev_spec(_rx_subdev_spec, _mboard_proxy->get_link()); + //sanity check + UHD_ASSERT_THROW(_rx_subdev_spec.size() == 1); + //set the mux + _iface->poke32(UE_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word( + _dboard_manager->get_rx_subdev(_rx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as() + )); + return; + + case MBOARD_PROP_TX_SUBDEV_SPEC: + _tx_subdev_spec = val.as(); + verify_tx_subdev_spec(_tx_subdev_spec, _mboard_proxy->get_link()); + //sanity check + UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1); + //set the mux + _iface->poke32(UE_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word( + _dboard_manager->get_tx_subdev(_tx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as() + )); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } +} diff --git a/host/lib/usrp/usrp_e100/usrp_e_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e_iface.cpp new file mode 100644 index 000000000..f00e92946 --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e_iface.cpp @@ -0,0 +1,194 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_iface.hpp" +#include +#include //ioctl +#include //open, close +#include //ioctl structures and constants +#include +#include //mutex +#include + +using namespace uhd; + +class usrp_e_iface_impl : public usrp_e_iface{ +public: + + int get_file_descriptor(void){ + return _node_fd; + } + + /******************************************************************* + * Structors + ******************************************************************/ + usrp_e_iface_impl(const std::string &node){ + //open the device node and check file descriptor + if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ + throw std::runtime_error(str( + boost::format("Failed to open %s") % node + )); + } + } + + ~usrp_e_iface_impl(void){ + //close the device node file descriptor + ::close(_node_fd); + } + + /******************************************************************* + * IOCTL: provides the communication base for all other calls + ******************************************************************/ + void ioctl(int request, void *mem){ + boost::mutex::scoped_lock lock(_ctrl_mutex); + + if (::ioctl(_node_fd, request, mem) < 0){ + throw std::runtime_error(str( + boost::format("ioctl failed with request %d") % request + )); + } + } + + /******************************************************************* + * Peek and Poke + ******************************************************************/ + void poke32(boost::uint32_t addr, boost::uint32_t value){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL32, &data); + } + + void poke16(boost::uint32_t addr, boost::uint16_t value){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL16, &data); + } + + boost::uint32_t peek32(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL32, &data); + + return data.buf[0]; + } + + boost::uint16_t peek16(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL16, &data); + + return data.buf[0]; + } + + /******************************************************************* + * I2C + ******************************************************************/ + static const size_t max_i2c_data_bytes = 10; + + void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ + //allocate some memory for this transaction + UHD_ASSERT_THROW(bytes.size() <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c *data = reinterpret_cast(mem); + data->addr = addr; + data->len = bytes.size(); + std::copy(bytes.begin(), bytes.end(), data->data); + + //call the spi ioctl + this->ioctl(USRP_E_I2C_WRITE, data); + } + + byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ + //allocate some memory for this transaction + UHD_ASSERT_THROW(num_bytes <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c *data = reinterpret_cast(mem); + data->addr = addr; + data->len = num_bytes; + + //call the spi ioctl + this->ioctl(USRP_E_I2C_READ, data); + + //unload the data + byte_vector_t bytes(data->len); + UHD_ASSERT_THROW(bytes.size() == num_bytes); + std::copy(data->data, data->data+bytes.size(), bytes.begin()); + return bytes; + } + + /******************************************************************* + * SPI + ******************************************************************/ + boost::uint32_t transact_spi( + int which_slave, + const spi_config_t &config, + boost::uint32_t bits, + size_t num_bits, + bool readback + ){ + //load data struct + usrp_e_spi data; + data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; + data.slave = which_slave; + data.length = num_bits; + data.data = bits; + + //load the flags + data.flags = 0; + data.flags |= (config.miso_edge == spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (config.mosi_edge == spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; + + //call the spi ioctl + this->ioctl(USRP_E_SPI, &data); + + //unload the data + return data.data; + } + +private: + int _node_fd; + boost::mutex _ctrl_mutex; +}; + +/*********************************************************************** + * Public Make Function + **********************************************************************/ +usrp_e_iface::sptr usrp_e_iface::make(const std::string &node){ + return sptr(new usrp_e_iface_impl(node)); +} diff --git a/host/lib/usrp/usrp_e100/usrp_e_iface.hpp b/host/lib/usrp/usrp_e100/usrp_e_iface.hpp new file mode 100644 index 000000000..59aac43d9 --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e_iface.hpp @@ -0,0 +1,112 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_USRP_E_IFACE_HPP +#define INCLUDED_USRP_E_IFACE_HPP + +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////// +// I2C addresses +//////////////////////////////////////////////////////////////////////// +#define I2C_DEV_EEPROM 0x50 // 24LC02[45]: 7-bits 1010xxx +#define I2C_ADDR_MBOARD (I2C_DEV_EEPROM | 0x0) +#define I2C_ADDR_TX_DB (I2C_DEV_EEPROM | 0x4) +#define I2C_ADDR_RX_DB (I2C_DEV_EEPROM | 0x5) +//////////////////////////////////////////////////////////////////////// + +/*! + * The usrp-e interface class: + * Provides a set of functions to implementation layer. + * Including spi, peek, poke, control... + */ +class usrp_e_iface : boost::noncopyable, public uhd::i2c_iface{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a new usrp-e interface with the control transport. + * \param node the device node name + * \return a new usrp-e interface object + */ + static sptr make(const std::string &node); + + /*! + * Get the underlying file descriptor. + * \return the file descriptor + */ + virtual int get_file_descriptor(void) = 0; + + /*! + * Perform an ioctl call on the device node file descriptor. + * This will throw when the internal ioctl call fails. + * \param request the control word + * \param mem pointer to some memory + */ + virtual void ioctl(int request, void *mem) = 0; + + /*! + * Write a register (32 bits) + * \param addr the address + * \param data the 32bit data + */ + virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; + + /*! + * Read a register (32 bits) + * \param addr the address + * \return the 32bit data + */ + virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; + + /*! + * Write a register (16 bits) + * \param addr the address + * \param data the 16bit data + */ + virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0; + + /*! + * Read a register (16 bits) + * \param addr the address + * \return the 16bit data + */ + virtual boost::uint16_t peek16(boost::uint32_t addr) = 0; + + /*! + * Perform an spi transaction. + * \param which_slave the slave device number + * \param config spi config args + * \param data the bits to write + * \param num_bits how many bits in data + * \param readback true to readback a value + * \return spi data if readback set + */ + virtual boost::uint32_t transact_spi( + int which_slave, + const uhd::spi_config_t &config, + boost::uint32_t data, + size_t num_bits, + bool readback + ) = 0; +}; + +#endif /* INCLUDED_USRP_E_IFACE_HPP */ diff --git a/host/lib/usrp/usrp_e100/usrp_e_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e_impl.cpp new file mode 100644 index 000000000..70cc399fb --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e_impl.cpp @@ -0,0 +1,201 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace uhd; +using namespace uhd::usrp; +namespace fs = boost::filesystem; + +/*********************************************************************** + * Helper Functions + **********************************************************************/ +static std::string abs_path(const std::string &file_path){ + return fs::system_complete(fs::path(file_path)).file_string(); +} + +/*********************************************************************** + * Discovery + **********************************************************************/ +static device_addrs_t usrp_e_find(const device_addr_t &hint){ + device_addrs_t usrp_e_addrs; + + //return an empty list of addresses when type is set to non-usrp-e + if (hint.has_key("type") and hint["type"] != "usrp-e") return usrp_e_addrs; + + //device node not provided, assume its 0 + if (not hint.has_key("node")){ + device_addr_t new_addr = hint; + new_addr["node"] = "/dev/usrp_e0"; + return usrp_e_find(new_addr); + } + + //use the given device node name + if (fs::exists(hint["node"])){ + device_addr_t new_addr; + new_addr["type"] = "usrp-e"; + new_addr["node"] = abs_path(hint["node"]); + usrp_e_addrs.push_back(new_addr); + } + + return usrp_e_addrs; +} + +/*********************************************************************** + * Make + **********************************************************************/ +static device::sptr usrp_e_make(const device_addr_t &device_addr){ + + //setup the main interface into fpga + std::string node = device_addr["node"]; + std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; + usrp_e_iface::sptr iface = usrp_e_iface::make(node); + + //------------------------------------------------------------------ + //-- Handle the FPGA loading... + //-- The image can be confimed as already loaded when: + //-- 1) The compatibility number matches. + //-- 2) The hash in the hash-file matches. + //------------------------------------------------------------------ + static const char *hash_file_path = "/tmp/usrp_e100_hash"; + + //extract the fpga path for usrp-e + std::string usrp_e_fpga_image = find_image_path( + device_addr.has_key("fpga")? device_addr["fpga"] : "usrp_e100_fpga.bin" + ); + + //calculate a hash of the fpga file + size_t fpga_hash = 0; + { + std::ifstream file(usrp_e_fpga_image.c_str()); + if (not file.good()) throw std::runtime_error( + "cannot open fpga file for read: " + usrp_e_fpga_image + ); + do{ + boost::hash_combine(fpga_hash, file.get()); + } while (file.good()); + file.close(); + } + + //read the compatibility number + boost::uint16_t fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); + + //read the hash in the hash-file + size_t loaded_hash = 0; + try{std::ifstream(hash_file_path) >> loaded_hash;}catch(...){} + + //if not loaded: load the fpga image and write the hash-file + if (fpga_compat_num != USRP_E_COMPAT_NUM or loaded_hash != fpga_hash){ + iface.reset(); + usrp_e_load_fpga(usrp_e_fpga_image); + std::cout << boost::format("re-Opening USRP-E on %s") % node << std::endl; + iface = usrp_e_iface::make(node); + try{std::ofstream(hash_file_path) << fpga_hash;}catch(...){} + } + + //check that the compatibility is correct + fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); + if (fpga_compat_num != USRP_E_COMPAT_NUM){ + throw std::runtime_error(str(boost::format( + "Expected fpga compatibility number 0x%x, but got 0x%x:\n" + "The fpga build is not compatible with the host code build." + ) % USRP_E_COMPAT_NUM % fpga_compat_num)); + } + + return device::sptr(new usrp_e_impl(iface)); +} + +UHD_STATIC_BLOCK(register_usrp_e_device){ + device::register_device(&usrp_e_find, &usrp_e_make); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp_e_impl::usrp_e_impl(usrp_e_iface::sptr iface): _iface(iface){ + + //setup interfaces into hardware + _clock_ctrl = usrp_e_clock_ctrl::make(_iface); + _codec_ctrl = usrp_e_codec_ctrl::make(_iface); + + //initialize the mboard + mboard_init(); + + //initialize the dboards + dboard_init(); + + //initialize the dsps + rx_ddc_init(); + tx_duc_init(); + + //init the codec properties + codec_init(); + + //init the io send/recv + io_init(); + + //set default subdev specs + this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t()); + this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t()); +} + +usrp_e_impl::~usrp_e_impl(void){ + /* NOP */ +} + +/*********************************************************************** + * Device Get + **********************************************************************/ +void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case DEVICE_PROP_NAME: + val = std::string("usrp-e device"); + return; + + case DEVICE_PROP_MBOARD: + UHD_ASSERT_THROW(key.name == ""); + val = _mboard_proxy->get_link(); + return; + + case DEVICE_PROP_MBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +/*********************************************************************** + * Device Set + **********************************************************************/ +void usrp_e_impl::set(const wax::obj &, const wax::obj &){ + UHD_THROW_PROP_SET_ERROR(); +} diff --git a/host/lib/usrp/usrp_e100/usrp_e_impl.hpp b/host/lib/usrp/usrp_e100/usrp_e_impl.hpp new file mode 100644 index 000000000..b5f21810d --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e_impl.hpp @@ -0,0 +1,164 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_iface.hpp" +#include "clock_ctrl.hpp" +#include "codec_ctrl.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef INCLUDED_USRP_E_IMPL_HPP +#define INCLUDED_USRP_E_IMPL_HPP + +static const boost::uint16_t USRP_E_COMPAT_NUM = 0x02; + +//! load an fpga image from a bin file into the usrp-e fpga +extern void usrp_e_load_fpga(const std::string &bin_file); + +/*! + * Make a usrp-e dboard interface. + * \param iface the usrp-e interface object + * \param clock the clock control interface + * \param codec the codec control interface + * \return a sptr to a new dboard interface + */ +uhd::usrp::dboard_iface::sptr make_usrp_e_dboard_iface( + usrp_e_iface::sptr iface, + usrp_e_clock_ctrl::sptr clock, + usrp_e_codec_ctrl::sptr codec +); + +/*! + * Simple wax obj proxy class: + * Provides a wax obj interface for a set and a get function. + * This allows us to create nested properties structures + * while maintaining flattened code within the implementation. + */ +class wax_obj_proxy : public wax::obj{ +public: + typedef boost::function get_t; + typedef boost::function set_t; + typedef boost::shared_ptr sptr; + + static sptr make(const get_t &get, const set_t &set){ + return sptr(new wax_obj_proxy(get, set)); + } + +private: + get_t _get; set_t _set; + wax_obj_proxy(const get_t &get, const set_t &set): _get(get), _set(set){}; + void get(const wax::obj &key, wax::obj &val){return _get(key, val);} + void set(const wax::obj &key, const wax::obj &val){return _set(key, val);} +}; + +/*! + * USRP1E implementation guts: + * The implementation details are encapsulated here. + * Handles properties on the mboard, dboard, dsps... + */ +class usrp_e_impl : public uhd::device{ +public: + //structors + usrp_e_impl(usrp_e_iface::sptr); + ~usrp_e_impl(void); + + //the io interface + size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t, double); + size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, double); + bool recv_async_msg(uhd::async_metadata_t &, double); + size_t get_max_send_samps_per_packet(void) const; + size_t get_max_recv_samps_per_packet(void) const; + +private: + //interface to ioctls and file descriptor + usrp_e_iface::sptr _iface; + + //handle io stuff + UHD_PIMPL_DECL(io_impl) _io_impl; + uhd::otw_type_t _send_otw_type, _recv_otw_type; + void io_init(void); + void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd); + void handle_overrun(size_t); + + //configuration shadows + uhd::clock_config_t _clock_config; + //TODO otw type recv/send + + //ad9522 clock control + usrp_e_clock_ctrl::sptr _clock_ctrl; + + //ad9862 codec control + usrp_e_codec_ctrl::sptr _codec_ctrl; + + //device functions and settings + void get(const wax::obj &, wax::obj &); + void set(const wax::obj &, const wax::obj &); + + //mboard functions and settings + void mboard_init(void); + void mboard_get(const wax::obj &, wax::obj &); + void mboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _mboard_proxy; + uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec; + + //xx dboard functions and settings + void dboard_init(void); + uhd::usrp::dboard_manager::sptr _dboard_manager; + uhd::usrp::dboard_iface::sptr _dboard_iface; + + //rx dboard functions and settings + uhd::usrp::dboard_eeprom_t _rx_db_eeprom; + void rx_dboard_get(const wax::obj &, wax::obj &); + void rx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _rx_dboard_proxy; + + //tx dboard functions and settings + uhd::usrp::dboard_eeprom_t _tx_db_eeprom; + void tx_dboard_get(const wax::obj &, wax::obj &); + void tx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _tx_dboard_proxy; + + //rx ddc functions and settings + void rx_ddc_init(void); + void rx_ddc_get(const wax::obj &, wax::obj &); + void rx_ddc_set(const wax::obj &, const wax::obj &); + double _ddc_freq; size_t _ddc_decim; + wax_obj_proxy::sptr _rx_ddc_proxy; + + //tx duc functions and settings + void tx_duc_init(void); + void tx_duc_get(const wax::obj &, wax::obj &); + void tx_duc_set(const wax::obj &, const wax::obj &); + double _duc_freq; size_t _duc_interp; + wax_obj_proxy::sptr _tx_duc_proxy; + + //codec functions and settings + void codec_init(void); + void rx_codec_get(const wax::obj &, wax::obj &); + void rx_codec_set(const wax::obj &, const wax::obj &); + void tx_codec_get(const wax::obj &, wax::obj &); + void tx_codec_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _rx_codec_proxy, _tx_codec_proxy; +}; + +#endif /* INCLUDED_USRP_E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp new file mode 100644 index 000000000..274bb043e --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp @@ -0,0 +1,215 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e_iface.hpp" +#include +#include +#include +#include //mmap +#include //getpagesize +#include //poll +#include +#include +#include + +using namespace uhd; +using namespace uhd::transport; + +static const bool fp_verbose = false; //fast-path verbose +static const bool sp_verbose = false; //slow-path verbose +static const size_t poll_breakout = 10; //how many poll timeouts constitute a full timeout + +/*********************************************************************** + * The zero copy interface implementation + **********************************************************************/ +class usrp_e_mmap_zero_copy_impl : public zero_copy_if, public boost::enable_shared_from_this { +public: + usrp_e_mmap_zero_copy_impl(usrp_e_iface::sptr iface): + _fd(iface->get_file_descriptor()), _recv_index(0), _send_index(0) + { + //get system sizes + iface->ioctl(USRP_E_GET_RB_INFO, &_rb_size); + size_t page_size = getpagesize(); + _frame_size = page_size/2; + + //calculate the memory size + _map_size = + (_rb_size.num_pages_rx_flags + _rb_size.num_pages_tx_flags) * page_size + + (_rb_size.num_rx_frames + _rb_size.num_tx_frames) * _frame_size; + + //print sizes summary + if (sp_verbose){ + std::cout << "page_size: " << page_size << std::endl; + std::cout << "frame_size: " << _frame_size << std::endl; + std::cout << "num_pages_rx_flags: " << _rb_size.num_pages_rx_flags << std::endl; + std::cout << "num_rx_frames: " << _rb_size.num_rx_frames << std::endl; + std::cout << "num_pages_tx_flags: " << _rb_size.num_pages_tx_flags << std::endl; + std::cout << "num_tx_frames: " << _rb_size.num_tx_frames << std::endl; + std::cout << "map_size: " << _map_size << std::endl; + } + + //call mmap to get the memory + _mapped_mem = ::mmap( + NULL, _map_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0 + ); + UHD_ASSERT_THROW(_mapped_mem != MAP_FAILED); + + //calculate the memory offsets for info and buffers + size_t recv_info_off = 0; + size_t recv_buff_off = recv_info_off + (_rb_size.num_pages_rx_flags * page_size); + size_t send_info_off = recv_buff_off + (_rb_size.num_rx_frames * _frame_size); + size_t send_buff_off = send_info_off + (_rb_size.num_pages_tx_flags * page_size); + + //print offset summary + if (sp_verbose){ + std::cout << "recv_info_off: " << recv_info_off << std::endl; + std::cout << "recv_buff_off: " << recv_buff_off << std::endl; + std::cout << "send_info_off: " << send_info_off << std::endl; + std::cout << "send_buff_off: " << send_buff_off << std::endl; + } + + //set the internal pointers for info and buffers + typedef ring_buffer_info (*rbi_pta)[]; + char *rb_ptr = reinterpret_cast(_mapped_mem); + _recv_info = reinterpret_cast(rb_ptr + recv_info_off); + _recv_buff = rb_ptr + recv_buff_off; + _send_info = reinterpret_cast(rb_ptr + send_info_off); + _send_buff = rb_ptr + send_buff_off; + } + + ~usrp_e_mmap_zero_copy_impl(void){ + if (sp_verbose) std::cout << "cleanup: munmap" << std::endl; + ::munmap(_mapped_mem, _map_size); + } + + managed_recv_buffer::sptr get_recv_buff(double timeout){ + if (fp_verbose) std::cout << "get_recv_buff: " << _recv_index << std::endl; + + //grab pointers to the info and buffer + ring_buffer_info *info = (*_recv_info) + _recv_index; + void *mem = _recv_buff + _frame_size*_recv_index; + + //poll/wait for a ready frame + if (not (info->flags & RB_USER)){ + for (size_t i = 0; i < poll_breakout; i++){ + pollfd pfd; + pfd.fd = _fd; + pfd.events = POLLIN; + ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3/poll_breakout)); + if (fp_verbose) std::cout << " POLLIN: " << poll_ret << std::endl; + if (poll_ret > 0) goto found_user_frame; //good poll, continue on + } + return managed_recv_buffer::sptr(); //timed-out for real + } found_user_frame: + + //the process has claimed the frame + info->flags = RB_USER_PROCESS; + + //increment the index for the next call + if (++_recv_index == size_t(_rb_size.num_rx_frames)) _recv_index = 0; + + //return the managed buffer for this frame + if (fp_verbose) std::cout << " make_recv_buff: " << info->len << std::endl; + return managed_recv_buffer::make_safe( + boost::asio::const_buffer(mem, info->len), + boost::bind(&usrp_e_mmap_zero_copy_impl::release, shared_from_this(), info) + ); + } + + size_t get_num_recv_frames(void) const{ + return _rb_size.num_rx_frames; + } + + size_t get_recv_frame_size(void) const{ + return _frame_size; + } + + managed_send_buffer::sptr get_send_buff(double timeout){ + if (fp_verbose) std::cout << "get_send_buff: " << _send_index << std::endl; + + //grab pointers to the info and buffer + ring_buffer_info *info = (*_send_info) + _send_index; + void *mem = _send_buff + _frame_size*_send_index; + + //poll/wait for a ready frame + if (not (info->flags & RB_KERNEL)){ + pollfd pfd; + pfd.fd = _fd; + pfd.events = POLLOUT; + ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3)); + if (fp_verbose) std::cout << " POLLOUT: " << poll_ret << std::endl; + if (poll_ret <= 0) return managed_send_buffer::sptr(); + } + + //increment the index for the next call + if (++_send_index == size_t(_rb_size.num_tx_frames)) _send_index = 0; + + //return the managed buffer for this frame + if (fp_verbose) std::cout << " make_send_buff: " << _frame_size << std::endl; + return managed_send_buffer::make_safe( + boost::asio::mutable_buffer(mem, _frame_size), + boost::bind(&usrp_e_mmap_zero_copy_impl::commit, shared_from_this(), info, _1) + ); + } + + size_t get_num_send_frames(void) const{ + return _rb_size.num_tx_frames; + } + + size_t get_send_frame_size(void) const{ + return _frame_size; + } + +private: + + void release(ring_buffer_info *info){ + if (fp_verbose) std::cout << "recv buff: release" << std::endl; + info->flags = RB_KERNEL; + } + + void commit(ring_buffer_info *info, size_t len){ + if (fp_verbose) std::cout << "send buff: commit " << len << std::endl; + info->len = len; + info->flags = RB_USER; + if (::write(_fd, NULL, 0) < 0){ + std::cerr << UHD_THROW_SITE_INFO("write error") << std::endl; + } + } + + int _fd; + + //the mapped memory itself + void *_mapped_mem; + + //mapped memory sizes + usrp_e_ring_buffer_size_t _rb_size; + size_t _frame_size, _map_size; + + //pointers to sections in the mapped memory + ring_buffer_info (*_recv_info)[], (*_send_info)[]; + char *_recv_buff, *_send_buff; + + //indexes into sub-sections of mapped memory + size_t _recv_index, _send_index; +}; + +/*********************************************************************** + * The zero copy interface make function + **********************************************************************/ +zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface){ + return zero_copy_if::sptr(new usrp_e_mmap_zero_copy_impl(iface)); +} diff --git a/host/lib/usrp/usrp_e100/usrp_e_regs.hpp b/host/lib/usrp/usrp_e100/usrp_e_regs.hpp new file mode 100644 index 000000000..8bfb08b6f --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e_regs.hpp @@ -0,0 +1,198 @@ + + +//////////////////////////////////////////////////////////////// +// +// Memory map for embedded wishbone bus +// +//////////////////////////////////////////////////////////////// + +// All addresses are byte addresses. All accesses are word (16-bit) accesses. +// This means that address bit 0 is usually 0. +// There are 11 bits of address for the control. + +#ifndef __USRP_E_REGS_H +#define __USRP_E_REGS_H + +///////////////////////////////////////////////////// +// Slave pointers + +#define UE_REG_SLAVE(n) ((n)<<7) +#define UE_REG_SR_ADDR(n) ((UE_REG_SLAVE(5)) + (4*(n))) + +///////////////////////////////////////////////////// +// Slave 0 -- Misc Regs + +#define UE_REG_MISC_BASE UE_REG_SLAVE(0) + +#define UE_REG_MISC_LED UE_REG_MISC_BASE + 0 +#define UE_REG_MISC_SW UE_REG_MISC_BASE + 2 +#define UE_REG_MISC_CGEN_CTRL UE_REG_MISC_BASE + 4 +#define UE_REG_MISC_CGEN_ST UE_REG_MISC_BASE + 6 +#define UE_REG_MISC_TEST UE_REG_MISC_BASE + 8 +#define UE_REG_MISC_RX_LEN UE_REG_MISC_BASE + 10 +#define UE_REG_MISC_TX_LEN UE_REG_MISC_BASE + 12 +#define UE_REG_MISC_XFER_RATE UE_REG_MISC_BASE + 14 +#define UE_REG_MISC_COMPAT UE_REG_MISC_BASE + 16 + +///////////////////////////////////////////////////// +// Slave 1 -- UART +// CLKDIV is 16 bits, others are only 8 + +#define UE_REG_UART_BASE UE_REG_SLAVE(1) + +#define UE_REG_UART_CLKDIV UE_REG_UART_BASE + 0 +#define UE_REG_UART_TXLEVEL UE_REG_UART_BASE + 2 +#define UE_REG_UART_RXLEVEL UE_REG_UART_BASE + 4 +#define UE_REG_UART_TXCHAR UE_REG_UART_BASE + 6 +#define UE_REG_UART_RXCHAR UE_REG_UART_BASE + 8 + +///////////////////////////////////////////////////// +// Slave 2 -- SPI Core +// This should be accessed through the IOCTL +// Users should not touch directly + +#define UE_REG_SPI_BASE UE_REG_SLAVE(2) + +//spi slave constants +#define UE_SPI_SS_AD9522 (1 << 3) +#define UE_SPI_SS_AD9862 (1 << 2) +#define UE_SPI_SS_TX_DB (1 << 1) +#define UE_SPI_SS_RX_DB (1 << 0) + +//////////////////////////////////////////////// +// Slave 3 -- I2C Core +// This should be accessed through the IOCTL +// Users should not touch directly + +#define UE_REG_I2C_BASE UE_REG_SLAVE(3) + + +//////////////////////////////////////////////// +// Slave 4 -- GPIO + +#define UE_REG_GPIO_BASE UE_REG_SLAVE(4) + +#define UE_REG_GPIO_RX_IO UE_REG_GPIO_BASE + 0 +#define UE_REG_GPIO_TX_IO UE_REG_GPIO_BASE + 2 +#define UE_REG_GPIO_RX_DDR UE_REG_GPIO_BASE + 4 +#define UE_REG_GPIO_TX_DDR UE_REG_GPIO_BASE + 6 +#define UE_REG_GPIO_RX_SEL UE_REG_GPIO_BASE + 8 +#define UE_REG_GPIO_TX_SEL UE_REG_GPIO_BASE + 10 +#define UE_REG_GPIO_RX_DBG UE_REG_GPIO_BASE + 12 +#define UE_REG_GPIO_TX_DBG UE_REG_GPIO_BASE + 14 + +//possible bit values for sel when dbg is 0: +#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg +#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic + +//possible bit values for sel when dbg is 1: +#define GPIO_SEL_DEBUG_0 0 // if pin is an output, debug lines from FPGA fabric +#define GPIO_SEL_DEBUG_1 1 // if pin is an output, debug lines from FPGA fabric + + +//////////////////////////////////////////////////// +// Slave 5 -- Settings Bus +// +// Output-only, no readback, 32 registers total +// Each register must be written 32 bits at a time +// First the address xxx_xx00 and then xxx_xx10 + +#define UE_REG_SETTINGS_BASE UE_REG_SLAVE(5) + +/////////////////////////////////////////////////// +// Slave 6 -- ATR Controller +// 16 regs + +#define UE_REG_ATR_BASE UE_REG_SLAVE(6) + +#define UE_REG_ATR_IDLE_RXSIDE UE_REG_ATR_BASE + 0 +#define UE_REG_ATR_IDLE_TXSIDE UE_REG_ATR_BASE + 2 +#define UE_REG_ATR_INTX_RXSIDE UE_REG_ATR_BASE + 4 +#define UE_REG_ATR_INTX_TXSIDE UE_REG_ATR_BASE + 6 +#define UE_REG_ATR_INRX_RXSIDE UE_REG_ATR_BASE + 8 +#define UE_REG_ATR_INRX_TXSIDE UE_REG_ATR_BASE + 10 +#define UE_REG_ATR_FULL_RXSIDE UE_REG_ATR_BASE + 12 +#define UE_REG_ATR_FULL_TXSIDE UE_REG_ATR_BASE + 14 + +///////////////////////////////////////////////// +// DSP RX Regs +//////////////////////////////////////////////// +#define UE_REG_DSP_RX_FREQ UE_REG_SR_ADDR(0) +#define UE_REG_DSP_RX_SCALE_IQ UE_REG_SR_ADDR(1) // {scale_i,scale_q} +#define UE_REG_DSP_RX_DECIM_RATE UE_REG_SR_ADDR(2) // hb and decim rate +#define UE_REG_DSP_RX_DCOFFSET_I UE_REG_SR_ADDR(3) // Bit 31 high sets fixed offset mode, using lower 14 bits, // otherwise it is automatic +#define UE_REG_DSP_RX_DCOFFSET_Q UE_REG_SR_ADDR(4) // Bit 31 high sets fixed offset mode, using lower 14 bits +#define UE_REG_DSP_RX_MUX UE_REG_SR_ADDR(5) + +/////////////////////////////////////////////////// +// VITA RX CTRL regs +/////////////////////////////////////////////////// +// The following 3 are logically a single command register. +// They are clocked into the underlying fifo when time_ticks is written. +#define UE_REG_CTRL_RX_STREAM_CMD UE_REG_SR_ADDR(8) // {now, chain, num_samples(30) +#define UE_REG_CTRL_RX_TIME_SECS UE_REG_SR_ADDR(9) +#define UE_REG_CTRL_RX_TIME_TICKS UE_REG_SR_ADDR(10) +#define UE_REG_CTRL_RX_CLEAR_OVERRUN UE_REG_SR_ADDR(11) // write anything to clear overrun +#define UE_REG_CTRL_RX_VRT_HEADER UE_REG_SR_ADDR(12) // word 0 of packet. FPGA fills in packet counter +#define UE_REG_CTRL_RX_VRT_STREAM_ID UE_REG_SR_ADDR(13) // word 1 of packet. +#define UE_REG_CTRL_RX_VRT_TRAILER UE_REG_SR_ADDR(14) +#define UE_REG_CTRL_RX_NSAMPS_PER_PKT UE_REG_SR_ADDR(15) +#define UE_REG_CTRL_RX_NCHANNELS UE_REG_SR_ADDR(16) // 1 in basic case, up to 4 for vector sources + +///////////////////////////////////////////////// +// DSP TX Regs +//////////////////////////////////////////////// +#define UE_REG_DSP_TX_FREQ UE_REG_SR_ADDR(17) +#define UE_REG_DSP_TX_SCALE_IQ UE_REG_SR_ADDR(18) // {scale_i,scale_q} +#define UE_REG_DSP_TX_INTERP_RATE UE_REG_SR_ADDR(19) +#define UE_REG_DSP_TX_UNUSED UE_REG_SR_ADDR(20) +#define UE_REG_DSP_TX_MUX UE_REG_SR_ADDR(21) + +///////////////////////////////////////////////// +// VITA TX CTRL regs +//////////////////////////////////////////////// +#define UE_REG_CTRL_TX_NCHANNELS UE_REG_SR_ADDR(24) +#define UE_REG_CTRL_TX_CLEAR_UNDERRUN UE_REG_SR_ADDR(25) +#define UE_REG_CTRL_TX_REPORT_SID UE_REG_SR_ADDR(26) +#define UE_REG_CTRL_TX_POLICY UE_REG_SR_ADDR(27) + +#define UE_FLAG_CTRL_TX_POLICY_WAIT (0x1 << 0) +#define UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET (0x1 << 1) +#define UE_FLAG_CTRL_TX_POLICY_NEXT_BURST (0x1 << 2) + +///////////////////////////////////////////////// +// VITA49 64 bit time (write only) +//////////////////////////////////////////////// + /*! + * \brief Time 64 flags + * + *
+   *
+   *    3                   2                   1
+   *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   * +-----------------------------------------------------------+-+-+
+   * |                                                           |S|P|
+   * +-----------------------------------------------------------+-+-+
+   *
+   * P - PPS edge selection (0=negedge, 1=posedge, default=0)
+   * S - Source (0=sma, 1=mimo, 0=default)
+   *
+   * 
+ */ +#define UE_REG_TIME64_SECS UE_REG_SR_ADDR(28) // value to set absolute secs to on next PPS +#define UE_REG_TIME64_TICKS UE_REG_SR_ADDR(29) // value to set absolute ticks to on next PPS +#define UE_REG_TIME64_FLAGS UE_REG_SR_ADDR(30) // flags - see chart above +#define UE_REG_TIME64_IMM UE_REG_SR_ADDR(31) // set immediate (0=latch on next pps, 1=latch immediate, default=0) +#define UE_REG_TIME64_TPS UE_REG_SR_ADDR(31) // clock ticks per second (counter rollover) + +//pps flags (see above) +#define UE_FLAG_TIME64_PPS_NEGEDGE (0 << 0) +#define UE_FLAG_TIME64_PPS_POSEDGE (1 << 0) +#define UE_FLAG_TIME64_PPS_SMA (0 << 1) +#define UE_FLAG_TIME64_PPS_MIMO (1 << 1) + +#define UE_FLAG_TIME64_LATCH_NOW 1 +#define UE_FLAG_TIME64_LATCH_NEXT_PPS 0 + +#endif + -- cgit v1.2.3 From 5f2c71383a2b5dd0f2f469f6ad8c4720358f2a12 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 9 Nov 2010 19:02:11 -0800 Subject: usrp-e100: renamed files and classes in usrp-e100 to e100 name --- host/lib/usrp/usrp_e100/CMakeLists.txt | 12 +- host/lib/usrp/usrp_e100/clock_ctrl.cpp | 14 +- host/lib/usrp/usrp_e100/clock_ctrl.hpp | 16 +- host/lib/usrp/usrp_e100/codec_ctrl.cpp | 38 ++-- host/lib/usrp/usrp_e100/codec_ctrl.hpp | 16 +- host/lib/usrp/usrp_e100/codec_impl.cpp | 24 +-- host/lib/usrp/usrp_e100/dboard_iface.cpp | 86 ++++----- host/lib/usrp/usrp_e100/dboard_impl.cpp | 24 +-- host/lib/usrp/usrp_e100/dsp_impl.cpp | 24 +-- host/lib/usrp/usrp_e100/fpga-downloader.cc | 2 +- host/lib/usrp/usrp_e100/io_impl.cpp | 38 ++-- host/lib/usrp/usrp_e100/mboard_impl.cpp | 14 +- host/lib/usrp/usrp_e100/usrp_e100_iface.cpp | 194 +++++++++++++++++++ host/lib/usrp/usrp_e100/usrp_e100_iface.hpp | 112 +++++++++++ host/lib/usrp/usrp_e100/usrp_e100_impl.cpp | 201 +++++++++++++++++++ host/lib/usrp/usrp_e100/usrp_e100_impl.hpp | 164 ++++++++++++++++ .../usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp | 215 +++++++++++++++++++++ host/lib/usrp/usrp_e100/usrp_e100_regs.hpp | 198 +++++++++++++++++++ host/lib/usrp/usrp_e100/usrp_e_iface.cpp | 194 ------------------- host/lib/usrp/usrp_e100/usrp_e_iface.hpp | 112 ----------- host/lib/usrp/usrp_e100/usrp_e_impl.cpp | 201 ------------------- host/lib/usrp/usrp_e100/usrp_e_impl.hpp | 164 ---------------- host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp | 215 --------------------- host/lib/usrp/usrp_e100/usrp_e_regs.hpp | 198 ------------------- 24 files changed, 1238 insertions(+), 1238 deletions(-) create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_iface.cpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_iface.hpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_impl.cpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_impl.hpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_regs.hpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_iface.cpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_iface.hpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_impl.cpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_impl.hpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_regs.hpp (limited to 'host') diff --git a/host/lib/usrp/usrp_e100/CMakeLists.txt b/host/lib/usrp/usrp_e100/CMakeLists.txt index 17ef53152..97a3d5d9a 100644 --- a/host/lib/usrp/usrp_e100/CMakeLists.txt +++ b/host/lib/usrp/usrp_e100/CMakeLists.txt @@ -52,12 +52,12 @@ IF(ENABLE_USRP_E100) ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/fpga-downloader.cc ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/io_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/mboard_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_impl.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_iface.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_iface.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_regs.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_impl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_iface.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_iface.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_regs.hpp ) ELSE(ENABLE_USRP_E100) MESSAGE(STATUS " Skipping USRP-E100 support.") diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.cpp b/host/lib/usrp/usrp_e100/clock_ctrl.cpp index 9d4625305..e99560540 100644 --- a/host/lib/usrp/usrp_e100/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e100/clock_ctrl.cpp @@ -19,7 +19,7 @@ #include "ad9522_regs.hpp" #include #include -#include "usrp_e_regs.hpp" //spi slave constants +#include "usrp_e100_regs.hpp" //spi slave constants #include #include #include @@ -58,9 +58,9 @@ static const size_t codec_clock_divider = size_t(master_clock_rate/64e6); /*********************************************************************** * Clock Control Implementation **********************************************************************/ -class usrp_e_clock_ctrl_impl : public usrp_e_clock_ctrl{ +class usrp_e100_clock_ctrl_impl : public usrp_e100_clock_ctrl{ public: - usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface){ + usrp_e100_clock_ctrl_impl(usrp_e100_iface::sptr iface){ _iface = iface; //init the clock gen registers @@ -137,7 +137,7 @@ public: this->enable_tx_dboard_clock(false); } - ~usrp_e_clock_ctrl_impl(void){ + ~usrp_e100_clock_ctrl_impl(void){ this->enable_rx_dboard_clock(false); this->enable_tx_dboard_clock(false); } @@ -210,7 +210,7 @@ public: } private: - usrp_e_iface::sptr _iface; + usrp_e100_iface::sptr _iface; ad9522_regs_t _ad9522_regs; void latch_regs(void){ @@ -232,6 +232,6 @@ private: /*********************************************************************** * Clock Control Make **********************************************************************/ -usrp_e_clock_ctrl::sptr usrp_e_clock_ctrl::make(usrp_e_iface::sptr iface){ - return sptr(new usrp_e_clock_ctrl_impl(iface)); +usrp_e100_clock_ctrl::sptr usrp_e100_clock_ctrl::make(usrp_e100_iface::sptr iface){ + return sptr(new usrp_e100_clock_ctrl_impl(iface)); } diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.hpp b/host/lib/usrp/usrp_e100/clock_ctrl.hpp index 3b5103ed1..0ae68728e 100644 --- a/host/lib/usrp/usrp_e100/clock_ctrl.hpp +++ b/host/lib/usrp/usrp_e100/clock_ctrl.hpp @@ -15,10 +15,10 @@ // along with this program. If not, see . // -#ifndef INCLUDED_USRP_E_CLOCK_CTRL_HPP -#define INCLUDED_USRP_E_CLOCK_CTRL_HPP +#ifndef INCLUDED_USRP_E100_CLOCK_CTRL_HPP +#define INCLUDED_USRP_E100_CLOCK_CTRL_HPP -#include "usrp_e_iface.hpp" +#include "usrp_e100_iface.hpp" #include #include #include @@ -28,16 +28,16 @@ * - Setup system clocks. * - Disable/enable clock lines. */ -class usrp_e_clock_ctrl : boost::noncopyable{ +class usrp_e100_clock_ctrl : boost::noncopyable{ public: - typedef boost::shared_ptr sptr; + typedef boost::shared_ptr sptr; /*! * Make a new clock control object. - * \param iface the usrp_e iface object + * \param iface the usrp_e100 iface object * \return the clock control object */ - static sptr make(usrp_e_iface::sptr iface); + static sptr make(usrp_e100_iface::sptr iface); /*! * Get the rate of the fpga clock line. @@ -85,4 +85,4 @@ public: }; -#endif /* INCLUDED_USRP_E_CLOCK_CTRL_HPP */ +#endif /* INCLUDED_USRP_E100_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e100/codec_ctrl.cpp b/host/lib/usrp/usrp_e100/codec_ctrl.cpp index a728d7e46..e7fd9792e 100644 --- a/host/lib/usrp/usrp_e100/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e100/codec_ctrl.cpp @@ -23,7 +23,7 @@ #include #include #include -#include "usrp_e_regs.hpp" //spi slave constants +#include "usrp_e100_regs.hpp" //spi slave constants #include #include @@ -31,17 +31,17 @@ using namespace uhd; static const bool codec_debug = false; -const gain_range_t usrp_e_codec_ctrl::tx_pga_gain_range(-20, 0, float(0.1)); -const gain_range_t usrp_e_codec_ctrl::rx_pga_gain_range(0, 20, 1); +const gain_range_t usrp_e100_codec_ctrl::tx_pga_gain_range(-20, 0, float(0.1)); +const gain_range_t usrp_e100_codec_ctrl::rx_pga_gain_range(0, 20, 1); /*********************************************************************** * Codec Control Implementation **********************************************************************/ -class usrp_e_codec_ctrl_impl : public usrp_e_codec_ctrl{ +class usrp_e100_codec_ctrl_impl : public usrp_e100_codec_ctrl{ public: //structors - usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface); - ~usrp_e_codec_ctrl_impl(void); + usrp_e100_codec_ctrl_impl(usrp_e100_iface::sptr iface); + ~usrp_e100_codec_ctrl_impl(void); //aux adc and dac control float read_aux_adc(aux_adc_t which); @@ -54,7 +54,7 @@ public: float get_rx_pga_gain(char); private: - usrp_e_iface::sptr _iface; + usrp_e100_iface::sptr _iface; ad9862_regs_t _ad9862_regs; aux_adc_t _last_aux_adc_a, _last_aux_adc_b; void send_reg(boost::uint8_t addr); @@ -64,7 +64,7 @@ private: /*********************************************************************** * Codec Control Structors **********************************************************************/ -usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ +usrp_e100_codec_ctrl_impl::usrp_e100_codec_ctrl_impl(usrp_e100_iface::sptr iface){ _iface = iface; //soft reset @@ -115,7 +115,7 @@ usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ this->send_reg(34); } -usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){ +usrp_e100_codec_ctrl_impl::~usrp_e100_codec_ctrl_impl(void){ //set aux dacs to zero this->write_aux_dac(AUX_DAC_A, 0); this->write_aux_dac(AUX_DAC_B, 0); @@ -135,19 +135,19 @@ usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){ **********************************************************************/ static const int mtpgw = 255; //maximum tx pga gain word -void usrp_e_codec_ctrl_impl::set_tx_pga_gain(float gain){ +void usrp_e100_codec_ctrl_impl::set_tx_pga_gain(float gain){ int gain_word = int(mtpgw*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw); this->send_reg(16); } -float usrp_e_codec_ctrl_impl::get_tx_pga_gain(void){ +float usrp_e100_codec_ctrl_impl::get_tx_pga_gain(void){ return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.max - tx_pga_gain_range.min)/mtpgw) + tx_pga_gain_range.min; } static const int mrpgw = 0x14; //maximum rx pga gain word -void usrp_e_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ +void usrp_e100_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ int gain_word = int(mrpgw*(gain - rx_pga_gain_range.min)/(rx_pga_gain_range.max - rx_pga_gain_range.min)); gain_word = std::clip(gain_word, 0, mrpgw); switch(which){ @@ -163,7 +163,7 @@ void usrp_e_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ } } -float usrp_e_codec_ctrl_impl::get_rx_pga_gain(char which){ +float usrp_e100_codec_ctrl_impl::get_rx_pga_gain(char which){ int gain_word; switch(which){ case 'A': gain_word = _ad9862_regs.rx_pga_a; break; @@ -180,7 +180,7 @@ static float aux_adc_to_volts(boost::uint8_t high, boost::uint8_t low){ return float((boost::uint16_t(high) << 2) | low)*3.3/0x3ff; } -float usrp_e_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ +float usrp_e100_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ //check to see if the switch needs to be set bool write_switch = false; switch(which){ @@ -233,7 +233,7 @@ float usrp_e_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ /*********************************************************************** * Codec Control AUX DAC Methods **********************************************************************/ -void usrp_e_codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ +void usrp_e100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ //special case for aux dac d (aka sigma delta word) if (which == AUX_DAC_D){ boost::uint16_t dac_word = std::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); @@ -266,7 +266,7 @@ void usrp_e_codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ /*********************************************************************** * Codec Control SPI Methods **********************************************************************/ -void usrp_e_codec_ctrl_impl::send_reg(boost::uint8_t addr){ +void usrp_e100_codec_ctrl_impl::send_reg(boost::uint8_t addr){ boost::uint32_t reg = _ad9862_regs.get_write_reg(addr); if (codec_debug) std::cout << "codec control write reg: " << std::hex << reg << std::endl; _iface->transact_spi( @@ -276,7 +276,7 @@ void usrp_e_codec_ctrl_impl::send_reg(boost::uint8_t addr){ ); } -void usrp_e_codec_ctrl_impl::recv_reg(boost::uint8_t addr){ +void usrp_e100_codec_ctrl_impl::recv_reg(boost::uint8_t addr){ boost::uint32_t reg = _ad9862_regs.get_read_reg(addr); if (codec_debug) std::cout << "codec control read reg: " << std::hex << reg << std::endl; boost::uint32_t ret = _iface->transact_spi( @@ -291,6 +291,6 @@ void usrp_e_codec_ctrl_impl::recv_reg(boost::uint8_t addr){ /*********************************************************************** * Codec Control Make **********************************************************************/ -usrp_e_codec_ctrl::sptr usrp_e_codec_ctrl::make(usrp_e_iface::sptr iface){ - return sptr(new usrp_e_codec_ctrl_impl(iface)); +usrp_e100_codec_ctrl::sptr usrp_e100_codec_ctrl::make(usrp_e100_iface::sptr iface){ + return sptr(new usrp_e100_codec_ctrl_impl(iface)); } diff --git a/host/lib/usrp/usrp_e100/codec_ctrl.hpp b/host/lib/usrp/usrp_e100/codec_ctrl.hpp index 87b6ff951..74ce9bd9a 100644 --- a/host/lib/usrp/usrp_e100/codec_ctrl.hpp +++ b/host/lib/usrp/usrp_e100/codec_ctrl.hpp @@ -15,10 +15,10 @@ // along with this program. If not, see . // -#ifndef INCLUDED_USRP_E_CODEC_CTRL_HPP -#define INCLUDED_USRP_E_CODEC_CTRL_HPP +#ifndef INCLUDED_USRP_E100_CODEC_CTRL_HPP +#define INCLUDED_USRP_E100_CODEC_CTRL_HPP -#include "usrp_e_iface.hpp" +#include "usrp_e100_iface.hpp" #include #include #include @@ -28,19 +28,19 @@ * - Init/power down codec. * - Read aux adc, write aux dac. */ -class usrp_e_codec_ctrl : boost::noncopyable{ +class usrp_e100_codec_ctrl : boost::noncopyable{ public: - typedef boost::shared_ptr sptr; + typedef boost::shared_ptr sptr; static const uhd::gain_range_t tx_pga_gain_range; static const uhd::gain_range_t rx_pga_gain_range; /*! * Make a new codec control object. - * \param iface the usrp_e iface object + * \param iface the usrp_e100 iface object * \return the codec control object */ - static sptr make(usrp_e_iface::sptr iface); + static sptr make(usrp_e100_iface::sptr iface); //! aux adc identifier constants enum aux_adc_t{ @@ -87,4 +87,4 @@ public: virtual float get_rx_pga_gain(char which) = 0; }; -#endif /* INCLUDED_USRP_E_CODEC_CTRL_HPP */ +#endif /* INCLUDED_USRP_E100_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e100/codec_impl.cpp b/host/lib/usrp/usrp_e100/codec_impl.cpp index 696fb37ec..6fd44bad3 100644 --- a/host/lib/usrp/usrp_e100/codec_impl.cpp +++ b/host/lib/usrp/usrp_e100/codec_impl.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see . // -#include "usrp_e_impl.hpp" +#include "usrp_e100_impl.hpp" #include #include #include @@ -26,15 +26,15 @@ using namespace uhd::usrp; /*********************************************************************** * Helper Methods **********************************************************************/ -void usrp_e_impl::codec_init(void){ +void usrp_e100_impl::codec_init(void){ //make proxies _rx_codec_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::rx_codec_get, this, _1, _2), - boost::bind(&usrp_e_impl::rx_codec_set, this, _1, _2) + boost::bind(&usrp_e100_impl::rx_codec_get, this, _1, _2), + boost::bind(&usrp_e100_impl::rx_codec_set, this, _1, _2) ); _tx_codec_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::tx_codec_get, this, _1, _2), - boost::bind(&usrp_e_impl::tx_codec_set, this, _1, _2) + boost::bind(&usrp_e100_impl::tx_codec_get, this, _1, _2), + boost::bind(&usrp_e100_impl::tx_codec_set, this, _1, _2) ); } @@ -43,7 +43,7 @@ void usrp_e_impl::codec_init(void){ **********************************************************************/ static const std::string ad9862_pga_gain_name = "ad9862 pga"; -void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key @@ -62,7 +62,7 @@ void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ case CODEC_PROP_GAIN_RANGE: UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - val = usrp_e_codec_ctrl::rx_pga_gain_range; + val = usrp_e100_codec_ctrl::rx_pga_gain_range; return; case CODEC_PROP_GAIN_I: @@ -79,7 +79,7 @@ void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ } } -void usrp_e_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ +void usrp_e100_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the set request conditioned on the key @@ -101,7 +101,7 @@ void usrp_e_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ /*********************************************************************** * TX Codec Properties **********************************************************************/ -void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key @@ -120,7 +120,7 @@ void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ case CODEC_PROP_GAIN_RANGE: UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - val = usrp_e_codec_ctrl::tx_pga_gain_range; + val = usrp_e100_codec_ctrl::tx_pga_gain_range; return; case CODEC_PROP_GAIN_I: //only one gain for I and Q @@ -133,7 +133,7 @@ void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ } } -void usrp_e_impl::tx_codec_set(const wax::obj &key_, const wax::obj &val){ +void usrp_e100_impl::tx_codec_set(const wax::obj &key_, const wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the set request conditioned on the key diff --git a/host/lib/usrp/usrp_e100/dboard_iface.cpp b/host/lib/usrp/usrp_e100/dboard_iface.cpp index 6898df8df..aa96171d6 100644 --- a/host/lib/usrp/usrp_e100/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e100/dboard_iface.cpp @@ -15,8 +15,8 @@ // along with this program. If not, see . // -#include "usrp_e_iface.hpp" -#include "usrp_e_regs.hpp" +#include "usrp_e100_iface.hpp" +#include "usrp_e100_regs.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" #include @@ -29,13 +29,13 @@ using namespace uhd; using namespace uhd::usrp; using namespace boost::assign; -class usrp_e_dboard_iface : public dboard_iface{ +class usrp_e100_dboard_iface : public dboard_iface{ public: - usrp_e_dboard_iface( - usrp_e_iface::sptr iface, - usrp_e_clock_ctrl::sptr clock, - usrp_e_codec_ctrl::sptr codec + usrp_e100_dboard_iface( + usrp_e100_iface::sptr iface, + usrp_e100_clock_ctrl::sptr clock, + usrp_e100_codec_ctrl::sptr codec ){ _iface = iface; _clock = clock; @@ -49,7 +49,7 @@ public: _iface->poke16(UE_REG_GPIO_TX_DBG, 0); } - ~usrp_e_dboard_iface(void){ + ~usrp_e100_dboard_iface(void){ /* NOP */ } @@ -94,27 +94,27 @@ public: double get_codec_rate(unit_t); private: - usrp_e_iface::sptr _iface; - usrp_e_clock_ctrl::sptr _clock; - usrp_e_codec_ctrl::sptr _codec; + usrp_e100_iface::sptr _iface; + usrp_e100_clock_ctrl::sptr _clock; + usrp_e100_codec_ctrl::sptr _codec; uhd::dict _clock_rates; }; /*********************************************************************** * Make Function **********************************************************************/ -dboard_iface::sptr make_usrp_e_dboard_iface( - usrp_e_iface::sptr iface, - usrp_e_clock_ctrl::sptr clock, - usrp_e_codec_ctrl::sptr codec +dboard_iface::sptr make_usrp_e100_dboard_iface( + usrp_e100_iface::sptr iface, + usrp_e100_clock_ctrl::sptr clock, + usrp_e100_codec_ctrl::sptr codec ){ - return dboard_iface::sptr(new usrp_e_dboard_iface(iface, clock, codec)); + return dboard_iface::sptr(new usrp_e100_dboard_iface(iface, clock, codec)); } /*********************************************************************** * Clock Rates **********************************************************************/ -void usrp_e_dboard_iface::set_clock_rate(unit_t unit, double rate){ +void usrp_e100_dboard_iface::set_clock_rate(unit_t unit, double rate){ _clock_rates[unit] = rate; switch(unit){ case UNIT_RX: return _clock->set_rx_dboard_clock_rate(rate); @@ -122,7 +122,7 @@ void usrp_e_dboard_iface::set_clock_rate(unit_t unit, double rate){ } } -std::vector usrp_e_dboard_iface::get_clock_rates(unit_t unit){ +std::vector usrp_e100_dboard_iface::get_clock_rates(unit_t unit){ switch(unit){ case UNIT_RX: return _clock->get_rx_dboard_clock_rates(); case UNIT_TX: return _clock->get_tx_dboard_clock_rates(); @@ -130,25 +130,25 @@ std::vector usrp_e_dboard_iface::get_clock_rates(unit_t unit){ } } -double usrp_e_dboard_iface::get_clock_rate(unit_t unit){ +double usrp_e100_dboard_iface::get_clock_rate(unit_t unit){ return _clock_rates[unit]; } -void usrp_e_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ +void usrp_e100_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ switch(unit){ case UNIT_RX: return _clock->enable_rx_dboard_clock(enb); case UNIT_TX: return _clock->enable_tx_dboard_clock(enb); } } -double usrp_e_dboard_iface::get_codec_rate(unit_t){ +double usrp_e100_dboard_iface::get_codec_rate(unit_t){ return _clock->get_fpga_clock_rate(); } /*********************************************************************** * GPIO **********************************************************************/ -void usrp_e_dboard_iface::set_pin_ctrl(unit_t unit, boost::uint16_t value){ +void usrp_e100_dboard_iface::set_pin_ctrl(unit_t unit, boost::uint16_t value){ UHD_ASSERT_THROW(GPIO_SEL_ATR == 1); //make this assumption switch(unit){ case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_SEL, value); return; @@ -156,21 +156,21 @@ void usrp_e_dboard_iface::set_pin_ctrl(unit_t unit, boost::uint16_t value){ } } -void usrp_e_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value){ +void usrp_e100_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value){ switch(unit){ case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_DDR, value); return; case UNIT_TX: _iface->poke16(UE_REG_GPIO_TX_DDR, value); return; } } -void usrp_e_dboard_iface::write_gpio(unit_t unit, boost::uint16_t value){ +void usrp_e100_dboard_iface::write_gpio(unit_t unit, boost::uint16_t value){ switch(unit){ case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_IO, value); return; case UNIT_TX: _iface->poke16(UE_REG_GPIO_TX_IO, value); return; } } -boost::uint16_t usrp_e_dboard_iface::read_gpio(unit_t unit){ +boost::uint16_t usrp_e100_dboard_iface::read_gpio(unit_t unit){ switch(unit){ case UNIT_RX: return _iface->peek16(UE_REG_GPIO_RX_IO); case UNIT_TX: return _iface->peek16(UE_REG_GPIO_TX_IO); @@ -178,7 +178,7 @@ boost::uint16_t usrp_e_dboard_iface::read_gpio(unit_t unit){ } } -void usrp_e_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){ +void usrp_e100_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){ //define mapping of unit to atr regs to register address static const uhd::dict< unit_t, uhd::dict @@ -199,7 +199,7 @@ void usrp_e_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_ _iface->poke16(unit_to_atr_to_addr[unit][atr], value); } -void usrp_e_dboard_iface::set_gpio_debug(unit_t unit, int which){ +void usrp_e100_dboard_iface::set_gpio_debug(unit_t unit, int which){ //set this unit to all outputs this->set_gpio_ddr(unit, 0xffff); @@ -238,7 +238,7 @@ static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){ throw std::invalid_argument("unknown unit type"); } -void usrp_e_dboard_iface::write_spi( +void usrp_e100_dboard_iface::write_spi( unit_t unit, const spi_config_t &config, boost::uint32_t data, @@ -247,7 +247,7 @@ void usrp_e_dboard_iface::write_spi( _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/); } -boost::uint32_t usrp_e_dboard_iface::read_write_spi( +boost::uint32_t usrp_e100_dboard_iface::read_write_spi( unit_t unit, const spi_config_t &config, boost::uint32_t data, @@ -259,39 +259,39 @@ boost::uint32_t usrp_e_dboard_iface::read_write_spi( /*********************************************************************** * I2C **********************************************************************/ -void usrp_e_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ +void usrp_e100_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ return _iface->write_i2c(addr, bytes); } -byte_vector_t usrp_e_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){ +byte_vector_t usrp_e100_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){ return _iface->read_i2c(addr, num_bytes); } /*********************************************************************** * Aux DAX/ADC **********************************************************************/ -void usrp_e_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, float value){ +void usrp_e100_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, float value){ //same aux dacs for each unit - static const uhd::dict which_to_aux_dac = map_list_of - (AUX_DAC_A, usrp_e_codec_ctrl::AUX_DAC_A) - (AUX_DAC_B, usrp_e_codec_ctrl::AUX_DAC_B) - (AUX_DAC_C, usrp_e_codec_ctrl::AUX_DAC_C) - (AUX_DAC_D, usrp_e_codec_ctrl::AUX_DAC_D) + static const uhd::dict which_to_aux_dac = map_list_of + (AUX_DAC_A, usrp_e100_codec_ctrl::AUX_DAC_A) + (AUX_DAC_B, usrp_e100_codec_ctrl::AUX_DAC_B) + (AUX_DAC_C, usrp_e100_codec_ctrl::AUX_DAC_C) + (AUX_DAC_D, usrp_e100_codec_ctrl::AUX_DAC_D) ; _codec->write_aux_dac(which_to_aux_dac[which], value); } -float usrp_e_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which){ +float usrp_e100_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which){ static const uhd::dict< - unit_t, uhd::dict + unit_t, uhd::dict > unit_to_which_to_aux_adc = map_list_of (UNIT_RX, map_list_of - (AUX_ADC_A, usrp_e_codec_ctrl::AUX_ADC_A1) - (AUX_ADC_B, usrp_e_codec_ctrl::AUX_ADC_B1) + (AUX_ADC_A, usrp_e100_codec_ctrl::AUX_ADC_A1) + (AUX_ADC_B, usrp_e100_codec_ctrl::AUX_ADC_B1) ) (UNIT_TX, map_list_of - (AUX_ADC_A, usrp_e_codec_ctrl::AUX_ADC_A2) - (AUX_ADC_B, usrp_e_codec_ctrl::AUX_ADC_B2) + (AUX_ADC_A, usrp_e100_codec_ctrl::AUX_ADC_A2) + (AUX_ADC_B, usrp_e100_codec_ctrl::AUX_ADC_B2) ) ; return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]); diff --git a/host/lib/usrp/usrp_e100/dboard_impl.cpp b/host/lib/usrp/usrp_e100/dboard_impl.cpp index f2840dcfc..9f2bfb8ae 100644 --- a/host/lib/usrp/usrp_e100/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e100/dboard_impl.cpp @@ -15,8 +15,8 @@ // along with this program. If not, see . // -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" +#include "usrp_e100_impl.hpp" +#include "usrp_e100_regs.hpp" #include #include #include @@ -30,12 +30,12 @@ using namespace uhd::usrp; /*********************************************************************** * Dboard Initialization **********************************************************************/ -void usrp_e_impl::dboard_init(void){ +void usrp_e100_impl::dboard_init(void){ _rx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes())); _tx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_TX_DB, 0, dboard_eeprom_t::num_bytes())); //create a new dboard interface and manager - _dboard_iface = make_usrp_e_dboard_iface( + _dboard_iface = make_usrp_e100_dboard_iface( _iface, _clock_ctrl, _codec_ctrl ); _dboard_manager = dboard_manager::make( @@ -44,19 +44,19 @@ void usrp_e_impl::dboard_init(void){ //setup the dboard proxies _rx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::rx_dboard_get, this, _1, _2), - boost::bind(&usrp_e_impl::rx_dboard_set, this, _1, _2) + boost::bind(&usrp_e100_impl::rx_dboard_get, this, _1, _2), + boost::bind(&usrp_e100_impl::rx_dboard_set, this, _1, _2) ); _tx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::tx_dboard_get, this, _1, _2), - boost::bind(&usrp_e_impl::tx_dboard_set, this, _1, _2) + boost::bind(&usrp_e100_impl::tx_dboard_get, this, _1, _2), + boost::bind(&usrp_e100_impl::tx_dboard_set, this, _1, _2) ); } /*********************************************************************** * RX Dboard Get **********************************************************************/ -void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key @@ -101,7 +101,7 @@ void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * RX Dboard Set **********************************************************************/ -void usrp_e_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ +void usrp_e100_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ switch(key.as()){ case DBOARD_PROP_DBOARD_ID: _rx_db_eeprom.id = val.as(); @@ -115,7 +115,7 @@ void usrp_e_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ /*********************************************************************** * TX Dboard Get **********************************************************************/ -void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key @@ -160,7 +160,7 @@ void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * TX Dboard Set **********************************************************************/ -void usrp_e_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ +void usrp_e100_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ switch(key.as()){ case DBOARD_PROP_DBOARD_ID: _tx_db_eeprom.id = val.as(); diff --git a/host/lib/usrp/usrp_e100/dsp_impl.cpp b/host/lib/usrp/usrp_e100/dsp_impl.cpp index 97f173c1a..43a3bd3be 100644 --- a/host/lib/usrp/usrp_e100/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e100/dsp_impl.cpp @@ -15,8 +15,8 @@ // along with this program. If not, see . // -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" +#include "usrp_e100_impl.hpp" +#include "usrp_e100_regs.hpp" #include #include #include @@ -30,10 +30,10 @@ using namespace uhd::usrp; /*********************************************************************** * RX DDC Initialization **********************************************************************/ -void usrp_e_impl::rx_ddc_init(void){ +void usrp_e100_impl::rx_ddc_init(void){ _rx_ddc_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::rx_ddc_get, this, _1, _2), - boost::bind(&usrp_e_impl::rx_ddc_set, this, _1, _2) + boost::bind(&usrp_e100_impl::rx_ddc_get, this, _1, _2), + boost::bind(&usrp_e100_impl::rx_ddc_set, this, _1, _2) ); //initial config and update @@ -44,7 +44,7 @@ void usrp_e_impl::rx_ddc_init(void){ /*********************************************************************** * RX DDC Get **********************************************************************/ -void usrp_e_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ @@ -79,7 +79,7 @@ void usrp_e_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * RX DDC Set **********************************************************************/ -void usrp_e_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ +void usrp_e100_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ @@ -113,10 +113,10 @@ void usrp_e_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ /*********************************************************************** * TX DUC Initialization **********************************************************************/ -void usrp_e_impl::tx_duc_init(void){ +void usrp_e100_impl::tx_duc_init(void){ _tx_duc_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::tx_duc_get, this, _1, _2), - boost::bind(&usrp_e_impl::tx_duc_set, this, _1, _2) + boost::bind(&usrp_e100_impl::tx_duc_get, this, _1, _2), + boost::bind(&usrp_e100_impl::tx_duc_set, this, _1, _2) ); //initial config and update @@ -127,7 +127,7 @@ void usrp_e_impl::tx_duc_init(void){ /*********************************************************************** * TX DUC Get **********************************************************************/ -void usrp_e_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ @@ -162,7 +162,7 @@ void usrp_e_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * TX DUC Set **********************************************************************/ -void usrp_e_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){ +void usrp_e100_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ diff --git a/host/lib/usrp/usrp_e100/fpga-downloader.cc b/host/lib/usrp/usrp_e100/fpga-downloader.cc index 4dc537919..4a3d3b9af 100644 --- a/host/lib/usrp/usrp_e100/fpga-downloader.cc +++ b/host/lib/usrp/usrp_e100/fpga-downloader.cc @@ -253,7 +253,7 @@ int main(int argc, char *argv[]) } */ -void usrp_e_load_fpga(const std::string &bin_file){ +void usrp_e100_load_fpga(const std::string &bin_file){ gpio gpio_prog_b(PROG_B, OUT); gpio gpio_init_b(INIT_B, IN); gpio gpio_done (DONE, IN); diff --git a/host/lib/usrp/usrp_e100/io_impl.cpp b/host/lib/usrp/usrp_e100/io_impl.cpp index e863944e8..7cb3e25e5 100644 --- a/host/lib/usrp/usrp_e100/io_impl.cpp +++ b/host/lib/usrp/usrp_e100/io_impl.cpp @@ -15,8 +15,8 @@ // along with this program. If not, see . // -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" +#include "usrp_e100_impl.hpp" +#include "usrp_e100_regs.hpp" #include #include #include @@ -30,7 +30,7 @@ using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; -zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface); +zero_copy_if::sptr usrp_e100_make_mmap_zero_copy(usrp_e100_iface::sptr iface); /*********************************************************************** * Constants @@ -46,14 +46,14 @@ static const bool recv_debug = false; * - thread loop * - vrt packet handler states **********************************************************************/ -struct usrp_e_impl::io_impl{ +struct usrp_e100_impl::io_impl{ //state management for the vrt packet handler code vrt_packet_handler::recv_state packet_handler_recv_state; vrt_packet_handler::send_state packet_handler_send_state; zero_copy_if::sptr data_xport; bool continuous_streaming; - io_impl(usrp_e_iface::sptr iface): - data_xport(usrp_e_make_mmap_zero_copy(iface)), + io_impl(usrp_e100_iface::sptr iface): + data_xport(usrp_e100_make_mmap_zero_copy(iface)), recv_pirate_booty(recv_booty_type::make(data_xport->get_num_recv_frames())), async_msg_fifo(bounded_buffer::make(100/*messages deep*/)) { @@ -73,7 +73,7 @@ struct usrp_e_impl::io_impl{ } //a pirate's life is the life for me! - void recv_pirate_loop(usrp_e_clock_ctrl::sptr); + void recv_pirate_loop(usrp_e100_clock_ctrl::sptr); typedef bounded_buffer recv_booty_type; recv_booty_type::sptr recv_pirate_booty; bounded_buffer::sptr async_msg_fifo; @@ -86,7 +86,7 @@ struct usrp_e_impl::io_impl{ * - while raiding, loot for recv buffers * - put booty into the alignment buffer **********************************************************************/ -void usrp_e_impl::io_impl::recv_pirate_loop(usrp_e_clock_ctrl::sptr clock_ctrl) +void usrp_e100_impl::io_impl::recv_pirate_loop(usrp_e100_clock_ctrl::sptr clock_ctrl) { set_thread_priority_safe(); recv_pirate_crew_raiding = true; @@ -140,7 +140,7 @@ void usrp_e_impl::io_impl::recv_pirate_loop(usrp_e_clock_ctrl::sptr clock_ctrl) /*********************************************************************** * Helper Functions **********************************************************************/ -void usrp_e_impl::io_init(void){ +void usrp_e100_impl::io_init(void){ //setup otw types _send_otw_type.width = 16; _send_otw_type.shift = 0; @@ -172,11 +172,11 @@ void usrp_e_impl::io_init(void){ //spawn a pirate, yarrr! _io_impl->recv_pirate_crew.create_thread(boost::bind( - &usrp_e_impl::io_impl::recv_pirate_loop, _io_impl.get(), _clock_ctrl + &usrp_e100_impl::io_impl::recv_pirate_loop, _io_impl.get(), _clock_ctrl )); } -void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ +void usrp_e100_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ _io_impl->continuous_streaming = (stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS); _iface->poke32(UE_REG_CTRL_RX_STREAM_CMD, dsp_type1::calc_stream_cmd_word( stream_cmd, get_max_recv_samps_per_packet() @@ -185,7 +185,7 @@ void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ _iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_tick_count(_clock_ctrl->get_fpga_clock_rate())); } -void usrp_e_impl::handle_overrun(size_t){ +void usrp_e100_impl::handle_overrun(size_t){ std::cerr << "O"; //the famous OOOOOOOOOOO _iface->poke32(UE_REG_CTRL_RX_CLEAR_OVERRUN, 0); if (_io_impl->continuous_streaming){ @@ -205,7 +205,7 @@ bool get_send_buffs( return buffs[0].get() != NULL; } -size_t usrp_e_impl::get_max_send_samps_per_packet(void) const{ +size_t usrp_e100_impl::get_max_send_samps_per_packet(void) const{ static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) - sizeof(vrt::if_packet_info_t().cid) //no class id ever used @@ -214,7 +214,7 @@ size_t usrp_e_impl::get_max_send_samps_per_packet(void) const{ return bpp/_send_otw_type.get_sample_size(); } -size_t usrp_e_impl::send( +size_t usrp_e100_impl::send( const std::vector &buffs, size_t num_samps, const tx_metadata_t &metadata, const io_type_t &io_type, send_mode_t send_mode, double timeout @@ -234,7 +234,7 @@ size_t usrp_e_impl::send( /*********************************************************************** * Data Recv **********************************************************************/ -size_t usrp_e_impl::get_max_recv_samps_per_packet(void) const{ +size_t usrp_e100_impl::get_max_recv_samps_per_packet(void) const{ static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer @@ -244,7 +244,7 @@ size_t usrp_e_impl::get_max_recv_samps_per_packet(void) const{ return bpp/_recv_otw_type.get_sample_size(); } -size_t usrp_e_impl::recv( +size_t usrp_e100_impl::recv( const std::vector &buffs, size_t num_samps, rx_metadata_t &metadata, const io_type_t &io_type, recv_mode_t recv_mode, double timeout @@ -256,15 +256,15 @@ size_t usrp_e_impl::recv( io_type, _recv_otw_type, //input and output types to convert _clock_ctrl->get_fpga_clock_rate(), //master clock tick rate uhd::transport::vrt::if_hdr_unpack_le, - boost::bind(&usrp_e_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout), - boost::bind(&usrp_e_impl::handle_overrun, this, _1) + boost::bind(&usrp_e100_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout), + boost::bind(&usrp_e100_impl::handle_overrun, this, _1) ); } /*********************************************************************** * Async Recv **********************************************************************/ -bool usrp_e_impl::recv_async_msg( +bool usrp_e100_impl::recv_async_msg( async_metadata_t &async_metadata, double timeout ){ boost::this_thread::disable_interruption di; //disable because the wait can throw diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp index f0118aa4b..2d5d028e6 100644 --- a/host/lib/usrp/usrp_e100/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp @@ -15,8 +15,8 @@ // along with this program. If not, see . // -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" +#include "usrp_e100_impl.hpp" +#include "usrp_e100_regs.hpp" #include #include #include @@ -30,10 +30,10 @@ using namespace uhd::usrp; /*********************************************************************** * Mboard Initialization **********************************************************************/ -void usrp_e_impl::mboard_init(void){ +void usrp_e100_impl::mboard_init(void){ _mboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::mboard_get, this, _1, _2), - boost::bind(&usrp_e_impl::mboard_set, this, _1, _2) + boost::bind(&usrp_e100_impl::mboard_get, this, _1, _2), + boost::bind(&usrp_e100_impl::mboard_set, this, _1, _2) ); //init the clock config @@ -46,7 +46,7 @@ void usrp_e_impl::mboard_init(void){ /*********************************************************************** * Mboard Get **********************************************************************/ -void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::mboard_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key @@ -114,7 +114,7 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * Mboard Set **********************************************************************/ -void usrp_e_impl::mboard_set(const wax::obj &key, const wax::obj &val){ +void usrp_e100_impl::mboard_set(const wax::obj &key, const wax::obj &val){ //handle the get request conditioned on the key switch(key.as()){ diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp new file mode 100644 index 000000000..ad623777e --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp @@ -0,0 +1,194 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e100_iface.hpp" +#include +#include //ioctl +#include //open, close +#include //ioctl structures and constants +#include +#include //mutex +#include + +using namespace uhd; + +class usrp_e100_iface_impl : public usrp_e100_iface{ +public: + + int get_file_descriptor(void){ + return _node_fd; + } + + /******************************************************************* + * Structors + ******************************************************************/ + usrp_e100_iface_impl(const std::string &node){ + //open the device node and check file descriptor + if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ + throw std::runtime_error(str( + boost::format("Failed to open %s") % node + )); + } + } + + ~usrp_e100_iface_impl(void){ + //close the device node file descriptor + ::close(_node_fd); + } + + /******************************************************************* + * IOCTL: provides the communication base for all other calls + ******************************************************************/ + void ioctl(int request, void *mem){ + boost::mutex::scoped_lock lock(_ctrl_mutex); + + if (::ioctl(_node_fd, request, mem) < 0){ + throw std::runtime_error(str( + boost::format("ioctl failed with request %d") % request + )); + } + } + + /******************************************************************* + * Peek and Poke + ******************************************************************/ + void poke32(boost::uint32_t addr, boost::uint32_t value){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL32, &data); + } + + void poke16(boost::uint32_t addr, boost::uint16_t value){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL16, &data); + } + + boost::uint32_t peek32(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL32, &data); + + return data.buf[0]; + } + + boost::uint16_t peek16(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL16, &data); + + return data.buf[0]; + } + + /******************************************************************* + * I2C + ******************************************************************/ + static const size_t max_i2c_data_bytes = 10; + + void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ + //allocate some memory for this transaction + UHD_ASSERT_THROW(bytes.size() <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c *data = reinterpret_cast(mem); + data->addr = addr; + data->len = bytes.size(); + std::copy(bytes.begin(), bytes.end(), data->data); + + //call the spi ioctl + this->ioctl(USRP_E_I2C_WRITE, data); + } + + byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ + //allocate some memory for this transaction + UHD_ASSERT_THROW(num_bytes <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c *data = reinterpret_cast(mem); + data->addr = addr; + data->len = num_bytes; + + //call the spi ioctl + this->ioctl(USRP_E_I2C_READ, data); + + //unload the data + byte_vector_t bytes(data->len); + UHD_ASSERT_THROW(bytes.size() == num_bytes); + std::copy(data->data, data->data+bytes.size(), bytes.begin()); + return bytes; + } + + /******************************************************************* + * SPI + ******************************************************************/ + boost::uint32_t transact_spi( + int which_slave, + const spi_config_t &config, + boost::uint32_t bits, + size_t num_bits, + bool readback + ){ + //load data struct + usrp_e_spi data; + data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; + data.slave = which_slave; + data.length = num_bits; + data.data = bits; + + //load the flags + data.flags = 0; + data.flags |= (config.miso_edge == spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (config.mosi_edge == spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; + + //call the spi ioctl + this->ioctl(USRP_E_SPI, &data); + + //unload the data + return data.data; + } + +private: + int _node_fd; + boost::mutex _ctrl_mutex; +}; + +/*********************************************************************** + * Public Make Function + **********************************************************************/ +usrp_e100_iface::sptr usrp_e100_iface::make(const std::string &node){ + return sptr(new usrp_e100_iface_impl(node)); +} diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp new file mode 100644 index 000000000..b52209a42 --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp @@ -0,0 +1,112 @@ +// +// Copyright 2010 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 . +// + +#ifndef INCLUDED_USRP_E100_IFACE_HPP +#define INCLUDED_USRP_E100_IFACE_HPP + +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////// +// I2C addresses +//////////////////////////////////////////////////////////////////////// +#define I2C_DEV_EEPROM 0x50 // 24LC02[45]: 7-bits 1010xxx +#define I2C_ADDR_MBOARD (I2C_DEV_EEPROM | 0x0) +#define I2C_ADDR_TX_DB (I2C_DEV_EEPROM | 0x4) +#define I2C_ADDR_RX_DB (I2C_DEV_EEPROM | 0x5) +//////////////////////////////////////////////////////////////////////// + +/*! + * The usrp-e interface class: + * Provides a set of functions to implementation layer. + * Including spi, peek, poke, control... + */ +class usrp_e100_iface : boost::noncopyable, public uhd::i2c_iface{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a new usrp-e interface with the control transport. + * \param node the device node name + * \return a new usrp-e interface object + */ + static sptr make(const std::string &node); + + /*! + * Get the underlying file descriptor. + * \return the file descriptor + */ + virtual int get_file_descriptor(void) = 0; + + /*! + * Perform an ioctl call on the device node file descriptor. + * This will throw when the internal ioctl call fails. + * \param request the control word + * \param mem pointer to some memory + */ + virtual void ioctl(int request, void *mem) = 0; + + /*! + * Write a register (32 bits) + * \param addr the address + * \param data the 32bit data + */ + virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; + + /*! + * Read a register (32 bits) + * \param addr the address + * \return the 32bit data + */ + virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; + + /*! + * Write a register (16 bits) + * \param addr the address + * \param data the 16bit data + */ + virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0; + + /*! + * Read a register (16 bits) + * \param addr the address + * \return the 16bit data + */ + virtual boost::uint16_t peek16(boost::uint32_t addr) = 0; + + /*! + * Perform an spi transaction. + * \param which_slave the slave device number + * \param config spi config args + * \param data the bits to write + * \param num_bits how many bits in data + * \param readback true to readback a value + * \return spi data if readback set + */ + virtual boost::uint32_t transact_spi( + int which_slave, + const uhd::spi_config_t &config, + boost::uint32_t data, + size_t num_bits, + bool readback + ) = 0; +}; + +#endif /* INCLUDED_USRP_E100_IFACE_HPP */ diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp new file mode 100644 index 000000000..73cb1f285 --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp @@ -0,0 +1,201 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e100_impl.hpp" +#include "usrp_e100_regs.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace uhd; +using namespace uhd::usrp; +namespace fs = boost::filesystem; + +/*********************************************************************** + * Helper Functions + **********************************************************************/ +static std::string abs_path(const std::string &file_path){ + return fs::system_complete(fs::path(file_path)).file_string(); +} + +/*********************************************************************** + * Discovery + **********************************************************************/ +static device_addrs_t usrp_e100_find(const device_addr_t &hint){ + device_addrs_t usrp_e100_addrs; + + //return an empty list of addresses when type is set to non-usrp-e + if (hint.has_key("type") and hint["type"] != "usrp-e") return usrp_e100_addrs; + + //device node not provided, assume its 0 + if (not hint.has_key("node")){ + device_addr_t new_addr = hint; + new_addr["node"] = "/dev/usrp_e1000"; + return usrp_e100_find(new_addr); + } + + //use the given device node name + if (fs::exists(hint["node"])){ + device_addr_t new_addr; + new_addr["type"] = "usrp-e"; + new_addr["node"] = abs_path(hint["node"]); + usrp_e100_addrs.push_back(new_addr); + } + + return usrp_e100_addrs; +} + +/*********************************************************************** + * Make + **********************************************************************/ +static device::sptr usrp_e100_make(const device_addr_t &device_addr){ + + //setup the main interface into fpga + std::string node = device_addr["node"]; + std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; + usrp_e100_iface::sptr iface = usrp_e100_iface::make(node); + + //------------------------------------------------------------------ + //-- Handle the FPGA loading... + //-- The image can be confimed as already loaded when: + //-- 1) The compatibility number matches. + //-- 2) The hash in the hash-file matches. + //------------------------------------------------------------------ + static const char *hash_file_path = "/tmp/usrp_e100100_hash"; + + //extract the fpga path for usrp-e + std::string usrp_e100_fpga_image = find_image_path( + device_addr.has_key("fpga")? device_addr["fpga"] : "usrp_e100100_fpga.bin" + ); + + //calculate a hash of the fpga file + size_t fpga_hash = 0; + { + std::ifstream file(usrp_e100_fpga_image.c_str()); + if (not file.good()) throw std::runtime_error( + "cannot open fpga file for read: " + usrp_e100_fpga_image + ); + do{ + boost::hash_combine(fpga_hash, file.get()); + } while (file.good()); + file.close(); + } + + //read the compatibility number + boost::uint16_t fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); + + //read the hash in the hash-file + size_t loaded_hash = 0; + try{std::ifstream(hash_file_path) >> loaded_hash;}catch(...){} + + //if not loaded: load the fpga image and write the hash-file + if (fpga_compat_num != USRP_E_COMPAT_NUM or loaded_hash != fpga_hash){ + iface.reset(); + usrp_e100_load_fpga(usrp_e100_fpga_image); + std::cout << boost::format("re-Opening USRP-E on %s") % node << std::endl; + iface = usrp_e100_iface::make(node); + try{std::ofstream(hash_file_path) << fpga_hash;}catch(...){} + } + + //check that the compatibility is correct + fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); + if (fpga_compat_num != USRP_E_COMPAT_NUM){ + throw std::runtime_error(str(boost::format( + "Expected fpga compatibility number 0x%x, but got 0x%x:\n" + "The fpga build is not compatible with the host code build." + ) % USRP_E_COMPAT_NUM % fpga_compat_num)); + } + + return device::sptr(new usrp_e100_impl(iface)); +} + +UHD_STATIC_BLOCK(register_usrp_e100_device){ + device::register_device(&usrp_e100_find, &usrp_e100_make); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp_e100_impl::usrp_e100_impl(usrp_e100_iface::sptr iface): _iface(iface){ + + //setup interfaces into hardware + _clock_ctrl = usrp_e100_clock_ctrl::make(_iface); + _codec_ctrl = usrp_e100_codec_ctrl::make(_iface); + + //initialize the mboard + mboard_init(); + + //initialize the dboards + dboard_init(); + + //initialize the dsps + rx_ddc_init(); + tx_duc_init(); + + //init the codec properties + codec_init(); + + //init the io send/recv + io_init(); + + //set default subdev specs + this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t()); + this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t()); +} + +usrp_e100_impl::~usrp_e100_impl(void){ + /* NOP */ +} + +/*********************************************************************** + * Device Get + **********************************************************************/ +void usrp_e100_impl::get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case DEVICE_PROP_NAME: + val = std::string("usrp-e device"); + return; + + case DEVICE_PROP_MBOARD: + UHD_ASSERT_THROW(key.name == ""); + val = _mboard_proxy->get_link(); + return; + + case DEVICE_PROP_MBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +/*********************************************************************** + * Device Set + **********************************************************************/ +void usrp_e100_impl::set(const wax::obj &, const wax::obj &){ + UHD_THROW_PROP_SET_ERROR(); +} diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp new file mode 100644 index 000000000..fe60ac0be --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp @@ -0,0 +1,164 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e100_iface.hpp" +#include "clock_ctrl.hpp" +#include "codec_ctrl.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef INCLUDED_USRP_E100_IMPL_HPP +#define INCLUDED_USRP_E100_IMPL_HPP + +static const boost::uint16_t USRP_E_COMPAT_NUM = 0x02; + +//! load an fpga image from a bin file into the usrp-e fpga +extern void usrp_e100_load_fpga(const std::string &bin_file); + +/*! + * Make a usrp-e dboard interface. + * \param iface the usrp-e interface object + * \param clock the clock control interface + * \param codec the codec control interface + * \return a sptr to a new dboard interface + */ +uhd::usrp::dboard_iface::sptr make_usrp_e100_dboard_iface( + usrp_e100_iface::sptr iface, + usrp_e100_clock_ctrl::sptr clock, + usrp_e100_codec_ctrl::sptr codec +); + +/*! + * Simple wax obj proxy class: + * Provides a wax obj interface for a set and a get function. + * This allows us to create nested properties structures + * while maintaining flattened code within the implementation. + */ +class wax_obj_proxy : public wax::obj{ +public: + typedef boost::function get_t; + typedef boost::function set_t; + typedef boost::shared_ptr sptr; + + static sptr make(const get_t &get, const set_t &set){ + return sptr(new wax_obj_proxy(get, set)); + } + +private: + get_t _get; set_t _set; + wax_obj_proxy(const get_t &get, const set_t &set): _get(get), _set(set){}; + void get(const wax::obj &key, wax::obj &val){return _get(key, val);} + void set(const wax::obj &key, const wax::obj &val){return _set(key, val);} +}; + +/*! + * USRP-E100 implementation guts: + * The implementation details are encapsulated here. + * Handles properties on the mboard, dboard, dsps... + */ +class usrp_e100_impl : public uhd::device{ +public: + //structors + usrp_e100_impl(usrp_e100_iface::sptr); + ~usrp_e100_impl(void); + + //the io interface + size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t, double); + size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, double); + bool recv_async_msg(uhd::async_metadata_t &, double); + size_t get_max_send_samps_per_packet(void) const; + size_t get_max_recv_samps_per_packet(void) const; + +private: + //interface to ioctls and file descriptor + usrp_e100_iface::sptr _iface; + + //handle io stuff + UHD_PIMPL_DECL(io_impl) _io_impl; + uhd::otw_type_t _send_otw_type, _recv_otw_type; + void io_init(void); + void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd); + void handle_overrun(size_t); + + //configuration shadows + uhd::clock_config_t _clock_config; + //TODO otw type recv/send + + //ad9522 clock control + usrp_e100_clock_ctrl::sptr _clock_ctrl; + + //ad9862 codec control + usrp_e100_codec_ctrl::sptr _codec_ctrl; + + //device functions and settings + void get(const wax::obj &, wax::obj &); + void set(const wax::obj &, const wax::obj &); + + //mboard functions and settings + void mboard_init(void); + void mboard_get(const wax::obj &, wax::obj &); + void mboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _mboard_proxy; + uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec; + + //xx dboard functions and settings + void dboard_init(void); + uhd::usrp::dboard_manager::sptr _dboard_manager; + uhd::usrp::dboard_iface::sptr _dboard_iface; + + //rx dboard functions and settings + uhd::usrp::dboard_eeprom_t _rx_db_eeprom; + void rx_dboard_get(const wax::obj &, wax::obj &); + void rx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _rx_dboard_proxy; + + //tx dboard functions and settings + uhd::usrp::dboard_eeprom_t _tx_db_eeprom; + void tx_dboard_get(const wax::obj &, wax::obj &); + void tx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _tx_dboard_proxy; + + //rx ddc functions and settings + void rx_ddc_init(void); + void rx_ddc_get(const wax::obj &, wax::obj &); + void rx_ddc_set(const wax::obj &, const wax::obj &); + double _ddc_freq; size_t _ddc_decim; + wax_obj_proxy::sptr _rx_ddc_proxy; + + //tx duc functions and settings + void tx_duc_init(void); + void tx_duc_get(const wax::obj &, wax::obj &); + void tx_duc_set(const wax::obj &, const wax::obj &); + double _duc_freq; size_t _duc_interp; + wax_obj_proxy::sptr _tx_duc_proxy; + + //codec functions and settings + void codec_init(void); + void rx_codec_get(const wax::obj &, wax::obj &); + void rx_codec_set(const wax::obj &, const wax::obj &); + void tx_codec_get(const wax::obj &, wax::obj &); + void tx_codec_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _rx_codec_proxy, _tx_codec_proxy; +}; + +#endif /* INCLUDED_USRP_E100_IMPL_HPP */ diff --git a/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp new file mode 100644 index 000000000..bf378a9b1 --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp @@ -0,0 +1,215 @@ +// +// Copyright 2010 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 . +// + +#include "usrp_e100_iface.hpp" +#include +#include +#include +#include //mmap +#include //getpagesize +#include //poll +#include +#include +#include + +using namespace uhd; +using namespace uhd::transport; + +static const bool fp_verbose = false; //fast-path verbose +static const bool sp_verbose = false; //slow-path verbose +static const size_t poll_breakout = 10; //how many poll timeouts constitute a full timeout + +/*********************************************************************** + * The zero copy interface implementation + **********************************************************************/ +class usrp_e100_mmap_zero_copy_impl : public zero_copy_if, public boost::enable_shared_from_this { +public: + usrp_e100_mmap_zero_copy_impl(usrp_e100_iface::sptr iface): + _fd(iface->get_file_descriptor()), _recv_index(0), _send_index(0) + { + //get system sizes + iface->ioctl(USRP_E_GET_RB_INFO, &_rb_size); + size_t page_size = getpagesize(); + _frame_size = page_size/2; + + //calculate the memory size + _map_size = + (_rb_size.num_pages_rx_flags + _rb_size.num_pages_tx_flags) * page_size + + (_rb_size.num_rx_frames + _rb_size.num_tx_frames) * _frame_size; + + //print sizes summary + if (sp_verbose){ + std::cout << "page_size: " << page_size << std::endl; + std::cout << "frame_size: " << _frame_size << std::endl; + std::cout << "num_pages_rx_flags: " << _rb_size.num_pages_rx_flags << std::endl; + std::cout << "num_rx_frames: " << _rb_size.num_rx_frames << std::endl; + std::cout << "num_pages_tx_flags: " << _rb_size.num_pages_tx_flags << std::endl; + std::cout << "num_tx_frames: " << _rb_size.num_tx_frames << std::endl; + std::cout << "map_size: " << _map_size << std::endl; + } + + //call mmap to get the memory + _mapped_mem = ::mmap( + NULL, _map_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0 + ); + UHD_ASSERT_THROW(_mapped_mem != MAP_FAILED); + + //calculate the memory offsets for info and buffers + size_t recv_info_off = 0; + size_t recv_buff_off = recv_info_off + (_rb_size.num_pages_rx_flags * page_size); + size_t send_info_off = recv_buff_off + (_rb_size.num_rx_frames * _frame_size); + size_t send_buff_off = send_info_off + (_rb_size.num_pages_tx_flags * page_size); + + //print offset summary + if (sp_verbose){ + std::cout << "recv_info_off: " << recv_info_off << std::endl; + std::cout << "recv_buff_off: " << recv_buff_off << std::endl; + std::cout << "send_info_off: " << send_info_off << std::endl; + std::cout << "send_buff_off: " << send_buff_off << std::endl; + } + + //set the internal pointers for info and buffers + typedef ring_buffer_info (*rbi_pta)[]; + char *rb_ptr = reinterpret_cast(_mapped_mem); + _recv_info = reinterpret_cast(rb_ptr + recv_info_off); + _recv_buff = rb_ptr + recv_buff_off; + _send_info = reinterpret_cast(rb_ptr + send_info_off); + _send_buff = rb_ptr + send_buff_off; + } + + ~usrp_e100_mmap_zero_copy_impl(void){ + if (sp_verbose) std::cout << "cleanup: munmap" << std::endl; + ::munmap(_mapped_mem, _map_size); + } + + managed_recv_buffer::sptr get_recv_buff(double timeout){ + if (fp_verbose) std::cout << "get_recv_buff: " << _recv_index << std::endl; + + //grab pointers to the info and buffer + ring_buffer_info *info = (*_recv_info) + _recv_index; + void *mem = _recv_buff + _frame_size*_recv_index; + + //poll/wait for a ready frame + if (not (info->flags & RB_USER)){ + for (size_t i = 0; i < poll_breakout; i++){ + pollfd pfd; + pfd.fd = _fd; + pfd.events = POLLIN; + ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3/poll_breakout)); + if (fp_verbose) std::cout << " POLLIN: " << poll_ret << std::endl; + if (poll_ret > 0) goto found_user_frame; //good poll, continue on + } + return managed_recv_buffer::sptr(); //timed-out for real + } found_user_frame: + + //the process has claimed the frame + info->flags = RB_USER_PROCESS; + + //increment the index for the next call + if (++_recv_index == size_t(_rb_size.num_rx_frames)) _recv_index = 0; + + //return the managed buffer for this frame + if (fp_verbose) std::cout << " make_recv_buff: " << info->len << std::endl; + return managed_recv_buffer::make_safe( + boost::asio::const_buffer(mem, info->len), + boost::bind(&usrp_e100_mmap_zero_copy_impl::release, shared_from_this(), info) + ); + } + + size_t get_num_recv_frames(void) const{ + return _rb_size.num_rx_frames; + } + + size_t get_recv_frame_size(void) const{ + return _frame_size; + } + + managed_send_buffer::sptr get_send_buff(double timeout){ + if (fp_verbose) std::cout << "get_send_buff: " << _send_index << std::endl; + + //grab pointers to the info and buffer + ring_buffer_info *info = (*_send_info) + _send_index; + void *mem = _send_buff + _frame_size*_send_index; + + //poll/wait for a ready frame + if (not (info->flags & RB_KERNEL)){ + pollfd pfd; + pfd.fd = _fd; + pfd.events = POLLOUT; + ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3)); + if (fp_verbose) std::cout << " POLLOUT: " << poll_ret << std::endl; + if (poll_ret <= 0) return managed_send_buffer::sptr(); + } + + //increment the index for the next call + if (++_send_index == size_t(_rb_size.num_tx_frames)) _send_index = 0; + + //return the managed buffer for this frame + if (fp_verbose) std::cout << " make_send_buff: " << _frame_size << std::endl; + return managed_send_buffer::make_safe( + boost::asio::mutable_buffer(mem, _frame_size), + boost::bind(&usrp_e100_mmap_zero_copy_impl::commit, shared_from_this(), info, _1) + ); + } + + size_t get_num_send_frames(void) const{ + return _rb_size.num_tx_frames; + } + + size_t get_send_frame_size(void) const{ + return _frame_size; + } + +private: + + void release(ring_buffer_info *info){ + if (fp_verbose) std::cout << "recv buff: release" << std::endl; + info->flags = RB_KERNEL; + } + + void commit(ring_buffer_info *info, size_t len){ + if (fp_verbose) std::cout << "send buff: commit " << len << std::endl; + info->len = len; + info->flags = RB_USER; + if (::write(_fd, NULL, 0) < 0){ + std::cerr << UHD_THROW_SITE_INFO("write error") << std::endl; + } + } + + int _fd; + + //the mapped memory itself + void *_mapped_mem; + + //mapped memory sizes + usrp_e_ring_buffer_size_t _rb_size; + size_t _frame_size, _map_size; + + //pointers to sections in the mapped memory + ring_buffer_info (*_recv_info)[], (*_send_info)[]; + char *_recv_buff, *_send_buff; + + //indexes into sub-sections of mapped memory + size_t _recv_index, _send_index; +}; + +/*********************************************************************** + * The zero copy interface make function + **********************************************************************/ +zero_copy_if::sptr usrp_e100_make_mmap_zero_copy(usrp_e100_iface::sptr iface){ + return zero_copy_if::sptr(new usrp_e100_mmap_zero_copy_impl(iface)); +} diff --git a/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp b/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp new file mode 100644 index 000000000..625fb2c35 --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp @@ -0,0 +1,198 @@ + + +//////////////////////////////////////////////////////////////// +// +// Memory map for embedded wishbone bus +// +//////////////////////////////////////////////////////////////// + +// All addresses are byte addresses. All accesses are word (16-bit) accesses. +// This means that address bit 0 is usually 0. +// There are 11 bits of address for the control. + +#ifndef INCLUDED_USRP_E100_REGS_HPP +#define INCLUDED_USRP_E100_REGS_HPP + +///////////////////////////////////////////////////// +// Slave pointers + +#define UE_REG_SLAVE(n) ((n)<<7) +#define UE_REG_SR_ADDR(n) ((UE_REG_SLAVE(5)) + (4*(n))) + +///////////////////////////////////////////////////// +// Slave 0 -- Misc Regs + +#define UE_REG_MISC_BASE UE_REG_SLAVE(0) + +#define UE_REG_MISC_LED UE_REG_MISC_BASE + 0 +#define UE_REG_MISC_SW UE_REG_MISC_BASE + 2 +#define UE_REG_MISC_CGEN_CTRL UE_REG_MISC_BASE + 4 +#define UE_REG_MISC_CGEN_ST UE_REG_MISC_BASE + 6 +#define UE_REG_MISC_TEST UE_REG_MISC_BASE + 8 +#define UE_REG_MISC_RX_LEN UE_REG_MISC_BASE + 10 +#define UE_REG_MISC_TX_LEN UE_REG_MISC_BASE + 12 +#define UE_REG_MISC_XFER_RATE UE_REG_MISC_BASE + 14 +#define UE_REG_MISC_COMPAT UE_REG_MISC_BASE + 16 + +///////////////////////////////////////////////////// +// Slave 1 -- UART +// CLKDIV is 16 bits, others are only 8 + +#define UE_REG_UART_BASE UE_REG_SLAVE(1) + +#define UE_REG_UART_CLKDIV UE_REG_UART_BASE + 0 +#define UE_REG_UART_TXLEVEL UE_REG_UART_BASE + 2 +#define UE_REG_UART_RXLEVEL UE_REG_UART_BASE + 4 +#define UE_REG_UART_TXCHAR UE_REG_UART_BASE + 6 +#define UE_REG_UART_RXCHAR UE_REG_UART_BASE + 8 + +///////////////////////////////////////////////////// +// Slave 2 -- SPI Core +// This should be accessed through the IOCTL +// Users should not touch directly + +#define UE_REG_SPI_BASE UE_REG_SLAVE(2) + +//spi slave constants +#define UE_SPI_SS_AD9522 (1 << 3) +#define UE_SPI_SS_AD9862 (1 << 2) +#define UE_SPI_SS_TX_DB (1 << 1) +#define UE_SPI_SS_RX_DB (1 << 0) + +//////////////////////////////////////////////// +// Slave 3 -- I2C Core +// This should be accessed through the IOCTL +// Users should not touch directly + +#define UE_REG_I2C_BASE UE_REG_SLAVE(3) + + +//////////////////////////////////////////////// +// Slave 4 -- GPIO + +#define UE_REG_GPIO_BASE UE_REG_SLAVE(4) + +#define UE_REG_GPIO_RX_IO UE_REG_GPIO_BASE + 0 +#define UE_REG_GPIO_TX_IO UE_REG_GPIO_BASE + 2 +#define UE_REG_GPIO_RX_DDR UE_REG_GPIO_BASE + 4 +#define UE_REG_GPIO_TX_DDR UE_REG_GPIO_BASE + 6 +#define UE_REG_GPIO_RX_SEL UE_REG_GPIO_BASE + 8 +#define UE_REG_GPIO_TX_SEL UE_REG_GPIO_BASE + 10 +#define UE_REG_GPIO_RX_DBG UE_REG_GPIO_BASE + 12 +#define UE_REG_GPIO_TX_DBG UE_REG_GPIO_BASE + 14 + +//possible bit values for sel when dbg is 0: +#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg +#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic + +//possible bit values for sel when dbg is 1: +#define GPIO_SEL_DEBUG_0 0 // if pin is an output, debug lines from FPGA fabric +#define GPIO_SEL_DEBUG_1 1 // if pin is an output, debug lines from FPGA fabric + + +//////////////////////////////////////////////////// +// Slave 5 -- Settings Bus +// +// Output-only, no readback, 32 registers total +// Each register must be written 32 bits at a time +// First the address xxx_xx00 and then xxx_xx10 + +#define UE_REG_SETTINGS_BASE UE_REG_SLAVE(5) + +/////////////////////////////////////////////////// +// Slave 6 -- ATR Controller +// 16 regs + +#define UE_REG_ATR_BASE UE_REG_SLAVE(6) + +#define UE_REG_ATR_IDLE_RXSIDE UE_REG_ATR_BASE + 0 +#define UE_REG_ATR_IDLE_TXSIDE UE_REG_ATR_BASE + 2 +#define UE_REG_ATR_INTX_RXSIDE UE_REG_ATR_BASE + 4 +#define UE_REG_ATR_INTX_TXSIDE UE_REG_ATR_BASE + 6 +#define UE_REG_ATR_INRX_RXSIDE UE_REG_ATR_BASE + 8 +#define UE_REG_ATR_INRX_TXSIDE UE_REG_ATR_BASE + 10 +#define UE_REG_ATR_FULL_RXSIDE UE_REG_ATR_BASE + 12 +#define UE_REG_ATR_FULL_TXSIDE UE_REG_ATR_BASE + 14 + +///////////////////////////////////////////////// +// DSP RX Regs +//////////////////////////////////////////////// +#define UE_REG_DSP_RX_FREQ UE_REG_SR_ADDR(0) +#define UE_REG_DSP_RX_SCALE_IQ UE_REG_SR_ADDR(1) // {scale_i,scale_q} +#define UE_REG_DSP_RX_DECIM_RATE UE_REG_SR_ADDR(2) // hb and decim rate +#define UE_REG_DSP_RX_DCOFFSET_I UE_REG_SR_ADDR(3) // Bit 31 high sets fixed offset mode, using lower 14 bits, // otherwise it is automatic +#define UE_REG_DSP_RX_DCOFFSET_Q UE_REG_SR_ADDR(4) // Bit 31 high sets fixed offset mode, using lower 14 bits +#define UE_REG_DSP_RX_MUX UE_REG_SR_ADDR(5) + +/////////////////////////////////////////////////// +// VITA RX CTRL regs +/////////////////////////////////////////////////// +// The following 3 are logically a single command register. +// They are clocked into the underlying fifo when time_ticks is written. +#define UE_REG_CTRL_RX_STREAM_CMD UE_REG_SR_ADDR(8) // {now, chain, num_samples(30) +#define UE_REG_CTRL_RX_TIME_SECS UE_REG_SR_ADDR(9) +#define UE_REG_CTRL_RX_TIME_TICKS UE_REG_SR_ADDR(10) +#define UE_REG_CTRL_RX_CLEAR_OVERRUN UE_REG_SR_ADDR(11) // write anything to clear overrun +#define UE_REG_CTRL_RX_VRT_HEADER UE_REG_SR_ADDR(12) // word 0 of packet. FPGA fills in packet counter +#define UE_REG_CTRL_RX_VRT_STREAM_ID UE_REG_SR_ADDR(13) // word 1 of packet. +#define UE_REG_CTRL_RX_VRT_TRAILER UE_REG_SR_ADDR(14) +#define UE_REG_CTRL_RX_NSAMPS_PER_PKT UE_REG_SR_ADDR(15) +#define UE_REG_CTRL_RX_NCHANNELS UE_REG_SR_ADDR(16) // 1 in basic case, up to 4 for vector sources + +///////////////////////////////////////////////// +// DSP TX Regs +//////////////////////////////////////////////// +#define UE_REG_DSP_TX_FREQ UE_REG_SR_ADDR(17) +#define UE_REG_DSP_TX_SCALE_IQ UE_REG_SR_ADDR(18) // {scale_i,scale_q} +#define UE_REG_DSP_TX_INTERP_RATE UE_REG_SR_ADDR(19) +#define UE_REG_DSP_TX_UNUSED UE_REG_SR_ADDR(20) +#define UE_REG_DSP_TX_MUX UE_REG_SR_ADDR(21) + +///////////////////////////////////////////////// +// VITA TX CTRL regs +//////////////////////////////////////////////// +#define UE_REG_CTRL_TX_NCHANNELS UE_REG_SR_ADDR(24) +#define UE_REG_CTRL_TX_CLEAR_UNDERRUN UE_REG_SR_ADDR(25) +#define UE_REG_CTRL_TX_REPORT_SID UE_REG_SR_ADDR(26) +#define UE_REG_CTRL_TX_POLICY UE_REG_SR_ADDR(27) + +#define UE_FLAG_CTRL_TX_POLICY_WAIT (0x1 << 0) +#define UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET (0x1 << 1) +#define UE_FLAG_CTRL_TX_POLICY_NEXT_BURST (0x1 << 2) + +///////////////////////////////////////////////// +// VITA49 64 bit time (write only) +//////////////////////////////////////////////// + /*! + * \brief Time 64 flags + * + *
+   *
+   *    3                   2                   1
+   *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   * +-----------------------------------------------------------+-+-+
+   * |                                                           |S|P|
+   * +-----------------------------------------------------------+-+-+
+   *
+   * P - PPS edge selection (0=negedge, 1=posedge, default=0)
+   * S - Source (0=sma, 1=mimo, 0=default)
+   *
+   * 
+ */ +#define UE_REG_TIME64_SECS UE_REG_SR_ADDR(28) // value to set absolute secs to on next PPS +#define UE_REG_TIME64_TICKS UE_REG_SR_ADDR(29) // value to set absolute ticks to on next PPS +#define UE_REG_TIME64_FLAGS UE_REG_SR_ADDR(30) // flags - see chart above +#define UE_REG_TIME64_IMM UE_REG_SR_ADDR(31) // set immediate (0=latch on next pps, 1=latch immediate, default=0) +#define UE_REG_TIME64_TPS UE_REG_SR_ADDR(31) // clock ticks per second (counter rollover) + +//pps flags (see above) +#define UE_FLAG_TIME64_PPS_NEGEDGE (0 << 0) +#define UE_FLAG_TIME64_PPS_POSEDGE (1 << 0) +#define UE_FLAG_TIME64_PPS_SMA (0 << 1) +#define UE_FLAG_TIME64_PPS_MIMO (1 << 1) + +#define UE_FLAG_TIME64_LATCH_NOW 1 +#define UE_FLAG_TIME64_LATCH_NEXT_PPS 0 + +#endif + diff --git a/host/lib/usrp/usrp_e100/usrp_e_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e_iface.cpp deleted file mode 100644 index f00e92946..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_iface.cpp +++ /dev/null @@ -1,194 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_iface.hpp" -#include -#include //ioctl -#include //open, close -#include //ioctl structures and constants -#include -#include //mutex -#include - -using namespace uhd; - -class usrp_e_iface_impl : public usrp_e_iface{ -public: - - int get_file_descriptor(void){ - return _node_fd; - } - - /******************************************************************* - * Structors - ******************************************************************/ - usrp_e_iface_impl(const std::string &node){ - //open the device node and check file descriptor - if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ - throw std::runtime_error(str( - boost::format("Failed to open %s") % node - )); - } - } - - ~usrp_e_iface_impl(void){ - //close the device node file descriptor - ::close(_node_fd); - } - - /******************************************************************* - * IOCTL: provides the communication base for all other calls - ******************************************************************/ - void ioctl(int request, void *mem){ - boost::mutex::scoped_lock lock(_ctrl_mutex); - - if (::ioctl(_node_fd, request, mem) < 0){ - throw std::runtime_error(str( - boost::format("ioctl failed with request %d") % request - )); - } - } - - /******************************************************************* - * Peek and Poke - ******************************************************************/ - void poke32(boost::uint32_t addr, boost::uint32_t value){ - //load the data struct - usrp_e_ctl32 data; - data.offset = addr; - data.count = 1; - data.buf[0] = value; - - //call the ioctl - this->ioctl(USRP_E_WRITE_CTL32, &data); - } - - void poke16(boost::uint32_t addr, boost::uint16_t value){ - //load the data struct - usrp_e_ctl16 data; - data.offset = addr; - data.count = 1; - data.buf[0] = value; - - //call the ioctl - this->ioctl(USRP_E_WRITE_CTL16, &data); - } - - boost::uint32_t peek32(boost::uint32_t addr){ - //load the data struct - usrp_e_ctl32 data; - data.offset = addr; - data.count = 1; - - //call the ioctl - this->ioctl(USRP_E_READ_CTL32, &data); - - return data.buf[0]; - } - - boost::uint16_t peek16(boost::uint32_t addr){ - //load the data struct - usrp_e_ctl16 data; - data.offset = addr; - data.count = 1; - - //call the ioctl - this->ioctl(USRP_E_READ_CTL16, &data); - - return data.buf[0]; - } - - /******************************************************************* - * I2C - ******************************************************************/ - static const size_t max_i2c_data_bytes = 10; - - void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ - //allocate some memory for this transaction - UHD_ASSERT_THROW(bytes.size() <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c *data = reinterpret_cast(mem); - data->addr = addr; - data->len = bytes.size(); - std::copy(bytes.begin(), bytes.end(), data->data); - - //call the spi ioctl - this->ioctl(USRP_E_I2C_WRITE, data); - } - - byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ - //allocate some memory for this transaction - UHD_ASSERT_THROW(num_bytes <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c *data = reinterpret_cast(mem); - data->addr = addr; - data->len = num_bytes; - - //call the spi ioctl - this->ioctl(USRP_E_I2C_READ, data); - - //unload the data - byte_vector_t bytes(data->len); - UHD_ASSERT_THROW(bytes.size() == num_bytes); - std::copy(data->data, data->data+bytes.size(), bytes.begin()); - return bytes; - } - - /******************************************************************* - * SPI - ******************************************************************/ - boost::uint32_t transact_spi( - int which_slave, - const spi_config_t &config, - boost::uint32_t bits, - size_t num_bits, - bool readback - ){ - //load data struct - usrp_e_spi data; - data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; - data.slave = which_slave; - data.length = num_bits; - data.data = bits; - - //load the flags - data.flags = 0; - data.flags |= (config.miso_edge == spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; - data.flags |= (config.mosi_edge == spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; - - //call the spi ioctl - this->ioctl(USRP_E_SPI, &data); - - //unload the data - return data.data; - } - -private: - int _node_fd; - boost::mutex _ctrl_mutex; -}; - -/*********************************************************************** - * Public Make Function - **********************************************************************/ -usrp_e_iface::sptr usrp_e_iface::make(const std::string &node){ - return sptr(new usrp_e_iface_impl(node)); -} diff --git a/host/lib/usrp/usrp_e100/usrp_e_iface.hpp b/host/lib/usrp/usrp_e100/usrp_e_iface.hpp deleted file mode 100644 index 59aac43d9..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_iface.hpp +++ /dev/null @@ -1,112 +0,0 @@ -// -// Copyright 2010 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 . -// - -#ifndef INCLUDED_USRP_E_IFACE_HPP -#define INCLUDED_USRP_E_IFACE_HPP - -#include -#include -#include -#include -#include - -//////////////////////////////////////////////////////////////////////// -// I2C addresses -//////////////////////////////////////////////////////////////////////// -#define I2C_DEV_EEPROM 0x50 // 24LC02[45]: 7-bits 1010xxx -#define I2C_ADDR_MBOARD (I2C_DEV_EEPROM | 0x0) -#define I2C_ADDR_TX_DB (I2C_DEV_EEPROM | 0x4) -#define I2C_ADDR_RX_DB (I2C_DEV_EEPROM | 0x5) -//////////////////////////////////////////////////////////////////////// - -/*! - * The usrp-e interface class: - * Provides a set of functions to implementation layer. - * Including spi, peek, poke, control... - */ -class usrp_e_iface : boost::noncopyable, public uhd::i2c_iface{ -public: - typedef boost::shared_ptr sptr; - - /*! - * Make a new usrp-e interface with the control transport. - * \param node the device node name - * \return a new usrp-e interface object - */ - static sptr make(const std::string &node); - - /*! - * Get the underlying file descriptor. - * \return the file descriptor - */ - virtual int get_file_descriptor(void) = 0; - - /*! - * Perform an ioctl call on the device node file descriptor. - * This will throw when the internal ioctl call fails. - * \param request the control word - * \param mem pointer to some memory - */ - virtual void ioctl(int request, void *mem) = 0; - - /*! - * Write a register (32 bits) - * \param addr the address - * \param data the 32bit data - */ - virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; - - /*! - * Read a register (32 bits) - * \param addr the address - * \return the 32bit data - */ - virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; - - /*! - * Write a register (16 bits) - * \param addr the address - * \param data the 16bit data - */ - virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0; - - /*! - * Read a register (16 bits) - * \param addr the address - * \return the 16bit data - */ - virtual boost::uint16_t peek16(boost::uint32_t addr) = 0; - - /*! - * Perform an spi transaction. - * \param which_slave the slave device number - * \param config spi config args - * \param data the bits to write - * \param num_bits how many bits in data - * \param readback true to readback a value - * \return spi data if readback set - */ - virtual boost::uint32_t transact_spi( - int which_slave, - const uhd::spi_config_t &config, - boost::uint32_t data, - size_t num_bits, - bool readback - ) = 0; -}; - -#endif /* INCLUDED_USRP_E_IFACE_HPP */ diff --git a/host/lib/usrp/usrp_e100/usrp_e_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e_impl.cpp deleted file mode 100644 index 70cc399fb..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_impl.cpp +++ /dev/null @@ -1,201 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace uhd; -using namespace uhd::usrp; -namespace fs = boost::filesystem; - -/*********************************************************************** - * Helper Functions - **********************************************************************/ -static std::string abs_path(const std::string &file_path){ - return fs::system_complete(fs::path(file_path)).file_string(); -} - -/*********************************************************************** - * Discovery - **********************************************************************/ -static device_addrs_t usrp_e_find(const device_addr_t &hint){ - device_addrs_t usrp_e_addrs; - - //return an empty list of addresses when type is set to non-usrp-e - if (hint.has_key("type") and hint["type"] != "usrp-e") return usrp_e_addrs; - - //device node not provided, assume its 0 - if (not hint.has_key("node")){ - device_addr_t new_addr = hint; - new_addr["node"] = "/dev/usrp_e0"; - return usrp_e_find(new_addr); - } - - //use the given device node name - if (fs::exists(hint["node"])){ - device_addr_t new_addr; - new_addr["type"] = "usrp-e"; - new_addr["node"] = abs_path(hint["node"]); - usrp_e_addrs.push_back(new_addr); - } - - return usrp_e_addrs; -} - -/*********************************************************************** - * Make - **********************************************************************/ -static device::sptr usrp_e_make(const device_addr_t &device_addr){ - - //setup the main interface into fpga - std::string node = device_addr["node"]; - std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; - usrp_e_iface::sptr iface = usrp_e_iface::make(node); - - //------------------------------------------------------------------ - //-- Handle the FPGA loading... - //-- The image can be confimed as already loaded when: - //-- 1) The compatibility number matches. - //-- 2) The hash in the hash-file matches. - //------------------------------------------------------------------ - static const char *hash_file_path = "/tmp/usrp_e100_hash"; - - //extract the fpga path for usrp-e - std::string usrp_e_fpga_image = find_image_path( - device_addr.has_key("fpga")? device_addr["fpga"] : "usrp_e100_fpga.bin" - ); - - //calculate a hash of the fpga file - size_t fpga_hash = 0; - { - std::ifstream file(usrp_e_fpga_image.c_str()); - if (not file.good()) throw std::runtime_error( - "cannot open fpga file for read: " + usrp_e_fpga_image - ); - do{ - boost::hash_combine(fpga_hash, file.get()); - } while (file.good()); - file.close(); - } - - //read the compatibility number - boost::uint16_t fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); - - //read the hash in the hash-file - size_t loaded_hash = 0; - try{std::ifstream(hash_file_path) >> loaded_hash;}catch(...){} - - //if not loaded: load the fpga image and write the hash-file - if (fpga_compat_num != USRP_E_COMPAT_NUM or loaded_hash != fpga_hash){ - iface.reset(); - usrp_e_load_fpga(usrp_e_fpga_image); - std::cout << boost::format("re-Opening USRP-E on %s") % node << std::endl; - iface = usrp_e_iface::make(node); - try{std::ofstream(hash_file_path) << fpga_hash;}catch(...){} - } - - //check that the compatibility is correct - fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); - if (fpga_compat_num != USRP_E_COMPAT_NUM){ - throw std::runtime_error(str(boost::format( - "Expected fpga compatibility number 0x%x, but got 0x%x:\n" - "The fpga build is not compatible with the host code build." - ) % USRP_E_COMPAT_NUM % fpga_compat_num)); - } - - return device::sptr(new usrp_e_impl(iface)); -} - -UHD_STATIC_BLOCK(register_usrp_e_device){ - device::register_device(&usrp_e_find, &usrp_e_make); -} - -/*********************************************************************** - * Structors - **********************************************************************/ -usrp_e_impl::usrp_e_impl(usrp_e_iface::sptr iface): _iface(iface){ - - //setup interfaces into hardware - _clock_ctrl = usrp_e_clock_ctrl::make(_iface); - _codec_ctrl = usrp_e_codec_ctrl::make(_iface); - - //initialize the mboard - mboard_init(); - - //initialize the dboards - dboard_init(); - - //initialize the dsps - rx_ddc_init(); - tx_duc_init(); - - //init the codec properties - codec_init(); - - //init the io send/recv - io_init(); - - //set default subdev specs - this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t()); - this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t()); -} - -usrp_e_impl::~usrp_e_impl(void){ - /* NOP */ -} - -/*********************************************************************** - * Device Get - **********************************************************************/ -void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - //handle the get request conditioned on the key - switch(key.as()){ - case DEVICE_PROP_NAME: - val = std::string("usrp-e device"); - return; - - case DEVICE_PROP_MBOARD: - UHD_ASSERT_THROW(key.name == ""); - val = _mboard_proxy->get_link(); - return; - - case DEVICE_PROP_MBOARD_NAMES: - val = prop_names_t(1, ""); //vector of size 1 with empty string - return; - - default: UHD_THROW_PROP_GET_ERROR(); - } -} - -/*********************************************************************** - * Device Set - **********************************************************************/ -void usrp_e_impl::set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); -} diff --git a/host/lib/usrp/usrp_e100/usrp_e_impl.hpp b/host/lib/usrp/usrp_e100/usrp_e_impl.hpp deleted file mode 100644 index b5f21810d..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_impl.hpp +++ /dev/null @@ -1,164 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_iface.hpp" -#include "clock_ctrl.hpp" -#include "codec_ctrl.hpp" -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef INCLUDED_USRP_E_IMPL_HPP -#define INCLUDED_USRP_E_IMPL_HPP - -static const boost::uint16_t USRP_E_COMPAT_NUM = 0x02; - -//! load an fpga image from a bin file into the usrp-e fpga -extern void usrp_e_load_fpga(const std::string &bin_file); - -/*! - * Make a usrp-e dboard interface. - * \param iface the usrp-e interface object - * \param clock the clock control interface - * \param codec the codec control interface - * \return a sptr to a new dboard interface - */ -uhd::usrp::dboard_iface::sptr make_usrp_e_dboard_iface( - usrp_e_iface::sptr iface, - usrp_e_clock_ctrl::sptr clock, - usrp_e_codec_ctrl::sptr codec -); - -/*! - * Simple wax obj proxy class: - * Provides a wax obj interface for a set and a get function. - * This allows us to create nested properties structures - * while maintaining flattened code within the implementation. - */ -class wax_obj_proxy : public wax::obj{ -public: - typedef boost::function get_t; - typedef boost::function set_t; - typedef boost::shared_ptr sptr; - - static sptr make(const get_t &get, const set_t &set){ - return sptr(new wax_obj_proxy(get, set)); - } - -private: - get_t _get; set_t _set; - wax_obj_proxy(const get_t &get, const set_t &set): _get(get), _set(set){}; - void get(const wax::obj &key, wax::obj &val){return _get(key, val);} - void set(const wax::obj &key, const wax::obj &val){return _set(key, val);} -}; - -/*! - * USRP1E implementation guts: - * The implementation details are encapsulated here. - * Handles properties on the mboard, dboard, dsps... - */ -class usrp_e_impl : public uhd::device{ -public: - //structors - usrp_e_impl(usrp_e_iface::sptr); - ~usrp_e_impl(void); - - //the io interface - size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t, double); - size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, double); - bool recv_async_msg(uhd::async_metadata_t &, double); - size_t get_max_send_samps_per_packet(void) const; - size_t get_max_recv_samps_per_packet(void) const; - -private: - //interface to ioctls and file descriptor - usrp_e_iface::sptr _iface; - - //handle io stuff - UHD_PIMPL_DECL(io_impl) _io_impl; - uhd::otw_type_t _send_otw_type, _recv_otw_type; - void io_init(void); - void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd); - void handle_overrun(size_t); - - //configuration shadows - uhd::clock_config_t _clock_config; - //TODO otw type recv/send - - //ad9522 clock control - usrp_e_clock_ctrl::sptr _clock_ctrl; - - //ad9862 codec control - usrp_e_codec_ctrl::sptr _codec_ctrl; - - //device functions and settings - void get(const wax::obj &, wax::obj &); - void set(const wax::obj &, const wax::obj &); - - //mboard functions and settings - void mboard_init(void); - void mboard_get(const wax::obj &, wax::obj &); - void mboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _mboard_proxy; - uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec; - - //xx dboard functions and settings - void dboard_init(void); - uhd::usrp::dboard_manager::sptr _dboard_manager; - uhd::usrp::dboard_iface::sptr _dboard_iface; - - //rx dboard functions and settings - uhd::usrp::dboard_eeprom_t _rx_db_eeprom; - void rx_dboard_get(const wax::obj &, wax::obj &); - void rx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _rx_dboard_proxy; - - //tx dboard functions and settings - uhd::usrp::dboard_eeprom_t _tx_db_eeprom; - void tx_dboard_get(const wax::obj &, wax::obj &); - void tx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _tx_dboard_proxy; - - //rx ddc functions and settings - void rx_ddc_init(void); - void rx_ddc_get(const wax::obj &, wax::obj &); - void rx_ddc_set(const wax::obj &, const wax::obj &); - double _ddc_freq; size_t _ddc_decim; - wax_obj_proxy::sptr _rx_ddc_proxy; - - //tx duc functions and settings - void tx_duc_init(void); - void tx_duc_get(const wax::obj &, wax::obj &); - void tx_duc_set(const wax::obj &, const wax::obj &); - double _duc_freq; size_t _duc_interp; - wax_obj_proxy::sptr _tx_duc_proxy; - - //codec functions and settings - void codec_init(void); - void rx_codec_get(const wax::obj &, wax::obj &); - void rx_codec_set(const wax::obj &, const wax::obj &); - void tx_codec_get(const wax::obj &, wax::obj &); - void tx_codec_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _rx_codec_proxy, _tx_codec_proxy; -}; - -#endif /* INCLUDED_USRP_E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp deleted file mode 100644 index 274bb043e..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp +++ /dev/null @@ -1,215 +0,0 @@ -// -// Copyright 2010 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 . -// - -#include "usrp_e_iface.hpp" -#include -#include -#include -#include //mmap -#include //getpagesize -#include //poll -#include -#include -#include - -using namespace uhd; -using namespace uhd::transport; - -static const bool fp_verbose = false; //fast-path verbose -static const bool sp_verbose = false; //slow-path verbose -static const size_t poll_breakout = 10; //how many poll timeouts constitute a full timeout - -/*********************************************************************** - * The zero copy interface implementation - **********************************************************************/ -class usrp_e_mmap_zero_copy_impl : public zero_copy_if, public boost::enable_shared_from_this { -public: - usrp_e_mmap_zero_copy_impl(usrp_e_iface::sptr iface): - _fd(iface->get_file_descriptor()), _recv_index(0), _send_index(0) - { - //get system sizes - iface->ioctl(USRP_E_GET_RB_INFO, &_rb_size); - size_t page_size = getpagesize(); - _frame_size = page_size/2; - - //calculate the memory size - _map_size = - (_rb_size.num_pages_rx_flags + _rb_size.num_pages_tx_flags) * page_size + - (_rb_size.num_rx_frames + _rb_size.num_tx_frames) * _frame_size; - - //print sizes summary - if (sp_verbose){ - std::cout << "page_size: " << page_size << std::endl; - std::cout << "frame_size: " << _frame_size << std::endl; - std::cout << "num_pages_rx_flags: " << _rb_size.num_pages_rx_flags << std::endl; - std::cout << "num_rx_frames: " << _rb_size.num_rx_frames << std::endl; - std::cout << "num_pages_tx_flags: " << _rb_size.num_pages_tx_flags << std::endl; - std::cout << "num_tx_frames: " << _rb_size.num_tx_frames << std::endl; - std::cout << "map_size: " << _map_size << std::endl; - } - - //call mmap to get the memory - _mapped_mem = ::mmap( - NULL, _map_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0 - ); - UHD_ASSERT_THROW(_mapped_mem != MAP_FAILED); - - //calculate the memory offsets for info and buffers - size_t recv_info_off = 0; - size_t recv_buff_off = recv_info_off + (_rb_size.num_pages_rx_flags * page_size); - size_t send_info_off = recv_buff_off + (_rb_size.num_rx_frames * _frame_size); - size_t send_buff_off = send_info_off + (_rb_size.num_pages_tx_flags * page_size); - - //print offset summary - if (sp_verbose){ - std::cout << "recv_info_off: " << recv_info_off << std::endl; - std::cout << "recv_buff_off: " << recv_buff_off << std::endl; - std::cout << "send_info_off: " << send_info_off << std::endl; - std::cout << "send_buff_off: " << send_buff_off << std::endl; - } - - //set the internal pointers for info and buffers - typedef ring_buffer_info (*rbi_pta)[]; - char *rb_ptr = reinterpret_cast(_mapped_mem); - _recv_info = reinterpret_cast(rb_ptr + recv_info_off); - _recv_buff = rb_ptr + recv_buff_off; - _send_info = reinterpret_cast(rb_ptr + send_info_off); - _send_buff = rb_ptr + send_buff_off; - } - - ~usrp_e_mmap_zero_copy_impl(void){ - if (sp_verbose) std::cout << "cleanup: munmap" << std::endl; - ::munmap(_mapped_mem, _map_size); - } - - managed_recv_buffer::sptr get_recv_buff(double timeout){ - if (fp_verbose) std::cout << "get_recv_buff: " << _recv_index << std::endl; - - //grab pointers to the info and buffer - ring_buffer_info *info = (*_recv_info) + _recv_index; - void *mem = _recv_buff + _frame_size*_recv_index; - - //poll/wait for a ready frame - if (not (info->flags & RB_USER)){ - for (size_t i = 0; i < poll_breakout; i++){ - pollfd pfd; - pfd.fd = _fd; - pfd.events = POLLIN; - ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3/poll_breakout)); - if (fp_verbose) std::cout << " POLLIN: " << poll_ret << std::endl; - if (poll_ret > 0) goto found_user_frame; //good poll, continue on - } - return managed_recv_buffer::sptr(); //timed-out for real - } found_user_frame: - - //the process has claimed the frame - info->flags = RB_USER_PROCESS; - - //increment the index for the next call - if (++_recv_index == size_t(_rb_size.num_rx_frames)) _recv_index = 0; - - //return the managed buffer for this frame - if (fp_verbose) std::cout << " make_recv_buff: " << info->len << std::endl; - return managed_recv_buffer::make_safe( - boost::asio::const_buffer(mem, info->len), - boost::bind(&usrp_e_mmap_zero_copy_impl::release, shared_from_this(), info) - ); - } - - size_t get_num_recv_frames(void) const{ - return _rb_size.num_rx_frames; - } - - size_t get_recv_frame_size(void) const{ - return _frame_size; - } - - managed_send_buffer::sptr get_send_buff(double timeout){ - if (fp_verbose) std::cout << "get_send_buff: " << _send_index << std::endl; - - //grab pointers to the info and buffer - ring_buffer_info *info = (*_send_info) + _send_index; - void *mem = _send_buff + _frame_size*_send_index; - - //poll/wait for a ready frame - if (not (info->flags & RB_KERNEL)){ - pollfd pfd; - pfd.fd = _fd; - pfd.events = POLLOUT; - ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3)); - if (fp_verbose) std::cout << " POLLOUT: " << poll_ret << std::endl; - if (poll_ret <= 0) return managed_send_buffer::sptr(); - } - - //increment the index for the next call - if (++_send_index == size_t(_rb_size.num_tx_frames)) _send_index = 0; - - //return the managed buffer for this frame - if (fp_verbose) std::cout << " make_send_buff: " << _frame_size << std::endl; - return managed_send_buffer::make_safe( - boost::asio::mutable_buffer(mem, _frame_size), - boost::bind(&usrp_e_mmap_zero_copy_impl::commit, shared_from_this(), info, _1) - ); - } - - size_t get_num_send_frames(void) const{ - return _rb_size.num_tx_frames; - } - - size_t get_send_frame_size(void) const{ - return _frame_size; - } - -private: - - void release(ring_buffer_info *info){ - if (fp_verbose) std::cout << "recv buff: release" << std::endl; - info->flags = RB_KERNEL; - } - - void commit(ring_buffer_info *info, size_t len){ - if (fp_verbose) std::cout << "send buff: commit " << len << std::endl; - info->len = len; - info->flags = RB_USER; - if (::write(_fd, NULL, 0) < 0){ - std::cerr << UHD_THROW_SITE_INFO("write error") << std::endl; - } - } - - int _fd; - - //the mapped memory itself - void *_mapped_mem; - - //mapped memory sizes - usrp_e_ring_buffer_size_t _rb_size; - size_t _frame_size, _map_size; - - //pointers to sections in the mapped memory - ring_buffer_info (*_recv_info)[], (*_send_info)[]; - char *_recv_buff, *_send_buff; - - //indexes into sub-sections of mapped memory - size_t _recv_index, _send_index; -}; - -/*********************************************************************** - * The zero copy interface make function - **********************************************************************/ -zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface){ - return zero_copy_if::sptr(new usrp_e_mmap_zero_copy_impl(iface)); -} diff --git a/host/lib/usrp/usrp_e100/usrp_e_regs.hpp b/host/lib/usrp/usrp_e100/usrp_e_regs.hpp deleted file mode 100644 index 8bfb08b6f..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_regs.hpp +++ /dev/null @@ -1,198 +0,0 @@ - - -//////////////////////////////////////////////////////////////// -// -// Memory map for embedded wishbone bus -// -//////////////////////////////////////////////////////////////// - -// All addresses are byte addresses. All accesses are word (16-bit) accesses. -// This means that address bit 0 is usually 0. -// There are 11 bits of address for the control. - -#ifndef __USRP_E_REGS_H -#define __USRP_E_REGS_H - -///////////////////////////////////////////////////// -// Slave pointers - -#define UE_REG_SLAVE(n) ((n)<<7) -#define UE_REG_SR_ADDR(n) ((UE_REG_SLAVE(5)) + (4*(n))) - -///////////////////////////////////////////////////// -// Slave 0 -- Misc Regs - -#define UE_REG_MISC_BASE UE_REG_SLAVE(0) - -#define UE_REG_MISC_LED UE_REG_MISC_BASE + 0 -#define UE_REG_MISC_SW UE_REG_MISC_BASE + 2 -#define UE_REG_MISC_CGEN_CTRL UE_REG_MISC_BASE + 4 -#define UE_REG_MISC_CGEN_ST UE_REG_MISC_BASE + 6 -#define UE_REG_MISC_TEST UE_REG_MISC_BASE + 8 -#define UE_REG_MISC_RX_LEN UE_REG_MISC_BASE + 10 -#define UE_REG_MISC_TX_LEN UE_REG_MISC_BASE + 12 -#define UE_REG_MISC_XFER_RATE UE_REG_MISC_BASE + 14 -#define UE_REG_MISC_COMPAT UE_REG_MISC_BASE + 16 - -///////////////////////////////////////////////////// -// Slave 1 -- UART -// CLKDIV is 16 bits, others are only 8 - -#define UE_REG_UART_BASE UE_REG_SLAVE(1) - -#define UE_REG_UART_CLKDIV UE_REG_UART_BASE + 0 -#define UE_REG_UART_TXLEVEL UE_REG_UART_BASE + 2 -#define UE_REG_UART_RXLEVEL UE_REG_UART_BASE + 4 -#define UE_REG_UART_TXCHAR UE_REG_UART_BASE + 6 -#define UE_REG_UART_RXCHAR UE_REG_UART_BASE + 8 - -///////////////////////////////////////////////////// -// Slave 2 -- SPI Core -// This should be accessed through the IOCTL -// Users should not touch directly - -#define UE_REG_SPI_BASE UE_REG_SLAVE(2) - -//spi slave constants -#define UE_SPI_SS_AD9522 (1 << 3) -#define UE_SPI_SS_AD9862 (1 << 2) -#define UE_SPI_SS_TX_DB (1 << 1) -#define UE_SPI_SS_RX_DB (1 << 0) - -//////////////////////////////////////////////// -// Slave 3 -- I2C Core -// This should be accessed through the IOCTL -// Users should not touch directly - -#define UE_REG_I2C_BASE UE_REG_SLAVE(3) - - -//////////////////////////////////////////////// -// Slave 4 -- GPIO - -#define UE_REG_GPIO_BASE UE_REG_SLAVE(4) - -#define UE_REG_GPIO_RX_IO UE_REG_GPIO_BASE + 0 -#define UE_REG_GPIO_TX_IO UE_REG_GPIO_BASE + 2 -#define UE_REG_GPIO_RX_DDR UE_REG_GPIO_BASE + 4 -#define UE_REG_GPIO_TX_DDR UE_REG_GPIO_BASE + 6 -#define UE_REG_GPIO_RX_SEL UE_REG_GPIO_BASE + 8 -#define UE_REG_GPIO_TX_SEL UE_REG_GPIO_BASE + 10 -#define UE_REG_GPIO_RX_DBG UE_REG_GPIO_BASE + 12 -#define UE_REG_GPIO_TX_DBG UE_REG_GPIO_BASE + 14 - -//possible bit values for sel when dbg is 0: -#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg -#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic - -//possible bit values for sel when dbg is 1: -#define GPIO_SEL_DEBUG_0 0 // if pin is an output, debug lines from FPGA fabric -#define GPIO_SEL_DEBUG_1 1 // if pin is an output, debug lines from FPGA fabric - - -//////////////////////////////////////////////////// -// Slave 5 -- Settings Bus -// -// Output-only, no readback, 32 registers total -// Each register must be written 32 bits at a time -// First the address xxx_xx00 and then xxx_xx10 - -#define UE_REG_SETTINGS_BASE UE_REG_SLAVE(5) - -/////////////////////////////////////////////////// -// Slave 6 -- ATR Controller -// 16 regs - -#define UE_REG_ATR_BASE UE_REG_SLAVE(6) - -#define UE_REG_ATR_IDLE_RXSIDE UE_REG_ATR_BASE + 0 -#define UE_REG_ATR_IDLE_TXSIDE UE_REG_ATR_BASE + 2 -#define UE_REG_ATR_INTX_RXSIDE UE_REG_ATR_BASE + 4 -#define UE_REG_ATR_INTX_TXSIDE UE_REG_ATR_BASE + 6 -#define UE_REG_ATR_INRX_RXSIDE UE_REG_ATR_BASE + 8 -#define UE_REG_ATR_INRX_TXSIDE UE_REG_ATR_BASE + 10 -#define UE_REG_ATR_FULL_RXSIDE UE_REG_ATR_BASE + 12 -#define UE_REG_ATR_FULL_TXSIDE UE_REG_ATR_BASE + 14 - -///////////////////////////////////////////////// -// DSP RX Regs -//////////////////////////////////////////////// -#define UE_REG_DSP_RX_FREQ UE_REG_SR_ADDR(0) -#define UE_REG_DSP_RX_SCALE_IQ UE_REG_SR_ADDR(1) // {scale_i,scale_q} -#define UE_REG_DSP_RX_DECIM_RATE UE_REG_SR_ADDR(2) // hb and decim rate -#define UE_REG_DSP_RX_DCOFFSET_I UE_REG_SR_ADDR(3) // Bit 31 high sets fixed offset mode, using lower 14 bits, // otherwise it is automatic -#define UE_REG_DSP_RX_DCOFFSET_Q UE_REG_SR_ADDR(4) // Bit 31 high sets fixed offset mode, using lower 14 bits -#define UE_REG_DSP_RX_MUX UE_REG_SR_ADDR(5) - -/////////////////////////////////////////////////// -// VITA RX CTRL regs -/////////////////////////////////////////////////// -// The following 3 are logically a single command register. -// They are clocked into the underlying fifo when time_ticks is written. -#define UE_REG_CTRL_RX_STREAM_CMD UE_REG_SR_ADDR(8) // {now, chain, num_samples(30) -#define UE_REG_CTRL_RX_TIME_SECS UE_REG_SR_ADDR(9) -#define UE_REG_CTRL_RX_TIME_TICKS UE_REG_SR_ADDR(10) -#define UE_REG_CTRL_RX_CLEAR_OVERRUN UE_REG_SR_ADDR(11) // write anything to clear overrun -#define UE_REG_CTRL_RX_VRT_HEADER UE_REG_SR_ADDR(12) // word 0 of packet. FPGA fills in packet counter -#define UE_REG_CTRL_RX_VRT_STREAM_ID UE_REG_SR_ADDR(13) // word 1 of packet. -#define UE_REG_CTRL_RX_VRT_TRAILER UE_REG_SR_ADDR(14) -#define UE_REG_CTRL_RX_NSAMPS_PER_PKT UE_REG_SR_ADDR(15) -#define UE_REG_CTRL_RX_NCHANNELS UE_REG_SR_ADDR(16) // 1 in basic case, up to 4 for vector sources - -///////////////////////////////////////////////// -// DSP TX Regs -//////////////////////////////////////////////// -#define UE_REG_DSP_TX_FREQ UE_REG_SR_ADDR(17) -#define UE_REG_DSP_TX_SCALE_IQ UE_REG_SR_ADDR(18) // {scale_i,scale_q} -#define UE_REG_DSP_TX_INTERP_RATE UE_REG_SR_ADDR(19) -#define UE_REG_DSP_TX_UNUSED UE_REG_SR_ADDR(20) -#define UE_REG_DSP_TX_MUX UE_REG_SR_ADDR(21) - -///////////////////////////////////////////////// -// VITA TX CTRL regs -//////////////////////////////////////////////// -#define UE_REG_CTRL_TX_NCHANNELS UE_REG_SR_ADDR(24) -#define UE_REG_CTRL_TX_CLEAR_UNDERRUN UE_REG_SR_ADDR(25) -#define UE_REG_CTRL_TX_REPORT_SID UE_REG_SR_ADDR(26) -#define UE_REG_CTRL_TX_POLICY UE_REG_SR_ADDR(27) - -#define UE_FLAG_CTRL_TX_POLICY_WAIT (0x1 << 0) -#define UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET (0x1 << 1) -#define UE_FLAG_CTRL_TX_POLICY_NEXT_BURST (0x1 << 2) - -///////////////////////////////////////////////// -// VITA49 64 bit time (write only) -//////////////////////////////////////////////// - /*! - * \brief Time 64 flags - * - *
-   *
-   *    3                   2                   1
-   *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
-   * +-----------------------------------------------------------+-+-+
-   * |                                                           |S|P|
-   * +-----------------------------------------------------------+-+-+
-   *
-   * P - PPS edge selection (0=negedge, 1=posedge, default=0)
-   * S - Source (0=sma, 1=mimo, 0=default)
-   *
-   * 
- */ -#define UE_REG_TIME64_SECS UE_REG_SR_ADDR(28) // value to set absolute secs to on next PPS -#define UE_REG_TIME64_TICKS UE_REG_SR_ADDR(29) // value to set absolute ticks to on next PPS -#define UE_REG_TIME64_FLAGS UE_REG_SR_ADDR(30) // flags - see chart above -#define UE_REG_TIME64_IMM UE_REG_SR_ADDR(31) // set immediate (0=latch on next pps, 1=latch immediate, default=0) -#define UE_REG_TIME64_TPS UE_REG_SR_ADDR(31) // clock ticks per second (counter rollover) - -//pps flags (see above) -#define UE_FLAG_TIME64_PPS_NEGEDGE (0 << 0) -#define UE_FLAG_TIME64_PPS_POSEDGE (1 << 0) -#define UE_FLAG_TIME64_PPS_SMA (0 << 1) -#define UE_FLAG_TIME64_PPS_MIMO (1 << 1) - -#define UE_FLAG_TIME64_LATCH_NOW 1 -#define UE_FLAG_TIME64_LATCH_NEXT_PPS 0 - -#endif - -- cgit v1.2.3 From b43a1a9d5e01566457d9c9ee478d13e899a46e77 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 9 Nov 2010 19:23:17 -0800 Subject: usrp-e100: moved kernel header to lib dir, remove the header check, default enable to false --- host/include/linux/usrp_e.h | 91 -------------------------- host/lib/usrp/usrp_e100/CMakeLists.txt | 10 +-- host/lib/usrp/usrp_e100/include/linux/usrp_e.h | 91 ++++++++++++++++++++++++++ host/lib/usrp/usrp_e100/usrp_e100_impl.cpp | 2 +- 4 files changed, 95 insertions(+), 99 deletions(-) delete mode 100644 host/include/linux/usrp_e.h create mode 100644 host/lib/usrp/usrp_e100/include/linux/usrp_e.h (limited to 'host') diff --git a/host/include/linux/usrp_e.h b/host/include/linux/usrp_e.h deleted file mode 100644 index 4c6a5dd89..000000000 --- a/host/include/linux/usrp_e.h +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (C) 2010 Ettus Research, LLC - * - * Written by Philip Balister - * - * 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 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __USRP_E_H -#define __USRP_E_H - -#include -#include - -struct usrp_e_ctl16 { - __u32 offset; - __u32 count; - __u16 buf[20]; -}; - -struct usrp_e_ctl32 { - __u32 offset; - __u32 count; - __u32 buf[10]; -}; - -/* SPI interface */ - -#define UE_SPI_TXONLY 0 -#define UE_SPI_TXRX 1 - -/* Defines for spi ctrl register */ -#define UE_SPI_CTRL_TXNEG (1<<10) -#define UE_SPI_CTRL_RXNEG (1<<9) - -#define UE_SPI_PUSH_RISE 0 -#define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG -#define UE_SPI_LATCH_RISE 0 -#define UE_SPI_LATCH_FALL UE_SPI_CTRL_RXNEG - -struct usrp_e_spi { - __u8 readback; - __u32 slave; - __u32 data; - __u32 length; - __u32 flags; -}; - -struct usrp_e_i2c { - __u8 addr; - __u32 len; - __u8 data[]; -}; - -#define USRP_E_IOC_MAGIC 'u' -#define USRP_E_WRITE_CTL16 _IOW(USRP_E_IOC_MAGIC, 0x20, struct usrp_e_ctl16) -#define USRP_E_READ_CTL16 _IOWR(USRP_E_IOC_MAGIC, 0x21, struct usrp_e_ctl16) -#define USRP_E_WRITE_CTL32 _IOW(USRP_E_IOC_MAGIC, 0x22, struct usrp_e_ctl32) -#define USRP_E_READ_CTL32 _IOWR(USRP_E_IOC_MAGIC, 0x23, struct usrp_e_ctl32) -#define USRP_E_SPI _IOWR(USRP_E_IOC_MAGIC, 0x24, struct usrp_e_spi) -#define USRP_E_I2C_READ _IOWR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) -#define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) -#define USRP_E_GET_RB_INFO _IOR(USRP_E_IOC_MAGIC, 0x27, struct usrp_e_ring_buffer_size_t) -#define USRP_E_GET_COMPAT_NUMBER _IO(USRP_E_IOC_MAGIC, 0x28) - -#define USRP_E_COMPAT_NUMBER 1 - -/* Flag defines */ -#define RB_USER (1<<0) -#define RB_KERNEL (1<<1) -#define RB_OVERRUN (1<<2) -#define RB_DMA_ACTIVE (1<<3) -#define RB_USER_PROCESS (1<<4) - -struct ring_buffer_info { - int flags; - int len; -}; - -struct usrp_e_ring_buffer_size_t { - int num_pages_rx_flags; - int num_rx_frames; - int num_pages_tx_flags; - int num_tx_frames; -}; - -#endif diff --git a/host/lib/usrp/usrp_e100/CMakeLists.txt b/host/lib/usrp/usrp_e100/CMakeLists.txt index 97a3d5d9a..66c87e0d8 100644 --- a/host/lib/usrp/usrp_e100/CMakeLists.txt +++ b/host/lib/usrp/usrp_e100/CMakeLists.txt @@ -22,24 +22,20 @@ ######################################################################## MESSAGE(STATUS "Configuring USRP-E100 support...") -INCLUDE(CheckIncludeFileCXX) -CHECK_INCLUDE_FILE_CXX(linux/usrp_e.h HAVE_LINUX_USRP_E_H) - -SET(ENABLE_USRP_E TRUE) - IF(DEFINED ENABLE_USRP_E100) IF(ENABLE_USRP_E100) MESSAGE(STATUS "USRP-E100 support enabled by configure flag") ELSE(ENABLE_USRP_E100) MESSAGE(STATUS "USRP-E100 support disabled by configure flag") ENDIF(ENABLE_USRP_E100) -ELSE(DEFINED ENABLE_USRP_E100) #not defined: automatic enabling of component - SET(ENABLE_USRP_E100 ${HAVE_LINUX_USRP_E_H}) +ELSE(DEFINED ENABLE_USRP_E100) #not defined: automatic disabling of component + SET(ENABLE_USRP_E100 FALSE) ENDIF(DEFINED ENABLE_USRP_E100) SET(ENABLE_USRP_E100 ${ENABLE_USRP_E100} CACHE BOOL "enable USRP-E100 support") IF(ENABLE_USRP_E100) MESSAGE(STATUS " Building USRP-E100 support.") + INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/include) LIBUHD_APPEND_SOURCES( ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/clock_ctrl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/clock_ctrl.hpp diff --git a/host/lib/usrp/usrp_e100/include/linux/usrp_e.h b/host/lib/usrp/usrp_e100/include/linux/usrp_e.h new file mode 100644 index 000000000..4c6a5dd89 --- /dev/null +++ b/host/lib/usrp/usrp_e100/include/linux/usrp_e.h @@ -0,0 +1,91 @@ + +/* + * Copyright (C) 2010 Ettus Research, LLC + * + * Written by Philip Balister + * + * 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 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __USRP_E_H +#define __USRP_E_H + +#include +#include + +struct usrp_e_ctl16 { + __u32 offset; + __u32 count; + __u16 buf[20]; +}; + +struct usrp_e_ctl32 { + __u32 offset; + __u32 count; + __u32 buf[10]; +}; + +/* SPI interface */ + +#define UE_SPI_TXONLY 0 +#define UE_SPI_TXRX 1 + +/* Defines for spi ctrl register */ +#define UE_SPI_CTRL_TXNEG (1<<10) +#define UE_SPI_CTRL_RXNEG (1<<9) + +#define UE_SPI_PUSH_RISE 0 +#define UE_SPI_PUSH_FALL UE_SPI_CTRL_TXNEG +#define UE_SPI_LATCH_RISE 0 +#define UE_SPI_LATCH_FALL UE_SPI_CTRL_RXNEG + +struct usrp_e_spi { + __u8 readback; + __u32 slave; + __u32 data; + __u32 length; + __u32 flags; +}; + +struct usrp_e_i2c { + __u8 addr; + __u32 len; + __u8 data[]; +}; + +#define USRP_E_IOC_MAGIC 'u' +#define USRP_E_WRITE_CTL16 _IOW(USRP_E_IOC_MAGIC, 0x20, struct usrp_e_ctl16) +#define USRP_E_READ_CTL16 _IOWR(USRP_E_IOC_MAGIC, 0x21, struct usrp_e_ctl16) +#define USRP_E_WRITE_CTL32 _IOW(USRP_E_IOC_MAGIC, 0x22, struct usrp_e_ctl32) +#define USRP_E_READ_CTL32 _IOWR(USRP_E_IOC_MAGIC, 0x23, struct usrp_e_ctl32) +#define USRP_E_SPI _IOWR(USRP_E_IOC_MAGIC, 0x24, struct usrp_e_spi) +#define USRP_E_I2C_READ _IOWR(USRP_E_IOC_MAGIC, 0x25, struct usrp_e_i2c) +#define USRP_E_I2C_WRITE _IOW(USRP_E_IOC_MAGIC, 0x26, struct usrp_e_i2c) +#define USRP_E_GET_RB_INFO _IOR(USRP_E_IOC_MAGIC, 0x27, struct usrp_e_ring_buffer_size_t) +#define USRP_E_GET_COMPAT_NUMBER _IO(USRP_E_IOC_MAGIC, 0x28) + +#define USRP_E_COMPAT_NUMBER 1 + +/* Flag defines */ +#define RB_USER (1<<0) +#define RB_KERNEL (1<<1) +#define RB_OVERRUN (1<<2) +#define RB_DMA_ACTIVE (1<<3) +#define RB_USER_PROCESS (1<<4) + +struct ring_buffer_info { + int flags; + int len; +}; + +struct usrp_e_ring_buffer_size_t { + int num_pages_rx_flags; + int num_rx_frames; + int num_pages_tx_flags; + int num_tx_frames; +}; + +#endif diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp index 73cb1f285..1ff135eac 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp @@ -51,7 +51,7 @@ static device_addrs_t usrp_e100_find(const device_addr_t &hint){ //device node not provided, assume its 0 if (not hint.has_key("node")){ device_addr_t new_addr = hint; - new_addr["node"] = "/dev/usrp_e1000"; + new_addr["node"] = "/dev/usrp_e0"; return usrp_e100_find(new_addr); } -- cgit v1.2.3 From 3aba990a4f35c0bb58f037897f3100be77f517c1 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 9 Nov 2010 20:10:25 -0800 Subject: usrp-e100: add header path for the utils directory as well --- host/utils/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'host') diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index a9148de6d..39f5257af 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -18,6 +18,9 @@ ######################################################################## # Utilities that get installed into the runtime path ######################################################################## +#TODO needed by USRP-E100 utils, whats the best way to handle this +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/include) + ADD_EXECUTABLE(uhd_find_devices uhd_find_devices.cpp) TARGET_LINK_LIBRARIES(uhd_find_devices uhd) -- cgit v1.2.3 From 3e695d1c0026383fd0509da8e4ebbf5ce5dd1fa3 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 10 Nov 2010 10:09:40 -0800 Subject: fixed string constants find and replace typo --- host/lib/usrp/usrp_e100/usrp_e100_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp index 1ff135eac..8e40458d5 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp @@ -82,11 +82,11 @@ static device::sptr usrp_e100_make(const device_addr_t &device_addr){ //-- 1) The compatibility number matches. //-- 2) The hash in the hash-file matches. //------------------------------------------------------------------ - static const char *hash_file_path = "/tmp/usrp_e100100_hash"; + static const char *hash_file_path = "/tmp/usrp_e100_hash"; //extract the fpga path for usrp-e std::string usrp_e100_fpga_image = find_image_path( - device_addr.has_key("fpga")? device_addr["fpga"] : "usrp_e100100_fpga.bin" + device_addr.has_key("fpga")? device_addr["fpga"] : "usrp_e100_fpga.bin" ); //calculate a hash of the fpga file -- cgit v1.2.3 From 57a2fa2e0654226c8a13c7eddad2fcdb43f72703 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 10 Nov 2010 10:30:41 -0800 Subject: usrp-e100: added empty eeprom for eeprom get property --- host/lib/usrp/usrp_e100/mboard_impl.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'host') diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp index 2d5d028e6..e45d7c5a0 100644 --- a/host/lib/usrp/usrp_e100/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -107,6 +108,10 @@ void usrp_e100_impl::mboard_get(const wax::obj &key_, wax::obj &val){ val = _tx_subdev_spec; return; + case MBOARD_PROP_EEPROM_MAP: + val = mboard_eeprom_t(); + return; + default: UHD_THROW_PROP_GET_ERROR(); } } -- cgit v1.2.3 From a724f4b7262c6da6d24dccdbd64e08da61cb87fc Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 10 Nov 2010 16:48:02 -0800 Subject: usrp-e100: implemented wrapper for i2c device node + ioctls, implemented e100 eeprom map --- host/include/uhd/usrp/mboard_eeprom.hpp | 3 +- host/lib/usrp/mboard_eeprom.cpp | 77 +++++++++++++++++++++++++++ host/lib/usrp/usrp_e100/mboard_impl.cpp | 10 +++- host/lib/usrp/usrp_e100/usrp_e100_iface.cpp | 82 +++++++++++++++++++++++++++-- host/lib/usrp/usrp_e100/usrp_e100_iface.hpp | 7 +++ 5 files changed, 172 insertions(+), 7 deletions(-) (limited to 'host') diff --git a/host/include/uhd/usrp/mboard_eeprom.hpp b/host/include/uhd/usrp/mboard_eeprom.hpp index 530b177be..52363b95c 100644 --- a/host/include/uhd/usrp/mboard_eeprom.hpp +++ b/host/include/uhd/usrp/mboard_eeprom.hpp @@ -37,7 +37,8 @@ namespace uhd{ namespace usrp{ //! Possible EEPROM maps types enum map_type{ MAP_N100, - MAP_B000 + MAP_B000, + MAP_E100 }; //! Make a new empty mboard eeprom diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp index 661030aa7..444057ad9 100644 --- a/host/lib/usrp/mboard_eeprom.cpp +++ b/host/lib/usrp/mboard_eeprom.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using namespace uhd; using namespace uhd::usrp; @@ -171,6 +172,80 @@ static void store_b000(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN) ); } +/*********************************************************************** + * Implementation of E100 load/store + **********************************************************************/ +static const boost::uint8_t E100_EEPROM_ADDR = 0x51; + +struct e100_eeprom_map{ + unsigned int device_vendor; + unsigned char revision; + unsigned char content; + unsigned char fab_revision[8]; + unsigned char env_var[16]; + unsigned char env_setting[64]; + unsigned char serial[10]; + unsigned char name[NAME_MAX_LEN]; +}; + +template static const byte_vector_t to_bytes(const T &item){ + return byte_vector_t( + reinterpret_cast(&item), + reinterpret_cast(&item)+sizeof(item) + ); +} + +static void load_e100(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ + const size_t num_bytes = offsetof(e100_eeprom_map, fab_revision); + byte_vector_t map_bytes = iface.read_eeprom(E100_EEPROM_ADDR, 0, num_bytes); + e100_eeprom_map map; std::memcpy(&map, &map_bytes[0], map_bytes.size()); + + mb_eeprom["device_vendor"] = boost::lexical_cast(map.device_vendor); + mb_eeprom["revision"] = boost::lexical_cast(map.revision); + mb_eeprom["content"] = boost::lexical_cast(map.content); + + #define load_e100_string_xx(key) mb_eeprom[#key] = bytes_to_string(iface.read_eeprom( \ + E100_EEPROM_ADDR, offsetof(e100_eeprom_map, key), sizeof(e100_eeprom_map::key) \ + )); + + load_e100_string_xx(fab_revision); + load_e100_string_xx(env_var); + load_e100_string_xx(env_setting); + load_e100_string_xx(serial); + load_e100_string_xx(fab_revision); + load_e100_string_xx(name); +} + +static void store_e100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ + + if (mb_eeprom.has_key("device_vendor")) iface.write_eeprom( + E100_EEPROM_ADDR, offsetof(e100_eeprom_map, device_vendor), + to_bytes(boost::lexical_cast(mb_eeprom["device_vendor"])) + ); + + if (mb_eeprom.has_key("revision")) iface.write_eeprom( + E100_EEPROM_ADDR, offsetof(e100_eeprom_map, revision), + to_bytes(boost::lexical_cast(mb_eeprom["revision"])) + ); + + if (mb_eeprom.has_key("content")) iface.write_eeprom( + E100_EEPROM_ADDR, offsetof(e100_eeprom_map, content), + to_bytes(boost::lexical_cast(mb_eeprom["content"])) + ); + + #define store_e100_string_xx(key) if (mb_eeprom.has_key(#key)) iface.write_eeprom( \ + E100_EEPROM_ADDR, offsetof(e100_eeprom_map, key), \ + string_to_bytes(mb_eeprom[#key], sizeof(e100_eeprom_map::key)) \ + ); + + store_e100_string_xx(fab_revision); + store_e100_string_xx(env_var); + store_e100_string_xx(env_setting); + store_e100_string_xx(serial); + store_e100_string_xx(fab_revision); + store_e100_string_xx(name); + +} /*********************************************************************** * Implementation of mboard eeprom @@ -183,6 +258,7 @@ mboard_eeprom_t::mboard_eeprom_t(i2c_iface &iface, map_type map){ switch(map){ case MAP_N100: load_n100(*this, iface); break; case MAP_B000: load_b000(*this, iface); break; + case MAP_E100: load_e100(*this, iface); break; } } @@ -190,5 +266,6 @@ void mboard_eeprom_t::commit(i2c_iface &iface, map_type map){ switch(map){ case MAP_N100: store_n100(*this, iface); break; case MAP_B000: store_b000(*this, iface); break; + case MAP_E100: store_e100(*this, iface); break; } } diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp index e45d7c5a0..9c6317b94 100644 --- a/host/lib/usrp/usrp_e100/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -109,7 +108,7 @@ void usrp_e100_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_EEPROM_MAP: - val = mboard_eeprom_t(); + val = _iface->mb_eeprom; return; default: UHD_THROW_PROP_GET_ERROR(); @@ -159,6 +158,13 @@ void usrp_e100_impl::mboard_set(const wax::obj &key, const wax::obj &val){ )); return; + case MBOARD_PROP_EEPROM_MAP: + // Step1: commit the map, writing only those values set. + // Step2: readback the entire eeprom map into the iface. + val.as().commit(_iface->get_i2c_dev_iface(), mboard_eeprom_t::MAP_E100); + _iface->mb_eeprom = mboard_eeprom_t(_iface->get_i2c_dev_iface(), mboard_eeprom_t::MAP_E100); + return; + default: UHD_THROW_PROP_SET_ERROR(); } } diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp index ad623777e..40c7afabb 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp @@ -22,10 +22,74 @@ #include //ioctl structures and constants #include #include //mutex +#include +#include #include using namespace uhd; +using namespace uhd::usrp; +/*********************************************************************** + * I2C device node implementation wrapper + **********************************************************************/ +class i2c_dev_iface : public i2c_iface{ +public: + i2c_dev_iface(const std::string &node){ + if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ + throw std::runtime_error("Failed to open " + node); + } + } + + ~i2c_dev_iface(void){ + ::close(_node_fd); + } + + void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ + byte_vector_t rw_bytes(bytes); + + //setup the message + i2c_msg msg; + msg.addr = addr; + msg.flags = 0; + msg.len = bytes.size(); + msg.buf = &rw_bytes.front(); + + //setup the data + i2c_rdwr_ioctl_data data; + data.msgs = &msg; + data.nmsgs = 1; + + //call the ioctl + UHD_ASSERT_THROW(::ioctl(_node_fd, I2C_RDWR, &data) >= 0); + } + + byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ + byte_vector_t bytes(num_bytes); + + //setup the message + i2c_msg msg; + msg.addr = addr; + msg.flags = I2C_M_RD; + msg.len = bytes.size(); + msg.buf = &bytes.front(); + + //setup the data + i2c_rdwr_ioctl_data data; + data.msgs = &msg; + data.nmsgs = 1; + + //call the ioctl + UHD_ASSERT_THROW(::ioctl(_node_fd, I2C_RDWR, &data) >= 0); + + return bytes; + } + +private: int _node_fd; +}; + +/*********************************************************************** + * USRP-E100 interface implementation + **********************************************************************/ class usrp_e100_iface_impl : public usrp_e100_iface{ public: @@ -36,13 +100,15 @@ public: /******************************************************************* * Structors ******************************************************************/ - usrp_e100_iface_impl(const std::string &node){ + usrp_e100_iface_impl(const std::string &node): + _i2c_dev_iface(i2c_dev_iface("/dev/i2c-3")) + { //open the device node and check file descriptor if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ - throw std::runtime_error(str( - boost::format("Failed to open %s") % node - )); + throw std::runtime_error("Failed to open " + node); } + + mb_eeprom = mboard_eeprom_t(get_i2c_dev_iface(), mboard_eeprom_t::MAP_E100); } ~usrp_e100_iface_impl(void){ @@ -63,6 +129,13 @@ public: } } + /******************************************************************* + * I2C device node interface + ******************************************************************/ + i2c_iface &get_i2c_dev_iface(void){ + return _i2c_dev_iface; + } + /******************************************************************* * Peek and Poke ******************************************************************/ @@ -183,6 +256,7 @@ public: private: int _node_fd; + i2c_dev_iface _i2c_dev_iface; boost::mutex _ctrl_mutex; }; diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp index b52209a42..12283fb52 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp @@ -19,6 +19,7 @@ #define INCLUDED_USRP_E100_IFACE_HPP #include +#include #include #include #include @@ -63,6 +64,9 @@ public: */ virtual void ioctl(int request, void *mem) = 0; + //! Get the I2C interface for the I2C device node + virtual uhd::i2c_iface &get_i2c_dev_iface(void) = 0; + /*! * Write a register (32 bits) * \param addr the address @@ -107,6 +111,9 @@ public: size_t num_bits, bool readback ) = 0; + + //motherboard eeprom map structure + uhd::usrp::mboard_eeprom_t mb_eeprom; }; #endif /* INCLUDED_USRP_E100_IFACE_HPP */ -- cgit v1.2.3 From f2d5f0b12bd0e9a29d22a93a6aaa4565021583e4 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 11 Nov 2010 09:20:26 -0800 Subject: usrp_eXXX: Only include i2c-dev.h due to struct definition conflicts. --- host/lib/usrp/usrp_e100/usrp_e100_iface.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp index 40c7afabb..50ff4a8ff 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp @@ -23,7 +23,6 @@ #include #include //mutex #include -#include #include using namespace uhd; -- cgit v1.2.3 From 791401f979aae3e5909ed0a7a06e176f0c16cd5a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 11 Nov 2010 10:41:05 -0800 Subject: usrp-e100: split vendor/device field for eeprom, rename fab rev to model, fixed char cast (to treat like integer) --- host/lib/usrp/mboard_eeprom.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp index 444057ad9..842ee01e3 100644 --- a/host/lib/usrp/mboard_eeprom.cpp +++ b/host/lib/usrp/mboard_eeprom.cpp @@ -178,10 +178,11 @@ static void store_b000(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ static const boost::uint8_t E100_EEPROM_ADDR = 0x51; struct e100_eeprom_map{ - unsigned int device_vendor; + boost::uint16_t vendor; + boost::uint16_t device; unsigned char revision; unsigned char content; - unsigned char fab_revision[8]; + unsigned char model[8]; unsigned char env_var[16]; unsigned char env_setting[64]; unsigned char serial[10]; @@ -196,41 +197,46 @@ template static const byte_vector_t to_bytes(const T &item){ } static void load_e100(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ - const size_t num_bytes = offsetof(e100_eeprom_map, fab_revision); + const size_t num_bytes = offsetof(e100_eeprom_map, model); byte_vector_t map_bytes = iface.read_eeprom(E100_EEPROM_ADDR, 0, num_bytes); e100_eeprom_map map; std::memcpy(&map, &map_bytes[0], map_bytes.size()); - mb_eeprom["device_vendor"] = boost::lexical_cast(map.device_vendor); - mb_eeprom["revision"] = boost::lexical_cast(map.revision); - mb_eeprom["content"] = boost::lexical_cast(map.content); + mb_eeprom["vendor"] = boost::lexical_cast(map.vendor); + mb_eeprom["device"] = boost::lexical_cast(map.device); + mb_eeprom["revision"] = boost::lexical_cast(unsigned(map.revision)); + mb_eeprom["content"] = boost::lexical_cast(unsigned(map.content)); #define load_e100_string_xx(key) mb_eeprom[#key] = bytes_to_string(iface.read_eeprom( \ E100_EEPROM_ADDR, offsetof(e100_eeprom_map, key), sizeof(e100_eeprom_map::key) \ )); - load_e100_string_xx(fab_revision); + load_e100_string_xx(model); load_e100_string_xx(env_var); load_e100_string_xx(env_setting); load_e100_string_xx(serial); - load_e100_string_xx(fab_revision); load_e100_string_xx(name); } static void store_e100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ - if (mb_eeprom.has_key("device_vendor")) iface.write_eeprom( - E100_EEPROM_ADDR, offsetof(e100_eeprom_map, device_vendor), - to_bytes(boost::lexical_cast(mb_eeprom["device_vendor"])) + if (mb_eeprom.has_key("vendor")) iface.write_eeprom( + E100_EEPROM_ADDR, offsetof(e100_eeprom_map, vendor), + to_bytes(boost::lexical_cast(mb_eeprom["vendor"])) + ); + + if (mb_eeprom.has_key("device")) iface.write_eeprom( + E100_EEPROM_ADDR, offsetof(e100_eeprom_map, device), + to_bytes(boost::lexical_cast(mb_eeprom["device"])) ); if (mb_eeprom.has_key("revision")) iface.write_eeprom( E100_EEPROM_ADDR, offsetof(e100_eeprom_map, revision), - to_bytes(boost::lexical_cast(mb_eeprom["revision"])) + byte_vector_t(1, boost::lexical_cast(mb_eeprom["revision"])) ); if (mb_eeprom.has_key("content")) iface.write_eeprom( E100_EEPROM_ADDR, offsetof(e100_eeprom_map, content), - to_bytes(boost::lexical_cast(mb_eeprom["content"])) + byte_vector_t(1, boost::lexical_cast(mb_eeprom["content"])) ); #define store_e100_string_xx(key) if (mb_eeprom.has_key(#key)) iface.write_eeprom( \ @@ -238,11 +244,10 @@ static void store_e100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ string_to_bytes(mb_eeprom[#key], sizeof(e100_eeprom_map::key)) \ ); - store_e100_string_xx(fab_revision); + store_e100_string_xx(model); store_e100_string_xx(env_var); store_e100_string_xx(env_setting); store_e100_string_xx(serial); - store_e100_string_xx(fab_revision); store_e100_string_xx(name); } -- cgit v1.2.3 From 926fd69de88725f14c34062a81969a4a833a7f61 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 11 Nov 2010 11:07:39 -0800 Subject: usrp_e100: added byteswapping calls to vendor and device (its NBO) --- host/lib/usrp/mboard_eeprom.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp index 842ee01e3..70f4664a0 100644 --- a/host/lib/usrp/mboard_eeprom.cpp +++ b/host/lib/usrp/mboard_eeprom.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -201,8 +202,8 @@ static void load_e100(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ byte_vector_t map_bytes = iface.read_eeprom(E100_EEPROM_ADDR, 0, num_bytes); e100_eeprom_map map; std::memcpy(&map, &map_bytes[0], map_bytes.size()); - mb_eeprom["vendor"] = boost::lexical_cast(map.vendor); - mb_eeprom["device"] = boost::lexical_cast(map.device); + mb_eeprom["vendor"] = boost::lexical_cast(uhd::ntohx(map.vendor)); + mb_eeprom["device"] = boost::lexical_cast(uhd::ntohx(map.device)); mb_eeprom["revision"] = boost::lexical_cast(unsigned(map.revision)); mb_eeprom["content"] = boost::lexical_cast(unsigned(map.content)); @@ -221,12 +222,12 @@ static void store_e100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ if (mb_eeprom.has_key("vendor")) iface.write_eeprom( E100_EEPROM_ADDR, offsetof(e100_eeprom_map, vendor), - to_bytes(boost::lexical_cast(mb_eeprom["vendor"])) + to_bytes(uhd::htonx(boost::lexical_cast(mb_eeprom["vendor"]))) ); if (mb_eeprom.has_key("device")) iface.write_eeprom( E100_EEPROM_ADDR, offsetof(e100_eeprom_map, device), - to_bytes(boost::lexical_cast(mb_eeprom["device"])) + to_bytes(uhd::htonx(boost::lexical_cast(mb_eeprom["device"]))) ); if (mb_eeprom.has_key("revision")) iface.write_eeprom( -- cgit v1.2.3 From be3f1411c5c2ba7714b1531418a57f3be06829bf Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 11 Nov 2010 11:27:01 -0800 Subject: usrp-e100: add serial and name checks to the usrp-e100 discovery routine --- host/lib/usrp/usrp_e100/usrp_e100_impl.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp index 8e40458d5..13d31e423 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp @@ -32,13 +32,6 @@ using namespace uhd; using namespace uhd::usrp; namespace fs = boost::filesystem; -/*********************************************************************** - * Helper Functions - **********************************************************************/ -static std::string abs_path(const std::string &file_path){ - return fs::system_complete(fs::path(file_path)).file_string(); -} - /*********************************************************************** * Discovery **********************************************************************/ @@ -59,8 +52,24 @@ static device_addrs_t usrp_e100_find(const device_addr_t &hint){ if (fs::exists(hint["node"])){ device_addr_t new_addr; new_addr["type"] = "usrp-e"; - new_addr["node"] = abs_path(hint["node"]); - usrp_e100_addrs.push_back(new_addr); + new_addr["node"] = fs::system_complete(fs::path(hint["node"])).file_string(); + try{ + usrp_e100_iface::sptr iface = usrp_e100_iface::make(new_addr["node"]); + new_addr["name"] = iface->mb_eeprom["name"]; + new_addr["serial"] = iface->mb_eeprom["serial"]; + if ( + (not hint.has_key("name") or hint["name"] == new_addr["name"]) and + (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) + ){ + usrp_e100_addrs.push_back(new_addr); + } + } + catch(const std::exception &e){ + uhd::warning::post( + std::string("Ignoring discovered device\n") + + e.what() + ); + } } return usrp_e100_addrs; -- cgit v1.2.3 From 309964637e5eac309a6d9d36300a14a4235f34fb Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 11 Nov 2010 14:41:21 -0800 Subject: usrp_e : Add missing header file. --- host/lib/usrp/usrp_e100/usrp_e100_impl.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'host') diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp index 13d31e423..a3e03056a 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From 862a3f264671a133d9ff7e5b39d707d105a1dd45 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 17 Nov 2010 11:11:37 -0800 Subject: usrp e100 : Add i2c header back. --- host/lib/usrp/usrp_e100/usrp_e100_iface.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'host') diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp index 50ff4a8ff..40c7afabb 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp @@ -23,6 +23,7 @@ #include #include //mutex #include +#include #include using namespace uhd; -- cgit v1.2.3 From 27e128ea70249bf4a79c6957fab14a3c4cad75f8 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 17 Nov 2010 11:13:31 -0800 Subject: usrp e100 : Add sleep after loading module. After loading the module, we need to wait until /dev/usrp_e0 is available before proceeding. --- host/lib/usrp/usrp_e100/usrp_e100_impl.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'host') diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp index a3e03056a..40ea56466 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp @@ -123,6 +123,7 @@ static device::sptr usrp_e100_make(const device_addr_t &device_addr){ if (fpga_compat_num != USRP_E_COMPAT_NUM or loaded_hash != fpga_hash){ iface.reset(); usrp_e100_load_fpga(usrp_e100_fpga_image); + sleep(1); ///\todo do this better one day. std::cout << boost::format("re-Opening USRP-E on %s") % node << std::endl; iface = usrp_e100_iface::make(node); try{std::ofstream(hash_file_path) << fpga_hash;}catch(...){} -- cgit v1.2.3 From 13ae4786e091d5581baf31c9967dca822ef15e39 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Mon, 22 Nov 2010 18:26:54 -0800 Subject: E100: clock sync implemented. --- host/lib/usrp/usrp_e100/clock_ctrl.cpp | 26 ++++++++++++++++++++++++++ host/lib/usrp/usrp_e100/clock_ctrl.hpp | 15 +++++++++++++++ host/lib/usrp/usrp_e100/mboard_impl.cpp | 30 +++++++++++++++++++++++++++++- host/lib/usrp/usrp_e100/usrp_e100_impl.hpp | 5 ++++- 4 files changed, 74 insertions(+), 2 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.cpp b/host/lib/usrp/usrp_e100/clock_ctrl.cpp index e99560540..1fb1a7125 100644 --- a/host/lib/usrp/usrp_e100/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e100/clock_ctrl.cpp @@ -208,6 +208,32 @@ public: this->send_reg(0x197); this->latch_regs(); } + + /*********************************************************************** + * Clock reference control + **********************************************************************/ + void use_internal_ref(void) { + _ad9522_regs.enable_ref2 = 1; + _ad9522_regs.enable_ref1 = 0; + _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF2; + _ad9522_regs.enb_auto_ref_switchover = ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_MANUAL; + this->send_reg(0x01C); + } + + void use_external_ref(void) { + _ad9522_regs.enable_ref2 = 0; + _ad9522_regs.enable_ref1 = 1; + _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF1; + _ad9522_regs.enb_auto_ref_switchover = ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_MANUAL; + this->send_reg(0x01C); + } + + void use_auto_ref(void) { + _ad9522_regs.enable_ref2 = 1; + _ad9522_regs.enable_ref1 = 1; + _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF1; + _ad9522_regs.enb_auto_ref_switchover = ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_AUTO; + } private: usrp_e100_iface::sptr _iface; diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.hpp b/host/lib/usrp/usrp_e100/clock_ctrl.hpp index 0ae68728e..d613d1473 100644 --- a/host/lib/usrp/usrp_e100/clock_ctrl.hpp +++ b/host/lib/usrp/usrp_e100/clock_ctrl.hpp @@ -82,6 +82,21 @@ public: * \param enb true to enable */ virtual void enable_tx_dboard_clock(bool enb) = 0; + + /*! + * Use the internal TCXO reference + */ + virtual void use_internal_ref(void) = 0; + + /*! + * Use the external SMA reference + */ + virtual void use_external_ref(void) = 0; + + /*! + * Use external if available, internal otherwise + */ + virtual void use_auto_ref(void) = 0; }; diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp index 9c6317b94..03c4385aa 100644 --- a/host/lib/usrp/usrp_e100/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp @@ -39,8 +39,31 @@ void usrp_e100_impl::mboard_init(void){ //init the clock config _clock_config.ref_source = clock_config_t::REF_AUTO; _clock_config.pps_source = clock_config_t::PPS_SMA; + _clock_config.pps_polarity = clock_config_t::PPS_NEG; - //TODO poke the clock config regs + update_clock_config(); +} + +void usrp_e100_impl::update_clock_config(void){ + boost::uint32_t pps_flags = 0; + + //translate pps polarity enums + switch(_clock_config.pps_polarity){ + case clock_config_t::PPS_POS: pps_flags |= UE_FLAG_TIME64_PPS_POSEDGE; break; + case clock_config_t::PPS_NEG: pps_flags |= UE_FLAG_TIME64_PPS_NEGEDGE; break; + default: throw std::runtime_error("unhandled clock configuration pps polarity"); + } + + //set the pps flags + _iface->poke32(UE_REG_TIME64_FLAGS, pps_flags); + + //clock source ref 10mhz + switch(_clock_config.ref_source){ + case clock_config_t::REF_AUTO: _clock_ctrl->use_auto_ref(); + case clock_config_t::REF_INT: _clock_ctrl->use_internal_ref(); + case clock_config_t::REF_SMA: _clock_ctrl->use_external_ref(); + default: throw std::runtime_error("unhandled clock configuration ref source"); + } } /*********************************************************************** @@ -164,6 +187,11 @@ void usrp_e100_impl::mboard_set(const wax::obj &key, const wax::obj &val){ val.as().commit(_iface->get_i2c_dev_iface(), mboard_eeprom_t::MAP_E100); _iface->mb_eeprom = mboard_eeprom_t(_iface->get_i2c_dev_iface(), mboard_eeprom_t::MAP_E100); return; + + case MBOARD_PROP_CLOCK_CONFIG: + _clock_config = val.as(); + update_clock_config(); + return; default: UHD_THROW_PROP_SET_ERROR(); } diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp index fe60ac0be..de158ea5e 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp @@ -102,7 +102,6 @@ private: //configuration shadows uhd::clock_config_t _clock_config; - //TODO otw type recv/send //ad9522 clock control usrp_e100_clock_ctrl::sptr _clock_ctrl; @@ -159,6 +158,10 @@ private: void tx_codec_get(const wax::obj &, wax::obj &); void tx_codec_set(const wax::obj &, const wax::obj &); wax_obj_proxy::sptr _rx_codec_proxy, _tx_codec_proxy; + + //clock control functions and settings + void init_clock_config(void); + void update_clock_config(void); }; #endif /* INCLUDED_USRP_E100_IMPL_HPP */ -- cgit v1.2.3