Example #1
1
int enable(struct bladerf* dev, bool enabled)
{
    int status;

    if(enabled)
        printf("%-50s", "Enabling TX... ");
    else
        printf("%-50s", "Disabling TX... ");
    fflush(stdout);
    status = bladerf_enable_module(dev, BLADERF_MODULE_TX, enabled);
    if(status) {
        printf(KRED "Failed: %s" KNRM "\n", bladerf_strerror(status));
        bladerf_close(dev);
        return 1;
    }
    printf(KGRN "OK" KNRM "\n");

    if(enabled)
        printf("%-50s", "Enabling RX... ");
    else
        printf("%-50s", "Disabling RX... ");
    fflush(stdout);
    status = bladerf_enable_module(dev, BLADERF_MODULE_RX, enabled);
    if(status) {
        printf(KRED "Failed: %s" KNRM "\n", bladerf_strerror(status));
        bladerf_close(dev);
        return 1;
    }
    printf(KGRN "OK" KNRM "\n");

    return 0;
}
Example #2
0
int bladerf_init_device(struct bladerf *dev)
{
    unsigned int actual;
    uint32_t val;

    /* Readback the GPIO values to see if they are default or already set */
    bladerf_config_gpio_read( dev, &val );

    if (val == 0) {
        log_verbose( "Default GPIO value found - initializing device\n" );

        /* Set the GPIO pins to enable the LMS and select the low band */
        bladerf_config_gpio_write( dev, 0x57 );

        /* Set the internal LMS register to enable RX and TX */
        bladerf_lms_write( dev, 0x05, 0x3e );

        /* LMS FAQ: Improve TX spurious emission performance */
        bladerf_lms_write( dev, 0x47, 0x40 );

        /* LMS FAQ: Improve ADC performance */
        bladerf_lms_write( dev, 0x59, 0x29 );

        /* LMS FAQ: Common mode voltage for ADC */
        bladerf_lms_write( dev, 0x64, 0x36 );

        /* LMS FAQ: Higher LNA Gain */
        bladerf_lms_write( dev, 0x79, 0x37 );

        /* FPGA workaround: Set IQ polarity for RX */
        bladerf_lms_write( dev, 0x5a, 0xa0 );

        /* Set a default saplerate */
        bladerf_set_sample_rate( dev, BLADERF_MODULE_TX, 1000000, &actual );
        bladerf_set_sample_rate( dev, BLADERF_MODULE_RX, 1000000, &actual );

        /* Enable TX and RX */
        bladerf_enable_module( dev, BLADERF_MODULE_TX, false );
        bladerf_enable_module( dev, BLADERF_MODULE_RX, false );

        /* Set a default frequency of 1GHz */
        bladerf_set_frequency( dev, BLADERF_MODULE_TX, 1000000000 );
        bladerf_set_frequency( dev, BLADERF_MODULE_RX, 1000000000 );

        /* Set the calibrated VCTCXO DAC value */
        bladerf_dac_write( dev, dev->dac_trim );
    }

    /* TODO: Read this return from the SPI calls */
    return 0;
}
Example #3
0
void rxtx_task_exec_stop(struct rxtx_data *rxtx, unsigned char *requests,
                         struct bladerf *dev)
{
    int status;

    *requests = rxtx_get_requests(rxtx,
                                  RXTX_TASK_REQ_STOP | RXTX_TASK_REQ_SHUTDOWN);

    pthread_mutex_lock(&rxtx->data_mgmt.lock);
    bladerf_deinit_stream(rxtx->data_mgmt.stream);
    rxtx->data_mgmt.stream = NULL;
    pthread_mutex_unlock(&rxtx->data_mgmt.lock);

    pthread_mutex_lock(&rxtx->file_mgmt.file_lock);
    if (rxtx->file_mgmt.file != NULL) {
        fclose(rxtx->file_mgmt.file);
        rxtx->file_mgmt.file = NULL;
    }
    pthread_mutex_unlock(&rxtx->file_mgmt.file_lock);

    if (*requests & RXTX_TASK_REQ_SHUTDOWN) {
        rxtx_set_state(rxtx, RXTX_STATE_SHUTDOWN);
    } else {
        rxtx_set_state(rxtx, RXTX_STATE_IDLE);
    }

    status = bladerf_enable_module(dev, rxtx->module, false);
    if (status < 0) {
        set_last_error(&rxtx->last_error, ETYPE_BLADERF, status);
    }

    *requests = 0;

    rxtx_release_wait(rxtx);
}
Example #4
0
void Bladerf1Output::closeDevice()
{
    int res;

    if (m_dev == 0) { // was never open
        return;
    }

    if ((res = bladerf_enable_module(m_dev, BLADERF_MODULE_TX, false)) < 0)
    {
        qCritical("BladerfOutput::closeDevice: bladerf_enable_module with return code %d", res);
    }

    if (m_deviceAPI->getSourceBuddies().size() == 0)
    {
        qDebug("BladerfOutput::closeDevice: closing device since Rx side is not open");

        if (m_dev != 0) // close BladeRF
        {
            bladerf_close(m_dev);
        }
    }

    m_sharedParams.m_dev = 0;
    m_dev = 0;
}
Example #5
0
int rf_blade_stop_rx_stream(void *h)
{
  rf_blade_handler_t *handler = (rf_blade_handler_t*) h;
  int status = bladerf_enable_module(handler->dev, BLADERF_MODULE_RX, false);
  if (status != 0) {
    fprintf(stderr, "Failed to enable RX module: %s\n", bladerf_strerror(status));
    return status;
  }
  status = bladerf_enable_module(handler->dev, BLADERF_MODULE_TX, false);
  if (status != 0) {
    fprintf(stderr, "Failed to enable TX module: %s\n", bladerf_strerror(status));
    return status;
  }
  handler->rx_stream_enabled = false;
  handler->tx_stream_enabled = false; 
  return 0;
}
BladeRfTxComponent::~BladeRfTxComponent()
{
    if (device_) {
        if (bladerf_enable_module(device_, BLADERF_MODULE_TX, false) != 0)
            LOG(LERROR) << "Couldn't shutdown BladeRF Tx module!";
        bladerf_close(device_);
    }
}
Example #7
0
void radio_stop(struct bladerf *dev)
{
    int status;

    if (dev == NULL){
        return;
    }
    //Disable tx module
    status = bladerf_enable_module(dev, BLADERF_MODULE_TX, false);
    if (status != 0){
        fprintf(stderr, "Couldn't disable TX module: %s\n", bladerf_strerror(status));
    }
    //Disable rx module
    status = bladerf_enable_module(dev, BLADERF_MODULE_RX, false);
    if (status != 0){
        fprintf(stderr, "Couldn't disable RX module: %s\n", bladerf_strerror(status));
    }
}
Example #8
0
bool Bladerf1Output::openDevice()
{
    if (m_dev != 0)
    {
        closeDevice();
    }

    int res;

    m_sampleSourceFifo.resize(m_settings.m_devSampleRate/(1<<(m_settings.m_log2Interp <= 4 ? m_settings.m_log2Interp : 4)));

    if (m_deviceAPI->getSourceBuddies().size() > 0)
    {
        DeviceSourceAPI *sourceBuddy = m_deviceAPI->getSourceBuddies()[0];
        DeviceBladeRF1Params *buddySharedParams = (DeviceBladeRF1Params *) sourceBuddy->getBuddySharedPtr();

        if (buddySharedParams == 0)
        {
            qCritical("BladerfOutput::start: could not get shared parameters from buddy");
            return false;
        }

        if (buddySharedParams->m_dev == 0) // device is not opened by buddy
        {
            qCritical("BladerfOutput::start: could not get BladeRF handle from buddy");
            return false;
        }

        m_sharedParams = *(buddySharedParams); // copy parameters from buddy
        m_dev = m_sharedParams.m_dev;          // get BladeRF handle
    }
    else
    {
        if (!DeviceBladeRF1::open_bladerf(&m_dev, qPrintable(m_deviceAPI->getSampleSinkSerial())))
        {
            qCritical("BladerfOutput::start: could not open BladeRF %s", qPrintable(m_deviceAPI->getSampleSinkSerial()));
            return false;
        }

        m_sharedParams.m_dev = m_dev;
    }

    // TODO: adjust USB transfer data according to sample rate
    if ((res = bladerf_sync_config(m_dev, BLADERF_TX_X1, BLADERF_FORMAT_SC16_Q11, 64, 8192, 32, 10000)) < 0)
    {
        qCritical("BladerfOutput::start: bladerf_sync_config with return code %d", res);
        return false;
    }

    if ((res = bladerf_enable_module(m_dev, BLADERF_MODULE_TX, true)) < 0)
    {
        qCritical("BladerfOutput::start: bladerf_enable_module with return code %d", res);
        return false;
    }

    return true;
}
Example #9
0
int rf_blade_start_rx_stream(void *h)
{
  int status; 
  rf_blade_handler_t *handler = (rf_blade_handler_t*) h;
    
  /* Configure the device's RX module for use with the sync interface.
     * SC16 Q11 samples *with* metadata are used. */
  uint32_t buffer_size_rx = ms_buffer_size_rx*(handler->rx_rate/1000/1024); 
  
  status = bladerf_sync_config(handler->dev,
                                BLADERF_MODULE_RX,
                                BLADERF_FORMAT_SC16_Q11_META,
                                num_buffers,
                                buffer_size_rx,
                                num_transfers,
                                timeout_ms);
  if (status != 0) {
    fprintf(stderr, "Failed to configure RX sync interface: %s\n", bladerf_strerror(status));
    return status;
  }
  status = bladerf_sync_config(handler->dev,
                                BLADERF_MODULE_TX,
                                BLADERF_FORMAT_SC16_Q11_META,
                                num_buffers,
                                buffer_size_tx,
                                num_transfers,
                                timeout_ms);
  if (status != 0) {
    fprintf(stderr, "Failed to configure TX sync interface: %s\n", bladerf_strerror(status));
    return status; 
  }
  status = bladerf_enable_module(handler->dev, BLADERF_MODULE_RX, true);
  if (status != 0) {
    fprintf(stderr, "Failed to enable RX module: %s\n", bladerf_strerror(status));
    return status;
  }
  status = bladerf_enable_module(handler->dev, BLADERF_MODULE_TX, true);
  if (status != 0) {
    fprintf(stderr, "Failed to enable TX module: %s\n", bladerf_strerror(status));
    return status;
  }
  handler->rx_stream_enabled = true; 
  return 0;
}
Example #10
0
static void deinit(struct repeater *repeater)
{

    if (repeater->device) {
        if (repeater->rx_stream) {
            bladerf_deinit_stream(repeater->rx_stream);
        }

        if (repeater->tx_stream) {
            bladerf_deinit_stream(repeater->tx_stream);
        }

        bladerf_enable_module(repeater->device, BLADERF_MODULE_RX, false);
        bladerf_enable_module(repeater->device, BLADERF_MODULE_TX, false);

        bladerf_close(repeater->device);
        repeater->device = NULL;
    }
}
Example #11
0
int main(int argc, char *argv[])
{
    int status = 0;

    struct bladerf *dev = NULL;
    struct bladerf_devinfo dev_info;

    /* Initialize the information used to identify the desired device
     * to all wildcard (i.e., "any device") values */
    bladerf_init_devinfo(&dev_info);

    /* Request a device with the provided serial number.
     * Invalid strings should simply fail to match a device. */
    if (argc >= 2) {
        fprintf(stdout, "dev_info.serial: %s", dev_info.serial);
        strncpy(dev_info.serial, argv[1], sizeof(dev_info.serial) - 1);
    }

    status = bladerf_open_with_devinfo(&dev, &dev_info);
    if (status != 0) {
        fprintf(stderr, "Unable to open device: %s\n",
                bladerf_strerror(status));
        return 1;
    }

    /* A quick check that this works is to watch LO leakage on a VSA */

    status = bladerf_enable_module(dev, BLADERF_MODULE_TX, true);
    if (status != 0) {
        fprintf(stderr, "Failed to enable TX module: %s\n",
                bladerf_strerror(status));
        return status;
    }

    status = example(dev, BLADERF_MODULE_TX);

    bladerf_enable_module(dev, BLADERF_MODULE_TX, false);
    bladerf_close(dev);
    return status;
}
Example #12
0
/** [tx_meta_deinit] */
void deinit(struct bladerf *dev, int16_t *samples)
{
    printf("\nDeinitalizing device.\n");

    /* Disable TX module, shutting down our underlying TX stream */
    int status = bladerf_enable_module(dev, BLADERF_MODULE_TX, false);
    if (status != 0) {
        fprintf(stderr, "Failed to disable TX module: %s\n",
                bladerf_strerror(status));
    }

    /* Deinitialize and free resources */
    free(samples);
    bladerf_close(dev);
}
Example #13
0
static int tx_start_init(struct cli_state *s)
{
    int status = CMD_RET_UNKNOWN;
    enum rxtx_state state;

    switch(s->rxtx_data->tx.common.file_fmt) {
        case RXTX_FMT_CSV_C16:
            status = tx_csv_to_c16(s);
            if (status < 0)
                return status;

            printf("\nConverted CSV file to binary file. Using %s\n",
                    s->rxtx_data->tx.common.file_path);
            printf("Note that this program will not delete the temporary file.\n\n");
            /* Fall through - if we hit this line we're now using
             * a temporary binary file */

        case RXTX_FMT_BINLE_C16:
        case RXTX_FMT_BINBE_C16:
            s->rxtx_data->tx.read_samples = rxtx_read_bin_c16;
            break;

        /* This shouldn't happen...*/
        default:
            assert(0);
            return CMD_RET_UNKNOWN;
    }

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_TX, true);
    if (status >= 0) {
        set_state(&s->rxtx_data->tx.common, RXTX_STATE_RUNNING, true);

        /* Don't expect to poll here long... replace with cond var? */
        while ((state = get_state(&s->rxtx_data->tx.common)) == RXTX_STATE_IDLE) {
            usleep(100000);
        }

        if (state == RXTX_STATE_RUNNING) {
            status = 0;
        }
    }

    return status;
}
Example #14
0
static int rx_start_init(struct cli_state *s)
{
    enum rxtx_state state;
    int status = CMD_RET_UNKNOWN;
    struct rx_cfg *rx = &s->rxtx_data->rx;

    switch(s->rxtx_data->rx.common.file_fmt) {
        case RXTX_FMT_CSV_C16:
            rx->write_samples = rxtx_write_csv_c16;
            break;

        case RXTX_FMT_BINLE_C16:
        case RXTX_FMT_BINBE_C16:
            rx->write_samples = rxtx_write_bin_c16;
            break;

        /* This shouldn't happen...*/
        default:
            assert(0);
            return CMD_RET_UNKNOWN;
    }

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, true);
    if (status >= 0) {
        set_state(&rx->common, RXTX_STATE_RUNNING, true);

        while ((state = get_state(&rx->common)) == RXTX_STATE_IDLE) {
            usleep(100000);
        }

        if (state == RXTX_STATE_RUNNING) {
            status = 0;
        }
    }

    return status;
}
Example #15
0
int rf_blade_start_tx_stream(void *h)
{
  int status; 
  rf_blade_handler_t *handler = (rf_blade_handler_t*) h;
  
  status = bladerf_sync_config(handler->dev,
                                BLADERF_MODULE_TX,
                                BLADERF_FORMAT_SC16_Q11_META,
                                num_buffers,
                                buffer_size_tx,
                                num_transfers,
                                timeout_ms);
  if (status != 0) {
    fprintf(stderr, "Failed to configure TX sync interface: %s\n", bladerf_strerror(status));
    return status; 
  }
  status = bladerf_enable_module(handler->dev, BLADERF_MODULE_TX, true);
  if (status != 0) {
    fprintf(stderr, "Failed to enable TX module: %s\n", bladerf_strerror(status));
    return status;
  }
  handler->tx_stream_enabled = true; 
  return 0;
}
Example #16
0
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);
}
Example #17
0
static int run(struct bladerf *dev, struct app_params *p,
               int16_t *samples, const struct test_case *t)
{
    int status, status_out;
    struct bladerf_metadata meta;
    uint64_t timestamp;
    unsigned int gap;
    uint32_t counter;
    uint64_t tscount_diff;
    unsigned int i;
    bool suppress_overrun_msg = false;
    unsigned int overruns = 0;
    bool prev_iter_overrun = false;

    /* Clear out metadata and request that we just received any available
     * samples, with the timestamp filled in for us */
    memset(&meta, 0, sizeof(meta));
    meta.flags = BLADERF_META_FLAG_RX_NOW;

    status = enable_counter_mode(dev, true);
    if (status != 0) {
        goto out;
    }

    status = perform_sync_init(dev, BLADERF_MODULE_RX, 0, p);
    if (status != 0) {
        goto out;
    }

    /* Initial read to get a starting timestamp, and counter value */
    gap = get_gap(p, t);
    status = bladerf_sync_rx(dev, samples, gap, &meta, p->timeout_ms);
    if (status != 0) {
        fprintf(stderr, "Intial RX failed: %s\n", bladerf_strerror(status));
        goto out;
    }

    counter = extract_counter_val((uint8_t*) samples);
    timestamp = meta.timestamp;

    assert(timestamp >= (uint64_t) counter);
    tscount_diff = timestamp - (uint64_t) counter;

    if (t->gap != 0) {
        printf("\nTest Case: Read size=%"PRIu64" samples, %u iterations\n",
                t->gap, t->iterations);
    } else {
        printf("\nTest Case: Random read size, %u iterations\n", t->iterations);
    }

    printf("--------------------------------------------------------\n");

    assert((timestamp - tscount_diff) <= UINT32_MAX);
    status = check_data(samples, &meta, UINT64_MAX,
                        (uint32_t) (timestamp - tscount_diff),
                        meta.actual_count, &suppress_overrun_msg);

    if (status == DETECTED_OVERRUN) {
        overruns++;
        status = 0;
    }

    printf("Timestamp-counter diff: %"PRIu64"\n", tscount_diff);
    printf("Initial timestamp:      0x%016"PRIx64"\n", meta.timestamp);
    printf("Intital counter value:  0x%08"PRIx32"\n", counter);
    printf("Initial status:         0x%08"PRIu32"\n", meta.status);

    for (i = 0; i < t->iterations && status == 0; i++) {

        timestamp = meta.timestamp + gap;
        gap = get_gap(p, t);

        status = bladerf_sync_rx(dev, samples, gap, &meta, p->timeout_ms);
        if (status != 0) {
            fprintf(stderr, "RX %u failed: %s\n", i, bladerf_strerror(status));
            goto out;
        }

        /* If an overrun occured on the previous iteration, we don't know what
         * the timestamp will actually be on this iteration. */
        if (prev_iter_overrun) {
            timestamp = meta.timestamp;
        }

        status = check_data(samples, &meta, timestamp,
                            (uint32_t) (timestamp - tscount_diff),
                            gap, &suppress_overrun_msg);

        if (status == DETECTED_OVERRUN) {
            overruns++;
            status = 0;

            prev_iter_overrun = true;
        }
    }

    if (status != 0) {
        printf("Test failed due to errors.\n");
    } else if (overruns != 0) {
        printf("Test failed due to %u overruns.\n", overruns);
        status = -1;
    } else {
        printf("Test passed.\n");
    }

out:
    status_out = bladerf_enable_module(dev, BLADERF_MODULE_RX, false);
    if (status_out != 0) {
        fprintf(stderr, "Failed to disable RX module: %s\n",
                bladerf_strerror(status));
    }

    status = first_error(status, status_out);

    status_out = enable_counter_mode(dev, false);
    status = first_error(status, status_out);

    return status;
}
Example #18
0
int main(int argc, char *argv[])
{
    int status;
    unsigned int actual;
    struct bladerf *dev;
    struct bladerf_stream *stream;
    struct test_data test_data;
    bool conv_ok;

    if (argc != 4 && argc != 5) {
        fprintf(stderr,
                "Usage: %s [tx|rx] <samples per buffer> <# buffers> [# samples]\n", argv[0]);
        return EXIT_FAILURE;
    }

    if (strcasecmp(argv[1], "rx") == 0 ) {
        test_data.module = BLADERF_MODULE_RX ;
    } else if (strcasecmp(argv[1], "tx") == 0 ) {
        test_data.module = BLADERF_MODULE_TX;
    } else {
        fprintf(stderr, "Invalid module: %s\n", argv[1]);
        return EXIT_FAILURE;
    }

    test_data.idx = 0;
    test_data.fout = NULL;

    test_data.samples_per_buffer = str2int(argv[2], 1, INT_MAX, &conv_ok);
    if (!conv_ok) {
        fprintf(stderr, "Invalid samples per buffer value: %s\n", argv[2]);
        return EXIT_FAILURE;
    }

    test_data.num_buffers = str2int(argv[3], 1, INT_MAX, &conv_ok);
    if (!conv_ok) {
        fprintf(stderr, "Invalid # buffers: %s\n", argv[3]);
        return EXIT_FAILURE;
    }

    if(test_data.module == BLADERF_MODULE_RX && argc == 5) {
        test_data.samples_left = str2int(argv[4], 1, INT_MAX, &conv_ok);
        if(!conv_ok) {
            fprintf(stderr, "Invalid number of samples: %s\n", argv[4]);
            return EXIT_FAILURE;
        }
    }

    if (signal(SIGINT, handler) == SIG_ERR ||
        signal(SIGTERM, handler) == SIG_ERR) {
        fprintf(stderr, "Failed to set up signal handler\n");
        return EXIT_FAILURE;
    }

    status = bladerf_open(&dev, NULL);
    if (status < 0) {
        fprintf(stderr, "Failed to open device: %s\n", bladerf_strerror(status));
        return EXIT_FAILURE;
    }

    status = bladerf_is_fpga_configured(dev);
    if (status < 0) {
        fprintf(stderr, "Failed to determine FPGA state: %s\n",
                bladerf_strerror(status));
        return EXIT_FAILURE;
    } else if (status == 0) {
        fprintf(stderr, "Error: FPGA is not loaded.\n");
        bladerf_close(dev);
        return EXIT_FAILURE;
    }

    if (!status) {
        status = bladerf_set_frequency(dev, test_data.module, 1000000000);
        if (status < 0) {
            fprintf(stderr, "Failed to set frequency: %s\n",
                    bladerf_strerror(status));
            bladerf_close(dev);
            return EXIT_FAILURE;
        }
    }

    if (!status) {
        status = bladerf_set_sample_rate(dev, test_data.module, 40000000, &actual);
        if (status < 0) {
            fprintf(stderr, "Failed to set sample rate: %s\n",
                    bladerf_strerror(status));
            bladerf_close(dev);
            return EXIT_FAILURE;
        }
    }

    /* Initialize the stream */
    status = bladerf_init_stream(
                &stream,
                dev,
                stream_callback,
                &test_data.buffers,
                test_data.num_buffers,
                BLADERF_FORMAT_SC16_Q12,
                test_data.samples_per_buffer,
                test_data.num_buffers,
                &test_data
             ) ;

    /* Populate buffers with test data */
    if( test_data.module == BLADERF_MODULE_TX ) {
        if (populate_test_data(&test_data) ) {
            fprintf(stderr, "Failed to populated test data\n");
            bladerf_deinit_stream(stream);
            bladerf_close(dev);
            return EXIT_FAILURE;
        }
    } else {
        /* Open up file we'll read test data to */
        test_data.fout = fopen( "samples.txt", "w" );
        if (!test_data.fout) {
            fprintf(stderr, "Failed to open samples.txt: %s\n", strerror(errno));
            bladerf_deinit_stream(stream);
            bladerf_close(dev);
            return EXIT_FAILURE;
        }
    }

    status = bladerf_enable_module(dev, test_data.module, true);
    if (status < 0) {
        fprintf(stderr, "Failed to enable module: %s\n",
                bladerf_strerror(status));
    }

    if (!status) {
        /* Start stream and stay there until we kill the stream */
        status = bladerf_stream(stream, test_data.module);

        if (status < 0) {
            fprintf(stderr, "Stream error: %s\n", bladerf_strerror(status));
        }
    }

    status = bladerf_enable_module(dev, test_data.module, false);
    if (status < 0) {
        fprintf(stderr, "Failed to enable module: %s\n",
                bladerf_strerror(status));
    }

    bladerf_deinit_stream(stream);
    bladerf_close(dev);

    if (test_data.fout) {
        fclose(test_data.fout);
    }

    return 0;
}
Example #19
0
int sync_rx_example(struct bladerf *dev)
{
    int status, ret;
    bool done         = false;
    bool have_tx_data = false;

    /** [user_buffers] */

    /* "User" samples buffers and their associated sizes, in units of samples.
     * Recall that one sample = two int16_t values. */
    int16_t *rx_samples            = NULL;
    int16_t *tx_samples            = NULL;
    const unsigned int samples_len = 10000; /* May be any (reasonable) size */

    /* Allocate a buffer to store received samples in */
    rx_samples = malloc(samples_len * 2 * 1 * sizeof(int16_t));
    if (rx_samples == NULL) {
        perror("malloc");
        return BLADERF_ERR_MEM;
    }

    /* Allocate a buffer to prepare transmit data in */
    tx_samples = malloc(samples_len * 2 * 1 * sizeof(int16_t));
    if (tx_samples == NULL) {
        perror("malloc");
        free(rx_samples);
        return BLADERF_ERR_MEM;
    }

    /** [user_buffers] */

    /* Initialize synch interface on RX and TX */
    status = init_sync(dev);
    if (status != 0) {
        goto out;
    }

    /** [enable_modules] */

    status = bladerf_enable_module(dev, BLADERF_RX, true);
    if (status != 0) {
        fprintf(stderr, "Failed to enable RX: %s\n", bladerf_strerror(status));
        goto out;
    }

    status = bladerf_enable_module(dev, BLADERF_TX, true);
    if (status != 0) {
        fprintf(stderr, "Failed to enable TX: %s\n", bladerf_strerror(status));
        goto out;
    }

    /** [enable_modules] */
    /** [rxtx_loop] */

    while (status == 0 && !done) {
        /* Receive samples */
        status = bladerf_sync_rx(dev, rx_samples, samples_len, NULL, 5000);
        if (status == 0) {
            /* Process these samples, and potentially produce a response
             * to transmit */
            done = do_work(rx_samples, samples_len, &have_tx_data, tx_samples,
                           samples_len);

            if (!done && have_tx_data) {
                /* Transmit a response */
                status =
                    bladerf_sync_tx(dev, tx_samples, samples_len, NULL, 5000);

                if (status != 0) {
                    fprintf(stderr, "Failed to TX samples: %s\n",
                            bladerf_strerror(status));
                }
            }
        } else {
            fprintf(stderr, "Failed to RX samples: %s\n",
                    bladerf_strerror(status));
        }
    }

    if (status == 0) {
        /* Wait a few seconds for any remaining TX samples to finish
         * reaching the RF front-end */
        usleep(2000000);
    }

/** [rxtx_loop] */

out:
    ret = status;

    /** [disable_modules] */

    /* Disable RX, shutting down our underlying RX stream */
    status = bladerf_enable_module(dev, BLADERF_RX, false);
    if (status != 0) {
        fprintf(stderr, "Failed to disable RX: %s\n", bladerf_strerror(status));
    }

    /* Disable TX, shutting down our underlying TX stream */
    status = bladerf_enable_module(dev, BLADERF_TX, false);
    if (status != 0) {
        fprintf(stderr, "Failed to disable TX: %s\n", bladerf_strerror(status));
    }


    /* Free up our resources */
    free(rx_samples);
    free(tx_samples);

    /** [disable_modules] */

    return ret;
}
Example #20
0
int calibrate_dc(struct cli_state *s, unsigned int ops)
{
    int retval = 0;
    int status = BLADERF_ERR_UNEXPECTED;
    struct settings rx_settings, tx_settings;
    bladerf_loopback loopback;
    int16_t dc_i, dc_q;

    if (IS_RX_CAL(ops)) {
        status = backup_and_update_settings(s->dev, BLADERF_MODULE_RX,
                                            &rx_settings);
        if (status != 0) {
            s->last_lib_error = status;
            return CLI_RET_LIBBLADERF;
        }
    }

    if (IS_TX_CAL(ops)) {
        status = backup_and_update_settings(s->dev, BLADERF_MODULE_TX,
                                            &tx_settings);
        if (status != 0) {
            s->last_lib_error = status;
            return CLI_RET_LIBBLADERF;
        }
    }

    status = bladerf_get_loopback(s->dev, &loopback);
    if (status != 0) {
        s->last_lib_error = status;
        return CLI_RET_LIBBLADERF;
    }

    if (IS_RX_CAL(ops)) {
        status = set_rx_dc(s->dev, 0, 0);
        if (status != 0) {
            goto error;
        }

        status = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, true);
        if (status != 0) {
            goto error;
        }
    }

    if (IS_TX_CAL(ops)) {
        status = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, true);
        if (status != 0) {
            goto error;
        }

        status = bladerf_set_loopback(s->dev, BLADERF_LB_BB_TXVGA1_RXVGA2);
        if (status != 0) {
            goto error;
        }

        status = bladerf_enable_module(s->dev, BLADERF_MODULE_TX, true);
        if (status != 0) {
            goto error;
        }

        status = dummy_tx(s->dev);
        if (status != 0) {
            goto error;
        }

        status = bladerf_enable_module(s->dev, BLADERF_MODULE_TX, false);
        if (status != 0) {
            goto error;
        }
    }

    status = bladerf_set_loopback(s->dev, BLADERF_LB_NONE);
    if (status != 0) {
        goto error;
    }

    putchar('\n');

    if (IS_CAL(CAL_DC_LMS_TUNING, ops)) {
        printf("  Calibrating LMS LPF tuning module...\n");
        status = bladerf_calibrate_dc(s->dev, BLADERF_DC_CAL_LPF_TUNING);
        if (status != 0) {
            goto error;
        } else {
            struct bladerf_lms_dc_cals dc_cals;
            status = bladerf_lms_get_dc_cals(s->dev, &dc_cals);
            if (status != 0) {
                goto error;
            }

            printf("    LPF tuning module: %d\n\n", dc_cals.lpf_tuning);
        }
    }

    if (IS_CAL(CAL_DC_LMS_TXLPF, ops)) {
        printf("  Calibrating LMS TX LPF modules...\n");
        status = bladerf_calibrate_dc(s->dev, BLADERF_DC_CAL_TX_LPF);
        if (status != 0) {
            goto error;
        } else {
            struct bladerf_lms_dc_cals dc_cals;
            status = bladerf_lms_get_dc_cals(s->dev, &dc_cals);
            if (status != 0) {
                goto error;
            }

            printf("    TX LPF I filter: %d\n", dc_cals.tx_lpf_i);
            printf("    TX LPF Q filter: %d\n\n", dc_cals.tx_lpf_q);
        }
    }

    if (IS_CAL(CAL_DC_LMS_RXLPF, ops)) {
        printf("  Calibrating LMS RX LPF modules...\n");
        status = bladerf_calibrate_dc(s->dev, BLADERF_DC_CAL_RX_LPF);
        if (status != 0) {
            goto error;
        } else {
            struct bladerf_lms_dc_cals dc_cals;
            status = bladerf_lms_get_dc_cals(s->dev, &dc_cals);
            if (status != 0) {
                goto error;
            }

            printf("    RX LPF I filter: %d\n", dc_cals.rx_lpf_i);
            printf("    RX LPF Q filter: %d\n\n", dc_cals.rx_lpf_q);
        }
    }

    if (IS_CAL(CAL_DC_LMS_RXVGA2, ops)) {
        printf("  Calibrating LMS RXVGA2 modules...\n");
        status = bladerf_calibrate_dc(s->dev, BLADERF_DC_CAL_RXVGA2);
        if (status != 0) {
            goto error;
        } else {
            struct bladerf_lms_dc_cals dc_cals;
            status = bladerf_lms_get_dc_cals(s->dev, &dc_cals);
            if (status != 0) {
                goto error;
            }

            printf("    RX VGA2 DC reference module: %d\n", dc_cals.dc_ref);
            printf("    RX VGA2 stage 1, I channel: %d\n", dc_cals.rxvga2a_i);
            printf("    RX VGA2 stage 1, Q channel: %d\n", dc_cals.rxvga2a_q);
            printf("    RX VGA2 stage 2, I channel: %d\n", dc_cals.rxvga2b_i);
            printf("    RX VGA2 stage 2, Q channel: %d\n\n", dc_cals.rxvga2b_q);
        }
    }


    if (IS_CAL(CAL_DC_AUTO_RX, ops)) {
        int16_t avg_i, avg_q;
        status = calibrate_dc_rx(s, &dc_i, &dc_q, &avg_i, &avg_q);
        if (status != 0) {
            goto error;
        } else {
            printf("  RX DC I Setting = %d, error ~= %d\n", dc_i, avg_i);
            printf("  RX DC Q Setting = %d, error ~= %d\n\n", dc_q, avg_q);
        }
    }

    if (IS_CAL(CAL_DC_AUTO_TX, ops)) {
        float error_i, error_q;
        status = calibrate_dc_tx(s, &dc_i, &dc_q, &error_i, &error_q);
        if (status != 0) {
            goto error;
        } else {
            printf("  TX DC I Setting = %d, error ~= %f\n", dc_i, error_i);
            printf("  TX DC Q Setting = %d, error ~= %f\n\n", dc_q, error_q);
        }
    }

error:
    retval = status;

    if (IS_RX_CAL(ops)) {
        status = restore_settings(s->dev, BLADERF_MODULE_RX, &rx_settings);
        retval = first_error(retval, status);
    }


    if (IS_TX_CAL(ops)) {
        status = restore_settings(s->dev, BLADERF_MODULE_TX, &tx_settings);
        retval = first_error(retval, status);
    }

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, false);
    retval = first_error(retval, status);

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_TX, false);
    retval = first_error(retval, status);

    status = bladerf_set_loopback(s->dev, loopback);
    retval = first_error(retval, status);

    if (retval != 0) {
        s->last_lib_error = retval;
        retval = CLI_RET_LIBBLADERF;
    }

    return retval;
}
Example #21
0
/* See libbladeRF's dc_cal_table.c for the packed table data format */
int calibrate_dc_gen_tbl(struct cli_state *s, bladerf_module module,
                         const char *filename, unsigned int f_low,
                         unsigned f_inc, unsigned int f_high)
{
    int retval, status;
    size_t off;
    struct bladerf_lms_dc_cals lms_dc_cals;
    unsigned int f;
    struct settings settings;
    bladerf_loopback loopback_backup;
    struct bladerf_image *image = NULL;

    const uint16_t magic = HOST_TO_LE16(0x1ab1);
    const uint32_t reserved = HOST_TO_LE32(0x00000000);
    const uint32_t tbl_version = HOST_TO_LE32(0x00000001);

    const size_t lms_data_size = 10; /* 10 uint8_t register values */

    const uint32_t n_frequencies = (f_high - f_low) / f_inc + 1;
    const uint32_t n_frequencies_le = HOST_TO_LE32(n_frequencies);

    const size_t entry_size = sizeof(uint32_t) +   /* Frequency */
                              2 * sizeof(int16_t); /* DC I and Q valus */

    const size_t table_size = n_frequencies * entry_size;

    const size_t data_size = sizeof(magic) + sizeof(reserved) +
                             sizeof(tbl_version) + sizeof(n_frequencies_le) +
                             lms_data_size + table_size;

    assert(data_size <= UINT_MAX);

    status = backup_and_update_settings(s->dev, module, &settings);
    if (status != 0) {
        return status;
    }

    status = bladerf_get_loopback(s->dev, &loopback_backup);
    if (status != 0) {
        return status;
    }

    status = bladerf_lms_get_dc_cals(s->dev, &lms_dc_cals);
    if (status != 0) {
        goto out;
    }

    if (module == BLADERF_MODULE_RX) {
        image = bladerf_alloc_image(BLADERF_IMAGE_TYPE_RX_DC_CAL,
                                    0xffffffff, (unsigned int) data_size);
    } else {
        image = bladerf_alloc_image(BLADERF_IMAGE_TYPE_TX_DC_CAL,
                                    0xffffffff, (unsigned int) data_size);
    }

    if (image == NULL) {
        status = BLADERF_ERR_MEM;
        goto out;
    }

    status = bladerf_get_serial(s->dev, image->serial);
    if (status != 0) {
        goto out;
    }

    if (module == BLADERF_MODULE_RX) {
        status = bladerf_set_loopback(s->dev, BLADERF_LB_NONE);
        if (status != 0) {
            goto out;
        }
    }

    off = 0;

    memcpy(&image->data[off], &magic, sizeof(magic));
    off += sizeof(magic);

    memcpy(&image->data[off], &reserved, sizeof(reserved));
    off += sizeof(reserved);

    memcpy(&image->data[off], &tbl_version, sizeof(tbl_version));
    off += sizeof(tbl_version);

    memcpy(&image->data[off], &n_frequencies_le, sizeof(n_frequencies_le));
    off += sizeof(n_frequencies_le);

    image->data[off++] = (uint8_t)lms_dc_cals.lpf_tuning;
    image->data[off++] = (uint8_t)lms_dc_cals.tx_lpf_i;
    image->data[off++] = (uint8_t)lms_dc_cals.tx_lpf_q;
    image->data[off++] = (uint8_t)lms_dc_cals.rx_lpf_i;
    image->data[off++] = (uint8_t)lms_dc_cals.rx_lpf_q;
    image->data[off++] = (uint8_t)lms_dc_cals.dc_ref;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2a_i;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2a_q;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2b_i;
    image->data[off++] = (uint8_t)lms_dc_cals.rxvga2b_q;

    putchar('\n');

    for (f = f_low; f <= f_high; f += f_inc) {
        const uint32_t frequency = HOST_TO_LE32((uint32_t)f);
        int16_t dc_i, dc_q;

        printf("  Calibrating @ %u Hz...", f);

        status = bladerf_set_frequency(s->dev, module, f);
        if (status != 0) {
            goto out;
        }

        if (module == BLADERF_MODULE_RX) {
            int16_t error_i, error_q;
            status = calibrate_dc_rx(s, &dc_i, &dc_q, &error_i, &error_q);
            printf("    I=%-4d (avg: %-4d), Q=%-4d (avg: %-4d)\r",
                    dc_i, error_i, dc_q, error_q);
        } else {
            float error_i, error_q;
            status = calibrate_dc_tx(s, &dc_i, &dc_q, &error_i, &error_q);
            printf("    I=%-4d (avg: %3.3f), Q=%-4d (avg: %3.3f)\r",
                    dc_i, error_i, dc_q, error_q);
        }

        if (status != 0) {
            goto out;
        }

        fflush(stdout);

        dc_i = HOST_TO_LE16(dc_i);
        dc_q = HOST_TO_LE16(dc_q);

        memcpy(&image->data[off], &frequency, sizeof(frequency));
        off += sizeof(frequency);

        memcpy(&image->data[off], &dc_i, sizeof(dc_i));
        off += sizeof(dc_i);

        memcpy(&image->data[off], &dc_q, sizeof(dc_q));
        off += sizeof(dc_q);
    }

    status = bladerf_image_write(image, filename);

    printf("\n  Done.\n\n");

out:
    retval = status;

    if (module == BLADERF_MODULE_RX) {
        status = bladerf_set_loopback(s->dev, loopback_backup);
        retval = first_error(retval, status);
    }

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, false);
    retval = first_error(retval, status);

    status = restore_settings(s->dev, module, &settings);
    retval = first_error(retval, status);

    bladerf_free_image(image);
    return retval;
}
Example #22
0
/* FIXME Clean up this function up. It's very unreadable.
 *       Suggestions include moving to switch() and possibly adding some
 *       intermediary states. (More smaller, simpler states);
 */
static void *rx_task(void *arg) {
    int lib_ret, write_ret;
    enum rxtx_state state, prev_state;
    struct cli_state *s = (struct cli_state *) arg;
    struct rx_cfg *rx = &s->rxtx_data->rx;
    unsigned int n_samples_left = 0;
    bool inf = false;
    size_t to_write = 0;

    /* We expect to be in the IDLE state when this task is kicked off */
    state = prev_state = get_state(&rx->common);
    assert(state == RXTX_STATE_IDLE || state == RXTX_STATE_SHUTDOWN);

    while (state != RXTX_STATE_SHUTDOWN) {
        if (state == RXTX_STATE_RUNNING) {

            /* Transitioning from IDLE/ERROR -> RUNNING */
            if (prev_state == RXTX_STATE_IDLE ||
                prev_state == RXTX_STATE_ERROR) {

                pthread_mutex_lock(&rx->common.param_lock);
                n_samples_left = rx->n_samples;
                pthread_mutex_unlock(&rx->common.param_lock);

                inf = n_samples_left == 0;

                /* Task owns file while running */
                pthread_mutex_lock(&rx->common.file_lock);

                /* Flush out any old samples before recording any data */
                /*lib_ret = bladerf_read_c16(s->dev, rx->common.buff,
                                                   rx->common.buff_size / 2);*/
                lib_ret = bladerf_rx(
                            s->dev,
                            BLADERF_FORMAT_SC16_Q12,
                            rx->common.buff,
                            rx->common.buff_size/2,
                            NULL
                          );
                if (lib_ret < 0) {
                    set_last_error(&rx->common.error, ETYPE_BLADERF, lib_ret);
                    state = RXTX_STATE_ERROR;
                }
            } else {
                /*lib_ret = bladerf_read_c16(s->dev, rx->common.buff,
                                           rx->common.buff_size / 2);*/

                lib_ret = bladerf_rx(
                            s->dev,
                            BLADERF_FORMAT_SC16_Q12,
                            rx->common.buff,
                            rx->common.buff_size/2,
                            NULL
                          );
                if (lib_ret < 0) {
                    set_last_error(&rx->common.error, ETYPE_BLADERF, lib_ret);
                    state = RXTX_STATE_ERROR;
                } else {

                    /* Bug catcher */
                    assert((size_t)lib_ret <= (rx->common.buff_size / 2));

                    if (!inf) {
                        to_write = uint_min(n_samples_left, lib_ret);
                    } else {
                        to_write = rx->common.buff_size / 2;
                    }

                    write_ret = rx->write_samples(s, to_write);

                    if (write_ret < 0) {
                        /* write_samples will have set the last error info */
                        state = RXTX_STATE_ERROR;
                    } else if (!inf) {
                        n_samples_left -= to_write;
                        if (n_samples_left == 0) {
                            state = RXTX_STATE_IDLE;
                        }
                    }
                }
            }

        }

        if (state != RXTX_STATE_RUNNING && prev_state == RXTX_STATE_RUNNING) {
            /* Clean up as we transition from RUNNING -> <any other state> */
            lib_ret = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, false);
            close_samples_file(&rx->common, false);
            pthread_mutex_unlock(&rx->common.file_lock);

            if (lib_ret < 0) {
                set_last_error(&rx->common.error, ETYPE_BLADERF, lib_ret);
                state = RXTX_STATE_ERROR;
            }

            set_state(&rx->common, state, false);
        }


        prev_state = state;

        /* Wait here while if we're in the IDLE/ERROR states */
        pthread_mutex_lock(&rx->common.task_lock);
        while (state == RXTX_STATE_IDLE || state == RXTX_STATE_ERROR) {
            pthread_cond_wait(&rx->common.task_state_changed,
                                &rx->common.task_lock);

            state = rx->common.task_state;
        }

        state = rx->common.task_state;
        pthread_mutex_unlock(&rx->common.task_lock);
    }

    return NULL;
}
Example #23
0
int calibrate_dc_rx(struct cli_state *s,
                    int16_t *dc_i, int16_t *dc_q,
                    int16_t *avg_i, int16_t *avg_q)
{
    int status;
    int16_t *samples = NULL;
    int16_t dc_i0, dc_q0, dc_i1, dc_q1;
    int16_t avg_i0, avg_q0, avg_i1, avg_q1;

    int16_t test_i[7], test_q[7];
    int16_t tmp_i, tmp_q, min_i, min_q;
    unsigned int min_i_idx, min_q_idx, n;

    samples = (int16_t*) malloc(CAL_BUF_LEN * 2 * sizeof(samples[0]));
    if (samples == NULL) {
        status = BLADERF_ERR_MEM;;
        goto out;
    }

    /* Ensure old samples are flushed */
    status = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, false);
    if (status != 0) {
        goto out;
    }


    status = bladerf_sync_config(s->dev, BLADERF_MODULE_RX,
                                 BLADERF_FORMAT_SC16_Q11,
                                 CAL_NUM_BUFS, CAL_BUF_LEN,
                                 CAL_NUM_XFERS, CAL_TIMEOUT);
    if (status != 0) {
        goto out;
    }

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, true);
    if (status != 0) {
        goto out;
    }

    dc_i0 = dc_q0 = -512;
    dc_i1 = dc_q1 = 512;

    /* Get an initial set of sample points */
    status = set_rx_dc(s->dev, dc_i0, dc_q0);
    if (status != 0) {
        goto out;
    }

    status = rx_avg(s->dev, samples, &avg_i0, &avg_q0);
    if (status != 0) {
        goto out;
    }

    status = set_rx_dc(s->dev, dc_i1, dc_q1);
    if (status != 0) {
        goto out;
    }

    status = rx_avg(s->dev, samples, &avg_i1, &avg_q1);
    if (status != 0) {
        goto out;
    }

    status = interpolate(dc_i0, dc_i1, avg_i0, avg_i1, dc_i);
    if (status != 0) {
        cli_err(s, "Error", "RX I values appear to be stuck @ %d\n", avg_i0);
        goto out;
    }

    status = interpolate(dc_q0, dc_q1, avg_q0, avg_q1, dc_q);
    if (status != 0) {
        cli_err(s, "Error", "RX Q values appear to be stuck @ %d\n", avg_q0);
        goto out;
    }

    test_i[0] = *dc_i;
    test_i[1] = test_i[0] + 96;
    test_i[2] = test_i[0] + 64;
    test_i[3] = test_i[0] + 32;
    test_i[4] = test_i[0] - 32;
    test_i[5] = test_i[0] - 64;
    test_i[6] = test_i[0] - 96;

    test_q[0] = *dc_q;
    test_q[1] = test_q[0] + 96;
    test_q[2] = test_q[0] + 64;
    test_q[3] = test_q[0] + 32;
    test_q[4] = test_q[0] - 32;
    test_q[5] = test_q[0] - 64;
    test_q[6] = test_q[0] - 96;

    min_i_idx = min_q_idx = 0;
    min_i = min_q = INT16_MAX;

    for (n = 0; n < 7; n++) {

        if (test_i[n] > CAL_DC_MAX) {
            test_i[n] = CAL_DC_MAX;
        } else if (test_i[n] < CAL_DC_MIN) {
            test_i[n] = CAL_DC_MIN;
        }

        if (test_q[n] > CAL_DC_MAX) {
            test_q[n] = CAL_DC_MAX;
        } else if (test_q[n] < CAL_DC_MIN) {
            test_q[n] = CAL_DC_MIN;
        }

        /* See where we're at now... */
        status = set_rx_dc(s->dev, test_i[n], test_q[n]);
        if (status != 0) {
            goto out;
        }

        status = rx_avg(s->dev, samples, &tmp_i, &tmp_q);
        if (status != 0) {
            goto out;
        }

        if (abs(tmp_i) < abs(min_i)) {
            min_i = tmp_i;
            min_i_idx = n;
        }

        if (abs(tmp_q) < abs(min_q)) {
            min_q = tmp_q;
            min_q_idx = n;
        }
    }

    *dc_i = test_i[min_i_idx];
    *dc_q = test_q[min_q_idx];

    if (avg_i) {
        *avg_i = min_i;
    }

    if (avg_q) {
        *avg_q = min_q;
    }

    status = set_rx_dc(s->dev, *dc_i, *dc_q);
    if (status != 0) {
        goto out;
    }

out:
    free(samples);
    return status;
}
Example #24
0
static inline int setup_device(struct test *t)
{
    int status;
    struct bladerf *dev = t->dev;

#if !DISABLE_RX_LOOPBACK
    status = bladerf_set_loopback(dev, BLADERF_LB_BB_TXVGA1_RXVGA2);
    if (status != 0) {
        fprintf(stderr, "Failed to set loopback mode: %s\n",
                bladerf_strerror(status));
        return status;
    }
#endif

    status = bladerf_set_lna_gain(dev, BLADERF_LNA_GAIN_MAX);
    if (status != 0) {
        fprintf(stderr, "Failed to set LNA gain value: %s\n",
                bladerf_strerror(status));
        return status;
    }

    status = bladerf_set_rxvga1(dev, 30);
    if (status != 0) {
        fprintf(stderr, "Failed to set RXVGA1 value: %s\n",
                bladerf_strerror(status));
        return status;
    }

    status = bladerf_set_rxvga2(dev, 10);
    if (status != 0) {
        fprintf(stderr, "Failed to set RXVGA2 value: %s\n",
                bladerf_strerror(status));
        return status;
    }

    status = bladerf_set_txvga1(dev, -10);
    if (status != 0) {
        fprintf(stderr, "Failed to set TXVGA1 value: %s\n",
                bladerf_strerror(status));
        return status;
    }

    status = bladerf_set_txvga2(dev, BLADERF_TXVGA2_GAIN_MIN);
    if (status != 0) {
        fprintf(stderr, "Failed to set TXVGA2 value: %s\n",
                bladerf_strerror(status));
        return status;
    }


    status = bladerf_sync_config(t->dev, BLADERF_MODULE_RX,
                                 BLADERF_FORMAT_SC16_Q11_META,
                                 t->params->num_buffers,
                                 t->params->buf_size,
                                 t->params->num_xfers,
                                 t->params->timeout_ms);
    if (status != 0) {
        fprintf(stderr, "Failed to configure RX stream: %s\n",
                bladerf_strerror(status));
        return status;
    }

    status = bladerf_enable_module(t->dev, BLADERF_MODULE_RX, true);
    if (status != 0) {
        fprintf(stderr, "Failed to enable RX module: %s\n",
                bladerf_strerror(status));
        return status;

    }

    status = bladerf_sync_config(t->dev, BLADERF_MODULE_TX,
                                 BLADERF_FORMAT_SC16_Q11_META,
                                 t->params->num_buffers,
                                 t->params->buf_size,
                                 t->params->num_xfers,
                                 t->params->timeout_ms);
    if (status != 0) {
        fprintf(stderr, "Failed to configure TX stream: %s\n",
                bladerf_strerror(status));
        return status;
    }

    status = bladerf_enable_module(t->dev, BLADERF_MODULE_TX, true);
    if (status != 0) {
        fprintf(stderr, "Failed to enable RX module: %s\n",
                bladerf_strerror(status));
        return status;

    }


    return status;
}
Example #25
0
/* Initialization and stuff
 */
int main(int argc, char **argv)
{
	struct bladerf_devinfo *devs;
	struct sigaction sigact;
	struct devinfo_s device;
	int show_help = false;
	int n, ret;
	char ch;

	/* Set up default values, bandwidth and num_transfers
	 * are automatically calculated later */
	device.device_id = DEFAULT_DEVICE_ID;
	device.frequency = DEFAULT_FREQUENCY;
	device.samplerate = DEFAULT_SAMPLERATE;
	device.bandwidth = 0;
	device.txvga1 = DEFAULT_TXVGA1;
	device.txvga2 = DEFAULT_TXVGA2;

	device.buffers.gain = DEFAULT_GAIN;
	device.buffers.again = DEFAULT_AGAIN;
	device.buffers.num_buffers = DEFAULT_BUFFERS;
	device.buffers.num_samples = DEFAULT_SAMPLES;
	device.buffers.num_transfers = 0;
	device.buffers.pos = 0;

	/* Evaluate command line options */
	while((ch = getopt(argc, argv, "hd:f:r:b:g:G:a:m:n:s:t:")) != -1)
	{
		switch(ch)
		{
			case 'd':
				device.device_id = optarg; break;
			case 'f':
				device.frequency = atoi(optarg); break;
			case 'r':
				device.samplerate = atoi(optarg); break;
			case 'b':
				device.bandwidth = atoi(optarg); break;
			case 'g':
				device.txvga1 = atoi(optarg); break;
			case 'G':
				device.txvga2 = atoi(optarg); break;
			case 'm':
				device.buffers.gain = atof(optarg); break;
			case 'a':
				device.buffers.again = atof(optarg); break;
			case 'n':
				device.buffers.num_buffers = atoi(optarg); break;
			case 's':
				device.buffers.num_samples = atoi(optarg); break;
			case 't':
				device.buffers.num_transfers = atoi(optarg); break;
			case 'h':
			default:
				show_help = true;
		}
	}

	/* Now calculate bandwidth and num_transfers if the user didn't
	 * configure them manually */
	if(device.bandwidth == 0)
		device.bandwidth = device.samplerate * 3 / 4;
	if(device.buffers.num_transfers == 0)
		device.buffers.num_transfers = device.buffers.num_buffers / 2;

	if(show_help)
	{
		usage(argv[0], &device);
		return EXIT_FAILURE;
	}
	
	argc -= optind;
	argv += optind;

	/* Allocate the float input buffer */
	device.buffers.fbuf =
		malloc(device.buffers.num_samples * 2 * sizeof(float));
	
	/* Set up signal handler to enable clean shutdowns */
	sigact.sa_handler = sighandler;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);
	sigaction(SIGPIPE, &sigact, NULL);



	/* Look for devices attached */
	ret = bladerf_get_device_list(&devs);
	if(ret < 1)
	{
		fprintf(stderr, "No devices found.\n");
		return EXIT_FAILURE;
	}

	/* Print some information about all the devices */
	for(n = 0; n < ret; n++)
	{
		fprintf(stderr, 
			"Serial:\t%s\n"
			"USB bus:\t%i\n"
			"USB address:\t%i\n"
			"Instance:\t%i\n\n",
			devs[n].serial,
			devs[n].usb_bus,
			devs[n].usb_addr,
			devs[n].instance
		);
	}

	/* the list is not needed any more */
	bladerf_free_device_list(devs);



	/* Open a device by given device string
	 */
	ret = bladerf_open(&device.dev, device.device_id);
	if(ret != 0)
	{
		fprintf(stderr, "Error opening device %s: %s.\n",
			device.device_id, bladerf_strerror(ret));
		goto out0;
	}
	else
	{
		fprintf(stderr, "Device \"%s\" opened successfully.\n",
			device.device_id);
	}

	/* Set the device parameters */
	ret = bladerf_set_sample_rate(device.dev,
		BLADERF_MODULE_TX, device.samplerate, &device.samplerate);
	if(ret != 0)
	{
		fprintf(stderr, "Error setting sample rate to %i: %s.\n",
			device.samplerate, bladerf_strerror(ret));
		goto out1;
	}
	else
	{
		fprintf(stderr, "Actual sample rate is %i.\n",
			device.samplerate);
	}

	ret = bladerf_set_frequency(device.dev,
		BLADERF_MODULE_TX, device.frequency);
	if(ret != 0)
	{
		fprintf(stderr, "Error setting frequency to %iHz: %s.\n",
			device.frequency, bladerf_strerror(ret));
		goto out1;
	}
	else
	{
		fprintf(stderr, "Frequency set to %iHz.\n", device.frequency);
	}

	ret = bladerf_set_txvga1(device.dev, device.txvga1);
	if(ret != 0)
	{
		fprintf(stderr, "Error setting gain for txvga1: %s.\n",
			bladerf_strerror(ret));
		goto out1;
	}

	ret = bladerf_set_txvga2(device.dev, device.txvga2);
	if(ret != 0)
	{
		fprintf(stderr, "Error setting gain for txvga2: %s.\n",
			bladerf_strerror(ret));
		goto out1;
	}

	ret = bladerf_set_bandwidth(device.dev,
		BLADERF_MODULE_TX, device.bandwidth, &device.bandwidth);
	if(ret != 0)
	{
		fprintf(stderr, "Error setting LPF bandwidth: %s.\n",
			bladerf_strerror(ret));
		goto out1;
	}
	else
	{
		fprintf(stderr, "Bandwidth set to %iHz.\n", device.bandwidth);
	}

	/* Set up the sample stream */
	ret = bladerf_init_stream(&device.stream,
		device.dev, stream_callback, &device.buffers.sbuf,
		device.buffers.num_buffers,	BLADERF_FORMAT_SC16_Q12,
		device.buffers.num_samples, device.buffers.num_transfers,
		&device.buffers);
	if(ret != 0)
	{
		fprintf(stderr, "Failed setting up stream: %s.\n",
			bladerf_strerror(ret));
		goto out1;
	}
	

	/* Finally enable TX... */
	ret = bladerf_enable_module(device.dev, BLADERF_MODULE_TX, true);
	if(ret != 0)
	{
		fprintf(stderr, "Error enabling TX module: %s.\n",
			bladerf_strerror(ret));
		goto out1;
	}
	else
	{
		fprintf(stderr, "Successfully enabled TX module.\n");
	}

	/* ...and start the stream.
	 * Execution stops here until stream has finished. */
	ret = bladerf_stream(device.stream, BLADERF_MODULE_TX);
	if(ret != 0)
	{
		fprintf(stderr, "Failed starting stream: %s.\n",
			bladerf_strerror(ret));
		goto out2;
	}


	/* Cleanup the mess */
out2:
	bladerf_deinit_stream(device.stream);

out1:
	ret = bladerf_enable_module(device.dev, BLADERF_MODULE_TX, false);
	if(ret != 0)
	{
		fprintf(stderr, "Error disabling TX module: %s.\n",
			bladerf_strerror(ret));
	}
	else
	{
		fprintf(stderr, "Successfully disabled TX module.\n");
	}
	
	bladerf_close(device.dev);
	fprintf(stderr, "Device closed.\n");
	
out0:
	return EXIT_SUCCESS;
}
Example #26
0
/** [tx_meta_init] */
int16_t * init(struct bladerf *dev, int16_t num_samples)
{
    int status = -1;

    /* "User" buffer that we store our modulated samples in, and its
     * associated size, in units of samples. Recall that for the
     * SC16Q11 format (native to the ADCs), one sample = two int16_t values.
     *
     * When using the bladerf_sync_* functions, the buffer size isn't
     * restricted to multiples of any particular size.
     *
     * The value for `num_samples` has no major restrictions here, while the
     * `buffer_size` below must be a multiple of 1024.
     */
    int16_t *samples;

    /* These items configure the underlying asynch stream used by the the sync
     * interface. The "buffer" here refers to those used internally by worker
     * threads, not the `samples` buffer above. */
    const unsigned int num_buffers = 32;
    const unsigned int buffer_size = 2048;
    const unsigned int num_transfers = 16;
    const unsigned int timeout_ms  = 1000;

    samples = malloc(num_samples * 2 * sizeof(int16_t));
    if (samples == NULL) {
        perror("malloc");
        goto error;
    }

    /** [sync_config] */

    /* Configure the device's TX module for use with the sync interface.
     * SC16 Q11 samples *with* metadata are used. */
    status = bladerf_sync_config(dev,
                                 BLADERF_MODULE_TX,
                                 BLADERF_FORMAT_SC16_Q11_META,
                                 num_buffers,
                                 buffer_size,
                                 num_transfers,
                                 timeout_ms);

    if (status != 0) {
        fprintf(stderr, "Failed to configure TX sync interface: %s\n",
                bladerf_strerror(status));

        goto error;
    }

    /** [sync_config] */

    /* We must always enable the TX module *after* calling
     * bladerf_sync_config(), and *before* attempting to TX samples via
     * bladerf_sync_tx(). */
    status = bladerf_enable_module(dev, BLADERF_MODULE_TX, true);
    if (status != 0) {
        fprintf(stderr, "Failed to enable TX module: %s\n",
                bladerf_strerror(status));

        goto error;
    }

    status = 0;

error:
    if (status != 0) {
        free(samples);
        samples = NULL;
    }

    return samples;
}
Example #27
0
/* FIXME Clean up this function up. It's very unreadable.
 *       Suggestions include moving to switch() and possibly adding some
 *       intermediary states. (More smaller, simpler states);
 */
static void *tx_task(void *arg) {
    enum rxtx_state state, prev_state;
    struct cli_state *s = (struct cli_state *) arg;
    struct tx_cfg *tx = &s->rxtx_data->tx;
    ssize_t read_ret;
    int lib_ret;
    unsigned int last_repeats_left;
    unsigned int repeats_left = 0;
    unsigned int repeat_delay = 0;
    bool repeats_inf = false;


    /* We expect to be in the IDLE state when this task is kicked off */
    state = prev_state = get_state(&tx->common);
    assert(state == RXTX_STATE_IDLE || state == RXTX_STATE_SHUTDOWN);

    while (state != RXTX_STATE_SHUTDOWN) {

        if (state == RXTX_STATE_RUNNING) {

            /* Transitioning from IDLE/ERROR -> RUNNING */
            if (prev_state == RXTX_STATE_IDLE ||
                prev_state == RXTX_STATE_ERROR) {

                pthread_mutex_lock(&tx->common.param_lock);
                repeats_left = tx->repeat;
                repeat_delay = tx->repeat_delay;
                pthread_mutex_unlock(&tx->common.param_lock);

                repeats_inf = repeats_left == 0;

                /* Task owns the file while running */
                pthread_mutex_lock(&tx->common.file_lock);

            } else {

                /* Fetch samples to write */
                last_repeats_left = repeats_left;
                read_ret = tx->read_samples(s, &repeats_left);

                if (read_ret == (2 * LIBBLADERF_SAMPLE_BLOCK_SIZE) ||
                    read_ret == 0) {

                    if (read_ret != 0) {
                        /*
                        lib_ret = bladerf_send_c16(s->dev,
                                                   tx->common.buff,
                                                   tx->common.buff_size / 2);
                        */
                        lib_ret = bladerf_tx(
                                    s->dev,
                                    BLADERF_FORMAT_SC16_Q12,
                                    tx->common.buff,
                                    tx->common.buff_size/2,
                                    NULL
                                  );
                        if (lib_ret < 0) {
                            set_last_error(&tx->common.error,
                                    ETYPE_BLADERF, lib_ret);
                            state = RXTX_STATE_ERROR;
                        }
                    }

                    if (repeats_inf || repeats_left != 0) {
                        if (repeats_left != last_repeats_left &&
                            repeat_delay) {

                            /* Currently seeing timeouts from the driver when
                             * attempting to disable/enable TX here...
                             *
                             * FIXME re-enable this after driver issues are
                             *       resolved...
                             */
#if 0
                            lib_ret = bladerf_enable_module(s->dev, TX, false);
                            if (lib_ret < 0) {
                                set_last_error(&tx->common.error,
                                                ETYPE_BLADERF, lib_ret);
                                state = RXTX_STATE_ERROR;
                            } else {
#endif
                                /* TODO replace with 0-send here for better
                                 * accuracy, as usleep isn't sufficient here */

                                usleep(repeat_delay);
#if 0

                                lib_ret = bladerf_enable_module(s->dev, TX,
                                                                true);
                                if (lib_ret < 0) {
                                    set_last_error(&tx->common.error,
                                            ETYPE_BLADERF, lib_ret);
                                    state = RXTX_STATE_ERROR;
                                }
                            }
#endif
                        }
                    } else {
                        state = RXTX_STATE_IDLE;
                    }

                } else {
                    /* Reads of an in-between size are a bug */
                    assert(read_ret <= 0);

                    /* read-samples will have filled out "last error" */
                    state = RXTX_STATE_ERROR;
                }
            }

        }

        /* Clean up as we transition from RUNNING -> <any other state> */
        if (state != RXTX_STATE_RUNNING && prev_state == RXTX_STATE_RUNNING) {
            lib_ret = bladerf_enable_module(s->dev, BLADERF_MODULE_TX, false);
            close_samples_file(&tx->common, false);
            pthread_mutex_unlock(&tx->common.file_lock);

            if (lib_ret < 0) {
                set_last_error(&tx->common.error, ETYPE_BLADERF, lib_ret);
                state = RXTX_STATE_ERROR;
            }

            set_state(&tx->common, state, false);
        }

        prev_state = state;

        /* Wait here while if we're in the IDLE/ERROR states */
        pthread_mutex_lock(&tx->common.task_lock);
        while (state == RXTX_STATE_IDLE || state == RXTX_STATE_ERROR) {
            pthread_cond_wait(&tx->common.task_state_changed,
                                &tx->common.task_lock);

            state = tx->common.task_state;
        }

        state = tx->common.task_state;
        pthread_mutex_unlock(&tx->common.task_lock);
    }

    return NULL;
}
Example #28
0
int main(int argc, char *argv[])
{
    int status = 0;
    struct rc_config rc;
    struct cli_state *state;
    bool exit_immediately = false;

    /* If no actions are specified, just show the usage text and exit */
    if (argc == 1) {
        usage(argv[0]);
        return 0;
    }

    init_rc_config(&rc);

    if (get_rc_config(argc, argv, &rc)) {
        return 1;
    }

    state = cli_state_create();

    if (!state) {
        fprintf(stderr, "Failed to create state object\n");
        return 1;
    }

    bladerf_log_set_verbosity(rc.verbosity);

    if (rc.show_help) {
        usage(argv[0]);
        exit_immediately = true;
    } else if (rc.show_version) {
        printf(BLADERF_CLI_VERSION "\n");
        exit_immediately = true;
    } else if (rc.show_lib_version) {
        struct bladerf_version version;
        bladerf_version(&version);
        printf("%s\n", version.describe);
        exit_immediately = true;
    } else if (rc.probe) {
        status = cmd_handle(state, "probe");
        exit_immediately = true;
    }

    if (!exit_immediately) {
        /* Conditionally performed items, depending on runtime config */
        status = open_device(&rc, state, status);
        if (status) {
            fprintf(stderr, "Could not open device\n");
            goto main__issues ;
        }

        status = flash_fw(&rc, state, status);
        if (status) {
            fprintf(stderr, "Could not flash firmware\n");
            goto main__issues ;
        }

        status = load_fpga(&rc, state, status);
        if (status) {
            fprintf(stderr, "Could not load fpga\n");
            goto main__issues ;
        }

        status = open_script(&rc, state, status);
        if (status) {
            fprintf(stderr, "Could not load scripts\n");
            goto main__issues ;
        }

main__issues:
        /* These items are no longer needed */
        free(rc.device);
        rc.device = NULL;

        free(rc.fw_file);
        rc.fw_file = NULL;

        free(rc.fpga_file);
        rc.fpga_file = NULL;

        free(rc.script_file);
        rc.script_file = NULL;

        /* Drop into interactive mode or begin executing commands
         * from a script. If we're not requested to do either, exit cleanly */
        if (rc.interactive_mode || state->script != NULL) {
            status = start_threads(state);

            if (status < 0) {
                fprintf(stderr, "Failed to kick off threads\n");
            } else {
                status = interactive(state, !rc.interactive_mode);
                stop_threads(state);
            }

        }

        /* Ensure we exit with RX & TX disabled.
         * Can't do much about an error at this point anyway... */
        if (state->dev && bladerf_is_fpga_configured(state->dev)) {
            bladerf_enable_module(state->dev, BLADERF_MODULE_TX, false);
            bladerf_enable_module(state->dev, BLADERF_MODULE_RX, false);
        }
    }

    cli_state_destroy(state);
    return status;
}
Example #29
0
int test_fn_loopback_onoff(struct bladerf *dev, struct app_params *p)
{
    int status = 0;
    struct test test;
    pthread_t tx_thread;
    bool tx_started = false;

#if !DISABLE_RX_LOOPBACK
    pthread_t rx_thread;
    bool rx_started = false;
    bool rx_ready = false;
#endif

    test.dev = dev;
    test.params = p;
    test.num_bursts = 1000;
    test.stop = false;
    test.rx_ready = false;

    pthread_mutex_init(&test.lock, NULL);

    test.bursts = (struct burst *) malloc(test.num_bursts * sizeof(test.bursts[0]));
    if (test.bursts == NULL) {
        perror("malloc");
        return -1;
    } else {
        fill_bursts(&test);
    }

    status = setup_device(&test);
    if (status != 0) {
        goto out;
    }

    printf("Starting bursts...\n");

#if !DISABLE_RX_LOOPBACK
    status = pthread_create(&rx_thread, NULL, rx_task, &test);
    if (status != 0) {
        fprintf(stderr, "Failed to start RX thread: %s\n", strerror(status));
        goto out;
    } else {
        rx_started = true;
    }

    while (!rx_ready) {
        usleep(10000);
        pthread_mutex_lock(&test.lock);
        rx_ready = test.rx_ready;
        pthread_mutex_unlock(&test.lock);
    }
#endif

    status = pthread_create(&tx_thread, NULL, tx_task, &test);
    if (status != 0) {
        fprintf(stderr, "Failed to start TX thread: %s\n", strerror(status));
        goto out;
    } else {
        tx_started = true;
    }

out:
    if (tx_started) {
        pthread_join(tx_thread, NULL);
    }

#if !DISABLE_RX_LOOPBACK
    if (rx_started) {
        pthread_join(rx_thread, NULL);
    }
#endif

    free(test.bursts);

    bladerf_enable_module(dev, BLADERF_MODULE_RX, false);
    bladerf_enable_module(dev, BLADERF_MODULE_TX, false);
    bladerf_set_loopback(dev, BLADERF_LB_NONE);

    return status;
}
Example #30
0
int calibrate_dc_tx(struct cli_state *s,
                    int16_t *dc_i, int16_t *dc_q,
                    float *error_i, float *error_q)
{
    int retval, status;
    unsigned int rx_freq, tx_freq;
    int16_t *rx_samples = NULL;
    struct cal_tx_task tx_task;

    struct point p0, p1, p2, p3;
    struct point result;

    status = bladerf_get_frequency(s->dev, BLADERF_MODULE_RX, &rx_freq);
    if (status != 0) {
        return status;
    }

    status = bladerf_get_frequency(s->dev, BLADERF_MODULE_TX, &tx_freq);
    if (status != 0) {
        return status;
    }

    rx_samples = (int16_t*) malloc(CAL_BUF_LEN * 2 * sizeof(rx_samples[0]));
    if (rx_samples == NULL) {
        return BLADERF_ERR_MEM;
    }

    status = init_tx_task(s, &tx_task);
    if (status != 0) {
        goto out;

    }

    status = bladerf_set_frequency(s->dev, BLADERF_MODULE_TX,
                                   rx_freq + (CAL_SAMPLERATE / 4));
    if (status != 0) {
        goto out;
    }

    if (tx_freq < UPPER_BAND) {
        status = bladerf_set_loopback(s->dev, BLADERF_LB_RF_LNA1);
    } else {
        status = bladerf_set_loopback(s->dev, BLADERF_LB_RF_LNA2);
    }

    if (status != 0) {
        goto out;
    }

    /* Ensure old samples are flushed */
    status = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, false);
    if (status != 0) {
        goto out;
    }

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_TX, false);
    if (status != 0) {
        goto out;
    }

    status = bladerf_sync_config(s->dev, BLADERF_MODULE_RX,
                                 BLADERF_FORMAT_SC16_Q11,
                                 CAL_NUM_BUFS, CAL_BUF_LEN,
                                 CAL_NUM_XFERS, CAL_TIMEOUT);
    if (status != 0) {
        goto out;
    }

    status = bladerf_sync_config(s->dev, BLADERF_MODULE_TX,
                                 BLADERF_FORMAT_SC16_Q11,
                                 CAL_NUM_BUFS, CAL_BUF_LEN,
                                 CAL_NUM_XFERS, CAL_TIMEOUT);
    if (status != 0) {
        goto out;
    }

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_RX, true);
    if (status != 0) {
        goto out;
    }

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_TX, true);
    if (status != 0) {
        goto out;
    }

    status = start_tx_task(&tx_task);
    if (status != 0) {
        goto out;
    }

    /* Sample the results of 4 points, which should yield 2 intersecting lines,
     * for 4 different DC offset settings of the I channel */
    p0.x = -2048;
    p1.x = -512;
    p2.x = 512;
    p3.x = 2048;

    status = rx_avg_magnitude(s->dev, rx_samples, (int16_t) p0.x, 0, &p0.y);
    if (status != 0) {
        goto out;
    }

    status = rx_avg_magnitude(s->dev, rx_samples, (int16_t) p1.x, 0, &p1.y);
    if (status != 0) {
        goto out;
    }

    status = rx_avg_magnitude(s->dev, rx_samples, (int16_t) p2.x, 0, &p2.y);
    if (status != 0) {
        goto out;
    }

    status = rx_avg_magnitude(s->dev, rx_samples, (int16_t) p3.x, 0, &p3.y);
    if (status != 0) {
        goto out;
    }

    status = intersection(s, &p0, &p1, &p2, &p3, &result);
    if (status != 0) {
        goto out;
    }

    if (result.x < CAL_DC_MIN || result.x > CAL_DC_MAX) {
        cli_err(s, "Error", "Obtained out-of-range TX I DC cal value (%f).\n",
                result.x);
        status = BLADERF_ERR_UNEXPECTED;
        goto out;
    }

    *dc_i = (int16_t) (result.x + 0.5);
    *error_i = result.y;

    status = set_tx_dc(s->dev, *dc_i, 0);
    if (status != 0) {
        goto out;
    }

    /* Repeat for the Q channel */
    status = rx_avg_magnitude(s->dev, rx_samples, *dc_i, (int16_t) p0.x, &p0.y);
    if (status != 0) {
        goto out;
    }

    status = rx_avg_magnitude(s->dev, rx_samples, *dc_i, (int16_t) p1.x, &p1.y);
    if (status != 0) {
        goto out;
    }

    status = rx_avg_magnitude(s->dev, rx_samples, *dc_i, (int16_t) p2.x, &p2.y);
    if (status != 0) {
        goto out;
    }

    status = rx_avg_magnitude(s->dev, rx_samples, *dc_i, (int16_t) p3.x, &p3.y);
    if (status != 0) {
        goto out;
    }

    status = intersection(s, &p0, &p1, &p2, &p3, &result);
    if (status != 0) {
        goto out;
    }

    *dc_q = (int16_t) (result.x + 0.5);
    *error_q = result.y;

    status = set_tx_dc(s->dev, *dc_i, *dc_q);

out:
    retval = status;

    status = stop_tx_task(&tx_task);
    retval = first_error(retval, status);

    free(rx_samples);
    free(tx_task.samples);

    status = bladerf_enable_module(s->dev, BLADERF_MODULE_TX, false);
    retval = first_error(retval, status);

    /* Restore RX frequency */
    status = bladerf_set_frequency(s->dev, BLADERF_MODULE_TX, tx_freq);
    retval = first_error(retval, status);

    return retval;
}