Exemple #1
0
/** [tx_meta_now] */
int sync_tx_meta_now_example(struct bladerf *dev, int16_t *samples,
                             unsigned int num_samples, unsigned int tx_count,
                             unsigned int timeout_ms)
{
    int status = 0;
    struct bladerf_metadata meta;
    unsigned int i;

    memset(&meta, 0, sizeof(meta));

    /* Send entire burst worth of samples in one function call */
    meta.flags = BLADERF_META_FLAG_TX_BURST_START |
                 BLADERF_META_FLAG_TX_NOW |
                 BLADERF_META_FLAG_TX_BURST_END;

    for (i = 0; i < tx_count && status == 0; i++) {
        /* Fetch or produce IQ samples...*/
        produce_samples(samples, num_samples);

        status = bladerf_sync_tx(dev, samples, num_samples, &meta, timeout_ms);
        if (status != 0) {
            fprintf(stderr, "TX failed: %s\n", bladerf_strerror(status));
        } else {
            uint64_t curr_ts;

            status = bladerf_get_timestamp(dev, BLADERF_MODULE_TX, &curr_ts);
            if (status != 0) {
                fprintf(stderr, "Failed to get current TX timestamp: %s\n",
                        bladerf_strerror(status));
            } else {
                printf("TX'd at approximately t=%016"PRIu64"\n", curr_ts);
            }

            /* Delay next transmission by approximately 5 ms
             *
             * This is a very imprecise, "quick and dirty" means to do so in
             * cases where no particular intra-burst time is required. */
            usleep(5000);
        }
    }

    /* Wait for samples to be TX'd before completing.  */
    if (status == 0) {
        status = bladerf_get_timestamp(dev, BLADERF_MODULE_TX, &meta.timestamp);
        if (status != 0) {
            fprintf(stderr, "Failed to get current TX timestamp: %s\n",
                    bladerf_strerror(status));
            return status;
        } else {
            status = wait_for_timestamp(dev, BLADERF_MODULE_TX,
                                        meta.timestamp + 2 * num_samples,
                                        timeout_ms);
            if (status != 0) {
                fprintf(stderr, "Failed to wait for timestamp.\n");
            }
        }
    }

    return status;
}
Exemple #2
0
/** [tx_meta_sched] */
int sync_tx_meta_sched_example(struct bladerf *dev,
                             int16_t *samples, unsigned int num_samples,
                             unsigned int tx_count, unsigned int samplerate,
                             unsigned int timeout_ms)
{
    int status = 0;
    unsigned int i;
    struct bladerf_metadata meta;

    memset(&meta, 0, sizeof(meta));

    /* Send entire burst worth of samples in one function call */
    meta.flags = BLADERF_META_FLAG_TX_BURST_START |
                 BLADERF_META_FLAG_TX_BURST_END;

    /* Retrieve the current timestamp so we can schedule our transmission
     * in the future. */
    status = bladerf_get_timestamp(dev, BLADERF_MODULE_TX, &meta.timestamp);
    if (status != 0) {
        fprintf(stderr, "Failed to get current TX timestamp: %s\n",
                bladerf_strerror(status));
        return status;
    } else {
        printf("Current TX timestamp: %016"PRIu64"\n", meta.timestamp);
    }

    for (i = 0; i < tx_count && status == 0; i++) {
        /* Get sample to transmit... */
        produce_samples(samples, num_samples);

        /* Schedule burst 5 ms into the future */
        meta.timestamp += samplerate / 200;

        status = bladerf_sync_tx(dev, samples, num_samples, &meta, timeout_ms);
        if (status != 0) {
            fprintf(stderr, "TX failed: %s\n", bladerf_strerror(status));
            return status;
        } else {
            printf("TX'd @ t=%016"PRIu64"\n", meta.timestamp);
        }
    }

    /* Wait for samples to finish being transmitted. */
    if (status == 0) {
        meta.timestamp += 2 * num_samples;

        status = wait_for_timestamp(dev, BLADERF_MODULE_TX,
                                    meta.timestamp, timeout_ms);

        if (status != 0) {
            fprintf(stderr, "Failed to wait for timestamp.\n");
        }
    }

    return status;
}
Exemple #3
0
int read_message(int message_num, int publish, int no_wait)
{
	//  char *line[MAX_LINE_LENGTH];
	char *line;
	char *current_pos;
	int i, j;
	char command[100];
	static double last_update = 0;
	double current_time;

	line = (char *) malloc(MAX_LINE_LENGTH * sizeof(char));
	if (line == NULL)
		carmen_die("Could not alloc memory in playback.c:read_message()\n");

	carmen_logfile_read_line(logfile_index, logfile, message_num,
			MAX_LINE_LENGTH, line);
	current_pos = carmen_next_word(line);

	for(i = 0; i < (int)(sizeof(logger_callbacks) /
			sizeof(logger_callback_t)); i++) {
		/* copy the command over */
		j = 0;
		while(line[j] != ' ') {
			command[j] = line[j];
			j++;
		}
		command[j] = '\0';
		if(strncmp(command, logger_callbacks[i].logger_message_name, j) == 0) {
			if(!basic_messages || !logger_callbacks[i].interpreted) {
				current_pos =
					logger_callbacks[i].conv_func(current_pos,
							logger_callbacks[i].message_data);
				playback_timestamp = atof(current_pos);
				//printf("command = %s, playback_timestamp = %lf\n", command, playback_timestamp);
				if(publish) {
					current_time = carmen_get_time();
					if(current_time - last_update > 0.2) {
						print_playback_status();
						last_update = current_time;
					}
					if (!no_wait)
						wait_for_timestamp(playback_timestamp);
					IPC_publishData(logger_callbacks[i].ipc_message_name,
							logger_callbacks[i].message_data);
				}
				/* return 1 if it is a front laser message */
				free(line);
				return (strcmp(command, "FLASER") == 0);
			}
		}
	}

	free(line);
	return 0;
}
static void * tx_task(void *args)
{
    int status;
    int16_t *samples;
    unsigned int i;
    struct bladerf_metadata meta;
    uint64_t samples_left;
    struct test *t = (struct test *) args;
    bool stop = false;
    int16_t zeros[] = { 0, 0, 0, 0 };

    samples = (int16_t*) malloc(2 * sizeof(samples[0]) * t->params->buf_size);
    if (samples == NULL) {
        perror("malloc");
        return NULL;
    }

    memset(&meta, 0, sizeof(meta));

    for (i = 0; i < (2 * t->params->buf_size); i += 2) {
        samples[i] = samples[i + 1] = TX_MAGNITUDE;
    }

    status = bladerf_get_timestamp(t->dev, BLADERF_MODULE_TX, &meta.timestamp);
    if (status != 0) {
        fprintf(stderr, "Failed to get current timestamp: %s\n",
                bladerf_strerror(status));
    }

    meta.timestamp += 400000;

    for (i = 0; i < t->num_bursts && !stop; i++) {
        meta.flags = BLADERF_META_FLAG_TX_BURST_START;
        samples_left = t->bursts[i].duration;

        assert(samples_left <= UINT_MAX);

        if (i != 0) {
            meta.timestamp += (t->bursts[i-1].duration + t->bursts[i].gap);
        }

        while (samples_left != 0 && status == 0) {
            unsigned int to_send = uint_min(t->params->buf_size,
                                            (unsigned int) samples_left);

            status = bladerf_sync_tx(t->dev, samples, to_send, &meta,
                                     t->params->timeout_ms);

            if (status != 0) {
                fprintf(stderr, "Failed to TX @ burst %-4u with %"PRIu64
                        " samples left: %s\n",
                        i + 1, samples_left, bladerf_strerror(status));

                /* Stop the RX worker */
                pthread_mutex_lock(&t->lock);
                t->stop = true;
                pthread_mutex_unlock(&t->lock);
            }

            meta.flags &= ~BLADERF_META_FLAG_TX_BURST_START;
            samples_left -= to_send;
        }

        /* Flush TX samples by ensuring we have 2 zero samples at the end
         * of our burst (as required by libbladeRF) */
        if (status == 0) {
            meta.flags = BLADERF_META_FLAG_TX_BURST_END;
            status = bladerf_sync_tx(t->dev, zeros, 2, &meta,
                                     t->params->timeout_ms);

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

                /* Stop the RX worker */
                pthread_mutex_lock(&t->lock);
                t->stop = true;
                pthread_mutex_unlock(&t->lock);
            }
        }

        pthread_mutex_lock(&t->lock);
        stop = t->stop;
        pthread_mutex_unlock(&t->lock);
    }

    /* Wait for samples to finish */
    printf("TX: Waiting for samples to finish.\n");
    fflush(stdout);
    status = wait_for_timestamp(t->dev, BLADERF_MODULE_TX,
                                meta.timestamp + t->bursts[i - 1].duration,
                                3000);

    if (status != 0) {
        fprintf(stderr, "Failed to wait for TX to complete: %s\n",
                bladerf_strerror(status));
    }

    free(samples);

    printf("TX: Exiting task.\n");
    fflush(stdout);
    return NULL;
}
Exemple #5
0
/** [tx_meta_update] */
int sync_tx_meta_update_example(struct bladerf *dev,
                                int16_t *samples, unsigned int num_samples,
                                unsigned int tx_count, unsigned int samplerate,
                                unsigned int timeout_ms)
{
    int status = 0;
    unsigned int i;
    struct bladerf_metadata meta;
    int16_t zeros[] = { 0, 0, 0, 0 }; /* Two 0+0j samples */

    memset(&meta, 0, sizeof(meta));

    /* The first call to bladerf_sync_tx() will start our long "burst" at
     * a specific timestamp.
     *
     * In successive calls, we'll break this long "burst" up into shorter bursts
     * by using the BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP flag with new
     * timestamps.  The discontinuities will be zero-padded.
     */
    meta.flags = BLADERF_META_FLAG_TX_BURST_START;

    /* Retrieve the current timestamp so we can schedule our transmission
     * in the future. */
    status = bladerf_get_timestamp(dev, BLADERF_MODULE_TX, &meta.timestamp);
    if (status != 0) {
        fprintf(stderr, "Failed to get current TX timestamp: %s\n",
                bladerf_strerror(status));
        return status;
    } else {
        printf("Current TX timestamp: %016"PRIu64"\n", meta.timestamp);
    }

    /* Start 5 ms in the future */
    meta.timestamp += samplerate / 200;

    for (i = 0; i < tx_count && status == 0; i++) {
        /* Get sample to transmit... */
        produce_samples(samples, num_samples);

        status = bladerf_sync_tx(dev, samples, num_samples, &meta, timeout_ms);
        if (status != 0) {
            fprintf(stderr, "TX failed: %s\n", bladerf_strerror(status));
            return status;
        } else {
            printf("TX'd @ t=%016"PRIu64"\n", meta.timestamp);
        }

        /* Instruct bladerf_sync_tx() to position samples within this burst at
         * the specified timestamp. 0+0j will be transmitted up until that
         * point. */
        meta.flags = BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP;

        /* Schedule samples to be transmitted 1.25 ms after the completion of
         * the previous burst */
        meta.timestamp += num_samples + samplerate / 800;

    }

    /* End the burst and flush remaining samples. */
    meta.flags = BLADERF_META_FLAG_TX_BURST_END;
    status = bladerf_sync_tx(dev, zeros, 2, &meta, timeout_ms);

    /* Wait for samples to finish being transmitted. */
    if (status == 0) {
        meta.timestamp += 2 * num_samples;

        status = wait_for_timestamp(dev, BLADERF_MODULE_TX,
                                    meta.timestamp, timeout_ms);

        if (status != 0) {
            fprintf(stderr, "Failed to wait for timestamp.\n");
        }
    } else {
        fprintf(stderr, "Failed to complete burst: %s\n",
                bladerf_strerror(status));
    }


    return status;
}
Exemple #6
0
static int run(struct bladerf *dev, struct app_params *p,
               const struct test_case *t)
{
    int status, status_out, status_wait;
    unsigned int samples_left;
    size_t i;
    struct bladerf_metadata meta;
    int16_t *samples, *buf;

    samples = calloc(2 * sizeof(int16_t), t->burst_len + 2);
    if (samples == NULL) {
        perror("malloc");
        return BLADERF_ERR_MEM;
    }

    /* Leave the last two samples zero */
    for (i = 0; i < (2 * t->burst_len); i += 2) {
        samples[i] = samples[i + 1] = MAGNITUDE;
    }

    memset(&meta, 0, sizeof(meta));

    status = perform_sync_init(dev, BLADERF_MODULE_TX, t->buf_len, p);
    if (status != 0) {
        goto out;
    }

    status = bladerf_get_timestamp(dev, BLADERF_MODULE_TX, &meta.timestamp);
    if (status != 0) {
        fprintf(stderr, "Failed to get timestamp: %s\n",
                bladerf_strerror(status));
        goto out;
    } else {
        printf("Initial timestamp: 0x%016"PRIx64"\n", meta.timestamp);
    }

    meta.timestamp += 200000;


    for (i = 0; i < t->iterations && status == 0; i++) {
        meta.flags = BLADERF_META_FLAG_TX_BURST_START;
        samples_left = t->burst_len + 2;
        buf = samples;


        printf("Sending burst @ %llu\n", (unsigned long long) meta.timestamp);

        while (samples_left && status == 0) {
            unsigned int to_send = uint_min(p->buf_size, samples_left);

            if (to_send == samples_left) {
                meta.flags |= BLADERF_META_FLAG_TX_BURST_END;
            } else {
                meta.flags &= ~BLADERF_META_FLAG_TX_BURST_END;
            }

            status = bladerf_sync_tx(dev, buf, to_send, &meta, 10000); //p->timeout_ms);
            if (status != 0) {
                fprintf(stderr, "TX failed @ iteration (%u) %s\n",
                        (unsigned int )i, bladerf_strerror(status));
            }

            meta.flags &= ~BLADERF_META_FLAG_TX_BURST_START;
            samples_left -= to_send;
            buf += 2 * to_send;
        }

        meta.timestamp += (t->burst_len + t->gap_len - 2);
    }

    printf("Waiting for samples to finish...\n");
    fflush(stdout);

    /* Wait for samples to be transmitted before shutting down the TX module */
    status_wait = wait_for_timestamp(dev, BLADERF_MODULE_TX,
                                     meta.timestamp - t->gap_len + 2,
                                     3000);
    if (status_wait != 0) {
        status = first_error(status, status_wait);
        fprintf(stderr, "Failed to wait for TX to finish: %s\n",
                bladerf_strerror(status_wait));
    }

out:
    status_out = bladerf_enable_module(dev, BLADERF_MODULE_TX, false);
    if (status_out != 0) {
        fprintf(stderr, "Failed to disable TX module: %s\n",
                bladerf_strerror(status));
    } else {
        printf("Done waiting.\n");
        fflush(stdout);
    }

    status = first_error(status, status_out);

    free(samples);
    return status;
}