• 0
joel

Custom protocol script in Logic Analyzer

Question

Hi--

I'd like to develop a "custom" protocol display for the Logic Analyzer, but I'm afraid I'm not finding the most basic information in the documentation.

For example, I have added a "Custom" protocol simply for test purposes, by simply using the supplied examples, but there is no indication that it is tied to any input, nor any suggestion in the documentation of how one ties an input line to a custom protocol.

As another example...when I add a custom protocol based upon the "SPI" example code, there is no indication in the display that 3 signal lines will be involved/displayed.

And when I run a custom protocol alongside a standard protocol which _is_ correctly sampling, there is no indication of any activity in the "custom" display line.

I understand the questions are very basic--I'd be happy to be directed to documentation I've missed (I've looked in the online "Help") or a complete working example.

I'm running an Analog Discovery 2 and WaveForms 2015 (3.3.5) under Mac OS X 10.11.5.

Thanks!

Share this post


Link to post
Share on other sites

13 answers to this question

Recommended Posts

  • 0

Hello,

See the Custom script Examples.

The Decoder script input is the rgData (raw digital input samples of 16/32bit values) and it should store the decoded protocol for each sample in the rgValue and rgFlag arrays.
The "Value to Text" script function should return the text representation for value and flag pairs.

Share this post


Link to post
Share on other sites
  • 0

Hi Atilla--

Thanks.

As I mentioned, I already have explored the Custom script examples. And I understand that the script input is the rgData. My question is perhaps more basic:

Example: If I set up the Analog Discovery to monitor an external SPI bus, and use the pre-built SPI protocol, trigger some SPI communications, I am able to collect the data. All works great.

Now, let's say I add a "Custom" protocol, and I select the "SPI" example decoder code from the Custom creation dialog, add it, and then trigger the same data communication. The "Custom" SPI protocol gives no indication that any data is being monitored, there is no indication in the UI that there are any input lines tied to the protocol, and so on. See screen shot. The Custom examples show useful-looking code, but I am unclear about how exactly the code is _used_ .

 

 

Screen Shot 2016-07-19 at 7.27.10 AM.png

Screen Shot 2016-07-19 at 7.26.48 AM.png

Share this post


Link to post
Share on other sites
  • 0

Here you can see the Custom SPI example and SPI interpreter. In the example the select is active high.

i4.png

The example code with a bit more comments:

// rgData: input, raw digital sample array
// rgValue: output, decoded data array
// rgFlag: output, decoded flag array

c = rgData.length // c = number of raw samples
pClock = false; // previous cock signal level
iStart = 0;     // used to keep track on byte start index
cByte = 0;      // byte count per transmission
cBits = 0;      // bit counter
bValue = 0;     // value variable

for(var i = 0; i < c; i++){ // for each sample
   s = rgData[i]; // current sample
   fClock = s & (1<<0); // pin0 is the clock signal
   fData = s & (1<<1); // pin1 is the data signal
   fSelect = s & (1<<2); // pin2 is the select signal

   if(fSelect == 0){ // select active high
      // while select inactive reset our counters/variables
      iStart = i+1; // select might become active with next sample
      cByte = 0;
      cBits = 0;
      bValue = 0;
      pClock = false;
      continue;
   }
   if(pClock == false && fClock == true){
      // sample on clock rising edge
      if(fData) {
         bValue |= 1<<cBits; // serial data bit, LSBit first
      }
      cBits++;
      if(cBits==8){ // when got the 8th bit store it
         cByte++;
         // store rgValue/Flag from byte start index to current sample position
         for(var j = iStart; j < i; j++){
            // Flag change will be visible on plot even when data remains constant.
            // This is useful in case we get more consecutive equal values.
            rgFlag[j] = cByte;
            rgValue[j] = bValue;
         }
         iStart = i+1; // next byte might start after this sample
         cBits = 0;  // reset bit count for the next byte
         bValue = 0; // reset value variable
      }
   }
   pClock = fClock; // previous clock level
}

 

Share this post


Link to post
Share on other sites
  • 0

Thanks Atilla-- 

you screen shot helps, because it tells me:

- A Custom protocol will not show any entry in the "I/O" column. I expected it would, but yours does not. That clarifies one issue.

- A Custom protocol will not display channels for the (three) data lines which are involved. Again, I expected it would, but yours does not. To confirm: a Custom protocol ONLY shows the "Decoded data" output...not the associated data lines?

Despite these lessons, I am still stuck. In my hands, the "Custom" SPI gives no indication that it's listening to anything. As you can see from the attached screenshot, when I do my version of your experiment, my "normal" SPI decoders work completely as expected, but the Custom display is completely inert.  I just copy/pasted the example code you provided, redefined the data lines to match my setup:

 fData = s & (1<<0) // pin0 is the data signal
 fClock = s & (1<<1) // pin1 is the clock signal
 fSelect = s & (1<<2) // pin2 is the select signal

and altered the code to reset when select is HIGH (because in my setup, select is active LOW):

   if (fSelect == 0) {

And then ran the tool. Is there something else I need to do? Thanks

Screen Shot 2016-07-19 at 9.35.56 AM.png

Share this post


Link to post
Share on other sites
  • 0

To have select active low in the above example use "  if (fSelect != 0) { "

Could you tell me for what protocol do you want to create interpreter ?

Share this post


Link to post
Share on other sites
  • 0

Sadly, your suggestion made no difference.

As far as what I'm trying to do: first, I was trying to understand the capabilities of the custom-protocol feature. I'm focused currently on variants of SPI.

For example, I'd like to display decoded MOSI and MISO at the same time. To do this currently, I have to instantiate two standard SPI decoders. I initially wanted to know if I could create a custom decoder that would display both--but now I have learned that a custom decoder only shows a single decode line of data--it does not show the data lines themselves, much less multiple decode lines. Oh well.

Secondly, I was wondering if I could change the data display to decode the SPI traffic into custom-domain-specific language, instead of just raw data. For example, if my local application sends "FF" in byte 2 to indicate that an "updateFoo" is being requested, could I display "updateFoo" instead of "FF". This seems less likely, now that I know more about the capabilities.

At the moment, I have to confess that I'm wondering if the Mac OS version of the custom protocol decoder for logic analyzer works properly. I note that your examples are using Windows, and I understand that the Mac version of WaveForms was a secondary project compared to the Windows version. I'll locate a Windows machine and try these tests again.

One question: the examples you've sent seem to declare all variables as globals--is that intentional, or just saving typing? I would expect rgData, rgValue, and rgFlag to be the only shared vars (and those are declared outside the Decoder), but since there's no explanation of the actual interface being used by these decoder snippets, I don't know if the other variables are also global (and therefore names are critical.) Can you let me know?

Thanks

Share this post


Link to post
Share on other sites
  • 0

Please try again, it should work on Windows, OS X and Linux too.

The "var"s were avoided to simplify the example. Beside the Math.* and other standard JS stuff the Custom interpreter uses the: rgData, rgValue, rgFlag, hzRate (sample rate)

Here you have an example that shows MOSI and MISO under one channel, select is active low, MSBits first, shows "updateFoo" for 0xFF second MOSI byte...

i5.png

Decoder:

// rgData: input, raw digital sample array
// rgValue: output, decoded data array
// rgFlag: output, decoded flag array

var c = rgData.length // c = number of raw samples
var pClock = false; // previous cock signal level
var iStart = 0;     // used to keep track on byte start index
var cByte = 0;      // byte count per transmission
var cBits = 0;      // bit counter
var bMosi = 0;     // value variable
var bMiso = 0;     // value variable

for(var i = 0; i < c; i++){ // for each sample
    var s = rgData[i]; // current sample
    var fSelect = s & (1<<2); // pin2 is the select signal
    var fClock = s & (1<<0); // pin0 is the clock signal
    var fMosi = s & (1<<1); // pin1 is the MOSI data signal
    var fMiso = s & (1<<3); // pin3 is the MISO data signal
    
    if(fSelect != 0){ // select active low
        // while select inactive reset our counters/variables
        iStart = i+1; // select might become active with next sample
        cByte = 0;
        cBits = 0;
        bMosi = 0;
        bMiso = 0;
        pClock = false;
        continue;
    }
    if(pClock == false && fClock == true){
        // sample on clock rising edge
        bMosi <<= 1; // serial data bit, MSBit first
        if(fMosi) {
            bMosi |= 1; 
        }
        bMiso <<= 1; // serial data bit, MSBit first
        if(fMiso) {
            bMiso |= 1; 
        }
        cBits++;
        if(cBits==8){ // when got the 8th bit store it
            cByte++;
            // store rgValue/Flag from byte start index to current sample position
            for(var j = iStart; j < i; j++){
                // Flag change will be visible on plot even when data remains constant.
                // This is useful in case we get more consecutive equal values.
                rgFlag[j] = cByte;
                rgValue[j] = (bMosi<<16) | bMiso;
            }
            iStart = i+1; // next byte might start after this sample
            cBits = 0;  // reset bit count for the next byte
            bMosi = 0; // reset value variable
            bMiso = 0; // reset value variable
        }
    }
    pClock = fClock; // previous clock level
}

Value 2 text:

// value: value sample
// flag: flag sample

function Value2Text(flag, value){
  // in this example we store two number in value
  var bMosi = value >> 16;
  var bMiso = value & 0xFF;
  // in this example the flag indicates the byte index of the transmission
  if(flag==0){ 
    return "X";
  }else{
    var szMosi = "MOSI: h"+bMosi.toString(16);
    var szMiso = "MISO: h"+bMiso.toString(16);
    if(flag == 2 && bMosi == 0xFF){
      szMosi = "MOSI: updateFoo";
    }
    return szMosi+"\n"+szMiso;
  }
}

 

Share this post


Link to post
Share on other sites
  • 0

Atilla--

thanks for that example...much appreciated. A couple of questions remain.

1) Despite the nicer code, the decoder still would not run initially. Perhaps you can explain what I found: I had been using input 0 for MOSI, input 1 for Clock, input 2 for Select, input 4 for MISO. (Of course, that meant I had to change the code accordingly:    
var fSelect = s & (1<<2); // pin2 is the select signal
var fClock = s & (1<<1); // pin1 is the clock signal
var fMosi = s & (1<<1); // pin0 is the MOSI data signal
var fMiso = s & (1<<4); // pin4 is the MISO data signal
).

But this never worked--I would get hints that the decoder would work any time fClock was set to 0, but as soon as I did that, the decoder showed flat line. (and of course, if fClock was 0 then the data would decode incorrectly). 

So I finally simply re-wired my setup to use your definitions (0 for Clock, 1 for MOSI, 2 for Select, 4 for MISO) and it worked somewhat. Is there something in your code (other than the 4 signal definition lines, of course) that _require_ that Clock be on line 0? Or that line 0 can _not_ be used for data?

2) Now that it's working somewhat, I am only getting decode at the start of the transmission (see screen shot). Do you know why?
( I should point out that my application is using LSB data, so I made these changes as well:
   if(pClock == false && fClock == true){       
//        bMosi <<= 1; // serial data bit, MSBit first
        if(fMosi) {
            bMosi |= 1 << cBits;   // LSB instead
        }
//        bMiso <<= 1; // serial data bit, MSBit first
        if(fMiso) {
            bMiso |= 1 << cBits;   // LSB instead
        }
)

 

Finally: can the Script Debugger be used with Custom Decoder? I haven't been able to see that work, but it seems like it would be a huge help if it can be done.

Thanks

Screen Shot 2016-07-21 at 11.58.22 AM.png

Share this post


Link to post
Share on other sites
  • 0

1. The problem was that you have declared for both MOSI and Clock the pin 1. The fMosi (pin0) was changed only in the comment not in the bit shift operation. Correctly would have been:
var fSelect = s & (1<<2); // pin2 is the select signal
var fClock = s & (1<<1); // pin1 is the clock signal
var fMosi = s & (1<<0); // pin0 is the MOSI data signal
var fMiso = s & (1<<4); // pin4 is the MISO data signal

2. The further texts do not fit in the available space. Make the window wider or zoom in (reduce time base).
Or use shorter text like:
 

    var szMosi = "O h"+bMosi.toString(16);
    var szMiso = "I h"+bMiso.toString(16);
    if(flag == 2 && bMosi == 0xFF){
      szMosi = "O updateFoo";
    }
    return szMosi+"\n"+szMiso;
Edited by attila

Share this post


Link to post
Share on other sites
  • 0

Atilla--

1a) no, sorry: what you saw was a typo in blog entry, not in my code. Here's the code, copy/pasted:

    var fSelect = s & (1<<2); // pin2 is the select signal
    var fClock = s & (1<<1); // pin1 is the clock signal
    var fMosi = s & (1<<0); // pin0 is the MOSI data signal
    var fMiso = s & (1<<4); // pin4 is the MISO data signal

Not to mention the fact that I have tried this back and forth many times, re-creating the signal definitions each time. 

1b) With the above definitions in place, the custom decoder does not output anything but a single line, even though built-in decoders show all data correctly. But if I change fClock to line 0, the decoder shows data  _regardless_ of how MOSI/MISO lines are defined (Select line must be correct of course). Of course, that data is not correct unless I rewire so that line 0 _is_ the clock...but at least the decoder shows data.

In other words, the custom decoder is only showing ANYthing for me if a) the Select line is defined as 2 (which is where it actually is) and b) the Clock line is defined as 0 (whether the circuit clock is actually attached to 0 or to another analyzer line).

2) Thanks--you're correct about the spacing (of course).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now