From 1a4392b8dbfbad0b5ce273012a976ea381050df1 Mon Sep 17 00:00:00 2001 From: Thomas Roth Date: Mon, 9 May 2022 11:42:55 +0200 Subject: [PATCH] Fix marker sampling edge and add support for JTAG-to-SWD sequence. --- src/SWDAnalyzer.cpp | 6 +++++ src/SWDAnalyzerResults.cpp | 26 +++++++++++++++----- src/SWDTypes.cpp | 50 +++++++++++++++++++++++++++++++------- src/SWDTypes.h | 15 ++++++++++++ 4 files changed, 82 insertions(+), 15 deletions(-) diff --git a/src/SWDAnalyzer.cpp b/src/SWDAnalyzer.cpp index dbb1da0..7edc36a 100644 --- a/src/SWDAnalyzer.cpp +++ b/src/SWDAnalyzer.cpp @@ -41,6 +41,7 @@ void SWDAnalyzer::WorkerThread() // on calls to IsOperation or IsLineReset SWDOperation tran; SWDLineReset reset; + SWDJtagToSwd jtagToSwd; SWDBit error_bit; mSWDParser.Clear(); @@ -65,6 +66,11 @@ void SWDAnalyzer::WorkerThread() mResults->CommitResults(); } + else if( mSWDParser.IsJtagToSwd( jtagToSwd ) ) + { + jtagToSwd.AddFrames( mResults.get() ); + mResults->CommitResults(); + } else { // This is neither a valid transaction nor a valid reset, diff --git a/src/SWDAnalyzerResults.cpp b/src/SWDAnalyzerResults.cpp index 92bc31c..c0f062f 100644 --- a/src/SWDAnalyzerResults.cpp +++ b/src/SWDAnalyzerResults.cpp @@ -69,6 +69,13 @@ void SWDAnalyzerResults::GetBubbleText( const Frame& f, DisplayBase display_base results.push_back( "reset" ); results.push_back( "Line Reset" ); } + else if ( f.mType == SWDFT_JtagToSwd ) + { + results.push_back( "JTAG to SWD sequence" ); + results.push_back( "JtS" ); + results.push_back( "JTAGtoSWD" ); + results.push_back( "JTAG to SWD" ); + } else if( f.mType == SWDFT_Turnaround ) { results.push_back( "Turnaround" ); @@ -102,18 +109,18 @@ void SWDAnalyzerResults::GetBubbleText( const Frame& f, DisplayBase display_base results.push_back( "ACK" ); } - else if( f.mType == SWDFT_WData ) + else if( ( f.mType == SWDFT_WData ) || ( f.mType == SWDFT_RData ) ) { std::string data_str( int2str_sal( f.mData1, display_base, 32 ) ); SWDRegisters reg( SWDRegisters( f.mData2 ) ); std::string reg_name( GetRegisterName( reg ) ); std::string reg_value( GetRegisterValueDesc( reg, U32( f.mData1 ), display_base ) ); - + std::string prefix = ( f.mType == SWDFT_WData ) ? "WData" : "RData"; if( !reg_value.empty() ) - results.push_back( "WData " + data_str + " reg " + reg_name + " bits " + reg_value ); - results.push_back( "WData " + data_str + " reg " + reg_name ); - results.push_back( "WData" ); - results.push_back( "WData " + data_str ); + results.push_back( prefix + " " + data_str + " reg " + reg_name + " bits " + reg_value ); + results.push_back( prefix + " " + data_str + " reg " + reg_name ); + results.push_back( prefix ); + results.push_back( prefix + " " + data_str ); } else if( f.mType == SWDFT_DataParity ) { @@ -214,6 +221,13 @@ void SWDAnalyzerResults::GenerateExportFile( const char* file, DisplayBase displ record.push_back( "Line reset" ); SaveRecord( record, of ); } + else if( f.mType == SWDFT_JtagToSwd) + { + SaveRecord( record, of ); + record.push_back( GetSampleTimeStr( f.mStartingSampleInclusive ) ); + record.push_back( "JTAG to SWD Sequence" ); + SaveRecord( record, of ); + } else if( f.mType == SWDFT_Request ) { SaveRecord( record, of ); diff --git a/src/SWDTypes.cpp b/src/SWDTypes.cpp index cf889fa..0a63389 100644 --- a/src/SWDTypes.cpp +++ b/src/SWDTypes.cpp @@ -13,6 +13,7 @@ const int TRAN_REQ_AND_ACK = 8 + 1 + 3; // request/turnaround/ACK const int TRAN_READ_LENGTH = TRAN_REQ_AND_ACK + 33; // previous + 32bit data + parity const int TRAN_WRITE_LENGTH = TRAN_READ_LENGTH + 1; // previous + one bit for turnaround +const int TRAN_JTAG_TO_SWD = 16; S64 SWDBit::GetMinStartEnd() const { @@ -108,7 +109,12 @@ void SWDOperation::AddFrames( SWDAnalyzerResults* pResults ) // data f = bi->MakeFrame(); f.mEndingSampleInclusive = bi[ 31 ].GetEndSample(); - f.mType = SWDFT_WData; + if( IsRead() ) + { + f.mType = SWDFT_RData; + } else { + f.mType = SWDFT_WData; + } f.mData1 = data; f.mData2 = reg; pResults->AddFrame( f ); @@ -147,14 +153,9 @@ void SWDOperation::AddMarkers( SWDAnalyzerResults* pResults ) if( ndx == 8 || ndx == 12 && !IsRead() ) pResults->AddMarker( ( bi->falling + bi->rising ) / 2, AnalyzerResults::X, pResults->GetSettings()->mSWCLK ); - // write - else if( ndx < 8 || ndx > 12 && !IsRead() ) - pResults->AddMarker( bi->falling, bi->state_falling == BIT_HIGH ? AnalyzerResults::One : AnalyzerResults::Zero, - pResults->GetSettings()->mSWCLK ); - // read - else - pResults->AddMarker( bi->rising, bi->state_rising == BIT_HIGH ? AnalyzerResults::One : AnalyzerResults::Zero, - pResults->GetSettings()->mSWCLK ); + // Data is always sampled by both ends on the rising edge. + pResults->AddMarker( bi->rising, bi->state_rising == BIT_HIGH ? AnalyzerResults::One : AnalyzerResults::Zero, + pResults->GetSettings()->mSWCLK ); } } @@ -238,6 +239,19 @@ void SWDLineReset::AddFrames( AnalyzerResults* pResults ) // ******************************************************************************** +void SWDJtagToSwd::AddFrames( AnalyzerResults* pResults ) +{ + Frame f; + f.mStartingSampleInclusive = bits.front().GetStartSample(); + f.mEndingSampleInclusive = bits.back().GetEndSample(); + f.mType = SWDFT_JtagToSwd; + f.mData1 = bits.size(); + pResults->AddFrame( f ); +} + +// ******************************************************************************** + + SWDParser::SWDParser() : mSWDIO( 0 ), mSWCLK( 0 ) { } @@ -491,3 +505,21 @@ bool SWDParser::IsLineReset( SWDLineReset& reset ) return true; } + +bool SWDParser::IsJtagToSwd( SWDJtagToSwd& jtagToSwd ) { + jtagToSwd.Clear(); + uint16_t sequence = 0b0111100111100111; + for( size_t cnt = 0; cnt < 16; cnt++ ) + { + if( cnt >= mBitsBuffer.size() ) + mBitsBuffer.push_back( ParseBit() ); + + if( mBitsBuffer[ cnt ].IsHigh() != ( ( sequence >> ( 15 - cnt ) ) & 0b1 ) ) + return false; + } + + jtagToSwd.bits = mBitsBuffer; + mBitsBuffer.clear(); + + return true; +} \ No newline at end of file diff --git a/src/SWDTypes.h b/src/SWDTypes.h index 69ed08c..12cda97 100644 --- a/src/SWDTypes.h +++ b/src/SWDTypes.h @@ -12,11 +12,13 @@ enum SWDFrameTypes SWDFT_Bit, SWDFT_LineReset, + SWDFT_JtagToSwd, SWDFT_Request, SWDFT_Turnaround, SWDFT_ACK, SWDFT_WData, + SWDFT_RData, SWDFT_DataParity, SWDFT_TrailingBits, }; @@ -131,6 +133,18 @@ struct SWDLineReset void AddFrames( AnalyzerResults* pResults ); }; +struct SWDJtagToSwd +{ + std::vector bits; + + void Clear() + { + bits.clear(); + } + + void AddFrames( AnalyzerResults* pResults ); +}; + struct SWDRequestFrame : public Frame { // mData1 contains addr, mData2 contains the register enum @@ -207,6 +221,7 @@ class SWDParser bool IsOperation( SWDOperation& tran ); bool IsLineReset( SWDLineReset& reset ); + bool IsJtagToSwd( SWDJtagToSwd& jtagToSwd ); SWDBit PopFrontBit(); };