size_t fifo_read(int16_t *buffer, size_t samples, sim_t *s) { size_t length; size_t samples_remaining; int16_t *buffer_current = buffer; length = get_sample_length(s); if (length < samples) samples = length; length = samples; // return value samples_remaining = FIFO_LENGTH - s->tail; if (samples > samples_remaining) { memcpy(buffer_current, &(s->fifo[s->tail * 2]), samples_remaining * sizeof(int16_t) * 2); s->tail = 0; buffer_current += samples_remaining * 2; samples -= samples_remaining; } memcpy(buffer_current, &(s->fifo[s->tail * 2]), samples * sizeof(int16_t) * 2); s->tail += (long)samples; if (s->tail >= FIFO_LENGTH) s->tail -= FIFO_LENGTH; return(length); }
void *tx_task(void *arg) { sim_t *s = (sim_t *)arg; size_t samples_populated; while (1) { int16_t *tx_buffer_current = s->tx.buffer; unsigned int buffer_samples_remaining = SAMPLES_PER_BUFFER; while (buffer_samples_remaining > 0) { pthread_mutex_lock(&(s->gps.lock)); while (get_sample_length(s) == 0) { pthread_cond_wait(&(s->fifo_read_ready), &(s->gps.lock)); } // assert(get_sample_length(s) > 0); samples_populated = fifo_read(tx_buffer_current, buffer_samples_remaining, s); pthread_mutex_unlock(&(s->gps.lock)); pthread_cond_signal(&(s->fifo_write_ready)); #if 0 if (is_fifo_write_ready(s)) { /* printf("\rTime = %4.1f", s->time); s->time += 0.1; fflush(stdout); */ } else if (is_finished_generation(s)) { goto out; } #endif // Advance the buffer pointer. buffer_samples_remaining -= (unsigned int)samples_populated; tx_buffer_current += (2 * samples_populated); } // If there were no errors, transmit the data buffer. bladerf_sync_tx(s->tx.dev, s->tx.buffer, SAMPLES_PER_BUFFER, NULL, TIMEOUT_MS); if (is_fifo_write_ready(s)) { /* printf("\rTime = %4.1f", s->time); s->time += 0.1; fflush(stdout); */ } else if (is_finished_generation(s)) { goto out; } } out: return NULL; }
int is_fifo_write_ready(sim_t *s) { int status = 0; s->sample_length = get_sample_length(s); if (s->sample_length < NUM_IQ_SAMPLES) status = 1; return(status); }