diff --git a/DSView/CMakeLists.txt b/DSView/CMakeLists.txt index 652cb58d..c5703c64 100644 --- a/DSView/CMakeLists.txt +++ b/DSView/CMakeLists.txt @@ -103,7 +103,7 @@ set(DS_DESCRIPTION "A GUI for instruments of DreamSourceLab") set(DS_VERSION_MAJOR 0) set(DS_VERSION_MINOR 9) -set(DS_VERSION_MICRO 4) +set(DS_VERSION_MICRO 5) set(DS_VERSION_STRING ${DS_VERSION_MAJOR}.${DS_VERSION_MINOR}.${DS_VERSION_MICRO} ) @@ -144,6 +144,7 @@ set(DSView_SOURCES pv/dialogs/storeprogress.cpp pv/dialogs/streamoptions.cpp pv/dialogs/waitingdialog.cpp + pv/dialogs/dsomeasure.cpp pv/dock/dsotriggerdock.cpp pv/dock/measuredock.cpp pv/dock/searchdock.cpp @@ -189,6 +190,7 @@ set(DSView_HEADERS pv/dialogs/storeprogress.h pv/dialogs/streamoptions.h pv/dialogs/waitingdialog.h + pv/dialogs/dsomeasure.h pv/dock/dsotriggerdock.h pv/dock/measuredock.h pv/dock/searchdock.h diff --git a/DSView/DSView.qrc b/DSView/DSView.qrc index f93bad84..05955d6d 100644 --- a/DSView/DSView.qrc +++ b/DSView/DSView.qrc @@ -24,8 +24,8 @@ icons/start.png icons/dsl_logo.png icons/logo.png - icons/decoder-hidden.png - icons/decoder-shown.png + icons/hidden.png + icons/shown.png icons/instant.png icons/trigger_dis.png icons/file_dis.png @@ -55,5 +55,6 @@ icons/instant_dis_cn.png icons/start_dis.png icons/start_dis_cn.png + icons/settings.png diff --git a/DSView/cmake_clear b/DSView/cmake_clear index 6a573ce0..592a8878 100755 --- a/DSView/cmake_clear +++ b/DSView/cmake_clear @@ -3,4 +3,6 @@ rm ./cmake_install.cmake rm -r ./CMakeFiles rm ./Makefile rm ./CMakeCache.txt +find . -name 'moc_*.cpp*' | xargs rm -rf +find . -name 'qrc_*.cpp' | xargs rm -rf echo "rm cmake cache end..." diff --git a/DSView/icons/about.png b/DSView/icons/about.png index b249edb1..ac389095 100644 Binary files a/DSView/icons/about.png and b/DSView/icons/about.png differ diff --git a/DSView/icons/add.png b/DSView/icons/add.png index e4e1684b..efe2e387 100644 Binary files a/DSView/icons/add.png and b/DSView/icons/add.png differ diff --git a/DSView/icons/capture.png b/DSView/icons/capture.png index 15e44bf8..6c12ad27 100644 Binary files a/DSView/icons/capture.png and b/DSView/icons/capture.png differ diff --git a/DSView/icons/decoder-hidden.png b/DSView/icons/decoder-hidden.png deleted file mode 100644 index 215b5ada..00000000 Binary files a/DSView/icons/decoder-hidden.png and /dev/null differ diff --git a/DSView/icons/decoder-shown.png b/DSView/icons/decoder-shown.png deleted file mode 100644 index d745e24f..00000000 Binary files a/DSView/icons/decoder-shown.png and /dev/null differ diff --git a/DSView/icons/del.png b/DSView/icons/del.png index 9420adc1..ff04e887 100644 Binary files a/DSView/icons/del.png and b/DSView/icons/del.png differ diff --git a/DSView/icons/down-arrow.png b/DSView/icons/down-arrow.png index 4cc0d6ca..09e14ad2 100644 Binary files a/DSView/icons/down-arrow.png and b/DSView/icons/down-arrow.png differ diff --git a/DSView/icons/dsl_logo.png b/DSView/icons/dsl_logo.png index 7e4db82b..d2502a28 100644 Binary files a/DSView/icons/dsl_logo.png and b/DSView/icons/dsl_logo.png differ diff --git a/DSView/icons/file.png b/DSView/icons/file.png index 06a9f281..2a4715da 100644 Binary files a/DSView/icons/file.png and b/DSView/icons/file.png differ diff --git a/DSView/icons/file_dis.png b/DSView/icons/file_dis.png index 71eb703d..65373110 100644 Binary files a/DSView/icons/file_dis.png and b/DSView/icons/file_dis.png differ diff --git a/DSView/icons/gear.png b/DSView/icons/gear.png index 2c52b8df..4a1883e2 100644 Binary files a/DSView/icons/gear.png and b/DSView/icons/gear.png differ diff --git a/DSView/icons/hidden.png b/DSView/icons/hidden.png new file mode 100644 index 00000000..8d098807 Binary files /dev/null and b/DSView/icons/hidden.png differ diff --git a/DSView/icons/instant.png b/DSView/icons/instant.png index ac1b5d03..2aa5c250 100644 Binary files a/DSView/icons/instant.png and b/DSView/icons/instant.png differ diff --git a/DSView/icons/logo.png b/DSView/icons/logo.png index 9cdf4644..ca65932d 100644 Binary files a/DSView/icons/logo.png and b/DSView/icons/logo.png differ diff --git a/DSView/icons/logo_color.png b/DSView/icons/logo_color.png index 1b820058..7a2e44eb 100644 Binary files a/DSView/icons/logo_color.png and b/DSView/icons/logo_color.png differ diff --git a/DSView/icons/logo_noColor.png b/DSView/icons/logo_noColor.png index a245df39..dc69820c 100644 Binary files a/DSView/icons/logo_noColor.png and b/DSView/icons/logo_noColor.png differ diff --git a/DSView/icons/measure.png b/DSView/icons/measure.png index f0b28b7f..c858a50d 100644 Binary files a/DSView/icons/measure.png and b/DSView/icons/measure.png differ diff --git a/DSView/icons/measure_dis.png b/DSView/icons/measure_dis.png index 244eb979..8510560a 100644 Binary files a/DSView/icons/measure_dis.png and b/DSView/icons/measure_dis.png differ diff --git a/DSView/icons/next.png b/DSView/icons/next.png index 9e86ecf6..cc35544b 100644 Binary files a/DSView/icons/next.png and b/DSView/icons/next.png differ diff --git a/DSView/icons/open.png b/DSView/icons/open.png index df9cf3f9..5fde3ba2 100644 Binary files a/DSView/icons/open.png and b/DSView/icons/open.png differ diff --git a/DSView/icons/params.png b/DSView/icons/params.png index 5b5af174..ea7c1a0e 100644 Binary files a/DSView/icons/params.png and b/DSView/icons/params.png differ diff --git a/DSView/icons/params_dis.png b/DSView/icons/params_dis.png index 67811f26..277a3266 100644 Binary files a/DSView/icons/params_dis.png and b/DSView/icons/params_dis.png differ diff --git a/DSView/icons/pre.png b/DSView/icons/pre.png index 1eac2f4e..f7ccd2eb 100644 Binary files a/DSView/icons/pre.png and b/DSView/icons/pre.png differ diff --git a/DSView/icons/protocol.png b/DSView/icons/protocol.png index b1a9cf44..91423ec2 100644 Binary files a/DSView/icons/protocol.png and b/DSView/icons/protocol.png differ diff --git a/DSView/icons/protocol_dis.png b/DSView/icons/protocol_dis.png index 3238fcfc..b5278b68 100644 Binary files a/DSView/icons/protocol_dis.png and b/DSView/icons/protocol_dis.png differ diff --git a/DSView/icons/save.png b/DSView/icons/save.png index f32906a4..2baec172 100644 Binary files a/DSView/icons/save.png and b/DSView/icons/save.png differ diff --git a/DSView/icons/search-bar.png b/DSView/icons/search-bar.png index ee7e1121..20b94274 100644 Binary files a/DSView/icons/search-bar.png and b/DSView/icons/search-bar.png differ diff --git a/DSView/icons/search-bar_dis.png b/DSView/icons/search-bar_dis.png index 81805a60..a19d5834 100644 Binary files a/DSView/icons/search-bar_dis.png and b/DSView/icons/search-bar_dis.png differ diff --git a/DSView/icons/search.png b/DSView/icons/search.png index 3ad1068b..5a67758e 100644 Binary files a/DSView/icons/search.png and b/DSView/icons/search.png differ diff --git a/DSView/icons/settings.png b/DSView/icons/settings.png new file mode 100755 index 00000000..b0065b51 Binary files /dev/null and b/DSView/icons/settings.png differ diff --git a/DSView/icons/shown.png b/DSView/icons/shown.png new file mode 100644 index 00000000..25262044 Binary files /dev/null and b/DSView/icons/shown.png differ diff --git a/DSView/icons/slider-handle.png b/DSView/icons/slider-handle.png index a23b0fb7..ac1f6e22 100644 Binary files a/DSView/icons/slider-handle.png and b/DSView/icons/slider-handle.png differ diff --git a/DSView/icons/start.png b/DSView/icons/start.png index badd73e5..bd42b602 100644 Binary files a/DSView/icons/start.png and b/DSView/icons/start.png differ diff --git a/DSView/icons/stop.png b/DSView/icons/stop.png index a6fd48db..969a6999 100644 Binary files a/DSView/icons/stop.png and b/DSView/icons/stop.png differ diff --git a/DSView/icons/trigger.png b/DSView/icons/trigger.png index 9eeba7f3..5f8f4965 100644 Binary files a/DSView/icons/trigger.png and b/DSView/icons/trigger.png differ diff --git a/DSView/icons/trigger_dis.png b/DSView/icons/trigger_dis.png index 0a0ed190..9c804d0e 100644 Binary files a/DSView/icons/trigger_dis.png and b/DSView/icons/trigger_dis.png differ diff --git a/DSView/icons/wiki.png b/DSView/icons/wiki.png index aa9d2d58..4515019c 100644 Binary files a/DSView/icons/wiki.png and b/DSView/icons/wiki.png differ diff --git a/DSView/pv/data/analogsnapshot.cpp b/DSView/pv/data/analogsnapshot.cpp index 981dc0f9..085cf20c 100644 --- a/DSView/pv/data/analogsnapshot.cpp +++ b/DSView/pv/data/analogsnapshot.cpp @@ -47,7 +47,7 @@ const float AnalogSnapshot::LogEnvelopeScaleFactor = const uint64_t AnalogSnapshot::EnvelopeDataUnit = 64*1024; // bytes AnalogSnapshot::AnalogSnapshot(const sr_datafeed_analog &analog, uint64_t _total_sample_len, unsigned int channel_num) : - Snapshot(sizeof(uint16_t), _total_sample_len, channel_num) + Snapshot(sizeof(uint16_t)*channel_num, _total_sample_len, channel_num) { boost::lock_guard lock(_mutex); memset(_envelope_levels, 0, sizeof(_envelope_levels)); @@ -66,7 +66,7 @@ void AnalogSnapshot::append_payload( const sr_datafeed_analog &analog) { boost::lock_guard lock(_mutex); - append_data(analog.data, analog.num_samples); + append_data(analog.data, analog.num_samples); // Generate the first mip-map from the data append_payload_to_envelope_levels(); diff --git a/DSView/pv/data/decode/annotation.cpp b/DSView/pv/data/decode/annotation.cpp index 32d38970..a474dd90 100644 --- a/DSView/pv/data/decode/annotation.cpp +++ b/DSView/pv/data/decode/annotation.cpp @@ -40,15 +40,20 @@ Annotation::Annotation(const srd_proto_data *const pdata) : (const srd_proto_data_annotation*)pdata->data; assert(pda); - _format = pda->ann_class; + _format = pda->ann_class; - const char *const *annotations = (char**)pda->ann_text; + const char *const *annotations = (char**)pda->ann_text; while(*annotations) { - _annotations.push_back(QString::fromUtf8(*annotations)); + _annotations.push_back(QString::fromUtf8(*annotations)); annotations++; } } +Annotation::~Annotation() +{ + _annotations.clear(); +} + uint64_t Annotation::start_sample() const { return _start_sample; diff --git a/DSView/pv/data/decode/annotation.h b/DSView/pv/data/decode/annotation.h index dcbdd5cd..a2676bd3 100644 --- a/DSView/pv/data/decode/annotation.h +++ b/DSView/pv/data/decode/annotation.h @@ -35,6 +35,7 @@ class Annotation { public: Annotation(const srd_proto_data *const pdata); + ~Annotation(); uint64_t start_sample() const; uint64_t end_sample() const; diff --git a/DSView/pv/data/decode/decoder.cpp b/DSView/pv/data/decode/decoder.cpp index da17fb48..00d6a1f5 100644 --- a/DSView/pv/data/decode/decoder.cpp +++ b/DSView/pv/data/decode/decoder.cpp @@ -46,6 +46,10 @@ Decoder::~Decoder() for (map::const_iterator i = _options.begin(); i != _options.end(); i++) g_variant_unref((*i).second); + + for (map::const_iterator i = _options_back.begin(); + i != _options_back.end(); i++) + g_variant_unref((*i).second); } const srd_decoder* Decoder::decoder() const @@ -130,6 +134,7 @@ set< shared_ptr > Decoder::get_data() srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session, int unit_size) const { + (void)unit_size; GHashTable *const opt_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); @@ -164,7 +169,7 @@ srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session, int unit_si g_hash_table_insert(probes, (*i).first->id, gvar); } - srd_inst_channel_set_all(decoder_inst, probes, unit_size); + srd_inst_channel_set_all(decoder_inst, probes); return decoder_inst; } diff --git a/DSView/pv/data/decode/row.cpp b/DSView/pv/data/decode/row.cpp index 2aabf0f9..1c0ee9cc 100644 --- a/DSView/pv/data/decode/row.cpp +++ b/DSView/pv/data/decode/row.cpp @@ -38,6 +38,11 @@ Row::Row(const srd_decoder *decoder, const srd_decoder_annotation_row *row) : { } +Row::~Row() +{ + +} + const srd_decoder* Row::decoder() const { return _decoder; diff --git a/DSView/pv/data/decode/row.h b/DSView/pv/data/decode/row.h index 71ee071e..6826c0fc 100644 --- a/DSView/pv/data/decode/row.h +++ b/DSView/pv/data/decode/row.h @@ -36,6 +36,7 @@ class Row { public: Row(); + ~Row(); Row(const srd_decoder *decoder, const srd_decoder_annotation_row *row = NULL); diff --git a/DSView/pv/data/decode/rowdata.cpp b/DSView/pv/data/decode/rowdata.cpp index 1d3ed27f..840459a6 100644 --- a/DSView/pv/data/decode/rowdata.cpp +++ b/DSView/pv/data/decode/rowdata.cpp @@ -34,6 +34,11 @@ RowData::RowData() : { } +RowData::~RowData() +{ + _annotations.clear(); +} + uint64_t RowData::get_max_sample() const { if (_annotations.empty()) diff --git a/DSView/pv/data/decode/rowdata.h b/DSView/pv/data/decode/rowdata.h index ddcdfe24..03076494 100644 --- a/DSView/pv/data/decode/rowdata.h +++ b/DSView/pv/data/decode/rowdata.h @@ -33,6 +33,7 @@ class RowData { public: RowData(); + ~RowData(); public: uint64_t get_max_sample() const; diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index b78b9996..1df0abb0 100644 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -88,6 +88,8 @@ DecoderStack::~DecoderStack() // _decode_thread.join(); // } stop_decode(); + _stack.clear(); + clear(); } const std::list< boost::shared_ptr >& @@ -335,7 +337,7 @@ void DecoderStack::decode_data( { //uint8_t chunk[DecodeChunkLength]; uint8_t *chunk = NULL; - chunk = (uint8_t *)realloc(chunk, DecodeChunkLength); + //chunk = (uint8_t *)realloc(chunk, DecodeChunkLength); const uint64_t chunk_sample_count = DecodeChunkLength / _snapshot->unit_size(); @@ -349,10 +351,10 @@ void DecoderStack::decode_data( const uint64_t chunk_end = min( i + chunk_sample_count, sample_count); - _snapshot->get_samples(chunk, i, chunk_end); + chunk = _snapshot->get_samples(i, chunk_end); if (srd_session_send(session, i, i + sample_count, chunk, - (chunk_end - i) * unit_size) != SRD_OK) { + (chunk_end - i) * unit_size, unit_size) != SRD_OK) { _error_message = tr("Decoder reported an error"); break; } diff --git a/DSView/pv/data/decoderstack.h b/DSView/pv/data/decoderstack.h index 19c518a4..b2cd65f8 100644 --- a/DSView/pv/data/decoderstack.h +++ b/DSView/pv/data/decoderstack.h @@ -173,7 +173,7 @@ private: QString _error_message; - std::auto_ptr _decode_thread; + std::unique_ptr _decode_thread; decode_state _decode_state; bool _options_changed; diff --git a/DSView/pv/data/dsosnapshot.cpp b/DSView/pv/data/dsosnapshot.cpp index af1ae6dc..4e0e1b26 100644 --- a/DSView/pv/data/dsosnapshot.cpp +++ b/DSView/pv/data/dsosnapshot.cpp @@ -45,6 +45,8 @@ const float DsoSnapshot::LogEnvelopeScaleFactor = logf(EnvelopeScaleFactor); const uint64_t DsoSnapshot::EnvelopeDataUnit = 4*1024; // bytes +const int DsoSnapshot::VrmsScaleFactor = 1 << 8; + DsoSnapshot::DsoSnapshot(const sr_datafeed_dso &dso, uint64_t _total_sample_len, unsigned int channel_num, bool instant) : Snapshot(sizeof(uint16_t), _total_sample_len, channel_num), _envelope_en(false), @@ -73,14 +75,14 @@ void DsoSnapshot::append_payload(const sr_datafeed_dso &dso) // Generate the first mip-map from the data if (_envelope_en) - append_payload_to_envelope_levels(); + append_payload_to_envelope_levels(dso.samplerate_tog); } } void DsoSnapshot::enable_envelope(bool enable) { - if (!_envelope_done & enable) - append_payload_to_envelope_levels(); + if (!_envelope_done && enable) + append_payload_to_envelope_levels(true); _envelope_en = enable; } @@ -144,26 +146,25 @@ void DsoSnapshot::reallocate_envelope(Envelope &e) } } -void DsoSnapshot::append_payload_to_envelope_levels() +void DsoSnapshot::append_payload_to_envelope_levels(bool header) { - unsigned int i; - for (i = 0; i < _channel_num; i++) { + for (unsigned int i = 0; i < _channel_num; i++) { Envelope &e0 = _envelope_levels[i][0]; uint64_t prev_length; EnvelopeSample *dest_ptr; - // Expand the data buffer to fit the new samples - prev_length = e0.length; - e0.length = get_sample_count() / EnvelopeScaleFactor; + if (header) + prev_length = 0; + else + prev_length = e0.length; + e0.length = _sample_count / EnvelopeScaleFactor; - // Break off if there are no new samples to compute - // if (e0.length == prev_length) - // return; if (e0.length == 0) return; if (e0.length == prev_length) prev_length = 0; + // Expand the data buffer to fit the new samples reallocate_envelope(e0); dest_ptr = e0.samples + prev_length; @@ -171,17 +172,6 @@ void DsoSnapshot::append_payload_to_envelope_levels() // Iterate through the samples to populate the first level mipmap const uint8_t *const stop_src_ptr = (uint8_t*)_data + e0.length * EnvelopeScaleFactor * _channel_num; -// for (const uint16_t *src_ptr = (uint16_t*)_data + -// prev_length * EnvelopeScaleFactor; -// src_ptr < end_src_ptr; src_ptr += EnvelopeScaleFactor) -// { -// const EnvelopeSample sub_sample = { -// *min_element(src_ptr, src_ptr + EnvelopeScaleFactor), -// *max_element(src_ptr, src_ptr + EnvelopeScaleFactor), -// }; - -// *dest_ptr++ = sub_sample; -// } for (const uint8_t *src_ptr = (uint8_t*)_data + prev_length * EnvelopeScaleFactor * _channel_num + i; src_ptr < stop_src_ptr; src_ptr += EnvelopeScaleFactor * _channel_num) @@ -194,14 +184,13 @@ void DsoSnapshot::append_payload_to_envelope_levels() EnvelopeSample sub_sample; sub_sample.min = *begin_src_ptr; sub_sample.max = *begin_src_ptr; - begin_src_ptr += _channel_num; + //begin_src_ptr += _channel_num; while (begin_src_ptr < end_src_ptr) { sub_sample.min = min(sub_sample.min, *begin_src_ptr); sub_sample.max = max(sub_sample.max, *begin_src_ptr); begin_src_ptr += _channel_num; } - *dest_ptr++ = sub_sample; } @@ -248,5 +237,72 @@ void DsoSnapshot::append_payload_to_envelope_levels() _envelope_done = true; } +double DsoSnapshot::cal_vrms(double zero_off, int index) const +{ + assert(index >= 0); + assert(index < _channel_num); + + // root-meam-squart value + double vrms_pre = 0; + double vrms = 0; + double tmp; + + // Iterate through the samples to populate the first level mipmap + const uint8_t *const stop_src_ptr = (uint8_t*)_data + + _sample_count * _channel_num; + for (const uint8_t *src_ptr = (uint8_t*)_data + index; + src_ptr < stop_src_ptr; src_ptr += VrmsScaleFactor * _channel_num) + { + const uint8_t * begin_src_ptr = + src_ptr; + const uint8_t *const end_src_ptr = + src_ptr + VrmsScaleFactor * _channel_num; + + while (begin_src_ptr < end_src_ptr) + { + tmp = (zero_off - *begin_src_ptr); + vrms += tmp * tmp; + begin_src_ptr += _channel_num; + } + vrms = vrms_pre + vrms / _sample_count; + vrms_pre = vrms; + } + vrms = std::pow(vrms, 0.5); + + return vrms; +} + +double DsoSnapshot::cal_vmean(int index) const +{ + assert(index >= 0); + assert(index < _channel_num); + + // mean value + double vmean_pre = 0; + double vmean = 0; + + // Iterate through the samples to populate the first level mipmap + const uint8_t *const stop_src_ptr = (uint8_t*)_data + + _sample_count * _channel_num; + for (const uint8_t *src_ptr = (uint8_t*)_data + index; + src_ptr < stop_src_ptr; src_ptr += VrmsScaleFactor * _channel_num) + { + const uint8_t * begin_src_ptr = + src_ptr; + const uint8_t *const end_src_ptr = + src_ptr + VrmsScaleFactor * _channel_num; + + while (begin_src_ptr < end_src_ptr) + { + vmean += *begin_src_ptr; + begin_src_ptr += _channel_num; + } + vmean = vmean_pre + vmean / _sample_count; + vmean_pre = vmean; + } + + return vmean; +} + } // namespace data } // namespace pv diff --git a/DSView/pv/data/dsosnapshot.h b/DSView/pv/data/dsosnapshot.h index 88b678b8..eb3788bc 100644 --- a/DSView/pv/data/dsosnapshot.h +++ b/DSView/pv/data/dsosnapshot.h @@ -67,6 +67,8 @@ private: static const float LogEnvelopeScaleFactor; static const uint64_t EnvelopeDataUnit; + static const int VrmsScaleFactor; + public: DsoSnapshot(const sr_datafeed_dso &dso, uint64_t _total_sample_len, unsigned int channel_num, bool instant); @@ -82,10 +84,13 @@ public: void enable_envelope(bool enable); + double cal_vrms(double zero_off, int index) const; + double cal_vmean(int index) const; + private: void reallocate_envelope(Envelope &l); - void append_payload_to_envelope_levels(); + void append_payload_to_envelope_levels(bool header); private: struct Envelope _envelope_levels[2*DS_MAX_DSO_PROBES_NUM][ScaleStepCount]; diff --git a/DSView/pv/data/groupsnapshot.cpp b/DSView/pv/data/groupsnapshot.cpp index 8a1c4c8c..69a18f1a 100644 --- a/DSView/pv/data/groupsnapshot.cpp +++ b/DSView/pv/data/groupsnapshot.cpp @@ -61,6 +61,37 @@ GroupSnapshot::GroupSnapshot(const boost::shared_ptr &_logic_snap _sample_count = _logic_snapshot->get_sample_count(); _unit_size = _logic_snapshot->unit_size(); _index_list = index_list; + + _mask = 0; + std::list::iterator j = _index_list.begin(); + while(j != _index_list.end()) + _mask |= value_mask[(*j++)]; + + for (int i=0; i<32; i++) { + _bubble_start[i] = -1; + _bubble_end[i] = -1; + } + uint16_t mask = _mask; + int i = 0; + int k = 0; + int zero = 0; + int zero_pre = 0; + // max bubble count: 31 + do { + if (mask & 0x1) { + if (_bubble_start[k] != -1 && + _bubble_end[k] == -1) + _bubble_end[k++] = i - zero_pre; + } else { + if (_bubble_start[k] == -1) { + _bubble_start[k] = i - zero; + zero_pre = zero; + } + zero++; + } + i++; + }while(mask >>= 1); + append_payload(); } @@ -95,21 +126,25 @@ const uint16_t* GroupSnapshot::get_samples( assert(start_sample <= end_sample); int64_t i; - uint64_t pow; + uint16_t tmpl, tmpr; boost::lock_guard lock(_mutex); uint16_t *const data = new uint16_t[end_sample - start_sample]; // memcpy(data, (uint16_t*)_data + start_sample, sizeof(uint16_t) * // (end_sample - start_sample)); - memset(data, 0, sizeof(uint16_t) * (end_sample - start_sample)); +// memset(data, 0, sizeof(uint16_t) * (end_sample - start_sample)); for(i = start_sample; i < end_sample; i++) { - std::list::iterator j = _index_list.begin(); - pow = 0; - while(j != _index_list.end()) { - *(data + i - start_sample) += ((*((uint16_t*)_data + i) & value_mask[(*j)]) >> ((*j) - pow)); - pow++; - j++; + if (_unit_size == 2) + tmpl = *((uint16_t*)_data + i) & _mask; + else + tmpl = *((uint8_t*)_data + i) & _mask; + for(int j=0; _bubble_start[j] != -1; j++) { + tmpr = tmpl & (0xffff >> (16 - _bubble_start[j])); + tmpl >>= _bubble_end[j]; + tmpl <<= _bubble_start[j]; + tmpl += tmpr; } + *(data + i - start_sample) = tmpl; } return data; } @@ -170,61 +205,26 @@ void GroupSnapshot::append_payload_to_envelope_levels() // Iterate through the samples to populate the first level mipmap uint16_t group_value[EnvelopeScaleFactor]; - const uint16_t *const end_src_ptr = (uint16_t*)_data + - e0.length * EnvelopeScaleFactor; - for (const uint16_t *src_ptr = (uint16_t*)_data + - prev_length * EnvelopeScaleFactor; - src_ptr < end_src_ptr; src_ptr += EnvelopeScaleFactor) + const uint8_t *const end_src_ptr = (uint8_t*)_data + + e0.length * EnvelopeScaleFactor * _unit_size; + for (const uint8_t *src_ptr = (uint8_t*)_data + + prev_length * EnvelopeScaleFactor * _unit_size; + src_ptr < end_src_ptr; src_ptr += EnvelopeScaleFactor * _unit_size) { - int pow; -// for(i = 0; i < EnvelopeScaleFactor; i++) { -// group_value[i] = 0; -// std::list::iterator j = _index_list.begin(); -// pow = 0; -// while(j != _index_list.end()) { -// group_value[i] += ((*(src_ptr + i) & value_mask[(*j)]) >> ((*j) - pow)); -// pow++; -// j++; -// } -// } - group_value[0] = 0; - group_value[1] = 0; - group_value[2] = 0; - group_value[3] = 0; - group_value[4] = 0; - group_value[5] = 0; - group_value[6] = 0; - group_value[7] = 0; - group_value[8] = 0; - group_value[9] = 0; - group_value[10] = 0; - group_value[11] = 0; - group_value[12] = 0; - group_value[13] = 0; - group_value[14] = 0; - group_value[15] = 0; - std::list::iterator j = _index_list.begin(); - pow = 0; - while(j != _index_list.end()) { - group_value[0] += ((*(src_ptr + 0) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[1] += ((*(src_ptr + 1) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[2] += ((*(src_ptr + 2) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[3] += ((*(src_ptr + 3) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[4] += ((*(src_ptr + 4) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[5] += ((*(src_ptr + 5) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[6] += ((*(src_ptr + 6) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[7] += ((*(src_ptr + 7) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[8] += ((*(src_ptr + 8) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[9] += ((*(src_ptr + 9) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[10] += ((*(src_ptr + 10) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[11] += ((*(src_ptr + 11) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[12] += ((*(src_ptr + 12) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[13] += ((*(src_ptr + 13) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[14] += ((*(src_ptr + 14) & value_mask[(*j)]) >> ((*j) - pow)); - group_value[15] += ((*(src_ptr + 15) & value_mask[(*j)]) >> ((*j) - pow)); - pow++; - j++; + uint16_t tmpr; + for(int i = 0; i < EnvelopeScaleFactor; i++) { + if (_unit_size == 2) + group_value[i] = *((uint16_t*)src_ptr + i) & _mask; + else + group_value[i] = *((uint8_t*)src_ptr + i) & _mask; + for(int j=0; _bubble_start[j] != -1; j++) { + tmpr = group_value[i] & (0xffff >> (16 - _bubble_start[j])); + group_value[i] >>= _bubble_end[j]; + group_value[i] <<= _bubble_start[j]; + group_value[i] += tmpr; + } } + const EnvelopeSample sub_sample = { *min_element(group_value, group_value + EnvelopeScaleFactor), *max_element(group_value, group_value + EnvelopeScaleFactor), diff --git a/DSView/pv/data/groupsnapshot.h b/DSView/pv/data/groupsnapshot.h index 0b66bf00..729b57a7 100644 --- a/DSView/pv/data/groupsnapshot.h +++ b/DSView/pv/data/groupsnapshot.h @@ -68,7 +68,7 @@ private: }; private: - static const unsigned int ScaleStepCount = 10; + static const unsigned int ScaleStepCount = 16; static const int EnvelopeScalePower; static const int EnvelopeScaleFactor; static const float LogEnvelopeScaleFactor; @@ -103,6 +103,9 @@ private: int _unit_size; boost::shared_ptr _signal; std::list _index_list; + uint16_t _mask; + int _bubble_start[32]; + int _bubble_end[32]; friend class GroupSnapshotTest::Basic; }; diff --git a/DSView/pv/data/logicsnapshot.cpp b/DSView/pv/data/logicsnapshot.cpp index 31614471..ebdb904e 100644 --- a/DSView/pv/data/logicsnapshot.cpp +++ b/DSView/pv/data/logicsnapshot.cpp @@ -74,20 +74,21 @@ void LogicSnapshot::append_payload( append_payload_to_mipmap(); } -void LogicSnapshot::get_samples(uint8_t *const data, - int64_t start_sample, int64_t end_sample) const +uint8_t * LogicSnapshot::get_samples(int64_t start_sample, int64_t end_sample) const { - assert(data); + //assert(data); assert(start_sample >= 0); assert(start_sample <= (int64_t)_sample_count); assert(end_sample >= 0); assert(end_sample <= (int64_t)_sample_count); assert(start_sample <= end_sample); + (void)end_sample; //lock_guard lock(_mutex); - const size_t size = (end_sample - start_sample) * _unit_size; - memcpy(data, (const uint8_t*)_data + start_sample * _unit_size, size); + //const size_t size = (end_sample - start_sample) * _unit_size; + //memcpy(data, (const uint8_t*)_data + start_sample * _unit_size, size); + return (uint8_t*)_data + start_sample * _unit_size; } void LogicSnapshot::reallocate_mipmap_level(MipMapLevel &m) @@ -192,9 +193,7 @@ void LogicSnapshot::get_subsampled_edges( float min_length, int sig_index) { uint64_t index = start; - unsigned int level; bool last_sample; - bool fast_forward; assert(end <= get_sample_count()); assert(start <= end); @@ -254,7 +253,7 @@ bool LogicSnapshot::get_nxt_edge( unsigned int level; bool fast_forward; - assert(index > 0); + //assert(index > 0); const unsigned int min_level = max((int)floorf(logf(min_length) / LogMipMapScaleFactor) - 1, 0); @@ -447,9 +446,9 @@ bool LogicSnapshot::get_pre_edge( // If resolution is less than a mip map block, // round up to the beginning of the mip-map block // for this level of detail - const int min_level_scale_power = + const unsigned int min_level_scale_power = (level + 1) * MipMapScalePower; - if (index < (1 << min_level_scale_power)) + if (index < (uint64_t)(1 << min_level_scale_power)) index = 0; else index = pow2_ceil(index, min_level_scale_power) - (1 << min_level_scale_power) - 1; @@ -539,16 +538,13 @@ bool LogicSnapshot::get_pre_edge( // do a linear search for the next transition within the // block if (min_length < MipMapScaleFactor) { - for (; index >= 0; index--) { + for (; index > 0; index--) { const bool sample = (get_sample(index) & sig_mask) != 0; if (sample != last_sample) { index++; return true; } - - if (index == 0) - return false; } } } diff --git a/DSView/pv/data/logicsnapshot.h b/DSView/pv/data/logicsnapshot.h index 6e9aae12..ba40df84 100644 --- a/DSView/pv/data/logicsnapshot.h +++ b/DSView/pv/data/logicsnapshot.h @@ -67,8 +67,7 @@ public: void append_payload(const sr_datafeed_logic &logic); - void get_samples(uint8_t *const data, - int64_t start_sample, int64_t end_sample) const; + uint8_t * get_samples(int64_t start_sample, int64_t end_sample) const; private: void reallocate_mipmap_level(MipMapLevel &m); diff --git a/DSView/pv/device/file.cpp b/DSView/pv/device/file.cpp index 18c9f6fb..fdc1bd15 100644 --- a/DSView/pv/device/file.cpp +++ b/DSView/pv/device/file.cpp @@ -23,6 +23,8 @@ #include "inputfile.h" #include "sessionfile.h" +#include + #include #include @@ -39,7 +41,8 @@ File::File(QString path) : QString File::format_device_title() const { - return _path; + QFileInfo fi(_path); + return fi.fileName(); } File* File::create(QString name) diff --git a/DSView/pv/devicemanager.cpp b/DSView/pv/devicemanager.cpp index a3d6d212..066af640 100644 --- a/DSView/pv/devicemanager.cpp +++ b/DSView/pv/devicemanager.cpp @@ -102,7 +102,7 @@ std::list > DeviceManager::driver_scan( //release_driver(driver); // Check If DSL hardware driver - if (strcmp(driver->name, "demo") != 0) { + if (strncmp(driver->name, "virtual", 7)) { QDir dir(QCoreApplication::applicationDirPath()); if (!dir.cd("res")) return driver_devices; diff --git a/DSView/pv/dialogs/deviceoptions.cpp b/DSView/pv/dialogs/deviceoptions.cpp index ade12c06..f6a7874e 100644 --- a/DSView/pv/dialogs/deviceoptions.cpp +++ b/DSView/pv/dialogs/deviceoptions.cpp @@ -41,7 +41,7 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptrdev_inst()) { @@ -68,7 +68,16 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptrget_config(NULL, NULL, SR_CONF_OPERATION_MODE); + if (gvar != NULL) { + _mode = QString::fromUtf8(g_variant_get_string(gvar, NULL)); + g_variant_unref(gvar); + } + connect(&_mode_check, SIGNAL(timeout()), this, SLOT(mode_check())); + _mode_check.setInterval(100); + _mode_check.start(); } void DeviceOptions::accept() @@ -100,9 +109,7 @@ void DeviceOptions::accept() void DeviceOptions::reject() { - using namespace Qt; - QDialog::reject(); - + accept(); } QWidget* DeviceOptions::get_property_form() @@ -116,8 +123,11 @@ QWidget* DeviceOptions::get_property_form() BOOST_FOREACH(boost::shared_ptr p, properties) { assert(p); - const QString label = p->labeled_widget() ? QString() : p->name(); - layout->addRow(label, p->get_widget(form)); + const QString label = p->labeled_widget() ? QString() : p->name(); + if (label == tr("Operation Mode")) + layout->addRow(label, p->get_widget(form, true)); + else + layout->addRow(label, p->get_widget(form)); } return form; @@ -127,8 +137,9 @@ void DeviceOptions::setup_probes() { using namespace Qt; - int row = 0, col = 0; + int row0 = 0, row1 = 0, col = 0; int index = 0; + QString ch_mode; while(_probes_box_layout.count() > 0) { @@ -140,6 +151,30 @@ void DeviceOptions::setup_probes() _probes_label_list.clear(); _probes_checkBox_list.clear(); + if (_dev_inst->dev_inst()->mode == LOGIC) { + GVariant *gvar_opts; + gsize num_opts; + if (sr_config_list(_dev_inst->dev_inst()->driver, _dev_inst->dev_inst(), NULL, SR_CONF_CHANNEL_MODE, + &gvar_opts) == SR_OK) { + const char **const options = g_variant_get_strv(gvar_opts, &num_opts); + GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_CHANNEL_MODE); + if (gvar != NULL) { + ch_mode = QString::fromUtf8(g_variant_get_string(gvar, NULL)); + g_variant_unref(gvar); + + for (unsigned int i=0; isetChecked(true); + } + } + } + g_variant_unref(gvar_opts); + } + for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) { sr_channel *const probe = (sr_channel*)l->data; assert(probe); @@ -147,14 +182,14 @@ void DeviceOptions::setup_probes() QLabel *probe_label = new QLabel(QString::number(probe->index), this); QCheckBox *probe_checkBox = new QCheckBox(this); probe_checkBox->setCheckState(probe->enabled ? Qt::Checked : Qt::Unchecked); - _probes_box_layout.addWidget(probe_label, row * 2, col); - _probes_box_layout.addWidget(probe_checkBox, row * 2 + 1, col); + _probes_box_layout.addWidget(probe_label, row1 * 2 + row0, col); + _probes_box_layout.addWidget(probe_checkBox, row1 * 2 + 1 + row0, col); _probes_label_list.push_back(probe_label); _probes_checkBox_list.push_back(probe_checkBox); index++; col = index % 8; - row = index / 8; + row1 = index / 8; } QPushButton *_enable_all_probes = new QPushButton(tr("Enable All"), this); @@ -165,8 +200,8 @@ void DeviceOptions::setup_probes() connect(_disable_all_probes, SIGNAL(clicked()), this, SLOT(disable_all_probes())); - _probes_box_layout.addWidget(_enable_all_probes, (row + 1) * 2, 0, 1, 4); - _probes_box_layout.addWidget(_disable_all_probes, (row + 1) * 2, 4, 1, 4); + _probes_box_layout.addWidget(_enable_all_probes, (row1 + 1) * 2 + row0, 0, 1, 4); + _probes_box_layout.addWidget(_disable_all_probes, (row1 + 1) * 2 + row0, 4, 1, 4); } void DeviceOptions::set_all_probes(bool set) @@ -206,5 +241,44 @@ void DeviceOptions::zero_adj() } } +void DeviceOptions::mode_check() +{ + bool test; + QString mode; + GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_OPERATION_MODE); + if (gvar != NULL) { + mode = QString::fromUtf8(g_variant_get_string(gvar, NULL)); + g_variant_unref(gvar); + + if (mode != _mode) { + setup_probes(); + _mode = mode; + } + } + + gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_TEST); + if (gvar != NULL) { + test = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + + if (test) { + QVector::iterator i = _probes_checkBox_list.begin(); + while(i != _probes_checkBox_list.end()) { + (*i)->setCheckState(Qt::Checked); + (*i)->setDisabled(TRUE); + i++; + } + } + } +} + +void DeviceOptions::channel_check() +{ + QRadioButton* sc=dynamic_cast(sender()); + if(sc != NULL) + _dev_inst->set_config(NULL, NULL, SR_CONF_CHANNEL_MODE, g_variant_new_string(sc->text().toUtf8().data())); + setup_probes(); +} + } // namespace dialogs } // namespace pv diff --git a/DSView/pv/dialogs/deviceoptions.h b/DSView/pv/dialogs/deviceoptions.h index 14b1e5ce..e8cc4ce7 100644 --- a/DSView/pv/dialogs/deviceoptions.h +++ b/DSView/pv/dialogs/deviceoptions.h @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -68,6 +69,8 @@ private slots: void enable_all_probes(); void disable_all_probes(); void zero_adj(); + void mode_check(); + void channel_check(); private: boost::shared_ptr _dev_inst; @@ -84,6 +87,9 @@ private: QPushButton *_config_button; QDialogButtonBox _button_box; + QTimer _mode_check; + QString _mode; + pv::prop::binding::DeviceOptions _device_options_binding; }; diff --git a/DSView/pv/dialogs/dsomeasure.cpp b/DSView/pv/dialogs/dsomeasure.cpp new file mode 100644 index 00000000..9bb36909 --- /dev/null +++ b/DSView/pv/dialogs/dsomeasure.cpp @@ -0,0 +1,85 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2012 Joel Holdsworth + * Copyright (C) 2013 DreamSourceLab + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "dsomeasure.h" + +#include +#include + +#include + +using namespace boost; +using namespace std; +using namespace pv::view; + +namespace pv { +namespace dialogs { + +DsoMeasure::DsoMeasure(QWidget *parent, boost::shared_ptr dsoSig) : + QDialog(parent), + _dsoSig(dsoSig), + _layout(this), + _button_box(QDialogButtonBox::Ok, + Qt::Horizontal, this) +{ + setWindowTitle(tr("DSO Measure Options")); + setLayout(&_layout); + + for (int i=DsoSignal::DSO_MS_BEGIN+1; iget_ms_string(i), this); + checkBox->setProperty("id", QVariant(i)); + checkBox->setChecked(dsoSig->get_ms_en(i)); + _layout.addWidget(checkBox); + connect(checkBox, SIGNAL(toggled(bool)), this, SLOT(set_measure(bool))); + } + + _layout.addWidget(&_button_box); + + connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept())); + connect(&_button_box, SIGNAL(rejected()), this, SLOT(accept())); +} + +void DsoMeasure::set_measure(bool en) +{ + (void)en; + QCheckBox* sc=dynamic_cast(sender()); + if(sc != NULL) { + QVariant id = sc->property("id"); + _dsoSig->set_ms_en(id.toInt(), sc->isChecked()); + } +} + +void DsoMeasure::accept() +{ + using namespace Qt; + + QDialog::accept(); +} + +void DsoMeasure::reject() +{ + accept(); +} + +} // namespace dialogs +} // namespace pv diff --git a/DSView/pv/dialogs/dsomeasure.h b/DSView/pv/dialogs/dsomeasure.h new file mode 100644 index 00000000..05a1ba1a --- /dev/null +++ b/DSView/pv/dialogs/dsomeasure.h @@ -0,0 +1,67 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2012 Joel Holdsworth + * Copyright (C) 2013 DreamSourceLab + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_DSOMEASURE_H +#define DSVIEW_PV_DSOMEASURE_H + +#include +#include +#include + +#include + +#include + +namespace pv { + +namespace view { +class DsoSignal; +} + +namespace dialogs { + +class DsoMeasure : public QDialog +{ + Q_OBJECT + +public: + DsoMeasure(QWidget *parent, boost::shared_ptr dsoSig); + +private slots: + void set_measure(bool en); + +protected: + void accept(); + void reject(); + +private: + boost::shared_ptr _dsoSig; + + QVBoxLayout _layout; + QDialogButtonBox _button_box; +}; + +} // namespace dialogs +} // namespace pv + +#endif // DSVIEW_PV_DSOMEASURE_H diff --git a/DSView/pv/dialogs/search.cpp b/DSView/pv/dialogs/search.cpp index 13dd3d72..aeaeb464 100644 --- a/DSView/pv/dialogs/search.cpp +++ b/DSView/pv/dialogs/search.cpp @@ -48,7 +48,7 @@ Search::Search(QWidget *parent, struct sr_dev_inst *sdi, QString pattern) : search_lineEdit.setInputMask("X X X X X X X X X X X X X X X X"); search_lineEdit.setFont(font); - QLabel *search_label = new QLabel("1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0"); + QLabel *search_label = new QLabel("1 1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0"); search_label->setFont(font); search_buttonBox.addButton(QDialogButtonBox::Ok); diff --git a/DSView/pv/dock/triggerdock.cpp b/DSView/pv/dock/triggerdock.cpp index 8b40af7d..aea64b19 100644 --- a/DSView/pv/dock/triggerdock.cpp +++ b/DSView/pv/dock/triggerdock.cpp @@ -116,7 +116,7 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) : _inv1_comboBox->addItem(tr("!=")); _inv1_comboBox_list.push_back(_inv1_comboBox); - QLabel *value_exp_label = new QLabel("1 1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0", _widget); + QLabel *value_exp_label = new QLabel("1 1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ", _widget); QLabel *inv_exp_label = new QLabel("Inv", _widget); QLabel *count_exp_label = new QLabel("Counter", _widget); value_exp_label->setFont(font); @@ -147,11 +147,6 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) : connect(_value0_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); connect(_value1_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); - connect(_logic_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(logic_changed(int))); - connect(_inv0_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(inv_changed(int))); - connect(_inv1_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(inv_changed(int))); - connect(_count0_spinBox, SIGNAL(editingFinished()), this, SLOT(count_changed())); - connect(_count1_spinBox, SIGNAL(editingFinished()), this, SLOT(count_changed())); } _serial_start_label = new QLabel(tr("Start Flag: "), _widget); @@ -221,7 +216,6 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) : connect(_serial_start_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); connect(_serial_stop_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); connect(_serial_edge_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); - connect(_serial_data_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(serial_channel_changed(int))); connect(_serial_value_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); @@ -233,9 +227,8 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) : connect(simple_radioButton, SIGNAL(clicked()), this, SLOT(simple_trigger())); connect(adv_radioButton, SIGNAL(clicked()), this, SLOT(adv_trigger())); - connect(stages_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(trigger_stages_changed(int))); - connect(position_slider, SIGNAL(valueChanged(int)), this, SLOT(pos_changed(int))); - connect(_adv_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(adv_tog(int))); + connect(stages_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(widget_enable(int))); + QVBoxLayout *layout = new QVBoxLayout(_widget); QGridLayout *gLayout = new QGridLayout(); @@ -256,7 +249,7 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) : _widget->setLayout(layout); this->setWidget(_widget); - _widget->setGeometry(0, 0, sizeHint().width(), 1000); + //_widget->setGeometry(0, 0, sizeHint().width(), 1000); _widget->setObjectName("triggerWidget"); } @@ -274,25 +267,9 @@ void TriggerDock::paintEvent(QPaintEvent *) void TriggerDock::simple_trigger() { - int i; stages_label->setDisabled(true); stages_comboBox->setDisabled(true); _adv_tabWidget->setDisabled(true); - for (i = 0; i < TriggerStages; i++) { - stage_tabWidget->setTabEnabled(i, true); -// _mu_label_list.at(i)->setDisabled(true); -// _logic_comboBox_list.at(i)->setDisabled(true); - -// _value0_lineEdit_list.at(i)->setDisabled(true); -// _count0_spinBox_list.at(i)->setDisabled(true); -// _inv0_comboBox_list.at(i)->setDisabled(true); - -// _value1_lineEdit_list.at(i)->setDisabled(true); -// _count1_spinBox_list.at(i)->setDisabled(true); -// _inv1_comboBox_list.at(i)->setDisabled(true); - } - ds_trigger_set_mode(SIMPLE_TRIGGER); - _session.set_adv_trigger(false); } void TriggerDock::adv_trigger() @@ -313,12 +290,7 @@ void TriggerDock::adv_trigger() msg.exec(); simple_radioButton->setChecked(true); } else { - widget_enable(); - if (_adv_tabWidget->currentIndex() == 0) - ds_trigger_set_mode(ADV_TRIGGER); - else if (_adv_tabWidget->currentIndex() == 1) - ds_trigger_set_mode(SERIAL_TRIGGER); - _session.set_adv_trigger(true); + widget_enable(0); } } else { QMessageBox msg(this); @@ -331,18 +303,10 @@ void TriggerDock::adv_trigger() } } -void TriggerDock::trigger_stages_changed(int index) +void TriggerDock::widget_enable(int index) { - widget_enable(); - ds_trigger_set_stage(index); - value_changed(); - logic_changed(0); - inv_changed(0); - count_changed(); -} + (void) index; -void TriggerDock::widget_enable() -{ int i; int enable_stages; stages_label->setDisabled(false); @@ -352,176 +316,133 @@ void TriggerDock::widget_enable() enable_stages = stages_comboBox->currentText().toInt(); for (i = 0; i < enable_stages; i++) { stage_tabWidget->setTabEnabled(i, true); -// _mu_label_list.at(i)->setVisible(true); -// _mu_label_list.at(i)->setDisabled(false); -// _logic_comboBox_list.at(i)->setVisible(true); -// _logic_comboBox_list.at(i)->setDisabled(false); - -// _value0_lineEdit_list.at(i)->setVisible(true); -// _value0_lineEdit_list.at(i)->setDisabled(false); -// _count0_spinBox_list.at(i)->setVisible(true); -// _count0_spinBox_list.at(i)->setDisabled(false); -// _inv0_comboBox_list.at(i)->setVisible(true); -// _inv0_comboBox_list.at(i)->setDisabled(false); - -// _value1_lineEdit_list.at(i)->setVisible(true); -// _value1_lineEdit_list.at(i)->setDisabled(false); -// _count1_spinBox_list.at(i)->setVisible(true); -// _count1_spinBox_list.at(i)->setDisabled(false); -// _inv1_comboBox_list.at(i)->setVisible(true); -// _inv1_comboBox_list.at(i)->setDisabled(false); } for (i = enable_stages; i < TriggerStages; i++) { stage_tabWidget->setTabEnabled(i, false); -// _mu_label_list.at(i)->setVisible(false); -// _logic_comboBox_list.at(i)->setVisible(false); - -// _value0_lineEdit_list.at(i)->setVisible(false); -// _count0_spinBox_list.at(i)->setVisible(false); -// _inv0_comboBox_list.at(i)->setVisible(false); - -// _value1_lineEdit_list.at(i)->setVisible(false); -// _count1_spinBox_list.at(i)->setVisible(false); -// _inv1_comboBox_list.at(i)->setVisible(false); } } void TriggerDock::value_changed() { - int i; - - if (_adv_tabWidget->currentIndex() == 0) { - for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { - _value0_lineEdit_list.at(i)->setText(_value0_lineEdit_list.at(i)->text().toUpper()); - while(_value0_lineEdit_list.at(i)->text().length() < TriggerProbes) - _value0_lineEdit_list.at(i)->setText("X" + _value0_lineEdit_list.at(i)->text()); - - _value1_lineEdit_list.at(i)->setText(_value1_lineEdit_list.at(i)->text().toUpper()); - while(_value1_lineEdit_list.at(i)->text().length() < TriggerProbes) - _value1_lineEdit_list.at(i)->setText("X" + _value1_lineEdit_list.at(i)->text()); - - ds_trigger_stage_set_value(i, TriggerProbes, - _value0_lineEdit_list.at(i)->text().toLocal8Bit().data(), - _value1_lineEdit_list.at(i)->text().toLocal8Bit().data()); - } - } else if(_adv_tabWidget->currentIndex() == 1){ - _serial_start_lineEdit->setText(_serial_start_lineEdit->text().toUpper()); - ds_trigger_stage_set_value(0, TriggerProbes, - _serial_start_lineEdit->text().toLocal8Bit().data(), - _value1_lineEdit_list.at(0)->text().toLocal8Bit().data()); - _serial_stop_lineEdit->setText(_serial_stop_lineEdit->text().toUpper()); - ds_trigger_stage_set_value(1, TriggerProbes, - _serial_stop_lineEdit->text().toLocal8Bit().data(), - _value1_lineEdit_list.at(1)->text().toLocal8Bit().data()); - _serial_edge_lineEdit->setText(_serial_edge_lineEdit->text().toUpper()); - ds_trigger_stage_set_value(2, TriggerProbes, - _serial_edge_lineEdit->text().toLocal8Bit().data(), - _value1_lineEdit_list.at(2)->text().toLocal8Bit().data()); - //_serial_data_comboBox - const int data_channel = _serial_data_comboBox->currentText().toInt(); - char channel[31]; - for(i = 0; i < 31; i++){ - if (i == (30 - 2*data_channel)) - channel[i] = '1'; - else if (i%2 == 0) - channel[i] = '0'; - else - channel[i] = ' '; - } - ds_trigger_stage_set_value(3, TriggerProbes, - channel, - _value1_lineEdit_list.at(3)->text().toLocal8Bit().data()); - _serial_value_lineEdit->setText(_serial_value_lineEdit->text().toUpper()); - ds_trigger_stage_set_value(4, TriggerProbes, - _serial_value_lineEdit->text().toLocal8Bit().data(), - _value1_lineEdit_list.at(4)->text().toLocal8Bit().data()); - } -} - -void TriggerDock::serial_channel_changed(int index) -{ - (void)index; - value_changed(); -} - -void TriggerDock::logic_changed(int index) -{ - (void)index; - - int i; - - for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { - ds_trigger_stage_set_logic(i, TriggerProbes, - _logic_comboBox_list.at(i)->currentIndex()); - } -} - -void TriggerDock::inv_changed(int index) -{ - (void)index; - - int i; - - for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { - ds_trigger_stage_set_inv(i, TriggerProbes, - _inv0_comboBox_list.at(i)->currentIndex(), - _inv1_comboBox_list.at(i)->currentIndex()); - } -} - -void TriggerDock::count_changed() -{ - int i; - - for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { - ds_trigger_stage_set_count(i, TriggerProbes, - _count0_spinBox_list.at(i)->value() - 1, - _count1_spinBox_list.at(i)->value() - 1); - } -} - -void TriggerDock::pos_changed(int pos) -{ - ds_trigger_set_pos(pos); + QLineEdit* sc=dynamic_cast(sender()); + if(sc != NULL) + sc->setText(sc->text().toUpper()); } void TriggerDock::device_change() { + uint64_t max_hd_depth; bool stream = false; - GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_STREAM); + uint8_t maxRange; + uint64_t sample_limits; + GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_MAX_LOGIC_SAMPLELIMITS); if (gvar != NULL) { - stream = g_variant_get_boolean(gvar); + max_hd_depth = g_variant_get_uint64(gvar); g_variant_unref(gvar); - } - if (stream && - strcmp(_session.get_device()->dev_inst()->driver->name, "DSLogic") == 0) { - const int maxRange = SR_MB(11)*100/_session.get_device()->get_sample_limit(); - position_spinBox->setRange(0, maxRange); - position_slider->setRange(0, maxRange); - simple_radioButton->setChecked(true); - simple_trigger(); - } else { - position_spinBox->setRange(0, 99); - position_slider->setRange(0, 99); + if (_session.get_device()->dev_inst()->mode == LOGIC) { + sample_limits = _session.get_device()->get_sample_limit(); + if (max_hd_depth >= sample_limits) + maxRange = 99; + else + maxRange = max_hd_depth*70 / sample_limits; + position_spinBox->setRange(0, maxRange); + position_slider->setRange(0, maxRange); + + + + gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_STREAM); + if (gvar != NULL) { + stream = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + } + + if (!strncmp(_session.get_device()->dev_inst()->driver->name, "virtual", 7) || + stream) { + simple_radioButton->setChecked(true); + simple_trigger(); + } + } } } -void TriggerDock::adv_tog(int index) +bool TriggerDock::commit_trigger() { - if(index == 0) { - stages_label->setDisabled(false); - stages_comboBox->setDisabled(false); - ds_trigger_set_mode(ADV_TRIGGER); - } else if (index == 1) { - stages_label->setDisabled(true); - stages_comboBox->setDisabled(true); - ds_trigger_set_mode(SERIAL_TRIGGER); + // trigger position update + ds_trigger_set_pos(position_slider->value()); + + // trigger mode update + if (simple_radioButton->isChecked()) { + ds_trigger_set_mode(SIMPLE_TRIGGER); + return 0; + } else { + ds_trigger_set_en(true); + if (_adv_tabWidget->currentIndex() == 0) + ds_trigger_set_mode(ADV_TRIGGER); + else if (_adv_tabWidget->currentIndex() == 1) + ds_trigger_set_mode(SERIAL_TRIGGER); + + // trigger stage update + ds_trigger_set_stage(stages_comboBox->currentText().toInt()); + + int i; + // trigger value update + if (_adv_tabWidget->currentIndex() == 0) { + for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { + ds_trigger_stage_set_value(i, TriggerProbes, + _value0_lineEdit_list.at(i)->text().toLocal8Bit().data(), + _value1_lineEdit_list.at(i)->text().toLocal8Bit().data()); + } + } else if(_adv_tabWidget->currentIndex() == 1){ + ds_trigger_stage_set_value(0, TriggerProbes, + _serial_start_lineEdit->text().toLocal8Bit().data(), + _value1_lineEdit_list.at(0)->text().toLocal8Bit().data()); + ds_trigger_stage_set_value(1, TriggerProbes, + _serial_stop_lineEdit->text().toLocal8Bit().data(), + _value1_lineEdit_list.at(1)->text().toLocal8Bit().data()); + ds_trigger_stage_set_value(2, TriggerProbes, + _serial_edge_lineEdit->text().toLocal8Bit().data(), + _value1_lineEdit_list.at(2)->text().toLocal8Bit().data()); + //_serial_data_comboBox + const int data_channel = _serial_data_comboBox->currentText().toInt(); + char channel[31]; + for(i = 0; i < 31; i++){ + if (i == (30 - 2*data_channel)) + channel[i] = '1'; + else if (i%2 == 0) + channel[i] = '0'; + else + channel[i] = ' '; + } + ds_trigger_stage_set_value(3, TriggerProbes, + channel, + _value1_lineEdit_list.at(3)->text().toLocal8Bit().data()); + ds_trigger_stage_set_value(4, TriggerProbes, + _serial_value_lineEdit->text().toLocal8Bit().data(), + _value1_lineEdit_list.at(4)->text().toLocal8Bit().data()); + } + + // trigger logic update + for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { + ds_trigger_stage_set_logic(i, TriggerProbes, + _logic_comboBox_list.at(i)->currentIndex()); + } + + // trigger inv update + for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { + ds_trigger_stage_set_inv(i, TriggerProbes, + _inv0_comboBox_list.at(i)->currentIndex(), + _inv1_comboBox_list.at(i)->currentIndex()); + } + + // trigger count update + for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { + ds_trigger_stage_set_count(i, TriggerProbes, + _count0_spinBox_list.at(i)->value() - 1, + _count1_spinBox_list.at(i)->value() - 1); + } + return 1; } - value_changed(); - logic_changed(0); - inv_changed(0); - count_changed(); } void TriggerDock::init() @@ -597,11 +518,6 @@ void TriggerDock::set_session(QJsonObject ses) _serial_edge_lineEdit->setText(ses["triggerClock"].toString()); _serial_data_comboBox->setCurrentIndex(ses["triggerChannel"].toDouble()); _serial_value_lineEdit->setText(ses["triggerData"].toString()); - - value_changed(); - logic_changed(0); - inv_changed(0); - count_changed(); } } // namespace dock diff --git a/DSView/pv/dock/triggerdock.h b/DSView/pv/dock/triggerdock.h index 8b76b959..4d9fd4ec 100644 --- a/DSView/pv/dock/triggerdock.h +++ b/DSView/pv/dock/triggerdock.h @@ -61,30 +61,28 @@ public: void paintEvent(QPaintEvent *); - void device_change(); - void init(); QJsonObject get_session(); void set_session(QJsonObject ses); + /* + * commit trigger setting + * return 0: simple trigger + * 1: advanced trigger + */ + bool commit_trigger(); + signals: public slots: void simple_trigger(); void adv_trigger(); - void trigger_stages_changed(int index); - void widget_enable(); + void widget_enable(int index); void value_changed(); - void logic_changed(int index); - void count_changed(); - void inv_changed(int index); - void pos_changed(int pos); - - void adv_tog(int index); - void serial_channel_changed(int index); + void device_change(); private: diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index a00cc679..2b708075 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -71,6 +71,7 @@ #include "view/trace.h" #include "view/signal.h" #include "view/dsosignal.h" +#include "view/logicsignal.h" /* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */ #define __STDC_FORMAT_MACROS @@ -192,6 +193,8 @@ void MainWindow::setup_ui() SLOT(instant_stop())); connect(_sampling_bar, SIGNAL(update_scale()), _view, SLOT(update_scale()), Qt::DirectConnection); + connect(_sampling_bar, SIGNAL(sample_count_changed()), _trigger_widget, + SLOT(device_change())); connect(_dso_trigger_widget, SIGNAL(set_trig_pos(quint64)), _view, SLOT(set_trig_pos(quint64))); @@ -284,6 +287,7 @@ void MainWindow::update_device_list() { assert(_sampling_bar); + _session.stop_capture(); _view->show_trig_cursor(false); _trigger_widget->device_change(); #ifdef ENABLE_DECODE @@ -315,8 +319,7 @@ void MainWindow::update_device_list() errorMessage, infoMessage)); } - if (strcmp(selected_device->dev_inst()->driver->name, "demo") != 0 && - strcmp(selected_device->dev_inst()->driver->name, "virtual-session") != 0) { + if (strncmp(selected_device->dev_inst()->driver->name, "virtual", 7)) { _logo_bar->dsl_connected(true); QString ses_name = config_path + QString::fromUtf8(selected_device->dev_inst()->driver->name) + @@ -411,6 +414,7 @@ void MainWindow::run_stop() case SigSession::Stopped: _view->show_trig_cursor(false); _view->update_sample(false); + commit_trigger(false); _session.start_capture(false, boost::bind(&MainWindow::session_error, this, QString("Capture failed"), _1)); @@ -434,6 +438,7 @@ void MainWindow::instant_stop() case SigSession::Stopped: _view->show_trig_cursor(false); _view->update_sample(true); + commit_trigger(true); _session.start_capture(true, boost::bind(&MainWindow::session_error, this, QString("Capture failed"), _1)); @@ -483,6 +488,25 @@ void MainWindow::capture_state_changed(int state) _sampling_bar->enable_toggle(state != SigSession::Running); _trig_bar->enable_toggle(state != SigSession::Running); _measure_dock->widget()->setEnabled(state != SigSession::Running); + if (_session.get_device()->dev_inst()->mode == LOGIC && + state == SigSession::Stopped) { + GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_RLE); + if (gvar != NULL) { + bool rle = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + if (rle) { + gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_ACTUAL_SAMPLES); + if (gvar != NULL) { + uint64_t actual_samples = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + if (actual_samples != _session.get_device()->get_sample_limit()) { + show_session_error(tr("RLE Mode Warning"), + tr("Hardware buffer is full!\nActually received samples is less than setted sample depth!")); + } + } + } + } + } #ifdef TEST_MODE if (state == SigSession::Stopped) { test_timer.start(100); @@ -498,7 +522,8 @@ void MainWindow::closeEvent(QCloseEvent *event) QString driver_name = _session.get_device()->dev_inst()->driver->name; QString mode_name = QString::number(_session.get_device()->dev_inst()->mode); QString file_name = dir.absolutePath() + "/" + driver_name + mode_name + ".dsc"; - if (!file_name.isEmpty()) + if (strncmp(driver_name.toLocal8Bit(), "virtual", 7) && + !file_name.isEmpty()) store_session(file_name); } event->accept(); @@ -525,6 +550,26 @@ void MainWindow::on_trigger(bool visible) } } +void MainWindow::commit_trigger(bool instant) +{ + ds_trigger_init(); + + if (_session.get_device()->dev_inst()->mode != LOGIC || + instant) + return; + + if (!_trigger_widget->commit_trigger()) { + /* simple trigger check trigger_enable */ + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) + { + assert(s); + boost::shared_ptr logicSig; + if (logicSig = dynamic_pointer_cast(s)) + logicSig->commit_trig(); + } + } +} + void MainWindow::on_measure(bool visible) { _measure_dock->setVisible(visible); @@ -632,7 +677,6 @@ bool MainWindow::load_session(QString name) bool isEnabled = false; foreach (const QJsonValue &value, sessionObj["channel"].toArray()) { QJsonObject obj = value.toObject(); - qDebug("obj.index = %d", obj["index"].toDouble()); if ((probe->index == obj["index"].toDouble()) && (probe->type == obj["type"].toDouble())) { isEnabled = true; @@ -659,13 +703,16 @@ bool MainWindow::load_session(QString name) if ((s->get_index() == obj["index"].toDouble()) && (s->get_type() == obj["type"].toDouble())) { s->set_colour(QColor(obj["colour"].toString())); - s->set_trig(obj["strigger"].toDouble()); + + boost::shared_ptr logicSig; + if (logicSig = dynamic_pointer_cast(s)) { + logicSig->set_trig(obj["strigger"].toDouble()); + } + boost::shared_ptr dsoSig; if (dsoSig = dynamic_pointer_cast(s)) { - dsoSig->update_hDial(); - //dsoSig->update_vDial(); + dsoSig->load_settings(); dsoSig->set_zeroRate(obj["zeroPos"].toDouble()); - dsoSig->set_enable(obj["enabled"].toBool()); dsoSig->set_trigRate(obj["trigValue"].toDouble()); } break; @@ -736,11 +783,16 @@ bool MainWindow::store_session(QString name) s_obj["enabled"] = s->enabled(); s_obj["name"] = s->get_name(); s_obj["colour"] = QJsonValue::fromVariant(s->get_colour()); - s_obj["strigger"] = s->get_trig(); + + boost::shared_ptr logicSig; + if (logicSig = dynamic_pointer_cast(s)) { + s_obj["strigger"] = logicSig->get_trig(); + } + boost::shared_ptr dsoSig; if (dsoSig = dynamic_pointer_cast(s)) { - s_obj["vdiv"] = QJsonValue::fromVariant(dsoSig->get_vDialValue()); - s_obj["vfactor"] = QJsonValue::fromVariant(dsoSig->get_factor()); + s_obj["vdiv"] = QJsonValue::fromVariant(static_cast(dsoSig->get_vDialValue())); + s_obj["vfactor"] = QJsonValue::fromVariant(static_cast(dsoSig->get_factor())); s_obj["coupling"] = dsoSig->get_acCoupling(); s_obj["trigValue"] = dsoSig->get_trigRate(); s_obj["zeroPos"] = dsoSig->get_zeroRate(); diff --git a/DSView/pv/mainwindow.h b/DSView/pv/mainwindow.h index 4fd0b7c5..0ae69138 100644 --- a/DSView/pv/mainwindow.h +++ b/DSView/pv/mainwindow.h @@ -112,6 +112,8 @@ private slots: void on_trigger(bool visible); + void commit_trigger(bool instant); + void on_measure(bool visible); void on_search(bool visible); diff --git a/DSView/pv/prop/binding/binding_deviceoptions.cpp b/DSView/pv/prop/binding/binding_deviceoptions.cpp index e1ce83ec..c8c1e9a0 100644 --- a/DSView/pv/prop/binding/binding_deviceoptions.cpp +++ b/DSView/pv/prop/binding/binding_deviceoptions.cpp @@ -82,6 +82,8 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : case SR_CONF_BUFFERSIZE: case SR_CONF_TRIGGER_SOURCE: case SR_CONF_FILTER: + case SR_CONF_MAX_HEIGHT: + case SR_CONF_MAX_HEIGHT_VALUE: case SR_CONF_COUPLING: case SR_CONF_EN_CH: case SR_CONF_OPERATION_MODE: @@ -91,7 +93,7 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : case SR_CONF_TEST: case SR_CONF_STATUS: case SR_CONF_FACTOR: - bind_enum(name, key, gvar_list); + bind_enum(name, key, gvar_list); break; case SR_CONF_VTH: @@ -110,11 +112,11 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : break; case SR_CONF_TIMEBASE: - bind_enum(name, key, gvar_list, print_timebase); + bind_enum(name, key, gvar_list, print_timebase); break; case SR_CONF_VDIV: - bind_enum(name, key, gvar_list, print_vdiv); + bind_enum(name, key, gvar_list, print_vdiv); break; default: gvar_list = NULL; @@ -153,7 +155,7 @@ void DeviceOptions::bind_bool(const QString &name, int key) } void DeviceOptions::bind_enum(const QString &name, int key, - GVariant *const gvar_list, boost::function printer) + GVariant *const gvar_list, boost::function printer) { GVariant *gvar; GVariantIter iter; @@ -166,7 +168,7 @@ void DeviceOptions::bind_enum(const QString &name, int key, values.push_back(make_pair(gvar, printer(gvar))); _properties.push_back(boost::shared_ptr( - new Enum(name, values, + new Enum(name, values, bind(config_getter, _sdi, key), bind(config_setter, _sdi, key, _1)))); } @@ -235,7 +237,7 @@ void DeviceOptions::bind_samplerate(const QString &name, else if ((gvar_list_samplerates = g_variant_lookup_value(gvar_list, "samplerates", G_VARIANT_TYPE("at")))) { - bind_enum(name, SR_CONF_SAMPLERATE, + bind_enum(name, SR_CONF_SAMPLERATE, gvar_list_samplerates, print_samplerate); g_variant_unref(gvar_list_samplerates); } diff --git a/DSView/pv/prop/int.cpp b/DSView/pv/prop/int.cpp index 5c0dc7d7..1c9e79cd 100644 --- a/DSView/pv/prop/int.cpp +++ b/DSView/pv/prop/int.cpp @@ -32,20 +32,20 @@ using boost::optional; using namespace std; -#define INT8_MIN (-0x7f - 1) -#define INT16_MIN (-0x7fff - 1) -#define INT32_MIN (-0x7fffffff - 1) -#define INT64_MIN (-0x7fffffffffffffff - 1) - -#define INT8_MAX 0x7f -#define INT16_MAX 0x7fff -#define INT32_MAX 0x7fffffff -#define INT64_MAX 0x7fffffffffffffff - -#define UINT8_MAX 0xff -#define UINT16_MAX 0xffff -#define UINT32_MAX 0xffffffff -#define UINT64_MAX 0xffffffffffffffff +//#define INT8_MIN (-0x7f - 1) +//#define INT16_MIN (-0x7fff - 1) +//#define INT32_MIN (-0x7fffffff - 1) +//#define INT64_MIN (-0x7fffffffffffffff - 1) +// +//#define INT8_MAX 0x7f +//#define INT16_MAX 0x7fff +//#define INT32_MAX 0x7fffffff +//#define INT64_MAX 0x7fffffffffffffff +// +//#define UINT8_MAX 0xff +//#define UINT16_MAX 0xffff +//#define UINT32_MAX 0xffffffff +//#define UINT64_MAX 0xffffffffffffffff namespace pv { namespace prop { diff --git a/DSView/pv/prop/property.cpp b/DSView/pv/prop/property.cpp index d0ab15ea..48ca4a2c 100644 --- a/DSView/pv/prop/property.cpp +++ b/DSView/pv/prop/property.cpp @@ -29,7 +29,7 @@ namespace prop { Property::Property(QString name, Getter getter, Setter setter) : _getter(getter), _setter(setter), - _name(name) + _name(name) { } diff --git a/DSView/pv/prop/property.h b/DSView/pv/prop/property.h index d02bd510..6ef784d5 100644 --- a/DSView/pv/prop/property.h +++ b/DSView/pv/prop/property.h @@ -45,10 +45,10 @@ public: typedef boost::function Setter; protected: - Property(QString name, Getter getter, Setter setter); + Property(QString name, Getter getter, Setter setter); public: - const QString& name() const; + const QString& name() const; virtual QWidget* get_widget(QWidget *parent, bool auto_commit = false) = 0; @@ -61,7 +61,7 @@ protected: const Setter _setter; private: - QString _name; + QString _name; }; } // prop diff --git a/DSView/pv/prop/string.cpp b/DSView/pv/prop/string.cpp index 7542faef..e03064ef 100644 --- a/DSView/pv/prop/string.cpp +++ b/DSView/pv/prop/string.cpp @@ -64,7 +64,7 @@ void String::commit() if (!_line_edit) return; - QByteArray ba = _line_edit->text().toLocal8Bit(); + QByteArray ba = _line_edit->text().toUtf8(); _setter(g_variant_new_string(ba.data())); } diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 3a6cb096..fb547f52 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -92,9 +92,7 @@ SigSession::SigSession(DeviceManager &device_manager) : _session = this; _hot_attach = false; _hot_detach = false; - _adv_trigger = false; _group_cnt = 0; - ds_trigger_init(); register_hotplug_callback(); _view_timer.stop(); _view_timer.setSingleShot(true); @@ -177,19 +175,45 @@ void SigSession::set_file(QString name) throw(QString) } } -void SigSession::save_file(const QString name){ - const deque< boost::shared_ptr > &snapshots = - _logic_data->get_snapshots(); - if (snapshots.empty()) - return; - - const boost::shared_ptr &snapshot = - snapshots.front(); +void SigSession::save_file(const QString name, int type){ + unsigned char* data; + int unit_size; + uint64_t sample_count; + if (type == ANALOG) { + const deque< boost::shared_ptr > &snapshots = + _analog_data->get_snapshots(); + if (snapshots.empty()) + return; + const boost::shared_ptr &snapshot = + snapshots.front(); + data = (unsigned char*)snapshot->get_data(); + unit_size = snapshot->unit_size(); + sample_count = snapshot->get_sample_count(); + } else if (type == DSO) { + const deque< boost::shared_ptr > &snapshots = + _dso_data->get_snapshots(); + if (snapshots.empty()) + return; + const boost::shared_ptr &snapshot = + snapshots.front(); + data = (unsigned char*)snapshot->get_data(); + // snapshot->unit_size() is not valid for dso, replaced by enabled channel number + unit_size = get_ch_num(SR_CHANNEL_DSO); + sample_count = snapshot->get_sample_count(); + } else { + const deque< boost::shared_ptr > &snapshots = + _logic_data->get_snapshots(); + if (snapshots.empty()) + return; + const boost::shared_ptr &snapshot = + snapshots.front(); + data = (unsigned char*)snapshot->get_data(); + unit_size = snapshot->unit_size(); + sample_count = snapshot->get_sample_count(); + } sr_session_save(name.toLocal8Bit().data(), _dev_inst->dev_inst(), - (unsigned char*)snapshot->get_data(), - snapshot->unit_size(), - snapshot->get_sample_count()); + data, unit_size, sample_count); } QList SigSession::getSuportedExportFormats(){ @@ -205,7 +229,7 @@ QList SigSession::getSuportedExportFormats(){ format.append((*supportedModules)->id); format.append(")"); list.append(format); - *supportedModules++; + supportedModules++; } return list; } @@ -245,7 +269,7 @@ void SigSession::export_file(const QString name, QWidget* parent, const QString outModule = *supportedModules; break; } - *supportedModules++; + supportedModules++; } if(outModule == NULL) return; @@ -283,8 +307,8 @@ void SigSession::export_file(const QString name, QWidget* parent, const QString unsigned char* datat = (unsigned char*)snapshot->get_data(); unsigned int numsamples = snapshot->get_sample_count()*snapshot->unit_size(); GString *data_out; - int usize = 8192; - int size = usize; + unsigned int usize = 8192; + unsigned int size = usize; struct sr_datafeed_logic lp; struct sr_datafeed_packet p; for(uint64_t i = 0; i < numsamples; i+=usize){ @@ -311,8 +335,8 @@ void SigSession::export_file(const QString name, QWidget* parent, const QString unsigned char* datat = (unsigned char*)snapshot->get_data(); unsigned int numsamples = snapshot->get_sample_count(); GString *data_out; - int usize = 8192; - int size = usize; + unsigned int usize = 8192; + unsigned int size = usize; struct sr_datafeed_dso dp; struct sr_datafeed_packet p; for(uint64_t i = 0; i < numsamples; i+=usize){ @@ -365,8 +389,8 @@ void SigSession::set_default_device(boost::function error_ // Try and find the DreamSourceLab device and select that by default BOOST_FOREACH (boost::shared_ptr dev, devices) if (dev->dev_inst() && - strcmp(dev->dev_inst()->driver->name, - "demo") != 0) { + strncmp(dev->dev_inst()->driver->name, + "virtual", 7) != 0) { default_device = dev; break; } @@ -423,7 +447,10 @@ void SigSession::start_capture(bool instant, } // update setting - _instant = instant; + if (strcmp(_dev_inst->dev_inst()->driver->name, "virtual-session")) + _instant = instant; + else + _instant = true; if (~_instant) _view_timer.blockSignals(false); @@ -436,6 +463,7 @@ void SigSession::start_capture(bool instant, void SigSession::stop_capture() { + _instant = false; if (get_capture_state() != Running) return; sr_session_stop(); @@ -467,6 +495,7 @@ set< boost::shared_ptr > SigSession::get_data() const assert(sig); data.insert(sig->data()); } + data.insert(_group_data); return data; } @@ -532,25 +561,6 @@ void SigSession::sample_thread_proc(boost::shared_ptr dev_inst, assert(dev_inst->dev_inst()); assert(error_handler); - if (_instant) { - /* disable trigger under instant mode */ - ds_trigger_set_en(false); - } else if (!_adv_trigger) { - /* simple trigger check trigger_enable */ - ds_trigger_set_en(false); - BOOST_FOREACH(const boost::shared_ptr s, _signals) - { - assert(s); - if (s->get_trig() != 0) { - ds_trigger_set_en(true); - s->set_trig(s->get_trig()); - } - } - } else { - /* advanced trigger check trigger_enable */ - ds_trigger_set_en(true); - } - try { dev_inst->start(); } catch(const QString e) { @@ -623,16 +633,18 @@ void SigSession::add_group() _group_traces.push_back(signal); _group_cnt++; - if (_capture_state == Stopped) { - if (!_cur_group_snapshot) - { + const deque< boost::shared_ptr > &snapshots = + _logic_data->get_snapshots(); + if (!snapshots.empty()) { + //if (!_cur_group_snapshot) + //{ // Create a new data snapshot _cur_group_snapshot = boost::shared_ptr( - new data::GroupSnapshot(_logic_data->get_snapshots().front(), signal->get_index_list())); + new data::GroupSnapshot(snapshots.front(), signal->get_index_list())); //_cur_group_snapshot->append_payload(); _group_data->push_snapshot(_cur_group_snapshot); _cur_group_snapshot.reset(); - } + //} } signals_changed(); @@ -719,10 +731,6 @@ void SigSession::init_signals() if (logic_probe_count != 0) { _logic_data.reset(new data::Logic()); assert(_logic_data); - - _group_data.reset(new data::Group()); - assert(_group_data); - _group_cnt = 0; } if (dso_probe_count != 0) { @@ -734,10 +742,17 @@ void SigSession::init_signals() _analog_data.reset(new data::Analog()); assert(_analog_data); } + + _group_data.reset(new data::Group()); + assert(_group_data); + _group_cnt = 0; } // Make the logic probe list { + _group_traces.clear(); + vector< boost::shared_ptr >().swap(_group_traces); + for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) { const sr_channel *const probe = (const sr_channel *)l->data; @@ -793,12 +808,22 @@ void SigSession::reload() signal.reset(); switch(probe->type) { case SR_CHANNEL_LOGIC: - if (probe->enabled && probe->index < _signals.size()) - signal = boost::shared_ptr( - new view::LogicSignal(*_signals[probe->index].get(), _logic_data, probe)); - else if (probe->enabled) - signal = boost::shared_ptr( - new view::LogicSignal(_dev_inst, _logic_data, probe)); + if (probe->enabled) { + std::vector< boost::shared_ptr >::iterator i = _signals.begin(); + while (i != _signals.end()) { + if ((*i)->get_index() == probe->index) { + boost::shared_ptr logicSig; + if (logicSig = dynamic_pointer_cast(*i)) + signal = boost::shared_ptr( + new view::LogicSignal(logicSig, _logic_data, probe)); + break; + } + i++; + } + if (!signal.get()) + signal = boost::shared_ptr( + new view::LogicSignal(_dev_inst, _logic_data, probe)); + } break; case SR_CHANNEL_DSO: @@ -838,8 +863,10 @@ void SigSession::refresh(int holdtime) _analog_data->clear(); _cur_analog_snapshot.reset(); } - _data_lock = true; - _refresh_timer.start(holdtime); + if (strncmp(_dev_inst->dev_inst()->driver->name, "virtual", 7)) { + _data_lock = true; + _refresh_timer.start(holdtime); + } data_updated(); } @@ -1056,13 +1083,16 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi, { { boost::lock_guard lock(_data_mutex); - BOOST_FOREACH(const boost::shared_ptr g, _group_traces) - { - assert(g); + if (_cur_logic_snapshot) { + BOOST_FOREACH(const boost::shared_ptr g, _group_traces) + { + assert(g); - _cur_group_snapshot = boost::shared_ptr( - new data::GroupSnapshot(_logic_data->get_snapshots().front(), g->get_index_list())); - _group_data->push_snapshot(_cur_group_snapshot); + _cur_group_snapshot = boost::shared_ptr( + new data::GroupSnapshot(_logic_data->get_snapshots().front(), g->get_index_list())); + _group_data->push_snapshot(_cur_group_snapshot); + _cur_group_snapshot.reset(); + } } _cur_logic_snapshot.reset(); _cur_dso_snapshot.reset(); @@ -1186,15 +1216,6 @@ void SigSession::stop_hotplug_proc() _hotplug.reset(); } -/* - * Tigger - */ -void SigSession::set_adv_trigger(bool adv_trigger) -{ - _adv_trigger = adv_trigger; -} - - uint16_t SigSession::get_ch_num(int type) { uint16_t num_channels = 0; diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index 96503ef2..23ad6a90 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -117,13 +117,11 @@ public: void set_file(QString name) throw(QString); - void save_file(const QString name); + void save_file(const QString name, int type); void set_default_device(boost::function error_handler); void export_file(const QString name, QWidget* parent, const QString ext); - void set_default_device(); - void release_device(device::DevInst *dev_inst); capture_state get_capture_state() const; @@ -171,8 +169,6 @@ public: void register_hotplug_callback(); void deregister_hotplug_callback(); - void set_adv_trigger(bool adv_trigger); - uint16_t get_ch_num(int type); bool get_instant(); @@ -251,15 +247,13 @@ private: boost::shared_ptr _cur_group_snapshot; int _group_cnt; - std::auto_ptr _sampling_thread; + std::unique_ptr _sampling_thread; libusb_hotplug_callback_handle _hotplug_handle; - std::auto_ptr _hotplug; + std::unique_ptr _hotplug; bool _hot_attach; bool _hot_detach; - bool _adv_trigger; - QTimer _view_timer; QTimer _refresh_timer; bool _data_lock; diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp index a687a0b0..6d2ea359 100644 --- a/DSView/pv/storesession.cpp +++ b/DSView/pv/storesession.cpp @@ -150,8 +150,9 @@ void StoreSession::store_proc(shared_ptr snapshot) uint64_t start_sample = 0; /// TODO: Wrap this in a std::unique_ptr when we transition to C++11 - uint8_t *const data = new uint8_t[BlockSize]; - assert(data); + uint8_t *data = NULL; + //uint8_t *const data = new uint8_t[BlockSize]; + //assert(data); const int unit_size = snapshot->unit_size(); assert(unit_size != 0); @@ -170,7 +171,7 @@ void StoreSession::store_proc(shared_ptr snapshot) const uint64_t end_sample = min( start_sample + samples_per_block, _unit_count); - snapshot->get_samples(data, start_sample, end_sample); + data = snapshot->get_samples(start_sample, end_sample); if(sr_session_append(_file_name.c_str(), data, unit_size, end_sample - start_sample) != SR_OK) @@ -189,7 +190,7 @@ void StoreSession::store_proc(shared_ptr snapshot) progress_updated(); - delete[] data; + //delete[] data; } } // pv diff --git a/DSView/pv/toolbars/filebar.cpp b/DSView/pv/toolbars/filebar.cpp index 4f557505..5562db7a 100644 --- a/DSView/pv/toolbars/filebar.cpp +++ b/DSView/pv/toolbars/filebar.cpp @@ -200,22 +200,16 @@ void FileBar::on_actionSave_triggered() msg.setStandardButtons(QMessageBox::Ok); msg.setIcon(QMessageBox::Warning); msg.exec(); - } else if (_session.get_device()->dev_inst()->mode != LOGIC) { - QMessageBox msg(this); - msg.setText(tr("File Save")); - msg.setInformativeText(tr("DSView currently only support saving logic data to file!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); - msg.exec(); - }else { + } else { QString file_name = QFileDialog::getSaveFileName( - this, tr("Save File"), "", - tr("DSView Data (*.dsl)")); + this, tr("Save File"), "", + tr("DSView Data (*.dsl)")); + if (!file_name.isEmpty()) { QFileInfo f(file_name); if(f.suffix().compare("dsl")) file_name.append(tr(".dsl")); - _session.save_file(file_name); + _session.save_file(file_name, _session.get_device()->dev_inst()->mode); } } } diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index bad13045..85b45603 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -222,8 +222,12 @@ void SamplingBar::on_configure() pv::dialogs::DeviceOptions dlg(this, dev_inst); ret = dlg.exec(); - if (ret == QDialog::Accepted) + if (ret == QDialog::Accepted) { device_updated(); + update_sample_count_selector(); + update_sample_rate_selector(); + commit_sample_rate(); + } GVariant* gvar = dev_inst->get_config(NULL, NULL, SR_CONF_ZERO); if (gvar != NULL) { @@ -289,12 +293,24 @@ void SamplingBar::set_record_length(uint64_t length) void SamplingBar::update_record_length() { - update_sample_count_selector_value(); + disconnect(&_sample_count, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_samplecount_sel(int))); + + update_sample_count_selector(); + + connect(&_sample_count, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_samplecount_sel(int))); } void SamplingBar::update_sample_rate() { - update_sample_rate_selector_value(); + disconnect(&_sample_rate, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_samplerate_sel(int))); + + update_sample_rate_selector(); + + connect(&_sample_rate, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_samplerate_sel(int))); } void SamplingBar::set_sampling(bool sampling) @@ -415,9 +431,9 @@ void SamplingBar::update_sample_rate_selector() _updating_sample_rate = false; g_variant_unref(gvar_dict); + update_sample_rate_selector_value(); connect(&_sample_rate, SIGNAL(currentIndexChanged(int)), this, SLOT(on_samplerate_sel(int))); - update_sample_rate_selector_value(); } void SamplingBar::update_sample_rate_selector_value() @@ -438,7 +454,7 @@ void SamplingBar::update_sample_rate_selector_value() break; } } - + update_scale(); _updating_sample_rate = false; } @@ -478,12 +494,8 @@ void SamplingBar::commit_sample_rate() void SamplingBar::on_samplecount_sel(int index) { uint64_t sample_count = 0; - uint64_t max_sample_count = 0; - uint64_t last_sample_count = 0; - bool stream_mode = false; - bool buffer2stream = false; - bool stream2buffer = false; + qDebug() << "index: " << index; if (index >= 0) sample_count = _sample_count.itemData( index).value(); @@ -492,58 +504,13 @@ void SamplingBar::on_samplecount_sel(int index) assert(_devInst); if (strcmp(_devInst->dev_inst()->driver->name, "DSLogic") == 0 && _devInst->dev_inst()->mode != DSO) { - GVariant* gvar = _devInst->get_config(NULL, NULL, SR_CONF_LIMIT_SAMPLES); - if (gvar != NULL) { - last_sample_count = g_variant_get_uint64(gvar); - g_variant_unref(gvar); - } - gvar = _devInst->get_config(NULL, NULL, SR_CONF_MAX_LOGIC_SAMPLELIMITS); - if (gvar != NULL) { - max_sample_count = g_variant_get_uint64(gvar); - g_variant_unref(gvar); - } - gvar = _devInst->get_config(NULL, NULL, SR_CONF_STREAM); - if (gvar != NULL) { - stream_mode = g_variant_get_boolean(gvar); - g_variant_unref(gvar); - } - - if (((!stream_mode || (last_sample_count >= SR_GB(1))) && sample_count > max_sample_count) || - (sample_count >= SR_GB(1) && _devInst->get_sample_rate() <= SR_MHZ(10))) { - stream_mode = sample_count > max_sample_count; - buffer2stream = true; - } else if (stream_mode && sample_count <= max_sample_count) { - stream_mode = sample_count > max_sample_count; - stream2buffer = true; - } // Set the sample count _devInst->set_config(NULL, NULL, SR_CONF_LIMIT_SAMPLES, g_variant_new_uint64(sample_count)); - - - if (buffer2stream) { - pv::dialogs::StreamOptions stream(this, _devInst, sample_count, stream_mode); - stream.setFixedSize(300, 150); - stream.exec(); - update_sample_rate_selector_value(); - update_sample_count_selector_value(); - _devInst->set_config(NULL, NULL, - SR_CONF_STREAM, - g_variant_new_boolean(true)); - } else if (stream2buffer) { - QMessageBox msg(this); - pv::dialogs::StreamOptions stream(this, _devInst, sample_count, stream_mode); - stream.setFixedSize(300, 100); - stream.exec(); - _devInst->set_config(NULL, NULL, - SR_CONF_STREAM, - g_variant_new_boolean(false)); - } - - device_updated(); + sample_count_changed(); update_scale(); } } @@ -551,25 +518,23 @@ void SamplingBar::on_samplecount_sel(int index) void SamplingBar::on_samplerate_sel(int index) { uint64_t sample_rate = 0; - //uint64_t last_sample_rate = 0; if (index >= 0) sample_rate = _sample_rate.itemData( index).value(); - const sr_dev_inst* _sdi = get_selected_device()->dev_inst(); - assert(_sdi); + boost::shared_ptr _devInst = get_selected_device(); + assert(_devInst); // Get last samplerate //last_sample_rate = get_selected_device()->get_sample_rate(); - if (strcmp(_sdi->driver->name, "DSLogic") == 0 && _sdi->mode != DSO) { + if (strcmp(_devInst->dev_inst()->driver->name, "DSLogic") == 0 && _devInst->dev_inst()->mode != DSO) { // Set the samplerate get_selected_device()->set_config(NULL, NULL, SR_CONF_SAMPLERATE, g_variant_new_uint64(sample_rate)); - update_sample_count_selector_value(); - device_updated(); + update_scale(); } } @@ -579,6 +544,8 @@ void SamplingBar::update_sample_count_selector() GVariant *gvar_dict, *gvar_list; const uint64_t *elements = NULL; gsize num_elements; + bool stream_mode = false; + uint64_t max_sample_count = 0; if (_updating_sample_count) return; @@ -601,6 +568,17 @@ void SamplingBar::update_sample_count_selector() return; } + GVariant* gvar = dev_inst->get_config(NULL, NULL, SR_CONF_STREAM); + if (gvar != NULL) { + stream_mode = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + } + gvar = dev_inst->get_config(NULL, NULL, SR_CONF_RLE_SAMPLELIMITS); + if (gvar != NULL) { + max_sample_count = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + } + if ((gvar_list = g_variant_lookup_value(gvar_dict, "samplecounts", G_VARIANT_TYPE("at")))) { @@ -611,8 +589,12 @@ void SamplingBar::update_sample_count_selector() for (unsigned int i = 0; i < num_elements; i++) { char *const s = sr_samplecount_string(elements[i]); - _sample_count.addItem(QString(s), - qVariantFromValue(elements[i])); + if (!stream_mode && (elements[i] > max_sample_count)) + _sample_count.addItem(QString(s)+"(RLE)", + qVariantFromValue(elements[i])); + else + _sample_count.addItem(QString(s), + qVariantFromValue(elements[i])); g_free(s); } @@ -623,9 +605,9 @@ void SamplingBar::update_sample_count_selector() _updating_sample_count = false; g_variant_unref(gvar_dict); + update_sample_count_selector_value(); connect(&_sample_count, SIGNAL(currentIndexChanged(int)), this, SLOT(on_samplecount_sel(int))); - update_sample_count_selector_value(); } void SamplingBar::update_sample_count_selector_value() @@ -644,6 +626,8 @@ void SamplingBar::update_sample_count_selector_value() _sample_count.setCurrentIndex(i); _updating_sample_count = false; + sample_count_changed(); + update_scale(); } void SamplingBar::commit_sample_count() diff --git a/DSView/pv/toolbars/samplingbar.h b/DSView/pv/toolbars/samplingbar.h index 1414ceca..4055a1af 100644 --- a/DSView/pv/toolbars/samplingbar.h +++ b/DSView/pv/toolbars/samplingbar.h @@ -96,6 +96,7 @@ signals: void device_selected(); void device_updated(); void update_scale(); + void sample_count_changed(); private: void update_sample_rate_selector(); diff --git a/DSView/pv/view/analogsignal.cpp b/DSView/pv/view/analogsignal.cpp index ceeca037..dbef9c00 100644 --- a/DSView/pv/view/analogsignal.cpp +++ b/DSView/pv/view/analogsignal.cpp @@ -137,8 +137,7 @@ void AnalogSignal::paint_trace(QPainter &p, //p.setPen(QPen(_colour, 2, Qt::SolidLine)); QPointF *points = new QPointF[sample_count]; - QPointF *point = points; - + QPointF *point = points; for (int64_t sample = start; sample != end; sample++) { const float x = (sample / samples_per_pixel - pixels_offset) + left; @@ -147,7 +146,6 @@ void AnalogSignal::paint_trace(QPainter &p, } p.drawPolyline(points, point - points); - //delete[] samples; delete[] points; } diff --git a/DSView/pv/view/cursor.cpp b/DSView/pv/view/cursor.cpp index d93b1495..baa00faf 100644 --- a/DSView/pv/view/cursor.cpp +++ b/DSView/pv/view/cursor.cpp @@ -151,7 +151,8 @@ void Cursor::paint_fix_label(QPainter &p, const QRect &rect, void Cursor::compute_text_size(QPainter &p, unsigned int prefix) { - _text_size = p.boundingRect(QRectF(), 0, + (void)prefix; + _text_size = p.boundingRect(QRectF(), 0, Ruler::format_real_time(_index, _view.session().get_device()->get_sample_rate())).size(); } diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp index 22cfa930..d08627ea 100644 --- a/DSView/pv/view/decodetrace.cpp +++ b/DSView/pv/view/decodetrace.cpp @@ -136,6 +136,18 @@ DecodeTrace::DecodeTrace(pv::SigSession &session, this, SLOT(on_show_hide_decoder(int))); } +DecodeTrace::~DecodeTrace() +{ + if (_popup_form) + delete _popup_form; + if (_popup) + delete _popup; + _cur_row_headings.clear(); + _decoder_forms.clear(); + _probe_selectors.clear(); + _bindings.clear(); +} + bool DecodeTrace::enabled() const { return true; @@ -698,8 +710,10 @@ QComboBox* DecodeTrace::create_probe_selector( { selector->addItem(s->get_name(), qVariantFromValue((void*)s.get())); - if ((*probe_iter).second == s) - selector->setCurrentIndex(i + 1); + if (probe_iter != dec->channels().end()) { + if ((*probe_iter).second->get_index() == s->get_index()) + selector->setCurrentIndex(i + 1); + } } } @@ -809,13 +823,12 @@ int DecodeTrace::rows_size() return _decoder_stack->cur_rows_size(); } -void DecodeTrace::paint_type_options(QPainter &p, int right, bool hover, int action) +void DecodeTrace::paint_type_options(QPainter &p, int right, const QPoint pt) { - (void)hover; - (void)action; + (void)pt; int y = get_y(); - const QRectF group_index_rect = get_rect("groupIndex", y, right); + const QRectF group_index_rect = get_rect(CHNLREG, y, right); QString index_string; int last_index; p.setPen(Qt::transparent); @@ -837,5 +850,18 @@ void DecodeTrace::paint_type_options(QPainter &p, int right, bool hover, int act p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string); } +QRectF DecodeTrace::get_rect(DecodeSetRegions type, int y, int right) +{ + const QSizeF name_size(right - get_leftWidth() - get_rightWidth(), SquareWidth); + + if (type == CHNLREG) + return QRectF( + get_leftWidth() + name_size.width() + Margin, + y - SquareWidth / 2, + SquareWidth * SquareNum, SquareWidth); + else + return QRectF(0, 0, 0, 0); +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/decodetrace.h b/DSView/pv/view/decodetrace.h index a7532dd0..03cd6910 100644 --- a/DSView/pv/view/decodetrace.h +++ b/DSView/pv/view/decodetrace.h @@ -71,6 +71,11 @@ private: const srd_channel *_pdch; }; + enum DecodeSetRegions{ + NONEREG = -1, + CHNLREG, + }; + private: static const QColor DecodeColours[4]; static const QColor ErrorBgColour; @@ -89,6 +94,7 @@ public: DecodeTrace(pv::SigSession &session, boost::shared_ptr decoder_stack, int index); + ~DecodeTrace(); bool enabled() const; @@ -124,8 +130,10 @@ public: int rows_size(); + QRectF get_rect(DecodeSetRegions type, int y, int right); + protected: - void paint_type_options(QPainter &p, int right, bool hover, int action); + void paint_type_options(QPainter &p, int right, const QPoint pt); private: void create_popup_form(); diff --git a/DSView/pv/view/devmode.cpp b/DSView/pv/view/devmode.cpp index 295f8b0d..f48c453c 100644 --- a/DSView/pv/view/devmode.cpp +++ b/DSView/pv/view/devmode.cpp @@ -122,10 +122,10 @@ void DevMode::on_mode_change() i != _mode_button_list.end(); i++) { if ((*i).first.get() == button) { if (dev_inst->dev_inst()->mode != (*i).second->mode) { + _view.session().stop_capture(); dev_inst->set_config(NULL, NULL, SR_CONF_DEVICE_MODE, g_variant_new_int16((*i).second->mode)); - mode_changed(); } } diff --git a/DSView/pv/view/dsldial.cpp b/DSView/pv/view/dsldial.cpp index f19c7561..454dc620 100644 --- a/DSView/pv/view/dsldial.cpp +++ b/DSView/pv/view/dsldial.cpp @@ -25,7 +25,7 @@ dslDial::~dslDial() { } -void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor) +void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor, bool hover, bool inc) { p.setRenderHint(QPainter::Antialiasing, true); p.setPen(dialColor); @@ -64,8 +64,22 @@ void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor) } QString pText = QString::number(displayValue) + _unit[displayIndex] + "/div"; QFontMetrics fm(p.font()); - p.drawText(QRectF(dialRect.left(), dialRect.bottom()-dialRect.width()*0.3+fm.height()*0.5, dialRect.width(), fm.height()), Qt::AlignCenter, pText); + const QRectF valueRect = QRectF(dialRect.left(), dialRect.bottom()-dialRect.width()*0.3+fm.height()*0.5, dialRect.width(), fm.height()); + p.drawText(valueRect, Qt::AlignCenter, pText); + // draw +/- + if (hover) { + const int arcInc = 15; + const QRectF hoverRect = QRectF(dialRect.left()-arcInc, dialRect.top()-arcInc, dialRect.width()+arcInc*2, dialRect.height()+arcInc*2); + const double arcSpan = hoverRect.width()/(2*sqrt(2)); + p.drawArc(hoverRect, 135 * 16, -90 * 16); + if (inc) + p.drawLine(hoverRect.center().x()+arcSpan, hoverRect.center().y()-arcSpan, + hoverRect.center().x()+arcSpan-4, hoverRect.center().y()-arcSpan-10); + else + p.drawLine(hoverRect.center().x()-arcSpan, hoverRect.center().y()-arcSpan, + hoverRect.center().x()-arcSpan+4, hoverRect.center().y()-arcSpan-10); + } } void dslDial::set_sel(uint64_t sel) diff --git a/DSView/pv/view/dsldial.h b/DSView/pv/view/dsldial.h index 35701959..ddb7ea61 100644 --- a/DSView/pv/view/dsldial.h +++ b/DSView/pv/view/dsldial.h @@ -20,7 +20,7 @@ public: * @param p the QPainter to paint into. * @param dialRect the rectangle to draw the dial at. **/ - void paint(QPainter &p, QRectF dialRect, QColor dialColor); + void paint(QPainter &p, QRectF dialRect, QColor dialColor, bool hover, bool inc); // set/get current select void set_sel(uint64_t sel); diff --git a/DSView/pv/view/dsosignal.cpp b/DSView/pv/view/dsosignal.cpp index 995bb4d4..de5e0bbf 100644 --- a/DSView/pv/view/dsosignal.cpp +++ b/DSView/pv/view/dsosignal.cpp @@ -95,10 +95,10 @@ const QString DsoSignal::hDialUnit[DsoSignal::hDialUnitCount] = { }; const QColor DsoSignal::SignalColours[4] = { - QColor(238, 178, 17, 200), // dsYellow - QColor(0, 153, 37, 200), // dsGreen - QColor(213, 15, 37, 200), // dsRed - QColor(17, 133, 209, 200) // dsBlue + QColor(238, 178, 17, 255), // dsYellow + QColor(0, 153, 37, 255), // dsGreen + QColor(213, 15, 37, 255), // dsRed + QColor(17, 133, 209, 255) // dsBlue }; @@ -120,14 +120,15 @@ DsoSignal::DsoSignal(boost::shared_ptr dev_inst, //_trig_vpos(probe->index * 0.5 + 0.25), //_zeroPos(probe->index * 0.5 + 0.25) _trig_vpos(0.5), - _zeroPos(0.5), - _zero_off(255/2.0), _autoV(false), _autoH(false), _hover_en(false), _hover_index(0), _hover_point(QPointF(0, 0)), - _hover_value(0) + _hover_value(0), + _ms_gear_hover(false), + _ms_show_hover(false), + _ms_show(false) { QVector vValue; QVector vUnit; @@ -148,34 +149,13 @@ DsoSignal::DsoSignal(boost::shared_ptr dev_inst, _colour = SignalColours[probe->index % countof(SignalColours)]; -// GVariant* gvar; + for (int i = DSO_MS_BEGIN; i < DSO_MS_END; i++) + _ms_en[i] = false; + _ms_en[DSO_MS_FREQ] = true; + _ms_en[DSO_MS_VMAX] = true; + _ms_en[DSO_MS_VMIN] = true; -// gvar = dev_inst->get_config(probe, NULL, SR_CONF_VDIV); -// if (gvar != NULL) { -// _vDial->set_value(g_variant_get_uint64(gvar)); -// g_variant_unref(gvar); -// } else { -// qDebug() << "ERROR: config_get SR_CONF_VDIV failed."; -// } - -// gvar = dev_inst->get_config(NULL, NULL, SR_CONF_TIMEBASE); -// if (gvar != NULL) { -// _hDial->set_value(g_variant_get_uint64(gvar)); -// g_variant_unref(gvar); -// } else { -// qDebug() << "ERROR: config_get SR_CONF_TIMEBASE failed."; -// } - -// gvar = dev_inst->get_config(probe, NULL, SR_CONF_COUPLING); -// if (gvar != NULL) { -// _acCoupling = g_variant_get_byte(gvar); -// g_variant_unref(gvar); -// } else { -// qDebug() << "ERROR: config_get SR_CONF_COUPLING failed."; -// } - update_vDial(); - update_hDial(); - update_acCoupling(); + load_settings(); } DsoSignal::~DsoSignal() @@ -191,6 +171,14 @@ void DsoSignal::set_view(pv::view::View *view) { Trace::set_view(view); update_zeroPos(); + + const double ms_left = get_view_rect().right() - (MS_RectWidth + MS_RectMargin) * (get_index() + 1); + const double ms_top = get_view_rect().top() + 5; + for (int i = DSO_MS_BEGIN; i < DSO_MS_END; i++) + _ms_rect[i] = QRect(ms_left, ms_top + MS_RectHeight * i, MS_RectWidth, MS_RectHeight); + _ms_gear_rect = QRect(ms_left+MS_RectRad, ms_top+MS_RectRad, MS_IconSize, MS_IconSize); + _ms_show_rect = QRect(ms_left+MS_RectWidth-MS_RectRad-MS_IconSize, ms_top+MS_RectRad, MS_IconSize, MS_IconSize); + } void DsoSignal::set_scale(float scale) @@ -421,10 +409,10 @@ bool DsoSignal::go_hDialNext(bool setted) return true; } if (!setted) { - const double scale = _hDial->get_value() * std::pow(10.0, -9.0) * DS_CONF_DSO_HDIVS / get_view_rect().width(); - _view->set_scale_offset(scale, _view->offset()); - _dev_inst->set_config(_probe, NULL, SR_CONF_TIMEBASE, - g_variant_new_uint64(_hDial->get_value())); + const double scale = _hDial->get_value() * std::pow(10.0, -9.0) * DS_CONF_DSO_HDIVS / get_view_rect().width(); + _view->set_scale_offset(scale, _view->offset()); + _dev_inst->set_config(_probe, NULL, SR_CONF_TIMEBASE, + g_variant_new_uint64(_hDial->get_value())); } return true; } else { @@ -433,34 +421,24 @@ bool DsoSignal::go_hDialNext(bool setted) } } -bool DsoSignal::update_vDial() +bool DsoSignal::load_settings() { - uint64_t vdiv; - //uint64_t pre_vdiv = _vDial->get_value(); - GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_VDIV); - if (gvar != NULL) { - vdiv = g_variant_get_uint64(gvar); - g_variant_unref(gvar); - } else { - qDebug() << "ERROR: config_get SR_CONF_TIMEBASE failed."; - return false; - } + GVariant* gvar; - _vDial->set_value(vdiv); - _dev_inst->set_config(_probe, NULL, SR_CONF_VDIV, - g_variant_new_uint64(_vDial->get_value())); - if (_view) { - update_zeroPos(); - _view->set_need_update(true); - _view->update(); - } - return true; -} + // -- enable + //bool enable; + //gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_EN_CH); + //if (gvar != NULL) { + // enable = g_variant_get_boolean(gvar); + // g_variant_unref(gvar); + //} else { + // qDebug() << "ERROR: config_get SR_CONF_EN_CH failed."; + // return false; + //} -bool DsoSignal::update_hDial() -{ + // -- hdiv uint64_t hdiv; - GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_TIMEBASE); + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_TIMEBASE); if (gvar != NULL) { hdiv = g_variant_get_uint64(gvar); g_variant_unref(gvar); @@ -475,6 +453,60 @@ bool DsoSignal::update_hDial() if (_view) { const double scale = _hDial->get_value() * std::pow(10.0, -9.0) * DS_CONF_DSO_HDIVS / get_view_rect().width(); _view->set_scale_offset(scale, _view->offset()); + } + + // -- vdiv + uint64_t vdiv; + uint64_t vfactor; + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_VDIV); + if (gvar != NULL) { + vdiv = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + } else { + qDebug() << "ERROR: config_get SR_CONF_TIMEBASE failed."; + return false; + } + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_FACTOR); + if (gvar != NULL) { + vfactor = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + } else { + qDebug() << "ERROR: config_get SR_CONF_TIMEBASE failed."; + return false; + } + + _vDial->set_value(vdiv); + _vDial->set_factor(vfactor); + _dev_inst->set_config(_probe, NULL, SR_CONF_VDIV, + g_variant_new_uint64(_vDial->get_value())); + + // -- coupling + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_COUPLING); + if (gvar != NULL) { + _acCoupling = g_variant_get_byte(gvar); + g_variant_unref(gvar); + } else { + qDebug() << "ERROR: config_get SR_CONF_COUPLING failed."; + return false; + } + + _dev_inst->set_config(_probe, NULL, SR_CONF_COUPLING, + g_variant_new_byte(_acCoupling)); + + // -- vpos + double vpos; + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_VPOS); + if (gvar != NULL) { + vpos = g_variant_get_double(gvar); + g_variant_unref(gvar); + } else { + qDebug() << "ERROR: config_get SR_CONF_COUPLING failed."; + return false; + } + _zeroPos = min(max((0.5 - vpos / (_vDial->get_value() * DS_CONF_DSO_VDIVS)), 0.0), 1.0); + _zero_off = _zeroPos * 255; + + if (_view) { _view->set_need_update(true); _view->update(); } @@ -515,22 +547,6 @@ void DsoSignal::set_acCoupling(uint8_t coupling) } } -bool DsoSignal::update_acCoupling() -{ - GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_COUPLING); - if (gvar != NULL) { - _acCoupling = g_variant_get_byte(gvar); - g_variant_unref(gvar); - } else { - qDebug() << "ERROR: config_get SR_CONF_COUPLING failed."; - return false; - } - - _dev_inst->set_config(_probe, NULL, SR_CONF_COUPLING, - g_variant_new_byte(_acCoupling)); - return true; -} - int DsoSignal::get_trig_vpos() const { return _trig_vpos * get_view_rect().height() + UpMargin; @@ -607,6 +623,7 @@ void DsoSignal::set_zeroPos(int pos) void DsoSignal::set_zeroRate(double rate) { _zeroPos = rate; + _zero_off = rate * 255; update_zeroPos(); } @@ -648,6 +665,60 @@ uint64_t DsoSignal::get_factor() } } +void DsoSignal::set_ms_show(bool show) +{ + _ms_show = show; + _view->set_need_update(true); +} + +bool DsoSignal::get_ms_show() const +{ + return _ms_show; +} + +bool DsoSignal::get_ms_show_hover() const +{ + return _ms_show_hover; +} + +bool DsoSignal::get_ms_gear_hover() const +{ + return _ms_gear_hover; +} + +void DsoSignal::set_ms_en(int index, bool en) +{ + assert(index > DSO_MS_BEGIN); + assert(index < DSO_MS_END); + + _ms_en[index] = en; +} + +bool DsoSignal::get_ms_en(int index) const +{ + assert(index > DSO_MS_BEGIN); + assert(index < DSO_MS_END); + + return _ms_en[index]; +} + +QString DsoSignal::get_ms_string(int index) const +{ + assert(index > DSO_MS_BEGIN); + assert(index < DSO_MS_END); + + switch(index) { + case DSO_MS_FREQ: return "Frequency"; + case DSO_MS_PERD: return "Period"; + case DSO_MS_VMAX: return "Vmax"; + case DSO_MS_VMIN: return "Vmin"; + case DSO_MS_VRMS: return "Vrms"; + case DSO_MS_VMEA: return "Vmean"; + case DSO_MS_VP2P: return "Vp-p"; + default: return "Error: Out of Bound"; + } +} + void DsoSignal::update_zeroPos() { if (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0) { @@ -742,6 +813,8 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right) assert(scale > 0); const double offset = _view->offset(); + paint_measure(p); + const deque< boost::shared_ptr > &snapshots = _data->get_snapshots(); if (snapshots.empty()) @@ -779,8 +852,6 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right) start_sample, end_sample, pixels_offset, samples_per_pixel, number_channels); } - - paint_measure(p); } } @@ -856,7 +927,6 @@ void DsoSignal::paint_trace(QPainter &p, QColor trace_colour = _colour; trace_colour.setAlpha(150); p.setPen(trace_colour); - //p.setPen(QPen(_colour, 3, Qt::SolidLine)); QPointF *points = new QPointF[sample_count]; QPointF *point = points; @@ -884,6 +954,8 @@ void DsoSignal::paint_trace(QPainter &p, } p.drawPolyline(points, point - points); + p.eraseRect(get_view_rect().right(), get_view_rect().top(), + _view->viewport()->width() - get_view_rect().width(), get_view_rect().height()); //delete[] samples; delete[] points; @@ -952,30 +1024,31 @@ const std::vector< std::pair > DsoSignal::cur_edges() const } -void DsoSignal::paint_type_options(QPainter &p, int right, bool hover, int action) +void DsoSignal::paint_type_options(QPainter &p, int right, const QPoint pt) { int y = get_y(); - const QRectF vDial_rect = get_rect("vDial", y, right); - const QRectF x1_rect = get_rect("x1", y, right); - const QRectF x10_rect = get_rect("x10", y, right); - const QRectF x100_rect = get_rect("x100", y, right); - const QRectF hDial_rect = get_rect("hDial", y, right); - const QRectF acdc_rect = get_rect("acdc", y, right); - const QRectF chEn_rect = get_rect("chEn", y, right); + const QRectF vDial_rect = get_rect(DSO_VDIAL, y, right); + const QRectF vInc_rect = get_rect(DSO_VINC, y, right); + const QRectF hDial_rect = get_rect(DSO_HDIAL, y, right); + const QRectF hInc_rect = get_rect(DSO_HINC, y, right); - QColor vDial_color = _vDialActive ? dsActive : dsDisable; - QColor hDial_color = _hDialActive ? dsActive : dsDisable; - _vDial->paint(p, vDial_rect, vDial_color); - _hDial->paint(p, hDial_rect, hDial_color); + const QRectF x1_rect = get_rect(DSO_X1, y, right); + const QRectF x10_rect = get_rect(DSO_X10, y, right); + const QRectF x100_rect = get_rect(DSO_X100, y, right); + const QRectF acdc_rect = get_rect(DSO_ACDC, y, right); + const QRectF chEn_rect = get_rect(DSO_CHEN, y, right); + + _vDial->paint(p, vDial_rect, _colour, vDial_rect.contains(pt), vInc_rect.contains(pt)); + _hDial->paint(p, hDial_rect, _colour, hDial_rect.contains(pt), hInc_rect.contains(pt)); p.setPen(Qt::transparent); - p.setBrush((hover && action == CHEN) ? _colour.darker() : _colour); + p.setBrush(chEn_rect.contains(pt) ? _colour.darker() : _colour); p.drawRect(chEn_rect); p.setPen(Qt::white); p.drawText(chEn_rect, Qt::AlignCenter | Qt::AlignVCenter, enabled() ? tr("EN") : tr("DIS")); p.setPen(Qt::transparent); - p.setBrush(enabled() ? ((hover && action == ACDC) ? _colour.darker() : _colour) : dsDisable); + p.setBrush(enabled() ? (acdc_rect.contains(pt) ? _colour.darker() : _colour) : dsDisable); p.drawRect(acdc_rect); p.setPen(Qt::white); p.drawText(acdc_rect, Qt::AlignCenter | Qt::AlignVCenter, (_acCoupling == SR_GND_COUPLING) ? tr("GND") : @@ -994,19 +1067,189 @@ void DsoSignal::paint_type_options(QPainter &p, int right, bool hover, int actio } p.setPen(Qt::white); - p.setBrush((enabled() && (factor == 100)) ? ((hover && action == X100) ? _colour.darker() : _colour) : ((hover && action == X100) ? _colour.darker() : dsDisable)); + p.setBrush((enabled() && (factor == 100)) ? (x100_rect.contains(pt) ? _colour.darker() : _colour) : (x100_rect.contains(pt) ? _colour.darker() : dsDisable)); p.drawRect(x100_rect); p.drawText(x100_rect, Qt::AlignCenter | Qt::AlignVCenter, "x100"); - p.setBrush((enabled() && (factor == 10)) ? ((hover && action == X10) ? _colour.darker() : _colour) : ((hover && action == X10) ? _colour.darker() : dsDisable)); + p.setBrush((enabled() && (factor == 10)) ? (x10_rect.contains(pt) ? _colour.darker() : _colour) : (x10_rect.contains(pt) ? _colour.darker() : dsDisable)); p.drawRect(x10_rect); p.drawText(x10_rect, Qt::AlignCenter | Qt::AlignVCenter, "x10"); - p.setBrush((enabled() && (factor == 1)) ? ((hover && action == X1) ? _colour.darker() : _colour) : ((hover && action == X1) ? _colour.darker() : dsDisable)); + p.setBrush((enabled() && (factor == 1)) ? (x1_rect.contains(pt) ? _colour.darker() : _colour) : (x1_rect.contains(pt) ? _colour.darker() : dsDisable)); p.drawRect(x1_rect); p.drawText(x1_rect, Qt::AlignCenter | Qt::AlignVCenter, "x1"); } +bool DsoSignal::mouse_double_click(int right, const QPoint pt) +{ + int y = get_zeroPos(); + const QRectF label_rect = Trace::get_rect("label", y, right); + if (label_rect.contains(pt)) { + this->auto_set(); + return true; + } + return false; +} + +bool DsoSignal::mouse_press(int right, const QPoint pt) +{ + int y = get_y(); + bool setted = false; + const vector< boost::shared_ptr > traces(_view->get_traces()); + const QRectF vDec_rect = get_rect(DSO_VDEC, y, right); + const QRectF vInc_rect = get_rect(DSO_VINC, y, right); + const QRectF hDec_rect = get_rect(DSO_HDEC, y, right); + const QRectF hInc_rect = get_rect(DSO_HINC, y, right); + const QRectF chEn_rect = get_rect(DSO_CHEN, y, right); + const QRectF acdc_rect = get_rect(DSO_ACDC, y, right); + const QRectF x1_rect = get_rect(DSO_X1, y, right); + const QRectF x10_rect = get_rect(DSO_X10, y, right); + const QRectF x100_rect = get_rect(DSO_X100, y, right); + + if (chEn_rect.contains(pt)) { + if (strcmp(_dev_inst->dev_inst()->driver->name, "virtual-session") && + !_view->session().get_data_lock()) + set_enable(!enabled()); + return true; + } else if (enabled()) { + if (vDec_rect.contains(pt)) { + go_vDialPre(); + } else if (vInc_rect.contains(pt)) { + go_vDialNext(); + } else if (hDec_rect.contains(pt)) { + boost::shared_ptr dsoSig; + BOOST_FOREACH(const boost::shared_ptr t, traces) { + if (dsoSig = dynamic_pointer_cast(t)) { + dsoSig->go_hDialPre(setted); + setted = true; + } + } + } else if (hInc_rect.contains(pt)) { + boost::shared_ptr dsoSig; + BOOST_FOREACH(const boost::shared_ptr t, traces) { + if (dsoSig = dynamic_pointer_cast(t)) { + dsoSig->go_hDialNext(setted); + setted = true; + } + } + } else if (strcmp(_dev_inst->dev_inst()->driver->name, "virtual-session") && + acdc_rect.contains(pt)) { + if (strcmp(_view->session().get_device()->dev_inst()->driver->name, "DSLogic") == 0) + set_acCoupling((get_acCoupling()+1)%2); + else + set_acCoupling((get_acCoupling()+1)%3); + } else if (x1_rect.contains(pt)) { + set_factor(1); + } else if (x10_rect.contains(pt)) { + set_factor(10); + } else if (x100_rect.contains(pt)) { + set_factor(100); + } else { + return false; + } + return true; + } + return false; +} + +bool DsoSignal::mouse_wheel(int right, const QPoint pt, const int shift) +{ + int y = get_y(); + const vector< boost::shared_ptr > traces( + _view->get_traces()); + bool setted = false; + const QRectF vDial_rect = get_rect(DSO_VDIAL, y, right); + const QRectF hDial_rect = get_rect(DSO_HDIAL, y, right); + + if (vDial_rect.contains(pt)) { + if (shift > 1.0) + go_vDialNext(); + else if (shift < -1.0) + go_vDialPre(); + return true; + } else if (hDial_rect.contains(pt)) { + boost::shared_ptr dsoSig; + BOOST_FOREACH(const boost::shared_ptr t, traces) { + if (dsoSig = dynamic_pointer_cast(t)) { + if (shift > 1.0) { + dsoSig->go_hDialNext(setted); + setted = true; + } else if (shift < -1.0) { + dsoSig->go_hDialPre(setted); + setted = true; + } + } + } + } else { + return false; + } + + return true; +} + +QRectF DsoSignal::get_rect(DsoSetRegions type, int y, int right) +{ + const QSizeF name_size(right - get_leftWidth() - get_rightWidth(), SquareWidth); + + if (type == DSO_VDIAL) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin, + y - SquareWidth * SquareNum, + SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1)); + else if (type == DSO_VDEC) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin, + y - SquareWidth * SquareNum, + SquareWidth * (SquareNum-1) / 2, SquareWidth * (SquareNum-1)); + else if (type == DSO_VINC) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin + SquareWidth * (SquareNum-1) / 2, + y - SquareWidth * SquareNum, + SquareWidth * (SquareNum-1) / 2, SquareWidth * (SquareNum-1)); + else if (type == DSO_HDIAL) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin, + y + SquareWidth * 1.5, + SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1)); + else if (type == DSO_HDEC) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin, + y + SquareWidth * 1.5, + SquareWidth * (SquareNum-1) / 2, SquareWidth * (SquareNum-1)); + else if (type == DSO_HINC) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin + SquareWidth * (SquareNum-1) / 2, + y + SquareWidth * 1.5, + SquareWidth * (SquareNum-1) / 2, SquareWidth * (SquareNum-1)); + else if (type == DSO_X1) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45, + y - SquareWidth - SquareWidth * (SquareNum-1) * 0.85, + SquareWidth * 1.75, SquareWidth); + else if (type == DSO_X10) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45, + y - SquareWidth - SquareWidth * (SquareNum-1) * 0.55, + SquareWidth * 1.75, SquareWidth); + else if (type == DSO_X100) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45, + y - SquareWidth - SquareWidth * (SquareNum-1) * 0.25, + SquareWidth * 1.75, SquareWidth); + else if (type == DSO_CHEN) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth*0.75 + Margin, + y - SquareWidth / 2, + SquareWidth * 1.5, SquareWidth); + else if (type == DSO_ACDC) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth*2.75 + Margin, + y - SquareWidth / 2, + SquareWidth * 1.5, SquareWidth); + else + return QRectF(0, 0, 0, 0); +} + void DsoSignal::paint_measure(QPainter &p) { sr_status status; @@ -1020,58 +1263,125 @@ void DsoSignal::paint_measure(QPainter &p) const uint32_t count = (index == 0) ? status.ch0_pcnt : status.ch1_pcnt; double value_max = (_zero_off - _min) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); double value_min = (_zero_off - _max) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); + double value_p2p = value_max - value_min; _period = (count == 0) ? period * 10.0 : period * 10.0 / count; const int channel_count = _view->session().get_ch_num(SR_CHANNEL_DSO); uint64_t sample_rate = _dev_inst->get_sample_rate(); _period = _period * 200.0 / (channel_count * sample_rate * 1.0 / SR_MHZ(1)); - QString max_string = abs(value_max) > 1000 ? QString::number(value_max/1000.0, 'f', 2) + "V" : QString::number(value_max, 'f', 2) + "mV"; - QString min_string = abs(value_min) > 1000 ? QString::number(value_min/1000.0, 'f', 2) + "V" : QString::number(value_min, 'f', 2) + "mV"; - QString period_string = abs(_period) > 1000000000 ? QString::number(_period/1000000000, 'f', 2) + "S" : + _ms_string[DSO_MS_VMAX] = "Vmax: " + (abs(value_max) > 1000 ? QString::number(value_max/1000.0, 'f', 2) + "V" : QString::number(value_max, 'f', 2) + "mV"); + _ms_string[DSO_MS_VMIN] = "Vmin: " + (abs(value_min) > 1000 ? QString::number(value_min/1000.0, 'f', 2) + "V" : QString::number(value_min, 'f', 2) + "mV"); + _ms_string[DSO_MS_PERD] = "Perd: " + (abs(_period) > 1000000000 ? QString::number(_period/1000000000, 'f', 2) + "S" : abs(_period) > 1000000 ? QString::number(_period/1000000, 'f', 2) + "mS" : - abs(_period) > 1000 ? QString::number(_period/1000, 'f', 2) + "uS" : QString::number(_period, 'f', 2) + "nS"; - QString freq_string = abs(_period) > 1000000 ? QString::number(1000000000/_period, 'f', 2) + "Hz" : - abs(_period) > 1000 ? QString::number(1000000/_period, 'f', 2) + "kHz" : QString::number(1000/_period, 'f', 2) + "MHz"; - QColor measure_colour = _colour; - measure_colour.setAlpha(180); - p.setPen(measure_colour); - p.drawText(QRectF(0, 100*index + UpMargin, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, tr("Max: ")+max_string+" "); - p.drawText(QRectF(0, 100*index + UpMargin + 20, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, tr("Min: ")+min_string+" "); - p.drawText(QRectF(0, 100*index + UpMargin + 40, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, tr("Period: ")+period_string+" "); - p.drawText(QRectF(0, 100*index + UpMargin + 60, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, tr("Frequency: ")+freq_string+" "); + abs(_period) > 1000 ? QString::number(_period/1000, 'f', 2) + "uS" : QString::number(_period, 'f', 2) + "nS"); + _ms_string[DSO_MS_FREQ] = "Freq: " + (abs(_period) > 1000000 ? QString::number(1000000000/_period, 'f', 2) + "Hz" : + abs(_period) > 1000 ? QString::number(1000000/_period, 'f', 2) + "kHz" : QString::number(1000/_period, 'f', 2) + "MHz"); + _ms_string[DSO_MS_VP2P] = "Vp-p: " + (abs(value_p2p) > 1000 ? QString::number(value_p2p/1000.0, 'f', 2) + "V" : QString::number(value_p2p, 'f', 2) + "mV"); - if (_autoV) { - const uint8_t vscale = abs(_max - _min); - if (_max == 0xff || _min == 0x00 || vscale > 0xCC) { - go_vDialNext(); - } else if (vscale > 0x33) { - _autoV = false; - } else { - go_vDialPre(); + if (_ms_show && _ms_en[DSO_MS_VRMS]) { + const deque< boost::shared_ptr > &snapshots = + _data->get_snapshots(); + if (!snapshots.empty()) { + const boost::shared_ptr &snapshot = + snapshots.front(); + const double vrms = snapshot->cal_vrms(_zero_off, get_index()); + const double value_vrms = vrms * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); + _ms_string[DSO_MS_VRMS] = "Vrms: " + (abs(value_vrms) > 1000 ? QString::number(value_vrms/1000.0, 'f', 2) + "V" : QString::number(value_vrms, 'f', 2) + "mV"); } } - bool setted = false; - if (_autoH) { - const vector< boost::shared_ptr > traces(_view->get_traces()); - const double upPeriod = get_hDialValue() * DS_CONF_DSO_HDIVS * 0.8; - const double dnPeriod = get_hDialValue() * DS_CONF_DSO_HDIVS * 0.2; - if (_period > upPeriod) { - boost::shared_ptr dsoSig; - BOOST_FOREACH(const boost::shared_ptr t, traces) { - if (dsoSig = dynamic_pointer_cast(t)) { - dsoSig->go_hDialNext(setted); - setted = true; - } + if (_ms_show && _ms_en[DSO_MS_VMEA]) { + const deque< boost::shared_ptr > &snapshots = + _data->get_snapshots(); + if (!snapshots.empty()) { + const boost::shared_ptr &snapshot = + snapshots.front(); + const double vmean = snapshot->cal_vmean(get_index()); + const double value_vmean = (_zero_off - vmean) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); + _ms_string[DSO_MS_VMEA] = "Vmean: " + (abs(value_vmean) > 1000 ? QString::number(value_vmean/1000.0, 'f', 2) + "V" : QString::number(value_vmean, 'f', 2) + "mV"); + } + } + } else { + _ms_string[DSO_MS_VMAX] = "Vmax: #####"; + _ms_string[DSO_MS_VMIN] = "Vmin: #####"; + _ms_string[DSO_MS_PERD] = "Perd: #####"; + _ms_string[DSO_MS_FREQ] = "Freq: #####"; + _ms_string[DSO_MS_VP2P] = "Vp-p: #####"; + _ms_string[DSO_MS_VRMS] = "Vrms: #####"; + _ms_string[DSO_MS_VMEA] = "Vmean: #####"; + } + + QColor measure_colour = _colour; + measure_colour.setAlpha(180); + QColor back_colour = Qt::white; + back_colour.setAlpha(100); + + bool antialiasing = p.Antialiasing; + p.setRenderHint(QPainter::Antialiasing, true); + + p.setPen(Qt::NoPen); + p.setBrush(measure_colour); + p.drawRoundedRect(_ms_rect[DSO_MS_BEGIN], MS_RectRad, MS_RectRad); + const QPixmap gear_pix(":/icons/settings.png"); + const QPixmap show_pix(_ms_show ? ":/icons/shown.png" : ":/icons/hidden.png"); + if (_ms_gear_hover) { + p.setBrush(back_colour); + p.drawRoundedRect(_ms_gear_rect, MS_RectRad, MS_RectRad); + } else if (_ms_show_hover) { + p.setBrush(back_colour); + p.drawRoundedRect(_ms_show_rect, MS_RectRad, MS_RectRad); + } + p.drawPixmap(_ms_gear_rect, gear_pix); + p.drawPixmap(_ms_show_rect, show_pix); + p.setPen(Qt::white); + p.drawText(_ms_rect[DSO_MS_BEGIN], Qt::AlignCenter | Qt::AlignVCenter, "CH"+QString::number(index)); + + if (_ms_show) { + p.setBrush(back_colour); + int j = DSO_MS_BEGIN+1; + for (int i=DSO_MS_BEGIN+1; i 0xCC) { + go_vDialNext(); + } else if (vscale > 0x33) { + _autoV = false; + } else { + go_vDialPre(); + } + } + + bool setted = false; + if (_autoH) { + const vector< boost::shared_ptr > traces(_view->get_traces()); + const double upPeriod = get_hDialValue() * DS_CONF_DSO_HDIVS * 0.8; + const double dnPeriod = get_hDialValue() * DS_CONF_DSO_HDIVS * 0.2; + if (_period > upPeriod) { + boost::shared_ptr dsoSig; + BOOST_FOREACH(const boost::shared_ptr t, traces) { + if (dsoSig = dynamic_pointer_cast(t)) { + dsoSig->go_hDialNext(setted); + setted = true; } - } else if (_period > dnPeriod) { - _autoH = false; - } else { - boost::shared_ptr dsoSig; - BOOST_FOREACH(const boost::shared_ptr t, traces) { - if (dsoSig = dynamic_pointer_cast(t)) { - dsoSig->go_hDialPre(setted); - setted = true; - } + } + } else if (_period > dnPeriod) { + _autoH = false; + } else { + boost::shared_ptr dsoSig; + BOOST_FOREACH(const boost::shared_ptr t, traces) { + if (dsoSig = dynamic_pointer_cast(t)) { + dsoSig->go_hDialPre(setted); + setted = true; } } } @@ -1092,10 +1402,31 @@ void DsoSignal::auto_set() bool DsoSignal::measure(const QPointF &p) { + if (_ms_gear_rect.contains(QPoint(p.x(), p.y()))) { + _ms_gear_hover = true; + _view->set_need_update(true); + return false; + } else if (_ms_gear_hover) { + _view->set_need_update(true); + _ms_gear_hover = false; + } + if (_ms_show_rect.contains(QPoint(p.x(), p.y()))) { + _ms_show_hover = true; + _view->set_need_update(true); + return false; + } else if (_ms_show_hover){ + _view->set_need_update(true); + _ms_show_hover = false; + } + _hover_en = false; if (!enabled()) return false; + const QRectF window = get_view_rect(); + if (!window.contains(p)) + return false; + const deque< boost::shared_ptr > &snapshots = _data->get_snapshots(); if (snapshots.empty()) diff --git a/DSView/pv/view/dsosignal.h b/DSView/pv/view/dsosignal.h index ec7b672a..a2669d8a 100644 --- a/DSView/pv/view/dsosignal.h +++ b/DSView/pv/view/dsosignal.h @@ -62,6 +62,41 @@ private: static const int DownMargin; static const int RightMargin; +public: + enum DSO_MEASURE_TYPE { + DSO_MS_BEGIN = 0, + DSO_MS_FREQ, + DSO_MS_PERD, + DSO_MS_VMAX, + DSO_MS_VMIN, + DSO_MS_VRMS, + DSO_MS_VMEA, + DSO_MS_VP2P, + DSO_MS_END, + }; + + enum DsoSetRegions { + DSO_NONE = -1, + DSO_VDIAL, + DSO_HDIAL, + DSO_VDEC, + DSO_VINC, + DSO_HDEC, + DSO_HINC, + DSO_CHEN, + DSO_ACDC, + DSO_X1, + DSO_X10, + DSO_X100, + }; + +private: + static const uint16_t MS_RectRad = 5; + static const uint16_t MS_IconSize = 16; + static const uint16_t MS_RectWidth = 120; + static const uint16_t MS_RectMargin = 10; + static const uint16_t MS_RectHeight = 25; + public: DsoSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, @@ -101,9 +136,7 @@ public: void set_factor(uint64_t factor); uint64_t get_factor(); - bool update_vDial(); - bool update_hDial(); - bool update_acCoupling(); + bool load_settings(); /** * @@ -158,8 +191,24 @@ public: QRectF get_trig_rect(int left, int right) const; + void set_ms_show(bool show); + bool get_ms_show() const; + bool get_ms_show_hover() const; + bool get_ms_gear_hover() const; + void set_ms_en(int index, bool en); + bool get_ms_en(int index) const; + QString get_ms_string(int index) const; + + QRectF get_rect(DsoSetRegions type, int y, int right); + + bool mouse_double_click(int right, const QPoint pt); + + bool mouse_press(int right, const QPoint pt); + + bool mouse_wheel(int right, const QPoint pt, const int shift); + protected: - void paint_type_options(QPainter &p, int right, bool hover, int action); + void paint_type_options(QPainter &p, int right, const QPoint pt); private: void paint_trace(QPainter &p, @@ -200,6 +249,15 @@ private: uint64_t _hover_index; QPointF _hover_point; double _hover_value; + + QRect _ms_gear_rect; + QRect _ms_show_rect; + QRect _ms_rect[DSO_MS_END-DSO_MS_BEGIN]; + bool _ms_gear_hover; + bool _ms_show_hover; + bool _ms_show; + bool _ms_en[DSO_MS_END-DSO_MS_BEGIN]; + QString _ms_string[DSO_MS_END-DSO_MS_BEGIN]; }; } // namespace view diff --git a/DSView/pv/view/groupsignal.cpp b/DSView/pv/view/groupsignal.cpp index 1c6ac1d8..d5402acb 100644 --- a/DSView/pv/view/groupsignal.cpp +++ b/DSView/pv/view/groupsignal.cpp @@ -196,13 +196,12 @@ const std::vector< std::pair > GroupSignal::cur_edges() const } -void GroupSignal::paint_type_options(QPainter &p, int right, bool hover, int action) +void GroupSignal::paint_type_options(QPainter &p, int right, const QPoint pt) { - (void)hover; - (void)action; + (void)pt; int y = get_y(); - const QRectF group_index_rect = get_rect("groupIndex", y, right); + const QRectF group_index_rect = get_rect(CHNLREG, y, right); QString index_string; int last_index; p.setPen(Qt::transparent); @@ -224,5 +223,18 @@ void GroupSignal::paint_type_options(QPainter &p, int right, bool hover, int act p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string); } +QRectF GroupSignal::get_rect(GroupSetRegions type, int y, int right) +{ + const QSizeF name_size(right - get_leftWidth() - get_rightWidth(), SquareWidth); + + if (type == CHNLREG) + return QRectF( + get_leftWidth() + name_size.width() + Margin, + y - SquareWidth / 2, + SquareWidth * SquareNum, SquareWidth); + else + return QRectF(0, 0, 0, 0); +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/groupsignal.h b/DSView/pv/view/groupsignal.h index b4fe21f1..0aa18282 100644 --- a/DSView/pv/view/groupsignal.h +++ b/DSView/pv/view/groupsignal.h @@ -48,6 +48,11 @@ private: static const float EnvelopeThreshold; + enum GroupSetRegions{ + NONEREG = -1, + CHNLREG, + }; + public: GroupSignal(QString name, boost::shared_ptr data, @@ -74,8 +79,10 @@ public: const std::vector< std::pair > cur_edges() const; + QRectF get_rect(GroupSetRegions type, int y, int right); + protected: - void paint_type_options(QPainter &p, int right, bool hover, int action); + void paint_type_options(QPainter &p, int right, const QPoint pt); private: void paint_trace(QPainter &p, diff --git a/DSView/pv/view/header.cpp b/DSView/pv/view/header.cpp index d84f3f03..e6d20c37 100644 --- a/DSView/pv/view/header.cpp +++ b/DSView/pv/view/header.cpp @@ -118,7 +118,6 @@ void Header::paintEvent(QPaintEvent*) style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this); const int w = width(); - int action = 0; const vector< boost::shared_ptr > traces( _view.get_traces()); @@ -129,11 +128,7 @@ void Header::paintEvent(QPaintEvent*) BOOST_FOREACH(const boost::shared_ptr t, traces) { assert(t); - - const int y = t->get_y(); - const bool highlight = !dragging && - (action = t->pt_in_rect(y, w, _mouse_point)); - t->paint_label(painter, w, highlight, action); + t->paint_label(painter, w, dragging ? QPoint(-1, -1) : _mouse_point); } painter.end(); @@ -145,7 +140,6 @@ void Header::mouseDoubleClickEvent(QMouseEvent *event) const vector< boost::shared_ptr > traces( _view.get_traces()); - int action; if (event->button() & Qt::LeftButton) { _mouse_down_point = event->pos(); @@ -157,14 +151,9 @@ void Header::mouseDoubleClickEvent(QMouseEvent *event) make_pair(t, t->get_v_offset())); // Select the Trace if it has been clicked - const boost::shared_ptr mTrace = - get_mTrace(action, event->pos()); - if (action == Trace::LABEL && mTrace) { - boost::shared_ptr dsoSig; - if (dsoSig = dynamic_pointer_cast(mTrace)) { - dsoSig->auto_set(); - } - } + BOOST_FOREACH(const boost::shared_ptr t, traces) + if (t->mouse_double_click(width(), event->pos())) + break; } } @@ -213,93 +202,12 @@ void Header::mousePressEvent(QMouseEvent *event) } } mTrace->set_old_v_offset(mTrace->get_v_offset()); - } else if (action == Trace::POSTRIG && mTrace) { - if (mTrace->get_trig() == Trace::POSTRIG) - mTrace->set_trig(0); - else - mTrace->set_trig(Trace::POSTRIG); - } else if (action == Trace::HIGTRIG && mTrace) { - if (mTrace->get_trig() == Trace::HIGTRIG) - mTrace->set_trig(0); - else - mTrace->set_trig(Trace::HIGTRIG); - } else if (action == Trace::NEGTRIG && mTrace) { - if (mTrace->get_trig() == Trace::NEGTRIG) - mTrace->set_trig(0); - else - mTrace->set_trig(Trace::NEGTRIG); - } else if (action == Trace::LOWTRIG && mTrace) { - if (mTrace->get_trig() == Trace::LOWTRIG) - mTrace->set_trig(0); - else - mTrace->set_trig(Trace::LOWTRIG); - } else if (action == Trace::EDGETRIG && mTrace) { - if (mTrace->get_trig() == Trace::EDGETRIG) - mTrace->set_trig(0); - else - mTrace->set_trig(Trace::EDGETRIG); - } else if (action == Trace::VDIAL && mTrace) { - boost::shared_ptr dsoSig; - BOOST_FOREACH(const boost::shared_ptr t, traces) { - if (dsoSig = dynamic_pointer_cast(t)) { - dsoSig->set_hDialActive(false); - if (t != mTrace) { - dsoSig->set_vDialActive(false); - } - } - } - if (dsoSig = dynamic_pointer_cast(mTrace)) - dsoSig->set_vDialActive(!dsoSig->get_vDialActive()); - } else if (action == Trace::HDIAL && mTrace) { - boost::shared_ptr dsoSig; - if (dsoSig = dynamic_pointer_cast(mTrace)) { - if (dsoSig->get_hDialActive()) { - BOOST_FOREACH(const boost::shared_ptr t, traces) { - if(dsoSig = dynamic_pointer_cast(t)) { - dsoSig->set_vDialActive(false); - dsoSig->set_hDialActive(false); - } - } - } else { - BOOST_FOREACH(const boost::shared_ptr t, traces) { - if(dsoSig = dynamic_pointer_cast(t)) { - dsoSig->set_vDialActive(false); - dsoSig->set_hDialActive(true); - } - } - } - } - } else if (action == Trace::CHEN && mTrace) { - boost::shared_ptr dsoSig; - if (dsoSig = dynamic_pointer_cast(mTrace)) { - if (!_view.session().get_data_lock()) - dsoSig->set_enable(!dsoSig->enabled()); - } - } else if (action == Trace::ACDC && mTrace) { - boost::shared_ptr dsoSig; - if (dsoSig = dynamic_pointer_cast(mTrace)) { - if (strcmp(_view.session().get_device()->dev_inst()->driver->name, "DSLogic") == 0) - dsoSig->set_acCoupling((dsoSig->get_acCoupling()+1)%2); - else - dsoSig->set_acCoupling((dsoSig->get_acCoupling()+1)%3); - } - } else if (action == Trace::X1 && mTrace) { - boost::shared_ptr dsoSig; - if (dsoSig = dynamic_pointer_cast(mTrace)) { - dsoSig->set_factor(1); - } - } else if (action == Trace::X10 && mTrace) { - boost::shared_ptr dsoSig; - if (dsoSig = dynamic_pointer_cast(mTrace)) { - dsoSig->set_factor(10); - } - } else if (action == Trace::X100 && mTrace) { - boost::shared_ptr dsoSig; - if (dsoSig = dynamic_pointer_cast(mTrace)) { - dsoSig->set_factor(100); - } } + BOOST_FOREACH(const boost::shared_ptr t, traces) + if (t->mouse_press(width(), event->pos())) + break; + if (~QApplication::keyboardModifiers() & Qt::ControlModifier) { // Unselect all other Traces because the Ctrl is not // pressed @@ -350,27 +258,9 @@ void Header::wheelEvent(QWheelEvent *event) _view.get_traces()); // Vertical scrolling double shift = event->delta() / 20.0; - bool setted = false; - BOOST_FOREACH(const boost::shared_ptr t, traces) { - boost::shared_ptr dsoSig; - if (dsoSig = dynamic_pointer_cast(t)) { - if (dsoSig->get_vDialActive()) { - if (shift > 1.0) - dsoSig->go_vDialNext(); - else if (shift < -1.0) - dsoSig->go_vDialPre(); - break; - } else if (dsoSig->get_hDialActive()){ - if (shift > 1.0) - dsoSig->go_hDialNext(setted); - else if (shift < -1.0) - dsoSig->go_hDialPre(setted); - else - break; - setted = true; - } - } - } + BOOST_FOREACH(const boost::shared_ptr t, traces) + if (t->mouse_wheel(width(), event->pos(), shift)) + break; update(); } } diff --git a/DSView/pv/view/logicsignal.cpp b/DSView/pv/view/logicsignal.cpp index 6faede11..3ae1c9dd 100644 --- a/DSView/pv/view/logicsignal.cpp +++ b/DSView/pv/view/logicsignal.cpp @@ -70,23 +70,24 @@ LogicSignal::LogicSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, const sr_channel * const probe) : Signal(dev_inst, probe, SR_CHANNEL_LOGIC), - _data(data) + _data(data), + _trig(NONTRIG) { - assert(probe->index >= 0); _colour = SignalColours[probe->index % countof(SignalColours)]; } -LogicSignal::LogicSignal(const Signal &s, +LogicSignal::LogicSignal(boost::shared_ptr s, boost::shared_ptr data, const sr_channel * const probe) : - Signal(s, probe), - _data(data) + Signal(*s.get(), probe), + _data(data), + _trig(s->get_trig()) { - assert(probe->index >= 0); } LogicSignal::~LogicSignal() { + _cur_edges.clear(); } const sr_channel* LogicSignal::probe() const @@ -104,6 +105,39 @@ boost::shared_ptr LogicSignal::logic_data() const return _data; } +LogicSignal::LogicSetRegions LogicSignal::get_trig() const +{ + return _trig; +} + +void LogicSignal::set_trig(int trig) +{ + if (trig > NONTRIG && trig <= EDGTRIG) + _trig = (LogicSetRegions)trig; + else + _trig = NONTRIG; +} + +void LogicSignal::commit_trig() +{ + + if (_trig == NONTRIG) + ds_trigger_probe_set(_index_list.front(), 'X', 'X'); + else { + ds_trigger_set_en(true); + if (_trig == POSTRIG) + ds_trigger_probe_set(_index_list.front(), 'R', 'X'); + else if (_trig == HIGTRIG) + ds_trigger_probe_set(_index_list.front(), '1', 'X'); + else if (_trig == NEGTRIG) + ds_trigger_probe_set(_index_list.front(), 'F', 'X'); + else if (_trig == LOWTRIG) + ds_trigger_probe_set(_index_list.front(), '0', 'X'); + else if (_trig == EDGTRIG) + ds_trigger_probe_set(_index_list.front(), 'C', 'X'); + } +} + void LogicSignal::paint_mid(QPainter &p, int left, int right) { using pv::view::View; @@ -206,35 +240,30 @@ const std::vector< std::pair > LogicSignal::cur_edges() const return _cur_edges; } -void LogicSignal::paint_type_options(QPainter &p, int right, bool hover, int action) +void LogicSignal::paint_type_options(QPainter &p, int right, const QPoint pt) { int y = get_y(); - const QRectF posTrig_rect = get_rect("posTrig", y, right); - const QRectF higTrig_rect = get_rect("higTrig", y, right); - const QRectF negTrig_rect = get_rect("negTrig", y, right); - const QRectF lowTrig_rect = get_rect("lowTrig", y, right); - const QRectF edgeTrig_rect = get_rect("edgeTrig", y, right); + const QRectF posTrig_rect = get_rect(POSTRIG, y, right); + const QRectF higTrig_rect = get_rect(HIGTRIG, y, right); + const QRectF negTrig_rect = get_rect(NEGTRIG, y, right); + const QRectF lowTrig_rect = get_rect(LOWTRIG, y, right); + const QRectF edgeTrig_rect = get_rect(EDGTRIG, y, right); p.setPen(Qt::transparent); - p.setBrush(((hover && action == POSTRIG) || (_trig == POSTRIG)) ? - dsYellow : - dsBlue); + p.setBrush(posTrig_rect.contains(pt) ? dsYellow.darker() : + (_trig == POSTRIG) ? dsYellow : dsBlue); p.drawRect(posTrig_rect); - p.setBrush(((hover && action == HIGTRIG) || (_trig == HIGTRIG)) ? - dsYellow : - dsBlue); + p.setBrush(higTrig_rect.contains(pt) ? dsYellow.darker() : + (_trig == HIGTRIG) ? dsYellow : dsBlue); p.drawRect(higTrig_rect); - p.setBrush(((hover && action == NEGTRIG) || (_trig == NEGTRIG)) ? - dsYellow : - dsBlue); + p.setBrush(negTrig_rect.contains(pt) ? dsYellow.darker() : + (_trig == NEGTRIG) ? dsYellow : dsBlue); p.drawRect(negTrig_rect); - p.setBrush(((hover && action == LOWTRIG) || (_trig == LOWTRIG)) ? - dsYellow : - dsBlue); + p.setBrush(lowTrig_rect.contains(pt) ? dsYellow.darker() : + (_trig == LOWTRIG) ? dsYellow : dsBlue); p.drawRect(lowTrig_rect); - p.setBrush(((hover && action == EDGETRIG) || (_trig == EDGETRIG)) ? - dsYellow : - dsBlue); + p.setBrush(edgeTrig_rect.contains(pt) ? dsYellow.darker() : + (_trig == EDGTRIG) ? dsYellow : dsBlue); p.drawRect(edgeTrig_rect); p.setPen(QPen(Qt::blue, 1, Qt::DotLine)); @@ -325,5 +354,107 @@ bool LogicSignal::measure(const QPointF &p, uint64_t &index0, uint64_t &index1, return false; } + +bool LogicSignal::edges(const QPointF &p, uint64_t start, uint64_t &rising, uint64_t &falling) const +{ + uint64_t index, end; + const float gap = abs(p.y() - get_y()); + if (gap < get_signalHeight() * 0.5) { + const deque< boost::shared_ptr > &snapshots = + _data->get_snapshots(); + if (snapshots.empty()) + return false; + + const boost::shared_ptr &snapshot = + snapshots.front(); + if (snapshot->buf_null()) + return false; + + end = _data->samplerate() * (_view->offset() - _data->get_start_time() + p.x() * _view->scale()); + index = min(start, end); + end = max(start, end); + start = index; + if (end > (snapshot->get_sample_count() - 1)) + return false; + + const uint64_t sig_mask = 1ULL << get_index(); + bool sample = snapshot->get_sample(start) & sig_mask; + + rising = 0; + falling = 0; + do { + if (snapshot->get_nxt_edge(index, sample, snapshot->get_sample_count(), 1, get_index())) { + if (index > end) + break; + rising += !sample; + falling += sample; + sample = !sample; + } else { + break; + } + } while(index <= end); + return true; + } + return false; +} + +bool LogicSignal::mouse_press(int right, const QPoint pt) +{ + int y = get_y(); + const QRectF posTrig = get_rect(POSTRIG, y, right); + const QRectF higTrig = get_rect(HIGTRIG, y, right); + const QRectF negTrig = get_rect(NEGTRIG, y, right); + const QRectF lowTrig = get_rect(LOWTRIG, y, right); + const QRectF edgeTrig = get_rect(EDGTRIG, y, right); + + if (posTrig.contains(pt)) + set_trig((_trig == POSTRIG) ? NONTRIG : POSTRIG); + else if (higTrig.contains(pt)) + set_trig((_trig == HIGTRIG) ? NONTRIG : HIGTRIG); + else if (negTrig.contains(pt)) + set_trig((_trig == NEGTRIG) ? NONTRIG : NEGTRIG); + else if (lowTrig.contains(pt)) + set_trig((_trig == LOWTRIG) ? NONTRIG : LOWTRIG); + else if (edgeTrig.contains(pt)) + set_trig((_trig == EDGTRIG) ? NONTRIG : EDGTRIG); + else + return false; + + return true; +} + +QRectF LogicSignal::get_rect(LogicSetRegions type, int y, int right) +{ + const QSizeF name_size(right - get_leftWidth() - get_rightWidth(), SquareWidth); + + if (type == POSTRIG) + return QRectF( + get_leftWidth() + name_size.width() + Margin, + y - SquareWidth / 2, + SquareWidth, SquareWidth); + else if (type == HIGTRIG) + return QRectF( + get_leftWidth() + name_size.width() + SquareWidth + Margin, + y - SquareWidth / 2, + SquareWidth, SquareWidth); + else if (type == NEGTRIG) + return QRectF( + get_leftWidth() + name_size.width() + 2 * SquareWidth + Margin, + y - SquareWidth / 2, + SquareWidth, SquareWidth); + else if (type == LOWTRIG) + return QRectF( + get_leftWidth() + name_size.width() + 3 * SquareWidth + Margin, + y - SquareWidth / 2, + SquareWidth, SquareWidth); + else if (type == EDGTRIG) + return QRectF( + get_leftWidth() + name_size.width() + 4 * SquareWidth + Margin, + y - SquareWidth / 2, + SquareWidth, SquareWidth); + else + return QRectF(0, 0, 0, 0); +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/logicsignal.h b/DSView/pv/view/logicsignal.h index 9a03464f..5f4ba7d1 100644 --- a/DSView/pv/view/logicsignal.h +++ b/DSView/pv/view/logicsignal.h @@ -53,12 +53,21 @@ private: static const int StateHeight; static const int StateRound; + enum LogicSetRegions{ + NONTRIG = 0, + POSTRIG, + HIGTRIG, + NEGTRIG, + LOWTRIG, + EDGTRIG, + }; + public: LogicSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, const sr_channel * const probe); - LogicSignal(const Signal &s, + LogicSignal(boost::shared_ptr s, boost::shared_ptr data, const sr_channel * const probe); @@ -70,6 +79,13 @@ public: boost::shared_ptr logic_data() const; + /** + * + */ + LogicSetRegions get_trig() const; + void set_trig(int trig); + void commit_trig(); + /** * Paints the signal with a QPainter * @param p the QPainter to paint into. @@ -82,8 +98,14 @@ public: bool measure(const QPointF &p, uint64_t &index0, uint64_t &index1, uint64_t &index2) const; + bool edges(const QPointF &p, uint64_t start, uint64_t &rising, uint64_t &falling) const; + + bool mouse_press(int right, const QPoint pt); + + QRectF get_rect(LogicSetRegions type, int y, int right); + protected: - void paint_type_options(QPainter &p, int right, bool hover, int action); + void paint_type_options(QPainter &p, int right, const QPoint pt); private: @@ -95,6 +117,7 @@ private: private: boost::shared_ptr _data; std::vector< std::pair > _cur_edges; + LogicSetRegions _trig; }; } // namespace view diff --git a/DSView/pv/view/trace.cpp b/DSView/pv/view/trace.cpp index d0093578..92b4f210 100644 --- a/DSView/pv/view/trace.cpp +++ b/DSView/pv/view/trace.cpp @@ -42,7 +42,7 @@ const QColor Trace::dsYellow = QColor(238, 178, 17, 255); const QColor Trace::dsRed = QColor(213, 15, 37, 255); const QColor Trace::dsGreen = QColor(0, 153, 37, 200); const QColor Trace::dsGray = QColor(0x88, 0x8A, 0x85, 60); -const QColor Trace::dsFore = QColor(0xff, 0xff, 0xff, 100); +const QColor Trace::dsFore = QColor(0xff, 0xff, 0xff, 60); const QColor Trace::dsBack = QColor(0x16, 0x18, 0x23, 180); const QColor Trace::dsDisable = QColor(0x88, 0x8A, 0x85, 200); const QColor Trace::dsActive = QColor(17, 133, 209, 255); @@ -53,14 +53,13 @@ const QPen Trace::SignalAxisPen = QColor(128, 128, 128, 64); const QPen Trace::AxisPen(QColor(128, 128, 128, 64)); const int Trace::LabelHitPadding = 2; -Trace::Trace(QString name, int index, int type) : +Trace::Trace(QString name, uint16_t index, int type) : _view(NULL), _name(name), _v_offset(INT_MAX), _type(type), _sec_index(0), - _signalHeight(30), - _trig(0) + _signalHeight(30) { _index_list.push_back(index); } @@ -72,8 +71,7 @@ Trace::Trace(QString name, std::list index_list, int type, int sec_index) : _type(type), _index_list(index_list), _sec_index(sec_index), - _signalHeight(30), - _trig(0) + _signalHeight(30) { } @@ -87,7 +85,6 @@ Trace::Trace(const Trace &t) : _sec_index(t._sec_index), _old_v_offset(t._old_v_offset), _signalHeight(t._signalHeight), - _trig(t._trig), _text_size(t._text_size) { } @@ -180,28 +177,6 @@ void Trace::set_signalHeight(int height) _signalHeight = height; } -int Trace::get_trig() const -{ - return _trig; -} - -void Trace::set_trig(int trig) -{ - _trig = trig; - if (trig == 0) - ds_trigger_probe_set(_index_list.front(), 'X', 'X'); - else if (trig == POSTRIG) - ds_trigger_probe_set(_index_list.front(), 'R', 'X'); - else if (trig == HIGTRIG) - ds_trigger_probe_set(_index_list.front(), '1', 'X'); - else if (trig == NEGTRIG) - ds_trigger_probe_set(_index_list.front(), 'F', 'X'); - else if (trig == LOWTRIG) - ds_trigger_probe_set(_index_list.front(), '0', 'X'); - else if (trig == EDGETRIG) - ds_trigger_probe_set(_index_list.front(), 'C', 'X'); -} - void Trace::set_view(pv::view::View *view) { assert(view); @@ -231,7 +206,7 @@ void Trace::paint_fore(QPainter &p, int left, int right) (void)right; } -void Trace::paint_label(QPainter &p, int right, bool hover, int action) +void Trace::paint_label(QPainter &p, int right, const QPoint pt) { compute_text_size(p); const int y = get_y(); @@ -251,7 +226,7 @@ void Trace::paint_label(QPainter &p, int right, bool hover, int action) p.drawText(name_rect, Qt::AlignLeft | Qt::AlignVCenter, _name); // Paint the trigButton - paint_type_options(p, right, hover, action); + paint_type_options(p, right, pt); // Paint the label if (enabled()) { @@ -265,9 +240,9 @@ void Trace::paint_label(QPainter &p, int right, bool hover, int action) p.setPen(Qt::transparent); if (_type == SR_CHANNEL_DSO) - p.setBrush(((hover && action == LABEL) || selected()) ? _colour.darker() : _colour); + p.setBrush((label_rect.contains(pt) || selected()) ? _colour.darker() : _colour); else - p.setBrush(((hover && action == LABEL) || selected()) ? dsYellow : dsBlue); + p.setBrush((label_rect.contains(pt) || selected()) ? dsYellow : dsBlue); p.drawPolygon(points, countof(points)); p.setPen(QPen(Qt::blue, 1, Qt::DotLine)); @@ -288,65 +263,47 @@ void Trace::paint_label(QPainter &p, int right, bool hover, int action) } } -void Trace::paint_type_options(QPainter &p, int right, bool hover, int action) +void Trace::paint_type_options(QPainter &p, int right, const QPoint pt) { (void)p; (void)right; - (void)hover; - (void)action; + (void)pt; +} + +bool Trace::mouse_double_click(int right, const QPoint pt) +{ + (void)right; + (void)pt; + return false; +} + +bool Trace::mouse_press(int right, const QPoint pt) +{ + (void)right; + (void)pt; + return false; +} + +bool Trace::mouse_wheel(int right, const QPoint pt, const int shift) +{ + (void)right; + (void)pt; + (void)shift; + return false; } int Trace::pt_in_rect(int y, int right, const QPoint &point) { const QRectF color = get_rect("color", y, right); const QRectF name = get_rect("name", y, right); - const QRectF posTrig = get_rect("posTrig", y, right); - const QRectF higTrig = get_rect("higTrig", y, right); - const QRectF negTrig = get_rect("negTrig", y, right); - const QRectF lowTrig = get_rect("lowTrig", y, right); - const QRectF edgeTrig = get_rect("edgeTrig", y, right); const QRectF label = get_rect("label", get_zeroPos(), right); - const QRectF vDial = get_rect("vDial", y, right); - const QRectF x1 = get_rect("x1", y, right); - const QRectF x10 = get_rect("x10", y, right); - const QRectF x100 = get_rect("x100", y, right); - const QRectF hDial = get_rect("hDial", y, right); - const QRectF chEn = get_rect("chEn", y, right); - const QRectF acdc = get_rect("acdc", y, right); - const QRectF dsoTrig = get_rect("dsoTrig", 0, right); if (color.contains(point) && enabled()) return COLOR; else if (name.contains(point) && enabled()) return NAME; - else if (posTrig.contains(point) && _type == SR_CHANNEL_LOGIC) - return POSTRIG; - else if (higTrig.contains(point) && _type == SR_CHANNEL_LOGIC) - return HIGTRIG; - else if (negTrig.contains(point) && _type == SR_CHANNEL_LOGIC) - return NEGTRIG; - else if (lowTrig.contains(point) && _type == SR_CHANNEL_LOGIC) - return LOWTRIG; - else if (edgeTrig.contains(point) && _type == SR_CHANNEL_LOGIC) - return EDGETRIG; else if (label.contains(point) && enabled()) return LABEL; - else if (vDial.contains(point) && _type == SR_CHANNEL_DSO && enabled()) - return VDIAL; - else if (x1.contains(point) && _type == SR_CHANNEL_DSO && enabled()) - return X1; - else if (x10.contains(point) && _type == SR_CHANNEL_DSO && enabled()) - return X10; - else if (x100.contains(point) && _type == SR_CHANNEL_DSO && enabled()) - return X100; - else if (hDial.contains(point) && _type == SR_CHANNEL_DSO && enabled()) - return HDIAL; - else if (chEn.contains(point) && _type == SR_CHANNEL_DSO) - return CHEN; - else if (acdc.contains(point) && _type == SR_CHANNEL_DSO && enabled()) - return ACDC; - else if (dsoTrig.contains(point) && _type == SR_CHANNEL_DSO && enabled()) - return DSOTRIG; else return 0; } @@ -381,71 +338,6 @@ QRectF Trace::get_rect(const char *s, int y, int right) right - 1.5f * label_size.width(), y - SquareWidth / 2, label_size.width(), label_size.height()); - else if (!strcmp(s, "posTrig")) - return QRectF( - get_leftWidth() + name_size.width() + Margin, - y - SquareWidth / 2, - SquareWidth, SquareWidth); - else if (!strcmp(s, "higTrig")) - return QRectF( - get_leftWidth() + name_size.width() + SquareWidth + Margin, - y - SquareWidth / 2, - SquareWidth, SquareWidth); - else if (!strcmp(s, "negTrig")) - return QRectF( - get_leftWidth() + name_size.width() + 2 * SquareWidth + Margin, - y - SquareWidth / 2, - SquareWidth, SquareWidth); - else if (!strcmp(s, "lowTrig")) - return QRectF( - get_leftWidth() + name_size.width() + 3 * SquareWidth + Margin, - y - SquareWidth / 2, - SquareWidth, SquareWidth); - else if (!strcmp(s, "edgeTrig")) - return QRectF( - get_leftWidth() + name_size.width() + 4 * SquareWidth + Margin, - y - SquareWidth / 2, - SquareWidth, SquareWidth); - else if (!strcmp(s, "groupIndex")) - return QRectF( - get_leftWidth() + name_size.width() + Margin, - y - SquareWidth / 2, - SquareWidth * SquareNum, SquareWidth); - else if (!strcmp(s, "vDial")) - return QRectF( - get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin, - y - SquareWidth * SquareNum, - SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1)); - else if (!strcmp(s, "x1")) - return QRectF( - get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45, - y - SquareWidth - SquareWidth * (SquareNum-1) * 0.85, - SquareWidth * 1.75, SquareWidth); - else if (!strcmp(s, "x10")) - return QRectF( - get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45, - y - SquareWidth - SquareWidth * (SquareNum-1) * 0.55, - SquareWidth * 1.75, SquareWidth); - else if (!strcmp(s, "x100")) - return QRectF( - get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45, - y - SquareWidth - SquareWidth * (SquareNum-1) * 0.25, - SquareWidth * 1.75, SquareWidth); - else if (!strcmp(s, "hDial")) - return QRectF( - get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin, - y + SquareWidth * 1.5, - SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1)); - else if (!strcmp(s, "chEn")) - return QRectF( - get_leftWidth() + name_size.width() + SquareWidth*0.75 + Margin, - y - SquareWidth / 2, - SquareWidth * 1.5, SquareWidth); - else if (!strcmp(s, "acdc")) - return QRectF( - get_leftWidth() + name_size.width() + SquareWidth*2.75 + Margin, - y - SquareWidth / 2, - SquareWidth * 1.5, SquareWidth); else return QRectF( 2, diff --git a/DSView/pv/view/trace.h b/DSView/pv/view/trace.h index 8cc73307..ef3d31f3 100644 --- a/DSView/pv/view/trace.h +++ b/DSView/pv/view/trace.h @@ -45,7 +45,7 @@ class Trace : public SelectableItem { Q_OBJECT -private: +protected: static const int Margin = 3; static const int SquareNum = 5; static const QPen AxisPen; @@ -55,20 +55,7 @@ public: static const int SquareWidth = 20; static const int COLOR = 1; static const int NAME = 2; - static const int POSTRIG = 3; - static const int HIGTRIG = 4; - static const int NEGTRIG = 5; - static const int LOWTRIG = 6; - static const int EDGETRIG = 7; static const int LABEL = 8; - static const int VDIAL = 9; - static const int HDIAL = 10; - static const int CHEN = 11; - static const int ACDC = 12; - static const int DSOTRIG = 13; - static const int X1 = 14; - static const int X10 = 15; - static const int X100 = 16; static const QColor dsBlue; static const QColor dsYellow; @@ -84,7 +71,7 @@ public: static const QPen SignalAxisPen; protected: - Trace(QString name, int index, int type); + Trace(QString name, uint16_t index, int type); Trace(QString name, std::list index_list, int type, int sec_index); /** @@ -166,12 +153,6 @@ public: virtual int get_zeroPos(); - /** - * - */ - int get_trig() const; - void set_trig(int trig); - /** * Returns true if the trace is visible and enabled. */ @@ -208,10 +189,9 @@ public: * @param p the QPainter to paint into. * @param right the x-coordinate of the right edge of the header * area. - * @param hover true if the label is being hovered over by the mouse. - * @param action mouse position for hover + * @param point the mouse point. */ - virtual void paint_label(QPainter &p, int right, bool hover, int action); + virtual void paint_label(QPainter &p, int right, const QPoint pt); /** * Gets the y-offset of the axis. @@ -250,6 +230,12 @@ public: virtual QRectF get_view_rect() const; + virtual bool mouse_double_click(int right, const QPoint pt); + + virtual bool mouse_press(int right, const QPoint pt); + + virtual bool mouse_wheel(int right, const QPoint pt, const int shift); + protected: /** @@ -274,10 +260,9 @@ protected: * @param p the QPainter to paint into. * @param right the x-coordinate of the right edge of the header * area. - * @param hover true if the label is being hovered over by the mouse. - * @param action mouse position for hover + * @param point the mouse point. */ - virtual void paint_type_options(QPainter &p, int right, bool hover, int action); + virtual void paint_type_options(QPainter &p, int right, const QPoint pt); private: @@ -307,7 +292,6 @@ protected: int _sec_index; int _old_v_offset; int _signalHeight; - int _trig; QSizeF _text_size; }; diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index eb7f815a..3965524b 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -57,6 +57,7 @@ const int View::LabelMarginWidth = 70; const int View::RulerHeight = 50; const int View::MaxScrollValue = INT_MAX / 2; +const int View::MaxHeightUnit = 20; //const int View::SignalHeight = 30;s const int View::SignalMargin = 10; @@ -225,6 +226,7 @@ void View::zoom(double steps, int offset) } } } + _offset = cursor_offset - _scale * offset; _offset = max(min(_offset, get_max_offset()), get_min_offset()); @@ -470,6 +472,7 @@ void View::update_scale() void View::signals_changed() { int total_rows = 0; + uint8_t max_height = MaxHeightUnit; const vector< boost::shared_ptr > traces(get_traces()); BOOST_FOREACH(const boost::shared_ptr t, traces) { @@ -483,7 +486,16 @@ void View::signals_changed() - horizontalScrollBar()->height() - 2 * SignalMargin * traces.size()) * 1.0 / total_rows; - _signalHeight = (int)((height <= 0) ? 1 : height); + if (_session.get_device()->dev_inst()->mode == LOGIC) { + GVariant* gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_MAX_HEIGHT_VALUE); + if (gvar != NULL) { + max_height = (g_variant_get_byte(gvar) + 1) * MaxHeightUnit; + g_variant_unref(gvar); + } + _signalHeight = (int)((height <= 0) ? 1 : (height >= max_height) ? max_height : height); + } else { + _signalHeight = (int)((height <= 0) ? 1 : height); + } _spanY = _signalHeight + 2 * SignalMargin; int next_v_offset = SignalMargin; BOOST_FOREACH(boost::shared_ptr t, traces) { @@ -494,6 +506,7 @@ void View::signals_changed() next_v_offset += traceHeight + 2 * SignalMargin; } + _viewport->clear_measure(); header_updated(); normalize_layout(); } diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h index 92ba5c01..c3f6ac72 100644 --- a/DSView/pv/view/view.h +++ b/DSView/pv/view/view.h @@ -64,6 +64,7 @@ private: static const int RulerHeight; static const int MaxScrollValue; + static const int MaxHeightUnit; public: //static const int SignalHeight; diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp index 32652017..dfa94970 100644 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -32,10 +32,12 @@ #include "../data/logic.h" #include "../data/logicsnapshot.h" #include "../sigsession.h" +#include "../dialogs/dsomeasure.h" #include #include + #include #include @@ -70,7 +72,7 @@ Viewport::Viewport(View &parent) : { setMouseTracking(true); setAutoFillBackground(true); - setBackgroundRole(QPalette::Base); + setBackgroundRole(QPalette::Base); //setFixedSize(QSize(600, 400)); _mm_width = "#####"; @@ -379,10 +381,11 @@ void Viewport::mousePressEvent(QMouseEvent *event) const double samples_per_pixel = _view.session().get_device()->get_sample_rate() * _view.scale(); while (i != _view.get_cursorList().end()) { cursorX = (*i)->index()/samples_per_pixel - (_view.offset() / _view.scale()); - if ((*i)->grabbed()) + if ((*i)->grabbed()) { _view.get_ruler()->rel_grabbed_cursor(); - else if (qAbs(cursorX - event->pos().x()) <= HitCursorMargin) { + } else if (qAbs(cursorX - event->pos().x()) <= HitCursorMargin) { _view.get_ruler()->set_grabbed_cursor(*i); + _measure_type = LOGIC_CURS; break; } i++; @@ -396,13 +399,24 @@ void Viewport::mousePressEvent(QMouseEvent *event) if (!s->enabled()) continue; boost::shared_ptr dsoSig; - if ((dsoSig = dynamic_pointer_cast(s)) && - dsoSig->get_trig_rect(0, _view.get_view_width()).contains(_mouse_point)) { - _drag_sig = s; - break; + if (dsoSig = dynamic_pointer_cast(s)) { + if (dsoSig->get_trig_rect(0, _view.get_view_width()).contains(_mouse_point)) { + _drag_sig = s; + break; + } else if (dsoSig->get_ms_show_hover()) { + dsoSig->set_ms_show(!dsoSig->get_ms_show()); + break; + } else if (dsoSig->get_ms_gear_hover()) { + pv::dialogs::DsoMeasure dsoMeasureDialog(this, dsoSig); + dsoMeasureDialog.exec(); + break; + } } } + if (_measure_type == LOGIC_FREQ) + _measure_type = NO_MEASURE; + update(); } @@ -444,7 +458,7 @@ void Viewport::mousePressEvent(QMouseEvent *event) _dso_xm_index[i-1] = min(_dso_xm_index[i-1], _dso_xm_index[i]); _dso_xm_index[i] = max_index; } - _dso_xm_stage = (++_dso_xm_stage) % (DsoMeasureStages + 1); + _dso_xm_stage = (_dso_xm_stage + 1) % (DsoMeasureStages + 1); } } } @@ -470,7 +484,7 @@ void Viewport::mouseMoveEvent(QMouseEvent *event) (_mouse_down_point - event->pos()).x() * _view.scale()); _drag_strength = (_mouse_down_point - event->pos()).x(); - measure(); + //measure(); } } @@ -511,18 +525,45 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event) if(_drag_sig) _drag_sig.reset(); - const double strength = _drag_strength*DragTimerInterval*1.0/_time.elapsed(); - if (abs(_drag_strength) < MinorDragOffsetUp && abs(strength) > MinorDragRateUp) { - _drag_strength = _drag_strength; - _drag_timer.start(DragTimerInterval); - } else if (abs(strength) > DragTimerInterval) { - _drag_strength = strength * 5; - _drag_timer.start(DragTimerInterval); - } else { - _drag_strength = 0; - _drag_timer.stop(); + if ((_measure_type != LOGIC_MOVE && _measure_type != LOGIC_CURS) && + _view.session().get_device()->dev_inst()->mode == LOGIC && + _mouse_down_point.x() == event->pos().x() && + event->button() & Qt::LeftButton) { + if (_measure_type == LOGIC_EDGE) { + _measure_type = NO_MEASURE; + _measure_shown = false; + _edge_rising = 0; + _edge_falling = 0; + } else { + _measure_type = LOGIC_EDGE; + _edge_start = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().get_device()->get_sample_rate(); + } } + if (_view.session().get_device()->dev_inst()->mode == LOGIC && + (_measure_type == NO_MEASURE || _measure_type == LOGIC_MOVE)) { + const double strength = _drag_strength*DragTimerInterval*1.0/_time.elapsed(); + if (_time.elapsed() < 200 && + abs(_drag_strength) < MinorDragOffsetUp && + abs(strength) > MinorDragRateUp) { + _drag_strength = _drag_strength; + _drag_timer.start(DragTimerInterval); + _measure_type = LOGIC_MOVE; + } else if (_time.elapsed() < 200 && + abs(strength) > DragTimerInterval) { + _drag_strength = strength * 5; + _drag_timer.start(DragTimerInterval); + _measure_type = LOGIC_MOVE; + } else { + _drag_strength = 0; + _drag_timer.stop(); + _measure_type = NO_MEASURE; + } + } + + if (!_view.get_ruler()->get_grabbed_cursor() && _measure_type == LOGIC_CURS) + _measure_type = NO_MEASURE; + update(); } @@ -532,14 +573,20 @@ void Viewport::mouseDoubleClickEvent(QMouseEvent *event) (void)event; if (_view.session().get_device()->dev_inst()->mode == LOGIC) { - if (_view.scale() == _view.get_maxscale()) - _view.set_preScale_preOffset(); - else - _view.set_scale_offset(_view.get_maxscale(), 0); - + if (event->button() & Qt::RightButton) { + if (_view.scale() == _view.get_maxscale()) + _view.set_preScale_preOffset(); + else + _view.set_scale_offset(_view.get_maxscale(), 0); + } else if (event->button() & Qt::LeftButton) { + uint64_t index = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().get_device()->get_sample_rate(); + _view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], index); + _view.show_cursors(true); + } update(); } else if (_view.session().get_device()->dev_inst()->mode == DSO && - _view.session().get_capture_state() != SigSession::Init) { + _view.session().get_capture_state() != SigSession::Init && + event->button() & Qt::LeftButton) { if (_dso_xm_stage == 0) { uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); double scale = _view.scale(); @@ -587,6 +634,10 @@ void Viewport::leaveEvent(QEvent *) _measure_shown = _dso_xm || _dso_ym; _mouse_point = QPoint(-1, -1); //_view.show_cursors(false); + if (_measure_type == LOGIC_EDGE || _measure_type == LOGIC_MOVE) { + _measure_type = NO_MEASURE; + _measure_shown = false; + } update(); } @@ -610,52 +661,74 @@ void Viewport::set_receive_len(quint64 length) update(); } +void Viewport::clear_measure() +{ + _measure_type = NO_MEASURE; + update(); +} + void Viewport::measure() { if ((_view.session().get_device()->dev_inst()->mode == LOGIC && _view.session().get_capture_state() == SigSession::Running) || _drag_strength != 0) return; - _measure_shown = _dso_xm || _dso_ym; - const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); - const vector< boost::shared_ptr > sigs(_view.session().get_signals()); - BOOST_FOREACH(const boost::shared_ptr s, sigs) { - assert(s); - boost::shared_ptr logicSig; - boost::shared_ptr dsoSig; - if (logicSig = dynamic_pointer_cast(s)) { - if (logicSig->measure(_view.hover_point(), _cur_sample, _nxt_sample, _thd_sample)) { - _measure_shown = true; - _measure_type = LOGIC_FREQ; + _measure_shown = _dso_xm || _dso_ym; + const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); + const vector< boost::shared_ptr > sigs(_view.session().get_signals()); + BOOST_FOREACH(const boost::shared_ptr s, sigs) { + assert(s); + boost::shared_ptr logicSig; + boost::shared_ptr dsoSig; + if (logicSig = dynamic_pointer_cast(s)) { + if (_measure_type != LOGIC_EDGE && + logicSig->measure(_view.hover_point(), _cur_sample, _nxt_sample, _thd_sample)) { + _measure_shown = true; + _measure_type = LOGIC_FREQ; - _mm_width = _view.get_ruler()->format_real_time(_nxt_sample - _cur_sample, sample_rate); - _mm_period = _thd_sample != 0 ? _view.get_ruler()->format_real_time(_thd_sample - _cur_sample, sample_rate) : "#####"; - _mm_freq = _thd_sample != 0 ? _view.get_ruler()->format_real_freq(_thd_sample - _cur_sample, sample_rate) : "#####"; + _mm_width = _view.get_ruler()->format_real_time(_nxt_sample - _cur_sample, sample_rate); + _mm_period = _thd_sample != 0 ? _view.get_ruler()->format_real_time(_thd_sample - _cur_sample, sample_rate) : "#####"; + _mm_freq = _thd_sample != 0 ? _view.get_ruler()->format_real_freq(_thd_sample - _cur_sample, sample_rate) : "#####"; - const double pixels_offset = _view.offset() / _view.scale(); - const double samples_per_pixel = sample_rate * _view.scale(); - _cur_preX = _cur_sample / samples_per_pixel - pixels_offset; - _cur_aftX = _nxt_sample / samples_per_pixel - pixels_offset; - _cur_thdX = _thd_sample / samples_per_pixel - pixels_offset; - _cur_midY = logicSig->get_y(); + const double pixels_offset = _view.offset() / _view.scale(); + const double samples_per_pixel = sample_rate * _view.scale(); + _cur_preX = _cur_sample / samples_per_pixel - pixels_offset; + _cur_aftX = _nxt_sample / samples_per_pixel - pixels_offset; + _cur_thdX = _thd_sample / samples_per_pixel - pixels_offset; + _cur_midY = logicSig->get_y(); - _mm_duty = _thd_sample != 0 ? QString::number((_nxt_sample - _cur_sample) * 100.0 / (_thd_sample - _cur_sample), 'f', 2)+"%" : + _mm_duty = _thd_sample != 0 ? QString::number((_nxt_sample - _cur_sample) * 100.0 / (_thd_sample - _cur_sample), 'f', 2)+"%" : "#####"; - mouse_measure(); - break; - } else { - _mm_width = "#####"; - _mm_period = "#####"; - _mm_freq = "#####"; - _mm_duty = "#####"; - } - mouse_measure(); - } else if (dsoSig = dynamic_pointer_cast(s)) { - if (_measure_en && dsoSig->measure(_view.hover_point())) { - _measure_shown = true; - _measure_type = DSO_FREQ; - } - } + mouse_measure(); + break; + } else if (_measure_type == LOGIC_EDGE && + logicSig->edges(_view.hover_point(), _edge_start, _edge_rising, _edge_falling)) { + _measure_shown = true; + + const double pixels_offset = _view.offset() / _view.scale(); + const double samples_per_pixel = sample_rate * _view.scale(); + _cur_preX = _edge_start / samples_per_pixel - pixels_offset; + _cur_aftX = _view.hover_point().x(); + _cur_midY = logicSig->get_y() - logicSig->get_signalHeight()/2 - 5; + + _em_rising = "Rising: " + QString::number(_edge_rising); + _em_falling = "Falling: " + QString::number(_edge_falling); + _em_edges = "Edges: " + QString::number(_edge_rising + _edge_falling); + + break; + } else { + _mm_width = "#####"; + _mm_period = "#####"; + _mm_freq = "#####"; + _mm_duty = "#####"; + } + mouse_measure(); + } else if (dsoSig = dynamic_pointer_cast(s)) { + if (_measure_en && dsoSig->measure(_view.hover_point())) { + _measure_shown = true; + _measure_type = DSO_FREQ; + } + } } } @@ -715,6 +788,43 @@ void Viewport::paintMeasure(QPainter &p) p.drawText(measure4_rect, Qt::AlignRight | Qt::AlignVCenter, tr("Duty Cycle: ") + _mm_duty); } + } else if (_measure_type == LOGIC_EDGE) { + p.setPen(QColor(17, 133, 209, 255)); + + p.drawLine(QLineF(_cur_preX, _cur_midY-5, _cur_preX, _cur_midY+5)); + p.drawLine(QLineF(_cur_aftX, _cur_midY-5, _cur_aftX, _cur_midY+5)); + p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_aftX, _cur_midY)); + + int typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, _em_edges).width(); + typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, _em_rising).width()); + typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, _em_falling).width()); + + typical_width = typical_width + 30; + + const double width = _view.get_view_width(); + const double height = _view.viewport()->height(); + const double left = _view.hover_point().x(); + const double top = _view.hover_point().y(); + const double right = left + typical_width; + const double bottom = top + 60; + QPointF org_pos = QPointF(right > width ? left - typical_width : left, bottom > height ? top - 80 : top); + QRectF measure_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 60.0); + QRectF measure1_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 20.0); + QRectF measure2_rect = QRectF(org_pos.x(), org_pos.y()+20, (double)typical_width, 20.0); + QRectF measure3_rect = QRectF(org_pos.x(), org_pos.y()+40, (double)typical_width, 20.0); + + p.setPen(Qt::NoPen); + p.setBrush(QColor(17, 133, 209, 150)); + p.drawRect(measure_rect); + + p.setPen(Qt::black); + p.drawText(measure1_rect, Qt::AlignRight | Qt::AlignVCenter, _em_edges); + p.drawText(measure2_rect, Qt::AlignRight | Qt::AlignVCenter, _em_rising); + p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter, _em_falling); + } else if (_measure_type == DSO_FREQ) { const vector< boost::shared_ptr > sigs(_view.session().get_signals()); BOOST_FOREACH(const boost::shared_ptr s, sigs) { diff --git a/DSView/pv/view/viewport.h b/DSView/pv/view/viewport.h index 6a0f8909..40a15bbc 100644 --- a/DSView/pv/view/viewport.h +++ b/DSView/pv/view/viewport.h @@ -57,6 +57,9 @@ public: enum MeasureType { NO_MEASURE, LOGIC_FREQ, + LOGIC_EDGE, + LOGIC_MOVE, + LOGIC_CURS, DSO_FREQ }; @@ -74,6 +77,8 @@ public: void start_trigger_timer(int msec); void stop_trigger_timer(); + void clear_measure(); + protected: void paintEvent(QPaintEvent *event); @@ -118,7 +123,7 @@ private: bool _measure_en; bool _measure_shown; - int _measure_type; + MeasureType _measure_type; uint64_t _cur_sample; uint64_t _nxt_sample; uint64_t _thd_sample; @@ -131,6 +136,13 @@ private: QString _mm_freq; QString _mm_duty; + uint64_t _edge_rising; + uint64_t _edge_falling; + uint64_t _edge_start; + QString _em_rising; + QString _em_falling; + QString _em_edges; + QTimer trigger_timer; bool triggered; int timer_cnt; diff --git a/DSView/pv/widgets/decodergroupbox.cpp b/DSView/pv/widgets/decodergroupbox.cpp index 7f90ad0d..3b4ec20a 100644 --- a/DSView/pv/widgets/decodergroupbox.cpp +++ b/DSView/pv/widgets/decodergroupbox.cpp @@ -33,7 +33,7 @@ namespace widgets { DecoderGroupBox::DecoderGroupBox(QString title, QWidget *parent) : QWidget(parent), _layout(new QGridLayout), - _show_hide_button(QIcon(":/icons/decoder-shown.png"), QString(), this) + _show_hide_button(QIcon(":/icons/shown.png"), QString(), this) { _layout->setContentsMargins(0, 0, 0, 0); setLayout(_layout); @@ -61,8 +61,8 @@ void DecoderGroupBox::add_layout(QLayout *layout) void DecoderGroupBox::set_decoder_visible(bool visible) { _show_hide_button.setIcon(QIcon(visible ? - ":/icons/decoder-shown.png" : - ":/icons/decoder-hidden.png")); + ":/icons/shown.png" : + ":/icons/hidden.png")); } } // widgets diff --git a/DSView/res/DSCope.bin b/DSView/res/DSCope.bin index 6b7e2124..505dbb74 100644 Binary files a/DSView/res/DSCope.bin and b/DSView/res/DSCope.bin differ diff --git a/DSView/res/DSLogic33.bin b/DSView/res/DSLogic33.bin index 61d0846d..849cd1df 100644 Binary files a/DSView/res/DSLogic33.bin and b/DSView/res/DSLogic33.bin differ diff --git a/DSView/res/DSLogic50.bin b/DSView/res/DSLogic50.bin index cb68b89c..afb8b0ae 100644 Binary files a/DSView/res/DSLogic50.bin and b/DSView/res/DSLogic50.bin differ diff --git a/DSView/res/DSLogicPro.bin b/DSView/res/DSLogicPro.bin index 3b13b479..c2bfdfae 100644 Binary files a/DSView/res/DSLogicPro.bin and b/DSView/res/DSLogicPro.bin differ diff --git a/INSTALL b/INSTALL index a75cb551..1ac01f09 100644 --- a/INSTALL +++ b/INSTALL @@ -49,7 +49,7 @@ Arch: Step2: Get the DSView source code - $ clone git://github.com/DreamSourceLab/DSView + $ git clone git://github.com/DreamSourceLab/DSView Step3: Building diff --git a/NEWS b/NEWS index 352fb1e4..7dd920f8 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,26 @@ +0.95 (2015-12-14) +----------------- + --for logic analyzer + *add RLE compress mode + *improve mode setting strategy, fix channel number + *add edge count function + *fix memory leakage when run protocol decoder + *add signal height setting, improve display issue + *fix crash issue when add group signal + *fix channel enable/disable issue + *fix channel display issue when load file input + *add cursor by mouse double-click + *fix other issues + + --for oscilloscope + *add file export/load function + *fix wait time issue when trigger setted + *improve display of signal measure + *add Vrms/Vmean/Vp-p measure + *fix setting issue when load session + *imporve add/del of measure ruler + *fix other issues + 0.94 (2015-06-29) ----------------- * add session load/store function diff --git a/libsigrok4DSL/dsdevice.c b/libsigrok4DSL/dsdevice.c index ec0346f6..cbc56591 100644 --- a/libsigrok4DSL/dsdevice.c +++ b/libsigrok4DSL/dsdevice.c @@ -47,7 +47,7 @@ */ /** @private */ -SR_PRIV struct sr_channel *sr_channel_new(int index, int type, +SR_PRIV struct sr_channel *sr_channel_new(uint16_t index, int type, gboolean enabled, const char *name) { struct sr_channel *probe; @@ -156,7 +156,7 @@ SR_API int sr_dev_probe_enable(const struct sr_dev_inst *sdi, int probenum, * * @since 0.1.0 (but the API changed in 0.2.0) */ -SR_API int sr_dev_trigger_set(const struct sr_dev_inst *sdi, int probenum, +SR_API int sr_dev_trigger_set(const struct sr_dev_inst *sdi, uint16_t probenum, const char *trigger) { GSList *l; @@ -208,7 +208,7 @@ SR_API gboolean sr_dev_has_option(const struct sr_dev_inst *sdi, int key) if (!sdi || !sdi->driver || !sdi->driver->config_list) return FALSE; - if (sdi->driver->config_list(SR_CONF_DEVICE_OPTIONS, &gvar, NULL, NULL) != SR_OK) + if (sdi->driver->config_list(SR_CONF_DEVICE_OPTIONS, &gvar, sdi, NULL) != SR_OK) return FALSE; ret = FALSE; diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index 07b3bc3f..26191168 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -52,6 +52,8 @@ static const char *opmodes[] = { "DRAM Loopback Test", }; +static uint16_t opmodes_show_count = 2; + static const char *thresholds[] = { "1.8/2.5/3.3V Level", "5.0V Level", @@ -254,7 +256,7 @@ static int fpga_setting(const struct sr_dev_inst *sdi) ((devc->op_mode == SR_OP_EXTERNAL_TEST) << 14) + ((devc->op_mode == SR_OP_LOOPBACK_TEST) << 13) + trigger->trigger_en + - ((sdi->mode > 0) << 4) + (devc->clock_type << 1) + (devc->clock_edge << 1) + + ((sdi->mode > 0) << 4) + (devc->clock_type << 1) + (devc->clock_edge << 2) + (((devc->cur_samplerate == SR_MHZ(200) && sdi->mode != DSO) || (sdi->mode == ANALOG)) << 5) + ((devc->cur_samplerate == SR_MHZ(400)) << 6) + ((sdi->mode == ANALOG) << 7) + @@ -579,7 +581,7 @@ static struct DSL_context *DSCope_dev_new(void) devc->clock_type = FALSE; devc->clock_edge = FALSE; devc->instant = FALSE; - devc->op_mode = SR_OP_NORMAL; + devc->op_mode = SR_OP_BUFFER; devc->th_level = SR_TH_3V3; devc->filter = SR_FILTER_NONE; devc->timebase = 10000; @@ -606,7 +608,7 @@ static int init(struct sr_context *sr_ctx) static int set_probes(struct sr_dev_inst *sdi, int num_probes) { - int j; + uint16_t j; struct sr_channel *probe; for (j = 0; j < num_probes; j++) { @@ -627,7 +629,7 @@ static int set_probes(struct sr_dev_inst *sdi, int num_probes) static int adjust_probes(struct sr_dev_inst *sdi, int num_probes) { - int j; + uint16_t j; GSList *l; struct sr_channel *probe; GSList *p; @@ -1298,6 +1300,11 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, return SR_ERR; *data = g_variant_new_uint64(DSCOPE_MAX_DEPTH); break; + case SR_CONF_RLE_SAMPLELIMITS: + if (!sdi) + return SR_ERR; + *data = g_variant_new_uint64(DSCOPE_MAX_DEPTH); + break; default: return SR_ERR_NA; } @@ -1386,8 +1393,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } else if (id == SR_CONF_OPERATION_MODE) { stropt = g_variant_get_string(data, NULL); ret = SR_OK; - if (!strcmp(stropt, opmodes[SR_OP_NORMAL])) { - devc->op_mode = SR_OP_NORMAL; + if (!strcmp(stropt, opmodes[SR_OP_BUFFER])) { + devc->op_mode = SR_OP_BUFFER; } else if (!strcmp(stropt, opmodes[SR_OP_INTERNAL_TEST])) { devc->op_mode = SR_OP_INTERNAL_TEST; } else if (!strcmp(stropt, opmodes[SR_OP_EXTERNAL_TEST])) { @@ -1483,10 +1490,10 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_VPOS)); } if (ret == SR_OK) - sr_dbg("%s: setting VPOS of channel %d to %d mv", + sr_dbg("%s: setting VPOS of channel %d to %lf mv", __func__, ch->index, ch->vpos); else - sr_dbg("%s: setting VPOS of channel %d to %d mv failed", + sr_dbg("%s: setting VPOS of channel %d to %lf mv failed", __func__, ch->index, ch->vpos); } else if (id == SR_CONF_TIMEBASE) { devc->timebase = g_variant_get_uint64(data); @@ -1651,7 +1658,7 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, *data = g_variant_new_string(TRIGGER_TYPE); break; case SR_CONF_OPERATION_MODE: - *data = g_variant_new_strv(opmodes, ARRAY_SIZE(opmodes)); + *data = g_variant_new_strv(opmodes, opmodes_show_count); break; case SR_CONF_THRESHOLD: *data = g_variant_new_strv(thresholds, ARRAY_SIZE(thresholds)); @@ -1936,7 +1943,8 @@ static void receive_transfer(struct libusb_transfer *transfer) mstatus.ch1_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 14/2); mstatus.vlen = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x7fffffff; mstatus.stream_mode = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x80000000; - mstatus.sample_divider = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2); + mstatus.sample_divider = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2) & 0x7fffffff; + mstatus.sample_divider_tog = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2) & 0x80000000; mstatus.zeroing = (*((const uint16_t*)cur_buf + mstatus_offset + 128) & 0x8000) != 0; mstatus.ch0_vpos_mid = *((const uint16_t*)cur_buf + mstatus_offset + 128) & 0x7fff; mstatus.ch0_voff_mid = *((const uint16_t*)cur_buf + mstatus_offset + 129); @@ -1970,8 +1978,10 @@ static void receive_transfer(struct libusb_transfer *transfer) dso.mq = SR_MQ_VOLTAGE; dso.unit = SR_UNIT_VOLT; dso.mqflags = SR_MQFLAG_AC; + dso.samplerate_tog = mstatus.sample_divider_tog; dso.data = cur_buf + trigger_offset_bytes; } else { + packet.type = SR_DF_ABANDON; mstatus_valid = FALSE; } } else { @@ -2026,7 +2036,8 @@ static void receive_transfer(struct libusb_transfer *transfer) } /* send data to session bus */ - sr_session_send(devc->cb_data, &packet); + if (packet.type != SR_DF_ABANDON) + sr_session_send(devc->cb_data, &packet); } devc->num_samples += cur_sample_count; diff --git a/libsigrok4DSL/hardware/DSL/dsl.h b/libsigrok4DSL/hardware/DSL/dsl.h index a83a43a0..2a693e70 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.h +++ b/libsigrok4DSL/hardware/DSL/dsl.h @@ -61,8 +61,8 @@ #define MAX_ANALOG_PROBES_NUM 9 #define MAX_DSO_PROBES_NUM 2 -#define DEFAULT_SAMPLERATE SR_MHZ(100) -#define DEFAULT_SAMPLELIMIT SR_MB(16) +#define DEFAULT_SAMPLERATE SR_MHZ(1) +#define DEFAULT_SAMPLELIMIT SR_MB(1) #define VPOS_MINISTEP 0.083 #define VPOS_STEP 26.0 @@ -150,13 +150,17 @@ struct DSL_context { /* Device/capture settings */ uint64_t cur_samplerate; uint64_t limit_samples; + uint64_t actual_samples; /* Operational settings */ gboolean sample_wide; gboolean clock_type; gboolean clock_edge; + gboolean rle_mode; gboolean instant; uint16_t op_mode; + uint16_t ch_mode; + uint16_t samplerates_size; uint16_t th_level; double vth; uint16_t filter; @@ -165,6 +169,7 @@ struct DSL_context { int trigger_stage; uint16_t trigger_buffer[NUM_TRIGGER_STAGES]; uint64_t timebase; + uint8_t max_height; uint8_t trigger_slope; uint8_t trigger_source; uint8_t trigger_hrate; diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index e50092c5..2250da53 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -52,12 +52,37 @@ static struct sr_dev_mode pro_mode_list[] = { }; static const char *opmodes[] = { - "Normal", + "Buffer Mode", + "Stream Mode", "Internal Test", "External Test", "DRAM Loopback Test", }; +static uint16_t opmodes_show_count = 3; + +static const char *stream_ch_modes[] = { + "Use Channels 0~15 (Max 10MHz)", + "Use Channels 0~7 (Max 25MHz)", +}; + +static const uint16_t stream_ch_num[] = { + 16, + 8, +}; + +static const char *buffer_ch_modes[] = { + "Use Channels 0~15 (Max 100MHz)", + "Use Channels 0~7 (Max 200MHz)", + "Use Channels 0~3 (Max 400MHz)", +}; + +static const uint16_t buffer_ch_num[] = { + 16, + 8, + 4, +}; + static const char *thresholds[] = { "1.8/2.5/3.3V Level", "5.0V Level", @@ -68,6 +93,14 @@ static const char *filters[] = { "1 Sample Clock", }; +static const char *maxHeights[] = { + "1X", + "2X", + "3X", + "4X", + "5X", +}; + static const int32_t hwopts[] = { SR_CONF_CONN, }; @@ -86,6 +119,7 @@ static const int32_t hwoptions[] = { SR_CONF_OPERATION_MODE, SR_CONF_THRESHOLD, SR_CONF_FILTER, + SR_CONF_MAX_HEIGHT, SR_CONF_CLOCK_TYPE, SR_CONF_CLOCK_EDGE, }; @@ -94,6 +128,7 @@ static const int32_t hwoptions_pro[] = { SR_CONF_OPERATION_MODE, SR_CONF_VTH, SR_CONF_FILTER, + SR_CONF_MAX_HEIGHT, SR_CONF_CLOCK_TYPE, SR_CONF_CLOCK_EDGE, }; @@ -104,6 +139,7 @@ static const int32_t sessions[] = { SR_CONF_CLOCK_TYPE, SR_CONF_CLOCK_EDGE, SR_CONF_OPERATION_MODE, + SR_CONF_CHANNEL_MODE, SR_CONF_THRESHOLD, SR_CONF_FILTER, SR_CONF_TRIGGER_SLOPE, @@ -118,6 +154,7 @@ static const int32_t sessions_pro[] = { SR_CONF_CLOCK_TYPE, SR_CONF_CLOCK_EDGE, SR_CONF_OPERATION_MODE, + SR_CONF_CHANNEL_MODE, SR_CONF_VTH, SR_CONF_FILTER, SR_CONF_TRIGGER_SLOPE, @@ -196,7 +233,6 @@ static const uint64_t samplecounts[] = { SR_MB(128), SR_MB(256), SR_MB(512), - SR_GB(1), }; static const uint8_t zero_base_addr = 0x80; @@ -311,6 +347,12 @@ static int fpga_setting(const struct sr_dev_inst *sdi) if (channel_en_cnt == 0) channel_en_cnt = 1; + devc->rle_mode = FALSE; + if (sdi->mode == LOGIC && + !devc->stream && + devc->limit_samples > DSLOGIC_MAX_LOGIC_DEPTH*ceil(devc->cur_samplerate * 1.0 / DSLOGIC_MAX_LOGIC_SAMPLERATE)) + devc->rle_mode = TRUE; + //setting.mode = (test_mode ? 0x8000 : 0x0000) + trigger->trigger_en + (sdi->mode << 4); setting.mode = ((devc->op_mode == SR_OP_INTERNAL_TEST) << 15) + ((devc->op_mode == SR_OP_EXTERNAL_TEST) << 14) + @@ -318,9 +360,10 @@ static int fpga_setting(const struct sr_dev_inst *sdi) ((devc->stream) << 12) + ((trigger->trigger_mode == SERIAL_TRIGGER) << 11) + trigger->trigger_en + - ((sdi->mode > 0) << 4) + (devc->clock_type << 1) + (devc->clock_edge << 1) + - (((channel_cnt == 8 && sdi->mode != DSO) || (sdi->mode == ANALOG)) << 5) + - ((channel_cnt == 4) << 6) + + ((sdi->mode > 0) << 4) + (devc->clock_type << 1) + (devc->clock_edge << 2) + + (devc->rle_mode << 3) + + ((((devc->cur_samplerate == (2 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) && sdi->mode != DSO) || (sdi->mode == ANALOG)) << 5) + + ((devc->cur_samplerate == (4 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) << 6) + ((sdi->mode == ANALOG) << 7) + ((devc->filter == SR_FILTER_1T) << 8) + (devc->instant << 9) + (devc->zero << 10); @@ -459,6 +502,7 @@ static int fpga_config(struct libusb_device_handle *hdl, const char *filename) offset += chunksize; } fclose(fw); + g_free(buf); if (result == SR_OK) sr_info("FPGA configure done"); @@ -596,12 +640,6 @@ static int configure_probes(const struct sr_dev_inst *sdi) if (probe->enabled == FALSE) continue; - if ((probe->index > 7 && probe->type == SR_CHANNEL_LOGIC) || - (probe->type == SR_CHANNEL_ANALOG || probe->type == SR_CHANNEL_DSO)) - devc->sample_wide = TRUE; - else - devc->sample_wide = FALSE; - probe_bit = 1 << (probe->index); if (!(probe->trigger)) continue; @@ -642,11 +680,14 @@ static struct DSL_context *DSLogic_dev_new(void) devc->fw_updated = 0; devc->cur_samplerate = DEFAULT_SAMPLERATE; devc->limit_samples = DEFAULT_SAMPLELIMIT; - devc->sample_wide = 0; + devc->sample_wide = TRUE; devc->clock_type = FALSE; devc->clock_edge = FALSE; + devc->rle_mode = FALSE; devc->instant = FALSE; - devc->op_mode = SR_OP_NORMAL; + devc->op_mode = SR_OP_BUFFER; + devc->ch_mode = 0; + devc->samplerates_size = 14; devc->th_level = SR_TH_3V3; devc->vth = 1.0; devc->filter = SR_FILTER_NONE; @@ -660,6 +701,7 @@ static struct DSL_context *DSLogic_dev_new(void) devc->stream = FALSE; devc->mstatus_valid = FALSE; devc->data_lock = FALSE; + devc->max_height = 1; return devc; } @@ -676,7 +718,7 @@ static int init(struct sr_context *sr_ctx) static int set_probes(struct sr_dev_inst *sdi, int num_probes) { - int j; + uint16_t j; struct sr_channel *probe; for (j = 0; j < num_probes; j++) { @@ -686,6 +728,7 @@ static int set_probes(struct sr_dev_inst *sdi, int num_probes) if (sdi->mode == DSO) { probe->vdiv = 1000; probe->vfactor = 1; + probe->vpos = 0; probe->coupling = SR_DC_COUPLING; probe->trig_value = 0x80; } @@ -696,7 +739,7 @@ static int set_probes(struct sr_dev_inst *sdi, int num_probes) static int adjust_probes(struct sr_dev_inst *sdi, int num_probes) { - int j; + uint16_t j; GSList *l; struct sr_channel *probe; GSList *p; @@ -812,9 +855,11 @@ static GSList *scan(GSList *options) sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); } else { - char *firmware = malloc(strlen(config_path)+strlen(prof->firmware)+1); - if (firmware == NULL) + char *firmware; + if (!(firmware = g_try_malloc(strlen(config_path)+strlen(prof->firmware)+1))) { + sr_err("Firmware path malloc error!"); return NULL; + } strcpy(firmware, config_path); strcat(firmware, prof->firmware); if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, @@ -824,6 +869,7 @@ static GSList *scan(GSList *options) else sr_err("Firmware upload failed for " "device %d.", devcnt); + g_free(firmware); sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new (libusb_get_bus_number(devlist[i]), 0xff, NULL); @@ -1060,9 +1106,11 @@ static int dev_open(struct sr_dev_inst *sdi) } else { /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ g_usleep(10 * 1000); - char *fpga_bit = malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1); - if (fpga_bit == NULL) + char *fpga_bit; + if (!(fpga_bit = g_try_malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1))) { + sr_err("fpag_bit path malloc error!"); return SR_ERR_MALLOC; + } strcpy(fpga_bit, config_path); switch(devc->th_level) { case SR_TH_3V3: @@ -1078,6 +1126,7 @@ static int dev_open(struct sr_dev_inst *sdi) if (ret != SR_OK) { sr_err("Configure FPGA failed!"); } + g_free(fpga_bit); } } @@ -1154,6 +1203,12 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, devc = sdi->priv; *data = g_variant_new_uint64(devc->limit_samples); break; + case SR_CONF_ACTUAL_SAMPLES: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_uint64(devc->actual_samples); + break; case SR_CONF_SAMPLERATE: if (!sdi) return SR_ERR; @@ -1172,6 +1227,12 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, devc = sdi->priv; *data = g_variant_new_boolean(devc->clock_edge); break; + case SR_CONF_RLE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean(devc->rle_mode); + break; case SR_CONF_INSTANT: if (!sdi) return SR_ERR; @@ -1184,11 +1245,21 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, devc = sdi->priv; *data = g_variant_new_string(opmodes[devc->op_mode]); break; + case SR_CONF_CHANNEL_MODE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + if (devc->stream) + *data = g_variant_new_string(stream_ch_modes[devc->ch_mode]); + else + *data = g_variant_new_string(buffer_ch_modes[devc->ch_mode]); + break; case SR_CONF_TEST: if (!sdi) return SR_ERR; devc = sdi->priv; - *data = g_variant_new_boolean(devc->op_mode != SR_OP_NORMAL); + *data = g_variant_new_boolean((devc->op_mode != SR_OP_BUFFER) && + (devc->op_mode != SR_OP_STREAM)); break; case SR_CONF_FILTER: if (!sdi) @@ -1196,6 +1267,18 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, devc = sdi->priv; *data = g_variant_new_string(filters[devc->filter]); break; + case SR_CONF_MAX_HEIGHT: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_string(maxHeights[devc->max_height]); + break; + case SR_CONF_MAX_HEIGHT_VALUE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_byte(devc->max_height); + break; case SR_CONF_THRESHOLD: if (!sdi) return SR_ERR; @@ -1218,6 +1301,11 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, return SR_ERR; *data = g_variant_new_uint64(ch->vfactor); break; + case SR_CONF_VPOS: + if (!ch) + return SR_ERR; + *data = g_variant_new_double(ch->vpos); + break; case SR_CONF_TIMEBASE: if (!sdi) return SR_ERR; @@ -1306,11 +1394,19 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_MAX_LOGIC_SAMPLELIMITS: if (!sdi) return SR_ERR; - *data = g_variant_new_uint64(DSLOGIC_MAX_LOGIC_DEPTH); + devc = sdi->priv; + *data = g_variant_new_uint64(DSLOGIC_MAX_LOGIC_DEPTH*ceil(devc->cur_samplerate * 1.0 / DSLOGIC_MAX_LOGIC_SAMPLERATE)); + break; + case SR_CONF_RLE_SAMPLELIMITS: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_uint64(DSLOGIC_MAX_LOGIC_DEPTH*ceil(samplerates[devc->samplerates_size-1] * 1.0 / DSLOGIC_MAX_LOGIC_SAMPLERATE)); break; case SR_CONF_STATUS: if (!sdi) return SR_ERR; + devc = sdi->priv; *data = g_variant_new_boolean(devc->status != DSL_INIT); break; default: @@ -1328,6 +1424,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, const char *stropt; int ret, num_probes; struct sr_usb_dev_inst *usb; + int i; (void)cg; @@ -1339,37 +1436,22 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, if (id == SR_CONF_SAMPLERATE) { devc->cur_samplerate = g_variant_get_uint64(data); - if (sdi->mode == LOGIC) { - if (devc->limit_samples > DSLOGIC_MAX_LOGIC_DEPTH) { - if (devc->cur_samplerate > SR_MHZ(25)) { - devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; - } else if (devc->cur_samplerate >= SR_MHZ(20) || - devc->limit_samples >= SR_GB(1)) { - adjust_probes(sdi, 8); - } else { - adjust_probes(sdi, 16); - } - } - - if (devc->limit_samples <= DSLOGIC_MAX_LOGIC_DEPTH) { - if (devc->cur_samplerate >= SR_MHZ(200)) { - adjust_probes(sdi, SR_MHZ(1600)/devc->cur_samplerate); - } else { - adjust_probes(sdi, 16); - } - } - - ret = SR_OK; - } else if(sdi->mode == DSO) { + if(sdi->mode == DSO) { + devc->sample_wide = (devc->cur_samplerate <= DSLOGIC_MAX_DSO_SAMPLERATE); ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); + } else { + devc->sample_wide = (devc->cur_samplerate <= DSLOGIC_MAX_LOGIC_SAMPLERATE); + ret = SR_OK; } - } else if (id == SR_CONF_CLOCK_TYPE) { devc->clock_type = g_variant_get_boolean(data); ret = SR_OK; } else if (id == SR_CONF_CLOCK_EDGE) { devc->clock_edge = g_variant_get_boolean(data); ret = SR_OK; + } else if (id == SR_CONF_RLE) { + devc->rle_mode = g_variant_get_boolean(data); + ret = SR_OK; } else if (id == SR_CONF_INSTANT) { if (sdi->mode == DSO) { devc->instant = g_variant_get_boolean(data); @@ -1494,25 +1576,84 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } else if (id == SR_CONF_OPERATION_MODE) { stropt = g_variant_get_string(data, NULL); ret = SR_OK; - if (!strcmp(stropt, opmodes[SR_OP_NORMAL])) { - devc->op_mode = SR_OP_NORMAL; - } else if (!strcmp(stropt, opmodes[SR_OP_INTERNAL_TEST])) { - devc->op_mode = SR_OP_INTERNAL_TEST; - devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; - devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; - } else if (!strcmp(stropt, opmodes[SR_OP_EXTERNAL_TEST])) { - devc->op_mode = SR_OP_EXTERNAL_TEST; - devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; - devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; - } else if (!strcmp(stropt, opmodes[SR_OP_LOOPBACK_TEST])) { - devc->op_mode = SR_OP_LOOPBACK_TEST; - devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; - devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; - } else { - ret = SR_ERR; + if (sdi->mode == LOGIC) { + if (!strcmp(stropt, opmodes[SR_OP_BUFFER]) && (devc->op_mode != SR_OP_BUFFER)) { + devc->op_mode = SR_OP_BUFFER; + devc->stream = FALSE; + devc->ch_mode = 0; + devc->samplerates_size = 14; + adjust_probes(sdi, buffer_ch_num[0]); + } else if (!strcmp(stropt, opmodes[SR_OP_STREAM]) && (devc->op_mode != SR_OP_STREAM)) { + devc->op_mode = SR_OP_STREAM; + devc->stream = TRUE; + devc->ch_mode = 0; + devc->samplerates_size = 10; + adjust_probes(sdi, stream_ch_num[0]); + } else if (!strcmp(stropt, opmodes[SR_OP_INTERNAL_TEST]) && (devc->op_mode != SR_OP_INTERNAL_TEST)) { + devc->op_mode = SR_OP_INTERNAL_TEST; + devc->stream = FALSE; + devc->ch_mode = 0; + devc->samplerates_size = 14; + adjust_probes(sdi, buffer_ch_num[0]); + devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; + devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; + devc->sample_wide = TRUE; + } else if (!strcmp(stropt, opmodes[SR_OP_EXTERNAL_TEST]) && (devc->op_mode != SR_OP_EXTERNAL_TEST)) { + devc->op_mode = SR_OP_EXTERNAL_TEST; + devc->stream = FALSE; + devc->ch_mode = 0; + devc->samplerates_size = 14; + adjust_probes(sdi, buffer_ch_num[0]); + devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; + devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; + devc->sample_wide = TRUE; + } else if (!strcmp(stropt, opmodes[SR_OP_LOOPBACK_TEST]) && (devc->op_mode != SR_OP_LOOPBACK_TEST)) { + devc->op_mode = SR_OP_LOOPBACK_TEST; + devc->stream = FALSE; + devc->ch_mode = 0; + devc->samplerates_size = 14; + adjust_probes(sdi, buffer_ch_num[0]); + devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; + devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; + devc->sample_wide = TRUE; + } else { + ret = SR_ERR; + } + if (devc->cur_samplerate > samplerates[devc->samplerates_size-1]) { + devc->cur_samplerate = samplerates[devc->samplerates_size-1]; + devc->sample_wide = (devc->cur_samplerate <= DSLOGIC_MAX_DSO_SAMPLERATE); + } } sr_dbg("%s: setting pattern to %d", __func__, devc->op_mode); + } else if (id == SR_CONF_CHANNEL_MODE) { + stropt = g_variant_get_string(data, NULL); + ret = SR_OK; + if (sdi->mode == LOGIC) { + if (devc->stream) { + for (i = 0; i < ARRAY_SIZE(stream_ch_modes); i++) + if (!strcmp(stropt, stream_ch_modes[i])) { + devc->ch_mode = i; + devc->samplerates_size = 10 + i * 2; + adjust_probes(sdi, stream_ch_num[i]); + break; + } + } else { + for (i = 0; i < ARRAY_SIZE(buffer_ch_modes); i++) + if (!strcmp(stropt, buffer_ch_modes[i])) { + devc->ch_mode = i; + devc->samplerates_size = 14 + i; + adjust_probes(sdi, buffer_ch_num[i]); + break; + } + } + if (devc->cur_samplerate > samplerates[devc->samplerates_size-1]) { + devc->cur_samplerate = samplerates[devc->samplerates_size-1]; + devc->sample_wide = (devc->cur_samplerate <= DSLOGIC_MAX_DSO_SAMPLERATE); + } + } + sr_dbg("%s: setting channel mode to %d", + __func__, devc->ch_mode); } else if (id == SR_CONF_THRESHOLD) { stropt = g_variant_get_string(data, NULL); ret = SR_OK; @@ -1523,28 +1664,33 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } else { ret = SR_ERR; } - if ((ret = command_fpga_config(usb->devhdl)) != SR_OK) { - sr_err("Send FPGA configure command failed!"); - } else { - /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ - g_usleep(10 * 1000); - char *fpga_bit = malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1); - if (fpga_bit == NULL) - return SR_ERR_MALLOC; - strcpy(fpga_bit, config_path); - switch(devc->th_level) { - case SR_TH_3V3: - strcat(fpga_bit, devc->profile->fpga_bit33);; - break; - case SR_TH_5V0: - strcat(fpga_bit, devc->profile->fpga_bit50);; - break; - default: - return SR_ERR; - } - ret = fpga_config(usb->devhdl, fpga_bit); - if (ret != SR_OK) { - sr_err("Configure FPGA failed!"); + if (sdi->mode == LOGIC) { + if ((ret = command_fpga_config(usb->devhdl)) != SR_OK) { + sr_err("Send FPGA configure command failed!"); + } else { + /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ + g_usleep(10 * 1000); + char *fpga_bit; + if (!(fpga_bit = g_try_malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1))) { + sr_err("fpag_bit path malloc error!"); + return SR_ERR_MALLOC; + } + strcpy(fpga_bit, config_path); + switch(devc->th_level) { + case SR_TH_3V3: + strcat(fpga_bit, devc->profile->fpga_bit33);; + break; + case SR_TH_5V0: + strcat(fpga_bit, devc->profile->fpga_bit50);; + break; + default: + return SR_ERR; + } + ret = fpga_config(usb->devhdl, fpga_bit); + if (ret != SR_OK) { + sr_err("Configure FPGA failed!"); + } + g_free(fpga_bit); } } sr_dbg("%s: setting threshold to %d", @@ -1570,6 +1716,17 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } sr_dbg("%s: setting threshold to %d", __func__, devc->th_level); + } else if (id == SR_CONF_MAX_HEIGHT) { + stropt = g_variant_get_string(data, NULL); + ret = SR_OK; + for (i = 0; i < ARRAY_SIZE(maxHeights); i++) { + if (!strcmp(stropt, maxHeights[i])) { + devc->max_height = i; + break; + } + } + sr_dbg("%s: setting Signal Max Height to %d", + __func__, devc->max_height); } else if (id == SR_CONF_EN_CH) { ch->enabled = g_variant_get_boolean(data); if (sdi->mode == DSO) { @@ -1724,11 +1881,13 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { + struct DSL_context *devc; GVariant *gvar; GVariantBuilder gvb; //(void)sdi; (void)cg; + devc = sdi->priv; switch (key) { case SR_CONF_SCAN_OPTIONS: @@ -1766,7 +1925,7 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, // gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates, // ARRAY_SIZE(samplerates), sizeof(uint64_t)); gvar = g_variant_new_from_data(G_VARIANT_TYPE("at"), - samplerates, ARRAY_SIZE(samplerates)*sizeof(uint64_t), TRUE, NULL, NULL); + samplerates, devc->samplerates_size*sizeof(uint64_t), TRUE, NULL, NULL); g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar); *data = g_variant_builder_end(&gvb); break; @@ -1781,7 +1940,15 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, *data = g_variant_new_string(TRIGGER_TYPE); break; case SR_CONF_OPERATION_MODE: - *data = g_variant_new_strv(opmodes, ARRAY_SIZE(opmodes)); + *data = g_variant_new_strv(opmodes, opmodes_show_count); + break; + case SR_CONF_CHANNEL_MODE: + if (devc->stream) + *data = g_variant_new_strv(stream_ch_modes, ARRAY_SIZE(stream_ch_modes)); + else if (devc->op_mode != SR_OP_BUFFER) + *data = g_variant_new_strv(buffer_ch_modes, 1); + else + *data = g_variant_new_strv(buffer_ch_modes, ARRAY_SIZE(buffer_ch_modes)); break; case SR_CONF_THRESHOLD: *data = g_variant_new_strv(thresholds, ARRAY_SIZE(thresholds)); @@ -1789,6 +1956,9 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_FILTER: *data = g_variant_new_strv(filters, ARRAY_SIZE(filters)); break; + case SR_CONF_MAX_HEIGHT: + *data = g_variant_new_strv(maxHeights, ARRAY_SIZE(maxHeights)); + break; default: return SR_ERR_NA; } @@ -1919,12 +2089,7 @@ static void receive_transfer(struct libusb_transfer *transfer) /* Save incoming transfer before reusing the transfer struct. */ cur_buf = transfer->buffer; - GSList *l; - int channel_cnt = 0; - for (l = ((struct sr_dev_inst *)(devc->cb_data))->channels; l; l = l->next) - channel_cnt++; - - sample_width = (channel_cnt > 8) ? 2 : 1; + sample_width = (devc->sample_wide) ? 2 : 1; cur_sample_count = transfer->actual_length / sample_width; switch (transfer->status) { @@ -2056,7 +2221,8 @@ static void receive_transfer(struct libusb_transfer *transfer) mstatus.ch1_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 14/2); mstatus.vlen = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x7fffffff; mstatus.stream_mode = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x80000000; - mstatus.sample_divider = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2); + mstatus.sample_divider = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2) & 0x7fffffff; + mstatus.sample_divider_tog = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2) & 0x80000000; mstatus.zeroing = (*((const uint16_t*)cur_buf + mstatus_offset + 128) & 0x8000) != 0; mstatus.ch0_adc_off = *((const uint8_t*)cur_buf + mstatus_offset*2 + 131*2); mstatus.ch0_adc_sign = *((const uint8_t*)cur_buf + mstatus_offset*2 + 131*2+1); @@ -2083,6 +2249,7 @@ static void receive_transfer(struct libusb_transfer *transfer) dso.mq = SR_MQ_VOLTAGE; dso.unit = SR_UNIT_VOLT; dso.mqflags = SR_MQFLAG_AC; + dso.samplerate_tog = mstatus.sample_divider_tog; dso.data = cur_buf + trigger_offset_bytes; } else { devc->mstatus_valid = FALSE; @@ -2091,16 +2258,16 @@ static void receive_transfer(struct libusb_transfer *transfer) packet.type = SR_DF_ANALOG; packet.payload = &analog; analog.probes = (*(struct sr_dev_inst *)(devc->cb_data)).channels; - analog.num_samples = transfer->actual_length / sample_width; + analog.num_samples = (transfer->actual_length / sample_width)/g_slist_length(analog.probes); analog.mq = SR_MQ_VOLTAGE; analog.unit = SR_UNIT_VOLT; analog.mqflags = SR_MQFLAG_AC; analog.data = cur_buf + trigger_offset_bytes; } - if ((devc->limit_samples && devc->num_samples < devc->limit_samples) || + if ((devc->limit_samples && devc->num_samples < devc->actual_samples) || (*(struct sr_dev_inst *)(devc->cb_data)).mode != LOGIC ) { - const uint64_t remain_length= (devc->limit_samples - devc->num_samples) * sample_width; + const uint64_t remain_length= (devc->actual_samples - devc->num_samples) * sample_width; logic.length = min(logic.length, remain_length); /* in test mode, check data content*/ @@ -2145,9 +2312,9 @@ static void receive_transfer(struct libusb_transfer *transfer) } devc->num_samples += cur_sample_count; - if (((*(struct sr_dev_inst *)(devc->cb_data)).mode == LOGIC || devc->instant) && + if (((*(struct sr_dev_inst *)(devc->cb_data)).mode == LOGIC || devc->instant) && devc->limit_samples && - (unsigned int)devc->num_samples >= devc->limit_samples) { + (unsigned int)devc->num_samples >= devc->actual_samples) { //abort_acquisition(devc); free_transfer(transfer); devc->status = DSL_STOP; @@ -2234,13 +2401,6 @@ static int dev_transfer_start(const struct sr_dev_inst *sdi) else dso_buffer_size = devc->limit_samples * channel_en_cnt + 512; -// if (sdi->mode == DSO) { -// timeout = 500; -// num_transfers = buffer_cnt; -// } else { -// timeout = get_timeout(devc); -// num_transfers = get_number_of_transfers(devc); -// } num_transfers = 1; size = (sdi->mode == ANALOG) ? cons_buffer_size : ((sdi->mode == DSO) ? dso_buffer_size : get_buffer_size(devc)); @@ -2327,14 +2487,22 @@ static void receive_trigger_pos(struct libusb_transfer *transfer) switch (transfer->status) { case LIBUSB_TRANSFER_COMPLETED: if (transfer->actual_length == sizeof(struct ds_trigger_pos)) { - packet.type = SR_DF_TRIGGER; - packet.payload = trigger_pos; - sr_session_send(devc->cb_data, &packet); + if (devc->stream || trigger_pos->remain_cnt < devc->limit_samples) { + if (!devc->stream) + devc->actual_samples = (devc->limit_samples - ceil(devc->cur_samplerate * 1.0 / DSLOGIC_MAX_LOGIC_SAMPLERATE) * (trigger_pos->remain_cnt)); - devc->status = DSL_TRIGGERED; - free_transfer(transfer); - devc->num_transfers = 0; - devc->empty_transfer_count = 0; + packet.type = SR_DF_TRIGGER; + packet.payload = trigger_pos; + sr_session_send(devc->cb_data, &packet); + + devc->status = DSL_TRIGGERED; + free_transfer(transfer); + devc->num_transfers = 0; + devc->empty_transfer_count = 0; + } else { + free_transfer(transfer); + devc->status = DSL_ERROR; + } } else { free_transfer(transfer); devc->status = DSL_ERROR; @@ -2402,6 +2570,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) devc->status = DSL_INIT; devc->num_transfers = 0; devc->submitted_transfers = 0; + devc->actual_samples = devc->limit_samples; /* Configures devc->trigger_* and devc->sample_wide */ if (configure_probes(sdi) != SR_OK) { @@ -2447,7 +2616,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) } if ((ret = command_start_acquisition (usb->devhdl, - devc->cur_samplerate, devc->sample_wide, (sdi->mode == LOGIC))) != SR_OK) { + devc->cur_samplerate, 1, (sdi->mode == LOGIC))) != SR_OK) { abort_acquisition(devc); return ret; } diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index 56a3a90f..a31467a5 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -56,9 +56,9 @@ #define CONST_LEN 50 -#define DEMO_MAX_LOGIC_DEPTH SR_MB(1) -#define DEMO_MAX_LOGIC_SAMPLERATE SR_MHZ(100) -#define DEMO_MAX_DSO_DEPTH SR_KB(32) +#define DEMO_MAX_LOGIC_DEPTH SR_MB(100) +#define DEMO_MAX_LOGIC_SAMPLERATE SR_MHZ(400) +#define DEMO_MAX_DSO_DEPTH SR_KB(20) #define DEMO_MAX_DSO_SAMPLERATE SR_MHZ(200) #define DEMO_MAX_DSO_PROBES_NUM 2 @@ -78,6 +78,14 @@ static const char *pattern_strings[] = { "Random", }; +static const char *maxHeights[] = { + "1X", + "2X", + "3X", + "4X", + "5X", +}; + static struct sr_dev_mode mode_list[] = { {"LA", LOGIC}, {"DAQ", ANALOG}, @@ -100,6 +108,11 @@ struct dev_context { uint64_t timebase; gboolean instant; gboolean data_lock; + uint8_t max_height; + + uint16_t *buf; + uint64_t pre_index; + struct sr_status mstatus; int trigger_stage; uint16_t trigger_mask; @@ -119,6 +132,7 @@ static const int hwcaps[] = { static const int hwoptions[] = { SR_CONF_PATTERN_MODE, + SR_CONF_MAX_HEIGHT, }; static const int32_t sessions[] = { @@ -127,8 +141,79 @@ static const int32_t sessions[] = { SR_CONF_PATTERN_MODE, }; +static const int const_dc = 50; +static const int sinx[] = { + 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 18, 20, 21, 23, 24, 26, 27, 28, + 30, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 41, 42, 43, 44, 45, 45, 46, 47, 47, + 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 49, 49, 49, 48, 48, + 47, 47, 46, 46, 45, 44, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 31, 30, + 29, 28, 26, 25, 24, 22, 21, 19, 18, 16, 15, 13, 12, 10, 9, 7, 6, 4, 2, 1, + -1, -2, -4, -6, -7, -9, -10, -12, -13, -15, -16, -18, -19, -21, -22, -24, -25, -26, -28, -29, +-30, -31, -33, -34, -35, -36, -37, -38, -39, -40, -41, -42, -43, -44, -44, -45, -46, -46, -47, -47, +-48, -48, -49, -49, -49, -50, -50, -50, -50, -50, -50, -50, -50, -50, -49, -49, -49, -49, -48, -48, +-47, -47, -46, -45, -45, -44, -43, -42, -41, -41, -40, -39, -38, -37, -35, -34, -33, -32, -31, -30, +-28, -27, -26, -24, -23, -21, -20, -18, -17, -16, -14, -12, -11, -9, -8, -6, -5, -3, -2, 0, +}; + +static const int sqrx[] = { + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +-50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, +-50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, +-50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, +-50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, +-50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, +}; + +static const int trix[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, + 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, + 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, + 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, +-20, -21, -22, -23, -24, -25, -26, -27, -28, -29, -30, -31, -32, -33, -34, -35, -36, -37, -38, -39, +-40, -41, -42, -43, -44, -45, -46, -47, -48, -49, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, +-40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, +-20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, +}; + +static const int sawx[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, + 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, + 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, + 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, + 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 50, +-50, -49, -48, -48, -47, -47, -46, -46, -45, -45, -44, -44, -43, -43, -42, -42, -41, -41, -40, -40, +-39, -39, -38, -38, -37, -37, -36, -36, -35, -35, -34, -34, -33, -33, -32, -32, -31, -31, -30, -30, +-29, -29, -28, -28, -27, -27, -26, -26, -25, -25, -24, -24, -23, -23, -22, -22, -21, -21, -20, -20, +-19, -19, -18, -18, -17, -17, -16, -16, -15, -15, -14, -14, -13, -13, -12, -12, -11, -11, -10, -10, + -9, -9, -8, -8, -7, -7, -6, -6, -5, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0, 0, +}; + +static const int ranx[] = { + -4, 47, -49, -1, -3, 6, -29, 26, 1, 14, -39, -38, 36, 17, 26, -37, -2, 27, -20, -15, +-49, -46, 36, 16, 29, 23, -30, -3, 28, -2, -6, 46, 43, 50, -42, 30, 48, -50, -38, -30, + 7, -36, -20, -24, -10, -34, -24, 3, -48, 46, -11, 22, 19, 28, 39, -49, -31, 34, 2, -29, + 9, 35, 8, 10, 38, 30, 17, 48, -3, -6, -28, 46, -19, 18, -43, -9, -31, -32, -41, 16, +-10, 46, -4, 4, -32, -43, -45, -39, -33, 28, 24, -17, -43, 42, -7, 36, -44, -5, 9, 39, + 17, -40, 12, 16, -42, -1, 2, -9, 50, -8, 27, 27, 14, 8, -18, 12, -8, 26, -8, 12, +-35, 49, 35, 2, -26, -24, -31, 33, 15, -47, 34, 46, -1, -12, 14, 32, -25, -31, -35, -18, +-48, -21, -5, 1, -27, -14, 12, 49, -11, 33, 31, 35, -36, 19, 20, 44, 29, -48, 14, -43, + 1, 30, -12, 44, 20, 49, 29, -43, 42, 30, -34, 24, 20, -40, 33, -12, 13, -45, 45, -24, +-41, 36, -8, 46, 47, -34, 28, -39, 7, -32, 38, -27, 28, -3, -8, 43, -37, -24, 6, 3, +}; static const uint64_t samplerates[] = { + SR_HZ(100), + SR_HZ(200), + SR_HZ(500), + SR_KHZ(1), + SR_KHZ(2), + SR_KHZ(5), SR_KHZ(10), SR_KHZ(20), SR_KHZ(50), @@ -146,25 +231,43 @@ static const uint64_t samplerates[] = { SR_MHZ(400), }; +//static const uint64_t samplecounts[] = { +// SR_KB(1), +// SR_KB(2), +// SR_KB(4), +// SR_KB(8), +// SR_KB(16), +// SR_KB(32), +// SR_KB(64), +// SR_KB(128), +// SR_KB(256), +// SR_KB(512), +// SR_MB(1), +// SR_MB(2), +// SR_MB(4), +// SR_MB(8), +// SR_MB(16), +//}; + static const uint64_t samplecounts[] = { SR_KB(1), SR_KB(2), - SR_KB(4), - SR_KB(8), - SR_KB(16), - SR_KB(32), - SR_KB(64), - SR_KB(128), - SR_KB(256), - SR_KB(512), + SR_KB(5), + SR_KB(10), + SR_KB(20), + SR_KB(50), + SR_KB(100), + SR_KB(200), + SR_KB(500), SR_MB(1), SR_MB(2), - SR_MB(4), - SR_MB(8), - SR_MB(16), + SR_MB(5), + SR_MB(10), + SR_MB(20), + SR_MB(50), + SR_MB(100), }; - /* We name the probes 0-7 on our demo driver. */ static const char *probe_names[NUM_PROBES + 1] = { "Channel 0", "Channel 1", "Channel 2", "Channel 3", @@ -204,7 +307,7 @@ static GSList *hw_scan(GSList *options) struct drv_context *drvc; struct dev_context *devc; GSList *devices; - int i; + uint16_t i; (void)options; @@ -228,12 +331,13 @@ static GSList *hw_scan(GSList *options) } devc->sdi = sdi; - devc->cur_samplerate = DEMO_MAX_LOGIC_SAMPLERATE; - devc->limit_samples = DEMO_MAX_LOGIC_DEPTH; + devc->cur_samplerate = SR_MHZ(1); + devc->limit_samples = SR_MB(1); devc->limit_msec = 0; devc->sample_generator = PATTERN_SINE; - devc->timebase = 10000; + devc->timebase = 200; devc->data_lock = FALSE; + devc->max_height = 1; sdi->priv = devc; @@ -355,6 +459,15 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_PATTERN_MODE: *data = g_variant_new_string(pattern_strings[devc->sample_generator]); break; + case SR_CONF_MAX_HEIGHT: + *data = g_variant_new_string(maxHeights[devc->max_height]); + break; + case SR_CONF_MAX_HEIGHT_VALUE: + *data = g_variant_new_byte(devc->max_height); + break; + case SR_CONF_VPOS: + *data = g_variant_new_double(ch->vpos); + break; case SR_CONF_VDIV: *data = g_variant_new_uint64(ch->vdiv); break; @@ -385,7 +498,10 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_MAX_LOGIC_SAMPLELIMITS: *data = g_variant_new_uint64(DEMO_MAX_LOGIC_DEPTH); break; - default: + case SR_CONF_RLE_SAMPLELIMITS: + *data = g_variant_new_uint64(DEMO_MAX_LOGIC_DEPTH); + break; + default: return SR_ERR_NA; } @@ -396,9 +512,11 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, struct sr_channel *ch, const struct sr_channel_group *cg) { - int i, ret; + uint16_t i; + int ret; const char *stropt; struct sr_channel *probe; + uint64_t tmp_u64; (void) cg; @@ -409,6 +527,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, if (id == SR_CONF_SAMPLERATE) { devc->cur_samplerate = g_variant_get_uint64(data); + devc->samples_counter = 0; + devc->pre_index = 0; sr_dbg("%s: setting samplerate to %" PRIu64, __func__, devc->cur_samplerate); ret = SR_OK; @@ -445,8 +565,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, else { probe->vdiv = 1000; probe->vfactor = 1; - probe->coupling = SR_DC_COUPLING; + probe->coupling = SR_AC_COUPLING; probe->trig_value = 0x80; + probe->vpos = (probe->index == 0 ? 0.5 : -0.5)*probe->vdiv; sdi->channels = g_slist_append(sdi->channels, probe); } } @@ -461,6 +582,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, else sdi->channels = g_slist_append(sdi->channels, probe); } + devc->cur_samplerate = SR_HZ(100); + devc->limit_samples = SR_KB(1); } else { ret = SR_ERR; } @@ -483,6 +606,17 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } sr_dbg("%s: setting pattern to %d", __func__, devc->sample_generator); + } else if (id == SR_CONF_MAX_HEIGHT) { + stropt = g_variant_get_string(data, NULL); + ret = SR_OK; + for (i = 0; i < ARRAY_SIZE(maxHeights); i++) { + if (!strcmp(stropt, maxHeights[i])) { + devc->max_height = i; + break; + } + } + sr_dbg("%s: setting Signal Max Height to %d", + __func__, devc->max_height); } else if (id == SR_CONF_INSTANT) { devc->instant = g_variant_get_boolean(data); sr_dbg("%s: setting INSTANT mode to %d", __func__, @@ -503,7 +637,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, devc->data_lock); ret = SR_OK; } else if (id == SR_CONF_VDIV) { - ch->vdiv = g_variant_get_uint64(data); + tmp_u64 = g_variant_get_uint64(data); + ch->vpos = (tmp_u64 * 1.0 / ch->vdiv) * ch->vpos; + ch->vdiv = tmp_u64; sr_dbg("%s: setting VDIV of channel %d to %" PRIu64, __func__, ch->index, ch->vdiv); ret = SR_OK; @@ -512,6 +648,11 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting FACTOR of channel %d to %" PRIu64, __func__, ch->index, ch->vfactor); ret = SR_OK; + } else if (id == SR_CONF_VPOS) { + ch->vpos = g_variant_get_double(data); + sr_dbg("%s: setting VPOS of channel %d to %lf", __func__, + ch->index, ch->vpos); + ret = SR_OK; } else if (id == SR_CONF_TIMEBASE) { devc->timebase = g_variant_get_uint64(data); sr_dbg("%s: setting TIMEBASE to %" PRIu64, __func__, @@ -574,6 +715,9 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_PATTERN_MODE: *data = g_variant_new_strv(pattern_strings, ARRAY_SIZE(pattern_strings)); break; + case SR_CONF_MAX_HEIGHT: + *data = g_variant_new_strv(maxHeights, ARRAY_SIZE(maxHeights)); + break; default: return SR_ERR_NA; } @@ -585,144 +729,106 @@ static void samples_generator(uint16_t *buf, uint64_t size, const struct sr_dev_inst *sdi, struct dev_context *devc) { - static uint16_t p = 0; - uint64_t i; - uint16_t demo_data; + uint64_t i, pre0_i, pre1_i, index; + GSList *l; + struct sr_channel *probe; + int offset; + int start_rand; + const uint64_t span = DEMO_MAX_DSO_SAMPLERATE / devc->cur_samplerate; + const uint64_t len = ARRAY_SIZE(sinx) - 1; + int *pre_buf; - switch (devc->sample_generator) { + switch (devc->sample_generator) { case PATTERN_SINE: /* Sine */ - for (i = 0; i < size; i++) { - if (i%CONST_LEN == 0) { - //demo_data = 0x8000 * sin(2 * PI * p / 0xffff) + 0x8000; - demo_data = 0x20 * (sin(2 * PI * p / 0xff) + 1); - p++; - } - GSList *l; - struct sr_channel *probe; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->coupling == SR_DC_COUPLING) - *(buf + i) += ((0x40 + demo_data) << (probe->index * 8)); - else if (probe->coupling == SR_AC_COUPLING) - *(buf + i) += ((0x60 + demo_data) << (probe->index * 8)); - else - if (probe->index == 0) { - *(buf + i) &= 0xff00; - *(buf + i) += 0x0080; - }else { - *(buf + i) &= 0x00ff; - *(buf + i) += 0x8000; - } - } - } - break; + pre_buf = sinx; + break; case PATTERN_SQUARE: - for (i = 0; i < size; i++) { - if (i%CONST_LEN == 0) { - demo_data = p > 0x7fff ? 0x4040 : 0x0000; - p += CONST_LEN * 10; - } - *(buf + i) = demo_data; - GSList *l; - struct sr_channel *probe; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->coupling == SR_DC_COUPLING) - *(buf + i) += (0x40 << (probe->index * 8)); - else if (probe->coupling == SR_AC_COUPLING) - *(buf + i) += (0x60 << (probe->index * 8)); - else - if (probe->index == 0) { - *(buf + i) &= 0xff00; - *(buf + i) += 0x0080; - }else { - *(buf + i) &= 0x00ff; - *(buf + i) += 0x8000; - } - } - } + pre_buf = sqrx; break; case PATTERN_TRIANGLE: - for (i = 0; i < size; i++) { - if (i%CONST_LEN == 0) { - demo_data = p > 0x7fff ? 0x40 * (1 + (0x8000 - p * 1.0) / 0x8000) : - 0x40 * (p * 1.0 / 0x8000); - p += CONST_LEN * 10; - } - *(buf + i) = demo_data + (demo_data << 8); - GSList *l; - struct sr_channel *probe; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->coupling == SR_DC_COUPLING) - *(buf + i) += (0x40 << (probe->index * 8)); - else if (probe->coupling == SR_AC_COUPLING) - *(buf + i) += (0x60 << (probe->index * 8)); - else - if (probe->index == 0) { - *(buf + i) &= 0xff00; - *(buf + i) += 0x0080; - }else { - *(buf + i) &= 0x00ff; - *(buf + i) += 0x8000; - } - } - } + pre_buf = trix; break; case PATTERN_SAWTOOTH: - for (i = 0; i < size; i++) { - if (i%CONST_LEN == 0) { - demo_data = p & 0x003f; - p ++; - } - *(buf + i) = demo_data + (demo_data << 8); - GSList *l; - struct sr_channel *probe; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->coupling == SR_DC_COUPLING) - *(buf + i) += (0x40 << (probe->index * 8)); - else if (probe->coupling == SR_AC_COUPLING) - *(buf + i) += (0x60 << (probe->index * 8)); - else - if (probe->index == 0) { - *(buf + i) &= 0xff00; - *(buf + i) += 0x0080; - }else { - *(buf + i) &= 0x00ff; - *(buf + i) += 0x8000; - } - } - } + pre_buf = sawx; break; - case PATTERN_RANDOM: /* Random */ + case PATTERN_RANDOM: + pre_buf = ranx; + break; + default: + pre_buf = sinx; + break; + } + + if (devc->samples_counter == devc->limit_samples && + size != devc->limit_samples) { + for (i = 0; i < devc->limit_samples; i++) + *(buf + i) = *(buf + ((i + size)%devc->limit_samples)); + } else if (sdi->mode != DSO) { + start_rand = rand()%len; for (i = 0; i < size; i++) { - if (i%CONST_LEN == 0) - demo_data = (uint16_t)(rand() * (0x40 * 1.0 / RAND_MAX)); - *(buf + i) = demo_data + (demo_data << 8); - GSList *l; - struct sr_channel *probe; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->coupling == SR_DC_COUPLING) - *(buf + i) += (0x40 << (probe->index * 8)); - else if (probe->coupling == SR_AC_COUPLING) - *(buf + i) += (0x60 << (probe->index * 8)); - else - if (probe->index == 0) { - *(buf + i) &= 0xff00; - *(buf + i) += 0x0080; - }else { - *(buf + i) &= 0x00ff; - *(buf + i) += 0x8000; + index = (i/g_slist_length(sdi->channels)+start_rand)%len; + *(buf + i) = (uint16_t)(((const_dc+pre_buf[index]) << 8) + (const_dc+pre_buf[index])); + } + } else { + if (devc->pre_index == 0) { + devc->mstatus.ch0_max = 0; + devc->mstatus.ch0_min = 255; + devc->mstatus.ch1_max = 0; + devc->mstatus.ch1_min = 255; + devc->mstatus.ch0_period = 0; + devc->mstatus.ch0_pcnt = 1; + devc->mstatus.ch1_period = 0; + devc->mstatus.ch1_pcnt = 1; + } + memset(buf+devc->pre_index, 0, size*sizeof(uint16_t)); + for (l = sdi->channels; l; l = l->next) { + start_rand = devc->pre_index == 0 ? rand()%len : 0; + probe = (struct sr_channel *)l->data; + offset = ceil((0.5 - (probe->vpos/probe->vdiv/10.0)) * 255); + pre0_i = devc->pre_index; + pre1_i = devc->pre_index; + for (i = devc->pre_index; i < devc->pre_index + size; i++) { + if (probe->coupling == SR_DC_COUPLING) { + *(buf + i) += (uint8_t)(offset + (1000.0/probe->vdiv) * (pre_buf[(i*span+start_rand)%len] - const_dc)) << (probe->index * 8); + } else if (probe->coupling == SR_AC_COUPLING) { + *(buf + i) += (uint8_t)(offset + (1000.0/probe->vdiv) * pre_buf[(i*span+start_rand)%len]) << (probe->index * 8); + } else { + *(buf + i) += offset << (probe->index * 8); + } + + if (probe->index == 0) { + devc->mstatus.ch0_max = MAX(devc->mstatus.ch0_max, (*(buf + i) & 0x00ff)); + devc->mstatus.ch0_min = MIN(devc->mstatus.ch0_min, (*(buf + i) & 0x00ff)); + if (i > devc->pre_index && + pre_buf[(i*span+start_rand)%len] < 0 && + pre_buf[((i-1)*span+start_rand)%len] > 0) { + devc->mstatus.ch0_period = 2*(i - pre0_i)*pow(10, 8)/DEMO_MAX_DSO_SAMPLERATE; + pre0_i = i; } + } else { + devc->mstatus.ch1_max = MAX(devc->mstatus.ch1_max, ((*(buf + i) & 0xff00) >> 8)); + devc->mstatus.ch1_min = MIN(devc->mstatus.ch1_min, ((*(buf + i) & 0xff00) >> 8)); + if (i > devc->pre_index && + pre_buf[(i*span+start_rand)%len] < 0 && + pre_buf[((i-1)*span+start_rand)%len] > 0) { + devc->mstatus.ch1_period = 2*(i - pre1_i)*pow(10, 8)/DEMO_MAX_DSO_SAMPLERATE; + pre1_i = i; + } + } } } - break; - default: - sr_err("Unknown pattern: %d.", devc->sample_generator); - break; - } + + for (l = sdi->channels; l; l = l->next) { + probe = (struct sr_channel *)l->data; + if (!probe->enabled) { + devc->mstatus.ch1_max = MAX(devc->mstatus.ch0_max, devc->mstatus.ch1_max); + devc->mstatus.ch1_min = MIN(devc->mstatus.ch0_min, devc->mstatus.ch1_min); + devc->mstatus.ch0_max = MAX(devc->mstatus.ch0_max, devc->mstatus.ch1_max); + devc->mstatus.ch0_min = MIN(devc->mstatus.ch0_min, devc->mstatus.ch1_min); + break; + } + } + } } /* Callback handling data */ @@ -733,8 +839,6 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) struct sr_datafeed_logic logic; struct sr_datafeed_dso dso; struct sr_datafeed_analog analog; - //uint16_t buf[BUFSIZE]; - uint16_t *buf; static uint64_t samples_to_send, expected_samplenum, sending_now; int64_t time, elapsed; static uint16_t last_sample = 0; @@ -744,43 +848,39 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) (void)fd; (void)revents; - if (!(buf = g_try_malloc(BUFSIZE*sizeof(uint16_t)))) { - sr_err("buf for receive_data malloc failed."); - return FALSE; - } - /* How many "virtual" samples should we have collected by now? */ time = g_get_monotonic_time(); elapsed = time - devc->starttime; devc->starttime = time; - expected_samplenum = elapsed * devc->cur_samplerate / 1000000; + //expected_samplenum = ceil(elapsed / 1000000.0 * devc->cur_samplerate); /* Of those, how many do we still have to send? */ //samples_to_send = (expected_samplenum - devc->samples_counter) / CONST_LEN * CONST_LEN; - samples_to_send = expected_samplenum / CONST_LEN * CONST_LEN; + //samples_to_send = expected_samplenum / CONST_LEN * CONST_LEN; + samples_to_send = ceil(elapsed / 1000000.0 * devc->cur_samplerate); if (devc->limit_samples) { - if (sdi->mode == LOGIC || devc->instant) + if ((sdi->mode == DSO && !devc->instant) || sdi->mode == ANALOG) samples_to_send = MIN(samples_to_send, - devc->limit_samples - devc->samples_counter); + devc->limit_samples - devc->pre_index); else samples_to_send = MIN(samples_to_send, - devc->limit_samples); + devc->limit_samples - devc->samples_counter); } while (samples_to_send > 0) { sending_now = MIN(samples_to_send, BUFSIZE); - samples_generator(buf, sending_now, sdi, devc); + samples_generator(devc->buf, sending_now, sdi, devc); if (devc->trigger_stage != 0) { for (i = 0; i < sending_now; i++) { if (devc->trigger_edge == 0) { - if ((*(buf + i) | devc->trigger_mask) == + if ((*(devc->buf + i) | devc->trigger_mask) == (devc->trigger_value | devc->trigger_mask)) { devc->trigger_stage = 0; break; } } else { - cur_sample = *(buf + i); + cur_sample = *(devc->buf + i); if (((last_sample & devc->trigger_edge) == (~devc->trigger_value & devc->trigger_edge)) && ((cur_sample | devc->trigger_mask) == @@ -802,6 +902,14 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) } } + if (sdi->mode == ANALOG) + devc->samples_counter += sending_now/g_slist_length(sdi->channels); + else + devc->samples_counter += sending_now; + if (sdi->mode == DSO && !devc->instant && + devc->samples_counter > devc->limit_samples) + devc->samples_counter = devc->limit_samples; + if (devc->trigger_stage == 0){ samples_to_send -= sending_now; if (sdi->mode == LOGIC) { @@ -809,47 +917,56 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) packet.payload = &logic; logic.length = sending_now * (NUM_PROBES >> 3); logic.unitsize = (NUM_PROBES >> 3); - logic.data = buf; + logic.data = devc->buf; } else if (sdi->mode == DSO) { packet.type = SR_DF_DSO; packet.payload = &dso; dso.probes = sdi->channels; - dso.num_samples = sending_now; + if (devc->instant) + dso.num_samples = sending_now; + else + dso.num_samples = devc->samples_counter; dso.mq = SR_MQ_VOLTAGE; dso.unit = SR_UNIT_VOLT; dso.mqflags = SR_MQFLAG_AC; - dso.data = buf; + dso.data = devc->buf; }else { packet.type = SR_DF_ANALOG; packet.payload = &analog; analog.probes = sdi->channels; - analog.num_samples = sending_now; + analog.num_samples = sending_now / g_slist_length(sdi->channels); analog.mq = SR_MQ_VOLTAGE; analog.unit = SR_UNIT_VOLT; analog.mqflags = SR_MQFLAG_AC; - analog.data = buf; + analog.data = devc->buf; + } + + if (sdi->mode == DSO && !devc->instant) { + devc->pre_index += sending_now; + if (sdi->mode == DSO && !devc->instant && + devc->pre_index >= devc->limit_samples) + devc->pre_index = 0; } sr_session_send(sdi, &packet); - if (sdi->mode == LOGIC || devc->instant) - devc->samples_counter += sending_now; - else - devc->samples_counter = (devc->samples_counter + sending_now) % devc->limit_samples; + + devc->mstatus.trig_hit = (devc->trigger_stage == 0); + devc->mstatus.captured_cnt0 = devc->samples_counter; + devc->mstatus.captured_cnt1 = devc->samples_counter >> 8; + devc->mstatus.captured_cnt2 = devc->samples_counter >> 16; + devc->mstatus.captured_cnt3 = devc->samples_counter >> 32; } else { break; } } - if (devc->limit_samples && + if ((sdi->mode == LOGIC || devc->instant) && devc->limit_samples && devc->samples_counter >= devc->limit_samples) { sr_info("Requested number of samples reached."); hw_dev_acquisition_stop(sdi, NULL); - g_free(buf); return TRUE; } - g_free(buf); - return TRUE; } @@ -865,6 +982,11 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, //devc->cb_data = cb_data; devc->samples_counter = 0; + devc->pre_index = 0; + devc->mstatus.captured_cnt0 = 0; + devc->mstatus.captured_cnt1 = 0; + devc->mstatus.captured_cnt2 = 0; + devc->mstatus.captured_cnt3 = 0; devc->stop = FALSE; /* @@ -912,6 +1034,11 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, //std_session_send_df_header(cb_data, LOG_PREFIX); std_session_send_df_header(sdi, LOG_PREFIX); + if (!(devc->buf = g_try_malloc(BUFSIZE*sizeof(uint16_t)))) { + sr_err("buf for receive_data malloc failed."); + return FALSE; + } + /* We use this timestamp to decide how many more samples to send. */ devc->starttime = g_get_monotonic_time(); @@ -933,6 +1060,8 @@ static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data) g_io_channel_unref(devc->channel); devc->channel = NULL; + g_free(devc->buf); + /* Send last packet. */ packet.type = SR_DF_END; sr_session_send(sdi, &packet); @@ -954,11 +1083,7 @@ static int hw_dev_status_get(struct sr_dev_inst *sdi, struct sr_status *status, (void)end; if (sdi) { struct dev_context *const devc = sdi->priv; - status->trig_hit = (devc->trigger_stage == 0); - status->captured_cnt0 = devc->samples_counter; - status->captured_cnt1 = devc->samples_counter >> 8; - status->captured_cnt2 = devc->samples_counter >> 16; - status->captured_cnt3 = devc->samples_counter >> 32; + *status = devc->mstatus; return SR_OK; } else { return SR_ERR; @@ -966,7 +1091,7 @@ static int hw_dev_status_get(struct sr_dev_inst *sdi, struct sr_status *status, } SR_PRIV struct sr_dev_driver demo_driver_info = { - .name = "demo", + .name = "virtual-demo", .longname = "Demo driver and pattern generator", .api_version = 1, .init = hw_init, diff --git a/libsigrok4DSL/hwdriver.c b/libsigrok4DSL/hwdriver.c index 0d187cca..4e437dfd 100644 --- a/libsigrok4DSL/hwdriver.c +++ b/libsigrok4DSL/hwdriver.c @@ -59,10 +59,12 @@ static struct sr_config_info sr_config_info_data[] = { "Sample rate", "Sample rate", NULL}, {SR_CONF_LIMIT_SAMPLES, SR_T_UINT64, "samplecount", "Sample count", "Sample count", NULL}, + {SR_CONF_ACTUAL_SAMPLES, SR_T_UINT64, "samplecount", + "Sample count", "Sample count", NULL}, {SR_CONF_CLOCK_TYPE, SR_T_BOOL, "clocktype", "Using External Clock", "Using External Clock", NULL}, {SR_CONF_CLOCK_EDGE, SR_T_BOOL, "clockedge", - "Using Clock Negedge", "Using Clock Negedge", NULL}, + "Using Clock Negedge", "Using Clock Negedge", NULL}, {SR_CONF_CAPTURE_RATIO, SR_T_UINT64, "captureratio", "Pre-trigger capture ratio", "Pre-trigger capture ratio", NULL}, {SR_CONF_PATTERN_MODE, SR_T_CHAR, "pattern", @@ -83,6 +85,10 @@ static struct sr_config_info sr_config_info_data[] = { "Buffer size", "Buffer size", NULL}, {SR_CONF_TIMEBASE, SR_T_UINT64, "timebase", "Time base", "Time base", NULL}, + {SR_CONF_MAX_HEIGHT, SR_T_CHAR, "height", + "Max Height", "Max Height", NULL}, + {SR_CONF_MAX_HEIGHT_VALUE, SR_T_UINT8, "height", + "Max Height", "Max Height", NULL}, {SR_CONF_FILTER, SR_T_CHAR, "filter", "Filter Targets", "Filter Targets", NULL}, {SR_CONF_VDIV, SR_T_RATIONAL_VOLT, "vdiv", @@ -95,6 +101,8 @@ static struct sr_config_info sr_config_info_data[] = { "Datalog", "Datalog", NULL}, {SR_CONF_OPERATION_MODE, SR_T_CHAR, "operation", "Operation Mode", "Operation Mode", NULL}, + {SR_CONF_CHANNEL_MODE, SR_T_CHAR, "channel", + "Channel Mode", "Channel Mode", NULL}, {SR_CONF_THRESHOLD, SR_T_CHAR, "threshold", "Threshold Level", "Threshold Level", NULL}, {SR_CONF_VTH, SR_T_FLOAT, "threshold", diff --git a/libsigrok4DSL/input/in_binary.c b/libsigrok4DSL/input/in_binary.c index 261156c5..00b954a8 100644 --- a/libsigrok4DSL/input/in_binary.c +++ b/libsigrok4DSL/input/in_binary.c @@ -53,7 +53,7 @@ static int format_match(const char *filename) static int init(struct sr_input *in, const char *filename) { struct sr_channel *probe; - int num_probes, i; + uint16_t num_probes, i; char name[SR_MAX_PROBENAME_LEN + 1]; char *param; struct context *ctx; diff --git a/libsigrok4DSL/input/in_vcd.c b/libsigrok4DSL/input/in_vcd.c index 61c896c1..61e72d7d 100644 --- a/libsigrok4DSL/input/in_vcd.c +++ b/libsigrok4DSL/input/in_vcd.c @@ -319,7 +319,7 @@ static int format_match(const char *filename) static int init(struct sr_input *in, const char *filename) { struct sr_channel *probe; - int num_probes, i; + uint16_t num_probes, i; char name[SR_MAX_PROBENAME_LEN + 1]; char *param; struct context *ctx; diff --git a/libsigrok4DSL/libsigrok-internal.h b/libsigrok4DSL/libsigrok-internal.h index 9c65e4d0..a201548c 100644 --- a/libsigrok4DSL/libsigrok-internal.h +++ b/libsigrok4DSL/libsigrok-internal.h @@ -83,7 +83,7 @@ SR_PRIV int sr_err(const char *format, ...); /*--- device.c --------------------------------------------------------------*/ -SR_PRIV struct sr_channel *sr_channel_new(int index, int type, +SR_PRIV struct sr_channel *sr_channel_new(uint16_t index, int type, gboolean enabled, const char *name); SR_PRIV void sr_dev_probes_free(struct sr_dev_inst *sdi); diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index d3cd9ee4..e55adbb0 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -176,6 +176,7 @@ enum { SR_DF_ANALOG, SR_DF_FRAME_BEGIN, SR_DF_FRAME_END, + SR_DF_ABANDON, }; /** Values for sr_datafeed_analog.mq. */ @@ -322,6 +323,8 @@ struct sr_datafeed_dso { int unit; /** Bitmap with extra information about the MQ. */ uint64_t mqflags; + /** samplerate different from last packet */ + gboolean samplerate_tog; /** The analog value(s). The data is interleaved according to * the probes list. */ void *data; @@ -556,7 +559,7 @@ enum { struct sr_channel { /* The index field will go: use g_slist_length(sdi->channels) instead. */ - int index; + uint16_t index; int type; gboolean enabled; char *name; @@ -624,6 +627,7 @@ struct sr_status { uint32_t vlen; gboolean stream_mode; uint32_t sample_divider; + gboolean sample_divider_tog; gboolean zeroing; uint16_t ch0_vpos_mid; @@ -753,6 +757,12 @@ enum { SR_CONF_ZERO, SR_CONF_ZERO_OVER, + /** status for dso channel */ + SR_CONF_STATUS_PERIOD, + SR_CONF_STATUS_PCNT, + SR_CONF_STATUS_MAX, + SR_CONF_STATUS_MIN, + /** Stream */ SR_CONF_STREAM, @@ -801,6 +811,13 @@ enum { /** Device operation mode */ SR_CONF_OPERATION_MODE, + /** Device channel mode */ + SR_CONF_CHANNEL_MODE, + + /** Signal max height **/ + SR_CONF_MAX_HEIGHT, + SR_CONF_MAX_HEIGHT_VALUE, + /** Device sample threshold */ SR_CONF_THRESHOLD, SR_CONF_VTH, @@ -810,6 +827,7 @@ enum { SR_CONF_MAX_DSO_SAMPLELIMITS, SR_CONF_MAX_LOGIC_SAMPLERATE, SR_CONF_MAX_LOGIC_SAMPLELIMITS, + SR_CONF_RLE_SAMPLELIMITS, /*--- Special stuff -------------------------------------------------*/ @@ -849,6 +867,11 @@ enum { */ SR_CONF_LIMIT_SAMPLES, + /** + * The actual sample count received + */ + SR_CONF_ACTUAL_SAMPLES, + /** * The device supports setting a frame limit (how many * frames should be acquired). @@ -919,13 +942,14 @@ enum { /** Device operation modes. */ enum { /** Normal */ - SR_OP_NORMAL = 0, + SR_OP_BUFFER = 0, + SR_OP_STREAM = 1, /** Internal pattern test mode */ - SR_OP_INTERNAL_TEST = 1, + SR_OP_INTERNAL_TEST = 2, /** External pattern test mode */ - SR_OP_EXTERNAL_TEST = 2, + SR_OP_EXTERNAL_TEST = 3, /** SDRAM loopback test mode */ - SR_OP_LOOPBACK_TEST = 3, + SR_OP_LOOPBACK_TEST = 4, }; /** Device threshold level. */ @@ -1065,7 +1089,8 @@ struct ds_trigger { struct ds_trigger_pos { uint32_t real_pos; uint32_t ram_saddr; - unsigned char first_block[504]; + uint32_t remain_cnt; + unsigned char first_block[500]; }; #include "proto.h" diff --git a/libsigrok4DSL/proto.h b/libsigrok4DSL/proto.h index 4ff18d18..fe9b1d95 100644 --- a/libsigrok4DSL/proto.h +++ b/libsigrok4DSL/proto.h @@ -49,7 +49,7 @@ SR_API int sr_dev_probe_name_set(const struct sr_dev_inst *sdi, int probenum, const char *name); SR_API int sr_dev_probe_enable(const struct sr_dev_inst *sdi, int probenum, gboolean state); -SR_API int sr_dev_trigger_set(const struct sr_dev_inst *sdi, int probenum, +SR_API int sr_dev_trigger_set(const struct sr_dev_inst *sdi, uint16_t probenum, const char *trigger); SR_API gboolean sr_dev_has_option(const struct sr_dev_inst *sdi, int key); SR_API GSList *sr_dev_list(const struct sr_dev_driver *driver); diff --git a/libsigrok4DSL/session_driver.c b/libsigrok4DSL/session_driver.c index dc9569b9..fa1d0c0f 100644 --- a/libsigrok4DSL/session_driver.c +++ b/libsigrok4DSL/session_driver.c @@ -54,6 +54,8 @@ struct session_vdev { uint64_t total_samples; int unitsize; int num_probes; + uint64_t timebase; + struct sr_status mstatus; }; static GSList *dev_insts = NULL; @@ -69,6 +71,8 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi) struct session_vdev *vdev; struct sr_datafeed_packet packet; struct sr_datafeed_logic logic; + struct sr_datafeed_dso dso; + struct sr_datafeed_analog analog; GSList *l; int ret, got_data; (void)fd; @@ -87,11 +91,31 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi) ret = zip_fread(vdev->capfile, vdev->buf, CHUNKSIZE); if (ret > 0) { got_data = TRUE; - packet.type = SR_DF_LOGIC; - packet.payload = &logic; - logic.length = ret; - logic.unitsize = vdev->unitsize; - logic.data = vdev->buf; + if (sdi->mode == DSO) { + packet.type = SR_DF_DSO; + packet.payload = &dso; + dso.num_samples = ret / vdev->unitsize; + dso.data = vdev->buf; + dso.probes = sdi->channels; + dso.mq = SR_MQ_VOLTAGE; + dso.unit = SR_UNIT_VOLT; + dso.mqflags = SR_MQFLAG_AC; + } else if (sdi->mode == ANALOG){ + packet.type = SR_DF_ANALOG; + packet.payload = &analog; + analog.probes = sdi->channels; + analog.num_samples = ret / vdev->unitsize; + analog.mq = SR_MQ_VOLTAGE; + analog.unit = SR_UNIT_VOLT; + analog.mqflags = SR_MQFLAG_AC; + analog.data = vdev->buf; + } else { + packet.type = SR_DF_LOGIC; + packet.payload = &logic; + logic.length = ret; + logic.unitsize = vdev->unitsize; + logic.data = vdev->buf; + } vdev->bytes_read += ret; sr_session_send(cb_sdi, &packet); } else { @@ -141,6 +165,13 @@ static int dev_open(struct sr_dev_inst *sdi) return SR_ERR_MALLOC; } + struct session_vdev *vdev; + vdev = sdi->priv; + if (!(vdev->buf = g_try_malloc(CHUNKSIZE))) { + sr_err("%s: vdev->buf malloc failed", __func__); + return SR_ERR_MALLOC; + } + dev_insts = g_slist_append(dev_insts, sdi); return SR_OK; @@ -159,7 +190,9 @@ static int dev_close(struct sr_dev_inst *sdi) return SR_OK; } -static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi) +static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, + const struct sr_channel *ch, + const struct sr_channel_group *cg) { struct session_vdev *vdev; @@ -178,14 +211,63 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi) } else return SR_ERR; break; - default: + case SR_CONF_TIMEBASE: + if (sdi) { + vdev = sdi->priv; + *data = g_variant_new_uint64(vdev->timebase); + } else + return SR_ERR; + break; + case SR_CONF_EN_CH: + if (sdi && ch) { + *data = g_variant_new_boolean(ch->enabled); + } else + return SR_ERR; + break; + case SR_CONF_COUPLING: + if (sdi && ch) { + *data = g_variant_new_byte(ch->coupling); + } else + return SR_ERR; + break; + case SR_CONF_VDIV: + if (sdi && ch) { + *data = g_variant_new_uint64(ch->vdiv); + } else + return SR_ERR; + break; + case SR_CONF_FACTOR: + if (sdi && ch) { + *data = g_variant_new_uint64(ch->vfactor); + } else + return SR_ERR; + break; + case SR_CONF_VPOS: + if (sdi && ch) { + *data = g_variant_new_double(ch->vpos); + } else + return SR_ERR; + break; + case SR_CONF_MAX_DSO_SAMPLERATE: + if (!sdi) + return SR_ERR; + *data = g_variant_new_uint64(vdev->samplerate); + break; + case SR_CONF_MAX_DSO_SAMPLELIMITS: + if (!sdi) + return SR_ERR; + *data = g_variant_new_uint64(vdev->total_samples); + break; + default: return SR_ERR_ARG; } return SR_OK; } -static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi) +static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi, + struct sr_channel *ch, + const struct sr_channel_group *cg) { struct session_vdev *vdev; @@ -197,7 +279,11 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi) samplerates[0] = vdev->samplerate; sr_info("Setting samplerate to %" PRIu64 ".", vdev->samplerate); break; - case SR_CONF_SESSIONFILE: + case SR_CONF_TIMEBASE: + vdev->timebase = g_variant_get_uint64(data); + sr_info("Setting timebase to %" PRIu64 ".", vdev->timebase); + break; + case SR_CONF_SESSIONFILE: vdev->sessionfile = g_strdup(g_variant_get_bytestring(data)); sr_info("Setting sessionfile to '%s'.", vdev->sessionfile); break; @@ -216,7 +302,46 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi) case SR_CONF_CAPTURE_NUM_PROBES: vdev->num_probes = g_variant_get_uint64(data); break; - default: + case SR_CONF_EN_CH: + ch->enabled = g_variant_get_boolean(data); + break; + case SR_CONF_COUPLING: + ch->coupling = g_variant_get_byte(data); + break; + case SR_CONF_VDIV: + ch->vdiv = g_variant_get_uint64(data); + break; + case SR_CONF_FACTOR: + ch->vfactor = g_variant_get_uint64(data); + break; + case SR_CONF_VPOS: + ch->vpos = g_variant_get_double(data); + break; + case SR_CONF_STATUS_PERIOD: + if (ch->index == 0) + vdev->mstatus.ch0_period = g_variant_get_uint64(data); + else + vdev->mstatus.ch1_period = g_variant_get_uint64(data); + break; + case SR_CONF_STATUS_PCNT: + if (ch->index == 0) + vdev->mstatus.ch0_pcnt = g_variant_get_uint64(data); + else + vdev->mstatus.ch1_pcnt = g_variant_get_uint64(data); + break; + case SR_CONF_STATUS_MAX: + if (ch->index == 0) + vdev->mstatus.ch0_max = g_variant_get_uint64(data); + else + vdev->mstatus.ch1_max = g_variant_get_uint64(data); + break; + case SR_CONF_STATUS_MIN: + if (ch->index == 0) + vdev->mstatus.ch0_min = g_variant_get_uint64(data); + else + vdev->mstatus.ch1_min = g_variant_get_uint64(data); + break; + default: sr_err("Unknown capability: %d.", id); return SR_ERR; } @@ -261,6 +386,22 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi) return SR_OK; } +static int dev_status_get(struct sr_dev_inst *sdi, struct sr_status *status, int begin, int end) +{ + (void)begin; + (void)end; + + struct session_vdev *vdev; + + if (sdi) { + vdev = sdi->priv; + *status = vdev->mstatus; + return SR_OK; + } else { + return SR_ERR; + } +} + static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) { @@ -291,11 +432,6 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, return SR_ERR; } - if (!(vdev->buf = g_try_malloc(CHUNKSIZE))) { - sr_err("%s: buf malloc failed", __func__); - return SR_ERR; - } - /* Send header packet to the session bus. */ std_session_send_df_header(sdi, LOG_PREFIX); @@ -322,7 +458,7 @@ SR_PRIV struct sr_dev_driver session_driver = { .dev_open = dev_open, .dev_close = dev_close, .dev_test = NULL, - .dev_status_get = NULL, + .dev_status_get = dev_status_get, .dev_acquisition_start = dev_acquisition_start, .dev_acquisition_stop = NULL, .priv = NULL, diff --git a/libsigrok4DSL/session_file.c b/libsigrok4DSL/session_file.c index e4b3b674..aa77128d 100644 --- a/libsigrok4DSL/session_file.c +++ b/libsigrok4DSL/session_file.c @@ -121,10 +121,15 @@ SR_API int sr_session_load(const char *filename) struct zip_stat zs; struct sr_dev_inst *sdi; struct sr_channel *probe; - int ret, probenum, devcnt, version, i, j; - uint64_t tmp_u64, total_probes, enabled_probes, p; + int ret, devcnt, i, j, k; + uint16_t probenum; + uint64_t tmp_u64, total_probes, enabled_probes; + uint16_t p; char **sections, **keys, *metafile, *val, s[11]; char probename[SR_MAX_PROBENAME_LEN + 1]; + int mode = LOGIC; + int channel_type = SR_CHANNEL_LOGIC; + double tmp_double; if (!filename) { sr_err("%s: filename was NULL", __func__); @@ -138,7 +143,7 @@ SR_API int sr_session_load(const char *filename) /* read "metadata" */ if (zip_stat(archive, "header", 0, &zs) == -1) { - sr_dbg("Not a valid DSLogic session file."); + sr_dbg("Not a valid DSView data file."); return SR_ERR; } @@ -173,8 +178,10 @@ SR_API int sr_session_load(const char *filename) keys = g_key_file_get_keys(kf, sections[i], NULL, NULL); for (j = 0; keys[j]; j++) { val = g_key_file_get_string(kf, sections[i], keys[j], NULL); - if (!strcmp(keys[j], "capturefile")) { - sdi = sr_dev_inst_new(LOGIC, devcnt, SR_ST_ACTIVE, NULL, NULL, NULL); + if (!strcmp(keys[j], "device mode")) { + mode = strtoull(val, NULL, 10); + } else if (!strcmp(keys[j], "capturefile")) { + sdi = sr_dev_inst_new(mode, devcnt, SR_ST_ACTIVE, NULL, NULL, NULL); sdi->driver = &session_driver; if (devcnt == 0) /* first device, init the driver */ @@ -198,13 +205,19 @@ SR_API int sr_session_load(const char *filename) tmp_u64 = strtoull(val, NULL, 10); sdi->driver->config_set(SR_CONF_LIMIT_SAMPLES, g_variant_new_uint64(tmp_u64), sdi, NULL, NULL); - } else if (!strcmp(keys[j], "total probes")) { + } else if (!strcmp(keys[j], "hDiv")) { + tmp_u64 = strtoull(val, NULL, 10); + sdi->driver->config_set(SR_CONF_TIMEBASE, + g_variant_new_uint64(tmp_u64), sdi, NULL, NULL); + } else if (!strcmp(keys[j], "total probes")) { total_probes = strtoull(val, NULL, 10); sdi->driver->config_set(SR_CONF_CAPTURE_NUM_PROBES, g_variant_new_uint64(total_probes), sdi, NULL, NULL); + channel_type = (mode == DSO) ? SR_CHANNEL_DSO : + (mode == ANALOG) ? SR_CHANNEL_ANALOG : SR_CHANNEL_LOGIC; for (p = 0; p < total_probes; p++) { snprintf(probename, SR_MAX_PROBENAME_LEN, "%" PRIu64, p); - if (!(probe = sr_channel_new(p, SR_CHANNEL_LOGIC, TRUE, + if (!(probe = sr_channel_new(p, channel_type, FALSE, probename))) return SR_ERR; sdi->channels = g_slist_append(sdi->channels, probe); @@ -215,17 +228,86 @@ SR_API int sr_session_load(const char *filename) enabled_probes++; tmp_u64 = strtoul(keys[j]+5, NULL, 10); /* sr_session_save() */ - sr_dev_probe_name_set(sdi, tmp_u64 - 1, val); + sr_dev_probe_name_set(sdi, tmp_u64, val); + sr_dev_probe_enable(sdi, tmp_u64, TRUE); } else if (!strncmp(keys[j], "trigger", 7)) { probenum = strtoul(keys[j]+7, NULL, 10); sr_dev_trigger_set(sdi, probenum, val); - } + } else if (!strncmp(keys[j], "enable", 6)) { + probenum = strtoul(keys[j]+6, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_EN_CH, + g_variant_new_boolean(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "coupling", 8)) { + probenum = strtoul(keys[j]+8, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_COUPLING, + g_variant_new_byte(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "vDiv", 4)) { + probenum = strtoul(keys[j]+4, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_VDIV, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "vFactor", 7)) { + probenum = strtoul(keys[j]+7, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_FACTOR, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "vPos", 4)) { + probenum = strtoul(keys[j]+4, NULL, 10); + tmp_double = strtod(val, NULL); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_VPOS, + g_variant_new_double(tmp_double), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "period", 6)) { + probenum = strtoul(keys[j]+6, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_STATUS_PERIOD, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "pcnt", 4)) { + probenum = strtoul(keys[j]+4, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_STATUS_PCNT, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "max", 3)) { + probenum = strtoul(keys[j]+3, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_STATUS_MAX, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "min", 3)) { + probenum = strtoul(keys[j]+3, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_STATUS_MIN, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } } g_strfreev(keys); - /* Disable probes not specifically listed. */ - if (total_probes) - for (p = enabled_probes; p < total_probes; p++) - sr_dev_probe_enable(sdi, p, FALSE); } devcnt++; } @@ -258,8 +340,9 @@ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, struct zip *zipfile; struct zip_source *versrc, *metasrc, *logicsrc; int tmpfile, ret, probecnt; - uint64_t samplerate; + uint64_t samplerate, timeBase, tmp_u64; char rawname[16], metafile[32], *s; + struct sr_status status; if (!filename) { sr_err("%s: filename was NULL", __func__); @@ -272,42 +355,68 @@ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, return SR_ERR; /* init "metadata" */ - strcpy(metafile, "DSLogic-meta-XXXXXX"); + strcpy(metafile, "DSView-meta-XXXXXX"); if ((tmpfile = g_mkstemp(metafile)) == -1) return SR_ERR; close(tmpfile); meta = g_fopen(metafile, "wb"); fprintf(meta, "[version]\n"); - fprintf(meta, "DSLogic version = %s\n", PACKAGE_VERSION); + fprintf(meta, "DSView version = %s\n", PACKAGE_VERSION); /* metadata */ fprintf(meta, "[header]\n"); - if (sdi->driver) + if (sdi->driver) { fprintf(meta, "driver = %s\n", sdi->driver->name); + fprintf(meta, "device mode = %d\n", sdi->mode); + } /* metadata */ fprintf(meta, "capturefile = data\n"); fprintf(meta, "unitsize = %d\n", unitsize); fprintf(meta, "total samples = %d\n", units); fprintf(meta, "total probes = %d\n", g_slist_length(sdi->channels)); - if (sr_dev_has_option(sdi, SR_CONF_SAMPLERATE)) { - if (sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_SAMPLERATE, - &gvar) == SR_OK) { - samplerate = g_variant_get_uint64(gvar); - s = sr_samplerate_string(samplerate); - fprintf(meta, "samplerate = %s\n", s); - g_free(s); - g_variant_unref(gvar); - } + if (sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_SAMPLERATE, + &gvar) == SR_OK) { + samplerate = g_variant_get_uint64(gvar); + s = sr_samplerate_string(samplerate); + fprintf(meta, "samplerate = %s\n", s); + g_free(s); + g_variant_unref(gvar); + } + if (sdi->mode == DSO && + sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_TIMEBASE, &gvar) == SR_OK) { + timeBase = g_variant_get_uint64(gvar); + fprintf(meta, "hDiv = %d\n", timeBase); + g_variant_unref(gvar); } probecnt = 1; for (l = sdi->channels; l; l = l->next) { probe = l->data; - if (probe->enabled) { + if (probe->enabled || sdi->mode == DSO) { if (probe->name) - fprintf(meta, "probe%d = %s\n", probecnt, probe->name); + fprintf(meta, "probe%d = %s\n", probe->index, probe->name); if (probe->trigger) - fprintf(meta, " trigger%d = %s\n", probecnt, probe->trigger); + fprintf(meta, " trigger%d = %s\n", probe->index, probe->trigger); + if (sdi->mode == DSO) { + fprintf(meta, " enable%d = %d\n", probe->index, probe->enabled); + fprintf(meta, " coupling%d = %d\n", probe->index, probe->coupling); + fprintf(meta, " vDiv%d = %d\n", probe->index, probe->vdiv); + fprintf(meta, " vFactor%d = %d\n", probe->index, probe->vfactor); + fprintf(meta, " vPos%d = %lf\n", probe->index, probe->vpos); + if (sr_status_get(sdi, &status, 0, 0) == SR_OK) { + if (probe->index == 0) { + fprintf(meta, " period%d = %d\n", probe->index, status.ch0_period); + fprintf(meta, " pcnt%d = %d\n", probe->index, status.ch0_pcnt); + fprintf(meta, " max%d = %d\n", probe->index, status.ch0_max); + fprintf(meta, " min%d = %d\n", probe->index, status.ch0_min); + } else { + fprintf(meta, " period%d = %d\n", probe->index, status.ch1_period); + fprintf(meta, " pcnt%d = %d\n", probe->index, status.ch1_pcnt); + fprintf(meta, " max%d = %d\n", probe->index, status.ch1_max); + fprintf(meta, " min%d = %d\n", probe->index, status.ch1_min); + } + } + } probecnt++; } } diff --git a/libsigrok4DSL/trigger.c b/libsigrok4DSL/trigger.c index 17e0740d..c3350c95 100644 --- a/libsigrok4DSL/trigger.c +++ b/libsigrok4DSL/trigger.c @@ -45,9 +45,11 @@ SR_API int ds_trigger_init(void) { int i, j; - if (!(trigger = g_try_malloc0(sizeof(struct ds_trigger)))) { - sr_err("Trigger malloc failed."); - return SR_ERR_MALLOC; + if (!trigger) { + if (!(trigger = g_try_malloc0(sizeof(struct ds_trigger)))) { + sr_err("Trigger malloc failed."); + return SR_ERR_MALLOC; + } } trigger->trigger_en = 0;