LimeSuite: Specify 3 gains

Hello,

According to AI chat, there is an old version in which I can specify 3 different gains:

SetRFELNA_dB ()

SetRFETIA_dB ()

SetRBBPGA_dB ()

The prototypes are in LMS7002M.h

How can I get this old version ?

Thank you,

Zvi

Hi,

We recommend to avoid using the old LimeSuite API or mixing it with LimeSuiteNG API.

Instead use the new API gain setter as shown in here - Common control and configuration options — Lime Suite NG latest documentation

Also here is a full reference to LimeSuiteNG library and API - Lime Suite NG library reference — Lime Suite NG latest documentation

Hello,

I wrote my application with the newest API:

 
lime::SDRDevice* device;

static void LogCallback(LogLevel lvl, const std::string& msg)
{
    if (lvl > logVerbosity)
        return;
    std::cout << msg << std::endl;
}

int main (void)
{
lime::registerLogHandler(LogCallback);

 std::vector<lime::DeviceHandle> listOfDevices = lime::DeviceRegistry::enumerate();

 std::cout << "Found " << listOfDevices.size() << " devices\n";
 for (const auto& item : listOfDevices)
     std::cout << item.Serialize() << std::endl;

 lime::SDRDevice* device = lime::DeviceRegistry::makeDevice(listOfDevices.at(0));
 if (device == nullptr)
 {
     std::cout << "Failed to connect to SDR device\n";
     return SDR_OPEN_FAILED;
 }

 rc=device->Init();
 if (rc != OpStatus::Success)
 {
     printf("Init failed.\n");
     return SDR_OPEN_FAILED;
 }

// RF parameters
SDRConfig config;
config.channel[0].rx.enabled = true;
config.channel[0].rx.centerFrequency = CenterFreq; //800e6
config.channel[0].rx.sampleRate = SampFreq; //8e6
config.channel[0].rx.oversample = 2;
config.channel[0].rx.lpf = BandWidth; //8e6
config.channel[0].rx.path = Antenna; //3
config.channel[0].rx.calibrate = CalibrationFlag::FILTER;  
config.channel[0].rx.testSignal.enabled = false;

config.channel[0].tx.enabled = false;
config.channel[0].tx.sampleRate = 0;
config.channel[0].tx.oversample = 0;
config.channel[0].tx.path = 0;
config.channel[0].tx.centerFrequency = 0;
config.channel[0].tx.testSignal.enabled = false;

std::cout << "Configuring device ...\n"sv;

rc=device->Configure(config, 0);
if (rc != OpStatus::Success)
{
    printf("Configure failed.\n");
    return SDR_START_FAILED;
}

printf("Starting stream...\n");

// Samples data streaming configuration
StreamConfig streamCfg;
streamCfg.channels[TRXDir::Rx] = { 0 };
streamCfg.format = DataFormat::I16;
streamCfg.linkFormat = DataFormat::I16;

std::unique_ptr<lime::RFStream> stream = device->StreamCreate(streamCfg, 0);
rc=stream->Start();
if (rc != OpStatus::Success)
{
    printf("StreamCreate failed.\n");
    return SDR_START_FAILED;
}

printf("Stream started\n");

According to the flow, after “Configuring device…” I should get “Starting stream…”

But I’m not getting this. Instead the application breaks with no error. Just quitting.

Can you please advise what is wrong in my code ?

Thank you,

Zvi

From the code you provided, it seems like you start the stream, but never read any samples (stream->Receive(…)). Please provide more code.

Generic streaming example - Streaming with SDR device — Lime Suite NG latest documentation

Hi,

Thank you for your response.
I did not try to read samples yet.
Can this cause a problem?

Best regards,
Zvi

Sorry, I misread your original post.

First off, could you update your logcallback function to ignore log verbosity to print all messages.

Secondly, could you try to configure your device without the calibration flag enabled (remove the line entirely) and see if that changes anything?

Hi Arnius,

The code now is:

using namespace lime;
using namespace std::literals::string_view_literals;
std::unique_ptr<lime::RFStream> stream;
SDRConfig config;
StreamConfig streamCfg;
/******************************************************************************/
static void LogCallback(LogLevel lvl, const std::string& msg)
{
    printf("LogCallback[%d]: %s\n", lvl,msg.c_str());
}

int main (void)
{
   lime::registerLogHandler(LogCallback);

   std::vector<lime::DeviceHandle> listOfDevices =       lime::DeviceRegistry::enumerate();

   std::cout << "Found " << listOfDevices.size() << " devices\n";
for (const auto& item : listOfDevices)
    std::cout << item.Serialize() << std::endl;

   lime::SDRDevice* device =  lime::DeviceRegistry::makeDevice(listOfDevices.at(0));
if (device == nullptr)
{
    std::cout << "Failed to connect to SDR device\n";
    return SDR_OPEN_FAILED;
}

   rc=device->Init();
   if (rc != OpStatus::Success)
   {
      printf("Init failed.\n");
      return SDR_OPEN_FAILED;
   }
   config.channel[0].rx.enabled = true;
   config.channel[0].rx.centerFrequency = CenterFreq;
   config.channel[0].rx.sampleRate = SampFreq;
   config.channel[0].rx.oversample = 2;
   config.channel[0].rx.lpf = BandWidth;
   config.channel[0].rx.path = Antenna;
   //config.channel[0].rx.calibrate = CalibrationFlag::FILTER;
   config.channel[0].rx.testSignal.enabled = false;

   config.channel[0].tx.enabled = false;
   config.channel[0].tx.sampleRate = 0;
   config.channel[0].tx.oversample = 0;
   config.channel[0].tx.path = 0;
   config.channel[0].tx.centerFrequency = 0;
   config.channel[0].tx.testSignal.enabled = false;

   std::cout << "Configuring device ...\n"sv;

   rc=device->Configure(config, 0);
  if (rc != OpStatus::Success)
  {
    printf("Configure failed.\n");
    return SDR_START_FAILED;
  }

I blocked the calibration line.

Following are the messages I’m getting from the callback:

LogCallback[5]: DeviceRegistry Added: FX3
LogCallback[5]: DeviceRegistry Added: FTDI
Found 1 devices
LimeSDR Mini, addr=0403:601f, serial=1DBB43DFE73B2D
LogCallback[5]: FPGA::DetectRefClk fx3Clk:1e+08
LogCallback[5]: Estimated reference clock 40.0013 MHz
LogCallback[3]: Reference clock 40.00 MHz
LogCallback[5]: FPGA: StopStreaming
LogCallback[5]: lms7002m_set_tx_lpf: bandwidth(20000000): LAD=140, H=0

LogCallback[5]: INT 57, FRAC 385875, DIV_OUTCH_CGEN 18
LogCallback[5]: CGEN_VCO 14720000 Hz, RefClk 0 Hz
LogCallback[5]: Calibrating CG_IAMP_TBB:
LogCallback[5]: CG_IAMP_TBB(1) RSSI:0x00001ED4  approx. -18.60 dBFS
LogCallback[5]: CG_IAMP_TBB(2) RSSI:0x000025E1  approx. -16.81 dBFS
LogCallback[5]: CG_IAMP_TBB(3) RSSI:0x000034B2  approx. -13.94 dBFS
LogCallback[5]: CG_IAMP_TBB(4) RSSI:0x00003D71  approx. -12.61 dBFS
LogCallback[5]: CG_IAMP_TBB(5) RSSI:0x00004EE4  approx. -10.44 dBFS
LogCallback[5]: CG_IAMP_TBB(6) RSSI:0x00005B52  approx. -9.17 dBFS
LogCallback[5]: CG_IAMP_TBB(7) RSSI:0x00006CB3  approx. -7.66 dBFS
LogCallback[5]: CG_IAMP_TBB(8) RSSI:0x00007930  approx. -6.71 dBFS
LogCallback[5]: CG_IAMP_TBB(9) RSSI:0x00008A50  approx. -5.56 dBFS
LogCallback[5]: CG_IAMP_TBB(10) RSSI:0x000096CB  approx. -4.81 dBFS
LogCallback[5]: CG_IAMP_TBB(11) RSSI:0x0000A7E9  approx. -3.88 dBFS
LogCallback[5]: CG_IAMP_TBB(12) RSSI:0x0000B585  approx. -3.20 dBFS
LogCallback[5]: lms7002m_set_rx_lpf: bandwidth(20000000): TIA_C=242, TIA_RCOMP=11, TIA_CCOMP=2, RX_L_C=59, RX_H_C=255

Configuring device ...

After ~3seconds from printing “Configuring device” the application breaks.

If I block the line:

rc=device->Configure(config, 0);

The application does not quit.

Can you please advise ?

Thank you very much,

Zvi

Hello,

It seems the cause to the crash is in my code.

Please inspect the following code from basicRX:

complex32f_t** rxSamples = new complex32f_t*[2]; // allocate two channels for simplicity
for (int i = 0; i < 2; ++i)
    rxSamples[i] = new complex32f_t[fftSize];

rxSamples[0], rxSampls[1] are 2 vectors.

uint32_t samplesRead = stream->StreamRx(rxSamples, fftSize, &rxMeta);

In StreamRX, into what vector the data is written ?

Why there are 2 vectors ? I need only one.

Thank you,

Zvi

Hi,

Two vectors can be used to receive data from two different channels at the same time. This is done to enable 2x2 MIMO mode. Same is true for the transmit direction.

To simplify the example above:

complex32f_t* rxChA_buff = new complex32f_t[fftSize];
complex32f_t* rxChB_buff = new complex32f_t[fftSize];
complex32f_t* rxBuffers[2] = {rxChA_buff, rxChB_buff};

// Some other program code

do
{
  // Here both buffers will fill up with fftSize samples 
  // (if there are enough samples received in hardware)
  auto samplesRead = stream->Receive(rxBuffers, fftSize, &rxMeta);
}
while(/*Some stop condition*/);

or (if you only need one channel [Channel A is always preferred]):

complex32f_t* rxBuffers[2] = {rxChA_buff, nullptr}; // Channel B is not used

Hi Arnius,

Thank you very much !

Best regards,
Zvi