So I am trying to do the same thing here with a LimeSDR Mini. I have just started my final year project at university where I am trying to design and build a system capable of tracking the 3D flight path of ‘an object’ by listenening to the objects telemetry packets from multiple locations and then computing the cross correlation of the IQ streams from the independant recievers to work out the TDOA, and hence the location of the object. The system therefore requires multiple independant SDRs to be syncronised easily - ideally to within 1 or 2 samples at 30MS/s.
In order to do this the obvious choice is to use the 1Hz PPS output from a GPS module as an external trigger to syncronicse the SDRs as described above.
The gateware for the Lime mini has a slightly different top level setup but is very similar to that of the Lime USB so I have been able to succesfully modify the gateware to implement the external trigger functionality. The PPS is fed into a GPIO pin and as above the sample index of the 0 to 1 transition is embedded in the USB packet header, with the MSB set as a flag for the PC.
With this flashed to the FPGA I also modified the file ‘streaming.cpp’ in LimeSuite/SoapyLMS7 and rebuilt so that the raw timestamp from the USB packet is returned to the user application.
//timeNs = SoapySDR::ticksToTimeNs(metadata.timestamp, sampleRate);
timeNs = metadata.timestamp;
Next a python script was written to look for packets with a modified timestamp and then report the number of samples between the current and previous sync events.
import SoapySDR
from SoapySDR import * #SOAPY_SDR_ constants
import numpy #use numpy for buffers
#enumerate devices
results = SoapySDR.Device.enumerate()
for result in results: print(result)
#create device instance
#args can be user defined or from the enumeration result
args = dict(driver="lime")
sdr = SoapySDR.Device(args)
#apply settings
sdr.setSampleRate(SOAPY_SDR_RX, 0, 30e6)
sdr.setFrequency(SOAPY_SDR_RX, 0, 868e6)
#setup a stream (complex floats)
rxStream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32)
sdr.activateStream(rxStream) #start streaming
#create a re-usable buffer for rx samples
buff = numpy.array([0]*1020, numpy.complex64)
pps = 0
prev = 0
for i in range(1000000):
sr = sdr.readStream(rxStream, [buff], len(buff))
ts = int(sr.timeNs)
if(ts < 0):
prev = pps
pps = ts + 9223372036854775808
if(pps!=prev):
print(pps-prev)
#shutdown the stream
sdr.deactivateStream(rxStream) #stop streaming
sdr.closeStream(rxStream)
At 30MS/s with a 40us wide PPS pulse the output from this script was as follows:
matt@ubuntu:~/Documents/iib-project/lime-sdr$ python3 delta-test.py
{addr=24607:1027, driver=lime, label=LimeSDR Mini [USB 3.0] 1D3AC940C7E517, media=USB 3.0, module=FT601,
name=LimeSDR Mini, serial=1D3AC940C7E517}
[INFO] Make connection: 'LimeSDR Mini [USB 3.0] 1D3AC940C7E517'
[INFO] Reference clock 40.00 MHz
[INFO] Device name: LimeSDR-Mini
[INFO] Reference: 40 MHz
[INFO] LMS7002M calibration values caching Disable
[INFO] Rx calibration finished
25030102
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000016
30000020
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000018
30000020
30000018
30000018
30000018
30000018
30000018
30000018
Now this seems to suggest that everything is working as intended, however there is somthing that is confusing me.
Why does this only work when I read the samples 1020 at a time? If I set the buffer size to 1360 then it all goes quite wrong. I see from the stream protocol that 16 bit samples are sent 1020 to a packet - does the SDR automatically choose the largest bit depth that it can happily spew out within the USB bandwidth?
From looking at the VHDL and the FT601 datasheet it is not obvious what is going on so if somebody could shed a little bit of light on the specifics regarding the USB packets on the lime mini that would be really helpful.
In addition I am happy to share the modified gateware should anyone want it. Big thanks to @cmichal for your work on the gateware for the Lime USB.
Matt