diff options
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, |