From bad63a6ede23049230fbc45748b211f1b26d9c80 Mon Sep 17 00:00:00 2001 From: DreamSourceLab Date: Sun, 19 Apr 2015 00:52:20 +0800 Subject: [PATCH] Fix measure pricision issue @ LA mode --- .gitignore | 12 +- DSView/pv/data/logicsnapshot.cpp | 766 ++++++++++--------------------- DSView/pv/data/logicsnapshot.h | 12 +- DSView/pv/dock/measuredock.cpp | 21 +- DSView/pv/dock/measuredock.h | 3 +- DSView/pv/mainwindow.cpp | 2 - DSView/pv/view/cursor.cpp | 10 +- DSView/pv/view/cursor.h | 4 +- DSView/pv/view/logicsignal.cpp | 43 ++ DSView/pv/view/logicsignal.h | 2 + DSView/pv/view/ruler.cpp | 39 +- DSView/pv/view/ruler.h | 3 + DSView/pv/view/timemarker.cpp | 30 +- DSView/pv/view/timemarker.h | 9 +- DSView/pv/view/view.cpp | 54 +-- DSView/pv/view/view.h | 8 +- DSView/pv/view/viewport.cpp | 164 +++---- DSView/pv/view/viewport.h | 17 +- 18 files changed, 465 insertions(+), 734 deletions(-) diff --git a/.gitignore b/.gitignore index e9af7c68..c1f91428 100644 --- a/.gitignore +++ b/.gitignore @@ -31,16 +31,18 @@ Makefile.in configure aclocal.m4 -DSLogic-gui/ui_*.h -DSLogic-gui/DSLogic -DSLogic-gui/install_manifest.txt +DSView/ui_*.h +DSView/DSView +DSView/install_manifest.txt moc_*.cxx moc_*.cxx_parameters -libsigrok4DSLogic/version.h +libsigrok4DSL/version.h libusbx-1.0.18/doc/doxygen.cfg libusbx-1.0.18/m4/ - +DSView-prj +libsigrokdecode +build* diff --git a/DSView/pv/data/logicsnapshot.cpp b/DSView/pv/data/logicsnapshot.cpp index 4b18551e..31614471 100644 --- a/DSView/pv/data/logicsnapshot.cpp +++ b/DSView/pv/data/logicsnapshot.cpp @@ -208,8 +208,6 @@ void LogicSnapshot::get_subsampled_edges( boost::lock_guard lock(_mutex); const uint64_t block_length = (uint64_t)max(min_length, 1.0f); - const unsigned int min_level = max((int)floorf(logf(min_length) / - LogMipMapScaleFactor) - 1, 0); const uint64_t sig_mask = 1ULL << sig_index; if (!edges.empty()) @@ -220,132 +218,8 @@ void LogicSnapshot::get_subsampled_edges( while (index + block_length <= end) { - //----- Continue to search -----// - level = min_level; - - // We cannot fast-forward if there is no mip-map data at - // at the minimum level. - fast_forward = (_mip_map[level].data != NULL); - - if (min_length < MipMapScaleFactor) - { - // Search individual samples up to the beginning of - // the next first level mip map block - const uint64_t final_index = min(end, - pow2_ceil(index, MipMapScalePower)); - - for (; index < final_index && - (index & ~(~0 << MipMapScalePower)) != 0; - index++) - { - const bool sample = - (get_sample(index) & sig_mask) != 0; - - // If there was a change we cannot fast forward - if (sample != last_sample) { - fast_forward = false; - break; - } - } - } - else - { - // 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 = - (level + 1) * MipMapScalePower; - index = pow2_ceil(index, min_level_scale_power); - if (index >= end) - break; - - // We can fast forward only if there was no change - const bool sample = - (get_sample(index) & sig_mask) != 0; - if (last_sample != sample) - fast_forward = false; - } - - if (fast_forward) { - - // Fast forward: This involves zooming out to higher - // levels of the mip map searching for changes, then - // zooming in on them to find the point where the edge - // begins. - - // Slide right and zoom out at the beginnings of mip-map - // blocks until we encounter a change - while (1) { - const int level_scale_power = - (level + 1) * MipMapScalePower; - const uint64_t offset = - index >> level_scale_power; - - // Check if we reached the last block at this - // level, or if there was a change in this block - if (offset >= _mip_map[level].length || - (get_subsample(level, offset) & - sig_mask)) - break; - - if ((offset & ~(~0 << MipMapScalePower)) == 0) { - // If we are now at the beginning of a - // higher level mip-map block ascend one - // level - if (level + 1 >= ScaleStepCount || - !_mip_map[level + 1].data) - break; - - level++; - } else { - // Slide right to the beginning of the - // next mip map block - index = pow2_ceil(index + 1, - level_scale_power); - } - } - - // Zoom in, and slide right until we encounter a change, - // and repeat until we reach min_level - while (1) { - assert(_mip_map[level].data); - - const int level_scale_power = - (level + 1) * MipMapScalePower; - const uint64_t offset = - index >> level_scale_power; - - // Check if we reached the last block at this - // level, or if there was a change in this block - if (offset >= _mip_map[level].length || - (get_subsample(level, offset) & - sig_mask)) { - // Zoom in unless we reached the minimum - // zoom - if (level == min_level) - break; - - level--; - } else { - // Slide right to the beginning of the - // next mip map block - index = pow2_ceil(index + 1, - level_scale_power); - } - } - - // If individual samples within the limit of resolution, - // do a linear search for the next transition within the - // block - if (min_length < MipMapScaleFactor) { - for (; index < end; index++) { - const bool sample = (get_sample(index) & - sig_mask) != 0; - if (sample != last_sample) - break; - } - } - } + // search next edge + get_nxt_edge(index, last_sample, end, min_length, sig_index); //----- Store the edge -----// @@ -373,44 +247,34 @@ void LogicSnapshot::get_subsampled_edges( edges.push_back(pair(end + 1, ~last_sample)); } -int LogicSnapshot::get_first_edge( - uint64_t &edge_index, bool &edge, - uint64_t start, uint64_t end, - int sig_index, int edge_type, - int flag_index, int flag) +bool LogicSnapshot::get_nxt_edge( + uint64_t &index, bool last_sample, uint64_t end, + 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); - assert(sig_index >= 0); - assert(sig_index < 64); + assert(index > 0); - boost::lock_guard lock(_mutex); - - const uint64_t block_length = 1; - const unsigned int min_level = 0; + const unsigned int min_level = max((int)floorf(logf(min_length) / + LogMipMapScaleFactor) - 1, 0); const uint64_t sig_mask = 1ULL << sig_index; - const uint64_t flag_mask = 1ULL << flag_index; - // Store the initial state - last_sample = (get_sample(start) & sig_mask) != 0; + if (index >= end) + return false; - while (index + block_length <= end) + //----- Continue to search -----// + level = min_level; + + // We cannot fast-forward if there is no mip-map data at + // at the minimum level. + fast_forward = (_mip_map[level].data != NULL); + + if (min_length < MipMapScaleFactor) { - //----- Continue to search -----// - level = min_level; - - // We cannot fast-forward if there is no mip-map data at - // at the minimum level. - fast_forward = (_mip_map[level].data != NULL); - // Search individual samples up to the beginning of // the next first level mip map block - uint64_t final_index = min(end, + const uint64_t final_index = min(end, pow2_ceil(index, MipMapScalePower)); for (; index < final_index && @@ -426,78 +290,97 @@ int LogicSnapshot::get_first_edge( break; } } + } + else + { + // 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 = + (level + 1) * MipMapScalePower; + index = pow2_ceil(index, min_level_scale_power); + if (index >= end) + return false; - if (fast_forward) { + // We can fast forward only if there was no change + const bool sample = + (get_sample(index) & sig_mask) != 0; + if (last_sample != sample) + fast_forward = false; + } - // Fast forward: This involves zooming out to higher - // levels of the mip map searching for changes, then - // zooming in on them to find the point where the edge - // begins. + if (fast_forward) { - // Slide right and zoom out at the beginnings of mip-map - // blocks until we encounter a change - while (1) { - const int level_scale_power = - (level + 1) * MipMapScalePower; - const uint64_t offset = - index >> level_scale_power; + // Fast forward: This involves zooming out to higher + // levels of the mip map searching for changes, then + // zooming in on them to find the point where the edge + // begins. - // Check if we reached the last block at this - // level, or if there was a change in this block - if (offset >= _mip_map[level].length || - (get_subsample(level, offset) & - sig_mask)) + // Slide right and zoom out at the beginnings of mip-map + // blocks until we encounter a change + while (1) { + const int level_scale_power = + (level + 1) * MipMapScalePower; + const uint64_t offset = + index >> level_scale_power; + + // Check if we reached the last block at this + // level, or if there was a change in this block + if (offset >= _mip_map[level].length || + (get_subsample(level, offset) & + sig_mask)) + break; + + if ((offset & ~(~0 << MipMapScalePower)) == 0) { + // If we are now at the beginning of a + // higher level mip-map block ascend one + // level + if (level + 1 >= ScaleStepCount || + !_mip_map[level + 1].data) break; - if ((offset & ~(~0 << MipMapScalePower)) == 0) { - // If we are now at the beginning of a - // higher level mip-map block ascend one - // level - if (level + 1 >= ScaleStepCount || - !_mip_map[level + 1].data) - break; - - level++; - } else { - // Slide right to the beginning of the - // next mip map block - index = pow2_ceil(index + 1, - level_scale_power); - } + level++; + } else { + // Slide right to the beginning of the + // next mip map block + index = pow2_ceil(index + 1, + level_scale_power); } + } - // Zoom in, and slide right until we encounter a change, - // and repeat until we reach min_level - while (1) { - assert(_mip_map[level].data); + // Zoom in, and slide right until we encounter a change, + // and repeat until we reach min_level + while (1) { + assert(_mip_map[level].data); - const int level_scale_power = - (level + 1) * MipMapScalePower; - const uint64_t offset = - index >> level_scale_power; + const int level_scale_power = + (level + 1) * MipMapScalePower; + const uint64_t offset = + index >> level_scale_power; - // Check if we reached the last block at this - // level, or if there was a change in this block - if (offset >= _mip_map[level].length || - (get_subsample(level, offset) & - sig_mask)) { - // Zoom in unless we reached the minimum - // zoom - if (level == min_level) - break; + // Check if we reached the last block at this + // level, or if there was a change in this block + if (offset >= _mip_map[level].length || + (get_subsample(level, offset) & + sig_mask)) { + // Zoom in unless we reached the minimum + // zoom + if (level == min_level) + break; - level--; - } else { - // Slide right to the beginning of the - // next mip map block - index = pow2_ceil(index + 1, - level_scale_power); - } + level--; + } else { + // Slide right to the beginning of the + // next mip map block + index = pow2_ceil(index + 1, + level_scale_power); } + } - // If individual samples within the limit of resolution, - // do a linear search for the next transition within the - // block + // If individual samples within the limit of resolution, + // do a linear search for the next transition within the + // block + if (min_length < MipMapScaleFactor) { for (; index < end; index++) { const bool sample = (get_sample(index) & sig_mask) != 0; @@ -505,90 +388,45 @@ int LogicSnapshot::get_first_edge( break; } } - - //----- Store the edge -----// - - // Take the last sample of the quanization block - final_index = index + block_length; - if (index + block_length > end) - break; - - // Store the final state - const bool final_sample = - (get_sample(final_index - 1) & sig_mask) != 0; - if (final_index > 1) { - const bool final_flag_sample = ((get_sample(final_index - 1) & flag_mask) != 0); - const bool final_pre_flag_sample = ((get_sample(final_index - 2) & flag_mask) != 0); - if (final_sample != last_sample && - ((edge_type == -1) || final_sample == (edge_type != 0)) && - ((flag == -1) || (final_flag_sample == (flag != 0) && final_flag_sample == final_pre_flag_sample))) { - edge_index = index; - edge = final_sample; - return SR_OK; - } - } - - index = final_index; - last_sample = final_sample; } - // Add the final state - const bool end_sample = ((get_sample(end) & sig_mask) != 0); - const bool end_flag_sample = ((get_sample(end) & flag_mask) != 0); - const bool end_pre_flag_sample = ((get_sample(end - 1) & flag_mask) != 0); - if (end_sample != last_sample && - ((edge_type == -1) || end_sample == (edge_type != 0)) && - ((flag == -1) || (end_flag_sample == (flag != 0) && end_flag_sample == end_pre_flag_sample))) { - edge_index = end; - edge = end_sample; - return SR_OK; - } else { - return SR_ERR; - } + if (index >= end) + return false; + else + return true; } -void LogicSnapshot::get_edges( - std::vector &edges, - uint64_t start, uint64_t end, int sig_index, int edge_type) +bool LogicSnapshot::get_pre_edge( + uint64_t &index, bool last_sample, + 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); - assert(sig_index >= 0); - assert(sig_index < 64); + assert(index < get_sample_count()); - boost::lock_guard lock(_mutex); - - const uint64_t block_length = 1; - const unsigned int min_level = 0; + const unsigned int min_level = max((int)floorf(logf(min_length) / + LogMipMapScaleFactor) - 1, 0); const uint64_t sig_mask = 1ULL << sig_index; - if (!edges.empty()) - edges.clear(); - // Store the initial state - last_sample = (get_sample(start) & sig_mask) != 0; + //----- Continue to search -----// + level = min_level; - while (index + block_length <= end) + // We cannot fast-forward if there is no mip-map data at + // at the minimum level. + fast_forward = (_mip_map[level].data != NULL); + + if (min_length < MipMapScaleFactor) { - //----- Continue to search -----// - level = min_level; + // Search individual samples down to the ending of + // the previous first level mip map block + uint64_t final_index; + if (index < (1 << MipMapScalePower)) + final_index = 0; + else + final_index = pow2_ceil(index + 1, MipMapScalePower) - (1 << MipMapScalePower) - 1; - // We cannot fast-forward if there is no mip-map data at - // at the minimum level. - fast_forward = (_mip_map[level].data != NULL); - - // Search individual samples up to the beginning of - // the next first level mip map block - uint64_t final_index = min(end, - pow2_ceil(index, MipMapScalePower)); - - for (; index < final_index && - (index & ~(~0 << MipMapScalePower)) != 0; - index++) + for (; index >= final_index; index--) { const bool sample = (get_sample(index) & sig_mask) != 0; @@ -596,267 +434,125 @@ void LogicSnapshot::get_edges( // If there was a change we cannot fast forward if (sample != last_sample) { fast_forward = false; - break; + index++; + return true; } + + if (index == 0) + return false; } - - if (fast_forward) { - - // Fast forward: This involves zooming out to higher - // levels of the mip map searching for changes, then - // zooming in on them to find the point where the edge - // begins. - - // Slide right and zoom out at the beginnings of mip-map - // blocks until we encounter a change - while (1) { - const int level_scale_power = - (level + 1) * MipMapScalePower; - const uint64_t offset = - index >> level_scale_power; - - // Check if we reached the last block at this - // level, or if there was a change in this block - if (offset >= _mip_map[level].length || - (get_subsample(level, offset) & - sig_mask)) - break; - - if ((offset & ~(~0 << MipMapScalePower)) == 0) { - // If we are now at the beginning of a - // higher level mip-map block ascend one - // level - if (level + 1 >= ScaleStepCount || - !_mip_map[level + 1].data) - break; - - level++; - } else { - // Slide right to the beginning of the - // next mip map block - index = pow2_ceil(index + 1, - level_scale_power); - } - } - - // Zoom in, and slide right until we encounter a change, - // and repeat until we reach min_level - while (1) { - assert(_mip_map[level].data); - - const int level_scale_power = - (level + 1) * MipMapScalePower; - const uint64_t offset = - index >> level_scale_power; - - // Check if we reached the last block at this - // level, or if there was a change in this block - if (offset >= _mip_map[level].length || - (get_subsample(level, offset) & - sig_mask)) { - // Zoom in unless we reached the minimum - // zoom - if (level == min_level) - break; - - level--; - } else { - // Slide right to the beginning of the - // next mip map block - index = pow2_ceil(index + 1, - level_scale_power); - } - } - - // If individual samples within the limit of resolution, - // do a linear search for the next transition within the - // block - for (; index < end; index++) { - const bool sample = (get_sample(index) & - sig_mask) != 0; - if (sample != last_sample) - break; - } - } - - //----- Store the edge -----// - - // Take the last sample of the quanization block - final_index = index + block_length; - if (index + block_length > end) - break; - - // Store the final state - const bool final_sample = - (get_sample(final_index - 1) & sig_mask) != 0; - if ((edge_type == -1) || (final_sample == (edge_type != 0))) - edges.push_back(pair(final_index - 1, final_sample)); - - index = final_index; - last_sample = final_sample; } - - // Add the final state - const bool end_sample = ((get_sample(end) & sig_mask) != 0); - if ((end_sample != last_sample) && - ((edge_type == -1) || (end_sample == (edge_type != 0)))) - edges.push_back(pair(end, end_sample)); -} - -uint64_t LogicSnapshot::get_min_pulse(uint64_t start, uint64_t end, int sig_index) -{ - uint64_t index = start; - unsigned int level; - bool last_sample; - bool fast_forward; - uint64_t last_index; - uint64_t min_pulse = end - start; - - assert(end <= get_sample_count()); - assert(start <= end); - assert(sig_index >= 0); - assert(sig_index < 64); - - boost::lock_guard lock(_mutex); - - const uint64_t block_length = 1; - const unsigned int min_level = 0; - const uint64_t sig_mask = 1ULL << sig_index; - - // Store the initial state - last_index = start; - last_sample = (get_sample(start) & sig_mask) != 0; - - while (index + block_length <= end) + else { - //----- Continue to search -----// - level = min_level; + // 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 = + (level + 1) * MipMapScalePower; + if (index < (1 << min_level_scale_power)) + index = 0; + else + index = pow2_ceil(index, min_level_scale_power) - (1 << min_level_scale_power) - 1; - // We cannot fast-forward if there is no mip-map data at - // at the minimum level. - fast_forward = (_mip_map[level].data != NULL); - - // Search individual samples up to the beginning of - // the next first level mip map block - uint64_t final_index = min(end, - pow2_ceil(index, MipMapScalePower)); - - for (; index < final_index && - (index & ~(~0 << MipMapScalePower)) != 0; - index++) - { - const bool sample = - (get_sample(index) & sig_mask) != 0; - - // If there was a change we cannot fast forward - if (sample != last_sample) { - fast_forward = false; - break; - } + // We can fast forward only if there was no change + const bool sample = + (get_sample(index) & sig_mask) != 0; + if (last_sample != sample) { + fast_forward = false; + index++; + return true; } - if (fast_forward) { - - // Fast forward: This involves zooming out to higher - // levels of the mip map searching for changes, then - // zooming in on them to find the point where the edge - // begins. - - // Slide right and zoom out at the beginnings of mip-map - // blocks until we encounter a change - while (1) { - const int level_scale_power = - (level + 1) * MipMapScalePower; - const uint64_t offset = - index >> level_scale_power; - - // Check if we reached the last block at this - // level, or if there was a change in this block - if (offset >= _mip_map[level].length || - (get_subsample(level, offset) & - sig_mask)) - break; - - if ((offset & ~(~0 << MipMapScalePower)) == 0) { - // If we are now at the beginning of a - // higher level mip-map block ascend one - // level - if (level + 1 >= ScaleStepCount || - !_mip_map[level + 1].data) - break; - - level++; - } else { - // Slide right to the beginning of the - // next mip map block - index = pow2_ceil(index + 1, - level_scale_power); - } - } - - // Zoom in, and slide right until we encounter a change, - // and repeat until we reach min_level - while (1) { - assert(_mip_map[level].data); - - const int level_scale_power = - (level + 1) * MipMapScalePower; - const uint64_t offset = - index >> level_scale_power; - - // Check if we reached the last block at this - // level, or if there was a change in this block - if (offset >= _mip_map[level].length || - (get_subsample(level, offset) & - sig_mask)) { - // Zoom in unless we reached the minimum - // zoom - if (level == min_level) - break; - - level--; - } else { - // Slide right to the beginning of the - // next mip map block - index = pow2_ceil(index + 1, - level_scale_power); - } - } - - // If individual samples within the limit of resolution, - // do a linear search for the next transition within the - // block - for (; index < end; index++) { - const bool sample = (get_sample(index) & - sig_mask) != 0; - if (sample != last_sample) - break; - } - } - - //----- Store the edge -----// - - // Take the last sample of the quanization block - final_index = index + block_length; - if (index + block_length > end) - break; - - // get pulse width - const bool final_sample = - (get_sample(final_index - 1) & sig_mask) != 0; - min_pulse = min(index - last_index, min_pulse); - last_index = index; - if (min_pulse == 1) - break; - - index = final_index; - last_sample = final_sample; + if (index == 0) + return false; } - // Add the final state - min_pulse = min(end - last_index, min_pulse); + if (fast_forward) { - return min_pulse; + // Fast forward: This involves zooming out to higher + // levels of the mip map searching for changes, then + // zooming in on them to find the point where the edge + // begins. + + // Slide left and zoom out at the endings of mip-map + // blocks until we encounter a change + while (1) { + const int level_scale_power = + (level + 1) * MipMapScalePower; + const uint64_t offset = + index >> level_scale_power; + + // Check if we reached the first block at this + // level, or if there was a change in this block + if (offset == 0 || + (get_subsample(level, offset) & + sig_mask)) + break; + + if (((offset+1) & ~(~0 << MipMapScalePower)) == 0) { + // If we are now at the ending of a + // higher level mip-map block ascend one + // level + if (level + 1 >= ScaleStepCount || + !_mip_map[level + 1].data) + break; + + level++; + } else { + // Slide left to the beginning of the + // previous mip map block + index = pow2_ceil(index + 1, + level_scale_power) - (1 << level_scale_power) - 1; + } + } + + // Zoom in, and slide left until we encounter a change, + // and repeat until we reach min_level + while (1) { + assert(_mip_map[level].data); + + const int level_scale_power = + (level + 1) * MipMapScalePower; + const uint64_t offset = + index >> level_scale_power; + + // Check if we reached the first block at this + // level, or if there was a change in this block + if (offset == 0 || + (get_subsample(level, offset) & + sig_mask)) { + // Zoom in unless we reached the minimum + // zoom + if (level == min_level) + break; + + level--; + } else { + // Slide left to the ending of the + // previous mip map block + index = pow2_ceil(index + 1, + level_scale_power) - (1 << level_scale_power) - 1; + } + } + + // If individual samples within the limit of resolution, + // do a linear search for the next transition within the + // block + if (min_length < MipMapScaleFactor) { + 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; + } + } + } + return false; } uint64_t LogicSnapshot::get_subsample(int level, uint64_t offset) const diff --git a/DSView/pv/data/logicsnapshot.h b/DSView/pv/data/logicsnapshot.h index 3914a2ed..6e9aae12 100644 --- a/DSView/pv/data/logicsnapshot.h +++ b/DSView/pv/data/logicsnapshot.h @@ -90,15 +90,11 @@ public: uint64_t start, uint64_t end, float min_length, int sig_index); - int get_first_edge(uint64_t &edge_index, bool &edge, - uint64_t start, uint64_t end, - int sig_index, int edge_type, - int flag_index, int flag); + bool get_nxt_edge(uint64_t &index, bool last_sample, uint64_t end, + float min_length, int sig_index); - void get_edges(std::vector &edges, - uint64_t start, uint64_t end, int sig_index, int edge_type); - - uint64_t get_min_pulse(uint64_t start, uint64_t end, int sig_index); + bool get_pre_edge(uint64_t &index, bool last_sample, + float min_length, int sig_index); private: uint64_t get_subsample(int level, uint64_t offset) const; diff --git a/DSView/pv/dock/measuredock.cpp b/DSView/pv/dock/measuredock.cpp index f782ee3a..211acdff 100644 --- a/DSView/pv/dock/measuredock.cpp +++ b/DSView/pv/dock/measuredock.cpp @@ -26,6 +26,7 @@ #include "../sigsession.h" #include "../view/cursor.h" #include "../view/view.h" +#include "../view/viewport.h" #include "../view/timemarker.h" #include "../view/ruler.h" #include "../view/logicsignal.h" @@ -54,9 +55,10 @@ MeasureDock::MeasureDock(QWidget *parent, View &view, SigSession &session) : _mouse_groupBox = new QGroupBox("Mouse measurement", this); _fen_checkBox = new QCheckBox("Enable floating measurement", this); _fen_checkBox->setChecked(true); - _width_label = new QLabel(view.get_mm_width(), this); - _period_label = new QLabel(view.get_mm_period(), this); - _freq_label = new QLabel(view.get_mm_freq(), this); + _width_label = new QLabel("#####", this); + _period_label = new QLabel("#####", this); + _freq_label = new QLabel("#####", this); + _duty_label = new QLabel("#####", this); _mouse_layout = new QGridLayout(); _mouse_layout->addWidget(_fen_checkBox, 0, 0, 1, 2); @@ -66,10 +68,13 @@ MeasureDock::MeasureDock(QWidget *parent, View &view, SigSession &session) : _mouse_layout->addWidget(_period_label, 2, 1); _mouse_layout->addWidget(new QLabel("Frequency: ", this), 3, 0); _mouse_layout->addWidget(_freq_label, 3, 1); + _mouse_layout->addWidget(new QLabel("Duty Cycle: ", this), 4, 0); + _mouse_layout->addWidget(_duty_label, 4, 1); _mouse_layout->addWidget(new QLabel(this), 0, 2); _mouse_layout->addWidget(new QLabel(this), 1, 2); _mouse_layout->addWidget(new QLabel(this), 2, 2); _mouse_layout->addWidget(new QLabel(this), 3, 2); + _mouse_layout->addWidget(new QLabel(this), 4, 2); _mouse_layout->setColumnStretch(2, 1); _mouse_groupBox->setLayout(_mouse_layout); @@ -134,6 +139,7 @@ MeasureDock::MeasureDock(QWidget *parent, View &view, SigSession &session) : connect(_t3_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update())); connect(_fen_checkBox, SIGNAL(stateChanged(int)), &_view, SLOT(set_measure_en(int))); + connect(_view.get_viewport(), SIGNAL(mouse_measure()), this, SLOT(mouse_measure())); } MeasureDock::~MeasureDock() @@ -216,11 +222,12 @@ void MeasureDock::cursor_update() update(); } -void MeasureDock::mouse_moved() +void MeasureDock::mouse_measure() { - _width_label->setText(_view.get_mm_width()); - _period_label->setText(_view.get_mm_period()); - _freq_label->setText(_view.get_mm_freq()); + _width_label->setText(_view.get_viewport()->get_measure("width")); + _period_label->setText(_view.get_viewport()->get_measure("period")); + _freq_label->setText(_view.get_viewport()->get_measure("frequency")); + _duty_label->setText(_view.get_viewport()->get_measure("duty")); } void MeasureDock::cursor_moved() diff --git a/DSView/pv/dock/measuredock.h b/DSView/pv/dock/measuredock.h index 500ec66e..fa29db64 100644 --- a/DSView/pv/dock/measuredock.h +++ b/DSView/pv/dock/measuredock.h @@ -74,7 +74,7 @@ private slots: public slots: void cursor_update(); void cursor_moved(); - void mouse_moved(); + void mouse_measure(); private: SigSession &_session; @@ -86,6 +86,7 @@ private: QLabel *_width_label; QLabel *_period_label; QLabel *_freq_label; + QLabel *_duty_label; QGridLayout *_cursor_layout; QGroupBox *_cursor_groupBox; diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 7a0c9407..10410ba6 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -244,8 +244,6 @@ void MainWindow::setup_ui() SLOT(cursor_update())); connect(_view, SIGNAL(cursor_moved()), _measure_widget, SLOT(cursor_moved())); - connect(_view, SIGNAL(mouse_moved()), _measure_widget, - SLOT(mouse_moved())); connect(_view, SIGNAL(mode_changed()), this, SLOT(update_device_list())); diff --git a/DSView/pv/view/cursor.cpp b/DSView/pv/view/cursor.cpp index 0945a6e8..819f97d4 100644 --- a/DSView/pv/view/cursor.cpp +++ b/DSView/pv/view/cursor.cpp @@ -51,8 +51,14 @@ const int Cursor::ArrowSize = 10; const int Cursor::CloseSize = 10; -Cursor::Cursor(View &view, QColor color, double time) : - TimeMarker(view, color, time), +Cursor::Cursor(View &view, QColor color, uint64_t index) : + TimeMarker(view, color, index), + _other(*this) +{ +} + +Cursor::Cursor(View &view, QColor color) : + TimeMarker(view, color), _other(*this) { } diff --git a/DSView/pv/view/cursor.h b/DSView/pv/view/cursor.h index d06c4186..afecc62f 100644 --- a/DSView/pv/view/cursor.h +++ b/DSView/pv/view/cursor.h @@ -55,7 +55,9 @@ public: * @param time The time to set the flag to. * @param other A reference to the other cursor. */ - Cursor(View &view, QColor color, double time); + Cursor(View &view, QColor color); + Cursor(View &view, QColor color, uint64_t index); + public: /** diff --git a/DSView/pv/view/logicsignal.cpp b/DSView/pv/view/logicsignal.cpp index df0bbb4e..9e9ae593 100644 --- a/DSView/pv/view/logicsignal.cpp +++ b/DSView/pv/view/logicsignal.cpp @@ -273,5 +273,48 @@ void LogicSignal::paint_type_options(QPainter &p, int right, bool hover, int act edgeTrig_rect.right() - 5, edgeTrig_rect.bottom() - 5); } +bool LogicSignal::measure(const QPointF &p, uint64_t &index0, uint64_t &index1, uint64_t &index2) const +{ + 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; + + uint64_t index = _data->samplerate() * (_view->offset() - _data->get_start_time() + p.x() * _view->scale()); + if (index == 0) + return false; + + const uint64_t sig_mask = 1ULL << get_index(); + bool sample = snapshot->get_sample(index) & sig_mask; + index--; + if (!snapshot->get_pre_edge(index, sample, 1, get_index())) + return false; + + index0 = index; + sample = snapshot->get_sample(index) & sig_mask; + index++; + if (!snapshot->get_nxt_edge(index, sample, snapshot->get_sample_count(), 1, get_index())) + return false; + + index1 = index; + sample = snapshot->get_sample(index) & sig_mask; + index++; + if (!snapshot->get_nxt_edge(index, sample, snapshot->get_sample_count(), 1, get_index())) + index2 = 0; + else + index2 = index; + + return true; + } + return false; +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/logicsignal.h b/DSView/pv/view/logicsignal.h index 47b46431..75ea8e4d 100644 --- a/DSView/pv/view/logicsignal.h +++ b/DSView/pv/view/logicsignal.h @@ -76,6 +76,8 @@ public: const std::vector< std::pair > cur_edges() const; + bool measure(const QPointF &p, uint64_t &index0, uint64_t &index1, uint64_t &index2) const; + protected: void paint_type_options(QPainter &p, int right, bool hover, int action); diff --git a/DSView/pv/view/ruler.cpp b/DSView/pv/view/ruler.cpp index a96a8561..b4b2ba9b 100644 --- a/DSView/pv/view/ruler.cpp +++ b/DSView/pv/view/ruler.cpp @@ -134,6 +134,29 @@ QString Ruler::format_time(double t) return format_time(t, _cur_prefix); } +QString Ruler::format_real_time(uint64_t delta_index, uint64_t sample_rate) +{ + uint64_t delta_time = delta_index * std::pow(10, 12) / sample_rate; + + if (delta_time == 0) + return "0"; + + int zero = 0; + int prefix = (int)floor(log10(delta_time)); + while(delta_time == (delta_time/10*10)) { + delta_time /= 10; + zero++; + } + + return format_time(delta_time * 1.0f / std::pow(10, 12-zero), prefix/3+1, prefix/3*3 > zero ? prefix/3*3 - zero : 0); +} + +QString Ruler::format_real_freq(uint64_t delta_index, uint64_t sample_rate) +{ + const double delta_period = delta_index * 1.0f / sample_rate; + return format_freq(delta_period); +} + TimeMarker* Ruler::get_grabbed_cursor() { return _grabbed_marker; @@ -182,8 +205,8 @@ void Ruler::mouseMoveEvent(QMouseEvent *e) (void)e; if (_grabbed_marker) { - _grabbed_marker->set_time(_view.offset() + - _view.hover_point().x() * _view.scale()); + _grabbed_marker->set_index((_view.offset() + + _view.hover_point().x() * _view.scale()) * _view.session().get_device()->get_sample_rate()); } update(); @@ -242,19 +265,17 @@ void Ruler::mouseReleaseEvent(QMouseEvent *event) _cursor_sel_visible = true; } else { int overCursor; - double time = _view.offset() + (_cursor_sel_x + 0.5) * _view.scale(); + uint64_t index = (_view.offset() + (_cursor_sel_x + 0.5) * _view.scale()) * _view.session().get_device()->get_sample_rate(); overCursor = in_cursor_sel_rect(event->pos()); if (overCursor == 0) { - //Cursor *newCursor = new Cursor(_view, CursorColor[_view.get_cursorList().size() % 8], time); - //_view.get_cursorList().push_back(newCursor); - _view.add_cursor(CursorColor[_view.get_cursorList().size() % 8], time); + _view.add_cursor(CursorColor[_view.get_cursorList().size() % 8], index); _view.show_cursors(true); addCursor = true; } else if (overCursor > 0) { list::iterator i = _view.get_cursorList().begin(); while (--overCursor != 0) i++; - (*i)->set_time(time); + (*i)->set_index(index); } _cursor_sel_visible = false; } @@ -262,10 +283,6 @@ void Ruler::mouseReleaseEvent(QMouseEvent *event) int overCursor; overCursor = in_cursor_sel_rect(event->pos()); if (overCursor > 0) { -// list::iterator i = _view.get_cursorList().begin(); -// while (--overCursor != 0) -// i++; -// _view.set_scale_offset(_view.scale(), (*i)->time() - _view.scale() * _view.viewport()->width() / 2); _view.set_cursor_middle(overCursor - 1); } diff --git a/DSView/pv/view/ruler.h b/DSView/pv/view/ruler.h index 114ff9ff..1f322470 100644 --- a/DSView/pv/view/ruler.h +++ b/DSView/pv/view/ruler.h @@ -25,6 +25,7 @@ #define DSVIEW_PV_VIEW_RULER_H #include +#include namespace pv { namespace view { @@ -66,6 +67,8 @@ public: unsigned precision = pricision); static QString format_freq(double period, unsigned precision = pricision); QString format_time(double t); + static QString format_real_time(uint64_t delta_index, uint64_t sample_rate); + static QString format_real_freq(uint64_t delta_index, uint64_t sample_rate); TimeMarker* get_grabbed_cursor(); void set_grabbed_cursor(TimeMarker* grabbed_marker); diff --git a/DSView/pv/view/timemarker.cpp b/DSView/pv/view/timemarker.cpp index 13856d9c..7fdcbbd9 100644 --- a/DSView/pv/view/timemarker.cpp +++ b/DSView/pv/view/timemarker.cpp @@ -24,6 +24,7 @@ #include "timemarker.h" #include "view.h" +#include "../device/device.h" #include @@ -31,18 +32,29 @@ namespace pv { namespace view { TimeMarker::TimeMarker(View &view, QColor &colour, - double time) : + uint64_t index) : _view(view), - _time(time), - _grabbed(false), + _time(index * 1.0f / view.session().get_device()->get_sample_rate()), + _index(index), + _grabbed(false), _colour(colour) { } +TimeMarker::TimeMarker(View &view, QColor &colour) : + _view(view), + _time(0), + _index(0), + _grabbed(false), + _colour(colour) +{ +} + TimeMarker::TimeMarker(const TimeMarker &s) : QObject(), _view(s._view), _time(s._time), + _index(s._index), _colour(s._colour) { } @@ -61,10 +73,16 @@ double TimeMarker::time() const return _time; } -void TimeMarker::set_time(double time) +uint64_t TimeMarker::index() const { - _time = time; - time_changed(); + return _index; +} + +void TimeMarker::set_index(uint64_t index) +{ + _index = index; + _time = index * 1.0f / _view.session().get_device()->get_sample_rate(); + time_changed(); } void TimeMarker::paint(QPainter &p, const QRect &rect, const bool highlight) diff --git a/DSView/pv/view/timemarker.h b/DSView/pv/view/timemarker.h index ad0ca7e6..e82b4c62 100644 --- a/DSView/pv/view/timemarker.h +++ b/DSView/pv/view/timemarker.h @@ -28,6 +28,8 @@ #include #include +#include + class QPainter; class QRect; @@ -47,7 +49,8 @@ protected: * @param colour A reference to the colour of this cursor. * @param time The time to set the flag to. */ - TimeMarker(View &view, QColor &colour, double time); + TimeMarker(View &view, QColor &colour, uint64_t index); + TimeMarker(View &view, QColor &colour); /** * Copy constructor @@ -59,11 +62,12 @@ public: * Gets the time of the marker. */ double time() const; + uint64_t index() const; /** * Sets the time of the marker. */ - void set_time(double time); + void set_index(uint64_t index); /* * @@ -104,6 +108,7 @@ protected: View &_view; double _time; + uint64_t _index; QSizeF _text_size; diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index 1a912d40..af440a76 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -125,10 +125,10 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget _header->setObjectName(tr("ViewArea_header")); _show_trig_cursor = false; - _trig_cursor = new Cursor(*this, Trace::dsLightRed, 0); + _trig_cursor = new Cursor(*this, Trace::dsLightRed); _show_search_cursor = false; _search_pos = 0; - _search_cursor = new Cursor(*this, Trace::dsLightBlue, _search_pos); + _search_cursor = new Cursor(*this, Trace::dsLightBlue); } SigSession& View::session() @@ -343,7 +343,7 @@ void View::set_trig_pos(quint64 trig_pos) { const double time = trig_pos * 1.0f / _session.get_device()->get_sample_rate(); _trig_pos = trig_pos; - _trig_cursor->set_time(time); + _trig_cursor->set_index(trig_pos); _show_trig_cursor = true; set_scale_offset(_scale, time - _scale * get_view_width() / 2); _ruler->update(); @@ -356,7 +356,7 @@ void View::set_search_pos(uint64_t search_pos) const double time = search_pos * 1.0f / _session.get_device()->get_sample_rate(); _search_pos = search_pos; - _search_cursor->set_time(time); + _search_cursor->set_index(search_pos); set_scale_offset(_scale, time - _scale * get_view_width() / 2); _ruler->update(); _viewport->update(); @@ -464,8 +464,7 @@ void View::update_scale() _preScale = _scale; _preOffset = _offset; - const double time = _trig_pos * 1.0f / sample_rate; - _trig_cursor->set_time(time); + _trig_cursor->set_index(_trig_pos); _ruler->update(); _viewport->update(); @@ -697,9 +696,9 @@ Ruler* View::get_ruler() return _ruler; } -void View::add_cursor(QColor color, double time) +void View::add_cursor(QColor color, uint64_t index) { - Cursor *newCursor = new Cursor(*this, color, time); + Cursor *newCursor = new Cursor(*this, color, index); _cursorList.push_back(newCursor); cursor_update(); } @@ -728,24 +727,14 @@ void View::receive_data(quint64 length) _viewport->set_receive_len(length); } -QString View::get_mm_width() +Viewport * View::get_viewport() { - return _viewport->get_mm_width(); -} - -QString View::get_mm_period() -{ - return _viewport->get_mm_period(); -} - -QString View::get_mm_freq() -{ - return _viewport->get_mm_freq(); + return _viewport; } QString View::get_cm_time(int index) { - return _ruler->format_time(get_cursor_time(index)); + return _ruler->format_real_time(get_cursor_samples(index), _session.get_device()->get_sample_rate()); } QString View::get_cm_delta(int index1, int index2) @@ -753,8 +742,10 @@ QString View::get_cm_delta(int index1, int index2) if (index1 == index2) return "0"; - return _ruler->format_time(abs(get_cursor_time(index1) - - get_cursor_time(index2))); + uint64_t samples1 = get_cursor_samples(index1); + uint64_t samples2 = get_cursor_samples(index2); + uint64_t delta_sample = (samples1 > samples2) ? samples1 - samples2 : samples2 - samples1; + return _ruler->format_real_time(delta_sample, _session.get_device()->get_sample_rate()); } double View::get_cursor_time(int index) @@ -773,17 +764,18 @@ double View::get_cursor_time(int index) uint64_t View::get_cursor_samples(int index) { - const double time = get_cursor_time(index); - const uint64_t sample_rate = _session.get_device()->get_sample_limit(); - assert(sample_rate !=0); + assert(index < (int)_cursorList.size()); - return time*sample_rate; + int curIndex = 0; + for (list::iterator i = _cursorList.begin(); + i != _cursorList.end(); i++) { + if (index == curIndex) { + return (*i)->index(); + } + curIndex++; + } } -void View::on_mouse_moved() -{ - mouse_moved(); -} void View::on_cursor_moved() { cursor_moved(); diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h index 2f82a01e..228318ac 100644 --- a/DSView/pv/view/view.h +++ b/DSView/pv/view/view.h @@ -140,7 +140,7 @@ public: * cursorList */ std::list& get_cursorList(); - void add_cursor(QColor color, double time); + void add_cursor(QColor color, uint64_t index); void del_cursor(Cursor* cursor); void set_cursor_middle(int index); @@ -163,13 +163,10 @@ public: bool need_update() const; uint64_t get_cursor_samples(int index); - QString get_mm_width(); - QString get_mm_period(); - QString get_mm_freq(); + Viewport * get_viewport(); QString get_cm_time(int index); QString get_cm_delta(int index1, int index2); - void on_mouse_moved(); void on_cursor_moved(); void on_state_changed(bool stop); @@ -189,7 +186,6 @@ signals: void cursor_update(); - void mouse_moved(); void cursor_moved(); void mode_changed(); diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp index c8aa4299..8bc05428 100644 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -27,6 +27,7 @@ #include "signal.h" #include "dsosignal.h" +#include "logicsignal.h" #include "../device/devinst.h" #include "../data/logic.h" #include "../data/logicsnapshot.h" @@ -63,6 +64,7 @@ Viewport::Viewport(View &parent) : _mm_width = "#####"; _mm_period = "#####"; _mm_freq = "#####"; + _mm_duty = "#####"; _measure_en = true; triggered = false; timer_cnt = 0; @@ -110,7 +112,7 @@ void Viewport::paintEvent(QPaintEvent *event) t->paint_back(p, 0, _view.get_view_width()); } - p.setRenderHint(QPainter::Antialiasing); + p.setRenderHint(QPainter::Antialiasing, false); if (_view.session().get_device()->dev_inst()->mode == LOGIC || _view.session().get_instant()) { switch(_view.session().get_capture_state()) { @@ -137,7 +139,7 @@ void Viewport::paintEvent(QPaintEvent *event) t->paint_fore(p, 0, _view.get_view_width()); } - p.setRenderHint(QPainter::Antialiasing, false); + //p.setRenderHint(QPainter::Antialiasing, false); if (_view.get_signalHeight() != _curSignalHeight) _curSignalHeight = _view.get_signalHeight(); @@ -159,7 +161,7 @@ void Viewport::paintSignals(QPainter &p) pixmap.fill(Qt::transparent); QPainter dbp(&pixmap); dbp.initFrom(this); - p.setRenderHint(QPainter::Antialiasing, false); + //p.setRenderHint(QPainter::Antialiasing, false); BOOST_FOREACH(const shared_ptr t, traces) { assert(t); @@ -404,12 +406,10 @@ void Viewport::mouseMoveEvent(QMouseEvent *event) const double cur_time = _view.offset() + _view.hover_point().x() * _view.scale(); const double pos = cur_time * sample_rate; const double pos_delta = pos - (int)pos; - if ( pos_delta < HitCursorTimeMargin) - grabbed_marker->set_time(1.0 / sample_rate * floor(pos)); - else if (pos_delta > (1.0 - HitCursorTimeMargin)) - grabbed_marker->set_time(1.0 / sample_rate * ceil(pos)); + if ( pos_delta < 0.5) + grabbed_marker->set_index(floor(pos)); else - grabbed_marker->set_time(cur_time); + grabbed_marker->set_index(ceil(pos)); } measure(); } @@ -499,99 +499,42 @@ void Viewport::set_receive_len(quint64 length) void Viewport::measure() { - uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); + 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); + shared_ptr logicSig; + if (logicSig = dynamic_pointer_cast(s)) { + if (logicSig->measure(_view.hover_point(), _cur_sample, _nxt_sample, _thd_sample)) { + _measure_shown = true; - const vector< boost::shared_ptr > sigs(_view.session().get_signals()); - BOOST_FOREACH(const boost::shared_ptr s, sigs) { - assert(s); - const int curY = _view.hover_point().y(); - const double curX = _view.hover_point().x(); - if (curY <= View::SignalMargin || s->get_type() != Trace::DS_LOGIC) { - _measure_shown = false; - break; - } else if ( curY < s->get_y() + _view.get_signalHeight() * 0.5 && - curY > (s->get_y() - _view.get_signalHeight() * 0.5)) { - if (s->cur_edges().size() > 2) { - const double pixels_offset = _view.offset() / _view.scale(); - const double samples_per_pixel = sample_rate * _view.scale(); + _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) : "#####"; - uint64_t findIndex = curX / _view.get_view_width() * s->cur_edges().size(); - uint64_t left_findIndex = 0; - uint64_t right_findIndex = s->cur_edges().size() - 1; - int times = 0; - while(!s->cur_edges().empty() && times < 20) { - findIndex = min(findIndex, (uint64_t)(s->cur_edges().size() - 2)); - const double pre_edge_x = - s->cur_edges().at(findIndex).first / samples_per_pixel - pixels_offset; - const double aft_edge_x = - s->cur_edges().at(findIndex + 1).first / samples_per_pixel - pixels_offset; - if ( curX >= pre_edge_x && curX <= aft_edge_x) { - if (aft_edge_x - pre_edge_x < 2 || - findIndex == 0 || - findIndex == s->cur_edges().size() - 2) { - _measure_shown = false; - break; - } else { - _measure_shown = true; - _cur_sample = s->cur_edges().at(findIndex).first; - _nxt_sample = s->cur_edges().at(findIndex + 1).first; - _cur_preX = pre_edge_x; - _cur_aftX = aft_edge_x; - //if (findIndex >= 0 && findIndex <= s->cur_edges().size() - 4) { - if(findIndex <= s->cur_edges().size() - 4) { - _thd_sample = s->cur_edges().at(findIndex + 2).first; - _cur_thdX = - s->cur_edges().at(findIndex + 2).first / samples_per_pixel - pixels_offset; - } else { - _thd_sample = 0; - _cur_thdX = 0; + 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(); - } - _cur_midY = s->get_y(); - break; - } - } else if (curX < pre_edge_x) { - right_findIndex = findIndex; - findIndex = (left_findIndex + findIndex) / 2; - } else if (curX > aft_edge_x) { - left_findIndex = findIndex; - findIndex = (right_findIndex + findIndex) / 2; - } - times++; - } - } - break; - } else if (curY >= s->get_y() + _view.get_signalHeight() && - curY <= (s->get_y() + _view.get_signalHeight() + 2 * View::SignalMargin)){ - _measure_shown = false; - break; - }else { - _measure_shown = false; - } + _mm_duty = _thd_sample != 0 ? QString::number((_nxt_sample - _cur_sample) * 100.0f / (_thd_sample - _cur_sample), 'f', 2)+"%" : + "#####"; + mouse_measure(); + return; + } else { + _mm_width = "#####"; + _mm_period = "#####"; + _mm_freq = "#####"; + _mm_duty = "#####"; + } + mouse_measure(); + } } - if (_measure_shown == true) { - const uint64_t delta_sample = _nxt_sample - _cur_sample; - const uint64_t delta1_sample = _thd_sample - _cur_sample; - //assert(delta_sample >= 0); - const double delta_time = delta_sample * 1.0f / sample_rate; - const double delta1_time = delta1_sample * 1.0f / sample_rate; - const int order = (int)floorf(log10f(delta_time)); - unsigned int prefix = (15 + order) / 3; - assert(prefix < 9); - - _mm_width = _view.get_ruler()->format_time(delta_time, prefix); - _mm_period = _thd_sample != 0 ? _view.get_ruler()->format_time(delta1_time, prefix) : - "#####"; - _mm_freq = _thd_sample != 0 ? _view.get_ruler()->format_freq(delta1_time) : - "#####"; - } else { - _mm_width = "#####"; - _mm_period = "#####"; - _mm_freq = "#####"; - } - - _view.on_mouse_moved(); + _measure_shown = false; + return; } void Viewport::paintMeasure(QPainter &p) @@ -614,13 +557,15 @@ void Viewport::paintMeasure(QPainter &p) double typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, Qt::AlignLeft | Qt::AlignTop, _mm_width).width() + 150; QRectF measure_rect = QRectF(_view.hover_point().x(), _view.hover_point().y(), - (double)typical_width, 60.0); + (double)typical_width, 80.0); QRectF measure1_rect = QRectF(_view.hover_point().x(), _view.hover_point().y(), (double)typical_width, 20.0); QRectF measure2_rect = QRectF(_view.hover_point().x(), _view.hover_point().y() + 20, (double)typical_width, 20.0); QRectF measure3_rect = QRectF(_view.hover_point().x(), _view.hover_point().y() + 40, (double)typical_width, 20.0); + QRectF measure4_rect = QRectF(_view.hover_point().x(), _view.hover_point().y() + 60, + (double)typical_width, 20.0); p.setPen(Qt::NoPen); p.setBrush(QColor(17, 133, 209, 150)); @@ -633,22 +578,23 @@ void Viewport::paintMeasure(QPainter &p) "Period: " + _mm_period); p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter, "Frequency: " + _mm_freq); + p.drawText(measure4_rect, Qt::AlignRight | Qt::AlignVCenter, + "Duty Cycle: " + _mm_duty); } } -QString Viewport::get_mm_width() +QString Viewport::get_measure(QString option) { - return _mm_width; -} - -QString Viewport::get_mm_period() -{ - return _mm_period; -} - -QString Viewport::get_mm_freq() -{ - return _mm_freq; + if(option.compare("width") == 0) + return _mm_width; + else if (option.compare("period") == 0) + return _mm_period; + else if (option.compare("frequency") == 0) + return _mm_freq; + else if (option.compare("duty") == 0) + return _mm_duty; + else + return "#####"; } void Viewport::set_measure_en(int enable) diff --git a/DSView/pv/view/viewport.h b/DSView/pv/view/viewport.h index 1f8157a9..68cc93c6 100644 --- a/DSView/pv/view/viewport.h +++ b/DSView/pv/view/viewport.h @@ -47,7 +47,6 @@ class Viewport : public QWidget public: static const int HitCursorMargin = 10; - static const double HitCursorTimeMargin = 0.3; public: explicit Viewport(View &parent); @@ -58,9 +57,7 @@ public: void set_receive_len(quint64 length); - QString get_mm_width(); - QString get_mm_period(); - QString get_mm_freq(); + QString get_measure(QString option); void set_measure_en(int enable); @@ -88,6 +85,9 @@ private slots: void on_traces_moved(); void on_trigger_timer(); +signals: + void mouse_measure(); + private: View &_view; @@ -109,13 +109,14 @@ private: uint64_t _cur_sample; uint64_t _nxt_sample; uint64_t _thd_sample; - int64_t _cur_preX; - int64_t _cur_aftX; - int64_t _cur_thdX; - int64_t _cur_midY; + double _cur_preX; + double _cur_aftX; + double _cur_thdX; + double _cur_midY; QString _mm_width; QString _mm_period; QString _mm_freq; + QString _mm_duty; QTimer trigger_timer; bool triggered;