예제 #1
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;
}
예제 #2
0
파일: bladegps.c 프로젝트: mfkiwl/bladeGPS
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);
}
예제 #3
0
파일: bladegps.c 프로젝트: uhwsin/bladeGPS
int main(int argc, char *argv[])
{
	sim_t s;
	char *devstr = NULL;
	int c;

	// Initialize structures
	init_sim(&s);

	// Allocate TX buffer to hold each block of samples to transmit.
	s.tx.buffer = (int16_t *)malloc(SAMPLES_PER_BUFFER * sizeof(int16_t) * 2); // for 16-bit I and Q samples
	
	if (s.tx.buffer == NULL) {
		fprintf(stderr, "Failed to allocate TX buffer.\n");
		goto out;
	}

	// Allocate FIFOs to hold 0.1 seconds of I/Q samples each.
	s.fifo = (int16_t *)malloc(FIFO_LENGTH * sizeof(int16_t) * 2); // for 16-bit I and Q samples

	if (s.fifo == NULL) {
		fprintf(stderr, "Failed to allocate I/Q sample buffer.\n");
		goto out;
	}

	// Initializing device.
	printf("Opening and initializing device...\n");

	s.status = bladerf_open(&s.tx.dev, devstr);
	if (s.status != 0) {
		fprintf(stderr, "Failed to open device: %s\n", bladerf_strerror(s.status));
		goto out;
	}

	s.status = bladerf_set_frequency(s.tx.dev, BLADERF_MODULE_TX, TX_FREQUENCY);
	if (s.status != 0) {
		fprintf(stderr, "Faield to set TX frequency: %s\n", bladerf_strerror(s.status));
		goto out;
	} 
	else {
		printf("TX frequency: %u Hz\n", TX_FREQUENCY);
	}

	s.status = bladerf_set_sample_rate(s.tx.dev, BLADERF_MODULE_TX, TX_SAMPLERATE, NULL);
	if (s.status != 0) {
		fprintf(stderr, "Failed to set TX sample rate: %s\n", bladerf_strerror(s.status));
		goto out;
	}
	else {
		printf("TX sample rate: %u sps\n", TX_SAMPLERATE);
	}

	s.status = bladerf_set_bandwidth(s.tx.dev, BLADERF_MODULE_TX, TX_BANDWIDTH, NULL);
	if (s.status != 0) {
		fprintf(stderr, "Failed to set TX bandwidth: %s\n", bladerf_strerror(s.status));
		goto out;
	}
	else {
		printf("TX bandwidth: %u Hz\n", TX_BANDWIDTH);
	}

	s.status = bladerf_set_txvga1(s.tx.dev, TX_VGA1);
	if (s.status != 0) {
		fprintf(stderr, "Failed to set TX VGA1 gain: %s\n", bladerf_strerror(s.status));
		goto out;
	}
	else {
		printf("TX VGA1 gain: %d dB\n", TX_VGA1);
	}

	s.status = bladerf_set_txvga2(s.tx.dev, TX_VGA2);
	if (s.status != 0) {
		fprintf(stderr, "Failed to set TX VGA2 gain: %s\n", bladerf_strerror(s.status));
		goto out;
	}
	else {
		printf("TX VGA2 gain: %d dB\n", TX_VGA2);
	}

	// Start GPS task.
	s.status = start_gps_task(&s);
	if (s.status < 0) {
		fprintf(stderr, "Failed to start GPS task.\n");
		goto out;
	}
	else
		printf("Creating GPS task...\n");

	// Wait until GPS task is initialized
	pthread_mutex_lock(&(s.tx.lock));
	while (!s.gps.ready)
		pthread_cond_wait(&(s.gps.initialization_done), &(s.tx.lock));
	pthread_mutex_unlock(&(s.tx.lock));

	// Fillfull the FIFO.
	if (is_fifo_write_ready(&s))
		pthread_cond_signal(&(s.fifo_write_ready));

	// Configure the TX module for use with the synchronous interface.
	s.status = bladerf_sync_config(s.tx.dev,
			BLADERF_MODULE_TX,
			BLADERF_FORMAT_SC16_Q11,
			NUM_BUFFERS,
			SAMPLES_PER_BUFFER,
			NUM_TRANSFERS,
			TIMEOUT_MS);

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

	// We must always enable the modules *after* calling bladerf_sync_config().
	s.status = bladerf_enable_module(s.tx.dev, BLADERF_MODULE_TX, true);
	if (s.status != 0) {
		fprintf(stderr, "Failed to enable TX module: %s\n", bladerf_strerror(s.status));
		goto out;
	}

	// Start TX task
	s.status = start_tx_task(&s);
	if (s.status < 0) {
		fprintf(stderr, "Failed to start TX task.\n");
		goto out;
	}
	else
		printf("Creating TX task...\n");

	// Running...
	printf("Running...\n");
	printf("Press 'q' to exit.\n");
	while (1) {
		c = _getch();
		if (c=='q')
			break;
	}

	//
	// TODO: Cleaning up the threads properly.
	//

	printf("\nDone!\n");

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

out:
	// Free up resources
	if (s.tx.buffer != NULL)
		free(s.tx.buffer);

	if (s.fifo != NULL)
		free(s.fifo);

	printf("Closing device...\n");
	bladerf_close(s.tx.dev);

	return(0);
}