I’m trying to adapt some LimeSDR-USB units for general-purpose signal acquisition. Specifically, I want to only capture information when a trigger signal is present. This has some benefits with the digital bandwidth (for short and sparse periods of activity, I should ideally be able to capture full bandwidth without USB3 being a bottleneck), but should also be useful in isolating specific activity I’m trying to monitor/record. I can reconstruct source waveforms from the IQ data that’s currently delivered from the system, but the signals aren’t of much use to me without precise control over the capture timing.
I’ve tried some fiddling in the vhdl code to add a quick and dirty trigger control in the RX path, but it still has some odd behavior that I’m trying to iron out. There’s a lot I’m still trying to understand about the architecture, so I figured it would be best to ask around and see if anybody else has tried something like this, or if anybody can point out any obstacles with the current architecture that would need to be worked around to make this feasible.
I should ideally be able to capture full bandwidth without USB3 being a bottleneck
What’s the bandwidth of the signals you wish to capture?
No matter what you do, I think you’ll always be limited to around 60MS/s, whether in mono or dual channel, no matter how short and sparse your signals are. On dual channel to achieve that speed, you’ll want your samples to be encoded in complex int 12 instead of complex float 16. You won’t lose any data as the ADC works on 12 bits, you’ll just need to convert the result back to float (by dividing by 2048, as the values will be [-2048, 2048) instead of [-1, 1) ).
You could continuously receive (by blocks of 680 in dual channel or 1360 in mono channel, see Synchronize two LimeSDR - #64 by cmichal for why), then you’d set the GPIO and leave it high for “long enough” (it should be at least the time needed to fill you block of samples). If it’s not long enough, you risk not been able to actually see the negative timestamp.
You could either set the GPIO a short time at the beginning and at the end of your interesting signal, or leave it on all the time then off once your interesting signal appears.
With the 2nd approach, you’d drop all block with negative timestamp, and keep those with positive timestamp. The resources needed to just receive and drop samples with negative timestamp should be pretty low. Any decent computer with a good USB3 could do that.
Also keep in mind that the timestamps are still being updated in the FPGA, so when you receive a positive timestamp, it has the same value as if you’d never set the GPIO, meaning you don’t lose any info concerning the time.
I’ve been wanting to have the “Oscilloscope in SDR” functionality shown in the “LimeSDR all in one lab” video since I bought my unit (just a bit more polished software-wise than calculating/tuning around LimeUtil):
I wonder if someone in this forum took the time to build a “Oscilloscope jig/frontend board for LimeSDR” that protects the LimeSDR I/O as a desk/commercial oscilloscope would do?:
DC block (IIRC it’s there already).
Transients/HV/inrush current protection.
Perhaps BNC connectors for regular oscilloscope probes? etc…
Unfortunately I cannot release my code due to the nature of my work. I can provide details about the changes I made, but currently my solution needs some more time to cook. The main changes involved joining the receive path’s first-stage FIFO write request with a direct trigger signal on the FPGA GPIO. You can do the same later in the receive chain, too, depending on goals and desired sample count effects. I also significantly expanded the FX3 FIFO size (and nixed memory-intensive components elsewhere that my application doesn’t need), but I think there needs to be changes on the software interface side to properly support the expanded size. I haven’t gotten to that yet, but given a new project direction I may not be able to work on it for some time.
I just installed the Quartus Prime intel FPGA environment (do you use something else, btw?), I’m getting some compile issues from the master_clean gateware branch:
I guess that the VHDL’s you are modifying are mostly under rx_path_top? Actually FX3_slaveFIFO5b_top, after finding quite useful gateware docs under that master_clean branch: