aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-04-12 15:19:25 -0700
committerJosh Blum <josh@joshknows.com>2010-04-12 15:19:25 -0700
commitb87d9afe82e962718f5f5d514abf9d79b9603b98 (patch)
treecaa53a69eaa9847994737748c1385a2dfd3153f8 /host/lib
parent24ca9fbd0784c7c53af6ad4f9035e8d43e888290 (diff)
parentfa96b25b99dbd19ac0689cab9bcab84063287ad3 (diff)
downloaduhd-b87d9afe82e962718f5f5d514abf9d79b9603b98.tar.gz
uhd-b87d9afe82e962718f5f5d514abf9d79b9603b98.tar.bz2
uhd-b87d9afe82e962718f5f5d514abf9d79b9603b98.zip
Merge branch 'rfx' of git@ettus.sourcerepo.com:ettus/uhd into io
Conflicts: host/lib/usrp/usrp2/io_impl.cpp
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/CMakeLists.txt54
-rwxr-xr-xhost/lib/ic_reg_maps/gen_adf4360_regs.py173
-rwxr-xr-xhost/lib/transport/gen_vrt.py24
-rw-r--r--host/lib/transport/vrt.cpp547
-rw-r--r--host/lib/types.cpp27
-rw-r--r--host/lib/usrp/dboard/db_basic_and_lf.cpp16
-rw-r--r--host/lib/usrp/dboard/db_rfx.cpp319
-rw-r--r--host/lib/usrp/dboard_interface.cpp53
-rw-r--r--host/lib/usrp/usrp2/dboard_impl.cpp1
-rw-r--r--host/lib/usrp/usrp2/dboard_interface.cpp95
-rw-r--r--host/lib/usrp/usrp2/fw_common.h7
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp7
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp8
13 files changed, 642 insertions, 689 deletions
diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt
index fac1bd19f..52ed809ab 100644
--- a/host/lib/CMakeLists.txt
+++ b/host/lib/CMakeLists.txt
@@ -15,6 +15,33 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+
+########################################################################
+# Setup Python
+########################################################################
+INCLUDE(FindPythonInterp)
+
+MACRO(PYTHON_CHECK_MODULE module have)
+ MESSAGE(STATUS "Checking for python module ${module}")
+ EXECUTE_PROCESS(
+ COMMAND ${PYTHON_EXECUTABLE} -c "import ${module}"
+ RESULT_VARIABLE ${have}
+ )
+ IF(${have} EQUAL 0)
+ MESSAGE(STATUS "Checking for python module ${module} - found")
+ SET(${have} TRUE)
+ ELSE(${have} EQUAL 0)
+ MESSAGE(STATUS "Checking for python module ${module} - not found")
+ SET(${have} FALSE)
+ ENDIF(${have} EQUAL 0)
+ENDMACRO(PYTHON_CHECK_MODULE)
+
+PYTHON_CHECK_MODULE("Cheetah" HAVE_PYTHON_MODULE_CHEETAH)
+
+IF(NOT HAVE_PYTHON_MODULE_CHEETAH)
+ MESSAGE(FATAL_ERROR "Error: Cheetah Templates needed for pre-build generation.")
+ENDIF(NOT HAVE_PYTHON_MODULE_CHEETAH)
+
########################################################################
# Create a list of libuhd sources
########################################################################
@@ -27,10 +54,9 @@ SET(libuhd_sources
transport/convert_types.cpp
transport/if_addrs.cpp
transport/udp_simple.cpp
- transport/vrt.cpp
usrp/dboard/db_basic_and_lf.cpp
+ usrp/dboard/db_rfx.cpp
usrp/dboard_base.cpp
- usrp/dboard_interface.cpp
usrp/simple_usrp.cpp
usrp/dboard_manager.cpp
usrp/tune_helper.cpp
@@ -43,6 +69,30 @@ SET(libuhd_sources
)
########################################################################
+# Generate Files
+########################################################################
+MACRO(UHD_PYTHON_GEN_SOURCE_FILE pyfile outfile)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${outfile} DEPENDS ${pyfile}
+ COMMAND ${PYTHON_EXECUTABLE} ${pyfile} ${outfile}
+ COMMENT "Calling ${pyfile} to generate ${outfile}"
+ )
+ LIST(APPEND libuhd_sources ${outfile})
+ENDMACRO(UHD_PYTHON_GEN_SOURCE_FILE)
+
+UHD_PYTHON_GEN_SOURCE_FILE(
+ ${CMAKE_CURRENT_SOURCE_DIR}/transport/gen_vrt.py
+ ${CMAKE_CURRENT_BINARY_DIR}/transport/vrt.cpp
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps)
+
+UHD_PYTHON_GEN_SOURCE_FILE(
+ ${CMAKE_CURRENT_SOURCE_DIR}/ic_reg_maps/gen_adf4360_regs.py
+ ${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps/adf4360_regs.hpp
+)
+
+########################################################################
# Conditionally add the udp sources
########################################################################
LIST(APPEND libuhd_sources
diff --git a/host/lib/ic_reg_maps/gen_adf4360_regs.py b/host/lib/ic_reg_maps/gen_adf4360_regs.py
new file mode 100755
index 000000000..e7c2c9435
--- /dev/null
+++ b/host/lib/ic_reg_maps/gen_adf4360_regs.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python
+#
+# Copyright 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 asversion 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.
+
+import re
+import os
+import sys
+from Cheetah.Template import Template
+def parse_tmpl(_tmpl_text, **kwargs):
+ return str(Template(_tmpl_text, kwargs))
+def safe_makedirs(path):
+ not os.path.isdir(path) and os.makedirs(path)
+
+########################################################################
+# Template for raw text data describing registers
+# name addr[bit range inclusive] default optional enums
+########################################################################
+REGS_DATA_TMPL="""\
+########################################################################
+## address 0
+########################################################################
+core_power_level 0[2:3] 0 5ma, 10ma, 15ma, 20ma
+counter_reset 0[4] 0 normal, reset
+muxout_control 0[5:7] 0 3state, dld, ndiv, dvdd, rdiv, nchan_od_ld, sdo, dgnd
+phase_detector_polarity 0[8] 0 neg, pos
+cp_three_state 0[9] 0 normal, 3state
+cp_gain_0 0[10] 0 set1, set2
+mute_till_ld 0[11] 0 dis, enb
+output_power_level 0[12:13] 0 3_5ma, 5_0ma, 7_5ma, 11_0ma
+#set $current_setting_enums = "0_31, 0_62, 0_93, 1_25, 1_56, 1_87, 2_18, 2_50"
+current_setting1 0[14:16] 0 $current_setting_enums
+current_setting2 0[17:19] 0 $current_setting_enums
+power_down 0[20:21] 0 normal_op=0, async_pd=1, sync_pd=3
+prescaler_value 0[22:23] 0 8_9, 16_17, 32_33
+########################################################################
+## address 2
+########################################################################
+a_counter 2[2:6] 0
+b_counter 2[8:20] 0
+cp_gain_1 2[21] 0 set1, set2
+divide_by_2_output 2[22] 0 fund, div2
+divide_by_2_prescaler 2[23] 0 fund, div2
+########################################################################
+## address 1
+########################################################################
+r_counter 1[2:15] 0
+ablpw 1[16:17] 0 3_0ns, 1_3ns, 6_0ns
+lock_detect_precision 1[18] 0 3cycles, 5cycles
+test_mode_bit 1[19] 0
+band_select_clock_div 1[20:21] 0 1, 2, 4, 8
+"""
+
+########################################################################
+# Header and Source templates below
+########################################################################
+HEADER_TEXT="""
+#import time
+
+/***********************************************************************
+ * This file was generated by $file on $time.strftime("%c")
+ **********************************************************************/
+
+\#ifndef INCLUDED_ADF4360_REGS_HPP
+\#define INCLUDED_ADF4360_REGS_HPP
+
+\#include <boost/cstdint.hpp>
+
+struct adf4360_regs_t{
+#for $reg in $regs
+ #if $reg.get_enums()
+ enum $(reg.get_name())_t{
+ #for $i, $enum in enumerate($reg.get_enums())
+ #set $end_comma = ',' if $i < len($reg.get_enums())-1 else ''
+ $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma
+ #end for
+ } $reg.get_name();
+ #else
+ boost::$reg.get_stdint_type() $reg.get_name();
+ #end if
+#end for
+
+ adf4360_regs_t(void){
+#for $reg in $regs
+ $reg.get_name() = $reg.get_default();
+#end for
+ }
+
+ enum addr_t{
+ ADDR_CONTROL = 0,
+ ADDR_NCOUNTER = 2,
+ ADDR_RCOUNTER = 1
+ };
+
+ boost::uint32_t get_reg(addr_t addr){
+ boost::uint32_t reg = addr & 0x3;
+ switch(addr){
+ #for $addr in (0, 1, 2)
+ case $addr:
+ #for $reg in filter(lambda r: r.get_addr() == addr, $regs)
+ reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift();
+ #end for
+ break;
+ #end for
+ }
+ return reg;
+ }
+};
+
+\#endif /* INCLUDED_ADF4360_REGS_HPP */
+"""
+
+class reg:
+ def __init__(self, reg_des):
+ x = re.match('^(\w*)\s*(\w*)\[(.*)\]\s*(\w*)\s*(.*)$', reg_des)
+ name, addr, bit_range, default, enums = x.groups()
+
+ #store variables
+ self._name = name
+ self._addr = int(addr)
+ if ':' in bit_range: self._addr_spec = map(int, bit_range.split(':'))
+ else: self._addr_spec = int(bit_range), int(bit_range)
+ self._default = int(default)
+
+ #extract enum
+ self._enums = list()
+ if enums:
+ enum_val = 0
+ for enum_str in map(str.strip, enums.split(',')):
+ if '=' in enum_str:
+ enum_name, enum_val = enum_str.split('=')
+ enum_val = int(enum_val)
+ else: enum_name = enum_str
+ self._enums.append((enum_name, enum_val))
+ enum_val += 1
+
+ def get_addr(self): return self._addr
+ def get_enums(self): return self._enums
+ def get_name(self): return self._name
+ def get_default(self):
+ for key, val in self.get_enums():
+ if val == self._default: return str.upper('%s_%s'%(self.get_name(), key))
+ return self._default
+ def get_stdint_type(self):
+ if self.get_bit_width() <= 8: return 'uint8_t'
+ if self.get_bit_width() <= 16: return 'uint16_t'
+ if self.get_bit_width() <= 32: return 'uint32_t'
+ if self.get_bit_width() <= 64: return 'uint64_t'
+ raise Exception, 'too damn big'
+ def get_shift(self): return self._addr_spec[0]
+ def get_mask(self): return hex(int('1'*self.get_bit_width(), 2))
+ def get_bit_width(self): return self._addr_spec[1] - self._addr_spec[0] + 1
+
+if __name__ == '__main__':
+ regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines())
+ safe_makedirs(os.path.dirname(sys.argv[1]))
+ open(sys.argv[1], 'w').write(parse_tmpl(HEADER_TEXT, regs=regs, file=__file__))
diff --git a/host/lib/transport/gen_vrt.py b/host/lib/transport/gen_vrt.py
index 918de3ad7..38a394dee 100755
--- a/host/lib/transport/gen_vrt.py
+++ b/host/lib/transport/gen_vrt.py
@@ -54,7 +54,8 @@ void vrt::pack(
size_t &num_header_words32, //output
size_t num_payload_words32, //input
size_t &num_packet_words32, //output
- size_t packet_count //input
+ size_t packet_count, //input
+ double tick_rate //input
){
boost::uint32_t vrt_hdr_flags;
@@ -91,7 +92,7 @@ void vrt::pack(
#if $pred & $tsf_p
header_buff[$num_header_words] = htonl(0);
#set $num_header_words += 1
- header_buff[$num_header_words] = htonl(metadata.time_spec.ticks);
+ header_buff[$num_header_words] = htonl(metadata.time_spec.get_ticks(tick_rate));
#set $num_header_words += 1
#set $flags |= (0x1 << 20);
#end if
@@ -127,7 +128,8 @@ void vrt::unpack(
size_t &num_header_words32, //output
size_t &num_payload_words32, //output
size_t num_packet_words32, //input
- size_t &packet_count //output
+ size_t &packet_count, //output
+ double tick_rate //input
){
//clear the metadata
metadata = rx_metadata_t();
@@ -180,7 +182,7 @@ void vrt::unpack(
#set $set_has_time_spec = True
#end if
#set $num_header_words += 1
- metadata.time_spec.ticks = ntohl(header_buff[$num_header_words]);
+ metadata.time_spec.set_ticks(ntohl(header_buff[$num_header_words]), tick_rate);
#set $num_header_words += 1
#end if
########## Trailer ##########
@@ -198,9 +200,15 @@ void vrt::unpack(
}
"""
-from Cheetah import Template
-def parse_str(_tmpl_text, **kwargs): return str(Template.Template(_tmpl_text, kwargs))
+import os
+import sys
+
+from Cheetah.Template import Template
+def parse_tmpl(_tmpl_text, **kwargs):
+ return str(Template(_tmpl_text, kwargs))
+def safe_makedirs(path):
+ not os.path.isdir(path) and os.makedirs(path)
if __name__ == '__main__':
- from Cheetah import Template
- print parse_str(TMPL_TEXT, file=__file__)
+ safe_makedirs(os.path.dirname(sys.argv[1]))
+ open(sys.argv[1], 'w').write(parse_tmpl(TMPL_TEXT, file=__file__))
diff --git a/host/lib/transport/vrt.cpp b/host/lib/transport/vrt.cpp
deleted file mode 100644
index bebca5db9..000000000
--- a/host/lib/transport/vrt.cpp
+++ /dev/null
@@ -1,547 +0,0 @@
-
-
-
-/***********************************************************************
- * This file was generated by ./gen_vrt.py on Fri Mar 26 15:33:00 2010
- **********************************************************************/
-
-#include <uhd/transport/vrt.hpp>
-#include <boost/asio.hpp> //endianness conversion
-#include <stdexcept>
-
-using namespace uhd;
-using namespace uhd::transport;
-
-void vrt::pack(
- const tx_metadata_t &metadata, //input
- boost::uint32_t *header_buff, //output
- size_t &num_header_words32, //output
- size_t num_payload_words32, //input
- size_t &num_packet_words32, //output
- size_t packet_count //input
-){
- boost::uint32_t vrt_hdr_flags;
-
- boost::uint8_t pred = 0;
- if (metadata.has_stream_id) pred |= 0x1;
- if (metadata.has_time_spec) pred |= 0xc;
-
- switch(pred){
- case 0:
- num_header_words32 = 1;
- num_packet_words32 = 1 + num_payload_words32;
- vrt_hdr_flags = 0x0;
- break;
- case 1:
- header_buff[1] = htonl(metadata.stream_id);
- num_header_words32 = 2;
- num_packet_words32 = 2 + num_payload_words32;
- vrt_hdr_flags = 0x10000000;
- break;
- case 2:
- header_buff[1] = htonl(0);
- header_buff[2] = htonl(0);
- num_header_words32 = 3;
- num_packet_words32 = 3 + num_payload_words32;
- vrt_hdr_flags = 0x8000000;
- break;
- case 3:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(0);
- num_header_words32 = 4;
- num_packet_words32 = 4 + num_payload_words32;
- vrt_hdr_flags = 0x18000000;
- break;
- case 4:
- header_buff[1] = htonl(metadata.time_spec.secs);
- num_header_words32 = 2;
- num_packet_words32 = 2 + num_payload_words32;
- vrt_hdr_flags = 0xc00000;
- break;
- case 5:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(metadata.time_spec.secs);
- num_header_words32 = 3;
- num_packet_words32 = 3 + num_payload_words32;
- vrt_hdr_flags = 0x10c00000;
- break;
- case 6:
- header_buff[1] = htonl(0);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(metadata.time_spec.secs);
- num_header_words32 = 4;
- num_packet_words32 = 4 + num_payload_words32;
- vrt_hdr_flags = 0x8c00000;
- break;
- case 7:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(0);
- header_buff[4] = htonl(metadata.time_spec.secs);
- num_header_words32 = 5;
- num_packet_words32 = 5 + num_payload_words32;
- vrt_hdr_flags = 0x18c00000;
- break;
- case 8:
- header_buff[1] = htonl(0);
- header_buff[2] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 3;
- num_packet_words32 = 3 + num_payload_words32;
- vrt_hdr_flags = 0x100000;
- break;
- case 9:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 4;
- num_packet_words32 = 4 + num_payload_words32;
- vrt_hdr_flags = 0x10100000;
- break;
- case 10:
- header_buff[1] = htonl(0);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(0);
- header_buff[4] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 5;
- num_packet_words32 = 5 + num_payload_words32;
- vrt_hdr_flags = 0x8100000;
- break;
- case 11:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(0);
- header_buff[4] = htonl(0);
- header_buff[5] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 6;
- num_packet_words32 = 6 + num_payload_words32;
- vrt_hdr_flags = 0x18100000;
- break;
- case 12:
- header_buff[1] = htonl(metadata.time_spec.secs);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 4;
- num_packet_words32 = 4 + num_payload_words32;
- vrt_hdr_flags = 0xd00000;
- break;
- case 13:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(metadata.time_spec.secs);
- header_buff[3] = htonl(0);
- header_buff[4] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 5;
- num_packet_words32 = 5 + num_payload_words32;
- vrt_hdr_flags = 0x10d00000;
- break;
- case 14:
- header_buff[1] = htonl(0);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(metadata.time_spec.secs);
- header_buff[4] = htonl(0);
- header_buff[5] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 6;
- num_packet_words32 = 6 + num_payload_words32;
- vrt_hdr_flags = 0x8d00000;
- break;
- case 15:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(0);
- header_buff[4] = htonl(metadata.time_spec.secs);
- header_buff[5] = htonl(0);
- header_buff[6] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 7;
- num_packet_words32 = 7 + num_payload_words32;
- vrt_hdr_flags = 0x18d00000;
- break;
- case 16:
- num_header_words32 = 1;
- num_packet_words32 = 2 + num_payload_words32;
- vrt_hdr_flags = 0x4000000;
- break;
- case 17:
- header_buff[1] = htonl(metadata.stream_id);
- num_header_words32 = 2;
- num_packet_words32 = 3 + num_payload_words32;
- vrt_hdr_flags = 0x14000000;
- break;
- case 18:
- header_buff[1] = htonl(0);
- header_buff[2] = htonl(0);
- num_header_words32 = 3;
- num_packet_words32 = 4 + num_payload_words32;
- vrt_hdr_flags = 0xc000000;
- break;
- case 19:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(0);
- num_header_words32 = 4;
- num_packet_words32 = 5 + num_payload_words32;
- vrt_hdr_flags = 0x1c000000;
- break;
- case 20:
- header_buff[1] = htonl(metadata.time_spec.secs);
- num_header_words32 = 2;
- num_packet_words32 = 3 + num_payload_words32;
- vrt_hdr_flags = 0x4c00000;
- break;
- case 21:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(metadata.time_spec.secs);
- num_header_words32 = 3;
- num_packet_words32 = 4 + num_payload_words32;
- vrt_hdr_flags = 0x14c00000;
- break;
- case 22:
- header_buff[1] = htonl(0);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(metadata.time_spec.secs);
- num_header_words32 = 4;
- num_packet_words32 = 5 + num_payload_words32;
- vrt_hdr_flags = 0xcc00000;
- break;
- case 23:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(0);
- header_buff[4] = htonl(metadata.time_spec.secs);
- num_header_words32 = 5;
- num_packet_words32 = 6 + num_payload_words32;
- vrt_hdr_flags = 0x1cc00000;
- break;
- case 24:
- header_buff[1] = htonl(0);
- header_buff[2] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 3;
- num_packet_words32 = 4 + num_payload_words32;
- vrt_hdr_flags = 0x4100000;
- break;
- case 25:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 4;
- num_packet_words32 = 5 + num_payload_words32;
- vrt_hdr_flags = 0x14100000;
- break;
- case 26:
- header_buff[1] = htonl(0);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(0);
- header_buff[4] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 5;
- num_packet_words32 = 6 + num_payload_words32;
- vrt_hdr_flags = 0xc100000;
- break;
- case 27:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(0);
- header_buff[4] = htonl(0);
- header_buff[5] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 6;
- num_packet_words32 = 7 + num_payload_words32;
- vrt_hdr_flags = 0x1c100000;
- break;
- case 28:
- header_buff[1] = htonl(metadata.time_spec.secs);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 4;
- num_packet_words32 = 5 + num_payload_words32;
- vrt_hdr_flags = 0x4d00000;
- break;
- case 29:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(metadata.time_spec.secs);
- header_buff[3] = htonl(0);
- header_buff[4] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 5;
- num_packet_words32 = 6 + num_payload_words32;
- vrt_hdr_flags = 0x14d00000;
- break;
- case 30:
- header_buff[1] = htonl(0);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(metadata.time_spec.secs);
- header_buff[4] = htonl(0);
- header_buff[5] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 6;
- num_packet_words32 = 7 + num_payload_words32;
- vrt_hdr_flags = 0xcd00000;
- break;
- case 31:
- header_buff[1] = htonl(metadata.stream_id);
- header_buff[2] = htonl(0);
- header_buff[3] = htonl(0);
- header_buff[4] = htonl(metadata.time_spec.secs);
- header_buff[5] = htonl(0);
- header_buff[6] = htonl(metadata.time_spec.ticks);
- num_header_words32 = 7;
- num_packet_words32 = 8 + num_payload_words32;
- vrt_hdr_flags = 0x1cd00000;
- break;
- }
-
- //set the burst flags
- if (metadata.start_of_burst) vrt_hdr_flags |= 0x2000000;
- if (metadata.end_of_burst) vrt_hdr_flags |= 0x1000000;
-
- //fill in complete header word
- header_buff[0] = htonl(vrt_hdr_flags |
- ((packet_count & 0xf) << 16) |
- (num_packet_words32 & 0xffff)
- );
-}
-
-void vrt::unpack(
- rx_metadata_t &metadata, //output
- const boost::uint32_t *header_buff, //input
- size_t &num_header_words32, //output
- size_t &num_payload_words32, //output
- size_t num_packet_words32, //input
- size_t &packet_count //output
-){
- //clear the metadata
- metadata = rx_metadata_t();
-
- //extract vrt header
- boost::uint32_t vrt_hdr_word = ntohl(header_buff[0]);
- size_t packet_words32 = vrt_hdr_word & 0xffff;
- packet_count = (vrt_hdr_word >> 16) & 0xf;
-
- //failure cases
- if (packet_words32 == 0 or num_packet_words32 < packet_words32)
- throw std::runtime_error("bad vrt header or packet fragment");
- if (vrt_hdr_word & (0x7 << 29))
- throw std::runtime_error("unsupported vrt packet type");
-
- boost::uint8_t pred = 0;
- if(vrt_hdr_word & 0x10000000) pred |= 0x1;
- if(vrt_hdr_word & 0x8000000) pred |= 0x2;
- if(vrt_hdr_word & 0xc00000) pred |= 0x4;
- if(vrt_hdr_word & 0x300000) pred |= 0x8;
- if(vrt_hdr_word & 0x4000000) pred |= 0x10;
-
- switch(pred){
- case 0:
- num_header_words32 = 1;
- num_payload_words32 = packet_words32 - 1;
- break;
- case 1:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- num_header_words32 = 2;
- num_payload_words32 = packet_words32 - 2;
- break;
- case 2:
- num_header_words32 = 3;
- num_payload_words32 = packet_words32 - 3;
- break;
- case 3:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- num_header_words32 = 4;
- num_payload_words32 = packet_words32 - 4;
- break;
- case 4:
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[1]);
- num_header_words32 = 2;
- num_payload_words32 = packet_words32 - 2;
- break;
- case 5:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[2]);
- num_header_words32 = 3;
- num_payload_words32 = packet_words32 - 3;
- break;
- case 6:
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[3]);
- num_header_words32 = 4;
- num_payload_words32 = packet_words32 - 4;
- break;
- case 7:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[4]);
- num_header_words32 = 5;
- num_payload_words32 = packet_words32 - 5;
- break;
- case 8:
- metadata.has_time_spec = true;
- metadata.time_spec.ticks = ntohl(header_buff[2]);
- num_header_words32 = 3;
- num_payload_words32 = packet_words32 - 3;
- break;
- case 9:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.ticks = ntohl(header_buff[3]);
- num_header_words32 = 4;
- num_payload_words32 = packet_words32 - 4;
- break;
- case 10:
- metadata.has_time_spec = true;
- metadata.time_spec.ticks = ntohl(header_buff[4]);
- num_header_words32 = 5;
- num_payload_words32 = packet_words32 - 5;
- break;
- case 11:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.ticks = ntohl(header_buff[5]);
- num_header_words32 = 6;
- num_payload_words32 = packet_words32 - 6;
- break;
- case 12:
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[1]);
- metadata.time_spec.ticks = ntohl(header_buff[3]);
- num_header_words32 = 4;
- num_payload_words32 = packet_words32 - 4;
- break;
- case 13:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[2]);
- metadata.time_spec.ticks = ntohl(header_buff[4]);
- num_header_words32 = 5;
- num_payload_words32 = packet_words32 - 5;
- break;
- case 14:
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[3]);
- metadata.time_spec.ticks = ntohl(header_buff[5]);
- num_header_words32 = 6;
- num_payload_words32 = packet_words32 - 6;
- break;
- case 15:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[4]);
- metadata.time_spec.ticks = ntohl(header_buff[6]);
- num_header_words32 = 7;
- num_payload_words32 = packet_words32 - 7;
- break;
- case 16:
- num_header_words32 = 1;
- num_payload_words32 = packet_words32 - 2;
- break;
- case 17:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- num_header_words32 = 2;
- num_payload_words32 = packet_words32 - 3;
- break;
- case 18:
- num_header_words32 = 3;
- num_payload_words32 = packet_words32 - 4;
- break;
- case 19:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- num_header_words32 = 4;
- num_payload_words32 = packet_words32 - 5;
- break;
- case 20:
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[1]);
- num_header_words32 = 2;
- num_payload_words32 = packet_words32 - 3;
- break;
- case 21:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[2]);
- num_header_words32 = 3;
- num_payload_words32 = packet_words32 - 4;
- break;
- case 22:
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[3]);
- num_header_words32 = 4;
- num_payload_words32 = packet_words32 - 5;
- break;
- case 23:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[4]);
- num_header_words32 = 5;
- num_payload_words32 = packet_words32 - 6;
- break;
- case 24:
- metadata.has_time_spec = true;
- metadata.time_spec.ticks = ntohl(header_buff[2]);
- num_header_words32 = 3;
- num_payload_words32 = packet_words32 - 4;
- break;
- case 25:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.ticks = ntohl(header_buff[3]);
- num_header_words32 = 4;
- num_payload_words32 = packet_words32 - 5;
- break;
- case 26:
- metadata.has_time_spec = true;
- metadata.time_spec.ticks = ntohl(header_buff[4]);
- num_header_words32 = 5;
- num_payload_words32 = packet_words32 - 6;
- break;
- case 27:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.ticks = ntohl(header_buff[5]);
- num_header_words32 = 6;
- num_payload_words32 = packet_words32 - 7;
- break;
- case 28:
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[1]);
- metadata.time_spec.ticks = ntohl(header_buff[3]);
- num_header_words32 = 4;
- num_payload_words32 = packet_words32 - 5;
- break;
- case 29:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[2]);
- metadata.time_spec.ticks = ntohl(header_buff[4]);
- num_header_words32 = 5;
- num_payload_words32 = packet_words32 - 6;
- break;
- case 30:
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[3]);
- metadata.time_spec.ticks = ntohl(header_buff[5]);
- num_header_words32 = 6;
- num_payload_words32 = packet_words32 - 7;
- break;
- case 31:
- metadata.has_stream_id = true;
- metadata.stream_id = ntohl(header_buff[1]);
- metadata.has_time_spec = true;
- metadata.time_spec.secs = ntohl(header_buff[4]);
- metadata.time_spec.ticks = ntohl(header_buff[6]);
- num_header_words32 = 7;
- num_payload_words32 = packet_words32 - 8;
- break;
- }
-}
-
diff --git a/host/lib/types.cpp b/host/lib/types.cpp
index 61a63b710..cd688e73d 100644
--- a/host/lib/types.cpp
+++ b/host/lib/types.cpp
@@ -26,6 +26,7 @@
#include <uhd/types/otw_type.hpp>
#include <uhd/types/io_type.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/math/special_functions/round.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/cstdint.hpp>
@@ -101,29 +102,26 @@ tx_metadata_t::tx_metadata_t(void){
/***********************************************************************
* time spec
**********************************************************************/
-time_spec_t::time_spec_t(boost::uint32_t new_secs, boost::uint32_t new_ticks){
+time_spec_t::time_spec_t(boost::uint32_t new_secs, double new_nsecs){
secs = new_secs;
- ticks = new_ticks;
+ nsecs = new_nsecs;
}
-static const boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
-static double time_tick_rate = double(boost::posix_time::time_duration::ticks_per_second());
+boost::uint32_t time_spec_t::get_ticks(double tick_rate) const{
+ return boost::math::iround(nsecs*tick_rate*1e-9);
+}
-time_spec_t::time_spec_t(boost::posix_time::ptime time, double tick_rate){
- boost::posix_time::time_duration td = time - epoch;
- secs = boost::uint32_t(td.total_seconds());
- double time_ticks_per_device_ticks = time_tick_rate/tick_rate;
- ticks = boost::uint32_t(td.fractional_seconds()/time_ticks_per_device_ticks);
+void time_spec_t::set_ticks(boost::uint32_t ticks, double tick_rate){
+ nsecs = double(ticks)*1e9/tick_rate;
}
/***********************************************************************
* device addr
**********************************************************************/
std::string device_addr_t::to_string(void) const{
- const device_addr_t &device_addr = *this;
std::stringstream ss;
- BOOST_FOREACH(std::string key, device_addr.keys()){
- ss << boost::format("%s: %s") % key % device_addr[key] << std::endl;
+ BOOST_FOREACH(std::string key, this->keys()){
+ ss << boost::format("%s: %s") % key % (*this)[key] << std::endl;
}
return ss.str();
}
@@ -137,9 +135,8 @@ static std::string trim(const std::string &in){
std::string device_addr_t::to_args_str(void) const{
std::string args_str;
- const device_addr_t &device_addr = *this;
- BOOST_FOREACH(const std::string &key, device_addr.keys()){
- args_str += key + pair_delim + device_addr[key] + arg_delim;
+ BOOST_FOREACH(const std::string &key, this->keys()){
+ args_str += key + pair_delim + (*this)[key] + arg_delim;
}
return args_str;
}
diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp
index 3c14e473e..5a992339b 100644
--- a/host/lib/usrp/dboard/db_basic_and_lf.cpp
+++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp
@@ -75,7 +75,7 @@ static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t const& args){
return dboard_base::sptr(new basic_tx(args, 32e6));
}
-UHD_STATIC_BLOCK(reg_dboards){
+UHD_STATIC_BLOCK(reg_basic_and_lf_dboards){
dboard_manager::register_dboard(0x0000, &make_basic_tx, "Basic TX");
dboard_manager::register_dboard(0x0001, &make_basic_rx, "Basic RX", list_of("ab")("a")("b"));
dboard_manager::register_dboard(0x000e, &make_lf_tx, "LF TX");
@@ -138,10 +138,6 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){
val = prop_names_t(1, ""); //vector of 1 empty string
return;
- case SUBDEV_PROP_ENABLED:
- val = true; //always enabled
- return;
-
case SUBDEV_PROP_QUADRATURE:
val = (get_subdev_name() == "ab"); //only quadrature in ab mode
return;
@@ -175,9 +171,6 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){
ASSERT_THROW(val.as<std::string>() == std::string(""));
return;
- case SUBDEV_PROP_ENABLED:
- return; // it wont do you much good, but you can set it
-
case SUBDEV_PROP_FREQ:
return; // it wont do you much good, but you can set it
@@ -240,10 +233,6 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){
val = prop_names_t(1, ""); //vector of 1 empty string
return;
- case SUBDEV_PROP_ENABLED:
- val = true; //always enabled
- return;
-
case SUBDEV_PROP_QUADRATURE:
val = true;
return;
@@ -277,9 +266,6 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){
ASSERT_THROW(val.as<std::string>() == std::string(""));
return;
- case SUBDEV_PROP_ENABLED:
- return; // it wont do you much good, but you can set it
-
case SUBDEV_PROP_FREQ:
return; // it wont do you much good, but you can set it
diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp
new file mode 100644
index 000000000..68fa51144
--- /dev/null
+++ b/host/lib/usrp/dboard/db_rfx.cpp
@@ -0,0 +1,319 @@
+//
+// 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 <http://www.gnu.org/licenses/>.
+//
+
+#include "adf4360_regs.hpp"
+#include <uhd/usrp/subdev_props.hpp>
+#include <uhd/types/ranges.hpp>
+#include <uhd/utils/assert.hpp>
+#include <uhd/utils/static.hpp>
+#include <uhd/usrp/dboard_base.hpp>
+#include <uhd/usrp/dboard_manager.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/format.hpp>
+
+using namespace uhd;
+using namespace uhd::usrp;
+using namespace boost::assign;
+
+/***********************************************************************
+ * The RFX series of dboards
+ **********************************************************************/
+class rfx_xcvr : public xcvr_dboard_base{
+public:
+ rfx_xcvr(ctor_args_t const& args, const freq_range_t &freq_range);
+ ~rfx_xcvr(void);
+
+ void rx_get(const wax::obj &key, wax::obj &val);
+ void rx_set(const wax::obj &key, const wax::obj &val);
+
+ void tx_get(const wax::obj &key, wax::obj &val);
+ void tx_set(const wax::obj &key, const wax::obj &val);
+
+private:
+ freq_range_t _freq_range;
+ double _lo_freq;
+ std::string _rx_ant;
+ float _rx_pga0_gain;
+ adf4360_regs_t _adf4360_regs;
+
+ void set_lo_freq(double freq);
+ void set_rx_ant(const std::string &ant);
+ void set_rx_pga0_gain(float gain);
+ void reload_adf4360_regs(void);
+};
+
+/***********************************************************************
+ * Register the RFX dboards
+ **********************************************************************/
+static dboard_base::sptr make_rfx_flex400(dboard_base::ctor_args_t const& args){
+ return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(400e6, 500e6)));
+}
+
+static dboard_base::sptr make_rfx_flex900(dboard_base::ctor_args_t const& args){
+ return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(750e6, 1050e6)));
+}
+
+static dboard_base::sptr make_rfx_flex1200(dboard_base::ctor_args_t const& args){
+ return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(1150e6, 1450e6)));
+}
+
+static dboard_base::sptr make_rfx_flex1800(dboard_base::ctor_args_t const& args){
+ return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(1500e6, 2100e6)));
+}
+
+static dboard_base::sptr make_rfx_flex2400(dboard_base::ctor_args_t const& args){
+ return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(2300e6, 2900e6)));
+}
+
+UHD_STATIC_BLOCK(reg_rfx_dboards){
+ dboard_manager::register_dboard(0x0024, &make_rfx_flex400, "Flex 400 Rx MIMO B");
+ dboard_manager::register_dboard(0x0028, &make_rfx_flex400, "Flex 400 Tx MIMO B");
+
+ dboard_manager::register_dboard(0x0025, &make_rfx_flex900, "Flex 900 Rx MIMO B");
+ dboard_manager::register_dboard(0x0029, &make_rfx_flex900, "Flex 900 Tx MIMO B");
+
+ dboard_manager::register_dboard(0x0026, &make_rfx_flex1200, "Flex 1200 Rx MIMO B");
+ dboard_manager::register_dboard(0x002a, &make_rfx_flex1200, "Flex 1200 Tx MIMO B");
+
+ dboard_manager::register_dboard(0x0034, &make_rfx_flex1800, "Flex 1800 Rx MIMO B");
+ dboard_manager::register_dboard(0x0035, &make_rfx_flex1800, "Flex 1800 Tx MIMO B");
+
+ dboard_manager::register_dboard(0x0027, &make_rfx_flex2400, "Flex 2400 Rx MIMO B");
+ dboard_manager::register_dboard(0x002b, &make_rfx_flex2400, "Flex 2400 Tx MIMO B");
+}
+
+/***********************************************************************
+ * Structors
+ **********************************************************************/
+rfx_xcvr::rfx_xcvr(
+ ctor_args_t const& args,
+ const freq_range_t &freq_range
+) : xcvr_dboard_base(args){
+ _freq_range = freq_range;
+ set_lo_freq((_freq_range.min + _freq_range.max)/2.0);
+ set_rx_ant("rx2");
+ set_rx_pga0_gain(0);
+}
+
+rfx_xcvr::~rfx_xcvr(void){
+ /* NOP */
+}
+
+/***********************************************************************
+ * Helper Methods
+ **********************************************************************/
+void rfx_xcvr::set_lo_freq(double freq){
+ /* NOP */
+ reload_adf4360_regs();
+}
+
+void rfx_xcvr::set_rx_ant(const std::string &ant){
+ /* NOP */
+}
+
+void rfx_xcvr::set_rx_pga0_gain(float gain){
+ /* NOP */
+}
+
+void rfx_xcvr::reload_adf4360_regs(void){
+ std::vector<adf4360_regs_t::addr_t> addrs = list_of
+ (adf4360_regs_t::ADDR_CONTROL)
+ (adf4360_regs_t::ADDR_NCOUNTER)
+ (adf4360_regs_t::ADDR_RCOUNTER)
+ ;
+ BOOST_FOREACH(adf4360_regs_t::addr_t addr, addrs){
+ this->get_interface()->write_spi(
+ dboard_interface::UNIT_TYPE_TX,
+ dboard_interface::spi_config_t::EDGE_RISE,
+ _adf4360_regs.get_reg(addr), 24
+ );
+ }
+}
+
+/***********************************************************************
+ * RX Get and Set
+ **********************************************************************/
+void rfx_xcvr::rx_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<subdev_prop_t>()){
+ case SUBDEV_PROP_NAME:
+ val = dboard_id::to_string(get_rx_id());
+ return;
+
+ case SUBDEV_PROP_OTHERS:
+ val = prop_names_t(); //empty
+ return;
+
+ case SUBDEV_PROP_GAIN:
+ val = _rx_pga0_gain;
+ return;
+
+ case SUBDEV_PROP_GAIN_RANGE:
+ val = gain_range_t(0, 45, float(0.022));
+ return;
+
+ case SUBDEV_PROP_GAIN_NAMES:
+ val = prop_names_t(1, "pga0");
+ return;
+
+ case SUBDEV_PROP_FREQ:
+ val = _lo_freq;
+ return;
+
+ case SUBDEV_PROP_FREQ_RANGE:
+ val = _freq_range;
+ return;
+
+ case SUBDEV_PROP_ANTENNA:
+ val = _rx_ant;
+ return;
+
+ case SUBDEV_PROP_ANTENNA_NAMES:{
+ prop_names_t ants = list_of("tx/rx")("rx2");
+ val = ants;
+ }
+ return;
+
+ case SUBDEV_PROP_QUADRATURE:
+ val = true;
+ return;
+
+ case SUBDEV_PROP_IQ_SWAPPED:
+ val = true;
+ return;
+
+ case SUBDEV_PROP_SPECTRUM_INVERTED:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_USE_LO_OFFSET:
+ val = false;
+ return;
+ }
+}
+
+void rfx_xcvr::rx_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 get request conditioned on the key
+ switch(key.as<subdev_prop_t>()){
+
+ case SUBDEV_PROP_GAIN:
+ ASSERT_THROW(name == "pga0");
+ set_rx_pga0_gain(val.as<float>());
+ return;
+
+ case SUBDEV_PROP_ANTENNA:
+ set_rx_ant(val.as<std::string>());
+ return;
+
+ default:
+ throw std::runtime_error(str(boost::format(
+ "Error: trying to set read-only property on %s subdev"
+ ) % dboard_id::to_string(get_rx_id())));
+ }
+}
+
+/***********************************************************************
+ * TX Get and Set
+ **********************************************************************/
+void rfx_xcvr::tx_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<subdev_prop_t>()){
+ case SUBDEV_PROP_NAME:
+ val = dboard_id::to_string(get_tx_id());
+ return;
+
+ case SUBDEV_PROP_OTHERS:
+ val = prop_names_t(); //empty
+ return;
+
+ case SUBDEV_PROP_GAIN:
+ val = float(0);
+ return;
+
+ case SUBDEV_PROP_GAIN_RANGE:
+ val = gain_range_t(0, 0, 0);
+ return;
+
+ case SUBDEV_PROP_GAIN_NAMES:
+ val = prop_names_t(); //empty
+ return;
+
+ case SUBDEV_PROP_FREQ:
+ val = _lo_freq;
+ return;
+
+ case SUBDEV_PROP_FREQ_RANGE:
+ val = _freq_range;
+ return;
+
+ case SUBDEV_PROP_ANTENNA:
+ val = std::string("tx/rx");
+ return;
+
+ case SUBDEV_PROP_ANTENNA_NAMES:
+ val = prop_names_t(1, "tx/rx");
+ return;
+
+ case SUBDEV_PROP_QUADRATURE:
+ val = true;
+ return;
+
+ case SUBDEV_PROP_IQ_SWAPPED:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_SPECTRUM_INVERTED:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_USE_LO_OFFSET:
+ val = true;
+ return;
+ }
+}
+
+void rfx_xcvr::tx_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 get request conditioned on the key
+ switch(key.as<subdev_prop_t>()){
+
+ case SUBDEV_PROP_GAIN:
+ //no gains to set!
+ return;
+
+ case SUBDEV_PROP_ANTENNA:
+ //its always set to tx/rx, so we only allow this value
+ ASSERT_THROW(val.as<std::string>() == "tx/rx");
+ return;
+
+ default:
+ throw std::runtime_error(str(boost::format(
+ "Error: trying to set read-only property on %s subdev"
+ ) % dboard_id::to_string(get_tx_id())));
+ }
+}
diff --git a/host/lib/usrp/dboard_interface.cpp b/host/lib/usrp/dboard_interface.cpp
deleted file mode 100644
index c40c9b398..000000000
--- a/host/lib/usrp/dboard_interface.cpp
+++ /dev/null
@@ -1,53 +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 <http://www.gnu.org/licenses/>.
-//
-
-#include <uhd/usrp/dboard_interface.hpp>
-
-using namespace uhd::usrp;
-
-dboard_interface::dboard_interface(void){
- /* NOP */
-}
-
-dboard_interface::~dboard_interface(void){
- /* NOP */
-}
-
-void dboard_interface::write_spi(
- spi_dev_t dev,
- spi_edge_t edge,
- const byte_vector_t &buf
-){
- transact_spi(dev, edge, buf, false); //dont readback
-}
-
-dboard_interface::byte_vector_t dboard_interface::read_spi(
- spi_dev_t dev,
- spi_edge_t edge,
- size_t num_bytes
-){
- byte_vector_t buf(num_bytes, 0x00); //dummy data
- return transact_spi(dev, edge, buf, true); //readback
-}
-
-dboard_interface::byte_vector_t dboard_interface::read_write_spi(
- spi_dev_t dev,
- spi_edge_t edge,
- const byte_vector_t &buf
-){
- return transact_spi(dev, edge, buf, true); //readback
-}
diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp
index d1515f2d5..3ac805421 100644
--- a/host/lib/usrp/usrp2/dboard_impl.cpp
+++ b/host/lib/usrp/usrp2/dboard_impl.cpp
@@ -22,6 +22,7 @@
#include <uhd/usrp/dboard_props.hpp>
#include <uhd/utils/assert.hpp>
#include <boost/format.hpp>
+#include <iostream>
using namespace uhd;
using namespace uhd::usrp;
diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp
index 6dd756420..eee7c087a 100644
--- a/host/lib/usrp/usrp2/dboard_interface.cpp
+++ b/host/lib/usrp/usrp2/dboard_interface.cpp
@@ -42,9 +42,35 @@ public:
double get_rx_clock_rate(void);
double get_tx_clock_rate(void);
+ void write_spi(
+ unit_type_t unit,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits
+ ){
+ transact_spi(unit, config, data, num_bits, false /*no rb*/);
+ }
+
+ boost::uint32_t read_spi(
+ unit_type_t unit,
+ const spi_config_t &config,
+ size_t num_bits
+ ){
+ return transact_spi(unit, config, 0, num_bits, true /*rb*/);
+ }
+
+ boost::uint32_t read_write_spi(
+ unit_type_t unit,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits
+ ){
+ return transact_spi(unit, config, data, num_bits, true /*rb*/);
+ }
+
private:
- byte_vector_t transact_spi(
- spi_dev_t, spi_edge_t, const byte_vector_t &, bool
+ boost::uint32_t transact_spi(
+ unit_type_t, const spi_config_t &, boost::uint32_t, size_t, bool
);
usrp2_impl *_impl;
@@ -136,17 +162,17 @@ void usrp2_dboard_interface::set_atr_reg(gpio_bank_t bank, atr_reg_t atr, boost:
* SPI
**********************************************************************/
/*!
- * Static function to convert a spi dev enum
- * to an over-the-wire value for the usrp2 control.
- * \param dev the dboard interface spi dev enum
+ * Static function to convert a unit type enum
+ * to an over-the-wire value for the spi device.
+ * \param unit the dboard interface unit type enum
* \return an over the wire representation
*/
-static boost::uint8_t spi_dev_to_otw(dboard_interface::spi_dev_t dev){
- switch(dev){
- case uhd::usrp::dboard_interface::SPI_DEV_TX: return SPI_SS_TX_DB;
- case uhd::usrp::dboard_interface::SPI_DEV_RX: return SPI_SS_RX_DB;
+static boost::uint8_t unit_to_otw_dev(dboard_interface::unit_type_t unit){
+ switch(unit){
+ case dboard_interface::UNIT_TYPE_TX: return SPI_SS_TX_DB;
+ case dboard_interface::UNIT_TYPE_RX: return SPI_SS_RX_DB;
}
- throw std::invalid_argument("unknown spi device type");
+ throw std::invalid_argument("unknown unit type type");
}
/*!
@@ -155,43 +181,36 @@ static boost::uint8_t spi_dev_to_otw(dboard_interface::spi_dev_t dev){
* \param edge the dboard interface spi edge enum
* \return an over the wire representation
*/
-static boost::uint8_t spi_edge_to_otw(dboard_interface::spi_edge_t edge){
+static boost::uint8_t spi_edge_to_otw(dboard_interface::spi_config_t::edge_t edge){
switch(edge){
- case uhd::usrp::dboard_interface::SPI_EDGE_RISE: return USRP2_CLK_EDGE_RISE;
- case uhd::usrp::dboard_interface::SPI_EDGE_FALL: return USRP2_CLK_EDGE_FALL;
+ case dboard_interface::spi_config_t::EDGE_RISE: return USRP2_CLK_EDGE_RISE;
+ case dboard_interface::spi_config_t::EDGE_FALL: return USRP2_CLK_EDGE_FALL;
}
throw std::invalid_argument("unknown spi edge type");
}
-dboard_interface::byte_vector_t usrp2_dboard_interface::transact_spi(
- spi_dev_t dev,
- spi_edge_t edge,
- const byte_vector_t &buf,
+boost::uint32_t usrp2_dboard_interface::transact_spi(
+ unit_type_t unit,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits,
bool readback
){
//setup the out data
usrp2_ctrl_data_t out_data;
out_data.id = htonl(USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO);
- out_data.data.spi_args.dev = spi_dev_to_otw(dev);
- out_data.data.spi_args.edge = spi_edge_to_otw(edge);
+ out_data.data.spi_args.dev = unit_to_otw_dev(unit);
+ out_data.data.spi_args.miso_edge = spi_edge_to_otw(config.miso_edge);
+ out_data.data.spi_args.mosi_edge = spi_edge_to_otw(config.mosi_edge);
out_data.data.spi_args.readback = (readback)? 1 : 0;
- out_data.data.spi_args.bytes = buf.size();
-
- //limitation of spi transaction size
- ASSERT_THROW(buf.size() <= sizeof(out_data.data.spi_args.data));
-
- //copy in the data
- std::copy(buf.begin(), buf.end(), out_data.data.spi_args.data);
+ out_data.data.spi_args.num_bits = num_bits;
+ out_data.data.spi_args.data = htonl(data);
//send and recv
usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data);
ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE);
- ASSERT_THROW(in_data.data.spi_args.bytes == buf.size());
- //copy out the data
- byte_vector_t result(buf.size());
- std::copy(in_data.data.spi_args.data, in_data.data.spi_args.data + buf.size(), result.begin());
- return result;
+ return ntohl(out_data.data.spi_args.data);
}
/***********************************************************************
@@ -245,19 +264,19 @@ dboard_interface::byte_vector_t usrp2_dboard_interface::read_i2c(int i2c_addr, s
* \param unit the dboard interface unit type enum
* \return an over the wire representation
*/
-static boost::uint8_t spi_dev_to_otw(dboard_interface::unit_type_t unit){
+static boost::uint8_t unit_to_otw(dboard_interface::unit_type_t unit){
switch(unit){
- case uhd::usrp::dboard_interface::UNIT_TYPE_TX: return USRP2_DIR_TX;
- case uhd::usrp::dboard_interface::UNIT_TYPE_RX: return USRP2_DIR_RX;
+ case dboard_interface::UNIT_TYPE_TX: return USRP2_DIR_TX;
+ case dboard_interface::UNIT_TYPE_RX: return USRP2_DIR_RX;
}
throw std::invalid_argument("unknown unit type type");
}
-void usrp2_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){
+void usrp2_dboard_interface::write_aux_dac(unit_type_t unit, int which, int value){
//setup the out data
usrp2_ctrl_data_t out_data;
out_data.id = htonl(USRP2_CTRL_ID_WRITE_THIS_TO_THE_AUX_DAC_BRO);
- out_data.data.aux_args.dir = spi_dev_to_otw(unit);
+ out_data.data.aux_args.dir = unit_to_otw(unit);
out_data.data.aux_args.which = which;
out_data.data.aux_args.value = htonl(value);
@@ -266,11 +285,11 @@ void usrp2_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, i
ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_DONE_WITH_THAT_AUX_DAC_DUDE);
}
-int usrp2_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){
+int usrp2_dboard_interface::read_aux_adc(unit_type_t unit, int which){
//setup the out data
usrp2_ctrl_data_t out_data;
out_data.id = htonl(USRP2_CTRL_ID_READ_FROM_THIS_AUX_ADC_BRO);
- out_data.data.aux_args.dir = spi_dev_to_otw(unit);
+ out_data.data.aux_args.dir = unit_to_otw(unit);
out_data.data.aux_args.which = which;
//send and recv
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index 019f3b931..b600a2a70 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -110,10 +110,11 @@ typedef struct{
} dboard_ids;
struct {
_SINS_ uint8_t dev;
- _SINS_ uint8_t edge;
+ _SINS_ uint8_t miso_edge;
+ _SINS_ uint8_t mosi_edge;
_SINS_ uint8_t readback;
- _SINS_ uint8_t bytes;
- _SINS_ uint8_t data[sizeof(_SINS_ uint32_t)];
+ _SINS_ uint32_t data;
+ _SINS_ uint8_t num_bits;
} spi_args;
struct {
_SINS_ uint8_t addr;
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index 62aca49ee..a760cbe3d 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -19,6 +19,7 @@
#include <uhd/transport/convert_types.hpp>
#include <boost/format.hpp>
#include <complex>
+#include <iostream>
using namespace uhd;
using namespace uhd::usrp;
@@ -70,7 +71,8 @@ void usrp2_impl::recv_raw(rx_metadata_t &metadata){
num_header_words32_out, //output
num_payload_words32_out, //output
num_packet_words32, //input
- packet_count_out //output
+ packet_count_out, //output
+ get_master_clock_freq()
);
}catch(const std::exception &e){
std::cerr << "bad vrt header: " << e.what() << std::endl;
@@ -124,7 +126,8 @@ size_t usrp2_impl::send(
num_header_words32, //output
num_samps, //input
num_packet_words32, //output
- packet_count //input
+ packet_count, //input
+ get_master_clock_freq()
);
boost::uint32_t *items = tx_mem + num_header_words32; //offset for data
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index 94ab88a6b..2fa2e5211 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -33,10 +33,6 @@ void usrp2_impl::mboard_init(void){
boost::bind(&usrp2_impl::mboard_get, this, _1, _2),
boost::bind(&usrp2_impl::mboard_set, this, _1, _2)
);
-
- //set the time on the usrp2 as close as possible to the system utc time
- boost::posix_time::ptime now(boost::posix_time::microsec_clock::universal_time());
- set_time_spec(time_spec_t(now, get_master_clock_freq()), true);
}
void usrp2_impl::init_clock_config(void){
@@ -75,7 +71,7 @@ void usrp2_impl::update_clock_config(void){
void usrp2_impl::set_time_spec(const time_spec_t &time_spec, bool now){
//set ticks and seconds
this->poke32(FR_TIME64_SECS, time_spec.secs);
- this->poke32(FR_TIME64_TICKS, time_spec.ticks);
+ this->poke32(FR_TIME64_TICKS, time_spec.get_ticks(get_master_clock_freq()));
//set the register to latch it all in
boost::uint32_t imm_flags = (now)? FRF_TIME64_LATCH_NOW : FRF_TIME64_LATCH_NEXT_PPS;
@@ -88,7 +84,7 @@ void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){
out_data.id = htonl(USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO);
out_data.data.stream_cmd.now = (stream_cmd.stream_now)? 1 : 0;
out_data.data.stream_cmd.secs = htonl(stream_cmd.time_spec.secs);
- out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.ticks);
+ out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.get_ticks(get_master_clock_freq()));
//set these to defaults, then change in the switch statement
out_data.data.stream_cmd.continuous = 0;