diff --git a/src/SpiAnalyzer.cpp b/src/SpiAnalyzer.cpp index 0b5412a..47b85f7 100644 --- a/src/SpiAnalyzer.cpp +++ b/src/SpiAnalyzer.cpp @@ -67,19 +67,27 @@ void SpiAnalyzer::Setup() if( mSettings->mDataValidEdge == AnalyzerEnums::LeadingEdge ) allow_last_trailing_clock_edge_to_fall_outside_enable = true; - if( mSettings->mClockInactiveState == BIT_LOW ) + if (mSettings->mSampleAtMiddle == SpiAnalyzerSettings::SAMPLE_MIDDLE) { - if( mSettings->mDataValidEdge == AnalyzerEnums::LeadingEdge ) - mArrowMarker = AnalyzerResults::UpArrow; - else - mArrowMarker = AnalyzerResults::DownArrow; - - }else + mArrowMarker = AnalyzerResults::Dot; + } + else { - if( mSettings->mDataValidEdge == AnalyzerEnums::LeadingEdge ) - mArrowMarker = AnalyzerResults::DownArrow; + if (mSettings->mClockInactiveState == BIT_LOW) + { + if (mSettings->mDataValidEdge == AnalyzerEnums::LeadingEdge) + mArrowMarker = AnalyzerResults::UpArrow; + else + mArrowMarker = AnalyzerResults::DownArrow; + + } else - mArrowMarker = AnalyzerResults::UpArrow; + { + if (mSettings->mDataValidEdge == AnalyzerEnums::LeadingEdge) + mArrowMarker = AnalyzerResults::DownArrow; + else + mArrowMarker = AnalyzerResults::UpArrow; + } } @@ -177,6 +185,7 @@ void SpiAnalyzer::GetWord() //we're assuming we come into this function with the clock in the idle state; U32 bits_per_transfer = mSettings->mBitsPerTransfer; + SpiAnalyzerSettings::SampleSetting sampleSetting = mSettings->mSampleAtMiddle; DataBuilder mosi_result; U64 mosi_word = 0; @@ -213,6 +222,11 @@ void SpiAnalyzer::GetWord() if( mSettings->mDataValidEdge == AnalyzerEnums::LeadingEdge ) { mCurrentSample = mClock->GetSampleNumber(); + if (sampleSetting == SpiAnalyzerSettings::SAMPLE_MIDDLE) + { + U64 nextSample = mClock->GetSampleOfNextEdge(); + mCurrentSample += (nextSample - mCurrentSample) / 2; + } if( mMosi != NULL ) { mMosi->AdvanceToAbsPosition( mCurrentSample ); @@ -256,6 +270,11 @@ void SpiAnalyzer::GetWord() if( mSettings->mDataValidEdge == AnalyzerEnums::TrailingEdge ) { mCurrentSample = mClock->GetSampleNumber(); + if (sampleSetting == SpiAnalyzerSettings::SAMPLE_MIDDLE) + { + U64 nextSample = mClock->GetSampleOfNextEdge(); + mCurrentSample += (nextSample - mCurrentSample) / 2; + } if( mMosi != NULL ) { mMosi->AdvanceToAbsPosition( mCurrentSample ); diff --git a/src/SpiAnalyzerSettings.cpp b/src/SpiAnalyzerSettings.cpp index 57498bc..2359b4c 100644 --- a/src/SpiAnalyzerSettings.cpp +++ b/src/SpiAnalyzerSettings.cpp @@ -13,7 +13,8 @@ SpiAnalyzerSettings::SpiAnalyzerSettings() mBitsPerTransfer( 8 ), mClockInactiveState( BIT_LOW ), mDataValidEdge( AnalyzerEnums::LeadingEdge ), - mEnableActiveState( BIT_LOW ) + mEnableActiveState( BIT_LOW ), + mSampleAtMiddle( SAMPLE_EDGE ) { mMosiChannelInterface.reset( new AnalyzerSettingInterfaceChannel() ); mMosiChannelInterface->SetTitleAndTooltip( "MOSI", "Master Out, Slave In" ); @@ -73,6 +74,12 @@ SpiAnalyzerSettings::SpiAnalyzerSettings() mEnableActiveStateInterface->AddNumber( BIT_HIGH, "Enable line is Active High", "" ); mEnableActiveStateInterface->SetNumber( mEnableActiveState ); + mSampleAtMiddleInterface.reset(new AnalyzerSettingInterfaceNumberList()); + mSampleAtMiddleInterface->SetTitleAndTooltip("Sample Point", "Configure at which point the data on the SPI bus is sampled."); + mSampleAtMiddleInterface->AddNumber(SAMPLE_EDGE, "Clock edge", "SPI data lines are sampled at the clock edge."); + mSampleAtMiddleInterface->AddNumber(SAMPLE_MIDDLE, "Delayed 1/2 clock", "SPI data lines are sampled at clocking halfway point."); + mSampleAtMiddleInterface->SetNumber(mSampleAtMiddle); + AddInterface( mMosiChannelInterface.get() ); AddInterface( mMisoChannelInterface.get() ); @@ -83,6 +90,7 @@ SpiAnalyzerSettings::SpiAnalyzerSettings() AddInterface( mClockInactiveStateInterface.get() ); AddInterface( mDataValidEdgeInterface.get() ); AddInterface( mEnableActiveStateInterface.get() ); + AddInterface( mSampleAtMiddleInterface.get() ); //AddExportOption( 0, "Export as text/csv file", "text (*.txt);;csv (*.csv)" ); @@ -136,6 +144,7 @@ bool SpiAnalyzerSettings::SetSettingsFromInterfaces() mClockInactiveState = (BitState) U32( mClockInactiveStateInterface->GetNumber() ); mDataValidEdge = (AnalyzerEnums::Edge) U32( mDataValidEdgeInterface->GetNumber() ); mEnableActiveState = (BitState) U32( mEnableActiveStateInterface->GetNumber() ); + mSampleAtMiddle = (SampleSetting) U32(mSampleAtMiddleInterface->GetNumber()); ClearChannels(); AddChannel( mMosiChannel, "MOSI", mMosiChannel != UNDEFINED_CHANNEL ); @@ -165,6 +174,7 @@ void SpiAnalyzerSettings::LoadSettings( const char* settings ) text_archive >> *(U32*)&mClockInactiveState; text_archive >> *(U32*)&mDataValidEdge; text_archive >> *(U32*)&mEnableActiveState; + text_archive >> *(U32*)&mSampleAtMiddle; //bool success = text_archive >> mUsePackets; //new paramater added -- do this for backwards compatibility //if( success == false ) @@ -193,6 +203,7 @@ const char* SpiAnalyzerSettings::SaveSettings() text_archive << mClockInactiveState; text_archive << mDataValidEdge; text_archive << mEnableActiveState; + text_archive << mSampleAtMiddle; return SetReturnString( text_archive.GetString() ); } @@ -208,4 +219,5 @@ void SpiAnalyzerSettings::UpdateInterfacesFromSettings() mClockInactiveStateInterface->SetNumber( mClockInactiveState ); mDataValidEdgeInterface->SetNumber( mDataValidEdge ); mEnableActiveStateInterface->SetNumber( mEnableActiveState ); + mSampleAtMiddleInterface->SetNumber(mSampleAtMiddle); } diff --git a/src/SpiAnalyzerSettings.h b/src/SpiAnalyzerSettings.h index b656e0f..b090a7d 100644 --- a/src/SpiAnalyzerSettings.h +++ b/src/SpiAnalyzerSettings.h @@ -7,6 +7,8 @@ class SpiAnalyzerSettings : public AnalyzerSettings { public: + enum SampleSetting { SAMPLE_EDGE, SAMPLE_MIDDLE }; + SpiAnalyzerSettings(); virtual ~SpiAnalyzerSettings(); @@ -25,6 +27,7 @@ class SpiAnalyzerSettings : public AnalyzerSettings BitState mClockInactiveState; AnalyzerEnums::Edge mDataValidEdge; BitState mEnableActiveState; + SampleSetting mSampleAtMiddle; protected: @@ -37,6 +40,7 @@ class SpiAnalyzerSettings : public AnalyzerSettings std::auto_ptr< AnalyzerSettingInterfaceNumberList > mClockInactiveStateInterface; std::auto_ptr< AnalyzerSettingInterfaceNumberList > mDataValidEdgeInterface; std::auto_ptr< AnalyzerSettingInterfaceNumberList > mEnableActiveStateInterface; + std::auto_ptr< AnalyzerSettingInterfaceNumberList > mSampleAtMiddleInterface; }; #endif //SPI_ANALYZER_SETTINGS