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; }
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) { samples_populated = fifo_read(tx_buffer_current, buffer_samples_remaining, s); if (is_fifo_write_ready(s)) { pthread_cond_signal(&(s->fifo_write_ready)); /* printf("\rTime = %4.1f", s->time); s->time += 0.1; fflush(stdout); */ } // 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); } }
int main(int argc, char *argv[]) { sim_t s; char *devstr = NULL; int c; int result; double duration; datetime_t t0; if (argc<3) { usage(); exit(1); } s.opt.navfile[0] = 0; s.opt.umfile[0] = 0; s.opt.g0.week = -1; s.opt.g0.sec = 0.0; s.opt.iduration = USER_MOTION_SIZE; s.opt.verb = TRUE; s.opt.nmeaGGA = FALSE; s.opt.staticLocationMode = TRUE; // default user motion s.opt.llh[0] = 35.274016 / R2D; s.opt.llh[1] = 137.013765 / R2D; s.opt.llh[2] = 100.0; while ((result=getopt(argc,argv,"e:u:g:l:t:d:"))!=-1) { switch (result) { case 'e': strcpy(s.opt.navfile, optarg); break; case 'u': strcpy(s.opt.umfile, optarg); s.opt.nmeaGGA = FALSE; s.opt.staticLocationMode = FALSE; break; case 'g': strcpy(s.opt.umfile, optarg); s.opt.nmeaGGA = TRUE; s.opt.staticLocationMode = FALSE; break; case 'l': // Static geodetic coordinates input mode // Added by [email protected] s.opt.nmeaGGA = FALSE; s.opt.staticLocationMode = TRUE; sscanf(optarg,"%lf,%lf,%lf",&s.opt.llh[0],&s.opt.llh[1],&s.opt.llh[2]); s.opt.llh[0] /= R2D; // convert to RAD s.opt.llh[1] /= R2D; // convert to RAD break; case 't': sscanf(optarg, "%d/%d/%d,%d:%d:%lf", &t0.y, &t0.m, &t0.d, &t0.hh, &t0.mm, &t0.sec); if (t0.y<=1980 || t0.m<1 || t0.m>12 || t0.d<1 || t0.d>31 || t0.hh<0 || t0.hh>23 || t0.mm<0 || t0.mm>59 || t0.sec<0.0 || t0.sec>=60.0) { printf("ERROR: Invalid date and time.\n"); exit(1); } t0.sec = floor(t0.sec); date2gps(&t0, &s.opt.g0); break; case 'd': duration = atof(optarg); if (duration<0.0 || duration>((double)USER_MOTION_SIZE)/10.0) { printf("ERROR: Invalid duration.\n"); exit(1); } s.opt.iduration = (int)(duration*10.0+0.5); break; case ':': case '?': usage(); exit(1); default: break; } } if (s.opt.navfile[0]==0) { printf("ERROR: GPS ephemeris file is not specified.\n"); exit(1); } if (s.opt.umfile[0]==0 && !s.opt.staticLocationMode) { printf("ERROR: User motion file / NMEA GGA stream is not specified.\n"); printf("You may use -l to specify the static location directly.\n"); exit(1); } // Initialize simulator init_sim(&s); // Allocate TX buffer to hold each block of samples to transmit. s.tx.buffer = (int16_t *)malloc(SAMPLES_PER_BUFFER * sizeof(int16_t) * 2); // for 16-bit I and Q samples if (s.tx.buffer == NULL) { fprintf(stderr, "Failed to allocate TX buffer.\n"); goto out; } // Allocate FIFOs to hold 0.1 seconds of I/Q samples each. s.fifo = (int16_t *)malloc(FIFO_LENGTH * sizeof(int16_t) * 2); // for 16-bit I and Q samples if (s.fifo == NULL) { fprintf(stderr, "Failed to allocate I/Q sample buffer.\n"); goto out; } // Initializing device. printf("Opening and initializing device...\n"); s.status = bladerf_open(&s.tx.dev, devstr); if (s.status != 0) { fprintf(stderr, "Failed to open device: %s\n", bladerf_strerror(s.status)); goto out; } s.status = bladerf_set_frequency(s.tx.dev, BLADERF_MODULE_TX, TX_FREQUENCY); if (s.status != 0) { fprintf(stderr, "Faield to set TX frequency: %s\n", bladerf_strerror(s.status)); goto out; } else { printf("TX frequency: %u Hz\n", TX_FREQUENCY); } s.status = bladerf_set_sample_rate(s.tx.dev, BLADERF_MODULE_TX, TX_SAMPLERATE, NULL); if (s.status != 0) { fprintf(stderr, "Failed to set TX sample rate: %s\n", bladerf_strerror(s.status)); goto out; } else { printf("TX sample rate: %u sps\n", TX_SAMPLERATE); } s.status = bladerf_set_bandwidth(s.tx.dev, BLADERF_MODULE_TX, TX_BANDWIDTH, NULL); if (s.status != 0) { fprintf(stderr, "Failed to set TX bandwidth: %s\n", bladerf_strerror(s.status)); goto out; } else { printf("TX bandwidth: %u Hz\n", TX_BANDWIDTH); } s.status = bladerf_set_txvga1(s.tx.dev, TX_VGA1); if (s.status != 0) { fprintf(stderr, "Failed to set TX VGA1 gain: %s\n", bladerf_strerror(s.status)); goto out; } else { printf("TX VGA1 gain: %d dB\n", TX_VGA1); } s.status = bladerf_set_txvga2(s.tx.dev, TX_VGA2); if (s.status != 0) { fprintf(stderr, "Failed to set TX VGA2 gain: %s\n", bladerf_strerror(s.status)); goto out; } else { printf("TX VGA2 gain: %d dB\n", TX_VGA2); } // Start GPS task. s.status = start_gps_task(&s); if (s.status < 0) { fprintf(stderr, "Failed to start GPS task.\n"); goto out; } else printf("Creating GPS task...\n"); // Wait until GPS task is initialized pthread_mutex_lock(&(s.tx.lock)); while (!s.gps.ready) pthread_cond_wait(&(s.gps.initialization_done), &(s.tx.lock)); pthread_mutex_unlock(&(s.tx.lock)); // Fillfull the FIFO. if (is_fifo_write_ready(&s)) pthread_cond_signal(&(s.fifo_write_ready)); // Configure the TX module for use with the synchronous interface. s.status = bladerf_sync_config(s.tx.dev, BLADERF_MODULE_TX, BLADERF_FORMAT_SC16_Q11, NUM_BUFFERS, SAMPLES_PER_BUFFER, NUM_TRANSFERS, TIMEOUT_MS); if (s.status != 0) { fprintf(stderr, "Failed to configure TX sync interface: %s\n", bladerf_strerror(s.status)); goto out; } // We must always enable the modules *after* calling bladerf_sync_config(). s.status = bladerf_enable_module(s.tx.dev, BLADERF_MODULE_TX, true); if (s.status != 0) { fprintf(stderr, "Failed to enable TX module: %s\n", bladerf_strerror(s.status)); goto out; } // Start TX task s.status = start_tx_task(&s); if (s.status < 0) { fprintf(stderr, "Failed to start TX task.\n"); goto out; } else printf("Creating TX task...\n"); // Running... printf("Running...\n"); printf("Press 'q' to exit.\n"); while (1) { c = _getch(); if (c=='q') break; } // // TODO: Cleaning up the threads properly. // printf("\nDone!\n"); // Disable TX module, shutting down our underlying TX stream. s.status = bladerf_enable_module(s.tx.dev, BLADERF_MODULE_TX, false); if (s.status != 0) { fprintf(stderr, "Failed to disable TX module: %s\n", bladerf_strerror(s.status)); } out: // Free up resources if (s.tx.buffer != NULL) free(s.tx.buffer); if (s.fifo != NULL) free(s.fifo); printf("Closing device...\n"); bladerf_close(s.tx.dev); return(0); }
int main(int argc, char *argv[]) { sim_t s; char *devstr = NULL; int c; // Initialize structures init_sim(&s); // Allocate TX buffer to hold each block of samples to transmit. s.tx.buffer = (int16_t *)malloc(SAMPLES_PER_BUFFER * sizeof(int16_t) * 2); // for 16-bit I and Q samples if (s.tx.buffer == NULL) { fprintf(stderr, "Failed to allocate TX buffer.\n"); goto out; } // Allocate FIFOs to hold 0.1 seconds of I/Q samples each. s.fifo = (int16_t *)malloc(FIFO_LENGTH * sizeof(int16_t) * 2); // for 16-bit I and Q samples if (s.fifo == NULL) { fprintf(stderr, "Failed to allocate I/Q sample buffer.\n"); goto out; } // Initializing device. printf("Opening and initializing device...\n"); s.status = bladerf_open(&s.tx.dev, devstr); if (s.status != 0) { fprintf(stderr, "Failed to open device: %s\n", bladerf_strerror(s.status)); goto out; } s.status = bladerf_set_frequency(s.tx.dev, BLADERF_MODULE_TX, TX_FREQUENCY); if (s.status != 0) { fprintf(stderr, "Faield to set TX frequency: %s\n", bladerf_strerror(s.status)); goto out; } else { printf("TX frequency: %u Hz\n", TX_FREQUENCY); } s.status = bladerf_set_sample_rate(s.tx.dev, BLADERF_MODULE_TX, TX_SAMPLERATE, NULL); if (s.status != 0) { fprintf(stderr, "Failed to set TX sample rate: %s\n", bladerf_strerror(s.status)); goto out; } else { printf("TX sample rate: %u sps\n", TX_SAMPLERATE); } s.status = bladerf_set_bandwidth(s.tx.dev, BLADERF_MODULE_TX, TX_BANDWIDTH, NULL); if (s.status != 0) { fprintf(stderr, "Failed to set TX bandwidth: %s\n", bladerf_strerror(s.status)); goto out; } else { printf("TX bandwidth: %u Hz\n", TX_BANDWIDTH); } s.status = bladerf_set_txvga1(s.tx.dev, TX_VGA1); if (s.status != 0) { fprintf(stderr, "Failed to set TX VGA1 gain: %s\n", bladerf_strerror(s.status)); goto out; } else { printf("TX VGA1 gain: %d dB\n", TX_VGA1); } s.status = bladerf_set_txvga2(s.tx.dev, TX_VGA2); if (s.status != 0) { fprintf(stderr, "Failed to set TX VGA2 gain: %s\n", bladerf_strerror(s.status)); goto out; } else { printf("TX VGA2 gain: %d dB\n", TX_VGA2); } // Start GPS task. s.status = start_gps_task(&s); if (s.status < 0) { fprintf(stderr, "Failed to start GPS task.\n"); goto out; } else printf("Creating GPS task...\n"); // Wait until GPS task is initialized pthread_mutex_lock(&(s.tx.lock)); while (!s.gps.ready) pthread_cond_wait(&(s.gps.initialization_done), &(s.tx.lock)); pthread_mutex_unlock(&(s.tx.lock)); // Fillfull the FIFO. if (is_fifo_write_ready(&s)) pthread_cond_signal(&(s.fifo_write_ready)); // Configure the TX module for use with the synchronous interface. s.status = bladerf_sync_config(s.tx.dev, BLADERF_MODULE_TX, BLADERF_FORMAT_SC16_Q11, NUM_BUFFERS, SAMPLES_PER_BUFFER, NUM_TRANSFERS, TIMEOUT_MS); if (s.status != 0) { fprintf(stderr, "Failed to configure TX sync interface: %s\n", bladerf_strerror(s.status)); goto out; } // We must always enable the modules *after* calling bladerf_sync_config(). s.status = bladerf_enable_module(s.tx.dev, BLADERF_MODULE_TX, true); if (s.status != 0) { fprintf(stderr, "Failed to enable TX module: %s\n", bladerf_strerror(s.status)); goto out; } // Start TX task s.status = start_tx_task(&s); if (s.status < 0) { fprintf(stderr, "Failed to start TX task.\n"); goto out; } else printf("Creating TX task...\n"); // Running... printf("Running...\n"); printf("Press 'q' to exit.\n"); while (1) { c = _getch(); if (c=='q') break; } // // TODO: Cleaning up the threads properly. // printf("\nDone!\n"); // Disable TX module, shutting down our underlying TX stream. s.status = bladerf_enable_module(s.tx.dev, BLADERF_MODULE_TX, false); if (s.status != 0) { fprintf(stderr, "Failed to disable TX module: %s\n", bladerf_strerror(s.status)); } out: // Free up resources if (s.tx.buffer != NULL) free(s.tx.buffer); if (s.fifo != NULL) free(s.fifo); printf("Closing device...\n"); bladerf_close(s.tx.dev); return(0); }