1 /* -*- c++ -*- */
2 /*
3  * Copyright 2012-2013 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include "ctrlport_probe2_c_impl.h"
28 #include <gnuradio/io_signature.h>
29 
30 namespace gr {
31 namespace blocks {
32 
make(const std::string & id,const std::string & desc,int len,unsigned int disp_mask)33 ctrlport_probe2_c::sptr ctrlport_probe2_c::make(const std::string& id,
34                                                 const std::string& desc,
35                                                 int len,
36                                                 unsigned int disp_mask)
37 {
38     return gnuradio::get_initial_sptr(
39         new ctrlport_probe2_c_impl(id, desc, len, disp_mask));
40 }
41 
ctrlport_probe2_c_impl(const std::string & id,const std::string & desc,int len,unsigned int disp_mask)42 ctrlport_probe2_c_impl::ctrlport_probe2_c_impl(const std::string& id,
43                                                const std::string& desc,
44                                                int len,
45                                                unsigned int disp_mask)
46     : sync_block("probe2_c",
47                  io_signature::make(1, 1, sizeof(gr_complex)),
48                  io_signature::make(0, 0, 0)),
49       d_id(id),
50       d_desc(desc),
51       d_len(len),
52       d_disp_mask(disp_mask)
53 {
54     set_length(len);
55 }
56 
~ctrlport_probe2_c_impl()57 ctrlport_probe2_c_impl::~ctrlport_probe2_c_impl() {}
58 
forecast(int noutput_items,gr_vector_int & ninput_items_required)59 void ctrlport_probe2_c_impl::forecast(int noutput_items,
60                                       gr_vector_int& ninput_items_required)
61 {
62     // make sure all inputs have noutput_items available
63     unsigned ninputs = ninput_items_required.size();
64     for (unsigned i = 0; i < ninputs; i++)
65         ninput_items_required[i] = d_len;
66 }
67 
get()68 std::vector<gr_complex> ctrlport_probe2_c_impl::get() { return buffered_get.get(); }
69 
set_length(int len)70 void ctrlport_probe2_c_impl::set_length(int len)
71 {
72     gr::thread::scoped_lock guard(d_setlock);
73 
74     if (len > 8191) {
75         GR_LOG_WARN(d_logger,
76                     boost::format("probe2_c: length %1% exceeds maximum"
77                                   " buffer size of 8191") %
78                         len);
79         len = 8191;
80     }
81 
82     d_len = len;
83     d_buffer.resize(d_len);
84     d_index = 0;
85 }
86 
length() const87 int ctrlport_probe2_c_impl::length() const { return (int)d_len; }
88 
work(int noutput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)89 int ctrlport_probe2_c_impl::work(int noutput_items,
90                                  gr_vector_const_void_star& input_items,
91                                  gr_vector_void_star& output_items)
92 {
93     const gr_complex* in = (const gr_complex*)input_items[0];
94 
95     gr::thread::scoped_lock guard(d_setlock);
96 
97     // copy samples to get buffer if we need samples
98     if (d_index < d_len) {
99         // copy smaller of remaining buffer space and num inputs to work()
100         int num_copy = std::min((int)(d_len - d_index), noutput_items);
101 
102         memcpy(&d_buffer[d_index], in, num_copy * sizeof(gr_complex));
103         d_index += num_copy;
104     }
105 
106     // notify the waiting get() if we fill up the buffer
107     if (d_index == d_len) {
108         buffered_get.offer_data(d_buffer);
109         d_index = 0;
110     }
111 
112     return noutput_items;
113 }
114 
setup_rpc()115 void ctrlport_probe2_c_impl::setup_rpc()
116 {
117 #ifdef GR_CTRLPORT
118     int len = static_cast<int>(d_len);
119     d_rpc_vars.emplace_back(
120         new rpcbasic_register_get<ctrlport_probe2_c, std::vector<std::complex<float>>>(
121             alias(),
122             d_id.c_str(),
123             &ctrlport_probe2_c::get,
124             pmt::mp(-2),
125             pmt::mp(2),
126             pmt::mp(0),
127             "volts",
128             d_desc.c_str(),
129             RPC_PRIVLVL_MIN,
130             d_disp_mask | DISPOPTCPLX));
131 
132     d_rpc_vars.emplace_back(
133         new rpcbasic_register_get<ctrlport_probe2_c, int>(alias(),
134                                                           "length",
135                                                           &ctrlport_probe2_c::length,
136                                                           pmt::mp(1),
137                                                           pmt::mp(10 * len),
138                                                           pmt::mp(len),
139                                                           "samples",
140                                                           "get vector length",
141                                                           RPC_PRIVLVL_MIN,
142                                                           DISPNULL));
143 
144     d_rpc_vars.emplace_back(
145         new rpcbasic_register_set<ctrlport_probe2_c, int>(alias(),
146                                                           "length",
147                                                           &ctrlport_probe2_c::set_length,
148                                                           pmt::mp(1),
149                                                           pmt::mp(10 * len),
150                                                           pmt::mp(len),
151                                                           "samples",
152                                                           "set vector length",
153                                                           RPC_PRIVLVL_MIN,
154                                                           DISPNULL));
155 #endif /* GR_CTRLPORT */
156 }
157 
158 } /* namespace blocks */
159 } /* namespace gr */
160