Can't use 2 RX channels in libbladeRF with metadata?

Having issues with the site, hardware, source code, or any other issues?
Post Reply
mikedon1
Posts: 2
Joined: Wed Aug 16, 2023 7:27 am

Can't use 2 RX channels in libbladeRF with metadata?

Post by mikedon1 »

Update: I'm only having the following problem when using BLADERF_FORMAT_SC16_Q11_META, with BLADERF_FORMAT_SC16_Q11 it works fine.

I'm trying to sample 2 RX channel simultaneously with the BladeRF micro using libbladeRF. I've been having trouble finding simple example code, so I've started with the example in bladeRF/host/libraries/libbladeRF_test/test_sync that was made for the original BladeRF, and am trying to modify it. If someone could point me to an easy example, it would be very helpful. If not, below is some more detail on the questions/problems I've been having. I've also added some code and program output to the bottom of the post.

What needs to be done for each channel? What should I change when switching the test_sync example from 1 to 2 channels? Some of the things I'm doing for 1 channel are:
bladerf_set_sample_rate
bladerf_set_frequency
bladerf_set_gain_mode
bladerf_set_gain_mode
bladerf_sync_config
bladerf_enable_module
bladerf_sync_rx

It sounds like the sample rate and freq. will be the same for both, and that bladerf_sync_rx will receive interleaved samples from both channels. I'm not sure about bladerf_sync_config and bladerf_enable_module, should I do these for both, or if I do it for RX2, will it apply to RX1 as well? It looks like I should double the num_samples for bladerf_sync_rx to acquire for the same period of time as with 1 RX channel, and therefore I need to double my sample buffer size too.

I've played around with it, and when I use 1 RX channel at a sampling rate of 1 MHz, the RX timestamp increases by 2048 for each rx of 2048 samples. But for 2 RX channels, the timestamp is only increasing by 255 for every 4096 samples I'm trying to read! I've tried a few configurations, doubling some of the parameters in bladerf_sync_config, etc., without success. I've started looking at the bladeRF-cli code which does seem to support 2 RX channels, but it is a much more complicated example that I'm having trouble going through.

Thanks in advance for any advice, -Mike

Here's a code example I've added after my original post. This is a streamlined version of the test_sync example. I use a n_channels var to configure 1 or 2 channels. I've also noticed that the bladerf_get_gain always returns 60 for some reason, even though the set gain seems to be working.

Code: Select all

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libbladeRF.h>
int main()
{
    unsigned int samplerate_actual;
    uint64_t frequency_actual;
    int gain_actual;
    struct bladerf_metadata meta;
    struct bladerf *dev;
    int16_t *samples;
    int i;
    int ch;
    unsigned int block_size=2048;
    int n_channels=1; // 1 or 2 for BladeRF micro
    unsigned int read_size=block_size/n_channels; //have to halve if using 2 channels?
    bladerf_channel_layout channel_layout = n_channels == 2 ? BLADERF_RX_X2 : BLADERF_RX_X1;
        
    //allocate memory
    memset(&meta, 0, sizeof(meta));
    meta.flags = BLADERF_META_FLAG_RX_NOW;
    samples = (int16_t *)calloc(block_size, 2 * sizeof(samples[0]));
    if (samples == NULL) return -1;
    
    //open BladeRF
    if ( bladerf_open(&dev, "*:serial=bdd7") != 0 ) return -1;
    if ( bladerf_is_fpga_configured(dev) <= 0 ) return -1;
    
    //setup BladeRF, these specify a "bladerf_channel"
    for (ch=0; ch<n_channels; ch++) {
        if ( bladerf_set_sample_rate(dev, BLADERF_CHANNEL_RX(ch), 1000000, &samplerate_actual) != 0 ) return -1;
        if ( bladerf_set_frequency(dev, BLADERF_CHANNEL_RX(ch), 2400000000) != 0 ) return -1;
        if ( bladerf_get_frequency(dev, BLADERF_CHANNEL_RX(ch), &frequency_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), 55) != 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,1000) !=0 ) return -1;

    //enable, this uses a "bladerf_channel"
    for (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 (i=0; i<5; i++) {
        if ( bladerf_sync_rx(dev, samples, read_size,  &meta, 1000) !=0 ) return -1;
        printf("rx time %ld, last sample=%d\n",meta.timestamp,samples[block_size*2-1]);
    }
    
    //clean up
    free(samples);
    for (ch=0; ch<n_channels; ch++) {
        if ( bladerf_enable_module(dev, BLADERF_CHANNEL_RX(ch), false) !=0 ) return -1;
    }
    bladerf_close(dev);
    printf("Bye!\n");
    return 0;
}
When I use 1 channel, it works fine. The time increments by 2048 for each read, and the samples look like they're written, here's an example output:

Channel 0: Fs=1000000, Freq=2400000000, gain=60
Starting rx, read_size = 2048
rx time 3, last sample=345
rx time 2051, last sample=270
rx time 4099, last sample=246
rx time 6147, last sample=155
rx time 8195, last sample=131
Bye!

When I use 2 channels, the time increments by 255 for each read, and the last sample isn't written, here's example output:

Channel 0: Fs=1000000, Freq=2400000000, gain=60
Channel 1: Fs=1000000, Freq=2400000000, gain=60
Starting rx, read_size = 1024
rx time 3, last sample=0
rx time 258, last sample=0
rx time 513, last sample=0
rx time 768, last sample=0
rx time 1023, last sample=0
Bye!
shc
Posts: 2
Joined: Mon Jul 24, 2023 10:41 am

Re: Can't use 2 RX channels in libbladeRF with metadata?

Post by shc »

I am seeing a similar (or probably the same) problem. I have a program that reads data in 2-channel mode and processes it. Metadata is enabled so I can verify that I am not losing data. Works fine with FPGA code releases 0.11.0 and 0.11.1. Does not work with 0.12.0 through 0.15.0.

A few observations:

With FPGA rev 0.11.x, the timestamp increment from metadata block to metadata block is 508 in single channel mode and 254 in dual channel mode.
With FPGA rev 0.12.0 ff, the timestamp increment is 508 in single channel mode and 255 in dual channel mode.

With 0.12.0 ff, the transfer stalls after about 1794 x 1024-sample buffers (or 897 x 2048 samples, etc) and I get timeout errors like this:
[ERROR @ host/libraries/libbladeRF/src/backend/usb/libusb.c:1089] Transfer timed out for buffer 0x5588232ca0

0.12.0 ff seem to work OK in single-channel mode.

Firmware/software versions used for testing:
FPGA: 0.12.0 ("0.12.0") (also 0.11.0, 0.11.1, 0.14.0, 0.15.0)
FW: 2.4.0 ("2.4.0-git-a3d5c55f")
Lib: 2.5.0 ("2.5.0-git-c123d839")

Any input would be appreciated ...
Post Reply