# Best Algorithm to Manually Calibrate TX DC?

Greetings.

Since the LMS_Calibrate function does a pretty bad job at surpressing the TX carrier from the transmitted TX signal, I was attempting to perform my own calibration routine.
I’m aware on how to change the TX DC Analog registers and the TX DC Digital registers for the channels, I just wanted to ask someone for the best strategy in tackling this variable search problem.

So far I have set TXLO = 44 MHz and RXLO = 45 MHz, with DAC/ADC sample rate = 4e6 MHz. The idea is to have RXLO = TXLO + Fsamp/4. This, by controlling the transmitting timestamps, I can send a TX signal directly to RX and then perform the FFT of the received signal on a single point corresponding to the TX carrier.

Apart from a few samples of latency, I’m pretty sure that the RX samples that I am analyzing corresponds to the TX signal being sent.

The problem is about the best searching algorithm. I have started by assuming all the 4 parameters independent (i.e., analog I correction, analog Q correction, digital I correction and digital Q correction), and then the problem consists in minimizing the FFT value of the point corresponding to the TX carrier.

Since each parameter is written in 2’s complementary, i.e., the MSB is the sign, my algorithm is currently doing the following:

For each individual parameter:

Set MSB = 1;

Set All other bits = 1;

Perform FFT at desired point and save value;

Change first bit after the MSB to 0;
Perform FFT at desired point; Is the new value better than the previous ref value? If yes, leave bit at 0 and set new ref value. If no, set bit to 1 again;

Change second bit after MSB to 0;
Perform FFT at desired point; Is the new value better than the previous ref value? If yes, leave bit at 0 and set new ref value. If no, set bit to 1 again;

(…)

When this loop is over, I set MSB=0 and then repeat the same ideas. I will then compare the results between both loops and choose the one that gives me the better TX Carrier aniquilation.

Then I repeat the algorithm for the other parameters as well.

The problem is that this algorithm doesn’t converge very well. I,e., for different essays with the same parameters, I sometimes have very different values, since the algorithm assumes that the function I’m minimizing changes monotonously with each parameter I’m searching, which may not be true. But can someone confirms this? Also, by changing the TX signal from something random to only 0’s per instance, changes the calibration results a lot, which should not be possible.

So, that being said, as anyone attempted to manually calibrate the TX DC without simple trial and error? If so, how? What algorithms have you used? Or can you recommend me any searching algorithm in c++ for the desired problem?

Thanks

First of all, there is no reason to use digital dc correctors, as the analog correctors provide much finer controls.

What you are trying to do is essentialy the same binary search, that the already existing algorithm is using https://github.com/myriadrf/LimeSuite/blob/master/mcu_program/common_src/lms7002m_calibrations.c#L344. The only difference is that you are using FFT as the measurement, while the original calibration uses digital RSSI as the measurement.

Make sure that the signal you are measuring is exactly in your selected FFT bin, or measure multiple nearby bins. Because if the signal is on bin edge it’s power might be spreaded over several bins depending on your settings and give unstable result.

Thanks for the quick response. I’m glad I was thinking about the same procedure as the one actually implemented by the already existing algorithm. However that algorithm fails at frequencies close to 30 MHz, don’t exactly know why.

Is there a way to use the RSSI through the LMS API? Otherwise I will just look in a region around the FFT bin or increase the bin size.

Thanks for the tip on avoiding TX digital DC corrections.

Probably because to go to frequencies lower than 30 MHz, the sampling frequencies and NCO shift changes have to be used, which are not accounted in the calibration.

There is no function exposed, but you can read it from registers: LimeSuite/mcu_program/common_src/lms7002m_calibrations.c at 01e2d00c5005b85d1f94cca02881756a72e35e2a · myriadrf/LimeSuite · GitHub

1 Like