summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/octoclock/Makefile56
-rw-r--r--firmware/octoclock/OctoClock-io.h70
-rw-r--r--firmware/octoclock/OctoClock.c844
-rw-r--r--host/CMakeLists.txt2
-rw-r--r--host/README.txt1
-rw-r--r--host/cmake/Modules/FindORC.cmake36
-rw-r--r--host/cmake/Modules/FindUSB1.cmake15
-rw-r--r--host/cmake/Modules/NSIS.InstallOptions.ini.in37
-rw-r--r--host/cmake/Modules/NSIS.template.in955
-rw-r--r--host/cmake/Modules/UHDPackage.cmake9
-rw-r--r--host/cmake/Modules/UHDUnitTest.cmake110
-rwxr-xr-xhost/cmake/debian/postinst.in4
-rwxr-xr-xhost/cmake/redhat/post_install.in4
-rw-r--r--host/docs/build.rst2
-rw-r--r--host/docs/calibration.rst11
-rw-r--r--host/docs/coding.rst6
-rw-r--r--host/docs/dboards.rst17
-rw-r--r--host/docs/general.rst22
-rw-r--r--host/docs/identification.rst8
-rw-r--r--host/docs/images.rst4
-rw-r--r--host/docs/index.rst10
-rw-r--r--host/docs/sync.rst16
-rw-r--r--host/docs/transport.rst6
-rw-r--r--host/docs/usrp1.rst4
-rw-r--r--host/docs/usrp2.rst14
-rw-r--r--host/docs/usrp_b100.rst6
-rw-r--r--host/docs/usrp_e1x0.rst10
-rw-r--r--host/examples/benchmark_rate.cpp3
-rw-r--r--host/examples/latency_test.cpp2
-rw-r--r--host/examples/network_relay.cpp5
-rw-r--r--host/examples/rx_ascii_art_dft.cpp9
-rw-r--r--host/examples/rx_multi_samples.cpp2
-rw-r--r--host/examples/rx_samples_to_file.cpp2
-rw-r--r--host/examples/rx_samples_to_udp.cpp2
-rw-r--r--host/examples/rx_timed_samples.cpp2
-rw-r--r--host/examples/test_dboard_coercion.cpp2
-rw-r--r--host/examples/test_messages.cpp2
-rw-r--r--host/examples/test_pps_input.cpp2
-rw-r--r--host/examples/test_timed_commands.cpp2
-rw-r--r--host/examples/transport_hammer.cpp2
-rw-r--r--host/examples/tx_bursts.cpp2
-rw-r--r--host/examples/tx_samples_from_file.cpp2
-rw-r--r--host/examples/tx_timed_samples.cpp2
-rw-r--r--host/examples/tx_waveforms.cpp2
-rw-r--r--host/examples/txrx_loopback_to_file.cpp2
-rw-r--r--host/include/uhd/types/tune_request.hpp15
-rw-r--r--host/include/uhd/utils/paths.hpp4
-rw-r--r--host/include/uhd/version.hpp4
-rw-r--r--host/lib/convert/CMakeLists.txt9
-rw-r--r--host/lib/ic_reg_maps/CMakeLists.txt5
-rw-r--r--host/lib/ic_reg_maps/gen_max2870_regs.py133
-rw-r--r--host/lib/transport/CMakeLists.txt4
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp27
-rw-r--r--host/lib/transport/usb_zero_copy_wrapper.cpp8
-rw-r--r--host/lib/usrp/b100/b100_impl.cpp1
-rw-r--r--host/lib/usrp/b100/io_impl.cpp4
-rw-r--r--host/lib/usrp/common/recv_packet_demuxer.cpp30
-rw-r--r--host/lib/usrp/dboard/CMakeLists.txt1
-rw-r--r--host/lib/usrp/dboard/db_cbx.cpp212
-rw-r--r--host/lib/usrp/dboard/db_sbx_common.cpp23
-rw-r--r--host/lib/usrp/dboard/db_sbx_common.hpp25
-rw-r--r--host/lib/usrp/gps_ctrl.cpp144
-rw-r--r--host/lib/usrp/multi_usrp.cpp8
-rw-r--r--host/lib/utils/CMakeLists.txt8
-rw-r--r--host/lib/utils/images.cpp2
-rw-r--r--host/lib/utils/paths.cpp8
-rw-r--r--host/tests/CMakeLists.txt12
-rw-r--r--host/utils/fx2_init_eeprom.cpp8
-rw-r--r--host/utils/query_gpsdo_sensors.cpp3
-rw-r--r--host/utils/uhd_cal_rx_iq_balance.cpp5
-rw-r--r--host/utils/uhd_cal_tx_dc_offset.cpp4
-rw-r--r--host/utils/uhd_cal_tx_iq_balance.cpp5
-rw-r--r--host/utils/uhd_find_devices.cpp7
-rw-r--r--host/utils/uhd_usrp_probe.cpp9
-rw-r--r--host/utils/usrp_burn_db_eeprom.cpp4
-rw-r--r--host/utils/usrp_burn_mb_eeprom.cpp6
-rw-r--r--images/Makefile24
77 files changed, 2902 insertions, 186 deletions
diff --git a/firmware/octoclock/Makefile b/firmware/octoclock/Makefile
new file mode 100644
index 000000000..6ef662bc6
--- /dev/null
+++ b/firmware/octoclock/Makefile
@@ -0,0 +1,56 @@
+#
+# Copyright 2009 Ettus Research LLC
+#
+
+##################################################
+# Compiler
+##################################################
+CC = avr-gcc
+OBJCOPY = avr-objcopy
+STRIP = avr-strip
+OBJDUMP = avr-objdump
+SREC = srec_cat
+#CFLAGS = -O2 -std=gnu99 -fshort-enums -pedantic-errors -Wall -Werror \
+# -Wstrict-prototypes -Wmissing-prototypes -Wcast-align -Wshadow
+CFLAGS = -std=gnu99 -O2
+
+#-D IO_DEBUG
+
+##################################################
+# Files
+##################################################
+HDRS = OctoClock-io.h
+SRCS = OctoClock.c
+TARGET = octoclock_fw
+
+##################################################
+# Device
+##################################################
+MMCU = atmega128
+PROGRAMMER = avrisp2
+PORT = usb
+AVRDUDE = avrdude -p $(MMCU) -c $(PROGRAMMER) -P $(PORT)
+
+##################################################
+# Global Targets
+##################################################
+all: $(TARGET).hex
+
+clean:
+ $(RM) *.o *.elf *.hex
+
+install: all
+ $(AVRDUDE) -U flash:w:$(TARGET).hex:i
+
+##################################################
+# Dependency Targets
+##################################################
+
+$(TARGET).hex: $(TARGET).elf
+ $(OBJCOPY) -O ihex $< $@
+
+$(TARGET).elf: $(SRCS:.c=.o)
+ $(CC) -mmcu=$(MMCU) $^ -o $@
+
+%.o: %.c $(HDRS) Makefile
+ $(CC) -mmcu=$(MMCU) -c $< -o $@ $(CFLAGS)
diff --git a/firmware/octoclock/OctoClock-io.h b/firmware/octoclock/OctoClock-io.h
new file mode 100644
index 000000000..88cd1499b
--- /dev/null
+++ b/firmware/octoclock/OctoClock-io.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2009 Ettus Research LLC
+ */
+
+#ifndef IO_H
+#define IO_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+
+typedef int8_t i8;
+typedef int16_t i16;
+typedef int32_t i32;
+typedef int64_t i64;
+
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+
+typedef float f32;
+typedef double f64;
+typedef long double f128;
+
+typedef int error_indicator; /* A type for functions, usually... */
+typedef unsigned int boolean; /* "natural" type */
+
+typedef char c8; /* 8-bit character */
+typedef unsigned char uc8; /* 8-bit character, unsigned*/
+/* it is sometimes useful to*/
+/* make the distinction*/
+
+#ifdef FALSE
+#undef FALSE
+#endif
+#define FALSE (0)
+
+#ifdef TRUE
+#undef TRUE
+#endif
+#define TRUE (!FALSE)
+
+#define is :{
+#define esac break;}
+
+
+// This other crap can be deleted, below, between the #if 0 and #endif inclusive
+
+#if 0
+
+#define IO_PX(port, pin) ((uint8_t)(((port - 'A') << 4) + pin))
+#define IO_PA(pin) IO_PX('A', pin)
+#define IO_PB(pin) IO_PX('B', pin)
+#define IO_PC(pin) IO_PX('C', pin)
+#define IO_PD(pin) IO_PX('D', pin)
+
+typedef const uint8_t io_pin_t;
+
+void io_output_pin(io_pin_t pin);
+void io_input_pin(io_pin_t pin);
+void io_set_pin(io_pin_t pin);
+void io_clear_pin(io_pin_t pin);
+bool io_test_pin(io_pin_t pin);
+
+#endif //if 0
+
+#endif /* IO_H */
diff --git a/firmware/octoclock/OctoClock.c b/firmware/octoclock/OctoClock.c
new file mode 100644
index 000000000..07397601d
--- /dev/null
+++ b/firmware/octoclock/OctoClock.c
@@ -0,0 +1,844 @@
+/*
+ * OctoClock.c
+ *
+ * V1.00 -- May 2013
+ *
+ *
+ * V1.03 -- Correct the switch to be UP for Internal and DOWN for External
+ * This means that the bat handle "points at" (sort of) the lower-left LED, which
+ * is the "STATUS" LED, which gets lit up when the external 10 MHz is present
+ * The "10 MHz Signal Detect" code accepts a very wide range of "10 MHz" signals
+ * 23 April 2013
+ *
+ *
+ * V1.02 -- Make LEDs consistent with Chassis - Top LED is INTERNAL; middle is EXTERNAL; bottom is STATUS
+ *
+ * STATUS is ON if the 10 MHz external input is present. 19 April 2013
+ *
+ *
+ * V1.01: Modify TI chip initialization to be in differentail mode
+ * which allows 10 MHz input down to 0.1 Volts according to the datasheet.
+ *
+ *
+ * New Version that supports CLOCK board Version 1.0
+ *
+ * Author: Michael@Cheponis.Com with code borrowed liberally from
+ * previous AVR projects
+ *
+ */
+
+/*
+ * Copyright 2013 Ettus Research LLC
+ */
+
+
+
+
+
+
+/* CLKSEL0 = 1 SUT1..0 is 11 CKOPT = 0 CKSEL3..1 is 111 => big output swing, long time to start up */
+/*
+
+NOT in M103 compatibility mode, no WDT, CKOPT full rail-to-rail xtal osc, 16K CK (16K clock cycles),
+additional delay 65ms for Crystal Oscillator, slowly rising power
+
+Very conservative settings; if lower power osc required, change CKOPT to '1' (UNPROGRAMMED) or, if you will,
+CKOPT = [ ]
+
+
+
+M103C = [ ]
+WDTON = [ ]
+OCDEN = [ ]
+JTAGEN = [X]
+SPIEN = [X]
+EESAVE = [ ]
+BOOTSZ = 4096W_F000
+BOOTRST = [ ]
+CKOPT = [X]
+BODLEVEL = 2V7
+BODEN = [ ]
+SUT_CKSEL = EXTHIFXTALRES_16KCK_64MS
+
+EXTENDED = 0xFF (valid)
+HIGH = 0x89 (valid)
+LOW = 0xFF (valid)
+
+
+*/
+
+// No interrupts are required
+
+#include "OctoClock-io.h"
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+
+#ifdef On
+#undef On
+#endif
+
+#ifdef Off
+#undef OFf
+#endif
+
+#define Off (0)
+#define On (!Off)
+
+
+// Important for the Serial Port, not used at the moment
+#define FOSC (7372800)
+#define BAUD (115200)
+
+#define MYUBRR FOSC/16/BAUD-1
+
+
+#define wait() for(u16 u=14000; u; u--) asm("nop");
+
+
+
+enum LEDs {Top,Middle,Bottom}; // Top is 0, Mid is 1, and Bottom is 2
+
+void
+led(enum LEDs which, int turn_it_on){
+
+ u8 LED = 0x20 << which; // selects the proper bit
+
+ if(turn_it_on)
+ PORTC |= LED;
+ else
+ PORTC &= ~LED;
+
+}
+
+
+enum TI_Input_10_MHz {Primary_GPS, Secondary_Ext};
+
+void setup_TI_CDCE18005(enum TI_Input_10_MHz);
+
+
+
+
+/*****************************************************************************************
+
+ SPI routines
+
+******************************************************************************************/
+
+
+
+/* All macros evaluate to compile-time constants */
+
+/* *** helper macros * * */
+
+/* turn a numeric literal into a hex constant
+ (avoids problems with leading zeros)
+ 8-bit constants max value 0x11111111, always fits in unsigned long
+ */
+ #define HEX__(n) 0x##n##LU
+
+/* 8-bit conversion function */
+ #define B8__(x) ((x&0x0000000FLU)?1:0) \
+ +((x&0x000000F0LU)?2:0) \
+ +((x&0x00000F00LU)?4:0) \
+ +((x&0x0000F000LU)?8:0) \
+ +((x&0x000F0000LU)?16:0) \
+ +((x&0x00F00000LU)?32:0) \
+ +((x&0x0F000000LU)?64:0) \
+ +((x&0xF0000000LU)?128:0)
+
+// Damn, that is SERIOUS magic ... ;-) Yes, I know how it works
+// but it's pretty cool....
+
+
+/* *** user macros *** */
+
+/* for upto 8-bit binary constants */
+ #define Bits_8(d) ((unsigned char)B8__(HEX__(d)))
+
+/* for upto 16-bit binary constants, MSB first */
+ #define Bits_16(dmsb,dlsb) (((unsigned short)Bits_8(dmsb)<<8) \
+ + Bits_8(dlsb))
+
+/* for upto 32-bit binary constants, MSB first */
+ #define Bits_32(dmsb,db2,db3,dlsb) (((unsigned long)Bits_8(dmsb)<<24) \
+ + ((unsigned long)Bits_8(db2)<<16) \
+ + ((unsigned long)Bits_8(db3)<<8) \
+ + Bits_8(dlsb))
+
+/* Sample usage:
+ Bits_8(01010101) = 85
+ Bits_16(10101010,01010101) = 43605
+ Bits_32(10000000,11111111,10101010,01010101) = 2164238933
+ */
+
+
+
+enum CDCE18005 {Reg0, Reg1, Reg2, Reg3, Reg4, Reg5, Reg6, Reg7, Reg8_Status_Control,
+ Read_Command=0xE, RAM_EEPROM_Unlock=0x1F, RAM_EEPROM_Lock=0x3f}
+ TI_CDCE18005;
+
+// Table of 32-bit constants to be written to the TI chip's registers.
+
+// Damn, inconsistent data sheet! Special settigns see p35 of TI datasheet
+
+// For the GPS's 10 MHz output
+u32 table_Pri_Ref[] = {
+
+ Bits_32(1,01010100,0,0), // Reg 0
+ Bits_32(1,01010100,0,0), // Outputs LVCMOS Positive&Negative Active - Non-inverted
+ Bits_32(1,01010100,0,0),
+ Bits_32(1,01010100,0,0),
+ Bits_32(1,01010100,0,0), // All have output divide ratio to be 1; Aux Output is OFF
+
+ Bits_32(0,0,1001,11010100), // Reg 5 LVCMOS in; p31 of TI datasheet
+
+ Bits_32(1,0,0010000,0), // Reg 6 // SCAS863A – NOVEMBER 2008 – REVISED JUNE 2011
+
+ Bits_32(1,01000000,0,0), // Reg 7
+ // 76543210
+ Bits_32(0,0,1,10000000) // Reg8 Status/Control
+};
+
+
+// Looks like it's doing the correct thing re: SPI interface
+// This is *definitely* AC coupled. I removed those resistors to +3.3 and ground
+// signal looked no different with differential measurement. Added 240+470 to
+// center tap of secondary side to bias up to approx 1.2V for proper LVDS
+//
+// For the External 10 MHz input LVDS with external termination -- Effectively DC coupled
+
+u32 table_Sec_Ref[] = {
+ Bits_32(0001,01010100,0,100000),// Reg 0 -- use Secondary Reference for all channels
+ Bits_32(0001,01010100,0,100000),// Outputs LVCMOS Positive&Negative Active - Non-inverted
+ Bits_32(0001,01010100,0,100000),
+ Bits_32(0001,01010100,0,100000),
+ Bits_32(0001,01010100,0,100000),
+
+// Bits_32(0,0,00001000,10010111), // Reg 5 LVDS with External Termination p32 of TI datasheet
+// Bits_32(0,0,00001000,11010111), // Reg 5 LVDS with INTERNAL Termination p32 of TI datasheet
+
+// May 2013 -- Turn OFF the LVDS Safe Mode, as it supposedly causes input thresholds to be increased.
+
+// Bits_32(0,0,1001,10011011), // Reg 5, try again. Pretty soon, try new board...
+
+ Bits_32(0,0,1,10011011), // Reg 5, Failsafe OFF b5.11 = 0
+
+
+// Bits_32(0,0,1001,11011011), // Reg 5, try again. Pretty soon, try new board...
+ // Try with DC input termination; bit 6 is a "1" 2013 March
+ // Seems to not work correctly.
+
+
+// Bits_32(1,0,0000000,0), // Reg 6; note that 6.12 must be 1 for LVDS w/External Termination, 0 int
+// Bits_32(1,0,0000000,0), // Reg 6; try Internal and DC coupling
+ Bits_32(1,0,10000,0), // Reg 6; try again
+
+ Bits_32(1,01000000,0,0),
+ Bits_32(0,0,1,10000000) // Reg8 Status/Control
+};
+
+//; Table 19 conflicts with Tables 5 thru 9 - in how LVCMOS outputs are defined
+// extra error in Table 9, for bits 24 and 25
+//
+// Could combine these into just table[][] with 1st subscript being 0 or 1 for Primary or Secondary
+// Maybe want to to that.
+
+int table_size = sizeof (table_Pri_Ref) / sizeof(u32);
+//int table_size = 1; // Testing read and write of Register 0 -- don't want excess SPI transactions
+//NOTE!!! Still need to shift left by 4 and OR in register, as defined in TI_CDCE18005 enum, above.
+
+
+enum Levels {Lo, Hi};
+
+#define CLK (PA0) // Shift by 0 bits (PA.0)
+#define CE_ (PA1) // Is really the "Chip Disable" signal, as Hi disables SPI
+#define MOSI (PA2)
+#define MISO (PA3)
+#define PD_ (PA4)
+#define SYNC_ (PA5)
+
+void
+set_bit(u8 bit_number, enum Levels bit_value){
+
+ if(bit_value == Hi)
+ PORTA |= 1<<bit_number;
+ else
+ PORTA &= ~ (1<<bit_number);
+}
+
+
+bool
+get_bit(u8 bit_number){
+ asm("nop");
+
+ u8 portA = PINA; // Maybe something is strange they way PORTA is read?
+// USART_Transmit( hex_table [0xf & (portA >> 4)], Control );
+// USART_Transmit( hex_table [0xf & portA], Control );
+// USART_Transmit(CR, Control); USART_Transmit(LF,Control);
+
+ return (portA & 1<< bit_number) > 0 ? TRUE : FALSE;
+ //return (portA & 8) != 0; // It's always MISO, so nail it for the moment
+}
+
+
+void
+send_SPI(u32 bits){
+// Send 32 bits to TI chip, LSB first.
+// Don't worry about reading any bits back at this
+// time, although for production, may want to do that
+// as an error-check / integrity check.
+
+/*
+#define CLK (PA0) // Shift by 0 bits (PA.0)
+#define CE_ (PA1) // Is really the "Chip Disable" signal, as Hi disables SPI
+#define MOSI (PA2)
+#define MISO (PA3)
+#define PD_ (PA4)
+#define SYNC_ (PA5)
+*/
+
+//Basically, when the clock is low, one can set MOSI to anything, as it's ignored.
+
+ set_bit(CE_, Lo); // Start SPI transaction with TI chip
+
+ for (u8 i=0; i<32; i++){ // Foreach bit we need to send
+ set_bit(MOSI, ((bits & (1UL<<i)) ? Hi : Lo) ); // LSB first
+ asm("nop"); // Need a little more delay before L->H on clock; (REALLY?)
+ set_bit(CLK, Hi);
+ set_bit(CLK, Lo); // Pulse the clock to clock in the bit
+ }
+// USART_Transmit(CR, Control); USART_Transmit(LF,Control);
+ //set_bit(MOSI, Lo); // Not needed, but keeps all bits zeros except /CE when idle
+ set_bit(CE_, Hi); // OK, transaction is over
+// USART_Transmit(CR, Control); USART_Transmit(LF,Control);
+}
+
+// Takes about 7.6 ms to init all regs (as seen on scope)
+// There is a very interesting phenomenon that is occurring --- The bit-to-bit time
+// at the beginning of transmission is 15 usec. However, as the number of bits
+// shifted to the left increases (as i increases in the for() loop )
+// the time between bits elongates. It's about 37 usec between bits
+// 30 and 31 (the last 2 bits). It's kinda cool, because it's easy to
+// know when the new word begins because the clock pulses will be
+// closer together.
+
+// See if it checks: (15+37)/2 = 26 usec between average bits
+// 32 bits * 9 words * 26 usec = 7.49 ms --- but have to add
+// in the little bit of time that CE_ goes high; so 7.6 ms
+// is a very reasonable number. (Assumes linear increase in
+// time as the number of shifts goes up, which seems to
+// work OK here.)
+//
+// Of course, using a table instead of doing those shifts all the
+// time would fix this; but it (should not) doesn't matter for this
+// SPI interface.
+//
+// So far, the first word looks good, and the beginning of writing
+// Register 1 also looks good.
+//
+
+
+
+
+
+
+// enum TI_Input_10_MHz {Primary_GPS, Secondary_Ext};
+
+void
+reset_TI_CDCE18005(){
+// First, reset the chip. Or, if you will, pull /SYNC low then high
+set_bit(CE_, Hi);
+set_bit(PD_, Lo);
+wait(); // This should put the EEPROM bits into the RAM -- we don't care, but should init the chip
+
+set_bit(PD_, Hi); // Out of Power Down state
+wait();
+
+set_bit(SYNC_, Lo);
+wait();
+set_bit(SYNC_, Hi);
+
+wait();
+// Now, by gosh, that darn chip ought to be fully enabled!
+}
+
+void
+setup_TI_CDCE18005(enum TI_Input_10_MHz which_input){
+ // Send the table of data to init the clock distribution chip. Uses SPI.
+ u32 temp;
+
+ //reset_TI_CDCE18005(); // This REALLY should not be necessary
+
+ if(which_input == Primary_GPS){
+
+ for(u8 i=0; i<table_size; i++){
+ temp = table_Pri_Ref[i]<<4;
+ temp |= i;
+ // print_u32(temp); // Debug *mac* -- correct
+ send_SPI(temp); // Make sure the register's address is in the LSBs
+ }
+ }
+ else { // is Secondary_Ext -- External 10 MHz input from SMA connector
+
+ for(u8 i=0; i<table_size; i++){
+ temp = table_Sec_Ref[i]<<4;
+ temp |= i;
+ send_SPI(temp); // Make sure the register's address is in the LSBs
+ }
+ }
+}
+u32
+receive_SPI(){
+ u32 bits;
+
+ bits = 0;
+
+ set_bit(CE_, Hi); // Make sure we're inactive
+ set_bit(CLK, Lo); // and clk line is inactive, too
+ set_bit(MOSI,Lo); // Make our bit output zero, for good measure
+
+
+ set_bit(CE_, Lo); // Start SPI transaction with TI chip; MOSI is don't care
+
+ for (u8 i=0; i<32; i++){ // Foreach bit we need to get
+ bits >>= 1; // get ready for next bit - NOTE: Only do this if we REALLY are putting in another bit
+ set_bit(CLK, Hi); // CPU is so slow, it easily meets setup & hold times
+ // 76543210
+ if( get_bit(MISO) ) bits |= 0x80000000; // because we receive the LSB first
+ set_bit(CLK, Lo); // Pulse the clock to clock in the bit
+ }
+ set_bit(CE_, Hi); // OK, transaction is over
+
+ return (u32)(bits >> 4); // Ditch the lower 4 bits, which only contain the address
+}
+
+u32
+get_TI_CDCE18005(enum CDCE18005 which_register){
+ u32 get_reg_value;
+
+ get_reg_value = 0;
+ get_reg_value = (0xf0 & which_register << 4) | Read_Command;
+ send_SPI(get_reg_value); // This tells the TI chip to send us the reg. value requested
+ return receive_SPI();
+};
+
+
+bool
+check_TI_CDCE18005(enum TI_Input_10_MHz which_input, enum CDCE18005 which_register) {
+ // USART_Transmit(CR, Control); USART_Transmit(LF,Control); //reset_TI_CDCE18005();
+ if(which_input == Primary_GPS){
+ u32 read_value = get_TI_CDCE18005(which_register);
+ return read_value == table_Pri_Ref[which_register];
+ }
+ else {
+ u32 read_value = get_TI_CDCE18005(which_register);
+ return read_value == table_Sec_Ref[which_register];
+ }
+};
+// This could obviously be done more elegantly to share more code; but this is
+// simple and easy to understand
+
+
+
+
+
+
+
+
+void
+Setup_Atmel_IO_Ports(){
+
+
+/////////////////////////////////////////////////////////////////////////////
+/*
+ * PORT A
+ *
+ *pin# Sig Our Functional Name
+ *
+ * p51 PA0 CLK_CDCE to U205 pin 24 -- L-->H edge latches MOSI and MISO in CDCE18005
+ * p50 PA1 CE_CDCE Low = Chip Enabled for SPI comm to U205 pin 25
+ * p49 PA2 MOSI_CDCE Goes to CDCE18005 - U205 pin 23
+ * p48 PA3 MISO_CDCE Input Comes from U205 pin 22
+ * p47 PA4 PD_CDCE Low = Chip is in Power-Down state; is Hi for normal operation U205 pin 12
+ * p46 PA5 SYNC_CDCE Low = Chip is sync'd with interal dividers; Hi for normal operation U205 pin 14
+ * p45 PA6 PPS_SEL Low --> PPS_EXT selected; Hi -> PPS_GPS selected; to U203 pin 1
+ * p44 PA7 gps_lock Input Comes from M9107 - U206 pin 3
+ *
+ */
+
+// Bit #: 76543210
+PORTA = Bits_8(00110010); // /pd_cdcd, /sync_code, /ce need to be 1 (disabled) to start
+DDRA = 1<<DDA6 | 1<<DDA5 | 1<<DDA4 | 1<<DDA2 | 1<<DDA1 | 1<<DDA0; //// all bits are outputs, except PA7 (gps_lock) and PA3 (MISO_CDCE) are inputs
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+/*
+ * Port B
+ *
+ *pin# Sig Our Functional Name
+ *
+ * p10 PB0 Ethernet /SEN
+ * p11 PB1 Ethernet SCLK
+ * p12 PB2 Ethernet MOSI
+ * p13 PB3 Ethernet MISO
+ * p14 PB4 Not connected, set as output with value 0
+ * p15 PB5 Ethernet /RESET -- Set to HI for normal use, weak input
+ * p16 PB6 Ethernet /WOL --- Wake on LAN -- set, weak input
+ * p17 PB7 Not connected, set as output with value 0
+ *
+ */
+
+
+ PORTB = Bits_8(01100001); // Initial Value is all zeros
+ DDRB = 1<<DDB2 | 1<<DDB4 | 1<<DDB7; // MOSI is an output; the Not Connected pins are also outputs
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+/*
+ * Port C
+ *
+ *pin# Sig Our Functional Name
+ *
+ * p34 PC0 Not connected, set as output with value 0
+ * p35 PC1 Reference Select Switch INPUT
+ * p36 PC2 Not connected, set as output with value 0
+ * p37 PC3 Not connected, set as output with value 0
+ * p38 PC4 Not connected, set as output with value 0
+ * p40 PC5 "Top LED" of D103 3-stack of green LEDs
+ * p41 PC6 "Middle LED"
+ * p43 PC7 "Bottom LED"
+ *
+ */
+PORTC = 0; // Initial Value is all zeros
+DDRC = ~( 1<<DDC1 ); // All bits are outputs, except PC1. including the 5 Not Connected bits
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+/*
+ * Port D
+ *
+ *pin# Sig Our Functional Name
+ *
+ * p25 PD0 Ethernet /INT input
+ * p26 PD1 GPS NMEA bit, output
+ * p27 PD2 GPS Serial Out (RXD; INT1) INPUT
+ * p28 PD3 GPS Serial In (TXD) OUTPUT
+ * p29 PD4 GPS Present, INPUT hi = Present
+ * p30 PD5 Not connected, set as output with value 0
+ * p31 PD6 Not connected, set as output with value 0
+ * p32 PD7 Not connected, set as output with value 0
+ *
+ */
+PORTD = 0; // Initial Value is all zeros
+DDRD = 1<<DDD1 | 1<<DDD3;
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+/*
+ * Port E
+ *
+ *pin# Sig Dir Our Functional Name
+ *
+ * p2 PE0 In avr_rxd (Also MOSI [PDI] when used for SPI programming of the chip)
+ * p3 PE1 Out avr_txd (Also MISO [PDO] when used for SPI programming of the chip)
+ * p4 PE2 In avr_cts
+ * p5 PE3 Out avr_rts DUE TO MOD, make this an input, too (as we go direct GPSDO to FPGA via level translators)
+ * p6 PE4 In PPS_GPS
+ * p7 PE5 In PPS_EXT_n
+ * p8 PE6 In Not Connected
+ * p9 PE7 In Not Connected
+ *
+ */
+PORTE = 0;
+DDRE = 1<<DDE1; // make outputs, set to zero. PE1 is usart0 TXD
+
+
+/////////////////////////////////////////////////////////////////////////////
+/*
+ * Port F
+ *
+ * Split into 2 nibbles; goes to Amp/Filter board to select ENABLE and two bits to select band
+ * one bit per nibble is not connected.
+ *
+ * pin Sig Dir Our Functional Name
+ * num
+ *
+ * p61 PF0 Out J117 pin 3 (J117 pins 1 and 2 are GND)
+ * p60 PF1 Out J117 pin 4
+ * p59 PF2 Out J117 pin 5
+ * p58 PF3 Out J117 pin 6
+ * p57 PF4 Out J118 pin 3 (J118 pins 1 and 2 are GND)
+ * p56 PF5 Out J118 pin 4
+ * p55 PF6 Out J118 pin 5
+ * p54 PF7 Out J118 pin 6
+ *
+ */
+
+
+PORTF = 0; // Initial Value is all zeros; be sure ENABLE bits are active high!!!!
+DDRF = 0xff; // All bits are outputs
+
+
+
+
+led(Middle,On);
+setup_TI_CDCE18005(Primary_GPS); // 10 MHz from Internal Source
+
+led(Top,On);
+PORTA |= (1<<PA6); // PPS from Internal source
+
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+//enum TI_Input_10_MHz {Primary_GPS, Secondary_Ext};
+
+//setup_TI_CDCE18005(enum TI_Input_10_MHz);
+
+bool Global_GPS_Present = (bool)FALSE;
+bool Global_Ext_Ref_Is_Present = (bool)FALSE; // NOT PRESENT unless proven so...
+// This was initially global becasue it was to be set in an interrupt routine
+// But it turned out interrupts were not needed. But kept this in because
+// although it's a Global, it is the only one, and it makes it easier to
+// go back and use interrupts if absolutely necessary. It could be
+// removed and replaced with some local variable that gets passed
+// around, but, really, it seems OK to me like this.
+
+
+
+void
+LEDs_Off(){
+ led(Top,Off);
+ led(Middle,Off);
+ led(Bottom,Off);
+}
+
+
+void
+Force_Internal(){
+ // led(Middle,On);
+ led(Top,On);
+ led(Middle,Off);
+ led(Bottom,On);
+
+ setup_TI_CDCE18005(Primary_GPS);
+
+ // Set PPS to Primary (1) n.b.: "1" in general means "Internal" for all such signals
+ PORTA |= (1<<PA6); // PPS from Internal source
+}
+
+
+void
+Force_External(){
+ // led(Middle, Off);
+ led(Top, Off);
+ led(Middle, On);
+ led(Bottom, On);
+
+ setup_TI_CDCE18005(Secondary_Ext);
+
+ // Set PPS to External (0
+ PORTA &= ~(1<<PA6); // PPS from External source
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+void
+Prefer_Internal(){
+
+ if(Global_GPS_Present)
+ Force_Internal();
+ else if(Global_Ext_Ref_Is_Present)
+ Force_External();
+ else
+ LEDs_Off();
+}
+
+
+
+
+
+void
+Prefer_External(){ // IF EXTERNAL IS OK, then do this stuff
+ // if external is NOT OK, then force Internal
+ if(Global_Ext_Ref_Is_Present)
+ Force_External();
+ else if(Global_GPS_Present)
+ Force_Internal();
+ else
+ LEDs_Off();
+}
+
+
+
+// Turns out, we don't need interrupts
+
+
+#if 0
+//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+u8 Global_Tick_Counter = (u8)0;
+u8 Global_Ext_Ref_Detect_Counter = (u8)0;
+
+// External Reference Detect interrupt; nominally at 610 Hz (10 MHz / 2**14 )
+ISR ( _VECTOR(1)){
+ asm("cli"); // Global Interrupt Disable --- enable with SEI if desired later
+
+
+ Global_Ext_Ref_Detect_Counter++ ; // We reset this elsewhere
+
+ asm("sei"); // Global Interrupt Enable
+}
+
+
+// Timer 0 Overflow Handler
+ISR ( _VECTOR(16)){
+ static u8 led_state = Off;
+
+ asm("cli"); // Global Interrupt Disable --- enable with SEI if desired later
+
+ led_state = (led_state ? Off : On);
+
+ asm("sei"); // Global Interrupt Enable
+}
+
+//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+
+void
+Setup_Atmel_Interrupts(){
+ // Timer 0 is all we need -- but simplest if both Timer 0 AND IRQ1 (ext_ref_detect 610 Hz signal) also
+ // Nah, don't need this...
+}
+
+#endif
+
+
+
+bool
+Check_What_Is_Present(){
+
+ Global_GPS_Present = (PIND & (1<<DDD4)) != 0; // See if +5 scaled to 3.3 from GPSDO is there
+
+
+ volatile u8 portE = PINE;
+ volatile u8 prev, now;
+
+ prev = ( portE & (1 << DDE7) ? 1 : 0); // Get PREVIOUS state of the input
+ for(u16 c=1; c; c++){
+ portE = PINE;
+ now = ( portE & (1 << DDE7) ? 1 : 0);
+ if(prev != now){
+ Global_Ext_Ref_Is_Present = (bool)TRUE;
+ return (bool)TRUE;
+ }
+ }
+ // Else, if it didn't wiggle in that time, then it didn't wiggle
+ // So ext. is NOT present
+
+ Global_Ext_Ref_Is_Present = (bool)FALSE;
+ return (bool)FALSE;
+
+}
+
+
+bool
+get_Switch_State(){
+ u8 portC = PINC;
+
+ // return (bool)(portC & (1<<DDC1) ? On : Off);
+ return (bool)(portC & (1<<DDC1) ? Off : On); // UP is prefer internal,
+ // DOWN is prefer external
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// M A I N //
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+
+int
+main(void){
+
+ bool Old_Switch_State, Current_Switch_State, Old_Global_Ext_Ref_Is_Present = FALSE;
+
+
+
+ asm("cli"); // Global Interrupt Disable --- enable with SEI if desired later
+
+ Setup_Atmel_IO_Ports();
+
+ // Setup_Atmel_Interrupts();
+
+
+ /*
+ * DO THIS FOREVER:
+ *
+ *
+ * get_switch_state
+ *
+ * if SWITCH_CHANGED:
+ *
+ *
+ * if PREFER_INTERNAL:
+ * if INTERNAL_PRESENT do_internal
+ * else if EXTERNAL_PRESENT do_external
+ * else LEDs OFF
+ *
+ * if PREFER_EXTERNAL:
+ * if EXTERNAL_PRESENT do_external
+ * else if INTERNAL_PRESENT do_internal
+ * else LEDs OFF
+ *
+ */
+
+
+
+
+ Old_Switch_State = ! get_Switch_State();
+
+ // Because down below, we use this to get state swap...
+ // So we arbitrarily set the PREVIOUS state to be the "other" state
+ // so that, below, we trigger what happens when the switch changes
+ // This first "change" is therefore artificial to keep the logic, below, cleaner
+
+ while(TRUE) {
+ Check_What_Is_Present(); // Set "Global_Ext_Ref_Is_Present" and "Global_GPS_Present"
+
+ // Off means "Prefer External" -- DOWN
+ // On means "Prefer Internal" -- UP
+
+ Current_Switch_State = get_Switch_State();
+
+ if( (Current_Switch_State != Old_Switch_State) ||
+ (Global_Ext_Ref_Is_Present != Old_Global_Ext_Ref_Is_Present) ) {
+
+ Old_Switch_State = Current_Switch_State;
+ Old_Global_Ext_Ref_Is_Present = Global_Ext_Ref_Is_Present;
+
+ if(Current_Switch_State == On)
+ Prefer_Internal();
+ else
+ Prefer_External();
+ } // if() checking for different switch status
+
+
+ } // WHILE() loop
+
+
+} /*end "main" of Program 'OctoClock.c */
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt
index cdcfc6529..3b2ce4297 100644
--- a/host/CMakeLists.txt
+++ b/host/CMakeLists.txt
@@ -52,7 +52,7 @@ SET(LIBRARY_DIR lib${LIB_SUFFIX})
SET(INCLUDE_DIR include)
SET(PKG_DATA_DIR share/uhd)
IF(NOT DEFINED PKG_LIB_DIR)
- SET(PKG_LIB_DIR ${PKG_DATA_DIR})
+ SET(PKG_LIB_DIR ${LIBRARY_DIR}/uhd)
ENDIF()
SET(PKG_DOC_DIR share/doc/uhd)
SET(PKG_MAN_DIR share/man/man1)
diff --git a/host/README.txt b/host/README.txt
index 473e0ab17..d678a1f0a 100644
--- a/host/README.txt
+++ b/host/README.txt
@@ -29,6 +29,7 @@ DBSRX2
TVRX
TVRX2
SBX
+CBX
###############################################
# Documentation
diff --git a/host/cmake/Modules/FindORC.cmake b/host/cmake/Modules/FindORC.cmake
new file mode 100644
index 000000000..0d9fc9ca1
--- /dev/null
+++ b/host/cmake/Modules/FindORC.cmake
@@ -0,0 +1,36 @@
+########################################################################
+# Find the library for ORC development files
+########################################################################
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(PC_ORC "orc-0.4")
+PKG_CHECK_MODULES(PC_ORC_V4_11 "orc-0.4 > 0.4.11")
+
+#we are using the pkg config as a version check
+#if we have pkg config, the right version must be found
+#the alternative is that no pkg config orc is found
+if (PC_ORC_V4_11_FOUND OR (NOT PC_ORC_FOUND AND NOT PC_ORC_V4_11_FOUND))
+
+FIND_PATH(
+ ORC_INCLUDE_DIRS
+ NAMES orc/orc.h
+ HINTS $ENV{ORC_DIR}/include/orc-0.4
+ ${PC_ORC_INCLUDEDIR}
+ PATHS /usr/local/include/orc-0.4
+ /usr/include/orc-0.4
+)
+
+FIND_LIBRARY(
+ ORC_LIBRARIES
+ NAMES orc-0.4
+ HINTS $ENV{ORC_DIR}/lib
+ ${PC_ORC_LIBDIR}
+ PATHS /usr/local/lib
+ /usr/lib
+)
+
+endif() #both PC ORC FOUND
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ORC DEFAULT_MSG ORC_LIBRARIES ORC_INCLUDE_DIRS)
+MARK_AS_ADVANCED(ORC_LIBRARIES ORC_INCLUDE_DIRS)
diff --git a/host/cmake/Modules/FindUSB1.cmake b/host/cmake/Modules/FindUSB1.cmake
index 21005344b..a1ab4ca90 100644
--- a/host/cmake/Modules/FindUSB1.cmake
+++ b/host/cmake/Modules/FindUSB1.cmake
@@ -32,7 +32,20 @@ FIND_LIBRARY(LIBUSB_LIBRARIES
PATHS /usr/local/lib /usr/lib /opt/local/lib
)
+enable_language(C) #needs C support for check below
+include(CheckFunctionExists)
+if(LIBUSB_INCLUDE_DIRS)
+ set(CMAKE_REQUIRED_INCLUDES ${LIBUSB_INCLUDE_DIRS})
+endif()
+if(LIBUSB_LIBRARIES)
+ set(CMAKE_REQUIRED_LIBRARIES ${LIBUSB_LIBRARIES})
+endif()
+CHECK_FUNCTION_EXISTS("libusb_handle_events_timeout_completed" HAVE_LIBUSB_HANDLE_EVENTS_TIMEOUT_COMPLETED)
+
+if(HAVE_LIBUSB_HANDLE_EVENTS_TIMEOUT_COMPLETED)
+ list(APPEND LIBUSB_DEFINITIONS "HAVE_LIBUSB_HANDLE_EVENTS_TIMEOUT_COMPLETED=1")
+endif(HAVE_LIBUSB_HANDLE_EVENTS_TIMEOUT_COMPLETED)
+
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIRS)
MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIRS LIBUSB_LIBRARIES)
-
diff --git a/host/cmake/Modules/NSIS.InstallOptions.ini.in b/host/cmake/Modules/NSIS.InstallOptions.ini.in
new file mode 100644
index 000000000..969a3ae52
--- /dev/null
+++ b/host/cmake/Modules/NSIS.InstallOptions.ini.in
@@ -0,0 +1,37 @@
+[Settings]
+NumFields=4
+
+[Field 1]
+Type=label
+Text=By default the USRP Hardware Driver (UHD) does not add its directory to the system PATH.
+Left=0
+Right=-1
+Top=0
+Bottom=20
+
+[Field 2]
+Type=radiobutton
+Text=Do not add @CPACK_PACKAGE_NAME@ to the system PATH
+Left=0
+Right=-1
+Top=30
+Bottom=40
+State=1
+
+[Field 3]
+Type=radiobutton
+Text=Add @CPACK_PACKAGE_NAME@ to the system PATH for all users
+Left=0
+Right=-1
+Top=40
+Bottom=50
+State=0
+
+[Field 4]
+Type=radiobutton
+Text=Add @CPACK_PACKAGE_NAME@ to the system PATH for current user
+Left=0
+Right=-1
+Top=50
+Bottom=60
+State=0
diff --git a/host/cmake/Modules/NSIS.template.in b/host/cmake/Modules/NSIS.template.in
new file mode 100644
index 000000000..3ab55d907
--- /dev/null
+++ b/host/cmake/Modules/NSIS.template.in
@@ -0,0 +1,955 @@
+; CPack install script designed for a nmake build
+
+;--------------------------------
+; You must define these values
+
+ !define VERSION "@CPACK_PACKAGE_VERSION@"
+ !define PATCH "@CPACK_PACKAGE_VERSION_PATCH@"
+ !define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@"
+
+;--------------------------------
+;Variables
+
+ Var MUI_TEMP
+ Var STARTMENU_FOLDER
+ Var SV_ALLUSERS
+ Var START_MENU
+ Var DO_NOT_ADD_TO_PATH
+ Var ADD_TO_PATH_ALL_USERS
+ Var ADD_TO_PATH_CURRENT_USER
+ Var INSTALL_DESKTOP
+ Var IS_DEFAULT_INSTALLDIR
+;--------------------------------
+;Include Modern UI
+
+ !include "MUI.nsh"
+
+ ;Default installation folder
+ InstallDir "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
+
+;--------------------------------
+;General
+
+ ;Name and file
+ Name "USRP Hardware Driver"
+ OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"
+
+ ;Set compression
+ SetCompressor @CPACK_NSIS_COMPRESSOR@
+
+@CPACK_NSIS_DEFINES@
+
+ !include Sections.nsh
+
+;--- Component support macros: ---
+; The code for the add/remove functionality is from:
+; http://nsis.sourceforge.net/Add/Remove_Functionality
+; It has been modified slightly and extended to provide
+; inter-component dependencies.
+Var AR_SecFlags
+Var AR_RegFlags
+@CPACK_NSIS_SECTION_SELECTED_VARS@
+
+; Loads the "selected" flag for the section named SecName into the
+; variable VarName.
+!macro LoadSectionSelectedIntoVar SecName VarName
+ SectionGetFlags ${${SecName}} $${VarName}
+ IntOp $${VarName} $${VarName} & ${SF_SELECTED} ;Turn off all other bits
+!macroend
+
+; Loads the value of a variable... can we get around this?
+!macro LoadVar VarName
+ IntOp $R0 0 + $${VarName}
+!macroend
+
+; Sets the value of a variable
+!macro StoreVar VarName IntValue
+ IntOp $${VarName} 0 + ${IntValue}
+!macroend
+
+!macro InitSection SecName
+ ; This macro reads component installed flag from the registry and
+ ;changes checked state of the section on the components page.
+ ;Input: section index constant name specified in Section command.
+
+ ClearErrors
+ ;Reading component status from registry
+ ReadRegDWORD $AR_RegFlags HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" "Installed"
+ IfErrors "default_${SecName}"
+ ;Status will stay default if registry value not found
+ ;(component was never installed)
+ IntOp $AR_RegFlags $AR_RegFlags & ${SF_SELECTED} ;Turn off all other bits
+ SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading default section flags
+ IntOp $AR_SecFlags $AR_SecFlags & 0xFFFE ;Turn lowest (enabled) bit off
+ IntOp $AR_SecFlags $AR_RegFlags | $AR_SecFlags ;Change lowest bit
+
+ ; Note whether this component was installed before
+ !insertmacro StoreVar ${SecName}_was_installed $AR_RegFlags
+ IntOp $R0 $AR_RegFlags & $AR_RegFlags
+
+ ;Writing modified flags
+ SectionSetFlags ${${SecName}} $AR_SecFlags
+
+ "default_${SecName}:"
+ !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected
+!macroend
+
+!macro FinishSection SecName
+ ; This macro reads section flag set by user and removes the section
+ ;if it is not selected.
+ ;Then it writes component installed flag to registry
+ ;Input: section index constant name specified in Section command.
+
+ SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading section flags
+ ;Checking lowest bit:
+ IntOp $AR_SecFlags $AR_SecFlags & ${SF_SELECTED}
+ IntCmp $AR_SecFlags 1 "leave_${SecName}"
+ ;Section is not selected:
+ ;Calling Section uninstall macro and writing zero installed flag
+ !insertmacro "Remove_${${SecName}}"
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \
+ "Installed" 0
+ Goto "exit_${SecName}"
+
+ "leave_${SecName}:"
+ ;Section is selected:
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \
+ "Installed" 1
+
+ "exit_${SecName}:"
+!macroend
+
+!macro RemoveSection SecName
+ ; This macro is used to call section's Remove_... macro
+ ;from the uninstaller.
+ ;Input: section index constant name specified in Section command.
+
+ !insertmacro "Remove_${${SecName}}"
+!macroend
+
+; Determine whether the selection of SecName changed
+!macro MaybeSelectionChanged SecName
+ !insertmacro LoadVar ${SecName}_selected
+ SectionGetFlags ${${SecName}} $R1
+ IntOp $R1 $R1 & ${SF_SELECTED} ;Turn off all other bits
+
+ ; See if the status has changed:
+ IntCmp $R0 $R1 "${SecName}_unchanged"
+ !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected
+
+ IntCmp $R1 ${SF_SELECTED} "${SecName}_was_selected"
+ !insertmacro "Deselect_required_by_${SecName}"
+ goto "${SecName}_unchanged"
+
+ "${SecName}_was_selected:"
+ !insertmacro "Select_${SecName}_depends"
+
+ "${SecName}_unchanged:"
+!macroend
+;--- End of Add/Remove macros ---
+
+;--------------------------------
+;Interface Settings
+
+ !define MUI_HEADERIMAGE
+ !define MUI_ABORTWARNING
+
+;--------------------------------
+; path functions
+
+!verbose 3
+!include "WinMessages.NSH"
+!verbose 4
+
+;----------------------------------------
+; based upon a script of "Written by KiCHiK 2003-01-18 05:57:02"
+;----------------------------------------
+!verbose 3
+!include "WinMessages.NSH"
+!verbose 4
+;====================================================
+; get_NT_environment
+; Returns: the selected environment
+; Output : head of the stack
+;====================================================
+!macro select_NT_profile UN
+Function ${UN}select_NT_profile
+ StrCmp $ADD_TO_PATH_ALL_USERS "1" 0 environment_single
+ DetailPrint "Selected environment for all users"
+ Push "all"
+ Return
+ environment_single:
+ DetailPrint "Selected environment for current user only."
+ Push "current"
+ Return
+FunctionEnd
+!macroend
+!insertmacro select_NT_profile ""
+!insertmacro select_NT_profile "un."
+;----------------------------------------------------
+!define NT_current_env 'HKCU "Environment"'
+!define NT_all_env 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
+
+!ifndef WriteEnvStr_RegKey
+ !ifdef ALL_USERS
+ !define WriteEnvStr_RegKey \
+ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
+ !else
+ !define WriteEnvStr_RegKey 'HKCU "Environment"'
+ !endif
+!endif
+
+; AddToPath - Adds the given dir to the search path.
+; Input - head of the stack
+; Note - Win9x systems requires reboot
+
+Function AddToPath
+ Exch $0
+ Push $1
+ Push $2
+ Push $3
+
+ # don't add if the path doesn't exist
+ IfFileExists "$0\*.*" "" AddToPath_done
+
+ ReadEnvStr $1 PATH
+ ; if the path is too long for a NSIS variable NSIS will return a 0
+ ; length string. If we find that, then warn and skip any path
+ ; modification as it will trash the existing path.
+ StrLen $2 $1
+ IntCmp $2 0 CheckPathLength_ShowPathWarning CheckPathLength_Done CheckPathLength_Done
+ CheckPathLength_ShowPathWarning:
+ Messagebox MB_OK|MB_ICONEXCLAMATION "Warning! PATH too long installer unable to modify PATH!"
+ Goto AddToPath_done
+ CheckPathLength_Done:
+ Push "$1;"
+ Push "$0;"
+ Call StrStr
+ Pop $2
+ StrCmp $2 "" "" AddToPath_done
+ Push "$1;"
+ Push "$0\;"
+ Call StrStr
+ Pop $2
+ StrCmp $2 "" "" AddToPath_done
+ GetFullPathName /SHORT $3 $0
+ Push "$1;"
+ Push "$3;"
+ Call StrStr
+ Pop $2
+ StrCmp $2 "" "" AddToPath_done
+ Push "$1;"
+ Push "$3\;"
+ Call StrStr
+ Pop $2
+ StrCmp $2 "" "" AddToPath_done
+
+ Call IsNT
+ Pop $1
+ StrCmp $1 1 AddToPath_NT
+ ; Not on NT
+ StrCpy $1 $WINDIR 2
+ FileOpen $1 "$1\autoexec.bat" a
+ FileSeek $1 -1 END
+ FileReadByte $1 $2
+ IntCmp $2 26 0 +2 +2 # DOS EOF
+ FileSeek $1 -1 END # write over EOF
+ FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n"
+ FileClose $1
+ SetRebootFlag true
+ Goto AddToPath_done
+
+ AddToPath_NT:
+ StrCmp $ADD_TO_PATH_ALL_USERS "1" ReadAllKey
+ ReadRegStr $1 ${NT_current_env} "PATH"
+ Goto DoTrim
+ ReadAllKey:
+ ReadRegStr $1 ${NT_all_env} "PATH"
+ DoTrim:
+ StrCmp $1 "" AddToPath_NTdoIt
+ Push $1
+ Call Trim
+ Pop $1
+ StrCpy $0 "$1;$0"
+ AddToPath_NTdoIt:
+ StrCmp $ADD_TO_PATH_ALL_USERS "1" WriteAllKey
+ WriteRegExpandStr ${NT_current_env} "PATH" $0
+ Goto DoSend
+ WriteAllKey:
+ WriteRegExpandStr ${NT_all_env} "PATH" $0
+ DoSend:
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+
+ AddToPath_done:
+ Pop $3
+ Pop $2
+ Pop $1
+ Pop $0
+FunctionEnd
+
+
+; RemoveFromPath - Remove a given dir from the path
+; Input: head of the stack
+
+Function un.RemoveFromPath
+ Exch $0
+ Push $1
+ Push $2
+ Push $3
+ Push $4
+ Push $5
+ Push $6
+
+ IntFmt $6 "%c" 26 # DOS EOF
+
+ Call un.IsNT
+ Pop $1
+ StrCmp $1 1 unRemoveFromPath_NT
+ ; Not on NT
+ StrCpy $1 $WINDIR 2
+ FileOpen $1 "$1\autoexec.bat" r
+ GetTempFileName $4
+ FileOpen $2 $4 w
+ GetFullPathName /SHORT $0 $0
+ StrCpy $0 "SET PATH=%PATH%;$0"
+ Goto unRemoveFromPath_dosLoop
+
+ unRemoveFromPath_dosLoop:
+ FileRead $1 $3
+ StrCpy $5 $3 1 -1 # read last char
+ StrCmp $5 $6 0 +2 # if DOS EOF
+ StrCpy $3 $3 -1 # remove DOS EOF so we can compare
+ StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine
+ StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine
+ StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine
+ StrCmp $3 "" unRemoveFromPath_dosLoopEnd
+ FileWrite $2 $3
+ Goto unRemoveFromPath_dosLoop
+ unRemoveFromPath_dosLoopRemoveLine:
+ SetRebootFlag true
+ Goto unRemoveFromPath_dosLoop
+
+ unRemoveFromPath_dosLoopEnd:
+ FileClose $2
+ FileClose $1
+ StrCpy $1 $WINDIR 2
+ Delete "$1\autoexec.bat"
+ CopyFiles /SILENT $4 "$1\autoexec.bat"
+ Delete $4
+ Goto unRemoveFromPath_done
+
+ unRemoveFromPath_NT:
+ StrCmp $ADD_TO_PATH_ALL_USERS "1" unReadAllKey
+ ReadRegStr $1 ${NT_current_env} "PATH"
+ Goto unDoTrim
+ unReadAllKey:
+ ReadRegStr $1 ${NT_all_env} "PATH"
+ unDoTrim:
+ StrCpy $5 $1 1 -1 # copy last char
+ StrCmp $5 ";" +2 # if last char != ;
+ StrCpy $1 "$1;" # append ;
+ Push $1
+ Push "$0;"
+ Call un.StrStr ; Find `$0;` in $1
+ Pop $2 ; pos of our dir
+ StrCmp $2 "" unRemoveFromPath_done
+ ; else, it is in path
+ # $0 - path to add
+ # $1 - path var
+ StrLen $3 "$0;"
+ StrLen $4 $2
+ StrCpy $5 $1 -$4 # $5 is now the part before the path to remove
+ StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove
+ StrCpy $3 $5$6
+
+ StrCpy $5 $3 1 -1 # copy last char
+ StrCmp $5 ";" 0 +2 # if last char == ;
+ StrCpy $3 $3 -1 # remove last char
+
+ StrCmp $ADD_TO_PATH_ALL_USERS "1" unWriteAllKey
+ WriteRegExpandStr ${NT_current_env} "PATH" $3
+ Goto unDoSend
+ unWriteAllKey:
+ WriteRegExpandStr ${NT_all_env} "PATH" $3
+ unDoSend:
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+
+ unRemoveFromPath_done:
+ Pop $6
+ Pop $5
+ Pop $4
+ Pop $3
+ Pop $2
+ Pop $1
+ Pop $0
+FunctionEnd
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Uninstall sutff
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+###########################################
+# Utility Functions #
+###########################################
+
+;====================================================
+; IsNT - Returns 1 if the current system is NT, 0
+; otherwise.
+; Output: head of the stack
+;====================================================
+; IsNT
+; no input
+; output, top of the stack = 1 if NT or 0 if not
+;
+; Usage:
+; Call IsNT
+; Pop $R0
+; ($R0 at this point is 1 or 0)
+
+!macro IsNT un
+Function ${un}IsNT
+ Push $0
+ ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
+ StrCmp $0 "" 0 IsNT_yes
+ ; we are not NT.
+ Pop $0
+ Push 0
+ Return
+
+ IsNT_yes:
+ ; NT!!!
+ Pop $0
+ Push 1
+FunctionEnd
+!macroend
+!insertmacro IsNT ""
+!insertmacro IsNT "un."
+
+; StrStr
+; input, top of stack = string to search for
+; top of stack-1 = string to search in
+; output, top of stack (replaces with the portion of the string remaining)
+; modifies no other variables.
+;
+; Usage:
+; Push "this is a long ass string"
+; Push "ass"
+; Call StrStr
+; Pop $R0
+; ($R0 at this point is "ass string")
+
+!macro StrStr un
+Function ${un}StrStr
+Exch $R1 ; st=haystack,old$R1, $R1=needle
+ Exch ; st=old$R1,haystack
+ Exch $R2 ; st=old$R1,old$R2, $R2=haystack
+ Push $R3
+ Push $R4
+ Push $R5
+ StrLen $R3 $R1
+ StrCpy $R4 0
+ ; $R1=needle
+ ; $R2=haystack
+ ; $R3=len(needle)
+ ; $R4=cnt
+ ; $R5=tmp
+ loop:
+ StrCpy $R5 $R2 $R3 $R4
+ StrCmp $R5 $R1 done
+ StrCmp $R5 "" done
+ IntOp $R4 $R4 + 1
+ Goto loop
+done:
+ StrCpy $R1 $R2 "" $R4
+ Pop $R5
+ Pop $R4
+ Pop $R3
+ Pop $R2
+ Exch $R1
+FunctionEnd
+!macroend
+!insertmacro StrStr ""
+!insertmacro StrStr "un."
+
+Function Trim ; Added by Pelaca
+ Exch $R1
+ Push $R2
+Loop:
+ StrCpy $R2 "$R1" 1 -1
+ StrCmp "$R2" " " RTrim
+ StrCmp "$R2" "$\n" RTrim
+ StrCmp "$R2" "$\r" RTrim
+ StrCmp "$R2" ";" RTrim
+ GoTo Done
+RTrim:
+ StrCpy $R1 "$R1" -1
+ Goto Loop
+Done:
+ Pop $R2
+ Exch $R1
+FunctionEnd
+
+Function ConditionalAddToRegisty
+ Pop $0
+ Pop $1
+ StrCmp "$0" "" ConditionalAddToRegisty_EmptyString
+ WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \
+ "$1" "$0"
+ ;MessageBox MB_OK "Set Registry: '$1' to '$0'"
+ DetailPrint "Set install registry entry: '$1' to '$0'"
+ ConditionalAddToRegisty_EmptyString:
+FunctionEnd
+
+;--------------------------------
+
+!ifdef CPACK_USES_DOWNLOAD
+Function DownloadFile
+ IfFileExists $INSTDIR\* +2
+ CreateDirectory $INSTDIR
+ Pop $0
+
+ ; Skip if already downloaded
+ IfFileExists $INSTDIR\$0 0 +2
+ Return
+
+ StrCpy $1 "@CPACK_DOWNLOAD_SITE@"
+
+ try_again:
+ NSISdl::download "$1/$0" "$INSTDIR\$0"
+
+ Pop $1
+ StrCmp $1 "success" success
+ StrCmp $1 "Cancelled" cancel
+ MessageBox MB_OK "Download failed: $1"
+ cancel:
+ Return
+ success:
+FunctionEnd
+!endif
+
+;--------------------------------
+; Installation types
+@CPACK_NSIS_INSTALLATION_TYPES@
+
+;--------------------------------
+; Component sections
+@CPACK_NSIS_COMPONENT_SECTIONS@
+
+;--------------------------------
+; Define some macro setting for the gui
+@CPACK_NSIS_INSTALLER_MUI_ICON_CODE@
+@CPACK_NSIS_INSTALLER_ICON_CODE@
+@CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@
+@CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE@
+
+;--------------------------------
+;Pages
+ !insertmacro MUI_PAGE_WELCOME
+
+ !insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@"
+ Page custom InstallOptionsPage
+ !insertmacro MUI_PAGE_DIRECTORY
+
+ ;Start Menu Folder Page Configuration
+ !define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX"
+ !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
+ !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
+ !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER
+
+ @CPACK_NSIS_PAGE_COMPONENTS@
+
+ !insertmacro MUI_PAGE_INSTFILES
+ !insertmacro MUI_PAGE_FINISH
+
+ !insertmacro MUI_UNPAGE_CONFIRM
+ !insertmacro MUI_UNPAGE_INSTFILES
+
+;--------------------------------
+;Languages
+
+ !insertmacro MUI_LANGUAGE "English" ;first language is the default language
+ !insertmacro MUI_LANGUAGE "Albanian"
+ !insertmacro MUI_LANGUAGE "Arabic"
+ !insertmacro MUI_LANGUAGE "Basque"
+ !insertmacro MUI_LANGUAGE "Belarusian"
+ !insertmacro MUI_LANGUAGE "Bosnian"
+ !insertmacro MUI_LANGUAGE "Breton"
+ !insertmacro MUI_LANGUAGE "Bulgarian"
+ !insertmacro MUI_LANGUAGE "Croatian"
+ !insertmacro MUI_LANGUAGE "Czech"
+ !insertmacro MUI_LANGUAGE "Danish"
+ !insertmacro MUI_LANGUAGE "Dutch"
+ !insertmacro MUI_LANGUAGE "Estonian"
+ !insertmacro MUI_LANGUAGE "Farsi"
+ !insertmacro MUI_LANGUAGE "Finnish"
+ !insertmacro MUI_LANGUAGE "French"
+ !insertmacro MUI_LANGUAGE "German"
+ !insertmacro MUI_LANGUAGE "Greek"
+ !insertmacro MUI_LANGUAGE "Hebrew"
+ !insertmacro MUI_LANGUAGE "Hungarian"
+ !insertmacro MUI_LANGUAGE "Icelandic"
+ !insertmacro MUI_LANGUAGE "Indonesian"
+ !insertmacro MUI_LANGUAGE "Irish"
+ !insertmacro MUI_LANGUAGE "Italian"
+ !insertmacro MUI_LANGUAGE "Japanese"
+ !insertmacro MUI_LANGUAGE "Korean"
+ !insertmacro MUI_LANGUAGE "Kurdish"
+ !insertmacro MUI_LANGUAGE "Latvian"
+ !insertmacro MUI_LANGUAGE "Lithuanian"
+ !insertmacro MUI_LANGUAGE "Luxembourgish"
+ !insertmacro MUI_LANGUAGE "Macedonian"
+ !insertmacro MUI_LANGUAGE "Malay"
+ !insertmacro MUI_LANGUAGE "Mongolian"
+ !insertmacro MUI_LANGUAGE "Norwegian"
+ !insertmacro MUI_LANGUAGE "Polish"
+ !insertmacro MUI_LANGUAGE "Portuguese"
+ !insertmacro MUI_LANGUAGE "PortugueseBR"
+ !insertmacro MUI_LANGUAGE "Romanian"
+ !insertmacro MUI_LANGUAGE "Russian"
+ !insertmacro MUI_LANGUAGE "Serbian"
+ !insertmacro MUI_LANGUAGE "SerbianLatin"
+ !insertmacro MUI_LANGUAGE "SimpChinese"
+ !insertmacro MUI_LANGUAGE "Slovak"
+ !insertmacro MUI_LANGUAGE "Slovenian"
+ !insertmacro MUI_LANGUAGE "Spanish"
+ !insertmacro MUI_LANGUAGE "Swedish"
+ !insertmacro MUI_LANGUAGE "Thai"
+ !insertmacro MUI_LANGUAGE "TradChinese"
+ !insertmacro MUI_LANGUAGE "Turkish"
+ !insertmacro MUI_LANGUAGE "Ukrainian"
+ !insertmacro MUI_LANGUAGE "Welsh"
+
+
+;--------------------------------
+;Reserve Files
+
+ ;These files should be inserted before other files in the data block
+ ;Keep these lines before any File command
+ ;Only for solid compression (by default, solid compression is enabled for BZIP2 and LZMA)
+
+ ReserveFile "NSIS.InstallOptions.ini"
+ !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
+
+;--------------------------------
+;Installer Sections
+
+Section "-Core installation"
+ ;Use the entire tree produced by the INSTALL target. Keep the
+ ;list of directories here in sync with the RMDir commands below.
+ SetOutPath "$INSTDIR"
+ @CPACK_NSIS_FULL_INSTALL@
+
+ ;Store installation folder
+ WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR
+
+ ;Create uninstaller
+ WriteUninstaller "$INSTDIR\Uninstall.exe"
+ Push "DisplayName"
+ Push "@CPACK_NSIS_DISPLAY_NAME@"
+ Call ConditionalAddToRegisty
+ Push "DisplayVersion"
+ Push "@CPACK_PACKAGE_VERSION@"
+ Call ConditionalAddToRegisty
+ Push "Publisher"
+ Push "@CPACK_PACKAGE_VENDOR@"
+ Call ConditionalAddToRegisty
+ Push "UninstallString"
+ Push "$INSTDIR\Uninstall.exe"
+ Call ConditionalAddToRegisty
+ Push "NoRepair"
+ Push "1"
+ Call ConditionalAddToRegisty
+
+ !ifdef CPACK_NSIS_ADD_REMOVE
+ ;Create add/remove functionality
+ Push "ModifyPath"
+ Push "$INSTDIR\AddRemove.exe"
+ Call ConditionalAddToRegisty
+ !else
+ Push "NoModify"
+ Push "1"
+ Call ConditionalAddToRegisty
+ !endif
+
+ ; Optional registration
+ Push "DisplayIcon"
+ Push "$INSTDIR\@CPACK_NSIS_INSTALLED_ICON_NAME@"
+ Call ConditionalAddToRegisty
+ Push "HelpLink"
+ Push "@CPACK_NSIS_HELP_LINK@"
+ Call ConditionalAddToRegisty
+ Push "URLInfoAbout"
+ Push "@CPACK_NSIS_URL_INFO_ABOUT@"
+ Call ConditionalAddToRegisty
+ Push "Contact"
+ Push "@CPACK_NSIS_CONTACT@"
+ Call ConditionalAddToRegisty
+ !insertmacro MUI_INSTALLOPTIONS_READ $INSTALL_DESKTOP "NSIS.InstallOptions.ini" "Field 5" "State"
+ !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+
+ ;Create shortcuts
+ CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
+@CPACK_NSIS_CREATE_ICONS@
+@CPACK_NSIS_CREATE_ICONS_EXTRA@
+ CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
+ CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\USRP2 Card Burner.lnk" "$INSTDIR\lib\uhd\utils\usrp2_card_burner_gui.py" "" "" "" SW_SHOWMINIMIZED
+ CreateShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\USRP-N2XX Net Burner.lnk" "$INSTDIR\lib\uhd\utils\usrp_n2xx_net_burner_gui.py" "" "" "" SW_SHOWMINIMIZED
+ CreateShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\UHD Images Downloader.lnk" "$INSTDIR\lib\uhd\utils\uhd_images_downloader.py"
+
+ ;Read a value from an InstallOptions INI file
+ !insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State"
+ !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_ALL_USERS "NSIS.InstallOptions.ini" "Field 3" "State"
+ !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_CURRENT_USER "NSIS.InstallOptions.ini" "Field 4" "State"
+
+ ; Write special uninstall registry entries
+ Push "StartMenu"
+ Push "$STARTMENU_FOLDER"
+ Call ConditionalAddToRegisty
+ Push "DoNotAddToPath"
+ Push "$DO_NOT_ADD_TO_PATH"
+ Call ConditionalAddToRegisty
+ Push "AddToPathAllUsers"
+ Push "$ADD_TO_PATH_ALL_USERS"
+ Call ConditionalAddToRegisty
+ Push "AddToPathCurrentUser"
+ Push "$ADD_TO_PATH_CURRENT_USER"
+ Call ConditionalAddToRegisty
+ Push "InstallToDesktop"
+ Push "$INSTALL_DESKTOP"
+ Call ConditionalAddToRegisty
+
+ !insertmacro MUI_STARTMENU_WRITE_END
+
+@CPACK_NSIS_EXTRA_INSTALL_COMMANDS@
+
+SectionEnd
+
+Section "-Add to path"
+ Push $INSTDIR\bin
+ StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 doNotAddToPath
+ StrCmp $DO_NOT_ADD_TO_PATH "1" doNotAddToPath 0
+ Call AddToPath
+ doNotAddToPath:
+SectionEnd
+
+;--------------------------------
+; Create custom pages
+Function InstallOptionsPage
+ !insertmacro MUI_HEADER_TEXT "Install Options" "Choose options for installing the USRP Hardware Driver (UHD)"
+ !insertmacro MUI_INSTALLOPTIONS_DISPLAY "NSIS.InstallOptions.ini"
+
+FunctionEnd
+
+;--------------------------------
+; determine admin versus local install
+Function un.onInit
+
+ ClearErrors
+ UserInfo::GetName
+ IfErrors noLM
+ Pop $0
+ UserInfo::GetAccountType
+ Pop $1
+ StrCmp $1 "Admin" 0 +3
+ SetShellVarContext all
+ ;MessageBox MB_OK 'User "$0" is in the Admin group'
+ Goto done
+ StrCmp $1 "Power" 0 +3
+ SetShellVarContext all
+ ;MessageBox MB_OK 'User "$0" is in the Power Users group'
+ Goto done
+
+ noLM:
+ ;Get installation folder from registry if available
+
+ done:
+
+FunctionEnd
+
+;--- Add/Remove callback functions: ---
+!macro SectionList MacroName
+ ;This macro used to perform operation on multiple sections.
+ ;List all of your components in following manner here.
+@CPACK_NSIS_COMPONENT_SECTION_LIST@
+!macroend
+
+Section -FinishComponents
+ ;Removes unselected components and writes component status to registry
+ !insertmacro SectionList "FinishSection"
+
+!ifdef CPACK_NSIS_ADD_REMOVE
+ ; Get the name of the installer executable
+ System::Call 'kernel32::GetModuleFileNameA(i 0, t .R0, i 1024) i r1'
+ StrCpy $R3 $R0
+
+ ; Strip off the last 13 characters, to see if we have AddRemove.exe
+ StrLen $R1 $R0
+ IntOp $R1 $R0 - 13
+ StrCpy $R2 $R0 13 $R1
+ StrCmp $R2 "AddRemove.exe" addremove_installed
+
+ ; We're not running AddRemove.exe, so install it
+ CopyFiles $R3 $INSTDIR\AddRemove.exe
+
+ addremove_installed:
+!endif
+SectionEnd
+;--- End of Add/Remove callback functions ---
+
+;--------------------------------
+; Component dependencies
+Function .onSelChange
+ !insertmacro SectionList MaybeSelectionChanged
+FunctionEnd
+
+;--------------------------------
+;Uninstaller Section
+
+Section "Uninstall"
+ ReadRegStr $START_MENU SHCTX \
+ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "StartMenu"
+ ;MessageBox MB_OK "Start menu is in: $START_MENU"
+ ReadRegStr $DO_NOT_ADD_TO_PATH SHCTX \
+ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "DoNotAddToPath"
+ ReadRegStr $ADD_TO_PATH_ALL_USERS SHCTX \
+ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathAllUsers"
+ ReadRegStr $ADD_TO_PATH_CURRENT_USER SHCTX \
+ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathCurrentUser"
+ ;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS"
+ ReadRegStr $INSTALL_DESKTOP SHCTX \
+ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "InstallToDesktop"
+ ;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP "
+
+@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@
+
+ ;Remove files we installed.
+ ;Keep the list of directories here in sync with the File commands above.
+@CPACK_NSIS_DELETE_FILES@
+@CPACK_NSIS_DELETE_DIRECTORIES@
+
+!ifdef CPACK_NSIS_ADD_REMOVE
+ ;Remove the add/remove program
+ Delete "$INSTDIR\AddRemove.exe"
+!endif
+
+ ;Remove the uninstaller itself.
+ Delete "$INSTDIR\Uninstall.exe"
+ DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
+
+ ;Remove the installation directory if it is empty.
+ RMDir "$INSTDIR"
+
+ ; Remove the registry entries.
+ DeleteRegKey SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
+
+ ; Removes all optional components
+ !insertmacro SectionList "RemoveSection"
+
+ !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
+
+ Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
+@CPACK_NSIS_DELETE_ICONS@
+@CPACK_NSIS_DELETE_ICONS_EXTRA@
+
+ ;Delete empty start menu parent diretories
+ StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
+
+ startMenuDeleteLoop:
+ ClearErrors
+ RMDir $MUI_TEMP
+ GetFullPathName $MUI_TEMP "$MUI_TEMP\.."
+
+ IfErrors startMenuDeleteLoopDone
+
+ StrCmp "$MUI_TEMP" "$SMPROGRAMS" startMenuDeleteLoopDone startMenuDeleteLoop
+ startMenuDeleteLoopDone:
+
+ ; If the user changed the shortcut, then untinstall may not work. This should
+ ; try to fix it.
+ StrCpy $MUI_TEMP "$START_MENU"
+ Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
+ Delete "$SMPROGRAMS\$MUI_TEMP\USRP2 Card Burner.lnk"
+ Delete "$SMPROGRAMS\$MUI_TEMP\USRP-N2XX Net Burner.lnk"
+ Delete "$SMPROGRAMS\$MUI_TEMP\UHD Images Downloader.lnk"
+@CPACK_NSIS_DELETE_ICONS_EXTRA@
+
+ ;Delete empty start menu parent diretories
+ StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
+
+ secondStartMenuDeleteLoop:
+ ClearErrors
+ RMDir $MUI_TEMP
+ GetFullPathName $MUI_TEMP "$MUI_TEMP\.."
+
+ IfErrors secondStartMenuDeleteLoopDone
+
+ StrCmp "$MUI_TEMP" "$SMPROGRAMS" secondStartMenuDeleteLoopDone secondStartMenuDeleteLoop
+ secondStartMenuDeleteLoopDone:
+
+ DeleteRegKey /ifempty SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
+
+ Push $INSTDIR\bin
+ StrCmp $DO_NOT_ADD_TO_PATH_ "1" doNotRemoveFromPath 0
+ Call un.RemoveFromPath
+ doNotRemoveFromPath:
+SectionEnd
+
+;--------------------------------
+; determine admin versus local install
+; Is install for "AllUsers" or "JustMe"?
+; Default to "JustMe" - set to "AllUsers" if admin or on Win9x
+; This function is used for the very first "custom page" of the installer.
+; This custom page does not show up visibly, but it executes prior to the
+; first visible page and sets up $INSTDIR properly...
+; Choose different default installation folder based on SV_ALLUSERS...
+; "Program Files" for AllUsers, "My Documents" for JustMe...
+
+Function .onInit
+ ; Reads components status for registry
+ !insertmacro SectionList "InitSection"
+
+ ; check to see if /D has been used to change
+ ; the install directory by comparing it to the
+ ; install directory that is expected to be the
+ ; default
+ StrCpy $IS_DEFAULT_INSTALLDIR 0
+ StrCmp "$INSTDIR" "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" 0 +2
+ StrCpy $IS_DEFAULT_INSTALLDIR 1
+
+ StrCpy $SV_ALLUSERS "JustMe"
+ ; if default install dir then change the default
+ ; if it is installed for JustMe
+ StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2
+ StrCpy $INSTDIR "$DOCUMENTS\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
+
+ ClearErrors
+ UserInfo::GetName
+ IfErrors noLM
+ Pop $0
+ UserInfo::GetAccountType
+ Pop $1
+ StrCmp $1 "Admin" 0 +3
+ SetShellVarContext all
+ ;MessageBox MB_OK 'User "$0" is in the Admin group'
+ StrCpy $SV_ALLUSERS "AllUsers"
+ Goto done
+ StrCmp $1 "Power" 0 +3
+ SetShellVarContext all
+ ;MessageBox MB_OK 'User "$0" is in the Power Users group'
+ StrCpy $SV_ALLUSERS "AllUsers"
+ Goto done
+
+ noLM:
+ StrCpy $SV_ALLUSERS "AllUsers"
+ ;Get installation folder from registry if available
+
+ done:
+ StrCmp $SV_ALLUSERS "AllUsers" 0 +3
+ StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2
+ StrCpy $INSTDIR "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
+
+ StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 noOptionsPage
+ !insertmacro MUI_INSTALLOPTIONS_EXTRACT "NSIS.InstallOptions.ini"
+
+ noOptionsPage:
+FunctionEnd
diff --git a/host/cmake/Modules/UHDPackage.cmake b/host/cmake/Modules/UHDPackage.cmake
index 85cbea81e..6af474f7a 100644
--- a/host/cmake/Modules/UHDPackage.cmake
+++ b/host/cmake/Modules/UHDPackage.cmake
@@ -117,7 +117,6 @@ SET(CPACK_COMPONENT_LIBRARIES_GROUP "Development")
SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
SET(CPACK_COMPONENT_UTILITIES_GROUP "Runtime")
SET(CPACK_COMPONENT_EXAMPLES_GROUP "Runtime")
-SET(CPACK_COMPONENT_TESTS_GROUP "Runtime")
SET(CPACK_COMPONENT_MANUAL_GROUP "Documentation")
SET(CPACK_COMPONENT_DOXYGEN_GROUP "Documentation")
SET(CPACK_COMPONENT_README_GROUP "Documentation")
@@ -126,7 +125,6 @@ SET(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ Headers")
SET(CPACK_COMPONENT_UTILITIES_DISPLAY_NAME "Utilities")
SET(CPACK_COMPONENT_EXAMPLES_DISPLAY_NAME "Examples")
-SET(CPACK_COMPONENT_TESTS_DISPLAY_NAME "Unit Tests")
SET(CPACK_COMPONENT_MANUAL_DISPLAY_NAME "Manual")
SET(CPACK_COMPONENT_DOXYGEN_DISPLAY_NAME "Doxygen")
SET(CPACK_COMPONENT_README_DISPLAY_NAME "Readme")
@@ -136,7 +134,6 @@ SET(CPACK_COMPONENT_LIBRARIES_DESCRIPTION "Dynamic link library")
SET(CPACK_COMPONENT_HEADERS_DESCRIPTION "C++ development headers")
SET(CPACK_COMPONENT_UTILITIES_DESCRIPTION "Utility executables and python scripts")
SET(CPACK_COMPONENT_EXAMPLES_DESCRIPTION "Example executables")
-SET(CPACK_COMPONENT_TESTS_DESCRIPTION "Unit test executables")
SET(CPACK_COMPONENT_MANUAL_DESCRIPTION "Manual/application notes (rst and html)")
SET(CPACK_COMPONENT_DOXYGEN_DESCRIPTION "API documentation (html)")
SET(CPACK_COMPONENT_README_DESCRIPTION "Readme files (txt)")
@@ -148,7 +145,7 @@ SET(CPACK_COMPONENT_UTILITIES_DEPENDS libraries)
SET(CPACK_COMPONENT_EXAMPLES_DEPENDS libraries)
SET(CPACK_COMPONENT_TESTS_DEPENDS libraries)
-SET(CPACK_COMPONENTS_ALL libraries headers utilities examples tests manual doxygen readme images)
+SET(CPACK_COMPONENTS_ALL libraries headers utilities examples manual doxygen readme images)
########################################################################
# Setup CPack Debian
@@ -191,11 +188,11 @@ SET(CPACK_NSIS_MODIFY_PATH ON)
SET(HLKM_ENV "\\\"SYSTEM\\\\CurrentControlSet\\\\Control\\\\Session Manager\\\\Environment\\\"")
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "
- WriteRegStr HKLM ${HLKM_ENV} \\\"UHD_PKG_DATA_PATH\\\" \\\"$INSTDIR\\\\share\\\\uhd\\\"
+ WriteRegStr HKLM ${HLKM_ENV} \\\"UHD_PKG_PATH\\\" \\\"$INSTDIR\\\"
")
SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "
- DeleteRegValue HKLM ${HLKM_ENV} \\\"UHD_PKG_DATA_PATH\\\"
+ DeleteRegValue HKLM ${HLKM_ENV} \\\"UHD_PKG_PATH\\\"
")
IF(MSVC)
diff --git a/host/cmake/Modules/UHDUnitTest.cmake b/host/cmake/Modules/UHDUnitTest.cmake
new file mode 100644
index 000000000..47cddc521
--- /dev/null
+++ b/host/cmake/Modules/UHDUnitTest.cmake
@@ -0,0 +1,110 @@
+#
+# Copyright 2010-2012 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/>.
+#
+
+########################################################################
+# Add a unit test and setup the environment for a unit test.
+# Takes the same arguments as the ADD_TEST function.
+#
+# Before calling set the following variables:
+# UHD_TEST_TARGET_DEPS - built targets for the library path
+# UHD_TEST_LIBRARY_DIRS - directories for the library path
+########################################################################
+function(UHD_ADD_TEST test_name)
+
+ #Ensure that the build exe also appears in the PATH.
+ list(APPEND UHD_TEST_TARGET_DEPS ${ARGN})
+
+ #In the land of windows, all libraries must be in the PATH.
+ #Since the dependent libraries are not yet installed,
+ #we must manually set them in the PATH to run tests.
+ #The following appends the path of a target dependency.
+ foreach(target ${UHD_TEST_TARGET_DEPS})
+ get_target_property(location ${target} LOCATION)
+ if(location)
+ get_filename_component(path ${location} PATH)
+ string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path})
+ list(APPEND UHD_TEST_LIBRARY_DIRS ${path})
+ endif(location)
+ endforeach(target)
+
+ file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir)
+ file(TO_NATIVE_PATH "${UHD_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list?
+
+ #http://www.cmake.org/pipermail/cmake/2009-May/029464.html
+ #Replaced this add test + set environs code with the shell script generation.
+ #Its nicer to be able to manually run the shell script to diagnose problems.
+ #ADD_TEST(${ARGV})
+ #SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}")
+
+ if(UNIX)
+ set(LD_PATH_VAR "LD_LIBRARY_PATH")
+ if(APPLE)
+ set(LD_PATH_VAR "DYLD_LIBRARY_PATH")
+ endif()
+
+ set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH")
+ list(APPEND libpath "$${LD_PATH_VAR}")
+
+ #replace list separator with the path separator
+ string(REPLACE ";" ":" libpath "${libpath}")
+ list(APPEND environs "PATH=${binpath}" "${LD_PATH_VAR}=${libpath}")
+
+ #generate a bat file that sets the environment and runs the test
+ find_program(SHELL sh)
+ set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh)
+ file(WRITE ${sh_file} "#!${SHELL}\n")
+ #each line sets an environment variable
+ foreach(environ ${environs})
+ file(APPEND ${sh_file} "export ${environ}\n")
+ endforeach(environ)
+ #load the command to run with its arguments
+ foreach(arg ${ARGN})
+ file(APPEND ${sh_file} "${arg} ")
+ endforeach(arg)
+ file(APPEND ${sh_file} "\n")
+
+ #make the shell file executable
+ execute_process(COMMAND chmod +x ${sh_file})
+
+ add_test(${test_name} ${SHELL} ${sh_file})
+
+ endif(UNIX)
+
+ if(WIN32)
+ list(APPEND libpath ${DLL_PATHS} "%PATH%")
+
+ #replace list separator with the path separator (escaped)
+ string(REPLACE ";" "\\;" libpath "${libpath}")
+ list(APPEND environs "PATH=${libpath}")
+
+ #generate a bat file that sets the environment and runs the test
+ set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat)
+ file(WRITE ${bat_file} "@echo off\n")
+ #each line sets an environment variable
+ foreach(environ ${environs})
+ file(APPEND ${bat_file} "SET ${environ}\n")
+ endforeach(environ)
+ #load the command to run with its arguments
+ foreach(arg ${ARGN})
+ file(APPEND ${bat_file} "${arg} ")
+ endforeach(arg)
+ file(APPEND ${bat_file} "\n")
+
+ add_test(${test_name} ${bat_file})
+ endif(WIN32)
+
+endfunction(UHD_ADD_TEST)
diff --git a/host/cmake/debian/postinst.in b/host/cmake/debian/postinst.in
index eaca15394..bc27c46f0 100755
--- a/host/cmake/debian/postinst.in
+++ b/host/cmake/debian/postinst.in
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright 2011 Ettus Research LLC
+# Copyright 2011,2013 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
@@ -17,7 +17,7 @@
#
if [ "$1" = "configure" ]; then
- cp @CMAKE_INSTALL_PREFIX@/share/uhd/utils/uhd-usrp.rules /etc/udev/rules.d/uhd-usrp.rules
+ cp @CMAKE_INSTALL_PREFIX@/lib/uhd/utils/uhd-usrp.rules /etc/udev/rules.d/uhd-usrp.rules
udevadm control --reload-rules
ldconfig
fi
diff --git a/host/cmake/redhat/post_install.in b/host/cmake/redhat/post_install.in
index 01fd3338f..25864e0ec 100755
--- a/host/cmake/redhat/post_install.in
+++ b/host/cmake/redhat/post_install.in
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright 2011 Ettus Research LLC
+# Copyright 2011,2013 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
@@ -16,6 +16,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-cp @CMAKE_INSTALL_PREFIX@/share/uhd/utils/uhd-usrp.rules /etc/udev/rules.d/uhd-usrp.rules
+cp @CMAKE_INSTALL_PREFIX@/lib/uhd/utils/uhd-usrp.rules /etc/udev/rules.d/uhd-usrp.rules
udevadm control --reload-rules
ldconfig
diff --git a/host/docs/build.rst b/host/docs/build.rst
index 0a18e9e9a..00f79aaaa 100644
--- a/host/docs/build.rst
+++ b/host/docs/build.rst
@@ -1,5 +1,5 @@
========================================================================
-UHD - Build Guide
+UHD Software - Build Guide
========================================================================
.. contents:: Table of Contents
diff --git a/host/docs/calibration.rst b/host/docs/calibration.rst
index 1468a9c2a..8ba3477b8 100644
--- a/host/docs/calibration.rst
+++ b/host/docs/calibration.rst
@@ -7,11 +7,11 @@ UHD - Calibration Application Notes
------------------------------------------------------------------------
Self-calibration
------------------------------------------------------------------------
-UHD comes with several self-calibration utilities for minimizing IQ imbalance and DC offset.
+UHD software comes with several self-calibration utilities for minimizing IQ imbalance and DC offset.
These utilities perform calibration sweeps using transmit leakage into the receive path
(special equipment is not required).
The results from a calibration are written to a CSV file in the user's home directory.
-UHD will automatically apply corrections at runtime when the user re-tunes the daughterboard LO.
+UHD software will automatically apply corrections at runtime when the user re-tunes the daughterboard LO.
Calibration results are specific to an individual RF board.
**Note:**
@@ -19,7 +19,7 @@ When a calibration table is present,
and the user wishes to override the calibration settings through the API:
the user should re-apply the desired setting every time the LO is re-tuned.
-UHD comes with the following calibration utilities:
+UHD software comes with the following calibration utilities:
* **uhd_cal_rx_iq_balance:** - mimimizes RX IQ imbalance vs. LO frequency
* **uhd_cal_tx_dc_offset:** - mimimizes TX DC offset vs. LO frequency
@@ -27,14 +27,15 @@ UHD comes with the following calibration utilities:
The following RF frontends are supported by the self-calibration utilities:
+ * RFX transceiver board
* WBX transceiver board
* SBX transceiver board
- * RFX transceiver board
+ * CBX transceiver board
********************************************
Calibration Utilities
********************************************
-UHD installs the calibration utilities into **<install-path>/bin**.
+UHD software installs the calibration utilities into **<install-path>/bin**.
**Disconnect** any external hardware from the RF antenna ports,
and run the following from the command line.
Each utility will take several minutes to complete.
diff --git a/host/docs/coding.rst b/host/docs/coding.rst
index ef8cb5fe2..432307cca 100644
--- a/host/docs/coding.rst
+++ b/host/docs/coding.rst
@@ -11,7 +11,7 @@ Various API interfaces
Low-Level: The device API
^^^^^^^^^^^^^^^^^^^^^^^^^^^
A device is an abstraction for hardware that is connected to the host system.
-For a USRP, this means that the motherboard and everything on it would be
+For a USRP device, this means that the motherboard and everything on it would be
considered to be a "device". The device API provides ways to:
* Discover devices that are physically connected to the host system.
@@ -25,6 +25,6 @@ See the documentation in *device.hpp* for reference.
^^^^^^^^^^^^^^^^^^^^^^^^^^^
High-Level: The Multi-USRP
^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The Multi-USRP class provides a fat interface to a single USRP with
-one or more channels, or multiple USRPs in a homogeneous setup.
+The Multi-USRP class provides a fat interface to a single USRP device with
+one or more channels, or multiple USRP devicess in a homogeneous setup.
See the documentation in *usrp/multi_usrp.hpp* for reference.
diff --git a/host/docs/dboards.rst b/host/docs/dboards.rst
index 29812592f..4b5a074a8 100644
--- a/host/docs/dboards.rst
+++ b/host/docs/dboards.rst
@@ -1,5 +1,5 @@
========================================================================
-UHD - Daughterboard Application Notes
+UHD Daughterboard Application Notes
========================================================================
.. contents:: Table of Contents
@@ -255,6 +255,11 @@ LEDs:
* **RX1/RX2**: Receiver on RX2 antenna port
^^^^^^^^^^^^^^^^^^^^^^^^^^^
+CBX
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+See SBX Series for more details.
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
TVRX
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The TVRX board has 1 real-mode frontend.
@@ -335,14 +340,14 @@ With the daughterboard plugged-in, run the following commands:
cd <install-path>/share/uhd/utils
./usrp_burn_db_eeprom --id=0x000d --unit=RX --args=<args> --slot=<slot>
-* **<args>** are device address arguments (optional if only one USRP is on your machine)
-* **<slot>** is the name of the daughterboard slot (optional if the USRP has only one slot)
+* **<args>** are device address arguments (optional if only one USRP device is on your machine)
+* **<slot>** is the name of the daughterboard slot (optional if the USRP device has only one slot)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
RFX - Mod
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Older RFX boards require modifications to use the motherboard oscillator.
-If this is the case, UHD will print a warning about the modification.
+If this is the case, UHD software will print a warning about the modification.
Please follow the modification procedures below:
**Step 1: Disable the daughterboard clocks**
@@ -377,5 +382,5 @@ With the daughterboard plugged-in, run the following commands:
* **RFX1800:** 0x0035
* **RFX1200:** 0x002a
* **RFX2400:** 0x002b
-* **<args>** are device address arguments (optional if only one USRP is on your machine)
-* **<slot>** is the name of the daughterboard slot (optional if the USRP has only one slot)
+* **<args>** are device address arguments (optional if only one USRP device is on your machine)
+* **<slot>** is the name of the daughterboard slot (optional if the USRP device has only one slot)
diff --git a/host/docs/general.rst b/host/docs/general.rst
index fc7caff3c..fc2735c46 100644
--- a/host/docs/general.rst
+++ b/host/docs/general.rst
@@ -23,10 +23,10 @@ frequency and actual frequency. The user may also explicitly control both
stages of tuning through through the **tune_request_t** object, which allows for
more advanced tuning.
-In general, Using UHD's advanced tuning is highly recommended as it makes it
+In general, Using UHD software's advanced tuning is highly recommended as it makes it
easy to move the DC component out of your band-of-interest. This can be done by
-passing your desired LO offset to the **tune_request_t** object, and letting UHD
-handle the rest.
+passing your desired LO offset to the **tune_request_t** object, and letting the UHD
+software handle the rest.
Tuning the receive chain:
::
@@ -125,13 +125,13 @@ Overflow notes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When receiving, the device produces samples at a constant rate.
Overflows occurs when the host does not consume data fast enough.
-When UHD detects the overflow, it prints an "O" to stdout,
+When UHD software detects the overflow, it prints an "O" to stdout,
and pushes an inline message packet into the receive stream.
**Network-based devices**:
The host does not back-pressure the receive stream.
When the kernel's socket buffer becomes full, it will drop subsequent packets.
-UHD detects the overflow as a discontinuity in the packet's sequence numbers,
+UHD software detects the overflow as a discontinuity in the packet's sequence numbers,
and pushes an inline message packet into the receive stream.
**Other devices**:
@@ -140,14 +140,14 @@ Therefore, overflows always occur in the device itself.
When the device's internal buffers become full, streaming is shut off,
and an inline message packet is sent to the host.
If the device was in continuous streaming mode,
-UHD will automatically restart streaming.
+the UHD software will automatically restart streaming.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Underflow notes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When transmitting, the device consumes samples at a constant rate.
Underflow occurs when the host does not produce data fast enough.
-When UHD detects underflow, it prints a "U" to stdout,
+When UHD software detects the underflow, it prints a "U" to stdout,
and pushes a message packet into the async message stream.
------------------------------------------------------------------------
@@ -157,7 +157,7 @@ Threading Notes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Thread safety notes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-For the most part, UHD is thread-safe.
+For the most part, UHD software is thread-safe.
Please observe the following limitations:
**Fast-path thread requirements:**
@@ -177,8 +177,8 @@ It is recommended to use at most one thread context for manipulating device sett
Thread priority scheduling
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-When UHD spawns a new thread it may try to boost the thread's scheduling priority.
-When setting the priority fails, UHD prints out an error.
+When UHD software spawns a new thread it may try to boost the thread's scheduling priority.
+When setting the priority fails, the UHD software prints out an error.
This error is harmless; it simply means that the thread will have a normal scheduling priority.
**Linux Notes:**
@@ -211,7 +211,7 @@ Disabling or redirecting prints to stdout
The user can disable the UHD library from printing directly to stdout by registering a custom message handler.
The handler will intercept all messages, which can be dropped or redirected.
Only one handler can be registered at a time.
-Make **register_handler** your first call into UHD:
+Make **register_handler** your first call into the UHD library:
::
diff --git a/host/docs/identification.rst b/host/docs/identification.rst
index a5e60e7f9..ba9b30898 100644
--- a/host/docs/identification.rst
+++ b/host/docs/identification.rst
@@ -5,7 +5,7 @@ UHD - Device Identification Notes
.. contents:: Table of Contents
------------------------------------------------------------------------
-Identifying USRPs
+Identifying USRP Devices
------------------------------------------------------------------------
Devices are addressed through key/value string pairs.
These string pairs can be used to narrow down the search for a specific device or group of devices.
@@ -89,10 +89,10 @@ such as detected daughterboards, frequency range, gain ranges, etc...
uhd_usrp_probe --args <device-specific-address-args>
------------------------------------------------------------------------
-Naming a USRP
+Naming a USRP Device
------------------------------------------------------------------------
-For convenience purposes, users may assign a custom name to their USRPs.
-The USRP can then be identified via name, rather than a difficult to remember serial or address.
+For convenience purposes, users may assign a custom name to their USRP device.
+The USRP device can then be identified via name, rather than a difficult to remember serial or address.
A name has the following properties:
diff --git a/host/docs/images.rst b/host/docs/images.rst
index dc9770460..95e2d96b0 100644
--- a/host/docs/images.rst
+++ b/host/docs/images.rst
@@ -29,7 +29,7 @@ See the UHD wiki for the download link.
The pre-built images come in two forms:
-* bundled with UHD in a platform-specific installer
+* bundled with UHD software in a platform-specific installer
* stand-alone platform-independent archive files
^^^^^^^^^^^^^^^^^^^^^^
@@ -59,7 +59,7 @@ When installing images from an archive, there are two options:
**Option 1:**
Unpack the archive into the UHD installation prefix.
-UHD will always search **<install-path>/share/uhd/images** for image files.
+UHD software will always search **<install-path>/share/uhd/images** for image files.
Where **<install-path>** was set by the **CMAKE_INSTALL_PREFIX** at configure-time.
**Option 2:**
diff --git a/host/docs/index.rst b/host/docs/index.rst
index 00b1c9618..5e3d08fb4 100644
--- a/host/docs/index.rst
+++ b/host/docs/index.rst
@@ -2,17 +2,17 @@
UHD - USRP Hardware Driver
========================================================================
-UHD is the "Universal Software Radio Peripheral" hardware driver.
-The goal of UHD is to provide a host driver and API for current and future Ettus Research products.
+UHD software is the "Universal Software Radio Peripheral" Hardware Driver software.
+The goal of UHD software is to provide a host driver and API for current and future Ettus Research products.
Users will be able to use the UHD driver standalone or with third-party applications.
------------------------------------------------------------------------
Contents
------------------------------------------------------------------------
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Building and Installing UHD
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Building and Installing UHD Software
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* `Build Guide <./build.html>`_
* `Installation Guide (Linux) <http://code.ettus.com/redmine/ettus/projects/uhd/wiki/UHD_Linux>`_
* `Installation Guide (Windows) <http://code.ettus.com/redmine/ettus/projects/uhd/wiki/UHD_Windows>`_
diff --git a/host/docs/sync.rst b/host/docs/sync.rst
index 8622dc642..a1f6cb7df 100644
--- a/host/docs/sync.rst
+++ b/host/docs/sync.rst
@@ -4,9 +4,9 @@ UHD - Synchronization Application Notes
.. contents:: Table of Contents
-The following application notes explain how to synchronize multiple USRPs
-with the goal of transmitting or receiving time-aligned samples for MIMO
-or other applications requiring multiple USRPs operating synchronously.
+The following application notes explain how to synchronize multiple USRP
+devices with the goal of transmitting or receiving time-aligned samples for MIMO
+or other applications requiring multiple USRP devices operating synchronously.
**Note:** The following synchronization notes do not apply to USRP1,
which does not support the advanced features available in newer products.
@@ -14,7 +14,7 @@ which does not support the advanced features available in newer products.
------------------------------------------------------------------------
Common Reference Signals
------------------------------------------------------------------------
-USRPs take two reference signals in order to synchronize clocks and time:
+USRP devices take two reference signals in order to synchronize clocks and time:
* A 10MHz reference to provide a single frequency reference for both devices.
* A pulse-per-second (PPS) to synchronize the sample time across devices.
@@ -103,16 +103,16 @@ and the user can also parse this string to determine GPS time:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Method 3 - internal GPSDO
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-USRPs with internal GPSDOs properly configured will automatically
+USRP devices with internal GPSDOs properly configured will automatically
configure themselves to set the VITA time to current UTC time.
See the `GPSDO Application Notes <./gpsdo.html>`_ for more details.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Method 4 - MIMO cable
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-A USRP can synchronize its time to another USRP via the MIMO cable.
+A USRP device can synchronize its time to another USRP device via the MIMO cable.
Unlike the other methods, this does not use a real "pulse per second".
-Rather, the USRP sends an encoded time message over the MIMO cable.
+Rather, the USRP device sends an encoded time message over the MIMO cable.
The slave device will automatically synchronize to the time on the master device.
See the `MIMO Cable Application Notes <./usrp2.html#using-the-mimo-cable>`_ for more detail.
@@ -123,7 +123,7 @@ Synchronizing Channel Phase
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Align CORDICs in the DSP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-In order to achieve phase alignment between USRPs, the CORDICS in both
+In order to achieve phase alignment between USRP devices, the CORDICS in both
devices must be aligned with respect to each other. This is easily achieved
by issuing stream commands with a time spec property, which instructs the
streaming to begin at a specified time. Since the devices are already
diff --git a/host/docs/transport.rst b/host/docs/transport.rst
index 2e39e75d1..db89c8db9 100644
--- a/host/docs/transport.rst
+++ b/host/docs/transport.rst
@@ -14,7 +14,7 @@ These optional parameters control how the transport object allocates memory,
resizes kernel buffers, spawns threads, etc.
When not spcified, the transport layer will use values for these parameters
that are known to perform well on a variety of systems.
-The transport parameters are defined below for the various transports in the UHD:
+The transport parameters are defined below for the various transports in the UHD software:
------------------------------------------------------------------------
UDP Transport (Sockets)
@@ -154,11 +154,11 @@ so that non-root users may access the device:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Install USB driver (Windows)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-A driver package must be installed to use a USB-based product with UHD:
+A driver package must be installed to use a USB-based product with UHD software:
* Download the driver from the UHD wiki page `here <http://files.ettus.com/binaries/misc/erllc_uhd_winusb_driver.zip>`_.
* Unzip the file into a known location. We will refer to this as the **<directory>**.
-* Open the device manager and plug in the USRP. You will see an unrecognized USB device in the device manager.
+* Open the device manager and plug in the USRP device. You will see an unrecognized USB device in the device manager.
* Right click on the unrecognized USB device and select update/install driver software (may vary for your OS).
* In the driver installation wizard, select "browse for driver", browse to the **<directory>**, and select the **.inf** file.
* Continue through the installation wizard until the driver is installed.
diff --git a/host/docs/usrp1.rst b/host/docs/usrp1.rst
index c1fdec146..b6fd24b09 100644
--- a/host/docs/usrp1.rst
+++ b/host/docs/usrp1.rst
@@ -79,7 +79,7 @@ Hardware Setup Notes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
External clock modification
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The USRP can be modified to accept an external clock reference instead of the 64MHz onboard reference.
+The USRP device can be modified to accept an external clock reference instead of the 64MHz onboard reference.
* Solder SMA (**LTI-SASF54GT**) connector to **J2001**.
* Move 0 ohm 0603 resistor **R2029** to **R2030**.
* Move 0.01uF 0603 capacitor **C925** to **C926**.
@@ -89,7 +89,7 @@ The new external clock needs to be a square wave between +7dBm and +15dBm
After the hardware modification,
the user should burn the setting into the EEPROM,
-so UHD can initialize with the correct clock rate.
+so UHD software can initialize with the correct clock rate.
Run the following commands to record the setting into the EEPROM:
::
diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst
index e675e61ba..5f1e51ea9 100644
--- a/host/docs/usrp2.rst
+++ b/host/docs/usrp2.rst
@@ -148,7 +148,7 @@ any parameters:
ifconfig -a
**Note:**
-When using UHD, if an IP address for the USRP2 is not specified,
+When using UHD software, if an IP address for the USRP2 is not specified,
the software will use UDP broadcast packets to locate the USRP2.
On some systems, the firewall will block UDP broadcast packets.
It is recommended that you change or disable your firewall settings.
@@ -213,13 +213,13 @@ The following tips are designed to help narrow down and diagnose the problem.
RuntimeError: no control response
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is a common error that occurs when you have set the subnet of your network
-interface to a different subnet than the network interface of the USRP. For
-example, if your network interface is set to **192.168.20.1**, and the USRP is
+interface to a different subnet than the network interface of the USRP device. For
+example, if your network interface is set to **192.168.20.1**, and the USRP device is
**192.168.10.2** (note the difference in the third numbers of the IP addresses), you
will likely see a 'no control response' error message.
Fixing this is simple - just set the your host PC's IP address to the same
-subnet as that of your USRP. Instructions for setting your IP address are in the
+subnet as that of your USRP device. Instructions for setting your IP address are in the
previous section of this documentation.
@@ -238,7 +238,7 @@ or create a rule to allow all incoming packets with UDP source port **49152**.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ping the device
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The USRP will reply to ICMP echo requests.
+The USRP device will reply to ICMP echo requests.
A successful ping response means that the device has booted properly
and that it is using the expected IP address.
@@ -346,7 +346,7 @@ the following clock configuration must be set on the slave device:
------------------------------------------------------------------------
Alternative stream destination
------------------------------------------------------------------------
-It is possible to program the USRP to send RX packets to an alternative IP/UDP destination.
+It is possible to program the USRP device to send RX packets to an alternative IP/UDP destination.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Set the subnet and gateway
@@ -429,7 +429,7 @@ Using a PPS signal for timestamp synchronization requires a square wave signal w
Test the PPS input with the following app:
-* **<args>** are device address arguments (optional if only one USRP is on your machine)
+* **<args>** are device address arguments (optional if only one USRP device is on your machine)
::
diff --git a/host/docs/usrp_b100.rst b/host/docs/usrp_b100.rst
index cdb853b61..b5dc79b50 100644
--- a/host/docs/usrp_b100.rst
+++ b/host/docs/usrp_b100.rst
@@ -21,7 +21,7 @@ Comparative features list
------------------------------------------------------------------------
Specify a Non-standard Image
------------------------------------------------------------------------
-UHD will automatically select the USRP B-Series images from the installed images package.
+UHD software will automatically select the USRP B-Series images from the installed images package.
The image selection can be overridden with the **--fpga=** and **--fw=** device address parameters.
Example device address string representations to specify non-standard images:
@@ -54,7 +54,7 @@ and X4 must be populated with a 61.44 MHz oscillator.
* **J15** is a three pin header, move the jumper to (pin1, pin2)
* **357LB3I061M4400** is the recommended oscillator for X4
-**Note:** See instructions below to communicate the desired clock rate into UHD.
+**Note:** See instructions below to communicate the desired clock rate into UHD software.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Set other rates - uses internal VCO
@@ -63,7 +63,7 @@ To use other clock rates, the jumper will need to be in the default position.
* **J15** is a three pin header, move the jumper to (pin2, pin3)
-To communicate the desired clock rate into UHD,
+To communicate the desired clock rate into UHD software,
specify the a special device address argument,
where the key is **master_clock_rate** and the value is a rate in Hz.
Example:
diff --git a/host/docs/usrp_e1x0.rst b/host/docs/usrp_e1x0.rst
index 189cbb86b..fc929e639 100644
--- a/host/docs/usrp_e1x0.rst
+++ b/host/docs/usrp_e1x0.rst
@@ -22,7 +22,7 @@ Comparative features list
------------------------------------------------------------------------
Specify a Non-standard Image
------------------------------------------------------------------------
-UHD will automatically select the USRP-Embedded FPGA image from the
+UHD software will automatically select the USRP-Embedded FPGA image from the
installed images package. The FPGA image selection can be overridden with the
**--fpga=** device address parameter.
@@ -53,7 +53,7 @@ on the device.
* **J16** is a two pin header; remove the jumper (or leave it on pin1 only).
* **J15** is a three pin header; move the jumper to (pin1, pin2).
-**Note:** See instructions below to communicate the desired clock rate UHD.
+**Note:** See instructions below to communicate the desired clock rate to UHD software.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Set other rates - uses internal VCO
@@ -63,7 +63,7 @@ To use other clock rates, the jumpers will need to be in the default position.
* **J16** is a two pin header; move the jumper to (pin1, pin2).
* **J15** is a three pin header; move the jumper to (pin2, pin3).
-To communicate the desired clock rate into UHD,
+To communicate the desired clock rate into UHD software,
specify the a special device address argument,
where the key is **master_clock_rate** and the value is a rate in Hz.
Example:
@@ -103,7 +103,7 @@ a connector.
Test the PPS input with the following app:
-* **<args** are device address arguments (optional if only one USRP is on your machine).
+* **<args** are device address arguments (optional if only one USRP device is on your machine).
::
@@ -116,7 +116,7 @@ Internal GPSDO
Please see the `Internal GPSDO Application Notes <./gpsdo.html>`_
for information on configuring and using the internal GPSDO.
-UHD will always try to detect an installed GPSDO at runtime.
+UHD software will always try to detect an installed GPSDO at runtime.
There is not a special EEPROM value to burn for GPSDO detection.
------------------------------------------------------------------------
diff --git a/host/examples/benchmark_rate.cpp b/host/examples/benchmark_rate.cpp
index 8a000f6c3..ed3a8580a 100644
--- a/host/examples/benchmark_rate.cpp
+++ b/host/examples/benchmark_rate.cpp
@@ -25,6 +25,7 @@
#include <boost/math/special_functions/round.hpp>
#include <iostream>
#include <complex>
+#include <cstdlib>
namespace po = boost::program_options;
@@ -264,5 +265,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/latency_test.cpp b/host/examples/latency_test.cpp
index 518d2383a..461ac9bf8 100644
--- a/host/examples/latency_test.cpp
+++ b/host/examples/latency_test.cpp
@@ -164,5 +164,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
**************************************************************/
std::cout << boost::format("\nACK %d, UNDERFLOW %d, TIME_ERR %d, other %d")
% ack % underflow % time_error % other << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/network_relay.cpp b/host/examples/network_relay.cpp
index e8f9e667f..bb09296b3 100644
--- a/host/examples/network_relay.cpp
+++ b/host/examples/network_relay.cpp
@@ -24,6 +24,7 @@
#include <iostream>
#include <csignal>
#include <vector>
+#include <cstdlib>
namespace po = boost::program_options;
namespace asio = boost::asio;
@@ -202,7 +203,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
<< "Runs a network relay between UHD on one computer and a USRP on the network.\n"
<< "This example is basically for test purposes. Use at your own convenience.\n"
<< std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
{
@@ -223,5 +224,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/rx_ascii_art_dft.cpp b/host/examples/rx_ascii_art_dft.cpp
index fe8fb0347..1aede51a4 100644
--- a/host/examples/rx_ascii_art_dft.cpp
+++ b/host/examples/rx_ascii_art_dft.cpp
@@ -25,6 +25,7 @@
#include <curses.h>
#include <iostream>
#include <complex>
+#include <cstdlib>
namespace po = boost::program_options;
@@ -63,7 +64,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//print the help message
if (vm.count("help") or not vm.count("rate")){
std::cout << boost::format("UHD RX ASCII Art DFT %s") % desc << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//create a usrp device
@@ -82,7 +83,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//set the sample rate
if (not vm.count("rate")){
std::cerr << "Please specify the sample rate with --rate" << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl;
usrp->set_rx_rate(rate);
@@ -91,7 +92,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//set the center frequency
if (not vm.count("freq")){
std::cerr << "Please specify the center frequency with --freq" << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl;
usrp->set_rx_freq(freq);
@@ -194,5 +195,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/rx_multi_samples.cpp b/host/examples/rx_multi_samples.cpp
index 42ef33d70..83d648eb5 100644
--- a/host/examples/rx_multi_samples.cpp
+++ b/host/examples/rx_multi_samples.cpp
@@ -174,5 +174,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/rx_samples_to_file.cpp b/host/examples/rx_samples_to_file.cpp
index 5197bfe69..d0a02a6c1 100644
--- a/host/examples/rx_samples_to_file.cpp
+++ b/host/examples/rx_samples_to_file.cpp
@@ -214,5 +214,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/rx_samples_to_udp.cpp b/host/examples/rx_samples_to_udp.cpp
index 2acaa5d8b..f637f9313 100644
--- a/host/examples/rx_samples_to_udp.cpp
+++ b/host/examples/rx_samples_to_udp.cpp
@@ -168,5 +168,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp
index 143bceb03..f0d49b4bd 100644
--- a/host/examples/rx_timed_samples.cpp
+++ b/host/examples/rx_timed_samples.cpp
@@ -124,5 +124,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/test_dboard_coercion.cpp b/host/examples/test_dboard_coercion.cpp
index 5b1e9f0e2..cfc745147 100644
--- a/host/examples/test_dboard_coercion.cpp
+++ b/host/examples/test_dboard_coercion.cpp
@@ -573,5 +573,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
if(test_tx and test_rx) std::cout << std::endl;
if(test_rx) std::cout << rx_results << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/test_messages.cpp b/host/examples/test_messages.cpp
index afb092092..6f2ddfe28 100644
--- a/host/examples/test_messages.cpp
+++ b/host/examples/test_messages.cpp
@@ -350,5 +350,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/test_pps_input.cpp b/host/examples/test_pps_input.cpp
index 994b7ca87..c07f2fffd 100644
--- a/host/examples/test_pps_input.cpp
+++ b/host/examples/test_pps_input.cpp
@@ -58,5 +58,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout << std::endl << "Attempt to detect the PPS and set the time..." << std::endl << std::endl;
usrp->set_time_unknown_pps(uhd::time_spec_t(0.0));
std::cout << std::endl << "Success!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/test_timed_commands.cpp b/host/examples/test_timed_commands.cpp
index 34c83dfd6..cecf1607c 100644
--- a/host/examples/test_timed_commands.cpp
+++ b/host/examples/test_timed_commands.cpp
@@ -125,5 +125,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/transport_hammer.cpp b/host/examples/transport_hammer.cpp
index e32912eaa..ff35ceb21 100644
--- a/host/examples/transport_hammer.cpp
+++ b/host/examples/transport_hammer.cpp
@@ -272,5 +272,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/tx_bursts.cpp b/host/examples/tx_bursts.cpp
index 4cf5f2fd1..8dd4a002c 100644
--- a/host/examples/tx_bursts.cpp
+++ b/host/examples/tx_bursts.cpp
@@ -156,5 +156,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/tx_samples_from_file.cpp b/host/examples/tx_samples_from_file.cpp
index 04a6a63d4..f9447c25d 100644
--- a/host/examples/tx_samples_from_file.cpp
+++ b/host/examples/tx_samples_from_file.cpp
@@ -192,5 +192,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp
index 3b8cc75d4..4cc31a7c0 100644
--- a/host/examples/tx_timed_samples.cpp
+++ b/host/examples/tx_timed_samples.cpp
@@ -124,5 +124,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/tx_waveforms.cpp b/host/examples/tx_waveforms.cpp
index 3c5eecd65..40326ae93 100644
--- a/host/examples/tx_waveforms.cpp
+++ b/host/examples/tx_waveforms.cpp
@@ -260,5 +260,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/txrx_loopback_to_file.cpp b/host/examples/txrx_loopback_to_file.cpp
index 495c9f7e4..9dc348da8 100644
--- a/host/examples/txrx_loopback_to_file.cpp
+++ b/host/examples/txrx_loopback_to_file.cpp
@@ -443,5 +443,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/include/uhd/types/tune_request.hpp b/host/include/uhd/types/tune_request.hpp
index 9c498bfe9..dd6123a9f 100644
--- a/host/include/uhd/types/tune_request.hpp
+++ b/host/include/uhd/types/tune_request.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2012 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
@@ -19,6 +19,7 @@
#define INCLUDED_UHD_TYPES_TUNE_REQUEST_HPP
#include <uhd/config.hpp>
+#include <uhd/types/device_addr.hpp>
namespace uhd{
@@ -88,6 +89,18 @@ namespace uhd{
*/
double dsp_freq;
+ /*!
+ * The args parameter is used to pass arbitrary key/value pairs.
+ * Possible keys used by args (depends on implementation):
+ *
+ * - mode_n: Allows the user to tell the daughterboard tune code
+ * to choose between an integer N diviver or fractional N divider.
+ * Default is fractional N on boards that support fractional N tuning.
+ * Fractional N provides greater tuning acuracy at the expense of spurs.
+ * Possible options for this key: "integer" or "fractional".
+ */
+ device_addr_t args;
+
};
} //namespace uhd
diff --git a/host/include/uhd/utils/paths.hpp b/host/include/uhd/utils/paths.hpp
index f5a40b2c9..e0f455e92 100644
--- a/host/include/uhd/utils/paths.hpp
+++ b/host/include/uhd/utils/paths.hpp
@@ -29,8 +29,8 @@ namespace uhd{
//! Get a string representing the system's appdata directory
UHD_API std::string get_app_path(void);
- //! Get a string representing the system's pkg data directory
- UHD_API std::string get_pkg_data_path(void);
+ //! Get a string representing the system's pkg directory
+ UHD_API std::string get_pkg_path(void);
} //namespace uhd
diff --git a/host/include/uhd/version.hpp b/host/include/uhd/version.hpp
index ab693f2b0..01e5c3cdb 100644
--- a/host/include/uhd/version.hpp
+++ b/host/include/uhd/version.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2012 Ettus Research LLC
+// Copyright 2010-2013 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
@@ -27,7 +27,7 @@
* The format is oldest API compatible release - ABI compat number.
* The compatibility number allows pre-release ABI to be versioned.
*/
-#define UHD_VERSION_ABI_STRING "3.4.0-3"
+#define UHD_VERSION_ABI_STRING "3.6.0-0"
namespace uhd{
diff --git a/host/lib/convert/CMakeLists.txt b/host/lib/convert/CMakeLists.txt
index 0d9d0983f..28defa8bc 100644
--- a/host/lib/convert/CMakeLists.txt
+++ b/host/lib/convert/CMakeLists.txt
@@ -24,12 +24,11 @@ MESSAGE(STATUS "")
########################################################################
# Look for Orc support
########################################################################
-FIND_PACKAGE(PkgConfig)
-IF(PKG_CONFIG_FOUND)
-PKG_CHECK_MODULES(ORC "orc-0.4 > 0.4.11")
-ENDIF(PKG_CONFIG_FOUND)
+FIND_PACKAGE(ORC)
-FIND_PROGRAM(ORCC_EXECUTABLE orcc)
+IF(NOT ORCC_EXECUTABLE)
+ FIND_PROGRAM(ORCC_EXECUTABLE orcc)
+ENDIF()
LIBUHD_REGISTER_COMPONENT("ORC" ENABLE_ORC ON "ENABLE_LIBUHD;ORC_FOUND;ORCC_EXECUTABLE" OFF)
diff --git a/host/lib/ic_reg_maps/CMakeLists.txt b/host/lib/ic_reg_maps/CMakeLists.txt
index dc2ab7847..b6e121db3 100644
--- a/host/lib/ic_reg_maps/CMakeLists.txt
+++ b/host/lib/ic_reg_maps/CMakeLists.txt
@@ -33,6 +33,11 @@ LIBUHD_PYTHON_GEN_SOURCE(
)
LIBUHD_PYTHON_GEN_SOURCE(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gen_max2870_regs.py
+ ${CMAKE_CURRENT_BINARY_DIR}/max2870_regs.hpp
+)
+
+LIBUHD_PYTHON_GEN_SOURCE(
${CMAKE_CURRENT_SOURCE_DIR}/gen_adf4360_regs.py
${CMAKE_CURRENT_BINARY_DIR}/adf4360_regs.hpp
)
diff --git a/host/lib/ic_reg_maps/gen_max2870_regs.py b/host/lib/ic_reg_maps/gen_max2870_regs.py
new file mode 100644
index 000000000..f26c27281
--- /dev/null
+++ b/host/lib/ic_reg_maps/gen_max2870_regs.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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/>.
+#
+
+########################################################################
+# Template for raw text data describing registers
+# name addr[bit range inclusive] default optional enums
+########################################################################
+
+REGS_TMPL="""\
+########################################################################
+## Address 0x00
+## Divider control
+## Write-only, default = 0x007D0000
+########################################################################
+int_n_mode 0x00[31] 0 frac_n, int_n
+int_16_bit 0x00[15:30] 0x007D ##Integer divider: 16-65535 in int-N mode, 19-4091 in frac-N mode.
+frac_12_bit 0x00[3:14] 0 ##Frac divider: 0-4095
+########################################################################
+## Address 0x01
+## Charge pump control
+## Write-only, default = 0x2000FFF9
+########################################################################
+cpoc 0x01[31] 0 disabled, enabled
+cpl 0x01[29:30] 1 disabled, enabled, res1, res2
+cpt 0x01[27:28] 0 normal, reserved, force_source, force_sink
+phase_12_bit 0x01[15:26] 1 ##sets phase shift
+mod_12_bit 0x01[3:14] 0xFFF ##VCO frac modulus
+########################################################################
+## Address 0x02
+## Misc. control
+## Write-only, default = 0x00004042
+########################################################################
+lds 0x02[31] 0 slow, fast
+low_noise_and_spur 0x02[29:30] 3 low_noise, reserved, low_spur_1, low_spur_2
+muxout 0x02[26:28] 1 tri_state, high, low, rdiv, ndiv, ald, dld, res7
+reference_doubler 0x02[25] 0 disabled, enabled
+reference_divide_by_2 0x02[24] 0 disabled, enabled
+r_counter_10_bit 0x02[14:23] 1 ##R divider value, 1-1023
+double_buffer 0x02[13] 0 disabled, enabled
+#set $current_setting_enums = ', '.join(map(lambda x: '_'.join(("%0.2fma"%(1.631/5.1 * (1.+x))).split('.')), range(0,16)))
+charge_pump_current 0x02[9:12] 7 $current_setting_enums
+ldf 0x02[8] 0 frac_n, int_n
+ldp 0x02[7] 0 10ns, 6ns
+pd_polarity 0x02[6] 1 negative, positive
+power_down 0x02[5] 0 normal, shutdown
+cp_three_state 0x02[4] 0 disabled, enabled
+counter_reset 0x02[3] 0 normal, reset
+########################################################################
+## Address 0x03
+## VCO control
+## Write-only, default = 0x0000000B
+########################################################################
+vco 0x03[26:31] 0 ##VCO subband selection, used when VAS disabledd
+vas 0x03[25] 0 enabled, disabled ##VCO autoselect
+retune 0x03[24] 1 disabled, enabled
+clock_div_mode 0x03[15:16] 0 clock_divider_off, fast_lock, phase, reserved
+clock_divider_12_bit 0x03[3:14] 1 ##clock divider, 1-4095
+########################################################################
+## Address 0x04
+## RF output control
+## Write-only, default = 0x6180B23C
+########################################################################
+res4 0x04[26:31] 0x18
+bs_msb 0x04[24:25] 0 ##Band select MSBs
+feedback_select 0x04[23] 1 divided, fundamental
+rf_divider_select 0x04[20:22] 0 div1, div2, div4, div8, div16, div32, div64, div128
+band_select_clock_div 0x04[12:19] 0
+aux_output_select 0x04[9] 1 divided, fundamental
+aux_output_enable 0x04[8] 0 disabled, enabled
+aux_output_power 0x04[6:7] 0 m4dBm, m1dBm, 2dBm, 5dBm
+rf_output_enable 0x04[5] 1 disabled, enabled
+output_power 0x04[3:4] 3 m4dBm, m1dBm, 2dBm, 5dBm
+########################################################################
+## Address 0x05
+## Misc
+## Write only, default = 0x00400005
+########################################################################
+f01 0x05[24] 1 frac_n, auto
+ld_pin_mode 0x05[22:23] 1 low, dld, ald, high
+mux_sdo 0x05[18] 0 normal, sdo
+"""
+
+########################################################################
+# Template for methods in the body of the struct
+########################################################################
+BODY_TMPL="""\
+enum addr_t{
+ ADDR_R0 = 0,
+ ADDR_R1 = 1,
+ ADDR_R2 = 2,
+ ADDR_R3 = 3,
+ ADDR_R4 = 4,
+ ADDR_R5 = 5
+};
+
+boost::uint32_t get_reg(boost::uint8_t addr){
+ boost::uint32_t reg = addr & 0x7;
+ switch(addr){
+ #for $addr in range(5+1)
+ 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;
+}
+"""
+
+if __name__ == '__main__':
+ import common; common.generate(
+ name='max2870_regs',
+ regs_tmpl=REGS_TMPL,
+ body_tmpl=BODY_TMPL,
+ file=__file__,
+ )
+
diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt
index 6524a8412..4eb7c8c92 100644
--- a/host/lib/transport/CMakeLists.txt
+++ b/host/lib/transport/CMakeLists.txt
@@ -37,6 +37,10 @@ IF(ENABLE_USB)
${CMAKE_CURRENT_SOURCE_DIR}/libusb1_base.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libusb1_base.hpp
)
+ SET_SOURCE_FILES_PROPERTIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/libusb1_zero_copy.cpp
+ PROPERTIES COMPILE_DEFINITIONS "${LIBUSB_DEFINITIONS}"
+ )
ELSE(ENABLE_USB)
LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/usb_dummy_impl.cpp
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index 28bff9709..3532dc4aa 100644
--- a/host/lib/transport/libusb1_zero_copy.cpp
+++ b/host/lib/transport/libusb1_zero_copy.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2012 Ettus Research LLC
+// Copyright 2010-2013 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
@@ -36,6 +36,12 @@ static const size_t DEFAULT_XFER_SIZE = 32*512; //bytes
#define LIBUSB_CALL
#endif /*LIBUSB_CALL*/
+//! libusb_handle_events_timeout_completed is only in newer API
+#ifndef HAVE_LIBUSB_HANDLE_EVENTS_TIMEOUT_COMPLETED
+ #define libusb_handle_events_timeout_completed(ctx, tx, completed)\
+ libusb_handle_events_timeout(ctx, tx)
+#endif
+
/*!
* All libusb callback functions should be marked with the LIBUSB_CALL macro
* to ensure that they are compiled with the same calling convention as libusb.
@@ -43,7 +49,8 @@ static const size_t DEFAULT_XFER_SIZE = 32*512; //bytes
//! helper function: handles all async callbacks
static void LIBUSB_CALL libusb_async_cb(libusb_transfer *lut){
- *(static_cast<bool *>(lut->user_data)) = true;
+ int *completed = (int *)lut->user_data;
+ *completed = 1;
}
/*!
@@ -61,7 +68,7 @@ static void LIBUSB_CALL libusb_async_cb(libusb_transfer *lut){
* \param completed a reference to the completed flag
* \return true for completion, false for timeout
*/
-UHD_INLINE bool wait_for_completion(libusb_context *ctx, const double timeout, bool &completed){
+UHD_INLINE bool wait_for_completion(libusb_context *ctx, const double timeout, int &completed){
//already completed by a previous call?
if (completed) return true;
@@ -69,7 +76,7 @@ UHD_INLINE bool wait_for_completion(libusb_context *ctx, const double timeout, b
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
- libusb_handle_events_timeout(ctx, &tv);
+ libusb_handle_events_timeout_completed(ctx, &tv, &completed);
if (completed) return true;
//finish the rest with a timeout loop
@@ -78,7 +85,7 @@ UHD_INLINE bool wait_for_completion(libusb_context *ctx, const double timeout, b
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 10000; /*10ms*/
- libusb_handle_events_timeout(ctx, &tv);
+ libusb_handle_events_timeout_completed(ctx, &tv, &completed);
}
return completed;
@@ -96,7 +103,7 @@ public:
_lut(lut), _frame_size(frame_size) { /* NOP */ }
void release(void){
- completed = false;
+ completed = 0;
_lut->length = _frame_size; //always reset length
UHD_ASSERT_THROW(libusb_submit_transfer(_lut) == 0);
}
@@ -109,7 +116,7 @@ public:
return managed_recv_buffer::sptr();
}
- bool completed;
+ int completed;
private:
libusb_context *_ctx;
@@ -129,7 +136,7 @@ public:
_lut(lut), _frame_size(frame_size) { completed = true; }
void release(void){
- completed = false;
+ completed = 0;
_lut->length = size();
UHD_ASSERT_THROW(libusb_submit_transfer(_lut) == 0);
}
@@ -142,7 +149,7 @@ public:
return managed_send_buffer::sptr();
}
- bool completed;
+ int completed;
private:
libusb_context *_ctx;
@@ -249,7 +256,7 @@ public:
}
//process all transfers until timeout occurs
- bool completed = false;
+ int completed = 0;
wait_for_completion(ctx, 0.01, completed);
//free all transfers
diff --git a/host/lib/transport/usb_zero_copy_wrapper.cpp b/host/lib/transport/usb_zero_copy_wrapper.cpp
index d04244ca9..ec5667020 100644
--- a/host/lib/transport/usb_zero_copy_wrapper.cpp
+++ b/host/lib/transport/usb_zero_copy_wrapper.cpp
@@ -176,6 +176,14 @@ public:
}
managed_recv_buffer::sptr get_recv_buff(double timeout){
+ //lazy flush mechanism - negative timeout
+ if (timeout < 0.0)
+ {
+ _last_recv_buff.reset();
+ while (_internal_zc->get_recv_buff()){}
+ return managed_recv_buffer::sptr();
+ }
+
//attempt to get a managed recv buffer
if (not _last_recv_buff){
_last_recv_buff = _internal_zc->get_recv_buff(timeout);
diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp
index c4d050242..b3237d547 100644
--- a/host/lib/usrp/b100/b100_impl.cpp
+++ b/host/lib/usrp/b100/b100_impl.cpp
@@ -516,6 +516,7 @@ void b100_impl::check_fw_compat(void){
"%s"
) % B100_FW_COMPAT_NUM % fw_compat_num % print_images_error()));
}
+ _tree->create<std::string>("/mboards/0/fw_version").set(str(boost::format("%u.0") % fw_compat_num));
}
void b100_impl::check_fpga_compat(void){
diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp
index 723756dcc..bcf712cd9 100644
--- a/host/lib/usrp/b100/io_impl.cpp
+++ b/host/lib/usrp/b100/io_impl.cpp
@@ -153,6 +153,10 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){
id.num_outputs = 1;
my_streamer->set_converter(id);
+ //flush stuff
+ _data_transport->get_recv_buff(-1.0); //negative flushes!!
+ _recv_demuxer = recv_packet_demuxer::make(_data_transport, _rx_dsps.size(), B100_RX_SID_BASE);
+
//bind callbacks for the handler
for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++){
const size_t dsp = args.channels[chan_i];
diff --git a/host/lib/usrp/common/recv_packet_demuxer.cpp b/host/lib/usrp/common/recv_packet_demuxer.cpp
index f2cfe3bb0..fe606213c 100644
--- a/host/lib/usrp/common/recv_packet_demuxer.cpp
+++ b/host/lib/usrp/common/recv_packet_demuxer.cpp
@@ -19,6 +19,8 @@
#include <uhd/utils/msg.hpp>
#include <uhd/utils/byteswap.hpp>
#include <boost/thread/mutex.hpp>
+#include <uhd/transport/vrt_if_packet.hpp>
+#include <uhd/types/metadata.hpp>
#include <queue>
#include <deque>
#include <vector>
@@ -27,6 +29,19 @@ using namespace uhd;
using namespace uhd::usrp;
using namespace uhd::transport;
+struct recv_pkt_demux_mrb : public managed_recv_buffer
+{
+public:
+ recv_pkt_demux_mrb(void){/*NOP*/}
+
+ void release(void)
+ {
+ delete this;
+ }
+
+ boost::uint32_t buff[10];
+};
+
static UHD_INLINE boost::uint32_t extract_sid(managed_recv_buffer::sptr &buff){
//ASSUME that the data is in little endian format
return uhd::wtohx(buff->cast<const boost::uint32_t *>()[1]);
@@ -66,7 +81,20 @@ public:
//otherwise queue and try again
if (rx_index < _queues.size()) _queues[rx_index].wrapper.push(buff);
- else UHD_MSG(error) << "Got a data packet with unknown SID " << extract_sid(buff) << std::endl;
+ else
+ {
+ UHD_MSG(error) << "Got a data packet with unknown SID " << extract_sid(buff) << std::endl;
+ recv_pkt_demux_mrb *mrb = new recv_pkt_demux_mrb();
+ vrt::if_packet_info_t info;
+ info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA;
+ info.num_payload_words32 = 1;
+ info.num_payload_bytes = info.num_payload_words32*sizeof(boost::uint32_t);
+ info.has_sid = true;
+ info.sid = _sid_base + index;
+ vrt::if_hdr_pack_le(mrb->buff, info);
+ mrb->buff[info.num_header_words32] = rx_metadata_t::ERROR_CODE_OVERFLOW;
+ return mrb->make(mrb, mrb->buff, info.num_packet_words32*sizeof(boost::uint32_t));
+ }
}
}
diff --git a/host/lib/usrp/dboard/CMakeLists.txt b/host/lib/usrp/dboard/CMakeLists.txt
index b000c7f33..9e8653608 100644
--- a/host/lib/usrp/dboard/CMakeLists.txt
+++ b/host/lib/usrp/dboard/CMakeLists.txt
@@ -26,6 +26,7 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/db_sbx_common.cpp
${CMAKE_CURRENT_SOURCE_DIR}/db_sbx_version3.cpp
${CMAKE_CURRENT_SOURCE_DIR}/db_sbx_version4.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/db_cbx.cpp
${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_common.cpp
${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_version2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_version3.cpp
diff --git a/host/lib/usrp/dboard/db_cbx.cpp b/host/lib/usrp/dboard/db_cbx.cpp
new file mode 100644
index 000000000..04399e64e
--- /dev/null
+++ b/host/lib/usrp/dboard/db_cbx.cpp
@@ -0,0 +1,212 @@
+//
+// Copyright 2011-2012 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 "max2870_regs.hpp"
+#include "db_sbx_common.hpp"
+
+
+using namespace uhd;
+using namespace uhd::usrp;
+using namespace boost::assign;
+
+/***********************************************************************
+ * Structors
+ **********************************************************************/
+sbx_xcvr::cbx::cbx(sbx_xcvr *_self_sbx_xcvr) {
+ //register the handle to our base CBX class
+ self_base = _self_sbx_xcvr;
+}
+
+
+sbx_xcvr::cbx::~cbx(void){
+ /* NOP */
+}
+
+
+/***********************************************************************
+ * Tuning
+ **********************************************************************/
+double sbx_xcvr::cbx::set_lo_freq(dboard_iface::unit_t unit, double target_freq) {
+ UHD_LOGV(often) << boost::format(
+ "CBX tune: target frequency %f Mhz"
+ ) % (target_freq/1e6) << std::endl;
+
+ //clip the input
+ target_freq = cbx_freq_range.clip(target_freq);
+
+ //map mode setting to valid integer divider (N) values
+ static const uhd::range_t int_n_mode_div_range(16,4095,1);
+ static const uhd::range_t frac_n_mode_div_range(19,4091,1);
+
+ //map rf divider select output dividers to enums
+ static const uhd::dict<int, max2870_regs_t::rf_divider_select_t> rfdivsel_to_enum = map_list_of
+ (1, max2870_regs_t::RF_DIVIDER_SELECT_DIV1)
+ (2, max2870_regs_t::RF_DIVIDER_SELECT_DIV2)
+ (4, max2870_regs_t::RF_DIVIDER_SELECT_DIV4)
+ (8, max2870_regs_t::RF_DIVIDER_SELECT_DIV8)
+ (16, max2870_regs_t::RF_DIVIDER_SELECT_DIV16)
+ (32, max2870_regs_t::RF_DIVIDER_SELECT_DIV32)
+ (64, max2870_regs_t::RF_DIVIDER_SELECT_DIV64)
+ (128, max2870_regs_t::RF_DIVIDER_SELECT_DIV128)
+ ;
+
+ double actual_freq, pfd_freq;
+ double ref_freq = self_base->get_iface()->get_clock_rate(unit);
+ max2870_regs_t::int_n_mode_t int_n_mode;
+ int R=0, BS=0, N=0, FRAC=0, MOD=4095;
+ int RFdiv = 1;
+ max2870_regs_t::reference_divide_by_2_t T = max2870_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
+ max2870_regs_t::reference_doubler_t D = max2870_regs_t::REFERENCE_DOUBLER_DISABLED;
+
+ //Reference doubler for 50% duty cycle
+ // if ref_freq < 12.5MHz enable regs.reference_divide_by_2
+ //NOTE: MAX2870 goes down to 10MHz ref vs. 12.5MHz on ADF4351
+ if(ref_freq <= 10.0e6) D = max2870_regs_t::REFERENCE_DOUBLER_ENABLED;
+
+ //increase RF divider until acceptable VCO frequency
+ double vco_freq = target_freq;
+ //NOTE: MIN freq for MAX2870 VCO is 3GHz vs. 2.2GHz on ADF4351
+ while (vco_freq < 3e9) {
+ vco_freq *= 2;
+ RFdiv *= 2;
+ }
+
+ /*
+ * The goal here is to loop though possible R dividers,
+ * band select clock dividers, N (int) dividers, and FRAC
+ * (frac) dividers.
+ *
+ * Calculate the N and F dividers for each set of values.
+ * The loop exits when it meets all of the constraints.
+ * The resulting loop values are loaded into the registers.
+ *
+ * from pg.21
+ *
+ * f_pfd = f_ref*(1+D)/(R*(1+T))
+ * f_vco = (N + (FRAC/MOD))*f_pfd
+ * N = f_vco/f_pfd - FRAC/MOD = f_vco*((R*(T+1))/(f_ref*(1+D))) - FRAC/MOD
+ * f_rf = f_vco/RFdiv
+ */
+ for(R = 1; R <= 1023; R+=1){
+ //PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D & T)
+ pfd_freq = ref_freq*(1+D)/(R*(1+T));
+
+ //keep the PFD frequency at or below 25MHz
+ if (pfd_freq > 25e6) continue;
+
+ //ignore fractional part of tuning
+ N = int(vco_freq/pfd_freq);
+
+ //Fractional-N calculation
+ FRAC = int((vco_freq/pfd_freq - N)*MOD);
+
+ //are we in int-N or frac-N mode?
+ int_n_mode = (FRAC == 0) ? max2870_regs_t::INT_N_MODE_INT_N : max2870_regs_t::INT_N_MODE_FRAC_N;
+
+ //keep N within int divider requirements
+ if(int_n_mode == max2870_regs_t::INT_N_MODE_INT_N) {
+ if(N < int_n_mode_div_range.start()) continue;
+ if(N > int_n_mode_div_range.stop()) continue;
+ } else {
+ if(N < frac_n_mode_div_range.start()) continue;
+ if(N > frac_n_mode_div_range.stop()) continue;
+ }
+
+ //keep pfd freq low enough to achieve 50kHz BS clock
+ BS = std::ceil(pfd_freq / 50e3);
+ if(BS <= 1023) break;
+ }
+
+ UHD_ASSERT_THROW(R <= 1023);
+
+ //Reference divide-by-2 for 50% duty cycle
+ // if R even, move one divide by 2 to to regs.reference_divide_by_2
+ if(R % 2 == 0){
+ T = max2870_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED;
+ R /= 2;
+ }
+
+ //actual frequency calculation
+ actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv);
+
+ UHD_LOGV(often)
+ << boost::format("CBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl
+ << boost::format("CBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d"
+ ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl
+ << boost::format("CBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"
+ ) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl;
+
+ //load the register values
+ max2870_regs_t regs;
+
+ if ((unit == dboard_iface::UNIT_TX) and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq)))
+ regs.output_power = max2870_regs_t::OUTPUT_POWER_2DBM;
+ else
+ regs.output_power = max2870_regs_t::OUTPUT_POWER_5DBM;
+
+ //set frac/int CPL mode
+ max2870_regs_t::cpl_t cpl;
+ max2870_regs_t::ldf_t ldf;
+ max2870_regs_t::cpoc_t cpoc;
+ if(int_n_mode == max2870_regs_t::INT_N_MODE_INT_N) {
+ cpl = max2870_regs_t::CPL_DISABLED;
+ cpoc = max2870_regs_t::CPOC_ENABLED;
+ ldf = max2870_regs_t::LDF_INT_N;
+ } else {
+ cpl = max2870_regs_t::CPL_ENABLED;
+ ldf = max2870_regs_t::LDF_FRAC_N;
+ cpoc = max2870_regs_t::CPOC_DISABLED;
+ }
+
+ regs.frac_12_bit = FRAC;
+ regs.int_16_bit = N;
+ regs.mod_12_bit = MOD;
+ regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD)));
+ regs.feedback_select = (target_freq >= 3.0e9) ? max2870_regs_t::FEEDBACK_SELECT_DIVIDED : max2870_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
+ regs.r_counter_10_bit = R;
+ regs.reference_divide_by_2 = T;
+ regs.reference_doubler = D;
+ regs.band_select_clock_div = BS;
+ UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(RFdiv));
+ regs.rf_divider_select = rfdivsel_to_enum[RFdiv];
+ regs.int_n_mode = int_n_mode;
+ regs.cpl = cpl;
+ regs.ldf = ldf;
+ regs.cpoc = cpoc;
+
+ //write the registers
+ //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0)
+ int addr;
+
+ for(addr=5; addr>=0; addr--){
+ UHD_LOGV(often) << boost::format(
+ "CBX SPI Reg (0x%02x): 0x%08x"
+ ) % addr % regs.get_reg(addr) << std::endl;
+ self_base->get_iface()->write_spi(
+ unit, spi_config_t::EDGE_RISE,
+ regs.get_reg(addr), 32
+ );
+ }
+
+ //return the actual frequency
+ UHD_LOGV(often) << boost::format(
+ "CBX tune: actual frequency %f Mhz"
+ ) % (actual_freq/1e6) << std::endl;
+ return actual_freq;
+}
+
diff --git a/host/lib/usrp/dboard/db_sbx_common.cpp b/host/lib/usrp/dboard/db_sbx_common.cpp
index 728cb17e9..9db29e65a 100644
--- a/host/lib/usrp/dboard/db_sbx_common.cpp
+++ b/host/lib/usrp/dboard/db_sbx_common.cpp
@@ -32,6 +32,7 @@ static dboard_base::sptr make_sbx(dboard_base::ctor_args_t args){
UHD_STATIC_BLOCK(reg_sbx_dboards){
dboard_manager::register_dboard(0x0054, 0x0055, &make_sbx, "SBX");
dboard_manager::register_dboard(0x0065, 0x0064, &make_sbx, "SBX v4");
+ dboard_manager::register_dboard(0x0067, 0x0066, &make_sbx, "CBX");
}
@@ -114,9 +115,15 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
switch(get_rx_id().to_uint16()) {
case 0x054:
db_actual = sbx_versionx_sptr(new sbx_version3(this));
+ freq_range = sbx_freq_range;
break;
case 0x065:
db_actual = sbx_versionx_sptr(new sbx_version4(this));
+ freq_range = sbx_freq_range;
+ break;
+ case 0x067:
+ db_actual = sbx_versionx_sptr(new cbx(this));
+ freq_range = cbx_freq_range;
break;
default:
/* We didn't recognize the version of the board... */
@@ -128,7 +135,8 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
////////////////////////////////////////////////////////////////////
if(get_rx_id() == 0x054) this->get_rx_subtree()->create<std::string>("name").set("SBXv3 RX");
else if(get_rx_id() == 0x065) this->get_rx_subtree()->create<std::string>("name").set("SBXv4 RX");
- else this->get_rx_subtree()->create<std::string>("name").set("SBX RX");
+ else if(get_rx_id() == 0x067) this->get_rx_subtree()->create<std::string>("name").set("CBX RX");
+ else this->get_rx_subtree()->create<std::string>("name").set("SBX/CBX RX");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
.publish(boost::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_RX));
@@ -141,8 +149,8 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
}
this->get_rx_subtree()->create<double>("freq/value")
.coerce(boost::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
- .set((sbx_freq_range.start() + sbx_freq_range.stop())/2.0);
- this->get_rx_subtree()->create<meta_range_t>("freq/range").set(sbx_freq_range);
+ .set((freq_range.start() + freq_range.stop())/2.0);
+ this->get_rx_subtree()->create<meta_range_t>("freq/range").set(freq_range);
this->get_rx_subtree()->create<std::string>("antenna/value")
.subscribe(boost::bind(&sbx_xcvr::set_rx_ant, this, _1))
.set("RX2");
@@ -159,8 +167,9 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
// Register TX properties
////////////////////////////////////////////////////////////////////
if(get_tx_id() == 0x055) this->get_tx_subtree()->create<std::string>("name").set("SBXv3 TX");
- else if(get_tx_id() == 0x067) this->get_tx_subtree()->create<std::string>("name").set("SBXv4 TX");
- else this->get_tx_subtree()->create<std::string>("name").set("SBX TX");
+ else if(get_tx_id() == 0x064) this->get_tx_subtree()->create<std::string>("name").set("SBXv4 TX");
+ else if(get_tx_id() == 0x066) this->get_tx_subtree()->create<std::string>("name").set("CBX TX");
+ else this->get_tx_subtree()->create<std::string>("name").set("SBX/CBX TX");
this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked")
.publish(boost::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_TX));
@@ -173,8 +182,8 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
}
this->get_tx_subtree()->create<double>("freq/value")
.coerce(boost::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
- .set((sbx_freq_range.start() + sbx_freq_range.stop())/2.0);
- this->get_tx_subtree()->create<meta_range_t>("freq/range").set(sbx_freq_range);
+ .set((freq_range.start() + freq_range.stop())/2.0);
+ this->get_tx_subtree()->create<meta_range_t>("freq/range").set(freq_range);
this->get_tx_subtree()->create<std::string>("antenna/value")
.subscribe(boost::bind(&sbx_xcvr::set_tx_ant, this, _1))
.set(sbx_tx_antennas.at(0));
diff --git a/host/lib/usrp/dboard/db_sbx_common.hpp b/host/lib/usrp/dboard/db_sbx_common.hpp
index 2a0e83115..4f3a2eeaa 100644
--- a/host/lib/usrp/dboard/db_sbx_common.hpp
+++ b/host/lib/usrp/dboard/db_sbx_common.hpp
@@ -100,6 +100,7 @@ using namespace boost::assign;
* The SBX dboard constants
**********************************************************************/
static const freq_range_t sbx_freq_range(400e6, 4.4e9);
+static const freq_range_t cbx_freq_range(1200e6, 6.0e9);
static const freq_range_t sbx_tx_lo_2dbm = list_of
(range_t(0.35e9, 0.37e9))
@@ -213,6 +214,30 @@ protected:
};
/*!
+ * CBX daughterboard
+ *
+ * The only driver difference between SBX and CBX is the MAX2870 vs. ADF435x.
+ * There is also no LO filter switching required, but the GPIO is left blank
+ * so we don't worry about it.
+ */
+ class cbx : public sbx_versionx {
+ public:
+ cbx(sbx_xcvr *_self_sbx_xcvr);
+ ~cbx(void);
+
+ double set_lo_freq(dboard_iface::unit_t unit, double target_freq);
+
+ /*! This is the registered instance of the wrapper class, sbx_base. */
+ sbx_xcvr *self_base;
+ };
+
+ /*!
+ * Frequency range of the daughterboard; this is set in the constructor
+ * to correspond either to SBX or CBX.
+ */
+ freq_range_t freq_range;
+
+ /*!
* Handle to the version-specific implementation of the SBX.
*
* Since many of this class's functions are dependent on the version of the
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp
index f3bdded60..c3af75faa 100644
--- a/host/lib/usrp/gps_ctrl.cpp
+++ b/host/lib/usrp/gps_ctrl.cpp
@@ -26,6 +26,10 @@
#include <boost/thread/thread.hpp>
#include <boost/tokenizer.hpp>
#include <boost/format.hpp>
+#include <boost/regex.hpp>
+
+#include "boost/tuple/tuple.hpp"
+#include "boost/foreach.hpp"
using namespace uhd;
using namespace boost::gregorian;
@@ -38,14 +42,69 @@ using namespace boost::this_thread;
*/
class gps_ctrl_impl : public gps_ctrl{
+private:
+ std::map<std::string, boost::tuple<std::string, boost::system_time, bool> > sensors;
+
+ std::string get_cached_sensor(const std::string sensor, const int freshness, const bool once, const bool touch=true) {
+ boost::system_time time = boost::get_system_time();
+ try {
+ // this is nasty ...
+ //std::cout << boost::format("Requested %s - seen? ") % sensor << sensors[sensor].get<2>() << " once? " << once << std::endl;
+ if(time - sensors[sensor].get<1>() < milliseconds(freshness) && (!once or !sensors[sensor].get<2>())) {
+ sensors[sensor] = boost::make_tuple(sensors[sensor].get<0>(), sensors[sensor].get<1>(), touch);
+ return sensors[sensor].get<0>();
+ } else {
+ return update_cached_sensors(sensor);
+ }
+ } catch(std::exception &e) {
+ UHD_MSG(warning) << "get_cached_sensor: " << e.what();
+ }
+ return std::string();
+ }
+
+ std::string update_cached_sensors(const std::string sensor) {
+ if(not gps_detected() || (gps_type != GPS_TYPE_JACKSON_LABS)) {
+ UHD_MSG(error) << "get_stat(): unsupported GPS or no GPS detected";
+ return std::string();
+ }
+
+ std::string msg = _recv();
+ static const boost::regex status_regex("\\d\\d-\\d\\d-\\d\\d");
+ boost::system_time time = boost::get_system_time();
+ if(msg.size() < 6)
+ return std::string();
+
+ std::string nmea = msg.substr(1,5);
+ const std::list<std::string> list = boost::assign::list_of("GPGGA")("GPRMC");
+ BOOST_FOREACH(std::string key, list) {
+ // beginning matches one of the NMEA keys
+ if(!nmea.compare(key)) {
+ sensors[key] = boost::make_tuple(msg, time, !sensor.compare(key));
+ // if this was what we're looking for return it
+ return (!sensor.compare(key))? msg : std::string();
+ }
+ }
+
+ //We're still here so it's not one of the NMEA strings from above
+ if(boost::regex_search(msg, status_regex, boost::regex_constants::match_continuous)) {
+ trim(msg);
+ sensors["SERVO"] = boost::make_tuple(msg, time, false);
+ if(!sensor.compare("SERVO"))
+ return msg;
+ else
+ return std::string();
+ }
+ return std::string();
+ }
public:
gps_ctrl_impl(uart_iface::sptr uart){
_uart = uart;
+
std::string reply;
bool i_heard_some_nmea = false, i_heard_something_weird = false;
gps_type = GPS_TYPE_NONE;
-
+
//first we look for a Jackson Labs Firefly (since that's what we provide...)
_flush(); //get whatever junk is in the rx buffer right now, and throw it away
_send("HAAAY GUYYYYS\n"); //to elicit a response from the Firefly
@@ -60,7 +119,7 @@ public:
if(reply.find("Command Error") != std::string::npos) {
gps_type = GPS_TYPE_JACKSON_LABS;
break;
- }
+ }
else if(reply.substr(0, 3) == "$GP") i_heard_some_nmea = true; //but keep looking for that "Command Error" response
else if(reply.length() != 0) i_heard_something_weird = true; //probably wrong baud rate
sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
@@ -99,7 +158,8 @@ public:
("gps_gpgga")
("gps_gprmc")
("gps_time")
- ("gps_locked");
+ ("gps_locked")
+ ("gps_servo");
return ret;
}
@@ -108,7 +168,7 @@ public:
or key == "gps_gprmc") {
return sensor_value_t(
boost::to_upper_copy(key),
- get_nmea(boost::to_upper_copy(key.substr(4,8))),
+ get_cached_sensor(boost::to_upper_copy(key.substr(4,8)), GPS_NMEA_NORMAL_FRESHNESS, false, false),
"");
}
else if(key == "gps_time") {
@@ -117,6 +177,9 @@ public:
else if(key == "gps_locked") {
return sensor_value_t("GPS lock status", locked(), "locked", "unlocked");
}
+ else if(key == "gps_servo") {
+ return sensor_value_t("GPS servo status", get_servo(), "");
+ }
else {
throw uhd::value_error("gps ctrl get_sensor unknown key: " + key);
}
@@ -138,24 +201,25 @@ private:
sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
_send("GPS:GPRMC 1\n");
sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+ _send("SERV:TRAC 0\n");
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
}
-
+
//retrieve a raw NMEA sentence
std::string get_nmea(std::string msgtype) {
- msgtype.insert(0, "$");
std::string reply;
- if(not gps_detected()) {
- UHD_MSG(error) << "get_nmea(): unsupported GPS or no GPS detected";
- return std::string();
- }
-
- _flush(); //flush all input before waiting for a message
const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS);
while(boost::get_system_time() < comm_timeout) {
- reply = _recv();
- if(reply.substr(0, 6) == msgtype)
- return reply;
+ if(!msgtype.compare("GPRMC")) {
+ reply = get_cached_sensor(msgtype, GPS_NMEA_FRESHNESS, true);
+ }
+ else {
+ reply = get_cached_sensor(msgtype, GPS_NMEA_LOW_FRESHNESS, false);
+ }
+ if(reply.size()) {
+ if(reply.substr(1, 5) == msgtype) return reply;
+ }
boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
}
throw uhd::value_error(str(boost::format("get_nmea(): no %s message found") % msgtype));
@@ -176,9 +240,10 @@ private:
}
ptime get_time(void) {
+ _flush();
int error_cnt = 0;
ptime gps_time;
- while(error_cnt < 3) {
+ while(error_cnt < 2) {
try {
std::string reply = get_nmea("GPRMC");
@@ -188,29 +253,30 @@ private:
if(datestr.size() == 0 or timestr.size() == 0) {
throw uhd::value_error(str(boost::format("Invalid response \"%s\"") % reply));
}
-
+
//just trust me on this one
- gps_time = ptime( date(
+ gps_time = ptime( date(
greg_year(boost::lexical_cast<int>(datestr.substr(4, 2)) + 2000),
- greg_month(boost::lexical_cast<int>(datestr.substr(2, 2))),
- greg_day(boost::lexical_cast<int>(datestr.substr(0, 2)))
+ greg_month(boost::lexical_cast<int>(datestr.substr(2, 2))),
+ greg_day(boost::lexical_cast<int>(datestr.substr(0, 2)))
),
hours( boost::lexical_cast<int>(timestr.substr(0, 2)))
+ minutes(boost::lexical_cast<int>(timestr.substr(2, 2)))
+ seconds(boost::lexical_cast<int>(timestr.substr(4, 2)))
);
return gps_time;
-
+
} catch(std::exception &e) {
UHD_MSG(warning) << "get_time: " << e.what();
+ _flush();
error_cnt++;
}
}
throw uhd::value_error("Timeout after no valid message found");
-
+
return gps_time; //keep gcc from complaining
}
-
+
time_t get_epoch_time(void) {
return (get_time() - from_time_t(0)).total_seconds();
}
@@ -223,7 +289,7 @@ private:
int error_cnt = 0;
while(error_cnt < 3) {
try {
- std::string reply = get_nmea("GPGGA");
+ std::string reply = get_cached_sensor("GPGGA", GPS_LOCK_FRESHNESS, false, false);
if(reply.size() <= 1) return false;
return (get_token(reply, 6) != "0");
@@ -236,6 +302,29 @@ private:
return false;
}
+ std::string get_servo(void) {
+
+ //enable servo reporting
+ _send("SERV:TRAC 1\n");
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+
+ std::string reply;
+
+ const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS);
+ while(boost::get_system_time() < comm_timeout) {
+ reply = get_cached_sensor("SERVO", GPS_NMEA_LOW_FRESHNESS, false);
+ if(reply.size())
+ {
+ //disable it before leaving function
+ _send("SERV:TRAC 0\n");
+ return reply;
+ }
+ boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
+ }
+ throw uhd::value_error("get_stat(): no servo message found");
+ return std::string();
+ }
+
uart_iface::sptr _uart;
void _flush(void){
@@ -258,7 +347,12 @@ private:
GPS_TYPE_NONE
} gps_type;
- static const int GPS_COMM_TIMEOUT_MS = 1500;
+ static const int GPS_COMM_TIMEOUT_MS = 1300;
+ static const int GPS_NMEA_FRESHNESS = 10;
+ static const int GPS_NMEA_LOW_FRESHNESS = 2500;
+ static const int GPS_NMEA_NORMAL_FRESHNESS = 1000;
+ static const int GPS_SERVO_FRESHNESS = 2500;
+ static const int GPS_LOCK_FRESHNESS = 2500;
static const int GPS_TIMEOUT_DELAY_MS = 200;
static const int FIREFLY_STUPID_DELAY_MS = 200;
};
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 0331cf93a..46dd8b670 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -140,6 +140,14 @@ static tune_result_t tune_xx_subdev_and_dsp(
}
//------------------------------------------------------------------
+ //-- poke the tune request args into the dboard
+ //------------------------------------------------------------------
+ if (rf_fe_subtree->exists("tune_args"))
+ {
+ rf_fe_subtree->access<device_addr_t>("tune_args").set(tune_request.args);
+ }
+
+ //------------------------------------------------------------------
//-- set the RF frequency depending upon the policy
//------------------------------------------------------------------
double target_rf_freq = 0.0;
diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt
index 95105f917..a28e1f9ef 100644
--- a/host/lib/utils/CMakeLists.txt
+++ b/host/lib/utils/CMakeLists.txt
@@ -115,14 +115,14 @@ SET_SOURCE_FILES_PROPERTIES(
########################################################################
# Define UHD_PKG_DATA_PATH for paths.cpp
########################################################################
-FILE(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${PKG_DATA_DIR} UHD_PKG_DATA_PATH)
-STRING(REPLACE "\\" "\\\\" UHD_PKG_DATA_PATH ${UHD_PKG_DATA_PATH})
-MESSAGE(STATUS "Full package data directory: ${UHD_PKG_DATA_PATH}")
+FILE(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX} UHD_PKG_PATH)
+STRING(REPLACE "\\" "\\\\" UHD_PKG_PATH ${UHD_PKG_PATH})
SET_SOURCE_FILES_PROPERTIES(
${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/images.cpp
PROPERTIES COMPILE_DEFINITIONS
- "UHD_PKG_DATA_PATH=\"${UHD_PKG_DATA_PATH}\""
+ "UHD_PKG_PATH=\"${UHD_PKG_PATH}\";UHD_LIB_DIR=\"lib${LIB_SUFFIX}\""
)
########################################################################
diff --git a/host/lib/utils/images.cpp b/host/lib/utils/images.cpp
index 251cadeaa..1ba2f81e6 100644
--- a/host/lib/utils/images.cpp
+++ b/host/lib/utils/images.cpp
@@ -42,7 +42,7 @@ std::string uhd::find_image_path(const std::string &image_name){
}
std::string uhd::find_images_downloader(void){
- return fs::path((fs::path(get_pkg_data_path()) / "utils" / "uhd_images_downloader.py")).string();
+ return fs::path(fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "utils" / "uhd_images_downloader.py").string();
}
std::string uhd::print_images_error(void){
diff --git a/host/lib/utils/paths.cpp b/host/lib/utils/paths.cpp
index 26fa6d1c7..53055314b 100644
--- a/host/lib/utils/paths.cpp
+++ b/host/lib/utils/paths.cpp
@@ -71,20 +71,20 @@ static std::vector<fs::path> get_env_paths(const std::string &var_name){
/***********************************************************************
* Get a list of special purpose paths
**********************************************************************/
-std::string uhd::get_pkg_data_path(void)
+std::string uhd::get_pkg_path(void)
{
- return get_env_var("UHD_PKG_DATA_PATH", UHD_PKG_DATA_PATH);
+ return get_env_var("UHD_PKG_PATH", UHD_PKG_PATH);
}
std::vector<fs::path> get_image_paths(void){
std::vector<fs::path> paths = get_env_paths("UHD_IMAGE_PATH");
- paths.push_back(fs::path(uhd::get_pkg_data_path()) / "images");
+ paths.push_back(fs::path(uhd::get_pkg_path()) / "share" / "uhd" / "images");
return paths;
}
std::vector<fs::path> get_module_paths(void){
std::vector<fs::path> paths = get_env_paths("UHD_MODULE_PATH");
- paths.push_back(fs::path(uhd::get_pkg_data_path()) / "modules");
+ paths.push_back(fs::path(uhd::get_pkg_path()) / UHD_LIB_DIR / "uhd" / "modules");
return paths;
}
diff --git a/host/tests/CMakeLists.txt b/host/tests/CMakeLists.txt
index e9d1e5e92..2a40d0050 100644
--- a/host/tests/CMakeLists.txt
+++ b/host/tests/CMakeLists.txt
@@ -16,6 +16,11 @@
#
########################################################################
+# unit test support
+########################################################################
+include(UHDUnitTest)
+
+########################################################################
# unit test suite
########################################################################
SET(test_sources
@@ -39,12 +44,15 @@ SET(test_sources
#turn each test cpp file into an executable with an int main() function
ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN)
-#for each source: build an executable, register it as a test, and install
+SET(UHD_TEST_TARGET_DEPS uhd)
+SET(UHD_TEST_LIBRARY_DIRS ${Boost_LIBRARY_DIRS})
+
+#for each source: build an executable, register it as a test
FOREACH(test_source ${test_sources})
GET_FILENAME_COMPONENT(test_name ${test_source} NAME_WE)
ADD_EXECUTABLE(${test_name} ${test_source})
TARGET_LINK_LIBRARIES(${test_name} uhd)
- ADD_TEST(${test_name} ${test_name})
+ UHD_ADD_TEST(${test_name} ${test_name})
UHD_INSTALL(TARGETS ${test_name} RUNTIME DESTINATION ${PKG_LIB_DIR}/tests COMPONENT tests)
ENDFOREACH(test_source)
diff --git a/host/utils/fx2_init_eeprom.cpp b/host/utils/fx2_init_eeprom.cpp
index c210ae575..701092a5d 100644
--- a/host/utils/fx2_init_eeprom.cpp
+++ b/host/utils/fx2_init_eeprom.cpp
@@ -41,12 +41,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
- po::notify(vm);
+ po::notify(vm);
//print the help message
if (vm.count("help")){
std::cout << boost::format("USRP EEPROM initialization %s") % desc << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//cant find a uninitialized usrp with this mystery module in the way...
@@ -76,7 +76,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
if (found_addrs.size() == 0){
std::cerr << "No USRP devices found" << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
for (size_t i = 0; i < found_addrs.size(); i++){
@@ -89,5 +89,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout << "Power-cycle the usrp for the changes to take effect." << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/query_gpsdo_sensors.cpp b/host/utils/query_gpsdo_sensors.cpp
index 8e34bb3d5..91088112c 100644
--- a/host/utils/query_gpsdo_sensors.cpp
+++ b/host/utils/query_gpsdo_sensors.cpp
@@ -27,6 +27,7 @@
#include <boost/thread.hpp>
#include <string>
#include <cmath>
+#include <ctime>
#include <cstdlib>
namespace po = boost::program_options;
@@ -102,6 +103,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//Check PPS and compare UHD device time to GPS time
boost::this_thread::sleep(boost::posix_time::seconds(1));
uhd::sensor_value_t gps_time = usrp->get_mboard_sensor("gps_time");
+ const time_t pc_clock_time = time(NULL);
const uhd::time_spec_t last_pps_time = usrp->get_time_last_pps();
if (last_pps_time.to_ticks(1.0) == gps_time.to_int()) {
std::cout << boost::format("GPS and UHD Device time are aligned.\n");
@@ -114,6 +116,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
uhd::sensor_value_t rmc_string = usrp->get_mboard_sensor("gps_gprmc");
std::cout << boost::format("%s\n%s\n%s\n") % gga_string.to_pp_string() % rmc_string.to_pp_string() % gps_time.to_pp_string();
std::cout << boost::format("UHD Device time: %.0f seconds\n") % (last_pps_time.get_real_secs());
+ std::cout << boost::format("PC Clock time: %.0f seconds\n") % pc_clock_time;
//finished
std::cout << boost::format("\nDone!\n\n");
diff --git a/host/utils/uhd_cal_rx_iq_balance.cpp b/host/utils/uhd_cal_rx_iq_balance.cpp
index 68d0443da..5fb494114 100644
--- a/host/utils/uhd_cal_rx_iq_balance.cpp
+++ b/host/utils/uhd_cal_rx_iq_balance.cpp
@@ -29,6 +29,7 @@
#include <complex>
#include <cmath>
#include <ctime>
+#include <cstdlib>
namespace po = boost::program_options;
@@ -120,7 +121,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout <<
"This application measures leakage between RX and TX on an XCVR daughterboard to self-calibrate.\n"
<< std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//create a usrp device
@@ -239,5 +240,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
store_results(usrp, results, "RX", "rx", "iq");
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/uhd_cal_tx_dc_offset.cpp b/host/utils/uhd_cal_tx_dc_offset.cpp
index 8f69b3ce1..c9cf757f4 100644
--- a/host/utils/uhd_cal_tx_dc_offset.cpp
+++ b/host/utils/uhd_cal_tx_dc_offset.cpp
@@ -123,7 +123,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout <<
"This application measures leakage between RX and TX on an XCVR daughterboard to self-calibrate.\n"
<< std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//create a usrp device
@@ -237,5 +237,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
store_results(usrp, results, "TX", "tx", "dc");
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/uhd_cal_tx_iq_balance.cpp b/host/utils/uhd_cal_tx_iq_balance.cpp
index 5478b07e3..20d018edf 100644
--- a/host/utils/uhd_cal_tx_iq_balance.cpp
+++ b/host/utils/uhd_cal_tx_iq_balance.cpp
@@ -28,6 +28,7 @@
#include <iostream>
#include <complex>
#include <ctime>
+#include <cstdlib>
namespace po = boost::program_options;
@@ -123,7 +124,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout <<
"This application measures leakage between RX and TX on an XCVR daughterboard to self-calibrate.\n"
<< std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//create a usrp device
@@ -242,5 +243,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
store_results(usrp, results, "TX", "tx", "iq");
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/uhd_find_devices.cpp b/host/utils/uhd_find_devices.cpp
index b778eeb68..c258c580e 100644
--- a/host/utils/uhd_find_devices.cpp
+++ b/host/utils/uhd_find_devices.cpp
@@ -20,6 +20,7 @@
#include <boost/program_options.hpp>
#include <boost/format.hpp>
#include <iostream>
+#include <cstdlib>
namespace po = boost::program_options;
@@ -37,7 +38,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//print the help message
if (vm.count("help")){
std::cout << boost::format("UHD Find Devices %s") % desc << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//discover the usrps and print the results
@@ -45,7 +46,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
if (device_addrs.size() == 0){
std::cerr << "No UHD Devices Found" << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
for (size_t i = 0; i < device_addrs.size(); i++){
@@ -56,5 +57,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//uhd::device::make(device_addrs[i]); //test make
}
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp
index 5b3702fb4..736490f19 100644
--- a/host/utils/uhd_usrp_probe.cpp
+++ b/host/utils/uhd_usrp_probe.cpp
@@ -30,6 +30,7 @@
#include <iostream>
#include <sstream>
#include <vector>
+#include <cstdlib>
namespace po = boost::program_options;
using namespace uhd;
@@ -197,12 +198,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//print the help message
if (vm.count("help")){
std::cout << boost::format("UHD USRP Probe %s") % desc << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
if (vm.count("version")){
std::cout << uhd::get_version_string() << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
device::sptr dev = device::make(vm["args"].as<std::string>());
@@ -210,11 +211,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
if (vm.count("string")){
std::cout << tree->access<std::string>(vm["string"].as<std::string>()).get() << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
if (vm.count("tree") != 0) print_tree("/", tree);
else std::cout << make_border(get_device_pp_string(tree)) << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/usrp_burn_db_eeprom.cpp b/host/utils/usrp_burn_db_eeprom.cpp
index b6b2dc4d6..3ca953115 100644
--- a/host/utils/usrp_burn_db_eeprom.cpp
+++ b/host/utils/usrp_burn_db_eeprom.cpp
@@ -58,7 +58,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
"Omit the ID argument to perform readback,\n"
"Or specify a new ID to burn into the EEPROM.\n"
) << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//make the device and extract the dboard w/ property
@@ -96,5 +96,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout << boost::format(" Current revision: \"%s\"") % db_eeprom.revision << std::endl;
std::cout << " Done" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/usrp_burn_mb_eeprom.cpp b/host/utils/usrp_burn_mb_eeprom.cpp
index ca9a6c8ba..1b13fb615 100644
--- a/host/utils/usrp_burn_mb_eeprom.cpp
+++ b/host/utils/usrp_burn_mb_eeprom.cpp
@@ -47,7 +47,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
"Omit the value argument to perform a readback,\n"
"Or specify a new value to burn into the EEPROM.\n"
) << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
std::cout << "Creating USRP device from address: " + args << std::endl;
@@ -60,7 +60,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
uhd::usrp::mboard_eeprom_t mb_eeprom = tree->access<uhd::usrp::mboard_eeprom_t>("/mboards/0/eeprom").get();
if (not mb_eeprom.has_key(key)){
std::cerr << boost::format("Cannot find value for EEPROM[%s]") % key << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % key % mb_eeprom[key] << std::endl;
std::cout << std::endl;
@@ -74,5 +74,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
}
std::cout << "Done" << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/images/Makefile b/images/Makefile
index 562aa76c0..2e3bcfd26 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright 2010-2011 Ettus Research LLC
+# Copyright 2010-2013 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
@@ -52,6 +52,12 @@ ifeq ($(shell xtclsh -h > /dev/null 2>&1 && echo $$?),0)
HAS_XTCLSH=1
endif
+ifeq ($(shell avr-gcc --version > /dev/null 2>&1 && echo $$?),0)
+ ifeq ($(shell avr-objcopy --version > /dev/null 2>&1 && echo $$?),0)
+ HAS_AVR_UTILS=1
+ endif
+endif
+
########################################################################
# USRP1 and B100 firmware
########################################################################
@@ -277,6 +283,22 @@ $(_usrp_e110_fpga_bin): $(GLOBAL_DEPS)
endif
########################################################################
+# OctoClock firmware
+########################################################################
+
+ifdef HAS_AVR_UTILS
+
+_octoclock_fw_dir = $(TOP_FW_DIR)/octoclock
+_octoclock_fw_bin = $(BUILT_IMAGES_DIR)/octoclock_fw.hex
+IMAGES_LIST += $(_octoclock_fw_bin)
+
+$(_octoclock_fw_bin): $(GLOBAL_DEPS)
+ cd $(_octoclock_fw_dir) && make -f Makefile clean
+ cd $(_octoclock_fw_dir) && make -f Makefile all
+ cp $(TOP_FW_DIR)/octoclock/octoclock_fw.hex $@
+endif
+
+########################################################################
# Build rules
########################################################################
images: $(IMAGES_LIST)