Clean up the bladerf driver a bit

This commit is contained in:
Oliver Jowett 2020-08-05 19:32:44 +08:00
parent 74607b31ed
commit c1f526b76d
1 changed files with 48 additions and 54 deletions

View File

@ -309,13 +309,15 @@ static void *handle_bladerf_samples(struct bladerf *dev,
size_t num_samples, size_t num_samples,
void *user_data) void *user_data)
{ {
static uint64_t nextTimestamp = 0; static uint64_t nextTimestamp = 0; // what's the next timestamp we expect to see?
static bool overrun = false; // do we have a pending overrun to report?
static bool dropped = 0; // do we have some dropped samples to report?
static bool first_buffer = true; // is this the very first callback?
MODES_NOTUSED(dev); MODES_NOTUSED(dev);
MODES_NOTUSED(stream); MODES_NOTUSED(stream);
MODES_NOTUSED(meta); MODES_NOTUSED(meta);
MODES_NOTUSED(user_data); MODES_NOTUSED(user_data);
MODES_NOTUSED(num_samples);
// record initial time for later sys timestamp calculation // record initial time for later sys timestamp calculation
uint64_t entryTimestamp = mstime(); uint64_t entryTimestamp = mstime();
@ -323,27 +325,17 @@ static void *handle_bladerf_samples(struct bladerf *dev,
sdrMonitor(); sdrMonitor();
if (Modes.exit) { if (Modes.exit) {
// ask our caller to return
return BLADERF_STREAM_SHUTDOWN; return BLADERF_STREAM_SHUTDOWN;
} }
struct mag_buf *outbuf = fifo_acquire(/* don't wait */ 0); timeouts = 0;
if (!outbuf) {
// FIFO is full. Drop this block.
return samples;
}
// start handling metadata blocks // start handling metadata blocks
outbuf->dropped = 0;
outbuf->validLength = outbuf->overlap;
outbuf->mean_level = outbuf->mean_power = 0;
unsigned blocks_processed = 0;
unsigned samples_per_block = (BladeRF.block_size - 16) / 4; unsigned samples_per_block = (BladeRF.block_size - 16) / 4;
struct mag_buf *outbuf = NULL;
static bool overrun = true; // ignore initial overruns as we get up to speed for (unsigned offset = 0; offset < num_samples * 4; offset += BladeRF.block_size) {
static bool first_buffer = true;
for (unsigned offset = 0; offset < MODES_MAG_BUF_SAMPLES * 4; offset += BladeRF.block_size) {
// read the next metadata header // read the next metadata header
uint8_t *header = ((uint8_t*)samples) + offset; uint8_t *header = ((uint8_t*)samples) + offset;
uint64_t metadata_magic = le32toh(*(uint32_t*)(header)); uint64_t metadata_magic = le32toh(*(uint32_t*)(header));
@ -359,62 +351,64 @@ static void *handle_bladerf_samples(struct bladerf *dev,
break; break;
} }
if (metadata_flags & BLADERF_META_STATUS_OVERRUN) { if (metadata_flags & BLADERF_META_STATUS_OVERRUN)
if (!overrun) {
fprintf(stderr, "bladeRF: receive overrun\n");
}
overrun = true; overrun = true;
} else {
overrun = false;
}
#ifndef BROKEN_FPGA_METADATA
// this needs a fixed decimating FPGA image that handles the timestamp correctly
if (nextTimestamp && nextTimestamp != metadata_timestamp) { if (nextTimestamp && nextTimestamp != metadata_timestamp) {
// dropped data or lost sync. start again. // dropped data or lost sync
overrun = true;
if (metadata_timestamp > nextTimestamp) if (metadata_timestamp > nextTimestamp)
outbuf->dropped += (metadata_timestamp - nextTimestamp); dropped = (metadata_timestamp - nextTimestamp);
outbuf->dropped += outbuf->validLength - outbuf->overlap; else
dropped = 0;
}
if (outbuf && (overrun || (outbuf->validLength + samples_per_block > outbuf->totalLength))) {
// discontinuity or buffer is full. Push the current buffer and get a new one
fifo_enqueue(outbuf);
outbuf = NULL;
}
if (!outbuf) {
// need a new buffer
outbuf = fifo_acquire(/* don't wait */ 0);
if (!outbuf) {
// we have nowhere to put this data, drop it. nb: don't update nextTimestamp
overrun = true;
continue;
}
// set metadata on the new buffer
outbuf->flags = 0;
if (overrun) {
outbuf->flags |= MAGBUF_DISCONTINUOUS;
}
outbuf->dropped = dropped;
outbuf->validLength = outbuf->overlap; outbuf->validLength = outbuf->overlap;
outbuf->flags |= MAGBUF_DISCONTINUOUS; outbuf->sampleTimestamp = metadata_timestamp * 12e6 / Modes.sample_rate / BladeRF.decimation;
blocks_processed = 0; outbuf->sysTimestamp = entryTimestamp + (num_samples - offset / 4) * 1000 / Modes.sample_rate / BladeRF.decimation;
outbuf->mean_level = outbuf->mean_power = 0; outbuf->mean_level = 0;
nextTimestamp = metadata_timestamp; outbuf->mean_power = 0;
}
#else
MODES_NOTUSED(metadata_timestamp);
#endif
if (!blocks_processed) { overrun = false;
// Compute the sample timestamp for the start of the block dropped = 0;
outbuf->sampleTimestamp = nextTimestamp * 12e6 / Modes.sample_rate / BladeRF.decimation;
} }
// Convert a block of data // Convert one block of sample data
double mean_level, mean_power; double mean_level, mean_power;
BladeRF.converter(sample_data, &outbuf->data[outbuf->validLength], samples_per_block, BladeRF.converter_state, &mean_level, &mean_power); BladeRF.converter(sample_data, &outbuf->data[outbuf->validLength], samples_per_block, BladeRF.converter_state, &mean_level, &mean_power);
outbuf->validLength += samples_per_block; outbuf->validLength += samples_per_block;
outbuf->mean_level += mean_level; outbuf->mean_level += mean_level;
outbuf->mean_power += mean_power; outbuf->mean_power += mean_power;
nextTimestamp += samples_per_block * BladeRF.decimation; nextTimestamp = metadata_timestamp + samples_per_block * BladeRF.decimation;
++blocks_processed;
timeouts = 0;
} }
first_buffer = false; // push the final buffer, if any
if (outbuf) {
if (blocks_processed) {
// Get the approx system time for the start of this block
unsigned block_duration = 1e3 * (outbuf->validLength - outbuf->overlap) / Modes.sample_rate;
outbuf->sysTimestamp = entryTimestamp - block_duration;
outbuf->mean_level /= blocks_processed;
outbuf->mean_power /= blocks_processed;
// Push the new data to the demodulation thread
fifo_enqueue(outbuf); fifo_enqueue(outbuf);
} }
first_buffer = false;
return samples; return samples;
} }