summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnuradio-runtime/python/gnuradio/gr/top_block.py11
-rw-r--r--gr-digital/include/gnuradio/digital/header_payload_demux.h71
-rw-r--r--gr-digital/lib/header_payload_demux_impl.cc14
-rw-r--r--gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc15
-rw-r--r--gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h1
-rw-r--r--gr-dtv/lib/dvbt/dvbt_configure.cc3
-rw-r--r--gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.cc3
-rw-r--r--gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc4
-rw-r--r--gr-dtv/lib/dvbt/dvbt_symbol_inner_interleaver_impl.cc3
-rw-r--r--gr-dtv/lib/dvbt2/dvbt2_framemapper_cc_impl.cc63
-rw-r--r--gr-dtv/lib/dvbt2/dvbt2_framemapper_cc_impl.h3
-rw-r--r--gr-dtv/lib/dvbt2/dvbt2_modulator_bc_impl.cc2
-rw-r--r--gr-dtv/lib/dvbt2/dvbt2_p1insertion_cc_impl.cc4
-rw-r--r--gr-dtv/lib/dvbt2/dvbt2_paprtr_cc_impl.cc2
-rw-r--r--gr-uhd/include/gnuradio/uhd/usrp_block.h56
-rw-r--r--gr-uhd/lib/usrp_block_impl.cc38
-rw-r--r--gr-uhd/lib/usrp_block_impl.h13
-rw-r--r--gr-utils/python/modtool/cmakefile_editor.py34
-rw-r--r--grc/base/Connection.py2
-rw-r--r--grc/base/ParseXML.py31
-rw-r--r--grc/gui/PropsDialog.py7
-rw-r--r--grc/python/Generator.py2
22 files changed, 262 insertions, 120 deletions
diff --git a/gnuradio-runtime/python/gnuradio/gr/top_block.py b/gnuradio-runtime/python/gnuradio/gr/top_block.py
index f449d98489..2efcbd9aae 100644
--- a/gnuradio-runtime/python/gnuradio/gr/top_block.py
+++ b/gnuradio-runtime/python/gnuradio/gr/top_block.py
@@ -63,11 +63,13 @@ class _top_block_waiter(_threading.Thread):
top_block_wait_unlocked(self.tb)
self.event.set()
- def wait(self):
+ def wait(self, handle_sigint=True):
try:
- while not self.event.isSet():
- self.event.wait(0.100)
+ while not self.event.wait(0.1):
+ pass
except KeyboardInterrupt:
+ if not handle_sigint:
+ raise
self.tb.stop()
self.wait()
@@ -98,6 +100,7 @@ class top_block(hier_block2):
"""
# not calling hier_block2.__init__, we set our own _impl
self._impl = top_block_swig(name)
+ self.handle_sigint = True
def start(self, max_noutput_items=10000000):
"""
@@ -128,7 +131,7 @@ class top_block(hier_block2):
"""
Wait for the flowgraph to finish running
"""
- _top_block_waiter(self._impl).wait()
+ _top_block_waiter(self._impl).wait(self.handle_sigint)
def dot_graph(self):
"""
diff --git a/gr-digital/include/gnuradio/digital/header_payload_demux.h b/gr-digital/include/gnuradio/digital/header_payload_demux.h
index d68c4ab9f3..303bebbf32 100644
--- a/gr-digital/include/gnuradio/digital/header_payload_demux.h
+++ b/gr-digital/include/gnuradio/digital/header_payload_demux.h
@@ -33,11 +33,20 @@ namespace gr {
* \ingroup packet_operators_blk
*
* \details
- * This block is designed to handle packets from a bursty transmission.
- * Input 0 takes a continuous transmission of samples.
- * If used, input 1 is a trigger signal. In this case, a 1 on input 1
- * is a trigger. Otherwise, a tag with the key specified in \p trigger_tag_key
- * is used as a trigger (its value is irrelevant).
+ * This block is designed to demultiplex packets from a bursty transmission.
+ * The typical application for this block is the case when you are receiving
+ * packets with yet-to-determine length. This block will pass the header
+ * section to other blocks for demodulation. Using the information from the
+ * demodulated header, it will then output the payload. The beginning of the
+ * header needs to be identified by a trigger signal (see below).
+ *
+ * \section hpd_theory_of_ops Theory of Operation
+ *
+ * Input 0 takes a continuous transmission of samples (items).
+ * Input 1 is an optional input for the trigger signal (mark beginning of
+ * packets). In this case, a non-zero value on input 1 identifies the beginning of a packet.
+ * Otherwise, a tag with the key specified in \p trigger_tag_key is used as a
+ * trigger (its value is irrelevant).
*
* Until a trigger signal is detected, all samples are dropped onto the floor.
* Once a trigger is detected, a total of \p header_len items are copied to output 0.
@@ -49,9 +58,33 @@ namespace gr {
* and taken as the payload length. The payload, together with the header data
* as tags, is then copied to output 1.
*
+ * \section hpd_item_sizes Symbols, Items and Item Sizes
+ *
+ * To generically and transparently handle different kinds of modulations,
+ * including OFDM, this block distinguises between \b symbols and \b items.
+ *
+ * Items are what are consumed at the input. Anything that uses complex samples
+ * will therefore use an itemsize of `sizeof(gr_complex)`. Symbols are a way of
+ * grouping items. In OFDM, we usually don't care about individual samples, but
+ * we do care about full OFDM symbols, so we set \p items_per_symbol to the
+ * IFFT / FFT length of the OFDM modulator / demodulator.
+ * For most single-carrier modulations, this value can be set to 1 (the default
+ * value).
* If specified, \p guard_interval items are discarded before every symbol.
* This is useful for demuxing bursts of OFDM signals.
*
+ * On the output, we can deal with symbols directly by setting \p output_symbols
+ * to true. In that case, the output item size is the <em>symbol size</em>.
+ *
+ * \b Example: OFDM with 48 sub-carriers, using a length-64 IFFT on the modulator,
+ * and a cyclic-prefix length of 16 samples. In this case, the itemsize is
+ * `sizeof(gr_complex)`, because we're receiving complex samples. One OFDM symbol
+ * has 64 samples, hence \p items_per_symbol is set to 64, and \p guard_interval to
+ * 16. The header length is specified in number of OFDM symbols. Because we want to
+ * deal with full OFDM symbols, we set \p output_symbols to true.
+ *
+ * \section hpd_tag_handling Tag Handling
+ *
* Any tags on the input stream are copied to the corresponding output *if* they're
* on an item that is propagated. Note that a tag on the header items is copied to the
* header stream; that means the header-parsing block must handle these tags if they
@@ -59,12 +92,12 @@ namespace gr {
* A special case are tags on items that make up the guard interval. These are copied
* to the first item of the following symbol.
* If a tag is situated very close to the end of the payload, it might be unclear if
- * it belongs to this packet or the following. In this case, the tag might be propagated
- * twice.
+ * it belongs to this packet or the following. In this case, it is possible that the
+ * tag might be propagated twice.
*
* Tags outside of packets are generally discarded. If this information is important,
* there are two additional mechanisms to preserve the tags:
- * - Timing tags might be relevant to know <em>when</em> a packet was received. By
+ * - Timing tags might be relevant to know \b when a packet was received. By
* specifying the name of a timestamp tag and the sample rate at this block, it
* keeps track of the time and will add the time to the first item of every packet.
* The name of the timestamp tag is usually 'rx_time' (see gr::uhd::usrp_source::make()).
@@ -90,19 +123,19 @@ namespace gr {
* \param itemsize Item size (bytes per item)
* \param timing_tag_key The name of the tag with timing information, usually 'rx_time' or empty (this means timing info is discarded)
* \param samp_rate Sampling rate at the input. Necessary to calculate the rx time of packets.
- * \param special_tags A vector of strings denoting tags which shall be preserved.
+ * \param special_tags A vector of strings denoting tags which shall be preserved (see \ref hpd_tag_handling)
*/
static sptr make(
- int header_len,
- int items_per_symbol,
- int guard_interval=0,
- const std::string &length_tag_key="frame_len",
- const std::string &trigger_tag_key="",
- bool output_symbols=false,
- size_t itemsize=sizeof(gr_complex),
- const std::string &timing_tag_key="",
- const double samp_rate=1.0,
- const std::vector<std::string> &special_tags=std::vector<std::string>()
+ int header_len,
+ int items_per_symbol=1,
+ int guard_interval=0,
+ const std::string &length_tag_key="frame_len",
+ const std::string &trigger_tag_key="",
+ bool output_symbols=false,
+ size_t itemsize=sizeof(gr_complex),
+ const std::string &timing_tag_key="",
+ const double samp_rate=1.0,
+ const std::vector<std::string> &special_tags=std::vector<std::string>()
);
};
diff --git a/gr-digital/lib/header_payload_demux_impl.cc b/gr-digital/lib/header_payload_demux_impl.cc
index 160f54036d..89428fa86e 100644
--- a/gr-digital/lib/header_payload_demux_impl.cc
+++ b/gr-digital/lib/header_payload_demux_impl.cc
@@ -221,7 +221,13 @@ namespace gr {
in += d_itemsize;
nread++;
d_state = STATE_FIND_TRIGGER;
- // Fall through
+ // The following break was added to this state as well as STATE_FIND_TRIGGER
+ // and STATE_HEADER. There appears to be a bug somewhere in this code without
+ // the breaks that can lead to failure of this block. With the breaks in the code
+ // testing has shown more stable performance with various block paramters.
+ // If an offset calculation bug is found and fixed, it should be possible to
+ // remove these breaks for some performance increase.
+ break;
case STATE_FIND_TRIGGER:
trigger_offset = find_trigger_signal(nread, noutput_items, input_items);
@@ -234,7 +240,7 @@ namespace gr {
consume_each (trigger_offset);
in += trigger_offset * d_itemsize;
d_state = STATE_HEADER;
- // Fall through
+ break;
case STATE_HEADER:
if (check_items_available(d_header_len, ninput_items, noutput_items, nread)) {
@@ -262,7 +268,7 @@ namespace gr {
consume_each (nread);
in += nread * d_itemsize;
d_state = STATE_PAYLOAD;
- // Fall through
+ break;
case STATE_PAYLOAD:
if (check_items_available(d_curr_payload_len, ninput_items, noutput_items, nread)) {
@@ -274,7 +280,7 @@ namespace gr {
set_min_noutput_items(d_output_symbols ? 1 : (d_items_per_symbol + d_gi));
d_state = STATE_FIND_TRIGGER;
}
- break;
+ break;
default:
throw std::runtime_error("invalid state");
diff --git a/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc b/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc
index e0c80ea304..551191c0e5 100644
--- a/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc
+++ b/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc
@@ -406,29 +406,24 @@ namespace gr {
m_frame[0] = 0;
m_frame[1] = 1;
m_frame_offset_bits = 2;
- temp = 0;
for (int n = 30; n >= 0; n--) {
- m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ m_frame[m_frame_offset_bits++] = 0;
}
- temp = 0;
for (int n = 21; n >= 0; n--) {
- m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ m_frame[m_frame_offset_bits++] = 0;
}
- temp = 0;
for (int n = 1; n >= 0; n--) {
- m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ m_frame[m_frame_offset_bits++] = 0;
}
- temp = 0;
for (int n = 9; n >= 0; n--) {
- m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ m_frame[m_frame_offset_bits++] = 0;
}
temp = ts_rate;
for (int n = 26; n >= 0; n--) {
m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
}
- temp = 0;
for (int n = 9; n >= 0; n--) {
- m_frame[m_frame_offset_bits++] = temp & (1 << n) ? 1 : 0;
+ m_frame[m_frame_offset_bits++] = 0;
}
}
diff --git a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h
index 3510ddf083..92c9eb370e 100644
--- a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h
+++ b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h
@@ -42,7 +42,6 @@ namespace gr {
unsigned int nbch;
unsigned int code_rate;
unsigned int q_val;
- unsigned int table_length;
unsigned int dvb_standard;
void ldpc_lookup_generate(void);
ldpc_encode_table ldpc_encode;
diff --git a/gr-dtv/lib/dvbt/dvbt_configure.cc b/gr-dtv/lib/dvbt/dvbt_configure.cc
index 1cd1b833c4..a6d1af7874 100644
--- a/gr-dtv/lib/dvbt/dvbt_configure.cc
+++ b/gr-dtv/lib/dvbt/dvbt_configure.cc
@@ -101,6 +101,9 @@ namespace gr {
{
d_symbols_per_frame = 68;
d_frames_per_superframe = 4;
+ d_symbol_index = 0;
+ d_frame_index = 0;
+ d_superframe_index = 0;
switch (d_transmission_mode) {
case T2k:
diff --git a/gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.cc b/gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.cc
index 9b497195ee..03dd0ffec5 100644
--- a/gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.cc
+++ b/gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.cc
@@ -68,7 +68,8 @@ namespace gr {
: gr::block("dvbt_energy_dispersal",
gr::io_signature::make(1, 1, sizeof(unsigned char)),
gr::io_signature::make(1, 1, sizeof(unsigned char) * nblocks * d_npacks * d_psize)),
- d_nblocks(nblocks)
+ d_nblocks(nblocks),
+ d_reg(0xa9)
{
set_relative_rate(1.0/(double) (d_nblocks * d_npacks * d_psize));
}
diff --git a/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc b/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc
index d64b403915..58fc76c64e 100644
--- a/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc
+++ b/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc
@@ -166,6 +166,10 @@ namespace gr {
d_tps_carriers = d_tps_carriers_2k;
}
+ d_freq_offset = 0;
+ d_carrier_freq_correction = 0.0;
+ d_sampling_freq_correction = 0.0;
+
//allocate PRBS buffer
d_wk = new char[d_Kmax - d_Kmin + 1];
if (d_wk == NULL) {
diff --git a/gr-dtv/lib/dvbt/dvbt_symbol_inner_interleaver_impl.cc b/gr-dtv/lib/dvbt/dvbt_symbol_inner_interleaver_impl.cc
index 7c2e2f7e1a..64d242d5fb 100644
--- a/gr-dtv/lib/dvbt/dvbt_symbol_inner_interleaver_impl.cc
+++ b/gr-dtv/lib/dvbt/dvbt_symbol_inner_interleaver_impl.cc
@@ -66,9 +66,6 @@ namespace gr {
else if (i == 1) {
reg = 0;
}
- else if (reg == 2) {
- reg = 1;
- }
else {
reg = 1;
for (int k = 3; k <= i; k++) {
diff --git a/gr-dtv/lib/dvbt2/dvbt2_framemapper_cc_impl.cc b/gr-dtv/lib/dvbt2/dvbt2_framemapper_cc_impl.cc
index aef610fe33..0c05285eda 100644
--- a/gr-dtv/lib/dvbt2/dvbt2_framemapper_cc_impl.cc
+++ b/gr-dtv/lib/dvbt2/dvbt2_framemapper_cc_impl.cc
@@ -86,9 +86,6 @@ namespace gr {
break;
}
}
- fef_present = FALSE; /* for testing only */
- fef_length = 134144; /* " " " */
- fef_interval = 1; /* " " " */
l1preinit->type = STREAMTYPE_TS;
l1preinit->bwt_ext = carriermode;
fft_size = fftsize;
@@ -100,12 +97,7 @@ namespace gr {
l1preinit->l1_mod = l1constellation;
l1preinit->l1_cod = 0;
l1preinit->l1_fec_type = 0;
- if (fef_present == FALSE) {
- l1preinit->l1_post_info_size = KSIG_POST - 32;
- }
- else {
- l1preinit->l1_post_info_size = KSIG_POST + 34 - 32;
- }
+ l1preinit->l1_post_info_size = KSIG_POST - 32;
l1preinit->pilot_pattern = pilotpattern;
l1preinit->tx_id_availability = 0;
l1preinit->cell_id = 0;
@@ -144,12 +136,7 @@ namespace gr {
l1postinit->ff_flag = 0;
l1postinit->first_rf_idx = 0;
l1postinit->first_frame_idx = 0;
- if (fef_present == FALSE) {
- l1postinit->plp_group_id = 1;
- }
- else {
- l1postinit->plp_group_id = 0;
- }
+ l1postinit->plp_group_id = 1;
switch (rate) {
case C1_3:
l1postinit->plp_cod = 6;
@@ -205,14 +192,8 @@ namespace gr {
else {
l1postinit->plp_mode = inputmode + 1;
}
- if (fef_present == FALSE) {
- l1postinit->static_flag = 0;
- l1postinit->static_padding_flag = 0;
- }
- else {
- l1postinit->static_flag = 1;
- l1postinit->static_padding_flag = 1;
- }
+ l1postinit->static_flag = 0;
+ l1postinit->static_padding_flag = 0;
l1postinit->fef_length_msb = 0;
if (reservedbiasbits == RESERVED_ON && version == VERSION_131) {
l1postinit->reserved_2 = 0x3fffffff;
@@ -351,6 +332,11 @@ namespace gr {
eta_mod = 6;
break;
}
+ N_P2 = 0;
+ C_P2 = 0;
+ N_FC = 0;
+ C_FC = 0;
+ C_DATA = 0;
if ((preamble == PREAMBLE_T2_SISO) || (preamble == PREAMBLE_T2_LITE_SISO)) {
switch (fft_size) {
case FFTSIZE_1K:
@@ -904,14 +890,8 @@ namespace gr {
C_FC = 0;
}
}
- if (fef_present == FALSE) {
- N_punc_temp = (6 * (KBCH_1_2 - KSIG_POST)) / 5;
- N_post_temp = KSIG_POST + NBCH_PARITY + 9000 - N_punc_temp;
- }
- else {
- N_punc_temp = (6 * (KBCH_1_2 - (KSIG_POST + 34))) / 5;
- N_post_temp = (KSIG_POST + 34) + NBCH_PARITY + 9000 - N_punc_temp;
- }
+ N_punc_temp = (6 * (KBCH_1_2 - KSIG_POST)) / 5;
+ N_post_temp = KSIG_POST + NBCH_PARITY + 9000 - N_punc_temp;
if (N_P2 == 1) {
N_post = ceil((float)N_post_temp / (2 * (float)eta_mod)) * 2 * eta_mod;
}
@@ -1166,12 +1146,7 @@ namespace gr {
for (int n = 2; n >= 0; n--) {
l1pre[offset_bits++] = temp & (1 << n) ? 1 : 0;
}
- if (fef_present == FALSE) {
- l1pre[offset_bits++] = 0;
- }
- else {
- l1pre[offset_bits++] = 1;
- }
+ l1pre[offset_bits++] = 0;
l1pre[offset_bits++] = l1preinit->l1_repetition_flag;
temp = l1preinit->guard_interval;
for (int n = 2; n >= 0; n--) {
@@ -1356,20 +1331,6 @@ namespace gr {
for (int n = 31; n >= 0; n--) {
l1post[offset_bits++] = temp & (1 << n) ? 1 : 0;
}
- if (fef_present == TRUE) {
- temp = 0;
- for (int n = 3; n >= 0; n--) {
- l1post[offset_bits++] = temp & (1 << n) ? 1 : 0;
- }
- temp = fef_length;
- for (int n = 21; n >= 0; n--) {
- l1post[offset_bits++] = temp & (1 << n) ? 1 : 0;
- }
- temp = fef_interval;
- for (int n = 7; n >= 0; n--) {
- l1post[offset_bits++] = temp & (1 << n) ? 1 : 0;
- }
- }
temp = l1postinit->plp_id;
for (int n = 7; n >= 0; n--) {
l1post[offset_bits++] = temp & (1 << n) ? 1 : 0;
diff --git a/gr-dtv/lib/dvbt2/dvbt2_framemapper_cc_impl.h b/gr-dtv/lib/dvbt2/dvbt2_framemapper_cc_impl.h
index 354c684bf3..8d35493f45 100644
--- a/gr-dtv/lib/dvbt2/dvbt2_framemapper_cc_impl.h
+++ b/gr-dtv/lib/dvbt2/dvbt2_framemapper_cc_impl.h
@@ -139,9 +139,6 @@ namespace gr {
int t2_frames;
int t2_frame_num;
int l1_scrambled;
- int fef_present;
- int fef_length;
- int fef_interval;
int N_P2;
int C_P2;
int N_FC;
diff --git a/gr-dtv/lib/dvbt2/dvbt2_modulator_bc_impl.cc b/gr-dtv/lib/dvbt2/dvbt2_modulator_bc_impl.cc
index 8127e372db..28e7c4fac2 100644
--- a/gr-dtv/lib/dvbt2/dvbt2_modulator_bc_impl.cc
+++ b/gr-dtv/lib/dvbt2/dvbt2_modulator_bc_impl.cc
@@ -556,7 +556,7 @@ namespace gr {
case MOD_64QAM:
for (int i = 0; i < noutput_items; i += cell_size) {
if (cyclic_delay == FALSE) {
- for (int j = 0; j < noutput_items; j++) {
+ for (int j = 0; j < cell_size; j++) {
index = *in++;
*out++ = m_64qam[index & 0x3f];
}
diff --git a/gr-dtv/lib/dvbt2/dvbt2_p1insertion_cc_impl.cc b/gr-dtv/lib/dvbt2/dvbt2_p1insertion_cc_impl.cc
index c644d49986..9a2a41b395 100644
--- a/gr-dtv/lib/dvbt2/dvbt2_p1insertion_cc_impl.cc
+++ b/gr-dtv/lib/dvbt2/dvbt2_p1insertion_cc_impl.cc
@@ -45,7 +45,6 @@ namespace gr {
gr::io_signature::make(1, 1, sizeof(gr_complex)))
{
int s1, s2, index = 0;
- int fef_present = FALSE; /* for testing only */
const gr_complex *in = (const gr_complex *) p1_freq;
gr_complex *out = (gr_complex *) p1_time;
s1 = preamble;
@@ -103,9 +102,6 @@ namespace gr {
}
init_p1_randomizer();
s2 = (fftsize & 0x7) << 1;
- if (fef_present == TRUE) {
- s2 |= 1;
- }
for (int i = 0; i < 8; i++) {
for (int j = 7; j >= 0; j--) {
modulation_sequence[index++] = (s1_modulation_patterns[s1][i] >> j) & 0x1;
diff --git a/gr-dtv/lib/dvbt2/dvbt2_paprtr_cc_impl.cc b/gr-dtv/lib/dvbt2/dvbt2_paprtr_cc_impl.cc
index 45ceeed40c..b4f17564af 100644
--- a/gr-dtv/lib/dvbt2/dvbt2_paprtr_cc_impl.cc
+++ b/gr-dtv/lib/dvbt2/dvbt2_paprtr_cc_impl.cc
@@ -500,6 +500,8 @@ namespace gr {
dy = 16;
break;
}
+ shift = 0;
+ papr_map = p2_papr_map;
fft_size = fftsize;
pilot_pattern = pilotpattern;
carrier_mode = carriermode;
diff --git a/gr-uhd/include/gnuradio/uhd/usrp_block.h b/gr-uhd/include/gnuradio/uhd/usrp_block.h
index 5605ab82fb..d57e1d24cb 100644
--- a/gr-uhd/include/gnuradio/uhd/usrp_block.h
+++ b/gr-uhd/include/gnuradio/uhd/usrp_block.h
@@ -500,6 +500,62 @@ namespace gr {
*/
virtual void set_stream_args(const ::uhd::stream_args_t &stream_args) = 0;
+ /*******************************************************************
+ * GPIO methods
+ ******************************************************************/
+ /*!
+ * Enumerate GPIO banks on the current device.
+ * \param mboard the motherboard index 0 to M-1
+ * \return a list of string for each bank name
+ */
+ virtual std::vector<std::string> get_gpio_banks(const size_t mboard) = 0;
+
+ /*!
+ * Set a GPIO attribute on a particular GPIO bank.
+ * Possible attribute names:
+ * - CTRL - 1 for ATR mode 0 for GPIO mode
+ * - DDR - 1 for output 0 for input
+ * - OUT - GPIO output level (not ATR mode)
+ * - ATR_0X - ATR idle state
+ * - ATR_RX - ATR receive only state
+ * - ATR_TX - ATR transmit only state
+ * - ATR_XX - ATR full duplex state
+ * \param bank the name of a GPIO bank
+ * \param attr the name of a GPIO attribute
+ * \param value the new value for this GPIO bank
+ * \param mask the bit mask to effect which pins are changed
+ * \param mboard the motherboard index 0 to M-1
+ */
+ virtual void set_gpio_attr(
+ const std::string &bank,
+ const std::string &attr,
+ const boost::uint32_t value,
+ const boost::uint32_t mask = 0xffffffff,
+ const size_t mboard = 0
+ ) = 0;
+
+ /*!
+ * Get a GPIO attribute on a particular GPIO bank.
+ * Possible attribute names:
+ * - CTRL - 1 for ATR mode 0 for GPIO mode
+ * - DDR - 1 for output 0 for input
+ * - OUT - GPIO output level (not ATR mode)
+ * - ATR_0X - ATR idle state
+ * - ATR_RX - ATR receive only state
+ * - ATR_TX - ATR transmit only state
+ * - ATR_XX - ATR full duplex state
+ * - READBACK - readback input GPIOs
+ * \param bank the name of a GPIO bank
+ * \param attr the name of a GPIO attribute
+ * \param mboard the motherboard index 0 to M-1
+ * \return the value set for this attribute
+ */
+ virtual boost::uint32_t get_gpio_attr(
+ const std::string &bank,
+ const std::string &attr,
+ const size_t mboard = 0
+ ) = 0;
+
};
} /* namespace uhd */
diff --git a/gr-uhd/lib/usrp_block_impl.cc b/gr-uhd/lib/usrp_block_impl.cc
index c36898aab8..1977b89a3a 100644
--- a/gr-uhd/lib/usrp_block_impl.cc
+++ b/gr-uhd/lib/usrp_block_impl.cc
@@ -327,6 +327,29 @@ usrp_block_impl::get_time_last_pps(size_t mboard)
return _dev->get_time_last_pps(mboard);
}
+std::vector<std::string>
+usrp_block_impl::get_gpio_banks(const size_t mboard)
+{
+#ifdef UHD_USRP_MULTI_USRP_GPIO_API
+ return _dev->get_gpio_banks(mboard);
+#else
+ throw std::runtime_error("not implemented in this version");
+#endif
+}
+
+boost::uint32_t
+usrp_block_impl::get_gpio_attr(
+ const std::string &bank,
+ const std::string &attr,
+ const size_t mboard
+) {
+#ifdef UHD_USRP_MULTI_USRP_GPIO_API
+ return _dev->get_gpio_attr(bank, attr, mboard);
+#else
+ throw std::runtime_error("not implemented in this version");
+#endif
+}
+
void
usrp_block_impl::set_time_now(const ::uhd::time_spec_t &time_spec,
size_t mboard)
@@ -379,6 +402,21 @@ usrp_block_impl::set_user_register(const uint8_t addr,
#endif
}
+void
+usrp_block_impl::set_gpio_attr(
+ const std::string &bank,
+ const std::string &attr,
+ const boost::uint32_t value,
+ const boost::uint32_t mask,
+ const size_t mboard
+) {
+#ifdef UHD_USRP_MULTI_USRP_GPIO_API
+ return _dev->set_gpio_attr(bank, attr, value, mask, mboard);
+#else
+ throw std::runtime_error("not implemented in this version");
+#endif
+}
+
::uhd::usrp::multi_usrp::sptr
usrp_block_impl::get_device(void)
{
diff --git a/gr-uhd/lib/usrp_block_impl.h b/gr-uhd/lib/usrp_block_impl.h
index 5b38b51fa5..2158d542bc 100644
--- a/gr-uhd/lib/usrp_block_impl.h
+++ b/gr-uhd/lib/usrp_block_impl.h
@@ -62,6 +62,12 @@ namespace gr {
::uhd::time_spec_t get_time_now(size_t mboard = 0);
::uhd::time_spec_t get_time_last_pps(size_t mboard);
::uhd::usrp::multi_usrp::sptr get_device(void);
+ std::vector<std::string> get_gpio_banks(const size_t mboard);
+ boost::uint32_t get_gpio_attr(
+ const std::string &bank,
+ const std::string &attr,
+ const size_t mboard = 0
+ );
// Setters
void set_clock_config(const ::uhd::clock_config_t &clock_config, size_t mboard);
@@ -74,6 +80,13 @@ namespace gr {
void set_command_time(const ::uhd::time_spec_t &time_spec, size_t mboard);
void set_user_register(const uint8_t addr, const uint32_t data, size_t mboard);
void clear_command_time(size_t mboard);
+ void set_gpio_attr(
+ const std::string &bank,
+ const std::string &attr,
+ const boost::uint32_t value,
+ const boost::uint32_t mask,
+ const size_t mboard
+ );
// RPC
void setup_rpc();
diff --git a/gr-utils/python/modtool/cmakefile_editor.py b/gr-utils/python/modtool/cmakefile_editor.py
index 3d90b8d163..d57c650c5e 100644
--- a/gr-utils/python/modtool/cmakefile_editor.py
+++ b/gr-utils/python/modtool/cmakefile_editor.py
@@ -39,8 +39,38 @@ class CMakeFileEditor(object):
return nsubs
def remove_value(self, entry, value, to_ignore_start='', to_ignore_end=''):
- """Remove a value from an entry."""
- regexp = '^\s*(%s\(\s*%s[^()]*?\s*)%s\s*([^()]*%s\s*\))' % (entry, to_ignore_start, value, to_ignore_end)
+ """
+ Remove a value from an entry.
+ Example: You want to remove file.cc from this list() entry:
+ list(SOURCES
+ file.cc
+ other_file.cc
+ )
+
+ Then run:
+ >>> C.remove_value('list', 'file.cc', 'SOURCES')
+
+ Returns the number of occurences of entry in the current file
+ that were removed.
+ """
+ # In the case of the example above, these are cases we need to catch:
+ # - list(file.cc ...
+ # entry is right after the value parentheses, no whitespace. Can only happen
+ # when to_ignore_start is empty.
+ # - list(... file.cc)
+ # Other entries come first, then entry is preceded by whitespace.
+ # - list(SOURCES ... file.cc) # whitespace!
+ # When to_ignore_start is not empty, entry must always be preceded by whitespace.
+ if len(to_ignore_start) == 0:
+ regexp = r'^\s*({entry}\((?:[^()]*?\s+|)){value}\s*([^()]*{to_ignore_end}\s*\)){to_ignore_start}'
+ else:
+ regexp = r'^\s*({entry}\(\s*{to_ignore_start}[^()]*?\s+){value}\s*([^()]*{to_ignore_end}\s*\))'
+ regexp = regexp.format(
+ entry=entry,
+ to_ignore_start=to_ignore_start,
+ value=value,
+ to_ignore_end=to_ignore_end,
+ )
regexp = re.compile(regexp, re.MULTILINE)
(self.cfile, nsubs) = re.subn(regexp, r'\1\2', self.cfile, count=1)
return nsubs
diff --git a/grc/base/Connection.py b/grc/base/Connection.py
index 3a2de5b9a5..bf3c75277c 100644
--- a/grc/base/Connection.py
+++ b/grc/base/Connection.py
@@ -51,7 +51,7 @@ class Connection(Element):
#ensure that this connection (source -> sink) is unique
for connection in self.get_parent().get_connections():
if connection.get_source() is source and connection.get_sink() is sink:
- raise Exception('This connection between source and sink is not unique.')
+ raise LookupError('This connection between source and sink is not unique.')
self._source = source
self._sink = sink
if source.get_type() == 'bus':
diff --git a/grc/base/ParseXML.py b/grc/base/ParseXML.py
index a2cede1c86..2d5fed0862 100644
--- a/grc/base/ParseXML.py
+++ b/grc/base/ParseXML.py
@@ -41,9 +41,9 @@ def validate_dtd(xml_file, dtd_file=None):
dtd_file: the optional dtd file
@throws Exception validation fails
"""
- #perform parsing, use dtd validation if dtd file is not specified
+ # perform parsing, use dtd validation if dtd file is not specified
+ parser = etree.XMLParser(dtd_validation=not dtd_file)
try:
- parser = etree.XMLParser(dtd_validation=not dtd_file)
xml = etree.parse(xml_file, parser=parser)
except etree.LxmlError:
pass
@@ -101,9 +101,10 @@ def _from_file(xml):
key, value = _from_file(elem).items()[0]
if nested_data.has_key(key): nested_data[key].append(value)
else: nested_data[key] = [value]
- #delistify if the length of values is 1
+ # delistify if the length of values is 1
for key, values in nested_data.iteritems():
- if len(values) == 1: nested_data[key] = values[0]
+ if len(values) == 1:
+ nested_data[key] = values[0]
return odict({tag: nested_data})
@@ -116,15 +117,17 @@ def to_file(nested_data, xml_file):
nested_data: the nested data
xml_file: the xml file path
"""
- # Create the processing instruction from the array
xml_data = ""
instructions = nested_data.pop('_instructions', None)
- if instructions:
+ if instructions: # create the processing instruction from the array
xml_data += etree.tostring(etree.ProcessingInstruction(
- 'grc', ' '.join("{0}='{1}'".format(*item) for item in instructions.iteritems())
- ), xml_declaration=True, pretty_print=True)
- xml_data += etree.tostring(_to_file(nested_data)[0], pretty_print=True)
- open(xml_file, 'w').write(xml_data)
+ 'grc', ' '.join(
+ "{0}='{1}'".format(*item) for item in instructions.iteritems())
+ ), xml_declaration=True, pretty_print=True, encoding='utf-8')
+ xml_data += etree.tostring(_to_file(nested_data)[0],
+ pretty_print=True, encoding='utf-8')
+ with open(xml_file, 'w') as fp:
+ fp.write(xml_data)
def _to_file(nested_data):
@@ -139,12 +142,14 @@ def _to_file(nested_data):
"""
nodes = list()
for key, values in nested_data.iteritems():
- #listify the values if not a list
+ # listify the values if not a list
if not isinstance(values, (list, set, tuple)):
values = [values]
for value in values:
node = etree.Element(key)
- if isinstance(value, (str, unicode)): node.text = value
- else: node.extend(_to_file(value))
+ if isinstance(value, (str, unicode)):
+ node.text = unicode(value)
+ else:
+ node.extend(_to_file(value))
nodes.append(node)
return nodes
diff --git a/grc/gui/PropsDialog.py b/grc/gui/PropsDialog.py
index d301a75dd1..91f7f4ffe9 100644
--- a/grc/gui/PropsDialog.py
+++ b/grc/gui/PropsDialog.py
@@ -161,7 +161,9 @@ class PropsDialog(gtk.Dialog):
for tab, label, vbox in self._params_boxes:
vbox.hide_all()
# empty the params box
- vbox.forall(lambda c: vbox.remove(c) or c.destroy())
+ for child in vbox.get_children():
+ vbox.remove(child)
+ child.destroy()
# repopulate the params box
box_all_valid = True
for param in filter(lambda p: p.get_tab_label() == tab, self._block.get_params()):
@@ -202,7 +204,8 @@ class PropsDialog(gtk.Dialog):
def _handle_response(self, widget, response):
if response in (gtk.RESPONSE_APPLY, gtk.RESPONSE_ACCEPT):
for tab, label, vbox in self._params_boxes:
- vbox.forall(lambda c: c.apply_pending_changes())
+ for child in vbox.get_children():
+ child.apply_pending_changes()
self.set_response_sensitive(gtk.RESPONSE_APPLY, False)
return True
return False
diff --git a/grc/python/Generator.py b/grc/python/Generator.py
index d9e92cd31f..33807c5b95 100644
--- a/grc/python/Generator.py
+++ b/grc/python/Generator.py
@@ -129,7 +129,7 @@ class TopBlockGenerator(object):
# when in no gui mode on linux, use a graphical terminal (looks nice)
xterm_executable = find_executable(XTERM_EXECUTABLE)
if self._generate_options == 'no_gui' and xterm_executable:
- cmds = [xterm_executable, '-e'] + cmds
+ cmds = [xterm_executable, '-e'] + ' '.join(cmds)
p = subprocess.Popen(
args=cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,