Calculating sample delay between transmit and receive (some help required)

Hi everyone,

I am back doing some LimeMini programming and I need a bit of help.
My application transmits a signal and then monitors what is being sent to the
transmitter and compares it to what is actually being received at the antenna.

To do this I have to keep a delayed copy of the transmitted signal so I can
compare the monitored signal to the ‘perfect transmitted signal’

I am assuming that if I use a single channel to do this then the sample rate
and frequency will be exactly the same as they use a common reference.

Easy part
What I want to know is what is the best approach to make sure that
when I send a block of samples I can read an identical sized block of
received samples with no loss of alignment (i.e dropped samples).

Hard Part
I need to know the exact delay between a transmitted sample and
the receive sample so I can delay my ‘golden reference’ by that amount.
What is the best way to do this using LimeSuite?

I do realise there will still be a small extra delay due to the length of cables
and delays through the external Power Amplifier but I can use a correlator
to fine tune that.

At the moment I have no idea how best to work out the loopback delay (via RF)
of the system. I have searched the message board but I have not found an
exact answer to my current problem.

  • Charles

What I have done to achieve the hard part is to read the HW timer, add some time
to it then send a block of samples specifying it to delay tx until the know time, then
every time I send a block of samples I increment a uint64_t time variable in
my code, using that and the HW timer values returned in the received metadata
I hopefully have a reasonable idea of the lag between tx and receive.

Anyone got any better ideas?

  • Charles

Well that didn’t work as it appears the hardware timer on the Rx and TX side of a channel have different values.

OK if I stop and then start the tx and rx stream on a channel it resets the hardware timer on the receive and transmit channel. Whether that helps with my delay issue I don’t know. I can query the Tx and Rx fifo size but I am not
sure how much help that is going to be either.

Can you explain what you mean by they have different values?

Because what I figured out from the FPGA code is that both the RX and TX paths use the RX PLL for their timestamp values.

Well I called LMS_GetStreamStatus for the receive stream and the transmit stream
on the same port one immediately after the other and they returned hugely different
timestamp values, the TX side 0 and the receive side 5062260. It could of course be
that the TX side value is always zero (just thought of that).

If I do an LMS_StopStream followed by an LMS_StartStream on the rx and tx stream
then do a GetStreamStatus on the two streams I then get them returning the same
value. It is as if they are simply counting the number of samples. I am using a Lime Mini
the classic Lime maybe totally different.

  • C

Just checked the TX count does change but the values appear totally wrong.
The receive side increments by the mount I would expect but the tx side seems to return silly values.

Hey,

Thanks for the explanation. Can you provide me your stream config, sampling rate and whether if you are writing any metadata timestamp using your application. I can maybe reproduce the issue with those info.

Best regards,
Saptarshi

I am only using channel 0 and the stream config is basically what was in the example.
The sample rate is 2664000 (333KS/s * 8) The sample block sizes are 4096
I am not using the metadata to time the transmit times. I have checked and I am not dropping any samples
either on transmit or receive.

What I am actually doing is trying to write a program to do digital pre-distortion of a Power Amplifier.
I have all the maths written to solve Ax=b and hence calculate the set of coefficients required
to do the pre-distortion but I need to have before and after samples from the PA that are perfectly
aligned so I can do the Ax=b (or in my case (U^HU)a=bU^H U is built from the received samples and b from the
delayed copy of the transmitted samples. For further information have a look at

https://www.keysight.com/upload/cmc_upload/All/DigitalPreDistortion_MicroApps.pdf

    m_rx_streams[i].channel = i; //channel number
   	m_rx_streams[i].fifoSize = 1024 * 128; //fifo size in samples
   	m_rx_streams[i].throughputVsLatency = 1.0; //optimize for maximum throughput
   	m_rx_streams[i].isTx = false; //RX channel
   	m_rx_streams[i].dataFmt = lms_stream_t::LMS_FMT_I16; //16-bit integers
   	if (LMS_SetupStream(m_lms_device, &m_rx_streams[i]) != 0) error();

   	m_tx_streams[i].channel = i; //channel number
   	m_tx_streams[i].fifoSize = 1024 * 128; //fifo size in samples
   	m_tx_streams[i].throughputVsLatency = 1.0; //optimize for  throughput
   	m_tx_streams[i].isTx = true; //TX channel
   	m_tx_streams[i].dataFmt = lms_stream_t::LMS_FMT_I16; //16-bit integers
   	if (LMS_SetupStream(m_lms_device, &m_tx_streams[i]) != 0) error();

    m_rx_metadata[i].flushPartialPacket = false; //Do not discard data remainder when read size differs from packet size
    m_rx_metadata[i].waitForTimestamp = false; //Do not wait for specific timestamps
	m_tx_metadata[i].flushPartialPacket = false; //Do not discard data remainder when read size differs from packet size
	m_tx_metadata[i].waitForTimestamp = false; //Do not wait for specific timestamps