mirror of
https://github.com/DreamSourceLab/DSView.git
synced 2025-01-23 13:42:55 +08:00
Fix measure pricision issue @ LA mode
This commit is contained in:
parent
153d1f9ebd
commit
bad63a6ede
12
.gitignore
vendored
12
.gitignore
vendored
@ -31,16 +31,18 @@ Makefile.in
|
|||||||
configure
|
configure
|
||||||
aclocal.m4
|
aclocal.m4
|
||||||
|
|
||||||
DSLogic-gui/ui_*.h
|
DSView/ui_*.h
|
||||||
DSLogic-gui/DSLogic
|
DSView/DSView
|
||||||
DSLogic-gui/install_manifest.txt
|
DSView/install_manifest.txt
|
||||||
|
|
||||||
moc_*.cxx
|
moc_*.cxx
|
||||||
moc_*.cxx_parameters
|
moc_*.cxx_parameters
|
||||||
|
|
||||||
libsigrok4DSLogic/version.h
|
libsigrok4DSL/version.h
|
||||||
|
|
||||||
libusbx-1.0.18/doc/doxygen.cfg
|
libusbx-1.0.18/doc/doxygen.cfg
|
||||||
libusbx-1.0.18/m4/
|
libusbx-1.0.18/m4/
|
||||||
|
|
||||||
|
DSView-prj
|
||||||
|
libsigrokdecode
|
||||||
|
build*
|
||||||
|
@ -208,8 +208,6 @@ void LogicSnapshot::get_subsampled_edges(
|
|||||||
boost::lock_guard<boost::recursive_mutex> lock(_mutex);
|
boost::lock_guard<boost::recursive_mutex> lock(_mutex);
|
||||||
|
|
||||||
const uint64_t block_length = (uint64_t)max(min_length, 1.0f);
|
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;
|
const uint64_t sig_mask = 1ULL << sig_index;
|
||||||
|
|
||||||
if (!edges.empty())
|
if (!edges.empty())
|
||||||
@ -220,6 +218,51 @@ void LogicSnapshot::get_subsampled_edges(
|
|||||||
|
|
||||||
while (index + block_length <= end)
|
while (index + block_length <= end)
|
||||||
{
|
{
|
||||||
|
// search next edge
|
||||||
|
get_nxt_edge(index, last_sample, end, min_length, sig_index);
|
||||||
|
|
||||||
|
//----- Store the edge -----//
|
||||||
|
|
||||||
|
// Take the last sample of the quanization block
|
||||||
|
const int64_t 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;
|
||||||
|
edges.push_back(pair<int64_t, bool>(index, 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 != get_sample_count() - 1) ||
|
||||||
|
((end == get_sample_count() - 1) && end_sample != last_sample))
|
||||||
|
edges.push_back(pair<int64_t, bool>(end, end_sample));
|
||||||
|
|
||||||
|
if (end == get_sample_count() - 1)
|
||||||
|
edges.push_back(pair<int64_t, bool>(end + 1, ~last_sample));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LogicSnapshot::get_nxt_edge(
|
||||||
|
uint64_t &index, bool last_sample, uint64_t end,
|
||||||
|
float min_length, int sig_index)
|
||||||
|
{
|
||||||
|
unsigned int level;
|
||||||
|
bool fast_forward;
|
||||||
|
|
||||||
|
assert(index > 0);
|
||||||
|
|
||||||
|
const unsigned int min_level = max((int)floorf(logf(min_length) /
|
||||||
|
LogMipMapScaleFactor) - 1, 0);
|
||||||
|
const uint64_t sig_mask = 1ULL << sig_index;
|
||||||
|
|
||||||
|
if (index >= end)
|
||||||
|
return false;
|
||||||
|
|
||||||
//----- Continue to search -----//
|
//----- Continue to search -----//
|
||||||
level = min_level;
|
level = min_level;
|
||||||
|
|
||||||
@ -257,7 +300,7 @@ void LogicSnapshot::get_subsampled_edges(
|
|||||||
(level + 1) * MipMapScalePower;
|
(level + 1) * MipMapScalePower;
|
||||||
index = pow2_ceil(index, min_level_scale_power);
|
index = pow2_ceil(index, min_level_scale_power);
|
||||||
if (index >= end)
|
if (index >= end)
|
||||||
break;
|
return false;
|
||||||
|
|
||||||
// We can fast forward only if there was no change
|
// We can fast forward only if there was no change
|
||||||
const bool sample =
|
const bool sample =
|
||||||
@ -347,60 +390,25 @@ void LogicSnapshot::get_subsampled_edges(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----- Store the edge -----//
|
if (index >= end)
|
||||||
|
return false;
|
||||||
// Take the last sample of the quanization block
|
else
|
||||||
const int64_t final_index = index + block_length;
|
return true;
|
||||||
if (index + block_length > end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Store the final state
|
|
||||||
const bool final_sample =
|
|
||||||
(get_sample(final_index - 1) & sig_mask) != 0;
|
|
||||||
edges.push_back(pair<int64_t, bool>(index, 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 != get_sample_count() - 1) ||
|
|
||||||
((end == get_sample_count() - 1) && end_sample != last_sample))
|
|
||||||
edges.push_back(pair<int64_t, bool>(end, end_sample));
|
|
||||||
|
|
||||||
if (end == get_sample_count() - 1)
|
|
||||||
edges.push_back(pair<int64_t, bool>(end + 1, ~last_sample));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int LogicSnapshot::get_first_edge(
|
bool LogicSnapshot::get_pre_edge(
|
||||||
uint64_t &edge_index, bool &edge,
|
uint64_t &index, bool last_sample,
|
||||||
uint64_t start, uint64_t end,
|
float min_length, int sig_index)
|
||||||
int sig_index, int edge_type,
|
|
||||||
int flag_index, int flag)
|
|
||||||
{
|
{
|
||||||
uint64_t index = start;
|
|
||||||
unsigned int level;
|
unsigned int level;
|
||||||
bool last_sample;
|
|
||||||
bool fast_forward;
|
bool fast_forward;
|
||||||
|
|
||||||
assert(end <= get_sample_count());
|
assert(index < get_sample_count());
|
||||||
assert(start <= end);
|
|
||||||
assert(sig_index >= 0);
|
|
||||||
assert(sig_index < 64);
|
|
||||||
|
|
||||||
boost::lock_guard<boost::recursive_mutex> lock(_mutex);
|
const unsigned int min_level = max((int)floorf(logf(min_length) /
|
||||||
|
LogMipMapScaleFactor) - 1, 0);
|
||||||
const uint64_t block_length = 1;
|
|
||||||
const unsigned int min_level = 0;
|
|
||||||
const uint64_t sig_mask = 1ULL << sig_index;
|
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;
|
|
||||||
|
|
||||||
while (index + block_length <= end)
|
|
||||||
{
|
|
||||||
//----- Continue to search -----//
|
//----- Continue to search -----//
|
||||||
level = min_level;
|
level = min_level;
|
||||||
|
|
||||||
@ -408,14 +416,17 @@ int LogicSnapshot::get_first_edge(
|
|||||||
// at the minimum level.
|
// at the minimum level.
|
||||||
fast_forward = (_mip_map[level].data != NULL);
|
fast_forward = (_mip_map[level].data != NULL);
|
||||||
|
|
||||||
// Search individual samples up to the beginning of
|
if (min_length < MipMapScaleFactor)
|
||||||
// the next first level mip map block
|
{
|
||||||
uint64_t final_index = min(end,
|
// Search individual samples down to the ending of
|
||||||
pow2_ceil(index, MipMapScalePower));
|
// 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;
|
||||||
|
|
||||||
for (; index < final_index &&
|
for (; index >= final_index; index--)
|
||||||
(index & ~(~0 << MipMapScalePower)) != 0;
|
|
||||||
index++)
|
|
||||||
{
|
{
|
||||||
const bool sample =
|
const bool sample =
|
||||||
(get_sample(index) & sig_mask) != 0;
|
(get_sample(index) & sig_mask) != 0;
|
||||||
@ -423,8 +434,37 @@ int LogicSnapshot::get_first_edge(
|
|||||||
// If there was a change we cannot fast forward
|
// If there was a change we cannot fast forward
|
||||||
if (sample != last_sample) {
|
if (sample != last_sample) {
|
||||||
fast_forward = false;
|
fast_forward = false;
|
||||||
break;
|
index++;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (index == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
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 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 (index == 0)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fast_forward) {
|
if (fast_forward) {
|
||||||
@ -434,7 +474,7 @@ int LogicSnapshot::get_first_edge(
|
|||||||
// zooming in on them to find the point where the edge
|
// zooming in on them to find the point where the edge
|
||||||
// begins.
|
// begins.
|
||||||
|
|
||||||
// Slide right and zoom out at the beginnings of mip-map
|
// Slide left and zoom out at the endings of mip-map
|
||||||
// blocks until we encounter a change
|
// blocks until we encounter a change
|
||||||
while (1) {
|
while (1) {
|
||||||
const int level_scale_power =
|
const int level_scale_power =
|
||||||
@ -442,15 +482,15 @@ int LogicSnapshot::get_first_edge(
|
|||||||
const uint64_t offset =
|
const uint64_t offset =
|
||||||
index >> level_scale_power;
|
index >> level_scale_power;
|
||||||
|
|
||||||
// Check if we reached the last block at this
|
// Check if we reached the first block at this
|
||||||
// level, or if there was a change in this block
|
// level, or if there was a change in this block
|
||||||
if (offset >= _mip_map[level].length ||
|
if (offset == 0 ||
|
||||||
(get_subsample(level, offset) &
|
(get_subsample(level, offset) &
|
||||||
sig_mask))
|
sig_mask))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((offset & ~(~0 << MipMapScalePower)) == 0) {
|
if (((offset+1) & ~(~0 << MipMapScalePower)) == 0) {
|
||||||
// If we are now at the beginning of a
|
// If we are now at the ending of a
|
||||||
// higher level mip-map block ascend one
|
// higher level mip-map block ascend one
|
||||||
// level
|
// level
|
||||||
if (level + 1 >= ScaleStepCount ||
|
if (level + 1 >= ScaleStepCount ||
|
||||||
@ -459,14 +499,14 @@ int LogicSnapshot::get_first_edge(
|
|||||||
|
|
||||||
level++;
|
level++;
|
||||||
} else {
|
} else {
|
||||||
// Slide right to the beginning of the
|
// Slide left to the beginning of the
|
||||||
// next mip map block
|
// previous mip map block
|
||||||
index = pow2_ceil(index + 1,
|
index = pow2_ceil(index + 1,
|
||||||
level_scale_power);
|
level_scale_power) - (1 << level_scale_power) - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom in, and slide right until we encounter a change,
|
// Zoom in, and slide left until we encounter a change,
|
||||||
// and repeat until we reach min_level
|
// and repeat until we reach min_level
|
||||||
while (1) {
|
while (1) {
|
||||||
assert(_mip_map[level].data);
|
assert(_mip_map[level].data);
|
||||||
@ -476,9 +516,9 @@ int LogicSnapshot::get_first_edge(
|
|||||||
const uint64_t offset =
|
const uint64_t offset =
|
||||||
index >> level_scale_power;
|
index >> level_scale_power;
|
||||||
|
|
||||||
// Check if we reached the last block at this
|
// Check if we reached the first block at this
|
||||||
// level, or if there was a change in this block
|
// level, or if there was a change in this block
|
||||||
if (offset >= _mip_map[level].length ||
|
if (offset == 0 ||
|
||||||
(get_subsample(level, offset) &
|
(get_subsample(level, offset) &
|
||||||
sig_mask)) {
|
sig_mask)) {
|
||||||
// Zoom in unless we reached the minimum
|
// Zoom in unless we reached the minimum
|
||||||
@ -488,375 +528,31 @@ int LogicSnapshot::get_first_edge(
|
|||||||
|
|
||||||
level--;
|
level--;
|
||||||
} else {
|
} else {
|
||||||
// Slide right to the beginning of the
|
// Slide left to the ending of the
|
||||||
// next mip map block
|
// previous mip map block
|
||||||
index = pow2_ceil(index + 1,
|
index = pow2_ceil(index + 1,
|
||||||
level_scale_power);
|
level_scale_power) - (1 << level_scale_power) - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If individual samples within the limit of resolution,
|
// If individual samples within the limit of resolution,
|
||||||
// do a linear search for the next transition within the
|
// do a linear search for the next transition within the
|
||||||
// block
|
// block
|
||||||
for (; index < end; index++) {
|
if (min_length < MipMapScaleFactor) {
|
||||||
|
for (; index >= 0; index--) {
|
||||||
const bool sample = (get_sample(index) &
|
const bool sample = (get_sample(index) &
|
||||||
sig_mask) != 0;
|
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 (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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogicSnapshot::get_edges(
|
|
||||||
std::vector<EdgePair> &edges,
|
|
||||||
uint64_t start, uint64_t end, int sig_index, int edge_type)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
boost::lock_guard<boost::recursive_mutex> lock(_mutex);
|
|
||||||
|
|
||||||
const uint64_t block_length = 1;
|
|
||||||
const unsigned int min_level = 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;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// 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) {
|
if (sample != last_sample) {
|
||||||
fast_forward = false;
|
index++;
|
||||||
break;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fast_forward) {
|
if (index == 0)
|
||||||
|
return 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.
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
|
|
||||||
// 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<int64_t, bool>(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<int64_t, bool>(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<boost::recursive_mutex> 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)
|
|
||||||
{
|
|
||||||
//----- 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,
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the final state
|
|
||||||
min_pulse = min(end - last_index, min_pulse);
|
|
||||||
|
|
||||||
return min_pulse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t LogicSnapshot::get_subsample(int level, uint64_t offset) const
|
uint64_t LogicSnapshot::get_subsample(int level, uint64_t offset) const
|
||||||
|
@ -90,15 +90,11 @@ public:
|
|||||||
uint64_t start, uint64_t end,
|
uint64_t start, uint64_t end,
|
||||||
float min_length, int sig_index);
|
float min_length, int sig_index);
|
||||||
|
|
||||||
int get_first_edge(uint64_t &edge_index, bool &edge,
|
bool get_nxt_edge(uint64_t &index, bool last_sample, uint64_t end,
|
||||||
uint64_t start, uint64_t end,
|
float min_length, int sig_index);
|
||||||
int sig_index, int edge_type,
|
|
||||||
int flag_index, int flag);
|
|
||||||
|
|
||||||
void get_edges(std::vector<EdgePair> &edges,
|
bool get_pre_edge(uint64_t &index, bool last_sample,
|
||||||
uint64_t start, uint64_t end, int sig_index, int edge_type);
|
float min_length, int sig_index);
|
||||||
|
|
||||||
uint64_t get_min_pulse(uint64_t start, uint64_t end, int sig_index);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t get_subsample(int level, uint64_t offset) const;
|
uint64_t get_subsample(int level, uint64_t offset) const;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "../sigsession.h"
|
#include "../sigsession.h"
|
||||||
#include "../view/cursor.h"
|
#include "../view/cursor.h"
|
||||||
#include "../view/view.h"
|
#include "../view/view.h"
|
||||||
|
#include "../view/viewport.h"
|
||||||
#include "../view/timemarker.h"
|
#include "../view/timemarker.h"
|
||||||
#include "../view/ruler.h"
|
#include "../view/ruler.h"
|
||||||
#include "../view/logicsignal.h"
|
#include "../view/logicsignal.h"
|
||||||
@ -54,9 +55,10 @@ MeasureDock::MeasureDock(QWidget *parent, View &view, SigSession &session) :
|
|||||||
_mouse_groupBox = new QGroupBox("Mouse measurement", this);
|
_mouse_groupBox = new QGroupBox("Mouse measurement", this);
|
||||||
_fen_checkBox = new QCheckBox("Enable floating measurement", this);
|
_fen_checkBox = new QCheckBox("Enable floating measurement", this);
|
||||||
_fen_checkBox->setChecked(true);
|
_fen_checkBox->setChecked(true);
|
||||||
_width_label = new QLabel(view.get_mm_width(), this);
|
_width_label = new QLabel("#####", this);
|
||||||
_period_label = new QLabel(view.get_mm_period(), this);
|
_period_label = new QLabel("#####", this);
|
||||||
_freq_label = new QLabel(view.get_mm_freq(), this);
|
_freq_label = new QLabel("#####", this);
|
||||||
|
_duty_label = new QLabel("#####", this);
|
||||||
|
|
||||||
_mouse_layout = new QGridLayout();
|
_mouse_layout = new QGridLayout();
|
||||||
_mouse_layout->addWidget(_fen_checkBox, 0, 0, 1, 2);
|
_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(_period_label, 2, 1);
|
||||||
_mouse_layout->addWidget(new QLabel("Frequency: ", this), 3, 0);
|
_mouse_layout->addWidget(new QLabel("Frequency: ", this), 3, 0);
|
||||||
_mouse_layout->addWidget(_freq_label, 3, 1);
|
_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), 0, 2);
|
||||||
_mouse_layout->addWidget(new QLabel(this), 1, 2);
|
_mouse_layout->addWidget(new QLabel(this), 1, 2);
|
||||||
_mouse_layout->addWidget(new QLabel(this), 2, 2);
|
_mouse_layout->addWidget(new QLabel(this), 2, 2);
|
||||||
_mouse_layout->addWidget(new QLabel(this), 3, 2);
|
_mouse_layout->addWidget(new QLabel(this), 3, 2);
|
||||||
|
_mouse_layout->addWidget(new QLabel(this), 4, 2);
|
||||||
_mouse_layout->setColumnStretch(2, 1);
|
_mouse_layout->setColumnStretch(2, 1);
|
||||||
_mouse_groupBox->setLayout(_mouse_layout);
|
_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(_t3_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update()));
|
||||||
|
|
||||||
connect(_fen_checkBox, SIGNAL(stateChanged(int)), &_view, SLOT(set_measure_en(int)));
|
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()
|
MeasureDock::~MeasureDock()
|
||||||
@ -216,11 +222,12 @@ void MeasureDock::cursor_update()
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeasureDock::mouse_moved()
|
void MeasureDock::mouse_measure()
|
||||||
{
|
{
|
||||||
_width_label->setText(_view.get_mm_width());
|
_width_label->setText(_view.get_viewport()->get_measure("width"));
|
||||||
_period_label->setText(_view.get_mm_period());
|
_period_label->setText(_view.get_viewport()->get_measure("period"));
|
||||||
_freq_label->setText(_view.get_mm_freq());
|
_freq_label->setText(_view.get_viewport()->get_measure("frequency"));
|
||||||
|
_duty_label->setText(_view.get_viewport()->get_measure("duty"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeasureDock::cursor_moved()
|
void MeasureDock::cursor_moved()
|
||||||
|
@ -74,7 +74,7 @@ private slots:
|
|||||||
public slots:
|
public slots:
|
||||||
void cursor_update();
|
void cursor_update();
|
||||||
void cursor_moved();
|
void cursor_moved();
|
||||||
void mouse_moved();
|
void mouse_measure();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SigSession &_session;
|
SigSession &_session;
|
||||||
@ -86,6 +86,7 @@ private:
|
|||||||
QLabel *_width_label;
|
QLabel *_width_label;
|
||||||
QLabel *_period_label;
|
QLabel *_period_label;
|
||||||
QLabel *_freq_label;
|
QLabel *_freq_label;
|
||||||
|
QLabel *_duty_label;
|
||||||
|
|
||||||
QGridLayout *_cursor_layout;
|
QGridLayout *_cursor_layout;
|
||||||
QGroupBox *_cursor_groupBox;
|
QGroupBox *_cursor_groupBox;
|
||||||
|
@ -244,8 +244,6 @@ void MainWindow::setup_ui()
|
|||||||
SLOT(cursor_update()));
|
SLOT(cursor_update()));
|
||||||
connect(_view, SIGNAL(cursor_moved()), _measure_widget,
|
connect(_view, SIGNAL(cursor_moved()), _measure_widget,
|
||||||
SLOT(cursor_moved()));
|
SLOT(cursor_moved()));
|
||||||
connect(_view, SIGNAL(mouse_moved()), _measure_widget,
|
|
||||||
SLOT(mouse_moved()));
|
|
||||||
connect(_view, SIGNAL(mode_changed()), this,
|
connect(_view, SIGNAL(mode_changed()), this,
|
||||||
SLOT(update_device_list()));
|
SLOT(update_device_list()));
|
||||||
|
|
||||||
|
@ -51,8 +51,14 @@ const int Cursor::ArrowSize = 10;
|
|||||||
|
|
||||||
const int Cursor::CloseSize = 10;
|
const int Cursor::CloseSize = 10;
|
||||||
|
|
||||||
Cursor::Cursor(View &view, QColor color, double time) :
|
Cursor::Cursor(View &view, QColor color, uint64_t index) :
|
||||||
TimeMarker(view, color, time),
|
TimeMarker(view, color, index),
|
||||||
|
_other(*this)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Cursor::Cursor(View &view, QColor color) :
|
||||||
|
TimeMarker(view, color),
|
||||||
_other(*this)
|
_other(*this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,9 @@ public:
|
|||||||
* @param time The time to set the flag to.
|
* @param time The time to set the flag to.
|
||||||
* @param other A reference to the other cursor.
|
* @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:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -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);
|
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<pv::data::LogicSnapshot> > &snapshots =
|
||||||
|
_data->get_snapshots();
|
||||||
|
if (snapshots.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const boost::shared_ptr<pv::data::LogicSnapshot> &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 view
|
||||||
} // namespace pv
|
} // namespace pv
|
||||||
|
@ -76,6 +76,8 @@ public:
|
|||||||
|
|
||||||
const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
|
const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
|
||||||
|
|
||||||
|
bool measure(const QPointF &p, uint64_t &index0, uint64_t &index1, uint64_t &index2) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paint_type_options(QPainter &p, int right, bool hover, int action);
|
void paint_type_options(QPainter &p, int right, bool hover, int action);
|
||||||
|
|
||||||
|
@ -134,6 +134,29 @@ QString Ruler::format_time(double t)
|
|||||||
return format_time(t, _cur_prefix);
|
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()
|
TimeMarker* Ruler::get_grabbed_cursor()
|
||||||
{
|
{
|
||||||
return _grabbed_marker;
|
return _grabbed_marker;
|
||||||
@ -182,8 +205,8 @@ void Ruler::mouseMoveEvent(QMouseEvent *e)
|
|||||||
(void)e;
|
(void)e;
|
||||||
|
|
||||||
if (_grabbed_marker) {
|
if (_grabbed_marker) {
|
||||||
_grabbed_marker->set_time(_view.offset() +
|
_grabbed_marker->set_index((_view.offset() +
|
||||||
_view.hover_point().x() * _view.scale());
|
_view.hover_point().x() * _view.scale()) * _view.session().get_device()->get_sample_rate());
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
@ -242,19 +265,17 @@ void Ruler::mouseReleaseEvent(QMouseEvent *event)
|
|||||||
_cursor_sel_visible = true;
|
_cursor_sel_visible = true;
|
||||||
} else {
|
} else {
|
||||||
int overCursor;
|
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());
|
overCursor = in_cursor_sel_rect(event->pos());
|
||||||
if (overCursor == 0) {
|
if (overCursor == 0) {
|
||||||
//Cursor *newCursor = new Cursor(_view, CursorColor[_view.get_cursorList().size() % 8], time);
|
_view.add_cursor(CursorColor[_view.get_cursorList().size() % 8], index);
|
||||||
//_view.get_cursorList().push_back(newCursor);
|
|
||||||
_view.add_cursor(CursorColor[_view.get_cursorList().size() % 8], time);
|
|
||||||
_view.show_cursors(true);
|
_view.show_cursors(true);
|
||||||
addCursor = true;
|
addCursor = true;
|
||||||
} else if (overCursor > 0) {
|
} else if (overCursor > 0) {
|
||||||
list<Cursor*>::iterator i = _view.get_cursorList().begin();
|
list<Cursor*>::iterator i = _view.get_cursorList().begin();
|
||||||
while (--overCursor != 0)
|
while (--overCursor != 0)
|
||||||
i++;
|
i++;
|
||||||
(*i)->set_time(time);
|
(*i)->set_index(index);
|
||||||
}
|
}
|
||||||
_cursor_sel_visible = false;
|
_cursor_sel_visible = false;
|
||||||
}
|
}
|
||||||
@ -262,10 +283,6 @@ void Ruler::mouseReleaseEvent(QMouseEvent *event)
|
|||||||
int overCursor;
|
int overCursor;
|
||||||
overCursor = in_cursor_sel_rect(event->pos());
|
overCursor = in_cursor_sel_rect(event->pos());
|
||||||
if (overCursor > 0) {
|
if (overCursor > 0) {
|
||||||
// list<Cursor*>::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);
|
_view.set_cursor_middle(overCursor - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#define DSVIEW_PV_VIEW_RULER_H
|
#define DSVIEW_PV_VIEW_RULER_H
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace pv {
|
namespace pv {
|
||||||
namespace view {
|
namespace view {
|
||||||
@ -66,6 +67,8 @@ public:
|
|||||||
unsigned precision = pricision);
|
unsigned precision = pricision);
|
||||||
static QString format_freq(double period, unsigned precision = pricision);
|
static QString format_freq(double period, unsigned precision = pricision);
|
||||||
QString format_time(double t);
|
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();
|
TimeMarker* get_grabbed_cursor();
|
||||||
void set_grabbed_cursor(TimeMarker* grabbed_marker);
|
void set_grabbed_cursor(TimeMarker* grabbed_marker);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "timemarker.h"
|
#include "timemarker.h"
|
||||||
|
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
#include "../device/device.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
@ -31,9 +32,19 @@ namespace pv {
|
|||||||
namespace view {
|
namespace view {
|
||||||
|
|
||||||
TimeMarker::TimeMarker(View &view, QColor &colour,
|
TimeMarker::TimeMarker(View &view, QColor &colour,
|
||||||
double time) :
|
uint64_t index) :
|
||||||
_view(view),
|
_view(view),
|
||||||
_time(time),
|
_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),
|
_grabbed(false),
|
||||||
_colour(colour)
|
_colour(colour)
|
||||||
{
|
{
|
||||||
@ -43,6 +54,7 @@ TimeMarker::TimeMarker(const TimeMarker &s) :
|
|||||||
QObject(),
|
QObject(),
|
||||||
_view(s._view),
|
_view(s._view),
|
||||||
_time(s._time),
|
_time(s._time),
|
||||||
|
_index(s._index),
|
||||||
_colour(s._colour)
|
_colour(s._colour)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -61,9 +73,15 @@ double TimeMarker::time() const
|
|||||||
return _time;
|
return _time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimeMarker::set_time(double time)
|
uint64_t TimeMarker::index() const
|
||||||
{
|
{
|
||||||
_time = time;
|
return _index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeMarker::set_index(uint64_t index)
|
||||||
|
{
|
||||||
|
_index = index;
|
||||||
|
_time = index * 1.0f / _view.session().get_device()->get_sample_rate();
|
||||||
time_changed();
|
time_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QRectF>
|
#include <QRectF>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
class QPainter;
|
class QPainter;
|
||||||
class QRect;
|
class QRect;
|
||||||
|
|
||||||
@ -47,7 +49,8 @@ protected:
|
|||||||
* @param colour A reference to the colour of this cursor.
|
* @param colour A reference to the colour of this cursor.
|
||||||
* @param time The time to set the flag to.
|
* @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
|
* Copy constructor
|
||||||
@ -59,11 +62,12 @@ public:
|
|||||||
* Gets the time of the marker.
|
* Gets the time of the marker.
|
||||||
*/
|
*/
|
||||||
double time() const;
|
double time() const;
|
||||||
|
uint64_t index() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the time of the marker.
|
* Sets the time of the marker.
|
||||||
*/
|
*/
|
||||||
void set_time(double time);
|
void set_index(uint64_t index);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
@ -104,6 +108,7 @@ protected:
|
|||||||
View &_view;
|
View &_view;
|
||||||
|
|
||||||
double _time;
|
double _time;
|
||||||
|
uint64_t _index;
|
||||||
|
|
||||||
QSizeF _text_size;
|
QSizeF _text_size;
|
||||||
|
|
||||||
|
@ -125,10 +125,10 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
|
|||||||
_header->setObjectName(tr("ViewArea_header"));
|
_header->setObjectName(tr("ViewArea_header"));
|
||||||
|
|
||||||
_show_trig_cursor = false;
|
_show_trig_cursor = false;
|
||||||
_trig_cursor = new Cursor(*this, Trace::dsLightRed, 0);
|
_trig_cursor = new Cursor(*this, Trace::dsLightRed);
|
||||||
_show_search_cursor = false;
|
_show_search_cursor = false;
|
||||||
_search_pos = 0;
|
_search_pos = 0;
|
||||||
_search_cursor = new Cursor(*this, Trace::dsLightBlue, _search_pos);
|
_search_cursor = new Cursor(*this, Trace::dsLightBlue);
|
||||||
}
|
}
|
||||||
|
|
||||||
SigSession& View::session()
|
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();
|
const double time = trig_pos * 1.0f / _session.get_device()->get_sample_rate();
|
||||||
_trig_pos = trig_pos;
|
_trig_pos = trig_pos;
|
||||||
_trig_cursor->set_time(time);
|
_trig_cursor->set_index(trig_pos);
|
||||||
_show_trig_cursor = true;
|
_show_trig_cursor = true;
|
||||||
set_scale_offset(_scale, time - _scale * get_view_width() / 2);
|
set_scale_offset(_scale, time - _scale * get_view_width() / 2);
|
||||||
_ruler->update();
|
_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();
|
const double time = search_pos * 1.0f / _session.get_device()->get_sample_rate();
|
||||||
_search_pos = search_pos;
|
_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);
|
set_scale_offset(_scale, time - _scale * get_view_width() / 2);
|
||||||
_ruler->update();
|
_ruler->update();
|
||||||
_viewport->update();
|
_viewport->update();
|
||||||
@ -464,8 +464,7 @@ void View::update_scale()
|
|||||||
_preScale = _scale;
|
_preScale = _scale;
|
||||||
_preOffset = _offset;
|
_preOffset = _offset;
|
||||||
|
|
||||||
const double time = _trig_pos * 1.0f / sample_rate;
|
_trig_cursor->set_index(_trig_pos);
|
||||||
_trig_cursor->set_time(time);
|
|
||||||
|
|
||||||
_ruler->update();
|
_ruler->update();
|
||||||
_viewport->update();
|
_viewport->update();
|
||||||
@ -697,9 +696,9 @@ Ruler* View::get_ruler()
|
|||||||
return _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);
|
_cursorList.push_back(newCursor);
|
||||||
cursor_update();
|
cursor_update();
|
||||||
}
|
}
|
||||||
@ -728,24 +727,14 @@ void View::receive_data(quint64 length)
|
|||||||
_viewport->set_receive_len(length);
|
_viewport->set_receive_len(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString View::get_mm_width()
|
Viewport * View::get_viewport()
|
||||||
{
|
{
|
||||||
return _viewport->get_mm_width();
|
return _viewport;
|
||||||
}
|
|
||||||
|
|
||||||
QString View::get_mm_period()
|
|
||||||
{
|
|
||||||
return _viewport->get_mm_period();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString View::get_mm_freq()
|
|
||||||
{
|
|
||||||
return _viewport->get_mm_freq();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString View::get_cm_time(int index)
|
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)
|
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)
|
if (index1 == index2)
|
||||||
return "0";
|
return "0";
|
||||||
|
|
||||||
return _ruler->format_time(abs(get_cursor_time(index1) -
|
uint64_t samples1 = get_cursor_samples(index1);
|
||||||
get_cursor_time(index2)));
|
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)
|
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)
|
uint64_t View::get_cursor_samples(int index)
|
||||||
{
|
{
|
||||||
const double time = get_cursor_time(index);
|
assert(index < (int)_cursorList.size());
|
||||||
const uint64_t sample_rate = _session.get_device()->get_sample_limit();
|
|
||||||
assert(sample_rate !=0);
|
|
||||||
|
|
||||||
return time*sample_rate;
|
int curIndex = 0;
|
||||||
|
for (list<Cursor*>::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()
|
void View::on_cursor_moved()
|
||||||
{
|
{
|
||||||
cursor_moved();
|
cursor_moved();
|
||||||
|
@ -140,7 +140,7 @@ public:
|
|||||||
* cursorList
|
* cursorList
|
||||||
*/
|
*/
|
||||||
std::list<Cursor*>& get_cursorList();
|
std::list<Cursor*>& get_cursorList();
|
||||||
void add_cursor(QColor color, double time);
|
void add_cursor(QColor color, uint64_t index);
|
||||||
void del_cursor(Cursor* cursor);
|
void del_cursor(Cursor* cursor);
|
||||||
void set_cursor_middle(int index);
|
void set_cursor_middle(int index);
|
||||||
|
|
||||||
@ -163,13 +163,10 @@ public:
|
|||||||
bool need_update() const;
|
bool need_update() const;
|
||||||
|
|
||||||
uint64_t get_cursor_samples(int index);
|
uint64_t get_cursor_samples(int index);
|
||||||
QString get_mm_width();
|
Viewport * get_viewport();
|
||||||
QString get_mm_period();
|
|
||||||
QString get_mm_freq();
|
|
||||||
QString get_cm_time(int index);
|
QString get_cm_time(int index);
|
||||||
QString get_cm_delta(int index1, int index2);
|
QString get_cm_delta(int index1, int index2);
|
||||||
|
|
||||||
void on_mouse_moved();
|
|
||||||
void on_cursor_moved();
|
void on_cursor_moved();
|
||||||
|
|
||||||
void on_state_changed(bool stop);
|
void on_state_changed(bool stop);
|
||||||
@ -189,7 +186,6 @@ signals:
|
|||||||
|
|
||||||
void cursor_update();
|
void cursor_update();
|
||||||
|
|
||||||
void mouse_moved();
|
|
||||||
void cursor_moved();
|
void cursor_moved();
|
||||||
|
|
||||||
void mode_changed();
|
void mode_changed();
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "signal.h"
|
#include "signal.h"
|
||||||
#include "dsosignal.h"
|
#include "dsosignal.h"
|
||||||
|
#include "logicsignal.h"
|
||||||
#include "../device/devinst.h"
|
#include "../device/devinst.h"
|
||||||
#include "../data/logic.h"
|
#include "../data/logic.h"
|
||||||
#include "../data/logicsnapshot.h"
|
#include "../data/logicsnapshot.h"
|
||||||
@ -63,6 +64,7 @@ Viewport::Viewport(View &parent) :
|
|||||||
_mm_width = "#####";
|
_mm_width = "#####";
|
||||||
_mm_period = "#####";
|
_mm_period = "#####";
|
||||||
_mm_freq = "#####";
|
_mm_freq = "#####";
|
||||||
|
_mm_duty = "#####";
|
||||||
_measure_en = true;
|
_measure_en = true;
|
||||||
triggered = false;
|
triggered = false;
|
||||||
timer_cnt = 0;
|
timer_cnt = 0;
|
||||||
@ -110,7 +112,7 @@ void Viewport::paintEvent(QPaintEvent *event)
|
|||||||
t->paint_back(p, 0, _view.get_view_width());
|
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 ||
|
if (_view.session().get_device()->dev_inst()->mode == LOGIC ||
|
||||||
_view.session().get_instant()) {
|
_view.session().get_instant()) {
|
||||||
switch(_view.session().get_capture_state()) {
|
switch(_view.session().get_capture_state()) {
|
||||||
@ -137,7 +139,7 @@ void Viewport::paintEvent(QPaintEvent *event)
|
|||||||
t->paint_fore(p, 0, _view.get_view_width());
|
t->paint_fore(p, 0, _view.get_view_width());
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setRenderHint(QPainter::Antialiasing, false);
|
//p.setRenderHint(QPainter::Antialiasing, false);
|
||||||
if (_view.get_signalHeight() != _curSignalHeight)
|
if (_view.get_signalHeight() != _curSignalHeight)
|
||||||
_curSignalHeight = _view.get_signalHeight();
|
_curSignalHeight = _view.get_signalHeight();
|
||||||
|
|
||||||
@ -159,7 +161,7 @@ void Viewport::paintSignals(QPainter &p)
|
|||||||
pixmap.fill(Qt::transparent);
|
pixmap.fill(Qt::transparent);
|
||||||
QPainter dbp(&pixmap);
|
QPainter dbp(&pixmap);
|
||||||
dbp.initFrom(this);
|
dbp.initFrom(this);
|
||||||
p.setRenderHint(QPainter::Antialiasing, false);
|
//p.setRenderHint(QPainter::Antialiasing, false);
|
||||||
BOOST_FOREACH(const shared_ptr<Trace> t, traces)
|
BOOST_FOREACH(const shared_ptr<Trace> t, traces)
|
||||||
{
|
{
|
||||||
assert(t);
|
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 cur_time = _view.offset() + _view.hover_point().x() * _view.scale();
|
||||||
const double pos = cur_time * sample_rate;
|
const double pos = cur_time * sample_rate;
|
||||||
const double pos_delta = pos - (int)pos;
|
const double pos_delta = pos - (int)pos;
|
||||||
if ( pos_delta < HitCursorTimeMargin)
|
if ( pos_delta < 0.5)
|
||||||
grabbed_marker->set_time(1.0 / sample_rate * floor(pos));
|
grabbed_marker->set_index(floor(pos));
|
||||||
else if (pos_delta > (1.0 - HitCursorTimeMargin))
|
|
||||||
grabbed_marker->set_time(1.0 / sample_rate * ceil(pos));
|
|
||||||
else
|
else
|
||||||
grabbed_marker->set_time(cur_time);
|
grabbed_marker->set_index(ceil(pos));
|
||||||
}
|
}
|
||||||
measure();
|
measure();
|
||||||
}
|
}
|
||||||
@ -499,99 +499,42 @@ void Viewport::set_receive_len(quint64 length)
|
|||||||
|
|
||||||
void Viewport::measure()
|
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<Signal> > sigs(_view.session().get_signals());
|
const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
|
||||||
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
|
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
|
||||||
assert(s);
|
assert(s);
|
||||||
const int curY = _view.hover_point().y();
|
shared_ptr<view::LogicSignal> logicSig;
|
||||||
const double curX = _view.hover_point().x();
|
if (logicSig = dynamic_pointer_cast<view::LogicSignal>(s)) {
|
||||||
if (curY <= View::SignalMargin || s->get_type() != Trace::DS_LOGIC) {
|
if (logicSig->measure(_view.hover_point(), _cur_sample, _nxt_sample, _thd_sample)) {
|
||||||
_measure_shown = false;
|
_measure_shown = true;
|
||||||
break;
|
|
||||||
} else if ( curY < s->get_y() + _view.get_signalHeight() * 0.5 &&
|
_mm_width = _view.get_ruler()->format_real_time(_nxt_sample - _cur_sample, sample_rate);
|
||||||
curY > (s->get_y() - _view.get_signalHeight() * 0.5)) {
|
_mm_period = _thd_sample != 0 ? _view.get_ruler()->format_real_time(_thd_sample - _cur_sample, sample_rate) : "#####";
|
||||||
if (s->cur_edges().size() > 2) {
|
_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 pixels_offset = _view.offset() / _view.scale();
|
||||||
const double samples_per_pixel = sample_rate * _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();
|
||||||
|
|
||||||
uint64_t findIndex = curX / _view.get_view_width() * s->cur_edges().size();
|
_mm_duty = _thd_sample != 0 ? QString::number((_nxt_sample - _cur_sample) * 100.0f / (_thd_sample - _cur_sample), 'f', 2)+"%" :
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
|
||||||
_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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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) :
|
|
||||||
"#####";
|
"#####";
|
||||||
|
mouse_measure();
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
_mm_width = "#####";
|
_mm_width = "#####";
|
||||||
_mm_period = "#####";
|
_mm_period = "#####";
|
||||||
_mm_freq = "#####";
|
_mm_freq = "#####";
|
||||||
|
_mm_duty = "#####";
|
||||||
|
}
|
||||||
|
mouse_measure();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_view.on_mouse_moved();
|
_measure_shown = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::paintMeasure(QPainter &p)
|
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,
|
double typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
|
||||||
Qt::AlignLeft | Qt::AlignTop, _mm_width).width() + 150;
|
Qt::AlignLeft | Qt::AlignTop, _mm_width).width() + 150;
|
||||||
QRectF measure_rect = QRectF(_view.hover_point().x(), _view.hover_point().y(),
|
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(),
|
QRectF measure1_rect = QRectF(_view.hover_point().x(), _view.hover_point().y(),
|
||||||
(double)typical_width, 20.0);
|
(double)typical_width, 20.0);
|
||||||
QRectF measure2_rect = QRectF(_view.hover_point().x(), _view.hover_point().y() + 20,
|
QRectF measure2_rect = QRectF(_view.hover_point().x(), _view.hover_point().y() + 20,
|
||||||
(double)typical_width, 20.0);
|
(double)typical_width, 20.0);
|
||||||
QRectF measure3_rect = QRectF(_view.hover_point().x(), _view.hover_point().y() + 40,
|
QRectF measure3_rect = QRectF(_view.hover_point().x(), _view.hover_point().y() + 40,
|
||||||
(double)typical_width, 20.0);
|
(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.setPen(Qt::NoPen);
|
||||||
p.setBrush(QColor(17, 133, 209, 150));
|
p.setBrush(QColor(17, 133, 209, 150));
|
||||||
@ -633,22 +578,23 @@ void Viewport::paintMeasure(QPainter &p)
|
|||||||
"Period: " + _mm_period);
|
"Period: " + _mm_period);
|
||||||
p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter,
|
p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter,
|
||||||
"Frequency: " + _mm_freq);
|
"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)
|
||||||
{
|
{
|
||||||
|
if(option.compare("width") == 0)
|
||||||
return _mm_width;
|
return _mm_width;
|
||||||
}
|
else if (option.compare("period") == 0)
|
||||||
|
|
||||||
QString Viewport::get_mm_period()
|
|
||||||
{
|
|
||||||
return _mm_period;
|
return _mm_period;
|
||||||
}
|
else if (option.compare("frequency") == 0)
|
||||||
|
|
||||||
QString Viewport::get_mm_freq()
|
|
||||||
{
|
|
||||||
return _mm_freq;
|
return _mm_freq;
|
||||||
|
else if (option.compare("duty") == 0)
|
||||||
|
return _mm_duty;
|
||||||
|
else
|
||||||
|
return "#####";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::set_measure_en(int enable)
|
void Viewport::set_measure_en(int enable)
|
||||||
|
@ -47,7 +47,6 @@ class Viewport : public QWidget
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static const int HitCursorMargin = 10;
|
static const int HitCursorMargin = 10;
|
||||||
static const double HitCursorTimeMargin = 0.3;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Viewport(View &parent);
|
explicit Viewport(View &parent);
|
||||||
@ -58,9 +57,7 @@ public:
|
|||||||
|
|
||||||
void set_receive_len(quint64 length);
|
void set_receive_len(quint64 length);
|
||||||
|
|
||||||
QString get_mm_width();
|
QString get_measure(QString option);
|
||||||
QString get_mm_period();
|
|
||||||
QString get_mm_freq();
|
|
||||||
|
|
||||||
void set_measure_en(int enable);
|
void set_measure_en(int enable);
|
||||||
|
|
||||||
@ -88,6 +85,9 @@ private slots:
|
|||||||
void on_traces_moved();
|
void on_traces_moved();
|
||||||
void on_trigger_timer();
|
void on_trigger_timer();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void mouse_measure();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
View &_view;
|
View &_view;
|
||||||
|
|
||||||
@ -109,13 +109,14 @@ private:
|
|||||||
uint64_t _cur_sample;
|
uint64_t _cur_sample;
|
||||||
uint64_t _nxt_sample;
|
uint64_t _nxt_sample;
|
||||||
uint64_t _thd_sample;
|
uint64_t _thd_sample;
|
||||||
int64_t _cur_preX;
|
double _cur_preX;
|
||||||
int64_t _cur_aftX;
|
double _cur_aftX;
|
||||||
int64_t _cur_thdX;
|
double _cur_thdX;
|
||||||
int64_t _cur_midY;
|
double _cur_midY;
|
||||||
QString _mm_width;
|
QString _mm_width;
|
||||||
QString _mm_period;
|
QString _mm_period;
|
||||||
QString _mm_freq;
|
QString _mm_freq;
|
||||||
|
QString _mm_duty;
|
||||||
|
|
||||||
QTimer trigger_timer;
|
QTimer trigger_timer;
|
||||||
bool triggered;
|
bool triggered;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user