Triggered RX example

Discussions related to embedded firmware, driver, and user mode application software development
Post Reply
eliu@dgs
Posts: 2
Joined: Thu Feb 19, 2026 7:55 am

Triggered RX example

Post by eliu@dgs »

I could not find examples of triggered RX. I have BladeRF xA9 with 1PPS from LBE-1421 GPSDO connected to pin 1 of J51. The RX timeout without the trigger. I expect 10 captures should finish in 10 seconds with 1PPS as trigger but all 10 captures finished within 1s even I disarmed the trigger after each capture. The code is below, thanks in advance for helps.

typedef struct {
bool rx;
bool mimo;
size_t num_samples;
uint64_t sample_rate;
uint64_t frequency;
uint32_t bandwidth;
int16_t *rx_samples;
bladerf_format format;
struct bladerf_metadata rx_meta;
size_t num_buffers;
size_t buffer_size;
size_t num_transfers;
size_t timeout_ms;
} test_config;

int main(int argc, char *argv[])
{
int status = 0;
struct bladerf *dev = NULL;
const char *fpga_file = "hostedxA9-latest.rbf";
// const char *fpga_file = NULL;

test_config config;
config.rx = true;
config.mimo = false;
config.num_samples = 1048576;
config.sample_rate = 61.44e6;
config.frequency = 2424000000;
config.bandwidth = 50000000;
config.rx_samples = (short *) malloc(4 * config.num_samples * sizeof(int16_t));
if (config.rx_samples == NULL) {
fprintf(stderr, "Failed to allocate memory for samples\n");
exit(EXIT_FAILURE);
};
config.format = BLADERF_FORMAT_SC16_Q11;
config.rx_meta.flags = BLADERF_META_FLAG_RX_NOW;
config.num_buffers = 512;
config.buffer_size = 4096;
config.num_transfers = 64;
config.timeout_ms = 10000; // 10s time out

// bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_INFO);

bladerf_open(&dev, NULL);

// if (fpga_file != NULL) {
if (!bladerf_is_fpga_configured(dev)) {
printf("Loading the FPGA image...\n");
bladerf_load_fpga(dev, fpga_file);
}

printf("Setting sample rate to %0.3f MHz...\n", config.sample_rate / 1e6);
bladerf_set_sample_rate(dev, BLADERF_CHANNEL_RX(0), config.sample_rate, NULL);


printf("Setting frequency to %.6f MHz...\n", config.frequency/1000000.0);
bladerf_set_frequency(dev, BLADERF_CHANNEL_RX(0), config.frequency);

bladerf_set_gain_mode(dev, BLADERF_CHANNEL_RX(0), BLADERF_GAIN_FASTATTACK_AGC);

uint32_t actual;
bladerf_set_bandwidth(dev, BLADERF_CHANNEL_RX(0), config.bandwidth, &actual);
printf("Setting bandwidth to %.6f MHz, actual bandwidth %.6f MHz\n", config.bandwidth/1000000.0, actual/1000000.0);

bladerf_trigger trigger_slave;
bladerf_trigger_signal trig = BLADERF_TRIGGER_J51_1;
bladerf_trigger_init(dev, BLADERF_RX_X1, trig, &trigger_slave);

printf("Streaming RX...\n");
bladerf_sync_config(
dev, BLADERF_RX_X1,
config.format, config.num_buffers, config.buffer_size,
config.num_transfers, config.timeout_ms);


bladerf_enable_module(dev, BLADERF_CHANNEL_RX(0), true);
bladerf_set_pll_enable(dev, true);
bladerf_set_pll_refclk(dev, 40000000);

/* Retrieve the current timestamp */
config.rx_meta.flags = 0;
for (int i = 0; i < 10; i++) {
trigger_slave.role = BLADERF_TRIGGER_ROLE_SLAVE;
bladerf_trigger_arm(dev, &trigger_slave, true, 0, 0);

status = bladerf_get_timestamp(dev, BLADERF_RX, &config.rx_meta.timestamp);
if (status != 0) {
fprintf(stderr, "Failed to get current RX timestamp: %s\n",
bladerf_strerror(status));
} else {
// printf("Current RX timestamp: 0x%016" PRIx64 "\n", config.rx_meta.timestamp);
}

// config.rx_meta.timestamp += config.sample_rate / 100;
config.rx_meta.timestamp += config.sample_rate * 100;

// printf("Scheduling RX for 0x%016" PRIx64 "\n", config.rx_meta.timestamp);
status = bladerf_sync_rx(dev, config.rx_samples, config.num_samples,
&config.rx_meta, config.timeout_ms);
if (status != 0) {
fprintf(stderr, "RX failed: %s\n", bladerf_strerror(status));
} else if (config.rx_meta.status & BLADERF_META_STATUS_OVERRUN) {
fprintf(stderr, "Overrun detected. %u valid samples were read.\n",
config.rx_meta.actual_count);
// print_bladerf_flag_statuses(config.rx_meta.status);
} else {
// printf("RX'd %u samples at t=0x%016" PRIx64 "\n", config.rx_meta.actual_count,
printf("RX'd %u samples, ", config.rx_meta.actual_count);
save_iq_file(0, config.rx_samples, config.num_samples, i + 1);
}
int32_t gain;
float temp;
int32_t pre_rssi, sym_rssi;
bool locked;
bladerf_get_gain(dev, BLADERF_CHANNEL_RX(0), &gain);
bladerf_get_rfic_temperature(dev, &temp);
bladerf_get_rfic_rssi(dev, BLADERF_CHANNEL_RX(0), &pre_rssi, &sym_rssi);
bladerf_get_pll_lock_state(dev, &locked);
printf("Gain %d, temp %.3f, RSSI %d %d, locked %d\n", gain, temp, pre_rssi, sym_rssi, locked);
trigger_slave.role = BLADERF_TRIGGER_ROLE_DISABLED;
bladerf_trigger_arm(dev, &trigger_slave, false, 0, 0);


}
bladerf_enable_module(dev, BLADERF_CHANNEL_RX(0), false);


if (config.rx_samples)
free(config.rx_samples);
if (dev)
bladerf_close(dev);

return status;
}
eliu@dgs
Posts: 2
Joined: Thu Feb 19, 2026 7:55 am

Re: Triggered RX example

Post by eliu@dgs »

The "test_streaming" example in the SDK doesn't seem to work:
The timestamp always read as 0 and "bladerf_sync_rx" returns without waiting for the scheduled time:
streaming RX...
Current RX timestamp: 0x0000000000000000
Scheduling RX for 0x00000000005dc000
RX'd 1048576 samples at t=0x00000000005dc000

When I changed timeout to 10s and scheduled time to 2s later, the "bladerf_sync_rx" returns without delay:
streaming RX...
Current RX timestamp: 0x0000000000000000
Scheduling RX for 0x0000000007530000
RX'd 1048576 samples at t=0x0000000007530000
Post Reply