azonenberg changed the topic of #scopehal to: libscopehal, libscopeprotocols, and glscopeclient development and testing | https://github.com/azonenberg/scopehal-apps | Logs: https://libera.irclog.whitequark.org/scopehal
<_whitenotifier-e> [scopehal] azonenberg pushed 1 commit to master [+0/-0/±1] https://github.com/azonenberg/scopehal/compare/a6b3a2c554d7...3cdbe5a27781
<_whitenotifier-e> [scopehal] azonenberg 3cdbe5a - DigilentOscilloscope: more work on trigger and attenuation. See #410
Degi has quit [Ping timeout: 256 seconds]
Degi has joined #scopehal
<azonenberg> @louis: So i hear you're starting to work on a DScope driver
<azonenberg> If you haven't already, I suggest you implement trigger interpolation
<azonenberg> Are you familiar with that?
bvernoux has joined #scopehal
massi has joined #scopehal
<azonenberg> (there are good examples in the pico and digilent bridges. Server side in both cases)
Bird|otherbox has quit [Remote host closed the connection]
Bird|otherbox has joined #scopehal
* GenTooMan sees azonenberg is burning the midnight oil literally.
massi has quit [Remote host closed the connection]
<azonenberg> Ok i heard back from digilent re the ac/dc coupling switch
<azonenberg> Apparently it's a private API that exists, but isn't in their public header file yet
<azonenberg> they plan to add it next release
<azonenberg> and gave me the spec so i can call it directly in the near term
Kliment has quit [Remote host closed the connection]
<d1b2> <louis> Yes! I have a U3P100 from work that I'm hacking around on
<d1b2> <louis> I am not familiar with trigger interpolation
<d1b2> <louis> RE: the general approach for writing a driver for it, per MP you suggested doing it in halves with a SCPI bridge like the pico scopes. This seems like it shouldn't be too bad, because the client application from DreamSource (DSView) was open-sourced
<d1b2> <louis> So I think my plan of attack is to pull out/reimplement the HAL from that and write a SCPI server/scope driver on top of libusb that runs on the machine the scope is attached to, and a scopehal driver that talks to it like the pico scope
<d1b2> <louis> Only caveat that I wanted to ping you about quick is that the DSView application (which contains the only reference material I can find for the scope's USB interface) is GPLv3, so pulling the protocol stuff directly out probably means that (at least the HAL part of) the bridge has to be GPL instead of BSD. (The half of the driver that lives in the scopehal tree is still BSD.)
<d1b2> <louis> Is that OK or is that a liability we'd like to avoid and I should be sniffing USB traffic to reverse it's interface and writing a driver licensed entirely alike to scopehal?
<azonenberg> louis: yes. longer term i want to look into refactoring some of the bridge code out into common base classes for making a scpi server etc
<azonenberg> as far as the GPL side, that is one of the key reasons for separation when working with third party SDKs and such
<azonenberg> having separate repos and a defined API between the modules provides a clean license boundary
<d1b2> <louis> Also, RE: the MSO5x driver, the scope at work went back to the shop for a touchscreen calibration, but I'll run some perf numbers when it's back.
<azonenberg> we can make the bridge whatever we want, and then keep the scopehal side BSD
<d1b2> <louis> Sounds good to me :). Saves me a lot of wiresharking.
<azonenberg> As far as trigger interpolation goes, the basic idea is
<azonenberg> if you do simple edge triggering on sampled data., the actual zero crossing happens at some point between sample X-1 and X where X is your nominal trigger position, right?
<azonenberg> i.e. you didn't cross the threshold last sample, but you did this one
<azonenberg> so the problem is, now your displayed waveform does not actually have a zero crossing at the trigger point
<azonenberg> it's a fraction of a sample left of the trigger point
<azonenberg> and that fraction changes every acquisition, assuming the scope ADC and your DUT don't have any shared clock source
<azonenberg> so you end up with one sample clock period of random jitter that's not actually there
<azonenberg> There's a couple of ways to fix this. One is to do the actual triggering with a comparator in the analog domain, then have that pulse feed into a time-to-digital converter
<azonenberg> and record the delay between the trigger event and the next ADC clock edge
<azonenberg> then offset the displayed waveform appropriately
<azonenberg> This is what the "trigger phase" field in the scopehal Waveform class is for (time for this is in femtoseconds regardless of sample interval)
<azonenberg> and Teledyne LeCroy scopes have this hardware TDC and report the trigger phase value directly in the waveform headers
<azonenberg> Most other models of scope lack dedicated hardware, but you can achieve almost the same effect by interpolating sample X-1 to X to find the actual time of the zero crossing to sub-sample precision
<azonenberg> So far the Pico and Digilent drivers do this,, and they do simple linear interpolation. at some point in the future if we want we can add sin(x)/x interpolation or something to get a slightly cleaner result
<azonenberg> in both cases, interpolation is done on the bridge side and the trigger phase is reported over the data socket in the waveform headers to the scopehal driver
<azonenberg> which simply slaps the time into the trigger phase on the waveform object
<d1b2> <louis> OK, that makes sense I think. take sample X-1 and X to form a line and walk the slope back until exactly where it crosses the trigger threshold, and offset the wave data by that amount so that the (estimated) exact crossing is always at zero?
<azonenberg> Yes. And again you're not changing the actual sample offsets in the waveform, since this is sub-sample resolution shifts
<azonenberg> (It could also be x and x+1, depending on how the scope does triggering)
<azonenberg> ultimately the actual timestamp of a sample in fs is trigphase + (offset[i]*timescale)
<azonenberg> also are you familiar with the "dense packed" flag for waveforms?
<azonenberg> (this is something that's mentioned in some comments, but there's no top level driver dev manual to explain it)
<azonenberg> (re trigger interpolation this thread https://twitter.com/azonenberg/status/1389425327655456771 has some nice visual examples with it off/on)
<d1b2> <louis> I just pulled it up in Waveform.h but not beyond that
<azonenberg> Ok
<azonenberg> So, the internal memory representation of a Waveform is sparse and allows samples of arbitrary length and spacing with gaps
<azonenberg> e.g. protocol events
<azonenberg> as well as analog waveforms sampled at irregular intervals, say a filter that outputs rise time of a signal with one sample per edge in the input waveform
<azonenberg> however, if the waveform is actually uniformly sampled (which is generally true for anything coming straight off a scope) then the sparsing results in a lot of extra unnecessary processing for filters and rendering
<azonenberg> Setting the dense packed flag is a hint to the library that all samples have duration of one timebase unit and offsets of 0...n-1
<azonenberg> i.e. the data is uniformly sampled
<d1b2> <louis> Sure, that makes sense
<azonenberg> You still have to fill out the duration and offset, but downstream logic can ignore it
<azonenberg> and filters often will reuse the same output waveform object, keeping duration and offset untouched as long as the previous and current waveforms are the same length
<azonenberg> and only work on the data
<azonenberg> The renderer for dense packed waveforms just pushes the Y axis values to the GPU and ignores the timestamps, etc
<azonenberg> So any time you know the data is uniformly sampled, set that flag for a significant performance increase
<azonenberg> The same thing applies to file storage
<azonenberg> when you save waveforms to a scopesession the timestamps are implicit for dense packed waveforms, and reconstructed in memory when you load the file later
<azonenberg> while for sparse waveforms the actual offset/duration are stored to disk
<azonenberg> (so if you're taking any notes for future developer documentation, this would be a good key concept to explain somewhere)
<d1b2> <louis> 👍
<azonenberg> on that note, long term I want to do some better handling of dense/sparse waveforms in some filters
<azonenberg> for example, the FFT filter probably acts really weird on non-dense waveforms
<azonenberg> it should either resample a sparse input to uniform rate or simply refuse to process the data
<azonenberg> the subtract filter does not handle unequal sample rates for inputs. it can be sparse/dense but both input waveforms need to have sample N simultaneous
<azonenberg> longer term, i want to add some kind of processing layer for filters to more cleanly handle arbitrary data
<azonenberg> for example, in the demo video of the tek mso and the lecroy scope i was sampling at 25 and 40 Gsps
<azonenberg> and had to manually create resample filters
<azonenberg> i would like to be able to just say subtract, and have the resampling be inserted automagically somehow
<azonenberg> This also goes for other kinds of data conversion
<azonenberg> you should be able to do say a uart decode directly on analog data and have it implicitly create a threshold filter for your
<azonenberg> for you*
<azonenberg> (that's all a ways out, just explaining kinda the overall concepts/vision)
<d1b2> <louis> sick! i'm relatively unfamiliar with scope hardware in general (CS, not [CE]E by training) so this is an interesting hands-on learning experience; only a little bit jumping into the deep end 🙂
<azonenberg> lol oh. this isnt the deep end
<azonenberg> deep end is designing scope hardware :p
<azonenberg> But welcome to the club, my degrees are in CS too
<d1b2> <louis> the filter-graph approach seems very theoretically clean and gnuradio-like, which is cool
<azonenberg> and here i am doing more EE than most of my classmates who got EE degrees lol
<azonenberg> most of them are doing software :p
<azonenberg> and yes, it is
<azonenberg> We're going to be assimilating more and more into the filter graph too
<azonenberg> for example, waveform views are going to become sinks in the filter graph
<azonenberg> rather than requiring the special handling they do now
<azonenberg> i already started the necessary refactoring but it's not finished