saleae / usb-analyzer

Saleae USB Analyzer
MIT License
28 stars 15 forks source link

Support High level Analyzers using FrameV2 #3

Closed KurtE closed 3 months ago

KurtE commented 2 years ago

As I have mentioned several times on the forums, when I use this analyzer for trying to understand a how a new USB device works when trying to support them using the USB Host code on a Teensy 3.6 or 4.x, I often find that I don't find the trees in the forest, unless I do a ton of post processing.

So I have been hoping that you would add the support to this analyzer to work with High Level Analyzers.... So I started doing an experiment of taking a cut at it: Some of the details are up on the forum thread: https://discuss.saleae.com/t/usb-ls-and-fs-analyzer-been-enhanced/1222/8

So I now have a fork/branch of the code that I have started with a first pass. https://github.com/KurtE/usb-analyzer/tree/alpha

It is setup to build v2, and I changed analyzer name as such that it can load from debug, while it still has your released version

I have mainly concentrated so far on doing it for packets mode, which may work in others as well, I have not completed the Control Transfers yet.

I have also experimented with python (which I have done very little with python before), which I put an HLA using the current defined messages, which I is pretty well for this. https://github.com/KurtE/Saleae_USB_Data_Packets_HLA usb_mouse.zip

image

The report output from the HLA has all of the data I would typically need: image

I included the sample capture if anyone wants to play with it.

Question is, is this something that anyone is interested in integrating in or should I just keep it for my own usage.

Also I can imagine several different ways to factor FramesV2... Currently sort of one for one for V1

KurtE commented 2 years ago

Questions about preferred ways of creating FrameV2 packets...

With the stuff I pushed up so far in my Alpha branch I have several FrameV2 packet types, that sort of follows the V1...

Frame Type: "addrendp"

Address and End Point

Property Type Description
addr bytes usb addr
endpoint bytes endpoint

Frame Type: "crc16"

Property Type Description
crc bytes crc
ccrc bytes calculated crd

Frame Type: "crc5"

Property Type Description
crc bytes crc
ccrc bytes calculated crd

Frame Type: "EOP"

End of Packet

Frame Type: "frame"

Start of frame

Property Type Description
framenum bytes 16 bit frame number

Frame Type: "pid"

Packet type id

Property Type Description
pid bytes packet id
0x69 = IN
0xE1 = OUT
0xA5 = SOF
0x2D = SETUP
0xC3 = DATA0
0x4B = DATA1

Frame Type: "result"

one data byte

Property Type Description
out byte one byte of data

Frame Type: "sync"

End of Packet


But this sort of creates a lot of columns in the table... image

So for example would it be better to instead of create lots of columns, with many of these that have only one value, maybe have a generic column, like data or value, that many of these, might use. Example Frame, or PID or ...

Also started playing with Control Transfer outputs.. So far I am playing with just one message per packet: like:

void USBPacket::AddStandardSetupPacketFrame( USBAnalyzerResults* pResults, USBControlTransferParser& parser, U8 address )
{
    U8 bRequestType = GetDataPayload( 0, 1 );
    U8 bRequest = GetDataPayload( 1, 1 );
    U16 wValue = GetDataPayload( 2, 2 );
    U16 wIndex = GetDataPayload( 4, 2 );
    U16 wLength = GetDataPayload( 6, 2 );

    FrameV2 fv2;

    bool isRecipientInterface = ( bRequestType & 0x1f ) == 1;
    bool isRecipientEndpoint = ( bRequestType & 0x1f ) == 2;

    fv2.AddByte( "bmRequestType", bRequestType );
    if( wLength )
        pResults->AddFrame( GetDataPayloadField( 0, 1, address, "bmRequestType", Fld_bmRequestType, FF_SetupBegin ) );
    else
        pResults->AddFrame( GetDataPayloadField( 0, 1, address, "bmRequestType", Fld_bmRequestType_NoData, FF_SetupBegin ) );

    fv2.AddByte( "bRequest", bRequest );
    pResults->AddFrame( GetDataPayloadField( 1, 1, address, "bRequest", Fld_bRequest_Standard ) );

    if( bRequest == SET_DESCRIPTOR || bRequest == GET_DESCRIPTOR )
        pResults->AddFrame( GetDataPayloadField( 2, 2, address, "wValue", Fld_wValue_Descriptor ) );
    else if( bRequest == SET_ADDRESS )
        pResults->AddFrame( GetDataPayloadField( 2, 2, address, "wValue", Fld_wValue_Address ) );
    else
        pResults->AddFrame( GetDataPayloadField( 2, 2, address, "wValue" ) );

    U8 wValue_bytearray[ 2 ];
    wValue_bytearray[ 0 ] = wValue >> 8;
    wValue_bytearray[ 1 ] = wValue >> 0;
    fv2.AddByteArray( "wValue", wValue_bytearray, 2 );

    U8 hiByte = GetDataPayload( 3, 1 );
    U8 loByte = GetDataPayload( 2, 1 );
    if( isRecipientInterface )
    {
        pResults->AddFrame( GetDataPayloadField( 4, 2, address, "wIndex", Fld_wIndex_InterfaceNum ) );
    }
    else if( isRecipientEndpoint )
    {
        pResults->AddFrame( GetDataPayloadField( 4, 2, address, "wIndex", Fld_wIndex_Endpoint ) );
    }
    else if( bRequest == GET_DESCRIPTOR )
    {
        if( hiByte == DT_STRING && loByte != 0 )
            pResults->AddFrame( GetDataPayloadField( 4, 2, address, "wIndex", Fld_wLANGID ) );
        else
            pResults->AddFrame( GetDataPayloadField( 4, 2, address, "wIndex" ) );
    }
    else
    {
        pResults->AddFrame( GetDataPayloadField( 4, 2, address, "wIndex" ) );
    }

    U8 wIndex_bytearray[ 2 ];
    wIndex_bytearray[ 0 ] = wIndex >> 8;
    wIndex_bytearray[ 1 ] = wIndex >> 0;
    fv2.AddByteArray( "wIndex", wIndex_bytearray, 2 );

    pResults->AddFrame( GetDataPayloadField( 6, 2, address, "wLength" ) );

    U8 wLength_bytearray[ 2 ];
    wLength_bytearray[ 0 ] = wLength >> 8;
    wLength_bytearray[ 1 ] = wLength >> 0;
    fv2.AddByteArray( "wLength", wLength_bytearray, 2 );

    pResults->AddFrameV2( fv2, "protocol", mBitBeginSamples[ 16 ], mBitBeginSamples[ 16 + ( 8 ) * 8 ] );
}

So output looks like: image Now could add in more columns with for example the descriptor is a STRING ... Could do that as more columns, or could output one packet per V1 packet and maybe have two columns, value and description...

KurtE commented 3 months ago

Wondering if worthwhile to leave this open.

I have my own version that works, but would be nice if there was an official version

timreyes commented 3 months ago

Hi @KurtE - we'd be happy to close this issue if you'd like. Our eventual goal is to update all of our analyzers to support FrameV2 at some point in the future. We unfortunately just haven't gotten to it yet due to other priority projects on our plate. We do not need to keep this GitHub issue open since we've got this task logged internally.

Given the above, would you like me to proceed with closing this issue?