RX Gain not set properly

Having issues with the site, hardware, source code, or any other issues?
Post Reply
lopz77
Posts: 3
Joined: Wed Jun 05, 2024 12:34 pm

RX Gain not set properly

Post by lopz77 »

I'm having difficulties with the bladeRF lib, regarding configuring the gain of the rx channels.
Based on the code below, is there a specific order to perform the configuration? I noticed that the gain is only applied correctly when the channels are active.
Is there a correct order for config calls?

Code: Select all

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libbladeRF.h>

#define FREQUENCY 2700000000 // 2_700_000_000
#define SAMPLERATE 2000000   // 1_000_000
#define BANDWIDTH 1000000    // 1_000_000
#define GAIN 30

int main()
{
    struct bladerf_metadata meta;
    struct bladerf *dev;
    int16_t *samples;

    unsigned int block_size = 2048;

    bladerf_sample_rate samplerate_actual;
    bladerf_frequency frequency_actual;
    bladerf_gain gain_actual;
    bladerf_bandwidth bandwidth_actual;

    int n_channels = 2; // 1 or 2 for BladeRF micro

    bladerf_channel_layout channel_layout = n_channels == 2 ? BLADERF_RX_X2 : BLADERF_RX_X1;
    unsigned int read_size = block_size / n_channels; // have to halve if using 2 channels?

    // allocate memory
    memset(&meta, 0, sizeof(meta));
    meta.flags = BLADERF_META_FLAG_RX_NOW;

    // samples = (int16_t *)calloc(block_size, 2 * sizeof(samples[0]));
    samples = malloc(block_size * 2 * sizeof(int16_t));

    if (samples == NULL)
        return -1;

    memset(samples, 0xFF, block_size * 2 * sizeof(int16_t));

    // open BladeRF
    if (bladerf_open(&dev, "*:serial=a8cf") != 0)
        return -1;

    if (bladerf_is_fpga_configured(dev) <= 0)
        return -1;

    // setup BladeRF, these specify a "bladerf_channel"
    for (int ch = 0; ch < n_channels; ch++)
    {
        if (bladerf_set_frequency(dev, BLADERF_CHANNEL_RX(ch), FREQUENCY) != 0)
            return -1;

        if (bladerf_get_frequency(dev, BLADERF_CHANNEL_RX(ch), &frequency_actual) != 0)
            return -1;

        if (bladerf_set_sample_rate(dev, BLADERF_CHANNEL_RX(ch), SAMPLERATE, &samplerate_actual) != 0)
            return -1;

        if (bladerf_get_sample_rate(dev, BLADERF_CHANNEL_RX(ch), &samplerate_actual) != 0)
            return -1;

        if (bladerf_set_gain_mode(dev, BLADERF_CHANNEL_RX(ch), BLADERF_GAIN_MGC) != 0)
            return -1;

        if (bladerf_set_gain(dev, BLADERF_CHANNEL_RX(ch), GAIN) != 0)
            return -1;

        if (bladerf_get_gain(dev, BLADERF_CHANNEL_RX(ch), &gain_actual) != 0)
            return -1;

        printf("Channel %d: Fs=%d, Freq=%ld, gain=%d\n", ch, samplerate_actual, frequency_actual, gain_actual);
    }

    // configure rx, this uses a "bladerf_channel_layout", BLADERF_RX_X2 configures for x2 RX
    if (bladerf_sync_config(dev, channel_layout, BLADERF_FORMAT_SC16_Q11_META, 32, 8192, 16, 3500) != 0)
        return -1;

    // enable, this uses a "bladerf_channel"
    for (int ch = 0; ch < n_channels; ch++)
    {
        if (bladerf_enable_module(dev, BLADERF_CHANNEL_RX(ch), true) != 0)
            return -1;
    }

    // do rx 5 times, check last sample
    printf("Starting rx, read_size = %d\n", read_size);

    for (int i = 0; i < 5; i++)
    {
        if (bladerf_sync_rx(dev, samples, block_size, &meta, 5000) != 0)
            return -1;

        if (meta.status & BLADERF_META_STATUS_OVERRUN)
            fprintf(stderr, "Overrun detected. %u valid samples were read.\n", meta.actual_count);

        printf("rx time %ld, last sample=%d\n", meta.timestamp, samples[block_size * 2 - 1]);
    }

    // clean up
    for (int ch = 0; ch < n_channels; ch++)
    {
        if (bladerf_enable_module(dev, BLADERF_CHANNEL_RX(ch), false) != 0)
            return -1;
    }

    free(samples);
    bladerf_close(dev);

    printf("Bye!\n");
    return 0;
}
dooley46
Posts: 1
Joined: Thu Jun 27, 2024 1:37 am

Re: RX Gain not set properly

Post by dooley46 »

lopz77 wrote: Mon Jun 17, 2024 9:56 am I'm having difficulties with the bladeRF lib, regarding configuring the gain of the rx channels.
Based on the code below, is there a specific order to perform the configuration? I noticed that the gain is only applied correctly when the channels are active.
Is there a correct order for config calls?
slope

Code: Select all

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libbladeRF.h>

#define FREQUENCY 2700000000 // 2_700_000_000
#define SAMPLERATE 2000000   // 1_000_000
#define BANDWIDTH 1000000    // 1_000_000
#define GAIN 30

int main()
{
    struct bladerf_metadata meta;
    struct bladerf *dev;
    int16_t *samples;

    unsigned int block_size = 2048;

    bladerf_sample_rate samplerate_actual;
    bladerf_frequency frequency_actual;
    bladerf_gain gain_actual;
    bladerf_bandwidth bandwidth_actual;

    int n_channels = 2; // 1 or 2 for BladeRF micro

    bladerf_channel_layout channel_layout = n_channels == 2 ? BLADERF_RX_X2 : BLADERF_RX_X1;
    unsigned int read_size = block_size / n_channels; // have to halve if using 2 channels?

    // allocate memory
    memset(&meta, 0, sizeof(meta));
    meta.flags = BLADERF_META_FLAG_RX_NOW;

    // samples = (int16_t *)calloc(block_size, 2 * sizeof(samples[0]));
    samples = malloc(block_size * 2 * sizeof(int16_t));

    if (samples == NULL)
        return -1;

    memset(samples, 0xFF, block_size * 2 * sizeof(int16_t));

    // open BladeRF
    if (bladerf_open(&dev, "*:serial=a8cf") != 0)
        return -1;

    if (bladerf_is_fpga_configured(dev) <= 0)
        return -1;

    // setup BladeRF, these specify a "bladerf_channel"
    for (int ch = 0; ch < n_channels; ch++)
    {
        if (bladerf_set_frequency(dev, BLADERF_CHANNEL_RX(ch), FREQUENCY) != 0)
            return -1;

        if (bladerf_get_frequency(dev, BLADERF_CHANNEL_RX(ch), &frequency_actual) != 0)
            return -1;

        if (bladerf_set_sample_rate(dev, BLADERF_CHANNEL_RX(ch), SAMPLERATE, &samplerate_actual) != 0)
            return -1;

        if (bladerf_get_sample_rate(dev, BLADERF_CHANNEL_RX(ch), &samplerate_actual) != 0)
            return -1;

        if (bladerf_set_gain_mode(dev, BLADERF_CHANNEL_RX(ch), BLADERF_GAIN_MGC) != 0)
            return -1;

        if (bladerf_set_gain(dev, BLADERF_CHANNEL_RX(ch), GAIN) != 0)
            return -1;

        if (bladerf_get_gain(dev, BLADERF_CHANNEL_RX(ch), &gain_actual) != 0)
            return -1;

        printf("Channel %d: Fs=%d, Freq=%ld, gain=%d\n", ch, samplerate_actual, frequency_actual, gain_actual);
    }

    // configure rx, this uses a "bladerf_channel_layout", BLADERF_RX_X2 configures for x2 RX
    if (bladerf_sync_config(dev, channel_layout, BLADERF_FORMAT_SC16_Q11_META, 32, 8192, 16, 3500) != 0)
        return -1;

    // enable, this uses a "bladerf_channel"
    for (int ch = 0; ch < n_channels; ch++)
    {
        if (bladerf_enable_module(dev, BLADERF_CHANNEL_RX(ch), true) != 0)
            return -1;
    }

    // do rx 5 times, check last sample
    printf("Starting rx, read_size = %d\n", read_size);

    for (int i = 0; i < 5; i++)
    {
        if (bladerf_sync_rx(dev, samples, block_size, &meta, 5000) != 0)
            return -1;

        if (meta.status & BLADERF_META_STATUS_OVERRUN)
            fprintf(stderr, "Overrun detected. %u valid samples were read.\n", meta.actual_count);

        printf("rx time %ld, last sample=%d\n", meta.timestamp, samples[block_size * 2 - 1]);
    }

    // clean up
    for (int ch = 0; ch < n_channels; ch++)
    {
        if (bladerf_enable_module(dev, BLADERF_CHANNEL_RX(ch), false) != 0)
            return -1;
    }

    free(samples);
    bladerf_close(dev);

    printf("Bye!\n");
    return 0;
}
It's generally recommended to configure the gain settings before enabling the RX channels. This ensures the gain is applied immediately when the channel becomes active.

The specific order might be crucial for some older bladeRF models with multiple gain stages (e.g., xA4/xA9). These models might require setting the LNA gain before the VGA gains. Consult the bladeRF documentation for your specific model if you suspect this applies.

Once you've configured the gains, you can enable the RX channels using

Code: Select all

bladerf_rx_enable(bladeRF_dev, channel)
.
Post Reply