Compare commits

...

12 Commits

Author SHA1 Message Date
866e5e9a7d init
Some checks failed
Build / windows (push) Has been cancelled
Build / macos (push) Has been cancelled
Build / linux (push) Has been cancelled
Build / publish (push) Has been cancelled
2025-12-21 21:43:47 +01:00
Mark
6485c4cc5e Merge pull request #29 from saleae/esal22-patch-1
Update Analyzer_API.md
2024-10-28 12:57:48 -07:00
Mark
170f083552 Merge pull request #30 from saleae/esal22-patch-1-1
Update Analyzer_API.md
2024-10-28 12:56:56 -07:00
Marcus10110
deb5da08bf updated github actions to v4: checkout, upload-artifact, download-artifact 2024-10-25 17:28:55 -07:00
Mark
4a803b0109 Merge pull request #33 from saleae/remove-auto-ptr
Remove std::auto_ptr
2024-08-01 13:47:28 -07:00
Marcus10110
371bdf4515 fix minor typo in API docs. 2024-07-31 14:04:00 -07:00
Marcus10110
432743b060 switched mResults over to a unique_ptr, because resetting the class directly with the default assignment operator broke its mutexes. 2024-07-31 13:57:47 -07:00
Marcus10110
9a0511d7f2 added missing include and removed forward declare, now that we're not using pointers for analyzer settings. 2024-07-31 13:29:50 -07:00
Marcus10110
7012904900 update API docs. 2024-07-31 13:24:32 -07:00
Marcus10110
fa24236c78 switch from using pointers to direct access. 2024-07-31 13:24:21 -07:00
Erik
2c170c6169 Update Analyzer_API.md 2023-12-06 09:25:55 -06:00
Erik
f32faf70e0 Update Analyzer_API.md
Updated reference to mData2 i the documentation.
2023-12-06 09:21:01 -06:00
15 changed files with 453 additions and 311 deletions

View File

@@ -12,20 +12,20 @@ jobs:
windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Build
run: |
cmake -B ${{github.workspace}}/build -A x64
cmake --build ${{github.workspace}}/build --config Release
- name: Upload windows build
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: windows
path: ${{github.workspace}}/build/Analyzers/Release/*.dll
macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Build
run: |
cmake -B ${{github.workspace}}/build/x86_64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=x86_64
@@ -33,19 +33,19 @@ jobs:
cmake -B ${{github.workspace}}/build/arm64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=arm64
cmake --build ${{github.workspace}}/build/arm64
- name: Upload MacOS x86_64 build
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: macos_x86_64
path: ${{github.workspace}}/build/x86_64/Analyzers/*.so
- name: Upload MacOS arm64 build
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: macos_arm64
path: ${{github.workspace}}/build/arm64/Analyzers/*.so
linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Build
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release
@@ -54,7 +54,7 @@ jobs:
CC: gcc-10
CXX: g++-10
- name: Upload Linux build
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: linux
path: ${{github.workspace}}/build/Analyzers/*.so
@@ -63,14 +63,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: download individual builds
uses: actions/download-artifact@v2
uses: actions/download-artifact@v4
with:
path: ${{github.workspace}}/artifacts
- name: zip
run: |
cd ${{github.workspace}}/artifacts
zip -r ${{github.workspace}}/analyzer.zip .
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: all-platforms
path: ${{github.workspace}}/artifacts/**

2
.gitignore vendored
View File

@@ -1,2 +1,4 @@
/build
.DS_Store
.cache/

View File

@@ -1,6 +1,6 @@
cmake_minimum_required (VERSION 3.13)
project(SimpleSerialAnalyzer)
project(TLC59731Analyzer)
add_definitions( -DLOGIC2 )
@@ -13,14 +13,14 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
include(ExternalAnalyzerSDK)
set(SOURCES
src/SimpleSerialAnalyzer.cpp
src/SimpleSerialAnalyzer.h
src/SimpleSerialAnalyzerResults.cpp
src/SimpleSerialAnalyzerResults.h
src/SimpleSerialAnalyzerSettings.cpp
src/SimpleSerialAnalyzerSettings.h
src/SimpleSerialSimulationDataGenerator.cpp
src/SimpleSerialSimulationDataGenerator.h
src/TLC59731Analyzer.cpp
src/TLC59731Analyzer.h
src/TLC59731AnalyzerResults.cpp
src/TLC59731AnalyzerResults.h
src/TLC59731AnalyzerSettings.cpp
src/TLC59731AnalyzerSettings.h
src/TLC59731SimulationDataGenerator.cpp
src/TLC59731SimulationDataGenerator.h
)
add_analyzer_plugin(${PROJECT_NAME} SOURCES ${SOURCES})

View File

@@ -172,8 +172,6 @@ One of the services the Analyzer SDK provides is a means for users to edit your
- ```AnalyzerSettingInterfaceText``` - Allows a user to enter some text into a textbox.
- ```AnalyzerSettingInterfaceBool``` - Provides the user with a checkbox.
```AnalyzerSettingsInterface``` types should be declared as pointers. Were using the ```std::auto_ptr``` type, which largely acts like a standard (raw) pointer. Its a simple form of whats called a “smart pointer” and it automatically calls ```delete``` on its contents when it goes out of scope.
## {YourName}AnalyzerSettings.cpp
### The Constructor
@@ -182,15 +180,10 @@ First, initialize all your settings variables to their default values. Second,
### Setting up each AnalyzerSettingInterface object
First, we create the object (call new) and assign the value to the interfaces pointer. Note that were using ```std::auto_ptr```, so this means calling the member function ```reset()```. For standard (raw pointers), you would do something like:
```c++
mInputChannelInterface = new AnalyzerSettingInterfaceChannel();
```
Next, we call the member function ```SetTitleAndTooltip()```. The title will appear to the left of the input element. Note that often times you wont need a title, but you should use one for ```Channels```. The tooltip shows up when hovering over the input element.
First, call the member function ```SetTitleAndTooltip()```. The title will appear to the left of the input element. Note that often times you wont need a title, but you should use one for ```Channels```. The tooltip shows up when hovering over the input element.
```c++
void SetTitleAndTooltip( const char* title, const char* tooltip );
mInputChannelInterface->SetTitleAndTooltip( "Serial", "Standard Async Serial" );
mInputChannelInterface.SetTitleAndTooltip( "Serial", "Standard Async Serial" );
```
Finally, Well want to set the value. The interface object is, well, an interface to our settings variables. When setting up the interface, we copy the value from our settings variable to the interface. When the user makes a change, we copy the value in the interface to our settings variable. The function names for this differ depending on the type of interface.
```c++
@@ -292,7 +285,7 @@ After assigning the interface values to your settings variables, you also need t
```c++
bool SimpleSerialAnalyzerSettings::SetSettingsFromInterfaces()
{
mInputChannel = mInputChannelInterface->GetChannel();
mInputChannel = mInputChannelInterface.GetChannel();
mBitRate = mBitRateInterface->GetInteger();
ClearChannels();
AddChannel( mInputChannel, "Simple Serial", true );
@@ -307,7 +300,7 @@ bool SimpleSerialAnalyzerSettings::SetSettingsFromInterfaces()
```c++
void SimpleSerialAnalyzerSettings::UpdateInterfacesFromSettings()
{
mInputChannelInterface->SetChannel( mInputChannel );
mInputChannelInterface.SetChannel( mInputChannel );
mBitRateInterface->SetInteger( mBitRate );
}
```
@@ -480,7 +473,7 @@ public:
#### Frame Member Variables
* ```mStartingSampleInclusive``` and ```mEndingSampleInclusive``` are the sample numbers for the beginning and end of the ```Frame```. Frames may not overlap and they cannot share the same sample. For example, if a single clock edge ends one Frame, and starts a new Frame, then youll need to add one (+1) to the ```mStartingSampleInclusive``` of the second frame. A single Frame cannot have ```mStartingSampleInclusive``` and ```mEndingSampleInclusive``` be equal. They must be at least 1 sample apart.
* ```mData1``` and ```mData1``` Two 64-bit numbers to store Frame data data. For example, in SPI, one of these is used for the MISO result, and the other for the MISO result. Often times youll only use one of these variables.
* ```mData1``` and ```mData2``` Two 64-bit numbers to store Frame data data. For example, in SPI, one of these is used for the MISO result, and the other for the MISO result. Often times youll only use one of these variables.
* ```mType``` variable is intended to be used to save a custom-defined enum value, representing the type of ```Frame```. For example, CAN can have many different types of frames header, data, CRC, etc. Serial only has one type, and it doesnt use this member variable.
* ```mFlags``` is intended to be a holder for custom flags which might apply to frame. Note that this is not intended for use with a custom enum, but rather for individual bits that can be ored together. For example, in Serial, there is a flag for framing-error, and a flag for parity error.
```c++
@@ -504,9 +497,9 @@ Frame frame = GetFrame( frame_index );
Bubbles can display different length strings, depending on how much room is available. You should generate several results strings. The simplest might simply indicate the type of contents (D for data, for example), longer ones might indicate the full number (“0xFF01”), and longer ones might be very verbose (“Left Channel Audio Data: 0xFF01”).
To provide strings to the caller, use the ```AddStringResult``` function. This will make sure that the strings persist after the function has returned. Always call ```ClearResultStrings``` before adding any string results.
To provide strings to the caller, use the ```AddResultString``` function. This will make sure that the strings persist after the function has returned. Always call ```ClearResultStrings``` before adding any string results.
Note that to easily concatenate multiple strings, simply provide ```AddStringResult``` with more strings.
Note that to easily concatenate multiple strings, simply provide ```AddResultString``` with more strings.
```c++
void ClearResultStrings();
@@ -674,7 +667,7 @@ extern "C" ANALYZER_EXPORT void __cdecl DestroyAnalyzer( Analyzer* analyzer );
Youll also need these member variables:
```c++
{YourName}AnalyzerSettings mSettings;
{YourName}AnalyzerResults mResults;
std::unique_ptr<{YourName}AnalyzerResults> mResults;
{YourName}SimulationDataGenerator mSimulationDataGenerator;
bool mSimulationInitialized;
```
@@ -692,13 +685,13 @@ Your constructor will look something like this
```c++
{YourName}Analyzer::{YourName}Analyzer()
: Analyzer(),
mSettings( new {YourName}AnalyzerSettings() ),
mSettings(),
mSimulationInitialized( false )
{
SetAnalyzerSettings( mSettings.get() );
SetAnalyzerSettings( &mSettings );
}
```
Note that here youre calling the base class constructor, ```new()```'ing your ```AnalyzerSettings``` derived class, and providing the base class with a pointer to your ```AnalyzerSettings``` - derived object.
Note that here youre calling the base class constructor and providing the base class with a pointer to your ```AnalyzerSettings``` - derived object.
## Destructor
This only thing your destructor must do is call ```KillThread```. This is a base class member function and will make sure your class destructs in the right order.
@@ -727,7 +720,7 @@ U32 {YourName}Analyzer::GenerateSimulationData( U64 minimum_sample_index, U32 de
{
if( mSimulationInitialized == false )
{
mSimulationDataGenerator.Initialize( GetSimulationSampleRate(), mSettings.get() );
mSimulationDataGenerator.Initialize( GetSimulationSampleRate(), &mSettings );
mSimulationInitialized = true;
}
return mSimulationDataGenerator.GenerateSimulationData( minimum_sample_index, device_sample_rate, simulation_channels );
@@ -740,7 +733,7 @@ This function is called to see if the users selected sample rate is sufficien
```c++
U32 SerialAnalyzer::GetMinimumSampleRateHz()
{
return mSettings->mBitRate * 4;
return mSettings.mBitRate * 4;
}
```
@@ -769,9 +762,9 @@ delete analyzer;
```
## ```{YourName}Analyzer::WorkerThread()```
Ok, now that everything else is taken care of, lets look at the most important part of the analyzer in detail. First, well ```new``` our ```AnalyzerResults``` derived object.
Ok, now that everything else is taken care of, lets look at the most important part of the analyzer in detail. First, well reset our ```AnalyzerResults``` derived object. This is because your analyzer class instance may be re-used for multiple runs, so at the beginning of each run, the generated results must be reset.
```c++
mResults.reset( new {YourName}AnalyzerResults( this, mSettings.get() ) );
mResults.reset( new {YourName}AnalyzerResults( this, &mSettings ) );
```
Well provide a pointer to our results to the base class:
```c++
@@ -779,7 +772,7 @@ SetAnalyzerResults( mResults.get() );
```
Lets indicate which channels well be displaying results on (in the form of bubbles). Usually this will only be one channel. (Except in the case of SPI, where well want to put bubbles on both the MISO and MISO lines.) Only indicate where we will display bubbles other markup, like tick marks, arrows, etc, are not bubbles, and should not be reported here.
```c++
mResults->AddChannelBubblesWillAppearOn( mSettings->mInputChannel );
mResults->AddChannelBubblesWillAppearOn( mSettings.mInputChannel );
```
Well probably want to know (and save in a member variable) the sample rate.
```c++
@@ -787,7 +780,7 @@ mSampleRateHz = GetSampleRate();
```
Now we need to get access to the data itself. Well need to get pointers to ```AnalyzerChannelData``` objects for each channel well need data from. For Serial, well just need one. For SPI, we might need 4. Etc.
```c++
mSerial = GetAnalyzerChannelData( mSettings->mInputChannel );
mSerial = GetAnalyzerChannelData( mSettings.mInputChannel );
```
# Traversing the Data
@@ -892,7 +885,7 @@ void AddMarker( U64 sample_number, MarkerType marker_type, Channel& channel );
```
For example, from ```SerialAnalyzer.cpp``` :
```c++
mResults->AddMarker( marker_location, AnalyzerResults::Dot, mSettings->mInputChannel );
mResults->AddMarker( marker_location, AnalyzerResults::Dot, mSettings.mInputChannel );
```
Currently, the available graphical artifacts are
@@ -1135,7 +1128,7 @@ SimpleSerialAnalyzerSettings* settings )
{
mSimulationSampleRateHz = simulation_sample_rate;
mSettings = settings;
mSerialSimulationData.SetChannel( mSettings->mInputChannel );
mSerialSimulationData.SetChannel( mSettings.mInputChannel );
mSerialSimulationData.SetSampleRate( simulation_sample_rate );
mSerialSimulationData.SetInitialBitState( BIT_HIGH );
}
@@ -1179,7 +1172,7 @@ simulation_channel )
}
void SimpleSerialSimulationDataGenerator::CreateSerialByte()
{
U32 samples_per_bit = mSimulationSampleRateHz / mSettings->mBitRate;
U32 samples_per_bit = mSimulationSampleRateHz / mSettings.mBitRate;
U8 byte = mSerialText[ mStringIndex ];
mStringIndex++;
if( mStringIndex == mSerialText.size() )
@@ -1254,22 +1247,22 @@ void SerialSimulationDataGenerator::CreateSerialByte( U64 value )
// assume we start high
mSerialSimulationData.Transition(); // low-going edge for start bit
mSerialSimulationData.Advance( mClockGenerator.AdvanceByHalfPeriod() ); // add
start bit time if( mSettings->mInverted == true ) value = ~value;
U32 num_bits = mSettings->mBitsPerTransfer;
BitExtractor bit_extractor( value, mSettings->mShiftOrder, num_bits );
start bit time if( mSettings.mInverted == true ) value = ~value;
U32 num_bits = mSettings.mBitsPerTransfer;
BitExtractor bit_extractor( value, mSettings.mShiftOrder, num_bits );
for( U32 i = 0; i < num_bits; i++ )
{
mSerialSimulationData.TransitionIfNeeded( bit_extractor.GetNextBit() );
mSerialSimulationData.Advance( mClockGenerator.AdvanceByHalfPeriod() );
}
if( mSettings->mParity == AnalyzerEnums::Even )
if( mSettings.mParity == AnalyzerEnums::Even )
{
if( AnalyzerHelpers::IsEven( AnalyzerHelpers::GetOnesCount( value ) ) == true )
mSerialSimulationData.TransitionIfNeeded( mBitLow ); // we want to
add a zero bit else mSerialSimulationData.TransitionIfNeeded( mBitHigh ); // we want to
add a one bit mSerialSimulationData.Advance( mClockGenerator.AdvanceByHalfPeriod() );
}
else if( mSettings->mParity == AnalyzerEnums::Odd )
else if( mSettings.mParity == AnalyzerEnums::Odd )
{
if( AnalyzerHelpers::IsOdd( AnalyzerHelpers::GetOnesCount( value ) ) == true )
mSerialSimulationData.TransitionIfNeeded( mBitLow ); // we want to
@@ -1355,9 +1348,9 @@ U32 I2cSimulationDataGenerator::GenerateSimulationData( U64 largest_sample_reque
```c++
void SpiSimulationDataGenerator::OutputWord_CPHA1( U64 mosi_data, U64 miso_data )
{
BitExtractor mosi_bits( mosi_data, mSettings->mShiftOrder, mSettings - > mBitsPerTransfer );
BitExtractor miso_bits( miso_data, mSettings->mShiftOrder, mSettings - > mBitsPerTransfer );
U32 count = mSettings->mBitsPerTransfer;
BitExtractor mosi_bits( mosi_data, mSettings.mShiftOrder, mSettings - > mBitsPerTransfer );
BitExtractor miso_bits( miso_data, mSettings.mShiftOrder, mSettings - > mBitsPerTransfer );
U32 count = mSettings.mBitsPerTransfer;
for( U32 i = 0; i < count; i++ )
{
mClock->Transition(); // data invalid
@@ -1381,7 +1374,7 @@ void SpiSimulationDataGenerator::CreateSpiTransaction()
if( mEnable != NULL )
mEnable->Transition();
mSpiSimulationChannels.AdvanceAll( mClockGenerator.AdvanceByHalfPeriod( 2.0 ) );
if( mSettings->mDataValidEdge == AnalyzerEnums::LeadingEdge )
if( mSettings.mDataValidEdge == AnalyzerEnums::LeadingEdge )
{
OutputWord_CPHA0( mValue, mValue + 1 );
mValue++;

View File

@@ -1,114 +0,0 @@
#include "SimpleSerialAnalyzer.h"
#include "SimpleSerialAnalyzerSettings.h"
#include <AnalyzerChannelData.h>
SimpleSerialAnalyzer::SimpleSerialAnalyzer()
: Analyzer2(),
mSettings( new SimpleSerialAnalyzerSettings() ),
mSimulationInitilized( false )
{
SetAnalyzerSettings( mSettings.get() );
}
SimpleSerialAnalyzer::~SimpleSerialAnalyzer()
{
KillThread();
}
void SimpleSerialAnalyzer::SetupResults()
{
mResults.reset( new SimpleSerialAnalyzerResults( this, mSettings.get() ) );
SetAnalyzerResults( mResults.get() );
mResults->AddChannelBubblesWillAppearOn( mSettings->mInputChannel );
}
void SimpleSerialAnalyzer::WorkerThread()
{
mSampleRateHz = GetSampleRate();
mSerial = GetAnalyzerChannelData( mSettings->mInputChannel );
if( mSerial->GetBitState() == BIT_LOW )
mSerial->AdvanceToNextEdge();
U32 samples_per_bit = mSampleRateHz / mSettings->mBitRate;
U32 samples_to_first_center_of_first_data_bit = U32( 1.5 * double( mSampleRateHz ) / double( mSettings->mBitRate ) );
for( ; ; )
{
U8 data = 0;
U8 mask = 1 << 7;
mSerial->AdvanceToNextEdge(); //falling edge -- beginning of the start bit
U64 starting_sample = mSerial->GetSampleNumber();
mSerial->Advance( samples_to_first_center_of_first_data_bit );
for( U32 i=0; i<8; i++ )
{
//let's put a dot exactly where we sample this bit:
mResults->AddMarker( mSerial->GetSampleNumber(), AnalyzerResults::Dot, mSettings->mInputChannel );
if( mSerial->GetBitState() == BIT_HIGH )
data |= mask;
mSerial->Advance( samples_per_bit );
mask = mask >> 1;
}
//we have a byte to save.
Frame frame;
frame.mData1 = data;
frame.mFlags = 0;
frame.mStartingSampleInclusive = starting_sample;
frame.mEndingSampleInclusive = mSerial->GetSampleNumber();
mResults->AddFrame( frame );
mResults->CommitResults();
ReportProgress( frame.mEndingSampleInclusive );
}
}
bool SimpleSerialAnalyzer::NeedsRerun()
{
return false;
}
U32 SimpleSerialAnalyzer::GenerateSimulationData( U64 minimum_sample_index, U32 device_sample_rate, SimulationChannelDescriptor** simulation_channels )
{
if( mSimulationInitilized == false )
{
mSimulationDataGenerator.Initialize( GetSimulationSampleRate(), mSettings.get() );
mSimulationInitilized = true;
}
return mSimulationDataGenerator.GenerateSimulationData( minimum_sample_index, device_sample_rate, simulation_channels );
}
U32 SimpleSerialAnalyzer::GetMinimumSampleRateHz()
{
return mSettings->mBitRate * 4;
}
const char* SimpleSerialAnalyzer::GetAnalyzerName() const
{
return "Simple Serial";
}
const char* GetAnalyzerName()
{
return "Simple Serial";
}
Analyzer* CreateAnalyzer()
{
return new SimpleSerialAnalyzer();
}
void DestroyAnalyzer( Analyzer* analyzer )
{
delete analyzer;
}

View File

@@ -1,73 +0,0 @@
#include "SimpleSerialAnalyzerSettings.h"
#include <AnalyzerHelpers.h>
SimpleSerialAnalyzerSettings::SimpleSerialAnalyzerSettings()
: mInputChannel( UNDEFINED_CHANNEL ),
mBitRate( 9600 )
{
mInputChannelInterface.reset( new AnalyzerSettingInterfaceChannel() );
mInputChannelInterface->SetTitleAndTooltip( "Serial", "Standard Simple Serial" );
mInputChannelInterface->SetChannel( mInputChannel );
mBitRateInterface.reset( new AnalyzerSettingInterfaceInteger() );
mBitRateInterface->SetTitleAndTooltip( "Bit Rate (Bits/S)", "Specify the bit rate in bits per second." );
mBitRateInterface->SetMax( 6000000 );
mBitRateInterface->SetMin( 1 );
mBitRateInterface->SetInteger( mBitRate );
AddInterface( mInputChannelInterface.get() );
AddInterface( mBitRateInterface.get() );
AddExportOption( 0, "Export as text/csv file" );
AddExportExtension( 0, "text", "txt" );
AddExportExtension( 0, "csv", "csv" );
ClearChannels();
AddChannel( mInputChannel, "Serial", false );
}
SimpleSerialAnalyzerSettings::~SimpleSerialAnalyzerSettings()
{
}
bool SimpleSerialAnalyzerSettings::SetSettingsFromInterfaces()
{
mInputChannel = mInputChannelInterface->GetChannel();
mBitRate = mBitRateInterface->GetInteger();
ClearChannels();
AddChannel( mInputChannel, "Simple Serial", true );
return true;
}
void SimpleSerialAnalyzerSettings::UpdateInterfacesFromSettings()
{
mInputChannelInterface->SetChannel( mInputChannel );
mBitRateInterface->SetInteger( mBitRate );
}
void SimpleSerialAnalyzerSettings::LoadSettings( const char* settings )
{
SimpleArchive text_archive;
text_archive.SetString( settings );
text_archive >> mInputChannel;
text_archive >> mBitRate;
ClearChannels();
AddChannel( mInputChannel, "Simple Serial", true );
UpdateInterfacesFromSettings();
}
const char* SimpleSerialAnalyzerSettings::SaveSettings()
{
SimpleArchive text_archive;
text_archive << mInputChannel;
text_archive << mBitRate;
return SetReturnString( text_archive.GetString() );
}

View File

@@ -1,29 +0,0 @@
#ifndef SIMPLESERIAL_SIMULATION_DATA_GENERATOR
#define SIMPLESERIAL_SIMULATION_DATA_GENERATOR
#include <SimulationChannelDescriptor.h>
#include <string>
class SimpleSerialAnalyzerSettings;
class SimpleSerialSimulationDataGenerator
{
public:
SimpleSerialSimulationDataGenerator();
~SimpleSerialSimulationDataGenerator();
void Initialize( U32 simulation_sample_rate, SimpleSerialAnalyzerSettings* settings );
U32 GenerateSimulationData( U64 newest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel );
protected:
SimpleSerialAnalyzerSettings* mSettings;
U32 mSimulationSampleRateHz;
protected:
void CreateSerialByte();
std::string mSerialText;
U32 mStringIndex;
SimulationChannelDescriptor mSerialSimulationData;
};
#endif //SIMPLESERIAL_SIMULATION_DATA_GENERATOR

252
src/TLC59731Analyzer.cpp Normal file
View File

@@ -0,0 +1,252 @@
#include "TLC59731Analyzer.h"
#include "TLC59731AnalyzerSettings.h"
#include <AnalyzerChannelData.h>
#include <AnalyzerResults.h>
TLC59731Analyzer::TLC59731Analyzer() : Analyzer2(), mSettings(), mSimulationInitilized( false )
{
SetAnalyzerSettings( &mSettings );
}
TLC59731Analyzer::~TLC59731Analyzer()
{
KillThread();
}
void TLC59731Analyzer::SetupResults()
{
// SetupResults is called each time the analyzer is run. Because the same instance can be used for multiple runs, we need to clear the
// results each time.
mResults.reset( new TLC59731AnalyzerResults( this, &mSettings ) );
SetAnalyzerResults( mResults.get() );
mResults->AddChannelBubblesWillAppearOn( mSettings.mInputChannel );
}
void TLC59731Analyzer::WorkerThread()
{
mSampleRateHz = GetSampleRate();
mSerial = GetAnalyzerChannelData( mSettings.mInputChannel );
while( SamplesToNS( mSerial->GetSampleOfNextEdge() - mSerial->GetSampleNumber() ) < TLL_MIN )
{
mSerial->AdvanceToNextEdge();
}
while( mSerial->GetBitState() != BIT_HIGH )
{
mSerial->AdvanceToNextEdge(); // wait for rising
}
U32 data = 0;
// measure cycletime
// start of bit
U64 SoB = mSerial->GetSampleNumber();
U64 starting_sample = SoB;
mSerial->AdvanceToNextEdge(); // falling edge
if( SamplesToNS( mSerial->GetSampleOfNextEdge() - SoB ) <= MAX_CYCLETIME )
{
mSerial->AdvanceToNextEdge(); // rising edge of second 0
cycleTime = SamplesToNS( mSerial->GetSampleNumber() - SoB );
SoB = mSerial->GetSampleNumber();
}
while( 1 )
{
mSerial->AdvanceToNextEdge(); // falling edge
if( SamplesToNS( mSerial->GetSampleOfNextEdge() - SoB ) < cycleTime / 2 )
{
// 1
data <<= 1;
data |= 1;
mSerial->AdvanceToNextEdge(); // rising edge of second pulse of 1
mSerial->AdvanceToNextEdge(); // falling edge of second ṕulse of 1
}
else
{
// 0
data <<= 1;
}
if( SamplesToNS( mSerial->GetSampleOfNextEdge() - SoB ) < cycleTime * 2 )
{
mSerial->AdvanceToNextEdge(); // rising edge of next bit
SoB = mSerial->GetSampleNumber();
}
else if( SamplesToNS( mSerial->GetSampleOfNextEdge() - SoB ) < cycleTime * 5.5 ||
SamplesToNS( mSerial->GetSampleOfNextEdge() - SoB ) > cycleTime * 8 )
{
// EOS end of sequence
Frame frame;
frame.mData1 = data;
frame.mFlags = 0;
frame.mStartingSampleInclusive = starting_sample;
frame.mEndingSampleInclusive = mSerial->GetSampleNumber();
mResults->AddFrame( frame );
mResults->CommitResults();
ReportProgress( frame.mEndingSampleInclusive );
data = 0;
mSerial->AdvanceToNextEdge();
SoB = mSerial->GetSampleNumber();
starting_sample = SoB;
}
}
// if( mSerial->GetBitState() == BIT_LOW )
// mSerial->AdvanceToNextEdge();
// U32 samples_per_bit = mSampleRateHz / mSettings.mBitRate;
// U32 samples_to_first_center_of_first_data_bit = U32( 1.5 * double( mSampleRateHz ) / double( mSettings.mBitRate ) );
// bool firstRun = 1;
// U64 startEdge, starting_sample;
// U8 bits = 0;
// while( 1 )
// {
// if( firstRun )
// {
// startEdge = mSerial->GetSampleNumber();
// starting_sample = startEdge;
// mSerial->AdvanceToNextEdge(); // falling edge
// cycleTime = SamplesToNS( mSerial->GetSampleOfNextEdge() - startEdge );
// firstRun = false;
// bits = 1;
// }
// else
// {
// }
// U32 data = 0;
// U8 bits = 2;
// mSerial->AdvanceToNextEdge(); // rising edge
// startEdge = mSerial->GetSampleNumber();
// mSerial->AdvanceToNextEdge(); // falling edge // second zero
// while( 1 )
// {
// if( SamplesToNS( mSerial->GetSampleOfNextEdge() - startEdge ) < cycleTime / 2 )
// {
// // one
// data <<= 1;
// data |= 1;
// bits += 1;
// mResults->AddMarker( startEdge, AnalyzerResults::One, mSettings.mInputChannel );
// }
// else if( SamplesToNS( mSerial->GetSampleOfNextEdge() - startEdge ) < cycleTime * 2 )
// {
// // zero
// data <<= 1;
// bits += 1;
// mResults->AddMarker( startEdge, AnalyzerResults::Zero, mSettings.mInputChannel );
// }
// else if( SamplesToNS( mSerial->GetSampleOfNextEdge() - startEdge ) < cycleTime * 5.5 )
// {
// }
// else if( SamplesToNS( mSerial->GetSampleOfNextEdge() - startEdge ) > cycleTime * 8 )
// {
// // cleanup
// }
// if( bits == 32 )
// {
// break;
// }
// else
// {
// mSerial->AdvanceToNextEdge(); // rising edge
// startEdge = mSerial->GetSampleOfNextEdge();
// mSerial->AdvanceToNextEdge(); // falling edge
// }
// }
// Frame frame;
// frame.mData1 = data;
// frame.mFlags = 0;
// frame.mStartingSampleInclusive = starting_sample;
// frame.mEndingSampleInclusive = mSerial->GetSampleNumber();
// mResults->AddFrame( frame );
// mResults->CommitResults();
// ReportProgress( frame.mEndingSampleInclusive );
// }
// for( ;; )
// {
// U8 data = 0;
// U8 mask = 1 << 7;
// mSerial->AdvanceToNextEdge(); // falling edge -- beginning of the start bit
// U64 starting_sample = mSerial->GetSampleNumber();
// // mSerial->Advance( samples_to_first_center_of_first_data_bit );
// for( U32 i = 0; i < 8; i++ )
// {
// // let's put a dot exactly where we sample this bit:
// mResults->AddMarker( mSerial->GetSampleNumber(), AnalyzerResults::Dot, mSettings.mInputChannel );
// if( mSerial->GetBitState() == BIT_HIGH )
// data |= mask;
// // mSerial->Advance( samples_per_bit );
// mask = mask >> 1;
// }
// // we have a byte to save.
// Frame frame;
// frame.mData1 = data;
// frame.mFlags = 0;
// frame.mStartingSampleInclusive = starting_sample;
// frame.mEndingSampleInclusive = mSerial->GetSampleNumber();
// mResults->AddFrame( frame );
// mResults->CommitResults();
// ReportProgress( frame.mEndingSampleInclusive );
// }
}
bool TLC59731Analyzer::NeedsRerun()
{
return false;
}
U32 TLC59731Analyzer::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 TLC59731Analyzer::GetMinimumSampleRateHz()
{
return mSettings.mBitRate * 4;
}
const char* TLC59731Analyzer::GetAnalyzerName() const
{
return "Simple Serial";
}
const char* GetAnalyzerName()
{
return "Simple Serial";
}
Analyzer* CreateAnalyzer()
{
return new TLC59731Analyzer();
}
void DestroyAnalyzer( Analyzer* analyzer )
{
delete analyzer;
}

View File

@@ -1,16 +1,22 @@
#ifndef SIMPLESERIAL_ANALYZER_H
#define SIMPLESERIAL_ANALYZER_H
#ifndef TLC59731_ANALYZER_H
#define TLC59731_ANALYZER_H
#include <Analyzer.h>
#include "SimpleSerialAnalyzerResults.h"
#include "SimpleSerialSimulationDataGenerator.h"
#include "TLC59731AnalyzerSettings.h"
#include "TLC59731AnalyzerResults.h"
#include "TLC59731SimulationDataGenerator.h"
#include <LogicPublicTypes.h>
#include <memory>
class SimpleSerialAnalyzerSettings;
class ANALYZER_EXPORT SimpleSerialAnalyzer : public Analyzer2
#define TLL_MIN 500000
#define MAX_CYCLETIME 50000 // in ns
class ANALYZER_EXPORT TLC59731Analyzer : public Analyzer2
{
public:
SimpleSerialAnalyzer();
virtual ~SimpleSerialAnalyzer();
TLC59731Analyzer();
virtual ~TLC59731Analyzer();
virtual void SetupResults();
virtual void WorkerThread();
@@ -20,23 +26,26 @@ public:
virtual const char* GetAnalyzerName() const;
virtual bool NeedsRerun();
U64 SamplesToNS(U64 samples) { return (samples * 1000000000) / mSampleRateHz; }
protected: //vars
SimpleSerialAnalyzerSettings mSettings;
SimpleSerialAnalyzerResults mResults;
TLC59731AnalyzerSettings mSettings;
std::unique_ptr<TLC59731AnalyzerResults> mResults;
AnalyzerChannelData* mSerial;
SimpleSerialSimulationDataGenerator mSimulationDataGenerator;
TLC59731SimulationDataGenerator mSimulationDataGenerator;
bool mSimulationInitilized;
//Serial analysis vars:
U32 mSampleRateHz;
U64 cycleTime;
U32 mStartOfStopBitOffset;
U32 mEndOfStopBitOffset;
};
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 //SIMPLESERIAL_ANALYZER_H
#endif //TLC59731_ANALYZER_H

View File

@@ -1,32 +1,32 @@
#include "SimpleSerialAnalyzerResults.h"
#include "TLC59731AnalyzerResults.h"
#include <AnalyzerHelpers.h>
#include "SimpleSerialAnalyzer.h"
#include "SimpleSerialAnalyzerSettings.h"
#include "TLC59731Analyzer.h"
#include "TLC59731AnalyzerSettings.h"
#include <iostream>
#include <fstream>
SimpleSerialAnalyzerResults::SimpleSerialAnalyzerResults( SimpleSerialAnalyzer* analyzer, SimpleSerialAnalyzerSettings* settings )
TLC59731AnalyzerResults::TLC59731AnalyzerResults( TLC59731Analyzer* analyzer, TLC59731AnalyzerSettings* settings )
: AnalyzerResults(),
mSettings( settings ),
mAnalyzer( analyzer )
{
}
SimpleSerialAnalyzerResults::~SimpleSerialAnalyzerResults()
TLC59731AnalyzerResults::~TLC59731AnalyzerResults()
{
}
void SimpleSerialAnalyzerResults::GenerateBubbleText( U64 frame_index, Channel& channel, DisplayBase display_base )
void TLC59731AnalyzerResults::GenerateBubbleText( U64 frame_index, Channel& channel, DisplayBase display_base )
{
ClearResultStrings();
Frame frame = GetFrame( frame_index );
char number_str[128];
AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 8, number_str, 128 );
AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 32, number_str, 128 );
AddResultString( number_str );
}
void SimpleSerialAnalyzerResults::GenerateExportFile( const char* file, DisplayBase display_base, U32 export_type_user_id )
void TLC59731AnalyzerResults::GenerateExportFile( const char* file, DisplayBase display_base, U32 export_type_user_id )
{
std::ofstream file_stream( file, std::ios::out );
@@ -58,7 +58,7 @@ void SimpleSerialAnalyzerResults::GenerateExportFile( const char* file, DisplayB
file_stream.close();
}
void SimpleSerialAnalyzerResults::GenerateFrameTabularText( U64 frame_index, DisplayBase display_base )
void TLC59731AnalyzerResults::GenerateFrameTabularText( U64 frame_index, DisplayBase display_base )
{
#ifdef SUPPORTS_PROTOCOL_SEARCH
Frame frame = GetFrame( frame_index );
@@ -70,13 +70,13 @@ void SimpleSerialAnalyzerResults::GenerateFrameTabularText( U64 frame_index, Dis
#endif
}
void SimpleSerialAnalyzerResults::GeneratePacketTabularText( U64 packet_id, DisplayBase display_base )
void TLC59731AnalyzerResults::GeneratePacketTabularText( U64 packet_id, DisplayBase display_base )
{
//not supported
}
void SimpleSerialAnalyzerResults::GenerateTransactionTabularText( U64 transaction_id, DisplayBase display_base )
void TLC59731AnalyzerResults::GenerateTransactionTabularText( U64 transaction_id, DisplayBase display_base )
{
//not supported
}

View File

@@ -3,14 +3,14 @@
#include <AnalyzerResults.h>
class SimpleSerialAnalyzer;
class SimpleSerialAnalyzerSettings;
class TLC59731Analyzer;
class TLC59731AnalyzerSettings;
class SimpleSerialAnalyzerResults : public AnalyzerResults
class TLC59731AnalyzerResults : public AnalyzerResults
{
public:
SimpleSerialAnalyzerResults( SimpleSerialAnalyzer* analyzer, SimpleSerialAnalyzerSettings* settings );
virtual ~SimpleSerialAnalyzerResults();
TLC59731AnalyzerResults( TLC59731Analyzer* analyzer, TLC59731AnalyzerSettings* settings );
virtual ~TLC59731AnalyzerResults();
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 );
@@ -22,8 +22,8 @@ public:
protected: //functions
protected: //vars
SimpleSerialAnalyzerSettings* mSettings;
SimpleSerialAnalyzer* mAnalyzer;
TLC59731AnalyzerSettings* mSettings;
TLC59731Analyzer* mAnalyzer;
};
#endif //SIMPLESERIAL_ANALYZER_RESULTS

View File

@@ -0,0 +1,73 @@
#include "TLC59731AnalyzerSettings.h"
#include <AnalyzerHelpers.h>
TLC59731AnalyzerSettings::TLC59731AnalyzerSettings()
: mInputChannel( UNDEFINED_CHANNEL ),
// mBitRate( 9600 ),
mInputChannelInterface(),
mBitRateInterface()
{
mInputChannelInterface.SetTitleAndTooltip( "Serial", "Standard Simple Serial" );
mInputChannelInterface.SetChannel( mInputChannel );
mBitRateInterface.SetTitleAndTooltip( "Bit Rate (Bits/S)", "Specify the bit rate in bits per second." );
mBitRateInterface.SetMax( 6000000 );
mBitRateInterface.SetMin( 1 );
mBitRateInterface.SetInteger( mBitRate );
AddInterface( &mInputChannelInterface );
AddInterface( &mBitRateInterface );
AddExportOption( 0, "Export as text/csv file" );
AddExportExtension( 0, "text", "txt" );
AddExportExtension( 0, "csv", "csv" );
ClearChannels();
AddChannel( mInputChannel, "Serial", false );
}
TLC59731AnalyzerSettings::~TLC59731AnalyzerSettings()
{
}
bool TLC59731AnalyzerSettings::SetSettingsFromInterfaces()
{
mInputChannel = mInputChannelInterface.GetChannel();
mBitRate = mBitRateInterface.GetInteger();
ClearChannels();
AddChannel( mInputChannel, "Simple Serial", true );
return true;
}
void TLC59731AnalyzerSettings::UpdateInterfacesFromSettings()
{
mInputChannelInterface.SetChannel( mInputChannel );
mBitRateInterface.SetInteger( mBitRate );
}
void TLC59731AnalyzerSettings::LoadSettings( const char* settings )
{
SimpleArchive text_archive;
text_archive.SetString( settings );
text_archive >> mInputChannel;
text_archive >> mBitRate;
ClearChannels();
AddChannel( mInputChannel, "Simple Serial", true );
UpdateInterfacesFromSettings();
}
const char* TLC59731AnalyzerSettings::SaveSettings()
{
SimpleArchive text_archive;
text_archive << mInputChannel;
text_archive << mBitRate;
return SetReturnString( text_archive.GetString() );
}

View File

@@ -4,11 +4,11 @@
#include <AnalyzerSettings.h>
#include <AnalyzerTypes.h>
class SimpleSerialAnalyzerSettings : public AnalyzerSettings
class TLC59731AnalyzerSettings : public AnalyzerSettings
{
public:
SimpleSerialAnalyzerSettings();
virtual ~SimpleSerialAnalyzerSettings();
TLC59731AnalyzerSettings();
virtual ~TLC59731AnalyzerSettings();
virtual bool SetSettingsFromInterfaces();
void UpdateInterfacesFromSettings();

View File

@@ -1,19 +1,19 @@
#include "SimpleSerialSimulationDataGenerator.h"
#include "SimpleSerialAnalyzerSettings.h"
#include "TLC59731SimulationDataGenerator.h"
#include "TLC59731AnalyzerSettings.h"
#include <AnalyzerHelpers.h>
SimpleSerialSimulationDataGenerator::SimpleSerialSimulationDataGenerator()
TLC59731SimulationDataGenerator::TLC59731SimulationDataGenerator()
: mSerialText( "My first analyzer, woo hoo!" ),
mStringIndex( 0 )
{
}
SimpleSerialSimulationDataGenerator::~SimpleSerialSimulationDataGenerator()
TLC59731SimulationDataGenerator::~TLC59731SimulationDataGenerator()
{
}
void SimpleSerialSimulationDataGenerator::Initialize( U32 simulation_sample_rate, SimpleSerialAnalyzerSettings* settings )
void TLC59731SimulationDataGenerator::Initialize( U32 simulation_sample_rate, TLC59731AnalyzerSettings* settings )
{
mSimulationSampleRateHz = simulation_sample_rate;
mSettings = settings;
@@ -23,7 +23,7 @@ void SimpleSerialSimulationDataGenerator::Initialize( U32 simulation_sample_rate
mSerialSimulationData.SetInitialBitState( BIT_HIGH );
}
U32 SimpleSerialSimulationDataGenerator::GenerateSimulationData( U64 largest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel )
U32 TLC59731SimulationDataGenerator::GenerateSimulationData( U64 largest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel )
{
U64 adjusted_largest_sample_requested = AnalyzerHelpers::AdjustSimulationTargetSample( largest_sample_requested, sample_rate, mSimulationSampleRateHz );
@@ -36,7 +36,7 @@ U32 SimpleSerialSimulationDataGenerator::GenerateSimulationData( U64 largest_sam
return 1;
}
void SimpleSerialSimulationDataGenerator::CreateSerialByte()
void TLC59731SimulationDataGenerator::CreateSerialByte()
{
U32 samples_per_bit = mSimulationSampleRateHz / mSettings->mBitRate;

View File

@@ -0,0 +1,29 @@
#ifndef TLC59731_SIMULATION_DATA_GENERATOR
#define TLC59731_SIMULATION_DATA_GENERATOR
#include <SimulationChannelDescriptor.h>
#include <string>
class TLC59731AnalyzerSettings;
class TLC59731SimulationDataGenerator
{
public:
TLC59731SimulationDataGenerator();
~TLC59731SimulationDataGenerator();
void Initialize( U32 simulation_sample_rate, TLC59731AnalyzerSettings* settings );
U32 GenerateSimulationData( U64 newest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel );
protected:
TLC59731AnalyzerSettings* mSettings;
U32 mSimulationSampleRateHz;
protected:
void CreateSerialByte();
std::string mSerialText;
U32 mStringIndex;
SimulationChannelDescriptor mSerialSimulationData;
};
#endif //TLC59731_SIMULATION_DATA_GENERATOR