Hla spi

Hello all,

I’m trying to write a custom HLA for TFT displays using SPI as the LLA. I’ve already managed to identify some commands sent to the display. Nevertheless I don’t know how to check the status of the line “Data/Command” that is not part of SPI. Any guides on this regard?

on a different topic, following this tutorial: High-Level Analyzer (HLA) Extensions - Saleae Support
I see a different output on the analyzer bubbles text than expected.

With the following code:

result_types = {
‘match’: {
‘format’: ‘{{data.command}}’

                    return AnalyzerFrame('match', frame.start_time, frame.end_time, {"command": COMMANDS[ch]} )

I expected only the command name, for example “MADCTL”:
but I get “match(command=MADCTL)”

is it possible to get the expected output?

looking forward your reply,
Best regards, Mauro.

@maurosmartins Sorry for the late reply! We’re just returning from the holidays now. For your question below:

Nevertheless I don’t know how to check the status of the line “Data/Command” that is not part of SPI. Any guides on this regard?

Can you let me know a little more about the “Data/Command” line? Our HLAs are limited to working with the frames that the underlying LLA produces. It unfortunately doesn’t have the ability to check the status of channels that are not attached to the LLA.

For your question on the analyzer bubble text output, I’ll review it with the team here and will follow up with you.

Sorry for jumping in here.

There are lots of SPI based displays like: ILI9341, ILI9488, ST7735, ST7789, … That use a D/C pin as part of their communications, that use this pin like logically an SPI 9 bit communications, where the pin (or 9th bit) signifies if the byte is a command or data bytes associated with the pin. For example from the ILI9341 manual:

Hello @timreyes,

thank you for your reply, I’ll be waiting for the comments on the analyzer bubble.

regarding previous question, as @KurtE explained (thank you), the “Data/Command” line is an extra line that tells the display if current information on SPI is Data or a command. Can’t the raw status of all channels be checked when running the “decode” function?

looking forward your reply,
Best regards, Mauro.

@KurtE Thanks for jumping in! The image helped a ton. It makes sense now.

@maurosmartins To my best knowledge, the raw status of any channel cannot be checked by HLAs. In addition to your other question about the analyzer bubble, I’m going to double check this with the team here to see if they know of a workaround.

Apologies in advance as I most likely won’t be able to review this with the team until early next week due to the New Year holidays coming up. I’ll follow up again once I’ve had a chance to discuss this with them.

We don’t have a way to read the raw digital states in the python HLA API at this time.

This is something we want to fix! If you have a moment, we would appreciate if you add your interested to the feature suggestion here: High-level analyzer: combine data from multiple sources - Logic 2 - Ideas and Feature Requests - Saleae. Any use case information you can add in the comments would be great too.

In the meantime, you would need to modify the C++ SPI analyzer to include the extra channel, and to indicate the channel state in the FrameV2 object that’s passed up into the HLA.

We’re in the process of making the C++ FrameV2 API public right now, however it can be used to day simply by looking at the existing SPI analyzer source code, which is already using the new API feature: GitHub - saleae/spi-analyzer at alpha

Unfortunately, this is a good bit more complicated than just adding a few extra lines of code to your python HLA. We’re focused on analog features at the moment, and unfortunately won’t be back on extension development for a while. (Our SW team is 3 developers)

1 Like

Sounds like an interesting approach, which I have thought of wanting for awhile, who knows maybe at some point will take a look. Wonder how common it is for devices to use this… As I mentioned earlier have seen it on many displays.

New user to Saleae. First use case is exactly what’s being described here. Analyzing SPI communications for TFT LCD and e-paper displays.

In addition to the MISO, MOSI, CS and CLK signals, most displays also use D/C and RST (reset) lines for control. E-paper displays also output a BSY (busy) signal when they are updating the contents of the display (shouldn’t try to access the display when it’s busy).

Being able to separate out commands and data in the trace and data tables would be a very good add, either by extending the existing SPI analyzer or creating a “Displays” extension on top of it that would qualify the data.

Right now I’ve kind of faked it by defining the DC line as the MISO signal so it shows up in the the data table, but it’s be nice to be able to include any other signal as part of the SPI group and send that directly to the table.


@xylopyrographer Since you brought up your workaround of defining the DC line as a MISO signal, I’m now wondering if it may be possible to simply add 2x SPI analyzers while configuring both to take a look at the DC line as the EN line. One SPI analyzers would be configured with an active low EN, and the other configured as an active high EN like in the image below.

Channel 3 is acting as the DC line in this case. This would allow separating out the data and command signals in 2 separate rows above the waveform as well.

I could be missing a pretty critical detail here though, but if this works, it could be way simpler than having to add a DC line to our SPI analyzer by using our protocol analyzer SDK.


Actually I am playing with a hacked up version of your SPI analyzer to add the DC… Have it building and running, but, issue restoring settings and minor issue of crashing the analyzer… :wink:

I have the wip up at: https://github.com/KurtE/spi-analyzer/tree/SPIEx

But will hopefully debug some.

Running into some questions to self like:

How to hold the DC state in a frame:

class LOGICAPI Frame
    Frame( const Frame& frame );

    S64 mStartingSampleInclusive;
    S64 mEndingSampleInclusive;
    U64 mData1;
    U64 mData2;
    U8 mType;
    U8 mFlags;

    bool HasFlag( U8 flag );

You stores miso and mosi in data1 and data2.

So question to self or others:
a) Can I store it as a bit in mFlags (That is what I am trying now),
b) store as lets say high bit in data1 or 2… and punt on handling 64 bit transfers working with DC… But I never do that anyway so…

Also is there a way to run this under debugger these days? Running on Windows 10.

Working a little better now… May change the results for DC, but…

Again it is up in my SPIEx branch…

I encoded the data in mData2…

Now maybe need to learn enough of the HLA stuff to try…

Hey @KurtE, we haven’t documented nor fully verified the ability to debug custom analyzers on Logic 2. We only have this documented for the older Logic 1.1.18 software, which unfortunately can’t be used with our Gen2 hardware (Logic 4, Logic 8, Logic Pro 8, and Logic Pro 16).

However, a community user seems to have found some success with getting debugging working on Logic 2. Their forum post on this topic can be found below:

Thankd @timreyes

Yes I remember debugging the Dynamixel stuff earlier on the old IDE (real old).

As you can see in my previous post, I fixed the fault and save/restore setting…

Now to see if I can hack up partial HLA and talk to it…

Need to look at docs to see what constraints…

Opps, looks like I started from Master branch… Probably need to work from alpha…

Will see how hard to migrate over…

put up new branch: alpha_spiex

This one at least talks to the spi transaction framer. So I know that it talks somee to HLA

Ah! Clever. :+1: Let me play around with that and see how it goes. Thanks.

I started playing around with maybe an ILI9341 example HLA using my SPIEx code…

It is coming along sort of, but python is not a language I have done anything in, other than try to get rid of Ros Python code a few years ago :wink:

So I am stumbling along:

But making some progress… If the DC is 0 I try to look it up in a table… The table also has an indication of why data might follow, more simple in 1 or 2 byte chunks from MOSI or MISO…

As you can see in picture it is showing that the command is the CASET, which the table shows 2 bytes for entries.

And it then shows the range for columns is 0 319…
But I am not sure if I should be displaying 319…

I have hacked in there:

            elif self.last_from == 2:  # mosi 2 bytes
                if self.data_packet_count == 0:
                    self.frame_start_time = frame.start_time
                    self.data_packet_count = 1
                    self.data_packet_value = mosi[0]
                    self.data_packet_count = 0
                    self.data_packet_value =  (self.data_packet_value * 256) + mosi[0]
                    frame_data["command"] = self.data_packet_value
                    frame_type = "result_packet"

But if I click on the 3 dot it shows that I should be outputting HEX… so question is do I
need to encode the values: to a hex string, and where do I in the Python code get what the
user wants the output format to be?

Also side comments. I started the python code in one directory… Can I move it to another directory? If so How do I update the list?

Also side question, If I look at some published HLAs, they may mention to customize it, clone the project… And then click the local button… Not sure how to do that…

Back to playing

Quick update:
The extended SPI code is currently up in my fork/branch

Wondering at times if it should just be incorporated into SPI…

The ILI9341 experiment code is up at:

If you mean “How do I manage user options” you may be interested in User settings for measurement extensions - #8 by timreyes - I have the same issue. My “Burst Stats” extension has two “user” parameters at the top of the Python source.

Thanks, I was able to roll my own as you can see in:

Edit: where you can see my: option default, which is sort of a kludge, but for caset ans paset it shows in decimal, but others show in hex…

I guess my question in this case was if you look at the context menu for the Extension you see:

And was wondering if this setting was available to the python extension