]> sigrok.org Git - pulseview.git/blob - pv/data/signalbase.hpp
Remove SignalBase::A2LChannel
[pulseview.git] / pv / data / signalbase.hpp
1 /*
2  * This file is part of the PulseView project.
3  *
4  * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
5  * Copyright (C) 2016 Soeren Apel <soeren@apelpie.net>
6  *
7  * This program 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 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifndef PULSEVIEW_PV_DATA_SIGNALBASE_HPP
22 #define PULSEVIEW_PV_DATA_SIGNALBASE_HPP
23
24 #include <atomic>
25 #include <condition_variable>
26 #include <thread>
27 #include <vector>
28
29 #include <QColor>
30 #include <QObject>
31 #include <QSettings>
32 #include <QString>
33 #include <QVariant>
34
35 #include <libsigrokcxx/libsigrokcxx.hpp>
36
37 using std::atomic;
38 using std::condition_variable;
39 using std::map;
40 using std::mutex;
41 using std::pair;
42 using std::shared_ptr;
43 using std::vector;
44
45 namespace sigrok {
46 class Channel;
47 }
48
49 namespace pv {
50 namespace data {
51
52 class Analog;
53 class DecoderStack;
54 class Logic;
55 class SignalData;
56
57 class SignalBase : public QObject
58 {
59         Q_OBJECT
60
61 public:
62         enum ChannelType {
63                 AnalogChannel = 1, ///< Analog data
64                 LogicChannel,  ///< Logic data
65                 DecodeChannel, ///< Protocol Decoder channel using libsigrokdecode
66                 MathChannel    ///< Virtual channel generated by math operations
67         };
68
69         enum ConversionType {
70                 NoConversion = 0,
71                 A2LConversionByThreshold = 1,
72                 A2LConversionBySchmittTrigger = 2
73         };
74
75         /**
76          * Conversion presets range from -1 to n, where 1..n are dependent on
77          * the conversion these presets apply to. -1 and 0 have fixed meanings,
78          * however.
79          */
80         enum ConversionPreset {
81                 NoPreset = -1,     ///< Conversion uses custom values
82                 DynamicPreset = 0  ///< Conversion uses calculated values
83         };
84
85 private:
86         static const int ColourBGAlpha;
87         static const uint64_t ConversionBlockSize;
88
89 public:
90         SignalBase(shared_ptr<sigrok::Channel> channel, ChannelType channel_type);
91         virtual ~SignalBase();
92
93 public:
94         /**
95          * Returns the underlying SR channel.
96          */
97         shared_ptr<sigrok::Channel> channel() const;
98
99         /**
100          * Returns enabled status of this channel.
101          */
102         bool enabled() const;
103
104         /**
105          * Sets the enabled status of this channel.
106          * @param value Boolean value to set.
107          */
108         void set_enabled(bool value);
109
110         /**
111          * Gets the type of this channel.
112          */
113         ChannelType type() const;
114
115         /**
116          * Gets the index number of this channel, i.e. a unique ID assigned by
117          * the device driver.
118          */
119         unsigned int index() const;
120
121         /**
122          * Returns which bit of a given sample for this signal represents the
123          * signal itself. This is relevant for compound signals like logic,
124          * rather meaningless for everything else but provided in case there
125          * is a conversion active that provides a digital signal using bit #0.
126          */
127         unsigned int logic_bit_index() const;
128
129         /**
130          * Gets the name of this signal.
131          */
132         QString name() const;
133
134         /**
135          * Gets the internal name of this signal, i.e. how the device calls it.
136          */
137         QString internal_name() const;
138
139         /**
140          * Sets the name of the signal.
141          */
142         virtual void set_name(QString name);
143
144         /**
145          * Get the colour of the signal.
146          */
147         QColor colour() const;
148
149         /**
150          * Set the colour of the signal.
151          */
152         void set_colour(QColor colour);
153
154         /**
155          * Get the background colour of the signal.
156          */
157         QColor bgcolour() const;
158
159         /**
160          * Sets the internal data object.
161          */
162         void set_data(shared_ptr<pv::data::SignalData> data);
163
164         /**
165          * Get the internal data as analog data object in case of analog type.
166          */
167         shared_ptr<pv::data::Analog> analog_data() const;
168
169         /**
170          * Get the internal data as logic data object in case of logic type.
171          */
172         shared_ptr<pv::data::Logic> logic_data() const;
173
174         /**
175          * Queries the kind of conversion performed on this channel.
176          */
177         ConversionType get_conversion_type() const;
178
179         /**
180          * Changes the kind of conversion performed on this channel.
181          *
182          * Restarts the conversion.
183          */
184         void set_conversion_type(ConversionType t);
185
186         /**
187          * Returns all currently known conversion options
188          */
189         map<QString, QVariant> get_conversion_options() const;
190
191         /**
192          * Sets the value of a particular conversion option
193          * Note: it is not checked whether the option is valid for the
194          * currently conversion. If it's not, it will be silently ignored.
195          *
196          * Does not restart the conversion.
197          *
198          * @return true if the value is different from before, false otherwise
199          */
200         bool set_conversion_option(QString key, QVariant value);
201
202         /**
203          * Returns the threshold(s) used for conversions, if applicable.
204          * The resulting thresholds are given for the chosen conversion, so you
205          * can query thresholds also for conversions which aren't currently active.
206          *
207          * If you want the thresholds for the currently active conversion,
208          * call it either with NoConversion or no parameter.
209          *
210          * @param t the type of conversion to obtain the thresholds for, leave
211          *          empty or use NoConversion if you want to query the currently
212          *          used conversion
213          *
214          * @param always_custom ignore the currently selected preset and always
215          *        return the custom values for this conversion, using 0 if those
216          *        aren't set
217          *
218          * @return a list of threshold(s) used by the chosen conversion
219          */
220         vector<double> get_conversion_thresholds(
221                 const ConversionType t = NoConversion, const bool always_custom=false) const;
222
223         /**
224          * Provides all conversion presets available for the currently active
225          * conversion.
226          *
227          * @return a list of description/ID pairs for each preset
228          */
229         vector<pair<QString, int> > get_conversion_presets() const;
230
231         /**
232          * Determines the ID of the currently used conversion preset, which is only
233          * valid for the currently available conversion presets. It is therefore
234          * suggested to call @ref get_conversion_presets right before calling this.
235          *
236          * @return the ID of the currently used conversion preset. -1 if no preset
237          *         is used. In that case, a user setting is used instead.
238          */
239         ConversionPreset get_current_conversion_preset() const;
240
241         /**
242          * Sets the conversion preset to be used.
243          *
244          * Does not restart the conversion.
245          *
246          * @param id the id of the preset to use
247          */
248         void set_conversion_preset(ConversionPreset id);
249
250 #ifdef ENABLE_DECODE
251         bool is_decode_signal() const;
252 #endif
253
254         virtual void save_settings(QSettings &settings) const;
255
256         virtual void restore_settings(QSettings &settings);
257
258         void start_conversion();
259
260 private:
261         bool conversion_is_a2l() const;
262
263         uint8_t convert_a2l_threshold(float threshold, float value);
264         uint8_t convert_a2l_schmitt_trigger(float lo_thr, float hi_thr,
265                 float value, uint8_t &state);
266
267         void conversion_thread_proc(QObject* segment);
268
269         void stop_conversion();
270
271 Q_SIGNALS:
272         void enabled_changed(const bool &value);
273
274         void name_changed(const QString &name);
275
276         void colour_changed(const QColor &colour);
277
278         void conversion_type_changed(const ConversionType t);
279
280         void samples_cleared();
281
282         void samples_added(QObject* segment, uint64_t start_sample,
283                 uint64_t end_sample);
284
285 private Q_SLOTS:
286         void on_samples_cleared();
287
288         void on_samples_added(QObject* segment, uint64_t start_sample,
289                 uint64_t end_sample);
290
291         void on_min_max_changed(float min, float max);
292
293         void on_capture_state_changed(int state);
294
295 protected:
296         shared_ptr<sigrok::Channel> channel_;
297         ChannelType channel_type_;
298         shared_ptr<pv::data::SignalData> data_;
299         shared_ptr<pv::data::SignalData> converted_data_;
300         ConversionType conversion_type_;
301         map<QString, QVariant> conversion_options_;
302
303         float min_value_, max_value_;
304
305         std::thread conversion_thread_;
306         atomic<bool> conversion_interrupt_;
307         mutex conversion_input_mutex_;
308         condition_variable conversion_input_cond_;
309
310         QString internal_name_, name_;
311         QColor colour_, bgcolour_;
312 };
313
314 } // namespace data
315 } // namespace pv
316
317 #endif // PULSEVIEW_PV_DATA_SIGNALBASE_HPP