static int enable_xb300(struct cli_state *state) { int status; printf(" Enabling XB-300 Amplifier board\n"); status = bladerf_expansion_attach(state->dev, BLADERF_XB_300); if (status != 0) { state->last_lib_error = status; return CLI_RET_LIBBLADERF; } printf(" XB-300 Amplifier board successfully enabled\n\n"); return status; }
int cmd_xb100(struct cli_state *state, int argc, char **argv) { int modelnum = MODEL_INVALID; int status = 0; const char *subcommand = NULL; if (NULL == state) { assert(0); // developer error return CLI_RET_INVPARAM; } if (argc < 3) { // incorrect number of arguments return CLI_RET_NARGS; } // xb 100 <subcommand> <args> modelnum = atoi(argv[1]); subcommand = argv[2]; if (modelnum != MODEL_XB100) { assert(0); // developer error return CLI_RET_INVPARAM; } putchar('\n'); // xb 100 enable if (!strcmp(subcommand, "enable")) { printf(" Enabling XB-100 GPIO expansion board\n"); status = bladerf_expansion_attach(state->dev, BLADERF_XB_100); if (status != 0) { state->last_lib_error = status; return CLI_RET_LIBBLADERF; } printf(" XB-100 GPIO expansion board successfully enabled\n\n"); } else { // unknown subcommand cli_err(state, subcommand, "Invalid subcommand for xb %d\n", modelnum); return CLI_RET_INVPARAM; } return status; }
bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, bool force) { bool forwardChange = false; bool suspendOwnThread = false; bool threadWasRunning = false; QList<QString> reverseAPIKeys; // QMutexLocker mutexLocker(&m_mutex); qDebug() << "BladerfOutput::applySettings: m_dev: " << m_dev; if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) { reverseAPIKeys.append("centerFrequency"); } if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force) { reverseAPIKeys.append("devSampleRate"); } if ((m_settings.m_log2Interp != settings.m_log2Interp) || force) { reverseAPIKeys.append("log2Interp"); } if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || (m_settings.m_log2Interp != settings.m_log2Interp) || force) { suspendOwnThread = true; } if (suspendOwnThread) { if (m_bladerfThread) { if (m_bladerfThread->isRunning()) { m_bladerfThread->stopWork(); threadWasRunning = true; } } } if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || (m_settings.m_log2Interp != settings.m_log2Interp) || force) { int fifoSize; if (settings.m_log2Interp >= 5) { fifoSize = DeviceBladeRF1Shared::m_sampleFifoMinSize32; } else { fifoSize = (std::max)( (int) ((settings.m_devSampleRate/(1<<settings.m_log2Interp)) * DeviceBladeRF1Shared::m_sampleFifoLengthInSeconds), DeviceBladeRF1Shared::m_sampleFifoMinSize); } m_sampleSourceFifo.resize(fifoSize); } if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force) { forwardChange = true; if (m_dev != 0) { unsigned int actualSamplerate; if (bladerf_set_sample_rate(m_dev, BLADERF_MODULE_TX, settings.m_devSampleRate, &actualSamplerate) < 0) { qCritical("BladerfOutput::applySettings: could not set sample rate: %d", settings.m_devSampleRate); } else { qDebug() << "BladerfOutput::applySettings: bladerf_set_sample_rate(BLADERF_MODULE_TX) actual sample rate is " << actualSamplerate; } } } if ((m_settings.m_log2Interp != settings.m_log2Interp) || force) { forwardChange = true; if (m_bladerfThread != 0) { m_bladerfThread->setLog2Interpolation(settings.m_log2Interp); qDebug() << "BladerfOutput::applySettings: set interpolation to " << (1<<settings.m_log2Interp); } } if ((m_settings.m_vga1 != settings.m_vga1) || force) { reverseAPIKeys.append("vga1"); if (m_dev != 0) { if (bladerf_set_txvga1(m_dev, settings.m_vga1) != 0) { qDebug("BladerfOutput::applySettings: bladerf_set_txvga1() failed"); } else { qDebug() << "BladerfOutput::applySettings: VGA1 gain set to " << settings.m_vga1; } } } if ((m_settings.m_vga2 != settings.m_vga2) || force) { reverseAPIKeys.append("vga2"); if(m_dev != 0) { if (bladerf_set_txvga2(m_dev, settings.m_vga2) != 0) { qDebug("BladerfOutput::applySettings:bladerf_set_rxvga2() failed"); } else { qDebug() << "BladerfOutput::applySettings: VGA2 gain set to " << settings.m_vga2; } } } if ((m_settings.m_xb200 != settings.m_xb200) || force) { reverseAPIKeys.append("xb200"); if (m_dev != 0) { bool changeSettings; if (m_deviceAPI->getSourceBuddies().size() > 0) { DeviceSourceAPI *buddy = m_deviceAPI->getSourceBuddies()[0]; if (buddy->getDeviceSourceEngine()->state() == DSPDeviceSourceEngine::StRunning) { // Tx side running changeSettings = false; } else { changeSettings = true; } } else // No Rx open { changeSettings = true; } if (changeSettings) { if (settings.m_xb200) { if (bladerf_expansion_attach(m_dev, BLADERF_XB_200) != 0) { qDebug("BladerfOutput::applySettings: bladerf_expansion_attach(xb200) failed"); } else { qDebug() << "BladerfOutput::applySettings: Attach XB200"; } } else { if (bladerf_expansion_attach(m_dev, BLADERF_XB_NONE) != 0) { qDebug("BladerfOutput::applySettings: bladerf_expansion_attach(none) failed"); } else { qDebug() << "BladerfOutput::applySettings: Detach XB200"; } } m_sharedParams.m_xb200Attached = settings.m_xb200; } } } if ((m_settings.m_xb200Path != settings.m_xb200Path) || force) { reverseAPIKeys.append("xb200Path"); if (m_dev != 0) { if (bladerf_xb200_set_path(m_dev, BLADERF_MODULE_TX, settings.m_xb200Path) != 0) { qDebug("BladerfOutput::applySettings: bladerf_xb200_set_path(BLADERF_MODULE_TX) failed"); } else { qDebug() << "BladerfOutput::applySettings: set xb200 path to " << settings.m_xb200Path; } } } if ((m_settings.m_xb200Filter != settings.m_xb200Filter) || force) { reverseAPIKeys.append("xb200Filter"); if (m_dev != 0) { if (bladerf_xb200_set_filterbank(m_dev, BLADERF_MODULE_TX, settings.m_xb200Filter) != 0) { qDebug("BladerfOutput::applySettings: bladerf_xb200_set_filterbank(BLADERF_MODULE_TX) failed"); } else { qDebug() << "BladerfOutput::applySettings: set xb200 filter to " << settings.m_xb200Filter; } } } if ((m_settings.m_bandwidth != settings.m_bandwidth) || force) { reverseAPIKeys.append("bandwidth"); if (m_dev != 0) { unsigned int actualBandwidth; if (bladerf_set_bandwidth(m_dev, BLADERF_MODULE_TX, settings.m_bandwidth, &actualBandwidth) < 0) { qCritical("BladerfOutput::applySettings: could not set bandwidth: %d", settings.m_bandwidth); } else { qDebug() << "BladerfOutput::applySettings: bladerf_set_bandwidth(BLADERF_MODULE_TX) actual bandwidth is " << actualBandwidth; } } } if (m_settings.m_centerFrequency != settings.m_centerFrequency) { forwardChange = true; } if (m_dev != 0) { if (bladerf_set_frequency( m_dev, BLADERF_MODULE_TX, settings.m_centerFrequency ) != 0) { qDebug("BladerfOutput::applySettings: bladerf_set_frequency(%lld) failed", settings.m_centerFrequency); } } if (threadWasRunning) { m_bladerfThread->startWork(); } if (settings.m_useReverseAPI) { bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || (m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) || (m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) || (m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex); webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force); } m_settings = settings; if (forwardChange) { int sampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2Interp); DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, m_settings.m_centerFrequency); m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); } qDebug() << "BladerfOutput::applySettings: center freq: " << m_settings.m_centerFrequency << " Hz" << " device sample rate: " << m_settings.m_devSampleRate << "S/s" << " baseband sample rate: " << m_settings.m_devSampleRate/(1<<m_settings.m_log2Interp) << "S/s" << " BW: " << m_settings.m_bandwidth << "Hz"; return true; }
int main(int argc, char *argv[]) { int status; struct app_params p; size_t i; struct bladerf *dev = NULL; bladerf_xb expected, attached; struct stats *stats = NULL; bool pass = true; status = get_params(argc, argv, &p); if (status != 0) { if (status == 1) { status = 0; } goto out; } for (i = 0; i < ARRAY_SIZE(tests); i++) { if (p.test_name == NULL || !strcasecmp(p.test_name, tests[i]->name)) { break; } } if (i >= ARRAY_SIZE(tests)) { fprintf(stderr, "Invalid test: %s\n", p.test_name); status = -1; goto out; } stats = calloc(ARRAY_SIZE(tests), sizeof(stats[0])); if (stats == NULL) { perror("calloc"); status = -1; goto out; } status = bladerf_open(&dev, p.device_str); if (status != 0) { fprintf(stderr, "Failed to open device: %s\n", bladerf_strerror(status)); goto out; } if (p.use_xb200) { expected = BLADERF_XB_200; status = bladerf_expansion_attach(dev, BLADERF_XB_200); if (status != 0) { fprintf(stderr, "Failed to attach XB-200: %s\n", bladerf_strerror(status)); goto out; } } else { expected = BLADERF_XB_NONE; } status = bladerf_expansion_get_attached(dev, &attached); if (status != 0) { fprintf(stderr, "Failed to query attached expansion board: %s\n", bladerf_strerror(status)); goto out; } if (expected != attached) { fprintf(stderr, "Unexpected expansion board readback: %d\n", attached); status = -1; goto out; } for (i = 0; i < ARRAY_SIZE(tests); i++) { if (p.test_name == NULL || !strcasecmp(p.test_name, tests[i]->name)) { p.randval_state = p.randval_seed; stats[i].ran = true; stats[i].failures = tests[i]->fn(dev, &p, false); } } puts("\nFailure counts"); puts("--------------------------------------------"); for (i = 0; i < ARRAY_SIZE(tests); i++) { if (stats[i].ran) { printf("%16s %u\n", tests[i]->name, stats[i].failures); } if (stats[i].failures != 0) { pass = false; } } puts(""); status = pass ? 0 : -1; out: if (dev) { bladerf_close(dev); } free(p.device_str); free(p.test_name); free(stats); return status; }
// Open BladeRF device. BladeRFSource::BladeRFSource(const char *serial) : m_dev(0), m_sampleRate(1000000), m_actualSampleRate(1000000), m_frequency(300000000), m_minFrequency(300000000), m_bandwidth(1500000), m_actualBandwidth(1500000), m_lnaGain(3), m_vga1Gain(6), m_vga2Gain(5), m_thread(0) { int status; struct bladerf_devinfo info; bladerf_init_devinfo(&info); if (serial != 0) { strncpy(info.serial, serial, BLADERF_SERIAL_LENGTH - 1); info.serial[BLADERF_SERIAL_LENGTH - 1] = '\0'; } status = bladerf_open_with_devinfo(&m_dev, &info); if (status == BLADERF_ERR_NODEV) { std::ostringstream err_ostr; err_ostr << "No devices available with serial=" << serial; m_error = err_ostr.str(); m_dev = 0; } else if (status != 0) { std::ostringstream err_ostr; err_ostr << "Failed to open device with serial=" << serial; m_error = err_ostr.str(); m_dev = 0; } else { int fpga_loaded = bladerf_is_fpga_configured(m_dev); if (fpga_loaded < 0) { std::ostringstream err_ostr; err_ostr << "Failed to check FPGA state: " << bladerf_strerror(fpga_loaded); m_error = err_ostr.str(); m_dev = 0; } else if (fpga_loaded == 0) { m_error = "The device's FPGA is not loaded."; m_dev = 0; } else { if ((status = bladerf_sync_config(m_dev, BLADERF_MODULE_RX, BLADERF_FORMAT_SC16_Q11, 64, 8192, 32, 10000)) < 0) { std::ostringstream err_ostr; err_ostr << "bladerf_sync_config failed with return code " << status; m_error = err_ostr.str(); m_dev = 0; } else { if ((status = bladerf_enable_module(m_dev, BLADERF_MODULE_RX, true)) < 0) { std::ostringstream err_ostr; err_ostr << "bladerf_enable_module failed with return code " << status; m_error = err_ostr.str(); m_dev = 0; } else { if (bladerf_expansion_attach(m_dev, BLADERF_XB_200) == 0) { std::cerr << "BladeRFSource::BladeRFSource: Attached XB200 extension" << std::endl; if ((status = bladerf_xb200_set_path(m_dev, BLADERF_MODULE_RX, BLADERF_XB200_MIX)) != 0) { std::cerr << "BladeRFSource::BladeRFSource: bladerf_xb200_set_path failed with return code " << status << std::endl; } else { if ((status = bladerf_xb200_set_filterbank(m_dev, BLADERF_MODULE_RX, BLADERF_XB200_AUTO_1DB)) != 0) { std::cerr << "BladeRFSource::BladeRFSource: bladerf_xb200_set_filterbank failed with return code " << status << std::endl; } else { std::cerr << "BladeRFSource::BladeRFSource: XB200 configured. Min freq set to 100kHz" << std::endl; m_minFrequency = 100000; } } } } } } } std::ostringstream lgains_ostr; for (int g: m_lnaGains) { lgains_ostr << g << " "; } m_lnaGainsStr = lgains_ostr.str(); std::ostringstream v1gains_ostr; for (int g: m_vga1Gains) { v1gains_ostr << g << " "; } m_vga1GainsStr = v1gains_ostr.str(); std::ostringstream v2gains_ostr; for (int g: m_vga2Gains) { v2gains_ostr << g << " "; } m_vga2GainsStr = v2gains_ostr.str(); std::ostringstream bw_ostr; for (int b: m_halfbw) { bw_ostr << 2*b << " "; } m_bwfiltStr = bw_ostr.str(); m_this = this; }
int main(int argc, char *argv[]) { sim_t s; char *devstr = NULL; int xb_board=0; int result; double duration; datetime_t t0; if (argc<3) { usage(); exit(1); } s.finished = false; 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; s.opt.interactive = FALSE; while ((result=getopt(argc,argv,"e:u:g:l:t:d:x:i"))!=-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 'x': xb_board=atoi(optarg); break; case 'i': s.opt.interactive = TRUE; 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; } if(xb_board == 200) { printf("Initializing XB200 expansion board...\n"); s.status = bladerf_expansion_attach(s.tx.dev, BLADERF_XB_200); if (s.status != 0) { fprintf(stderr, "Failed to enable XB200: %s\n", bladerf_strerror(s.status)); goto out; } s.status = bladerf_xb200_set_filterbank(s.tx.dev, BLADERF_MODULE_TX, BLADERF_XB200_CUSTOM); if (s.status != 0) { fprintf(stderr, "Failed to set XB200 TX filterbank: %s\n", bladerf_strerror(s.status)); goto out; } s.status = bladerf_xb200_set_path(s.tx.dev, BLADERF_MODULE_TX, BLADERF_XB200_BYPASS); if (s.status != 0) { fprintf(stderr, "Failed to enable TX bypass path on XB200: %s\n", bladerf_strerror(s.status)); goto out; } //For sake of completeness set also RX path to a known good state. s.status = bladerf_xb200_set_filterbank(s.tx.dev, BLADERF_MODULE_RX, BLADERF_XB200_CUSTOM); if (s.status != 0) { fprintf(stderr, "Failed to set XB200 RX filterbank: %s\n", bladerf_strerror(s.status)); goto out; } s.status = bladerf_xb200_set_path(s.tx.dev, BLADERF_MODULE_RX, BLADERF_XB200_BYPASS); if (s.status != 0) { fprintf(stderr, "Failed to enable RX bypass path on XB200: %s\n", bladerf_strerror(s.status)); goto out; } } if(xb_board == 300) { fprintf(stderr, "XB300 does not support transmitting on GPS frequency\n"); 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 'Ctrl+C' to abort.\n"); // Wainting for TX task to complete. pthread_join(s.tx.thread, NULL); printf("\nDone!\n"); // Disable TX module and shut down 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); }