mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-04-28 03:08:08 +00:00
Analyzer plug
This commit is contained in:
110
Analyzer/raw/PulseLengthStat/src/PulseLengthStatAnalyzer.cpp
Normal file
110
Analyzer/raw/PulseLengthStat/src/PulseLengthStatAnalyzer.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "PulseLengthStatAnalyzer.h"
|
||||
#include "PulseLengthStatAnalyzerSettings.h"
|
||||
#include <AnalyzerChannelData.h>
|
||||
|
||||
// One frame per stable level between edges. mData1 = duration in samples; mFlags: 1 = HIGH, 0 = LOW.
|
||||
|
||||
PulseLengthStatAnalyzer::PulseLengthStatAnalyzer()
|
||||
: Analyzer2(),
|
||||
mSettings(),
|
||||
mSimulationInitilized(false)
|
||||
{
|
||||
SetAnalyzerSettings(&mSettings);
|
||||
}
|
||||
|
||||
PulseLengthStatAnalyzer::~PulseLengthStatAnalyzer()
|
||||
{
|
||||
KillThread();
|
||||
}
|
||||
|
||||
void PulseLengthStatAnalyzer::SetupResults()
|
||||
{
|
||||
mResults.reset(new PulseLengthStatAnalyzerResults(this, &mSettings));
|
||||
SetAnalyzerResults(mResults.get());
|
||||
mResults->AddChannelBubblesWillAppearOn(mSettings.mInputChannel);
|
||||
}
|
||||
|
||||
void PulseLengthStatAnalyzer::WorkerThread()
|
||||
{
|
||||
mChannelData = GetAnalyzerChannelData(mSettings.mInputChannel);
|
||||
|
||||
U32 frames_since_commit = 0;
|
||||
const U32 kCommitBatch = 256;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CheckIfThreadShouldExit();
|
||||
|
||||
const U64 segment_start = mChannelData->GetSampleNumber();
|
||||
const BitState level = mChannelData->GetBitState();
|
||||
|
||||
mChannelData->AdvanceToNextEdge();
|
||||
|
||||
const U64 edge_sample = mChannelData->GetSampleNumber();
|
||||
if (edge_sample == segment_start)
|
||||
break;
|
||||
|
||||
const U64 duration_samples = edge_sample - segment_start;
|
||||
const U64 end_inclusive = edge_sample > segment_start ? edge_sample - 1 : segment_start;
|
||||
|
||||
Frame frame;
|
||||
frame.mData1 = duration_samples;
|
||||
frame.mFlags = (level == BIT_HIGH) ? 1 : 0;
|
||||
frame.mStartingSampleInclusive = static_cast<S64>(segment_start);
|
||||
frame.mEndingSampleInclusive = static_cast<S64>(end_inclusive);
|
||||
|
||||
mResults->AddFrame(frame);
|
||||
if (++frames_since_commit >= kCommitBatch)
|
||||
{
|
||||
mResults->CommitResults();
|
||||
frames_since_commit = 0;
|
||||
}
|
||||
ReportProgress(edge_sample);
|
||||
}
|
||||
|
||||
if (frames_since_commit != 0)
|
||||
mResults->CommitResults();
|
||||
}
|
||||
|
||||
bool PulseLengthStatAnalyzer::NeedsRerun()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
U32 PulseLengthStatAnalyzer::GenerateSimulationData(U64 minimum_sample_index, U32 device_sample_rate,
|
||||
SimulationChannelDescriptor** simulation_channels)
|
||||
{
|
||||
if (mSimulationInitilized == false)
|
||||
{
|
||||
mSimulationDataGenerator.Initialize(GetSimulationSampleRate(), &mSettings);
|
||||
mSimulationInitilized = true;
|
||||
}
|
||||
|
||||
return mSimulationDataGenerator.GenerateSimulationData(minimum_sample_index, device_sample_rate,
|
||||
simulation_channels);
|
||||
}
|
||||
|
||||
U32 PulseLengthStatAnalyzer::GetMinimumSampleRateHz()
|
||||
{
|
||||
return 200000;
|
||||
}
|
||||
|
||||
const char* PulseLengthStatAnalyzer::GetAnalyzerName() const
|
||||
{
|
||||
return "Pulse Length Stat";
|
||||
}
|
||||
|
||||
const char* GetAnalyzerName()
|
||||
{
|
||||
return "Pulse Length Stat";
|
||||
}
|
||||
|
||||
Analyzer* CreateAnalyzer()
|
||||
{
|
||||
return new PulseLengthStatAnalyzer();
|
||||
}
|
||||
|
||||
void DestroyAnalyzer(Analyzer* analyzer)
|
||||
{
|
||||
delete analyzer;
|
||||
}
|
||||
39
Analyzer/raw/PulseLengthStat/src/PulseLengthStatAnalyzer.h
Normal file
39
Analyzer/raw/PulseLengthStat/src/PulseLengthStatAnalyzer.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef PULSELENGTHSTAT_ANALYZER_H
|
||||
#define PULSELENGTHSTAT_ANALYZER_H
|
||||
|
||||
#include <Analyzer.h>
|
||||
#include "PulseLengthStatAnalyzerSettings.h"
|
||||
#include "PulseLengthStatAnalyzerResults.h"
|
||||
#include "PulseLengthStatSimulationDataGenerator.h"
|
||||
#include <memory>
|
||||
|
||||
class ANALYZER_EXPORT PulseLengthStatAnalyzer : public Analyzer2
|
||||
{
|
||||
public:
|
||||
PulseLengthStatAnalyzer();
|
||||
virtual ~PulseLengthStatAnalyzer();
|
||||
|
||||
virtual void SetupResults();
|
||||
virtual void WorkerThread();
|
||||
|
||||
virtual U32 GenerateSimulationData(U64 newest_sample_requested, U32 sample_rate,
|
||||
SimulationChannelDescriptor** simulation_channels);
|
||||
virtual U32 GetMinimumSampleRateHz();
|
||||
|
||||
virtual const char* GetAnalyzerName() const;
|
||||
virtual bool NeedsRerun();
|
||||
|
||||
protected:
|
||||
PulseLengthStatAnalyzerSettings mSettings;
|
||||
std::unique_ptr<PulseLengthStatAnalyzerResults> mResults;
|
||||
AnalyzerChannelData* mChannelData;
|
||||
|
||||
PulseLengthStatSimulationDataGenerator mSimulationDataGenerator;
|
||||
bool mSimulationInitilized;
|
||||
};
|
||||
|
||||
extern "C" ANALYZER_EXPORT const char* __cdecl GetAnalyzerName();
|
||||
extern "C" ANALYZER_EXPORT Analyzer* __cdecl CreateAnalyzer();
|
||||
extern "C" ANALYZER_EXPORT void __cdecl DestroyAnalyzer(Analyzer* analyzer);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,107 @@
|
||||
#include "PulseLengthStatAnalyzerResults.h"
|
||||
#include <AnalyzerHelpers.h>
|
||||
#include "PulseLengthStatAnalyzer.h"
|
||||
#include "PulseLengthStatAnalyzerSettings.h"
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
|
||||
PulseLengthStatAnalyzerResults::PulseLengthStatAnalyzerResults(PulseLengthStatAnalyzer* analyzer,
|
||||
PulseLengthStatAnalyzerSettings* settings)
|
||||
: AnalyzerResults(),
|
||||
mSettings(settings),
|
||||
mAnalyzer(analyzer)
|
||||
{
|
||||
}
|
||||
|
||||
PulseLengthStatAnalyzerResults::~PulseLengthStatAnalyzerResults()
|
||||
{
|
||||
}
|
||||
|
||||
static void FormatDurationUs(U64 duration_samples, U32 sample_rate_hz, char* out, size_t out_sz)
|
||||
{
|
||||
if (sample_rate_hz == 0)
|
||||
{
|
||||
snprintf(out, out_sz, "? us");
|
||||
return;
|
||||
}
|
||||
const double us = double(duration_samples) * 1e6 / double(sample_rate_hz);
|
||||
snprintf(out, out_sz, "%.2f us", us);
|
||||
}
|
||||
|
||||
void PulseLengthStatAnalyzerResults::GenerateBubbleText(U64 frame_index, Channel& channel, DisplayBase display_base)
|
||||
{
|
||||
(void)display_base;
|
||||
ClearResultStrings();
|
||||
Frame frame = GetFrame(frame_index);
|
||||
|
||||
const U32 fs = mAnalyzer->GetSampleRate();
|
||||
char dur[64];
|
||||
FormatDurationUs(frame.mData1, fs, dur, sizeof dur);
|
||||
|
||||
const char* lev = (frame.mFlags != 0) ? "HIGH" : "LOW";
|
||||
char line[160];
|
||||
snprintf(line, sizeof line, "%s %s", lev, dur);
|
||||
AddResultString(line);
|
||||
}
|
||||
|
||||
void PulseLengthStatAnalyzerResults::GenerateExportFile(const char* file, DisplayBase display_base, U32 export_type_user_id)
|
||||
{
|
||||
(void)export_type_user_id;
|
||||
(void)display_base;
|
||||
std::ofstream file_stream(file, std::ios::out);
|
||||
|
||||
const U64 trigger_sample = mAnalyzer->GetTriggerSample();
|
||||
const U32 sample_rate = mAnalyzer->GetSampleRate();
|
||||
|
||||
file_stream << "Time [s],Level,Duration_samples,Duration_us" << std::endl;
|
||||
|
||||
const U64 num_frames = GetNumFrames();
|
||||
for (U32 i = 0; i < num_frames; i++)
|
||||
{
|
||||
Frame frame = GetFrame(i);
|
||||
|
||||
char time_str[128];
|
||||
AnalyzerHelpers::GetTimeString(frame.mStartingSampleInclusive, trigger_sample, sample_rate, time_str, 128);
|
||||
|
||||
char dur_us[64];
|
||||
FormatDurationUs(frame.mData1, sample_rate, dur_us, sizeof dur_us);
|
||||
|
||||
file_stream << time_str << "," << ((frame.mFlags != 0) ? "HIGH" : "LOW") << "," << frame.mData1 << ","
|
||||
<< dur_us << std::endl;
|
||||
|
||||
if (UpdateExportProgressAndCheckForCancel(i, num_frames) == true)
|
||||
{
|
||||
file_stream.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
file_stream.close();
|
||||
}
|
||||
|
||||
void PulseLengthStatAnalyzerResults::GenerateFrameTabularText(U64 frame_index, DisplayBase display_base)
|
||||
{
|
||||
#ifdef SUPPORTS_PROTOCOL_SEARCH
|
||||
(void)display_base;
|
||||
Frame frame = GetFrame(frame_index);
|
||||
ClearTabularText();
|
||||
|
||||
const U32 fs = mAnalyzer->GetSampleRate();
|
||||
char dur[64];
|
||||
FormatDurationUs(frame.mData1, fs, dur, sizeof dur);
|
||||
AddTabularText((frame.mFlags != 0) ? "H" : "L");
|
||||
AddTabularText(dur);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PulseLengthStatAnalyzerResults::GeneratePacketTabularText(U64 packet_id, DisplayBase display_base)
|
||||
{
|
||||
(void)packet_id;
|
||||
(void)display_base;
|
||||
}
|
||||
|
||||
void PulseLengthStatAnalyzerResults::GenerateTransactionTabularText(U64 transaction_id, DisplayBase display_base)
|
||||
{
|
||||
(void)transaction_id;
|
||||
(void)display_base;
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
#ifndef PULSELENGTHSTAT_ANALYZER_RESULTS
|
||||
#define PULSELENGTHSTAT_ANALYZER_RESULTS
|
||||
|
||||
#include <AnalyzerResults.h>
|
||||
|
||||
class PulseLengthStatAnalyzer;
|
||||
class PulseLengthStatAnalyzerSettings;
|
||||
|
||||
class PulseLengthStatAnalyzerResults : public AnalyzerResults
|
||||
{
|
||||
public:
|
||||
PulseLengthStatAnalyzerResults(PulseLengthStatAnalyzer* analyzer, PulseLengthStatAnalyzerSettings* settings);
|
||||
virtual ~PulseLengthStatAnalyzerResults();
|
||||
|
||||
virtual void GenerateBubbleText(U64 frame_index, Channel& channel, DisplayBase display_base);
|
||||
virtual void GenerateExportFile(const char* file, DisplayBase display_base, U32 export_type_user_id);
|
||||
|
||||
virtual void GenerateFrameTabularText(U64 frame_index, DisplayBase display_base);
|
||||
virtual void GeneratePacketTabularText(U64 packet_id, DisplayBase display_base);
|
||||
virtual void GenerateTransactionTabularText(U64 transaction_id, DisplayBase display_base);
|
||||
|
||||
protected:
|
||||
PulseLengthStatAnalyzerSettings* mSettings;
|
||||
PulseLengthStatAnalyzer* mAnalyzer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,62 @@
|
||||
#include "PulseLengthStatAnalyzerSettings.h"
|
||||
#include <AnalyzerHelpers.h>
|
||||
|
||||
PulseLengthStatAnalyzerSettings::PulseLengthStatAnalyzerSettings()
|
||||
: mInputChannel(UNDEFINED_CHANNEL),
|
||||
mInputChannelInterface()
|
||||
{
|
||||
mInputChannelInterface.SetTitleAndTooltip(
|
||||
"Input",
|
||||
"Digital channel: one frame per stable level between edges (duration in samples / us).");
|
||||
mInputChannelInterface.SetChannel(mInputChannel);
|
||||
|
||||
AddInterface(&mInputChannelInterface);
|
||||
|
||||
AddExportOption(0, "Export as text/csv file");
|
||||
AddExportExtension(0, "text", "txt");
|
||||
AddExportExtension(0, "csv", "csv");
|
||||
|
||||
ClearChannels();
|
||||
AddChannel(mInputChannel, "Input", false);
|
||||
}
|
||||
|
||||
PulseLengthStatAnalyzerSettings::~PulseLengthStatAnalyzerSettings()
|
||||
{
|
||||
}
|
||||
|
||||
bool PulseLengthStatAnalyzerSettings::SetSettingsFromInterfaces()
|
||||
{
|
||||
mInputChannel = mInputChannelInterface.GetChannel();
|
||||
|
||||
ClearChannels();
|
||||
AddChannel(mInputChannel, "Pulse Length Stat", true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PulseLengthStatAnalyzerSettings::UpdateInterfacesFromSettings()
|
||||
{
|
||||
mInputChannelInterface.SetChannel(mInputChannel);
|
||||
}
|
||||
|
||||
void PulseLengthStatAnalyzerSettings::LoadSettings(const char* settings)
|
||||
{
|
||||
SimpleArchive text_archive;
|
||||
text_archive.SetString(settings);
|
||||
|
||||
text_archive >> mInputChannel;
|
||||
|
||||
ClearChannels();
|
||||
AddChannel(mInputChannel, "Pulse Length Stat", true);
|
||||
|
||||
UpdateInterfacesFromSettings();
|
||||
}
|
||||
|
||||
const char* PulseLengthStatAnalyzerSettings::SaveSettings()
|
||||
{
|
||||
SimpleArchive text_archive;
|
||||
|
||||
text_archive << mInputChannel;
|
||||
|
||||
return SetReturnString(text_archive.GetString());
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
#ifndef PULSELENGTHSTAT_ANALYZER_SETTINGS
|
||||
#define PULSELENGTHSTAT_ANALYZER_SETTINGS
|
||||
|
||||
#include <AnalyzerSettings.h>
|
||||
#include <AnalyzerTypes.h>
|
||||
|
||||
class PulseLengthStatAnalyzerSettings : public AnalyzerSettings
|
||||
{
|
||||
public:
|
||||
PulseLengthStatAnalyzerSettings();
|
||||
virtual ~PulseLengthStatAnalyzerSettings();
|
||||
|
||||
virtual bool SetSettingsFromInterfaces();
|
||||
void UpdateInterfacesFromSettings();
|
||||
virtual void LoadSettings(const char* settings);
|
||||
virtual const char* SaveSettings();
|
||||
|
||||
Channel mInputChannel;
|
||||
|
||||
protected:
|
||||
AnalyzerSettingInterfaceChannel mInputChannelInterface;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,65 @@
|
||||
#include "PulseLengthStatSimulationDataGenerator.h"
|
||||
#include "PulseLengthStatAnalyzerSettings.h"
|
||||
#include <AnalyzerHelpers.h>
|
||||
|
||||
PulseLengthStatSimulationDataGenerator::PulseLengthStatSimulationDataGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
PulseLengthStatSimulationDataGenerator::~PulseLengthStatSimulationDataGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
void PulseLengthStatSimulationDataGenerator::Initialize(U32 simulation_sample_rate, PulseLengthStatAnalyzerSettings* settings)
|
||||
{
|
||||
mSimulationSampleRateHz = simulation_sample_rate;
|
||||
mSettings = settings;
|
||||
|
||||
mSimChannel.SetChannel(mSettings->mInputChannel);
|
||||
mSimChannel.SetSampleRate(simulation_sample_rate);
|
||||
mSimChannel.SetInitialBitState(BIT_HIGH);
|
||||
}
|
||||
|
||||
void PulseLengthStatSimulationDataGenerator::EmitIdle(U32 samples)
|
||||
{
|
||||
mSimChannel.Advance(samples);
|
||||
}
|
||||
|
||||
void PulseLengthStatSimulationDataGenerator::EmitLow(U32 samples)
|
||||
{
|
||||
mSimChannel.TransitionIfNeeded(BIT_LOW);
|
||||
mSimChannel.Advance(samples);
|
||||
}
|
||||
|
||||
void PulseLengthStatSimulationDataGenerator::EmitHigh(U32 samples)
|
||||
{
|
||||
mSimChannel.TransitionIfNeeded(BIT_HIGH);
|
||||
mSimChannel.Advance(samples);
|
||||
}
|
||||
|
||||
U32 PulseLengthStatSimulationDataGenerator::GenerateSimulationData(U64 largest_sample_requested, U32 sample_rate,
|
||||
SimulationChannelDescriptor** simulation_channel)
|
||||
{
|
||||
const U64 adjusted_largest_sample_requested =
|
||||
AnalyzerHelpers::AdjustSimulationTargetSample(largest_sample_requested, sample_rate, mSimulationSampleRateHz);
|
||||
|
||||
while (mSimChannel.GetCurrentSampleNumber() < adjusted_largest_sample_requested)
|
||||
{
|
||||
const U32 us_to_samples = mSimulationSampleRateHz / 1000000;
|
||||
if (us_to_samples == 0)
|
||||
break;
|
||||
|
||||
EmitIdle(500 * us_to_samples);
|
||||
EmitLow(4500 * us_to_samples);
|
||||
EmitHigh(4500 * us_to_samples);
|
||||
EmitLow(4500 * us_to_samples);
|
||||
EmitHigh(4500 * us_to_samples);
|
||||
EmitLow(560 * us_to_samples);
|
||||
EmitHigh(560 * us_to_samples);
|
||||
EmitLow(560 * us_to_samples);
|
||||
EmitHigh(20000 * us_to_samples);
|
||||
}
|
||||
|
||||
*simulation_channel = &mSimChannel;
|
||||
return 1;
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
#ifndef PULSELENGTHSTAT_SIMULATION_DATA_GENERATOR
|
||||
#define PULSELENGTHSTAT_SIMULATION_DATA_GENERATOR
|
||||
|
||||
#include <SimulationChannelDescriptor.h>
|
||||
|
||||
class PulseLengthStatAnalyzerSettings;
|
||||
|
||||
class PulseLengthStatSimulationDataGenerator
|
||||
{
|
||||
public:
|
||||
PulseLengthStatSimulationDataGenerator();
|
||||
~PulseLengthStatSimulationDataGenerator();
|
||||
|
||||
void Initialize(U32 simulation_sample_rate, PulseLengthStatAnalyzerSettings* settings);
|
||||
U32 GenerateSimulationData(U64 newest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel);
|
||||
|
||||
protected:
|
||||
PulseLengthStatAnalyzerSettings* mSettings;
|
||||
U32 mSimulationSampleRateHz;
|
||||
SimulationChannelDescriptor mSimChannel;
|
||||
|
||||
void EmitIdle(U32 samples);
|
||||
void EmitLow(U32 samples);
|
||||
void EmitHigh(U32 samples);
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user