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:
52
Analyzer/raw/PulseLengthStat/.github/workflows/build.yml
vendored
Normal file
52
Analyzer/raw/PulseLengthStat/.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, main]
|
||||
tags:
|
||||
- "*"
|
||||
pull_request:
|
||||
branches: [master, main]
|
||||
|
||||
jobs:
|
||||
windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
cmake -B ${{github.workspace}}/Analyzer/raw/PulseLengthStat/build -S ${{github.workspace}}/Analyzer/raw/PulseLengthStat -A x64
|
||||
cmake --build ${{github.workspace}}/Analyzer/raw/PulseLengthStat/build --config Release
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows
|
||||
path: ${{github.workspace}}/Analyzer/raw/dll/*.dll
|
||||
|
||||
macos:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
cmake -B ${{github.workspace}}/Analyzer/raw/PulseLengthStat/build -S ${{github.workspace}}/Analyzer/raw/PulseLengthStat -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build ${{github.workspace}}/Analyzer/raw/PulseLengthStat/build
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macos
|
||||
path: ${{github.workspace}}/Analyzer/raw/dll/*.so
|
||||
|
||||
linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
cmake -B ${{github.workspace}}/Analyzer/raw/PulseLengthStat/build -S ${{github.workspace}}/Analyzer/raw/PulseLengthStat -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build ${{github.workspace}}/Analyzer/raw/PulseLengthStat/build
|
||||
env:
|
||||
CC: gcc-10
|
||||
CXX: g++-10
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: linux
|
||||
path: ${{github.workspace}}/Analyzer/raw/dll/*.so
|
||||
3
Analyzer/raw/PulseLengthStat/.gitignore
vendored
Normal file
3
Analyzer/raw/PulseLengthStat/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/build
|
||||
/build-nmake
|
||||
.DS_Store
|
||||
24
Analyzer/raw/PulseLengthStat/CMakeLists.txt
Normal file
24
Analyzer/raw/PulseLengthStat/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
project(PulseLengthStatAnalyzer)
|
||||
|
||||
add_definitions(-DLOGIC2)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
include(ExternalAnalyzerSDK)
|
||||
|
||||
set(SOURCES
|
||||
src/PulseLengthStatAnalyzer.cpp
|
||||
src/PulseLengthStatAnalyzer.h
|
||||
src/PulseLengthStatAnalyzerResults.cpp
|
||||
src/PulseLengthStatAnalyzerResults.h
|
||||
src/PulseLengthStatAnalyzerSettings.cpp
|
||||
src/PulseLengthStatAnalyzerSettings.h
|
||||
src/PulseLengthStatSimulationDataGenerator.cpp
|
||||
src/PulseLengthStatSimulationDataGenerator.h
|
||||
)
|
||||
|
||||
add_analyzer_plugin(${PROJECT_NAME} SOURCES ${SOURCES})
|
||||
49
Analyzer/raw/PulseLengthStat/CMakePresets.json
Normal file
49
Analyzer/raw/PulseLengthStat/CMakePresets.json
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
"version": 3,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 19,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "win-vs2022-x64",
|
||||
"displayName": "Visual Studio 2022 (x64)",
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"architecture": "x64",
|
||||
"binaryDir": "${sourceDir}/build"
|
||||
},
|
||||
{
|
||||
"name": "win-vs2019-x64",
|
||||
"displayName": "Visual Studio 2019 (x64)",
|
||||
"generator": "Visual Studio 16 2019",
|
||||
"architecture": "x64",
|
||||
"binaryDir": "${sourceDir}/build"
|
||||
},
|
||||
{
|
||||
"name": "win-nmake-release",
|
||||
"displayName": "NMake Release (x64 Native Tools Command Prompt)",
|
||||
"generator": "NMake Makefiles",
|
||||
"binaryDir": "${sourceDir}/build-nmake",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "win-release",
|
||||
"configurePreset": "win-vs2022-x64",
|
||||
"configuration": "Release"
|
||||
},
|
||||
{
|
||||
"name": "win-release-vs2019",
|
||||
"configurePreset": "win-vs2019-x64",
|
||||
"configuration": "Release"
|
||||
},
|
||||
{
|
||||
"name": "nmake-release",
|
||||
"configurePreset": "win-nmake-release"
|
||||
}
|
||||
]
|
||||
}
|
||||
21
Analyzer/raw/PulseLengthStat/build_msvc.bat
Normal file
21
Analyzer/raw/PulseLengthStat/build_msvc.bat
Normal file
@ -0,0 +1,21 @@
|
||||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
cd /d "%~dp0"
|
||||
|
||||
if not exist build\CMakeCache.txt (
|
||||
echo Run configure_msvc.bat first.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||
for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSINSTALL=%%i"
|
||||
if not defined VSINSTALL (
|
||||
echo MSVC not found. Add C++ workload in Visual Studio Installer.
|
||||
exit /b 1
|
||||
)
|
||||
call "!VSINSTALL!\Common7\Tools\VsDevCmd.bat" -arch=x64 -host_arch=x64
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
cmake --build build
|
||||
pause
|
||||
exit /b %ERRORLEVEL%
|
||||
66
Analyzer/raw/PulseLengthStat/cmake/ExternalAnalyzerSDK.cmake
Normal file
66
Analyzer/raw/PulseLengthStat/cmake/ExternalAnalyzerSDK.cmake
Normal file
@ -0,0 +1,66 @@
|
||||
include(FetchContent)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
||||
|
||||
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY OR NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/)
|
||||
endif()
|
||||
|
||||
if(NOT TARGET Saleae::AnalyzerSDK)
|
||||
FetchContent_Declare(
|
||||
analyzersdk
|
||||
GIT_REPOSITORY https://github.com/saleae/AnalyzerSDK.git
|
||||
GIT_TAG master
|
||||
GIT_SHALLOW True
|
||||
GIT_PROGRESS True
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(analyzersdk)
|
||||
|
||||
if(NOT analyzersdk_POPULATED)
|
||||
FetchContent_Populate(analyzersdk)
|
||||
include(${analyzersdk_SOURCE_DIR}/AnalyzerSDKConfig.cmake)
|
||||
|
||||
if(APPLE OR WIN32)
|
||||
get_target_property(analyzersdk_lib_location Saleae::AnalyzerSDK IMPORTED_LOCATION)
|
||||
if(CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
||||
file(COPY ${analyzersdk_lib_location} DESTINATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||
else()
|
||||
message(WARNING "Please define CMAKE_RUNTIME_OUTPUT_DIRECTORY and CMAKE_LIBRARY_OUTPUT_DIRECTORY if you want unit tests to locate ${analyzersdk_lib_location}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Shared folder for all Saleae LLA plugins in this repo: Analyzer/raw/dll
|
||||
set(ANALYZER_DLL_OUT_DIR "${CMAKE_SOURCE_DIR}/../dll")
|
||||
get_filename_component(ANALYZER_DLL_OUT_DIR "${ANALYZER_DLL_OUT_DIR}" ABSOLUTE)
|
||||
file(MAKE_DIRECTORY "${ANALYZER_DLL_OUT_DIR}")
|
||||
|
||||
function(add_analyzer_plugin TARGET)
|
||||
set(options)
|
||||
set(single_value_args)
|
||||
set(multi_value_args SOURCES)
|
||||
cmake_parse_arguments(_p "${options}" "${single_value_args}" "${multi_value_args}" ${ARGN})
|
||||
|
||||
add_library(${TARGET} MODULE ${_p_SOURCES})
|
||||
target_link_libraries(${TARGET} PRIVATE Saleae::AnalyzerSDK)
|
||||
|
||||
set(ANALYZER_DESTINATION "Analyzers")
|
||||
install(TARGETS ${TARGET} RUNTIME DESTINATION ${ANALYZER_DESTINATION}
|
||||
LIBRARY DESTINATION ${ANALYZER_DESTINATION})
|
||||
|
||||
set_target_properties(${TARGET} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${ANALYZER_DLL_OUT_DIR}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${ANALYZER_DLL_OUT_DIR}")
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
foreach(CFG ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER ${CFG} CFG_UPPER)
|
||||
set_target_properties(${TARGET} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY_${CFG_UPPER} "${ANALYZER_DLL_OUT_DIR}"
|
||||
LIBRARY_OUTPUT_DIRECTORY_${CFG_UPPER} "${ANALYZER_DLL_OUT_DIR}")
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
39
Analyzer/raw/PulseLengthStat/configure_msvc.bat
Normal file
39
Analyzer/raw/PulseLengthStat/configure_msvc.bat
Normal file
@ -0,0 +1,39 @@
|
||||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
cd /d "%~dp0"
|
||||
|
||||
echo === PulseLengthStatAnalyzer: configure with MSVC ===
|
||||
echo.
|
||||
|
||||
set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||
if not exist "%VSWHERE%" (
|
||||
echo [ERROR] vswhere not found. Install one of:
|
||||
echo - Visual Studio 2022 with workload "Desktop development with C++"
|
||||
echo - Build Tools for Visual Studio 2022: https://visualstudio.microsoft.com/visual-cpp-build-tools/
|
||||
echo ^(select "Desktop development with C++" / MSVC, Windows SDK^)
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSINSTALL=%%i"
|
||||
if not defined VSINSTALL (
|
||||
echo [ERROR] MSVC toolset not found. Add "Desktop development with C++" in Visual Studio Installer.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo Found: !VSINSTALL!
|
||||
call "!VSINSTALL!\Common7\Tools\VsDevCmd.bat" -arch=x64 -host_arch=x64
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
if exist build rmdir /s /q build
|
||||
if exist build-nmake rmdir /s /q build-nmake
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
echo.
|
||||
echo Configure OK. Build: build_msvc.bat ^(or from same VS env: cd build ^& cmake --build .^)
|
||||
echo Output DLL: ..\dll\ ^(all analyzers share this folder^)
|
||||
pause
|
||||
exit /b 0
|
||||
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