Example #1
0
void bladerf_close(struct bladerf *dev)
{
    if (dev) {
#ifdef ENABLE_LIBBLADERF_SYNC
        sync_deinit(dev->sync[BLADERF_MODULE_RX]);
        sync_deinit(dev->sync[BLADERF_MODULE_TX]);
#endif
        dev->fn->close(dev);
    }
}
Example #2
0
int bladerf_enable_module(struct bladerf *dev,
                            bladerf_module m, bool enable)
{
    int status;

    if (m != BLADERF_MODULE_RX && m != BLADERF_MODULE_TX) {
        return BLADERF_ERR_INVAL;
    }

    log_debug("Enable Module: %s - %s\n",
                (m == BLADERF_MODULE_RX) ? "RX" : "TX",
                enable ? "True" : "False") ;

#ifdef ENABLE_LIBBLADERF_SYNC
    if (enable == false) {
        sync_deinit(dev->sync[m]);
        dev->sync[m] = NULL;
    }
#endif

    lms_enable_rffe(dev, m, enable);
    status = dev->fn->enable_module(dev, m, enable);

    return status;
}
Example #3
0
int bladerf_enable_module(struct bladerf *dev,
                            bladerf_module m, bool enable)
{
    int status;

    if (m != BLADERF_MODULE_RX && m != BLADERF_MODULE_TX) {
        return BLADERF_ERR_INVAL;
    }

    log_debug("Enable Module: %s - %s\n",
                (m == BLADERF_MODULE_RX) ? "RX" : "TX",
                enable ? "True" : "False") ;

    MUTEX_LOCK(&dev->ctrl_lock);

    if (enable == false) {
        sync_deinit(dev->sync[m]);
        dev->sync[m] = NULL;
    }

    lms_enable_rffe(dev, m, enable);
    status = dev->fn->enable_module(dev, m, enable);

    MUTEX_UNLOCK(&dev->ctrl_lock);
    return status;
}
Example #4
0
void bladerf_close(struct bladerf *dev)
{
    if (dev) {

#ifdef ENABLE_LIBBLADERF_SYNC
        sync_deinit(dev->sync[BLADERF_MODULE_RX]);
        sync_deinit(dev->sync[BLADERF_MODULE_TX]);
#endif

        dev->fn->close(dev);

        free((void *)dev->fpga_version.describe);
        free((void *)dev->fw_version.describe);

        free(dev);
    }
}
Example #5
0
void bladerf_close(struct bladerf *dev)
{
    if (dev) {

        MUTEX_LOCK(&dev->ctrl_lock);
        sync_deinit(dev->sync[BLADERF_MODULE_RX]);
        sync_deinit(dev->sync[BLADERF_MODULE_TX]);

        dev->fn->close(dev);

        free((void *)dev->fpga_version.describe);
        free((void *)dev->fw_version.describe);

        dc_cal_tbl_free(dev->cal.dc_rx);
        dc_cal_tbl_free(dev->cal.dc_tx);

        MUTEX_UNLOCK(&dev->ctrl_lock);
        free(dev);
    }
}
Example #6
0
static int _rfic_fpga_enable_module(struct bladerf *dev,
                                    bladerf_channel ch,
                                    bool ch_enable)
{
    struct bladerf2_board_data *board_data = dev->board_data;
    struct controller_fns const *rfic      = board_data->rfic;
    bladerf_direction dir = BLADERF_CHANNEL_IS_TX(ch) ? BLADERF_TX : BLADERF_RX;
    uint32_t reg;     /* RFFE register value */
    bool ch_enabled;  /* Channel: initial state */
    bool ch_pending;  /* Channel: target state is not initial state */
    bool dir_enabled; /* Direction: initial state */
    bool dir_enable;  /* Direction: target state */
    bool dir_pending; /* Direction: target state is not initial state */
    bool be_toggle;   /* Backend: toggle off/on to reset backend FIFO */
    bool be_teardown; /* Backend: disable backend module */
    bool be_setup;    /* Backend: enable backend module */

    /* Read RFFE control register */
    CHECK_STATUS(dev->backend->rffe_control_read(dev, &reg));

#ifdef BLADERF_HEADLESS_C_DEBUG
    uint32_t reg_old = reg;
#endif

    /* Calculate initial and target states */
    ch_enabled  = _rffe_ch_enabled(reg, ch);
    dir_enabled = _rffe_dir_enabled(reg, dir);
    dir_enable  = ch_enable || _rffe_dir_otherwise_enabled(reg, ch);
    ch_pending  = ch_enabled != ch_enable;
    dir_pending = dir_enabled != dir_enable;
    be_toggle   = !BLADERF_CHANNEL_IS_TX(ch) && ch_enable && !dir_pending;
    be_setup    = be_toggle || (dir_pending && dir_enable);
    be_teardown = be_toggle || (dir_pending && !dir_enable);

    /* Perform Direction Teardown */
    if (dir_pending && !dir_enable) {
        sync_deinit(&board_data->sync[dir]);
        perform_format_deconfig(dev, dir);
    }

    /* Perform Channel Setup/Teardown */
    if (ch_pending) {
        /* Set/unset TX mute */
        if (BLADERF_CHANNEL_IS_TX(ch)) {
            CHECK_STATUS(rfic->set_txmute(dev, ch, !ch_enable));
        }

        /* Execute RFIC enable command. */
        CHECK_STATUS(_rfic_cmd_write(dev, ch, BLADERF_RFIC_COMMAND_ENABLE,
                                     ch_enable ? 1 : 0));
    }

    /* Perform backend teardown */
    if (be_teardown) {
        CHECK_STATUS(dev->backend->enable_module(dev, dir, false));
    }

    /* Perform backend setup */
    if (be_setup) {
        CHECK_STATUS(dev->backend->enable_module(dev, dir, true));
    }

    /* Warn the user if the sample rate isn't reasonable */
    if (ch_pending && ch_enable) {
        check_total_sample_rate(dev);
    }

#ifdef BLADERF_HEADLESS_C_DEBUG
    /* Debug output... */
    if (BLADERF_LOG_LEVEL_VERBOSE == log_get_verbosity()) {
        CHECK_STATUS(dev->backend->rffe_control_read(dev, &reg));

        log_verbose(
            "%s: %s ch[en=%d->%d pend=%d] dir[en=%d->%d pend=%d] be[clr=%d "
            "su=%d td=%d] reg=0x%08x->0x%08x\n",
            __FUNCTION__, channel2str(ch), ch_enabled, ch_enable, ch_pending,
            dir_enabled, dir_enable, dir_pending, be_toggle, be_setup,
            be_teardown, reg_old, reg);
    }
#endif

    return 0;
}
Example #7
0
int sync_init(struct bladerf *dev,
              bladerf_module module,
              bladerf_format format,
              unsigned int num_buffers,
              unsigned int buffer_size,
              unsigned int num_transfers,
              unsigned int stream_timeout)

{
    struct bladerf_sync *sync;
    int status = 0;
    size_t i, bytes_per_sample;

    if (num_transfers >= num_buffers) {
        return BLADERF_ERR_INVAL;
    }

    switch (format) {
        case BLADERF_FORMAT_SC16_Q11:
        case BLADERF_FORMAT_SC16_Q11_META:
            bytes_per_sample = 4;
            break;

        default:
            log_debug("Invalid format value: %d\n", format);
            return BLADERF_ERR_INVAL;
    }

    /* bladeRF GPIF DMA requirement */
    if ((bytes_per_sample * buffer_size) % 4096 != 0) {
        return BLADERF_ERR_INVAL;
    }

    /* Deallocate any existing sync handle for this module */
    switch (module) {
        case BLADERF_MODULE_TX:
        case BLADERF_MODULE_RX:
            sync_deinit(dev->sync[module]);
            sync = dev->sync[module] =
                (struct bladerf_sync *) calloc(1, sizeof(struct bladerf_sync));

            if (dev->sync[module] == NULL) {
                status = BLADERF_ERR_MEM;
            }
            break;

        default:
            log_debug("Invalid bladerf_module value encountered: %d", module);
            status = BLADERF_ERR_INVAL;
    }

    if (status != 0) {
        return status;
    }

    sync->dev = dev;
    sync->state = SYNC_STATE_CHECK_WORKER;

    sync->buf_mgmt.num_buffers = num_buffers;
    sync->buf_mgmt.resubmit_count = 0;

    sync->stream_config.module = module;
    sync->stream_config.format = format;
    sync->stream_config.samples_per_buffer = buffer_size;
    sync->stream_config.num_xfers = num_transfers;
    sync->stream_config.timeout_ms = stream_timeout;
    sync->stream_config.bytes_per_sample = bytes_per_sample;

    sync->meta.state = SYNC_META_STATE_HEADER;
    sync->meta.msg_per_buf = msg_per_buf(dev, buffer_size, bytes_per_sample);
    sync->meta.samples_per_msg = samples_per_msg(dev, bytes_per_sample);

    log_verbose("%s: Buffer size: %u\n",
                __FUNCTION__, buffer_size);

    log_verbose("%s: Msg per buffer: %u\n",
                __FUNCTION__, sync->meta.msg_per_buf);

    log_verbose("%s: Samples per msg: %u\n",
                __FUNCTION__, sync->meta.samples_per_msg);

    MUTEX_INIT(&sync->buf_mgmt.lock);
    pthread_cond_init(&sync->buf_mgmt.buf_ready, NULL);

    sync->buf_mgmt.status = (sync_buffer_status*) malloc(num_buffers * sizeof(sync_buffer_status));
    if (sync->buf_mgmt.status == NULL) {
        status = BLADERF_ERR_MEM;
    } else {
        switch (module) {
            case BLADERF_MODULE_RX:
                /* When starting up an RX stream, the first 'num_transfers'
                 * transfers will be submitted to the USB layer to grab data */
                sync->buf_mgmt.prod_i = num_transfers;
                sync->buf_mgmt.cons_i = 0;
                sync->buf_mgmt.partial_off = 0;

                for (i = 0; i < num_buffers; i++) {
                    if (i < num_transfers) {
                        sync->buf_mgmt.status[i] = SYNC_BUFFER_IN_FLIGHT;
                    } else {
                        sync->buf_mgmt.status[i] = SYNC_BUFFER_EMPTY;
                    }
                }

                sync->meta.msg_timestamp = 0;
                sync->meta.msg_flags = 0;

                break;

            case BLADERF_MODULE_TX:
                sync->buf_mgmt.prod_i = 0;
                sync->buf_mgmt.cons_i = 0;
                sync->buf_mgmt.partial_off = 0;

                for (i = 0; i < num_buffers; i++) {
                    sync->buf_mgmt.status[i] = SYNC_BUFFER_EMPTY;
                }

                sync->meta.in_burst = false;
                sync->meta.now = false;

                break;
        }

        status = sync_worker_init(sync);
    }

    if (status != 0) {
        sync_deinit(dev->sync[module]);
        dev->sync[module] = NULL;
    }

    return status;
}
Example #8
0
int sync_init(struct bladerf_sync *sync,
              struct bladerf *dev,
              bladerf_channel_layout layout,
              bladerf_format format,
              unsigned int num_buffers,
              size_t buffer_size,
              size_t msg_size,
              unsigned int num_transfers,
              unsigned int stream_timeout)

{
    int status = 0;
    size_t i, bytes_per_sample;

    if (num_transfers >= num_buffers) {
        return BLADERF_ERR_INVAL;
    }

    switch (format) {
        case BLADERF_FORMAT_SC16_Q11:
        case BLADERF_FORMAT_SC16_Q11_META:
            bytes_per_sample = 4;
            break;

        default:
            log_debug("Invalid format value: %d\n", format);
            return BLADERF_ERR_INVAL;
    }

    /* bladeRF GPIF DMA requirement */
    if ((bytes_per_sample * buffer_size) % 4096 != 0) {
        return BLADERF_ERR_INVAL;
    }

    /* Deinitialize sync handle if it's initialized */
    sync_deinit(sync);

    MUTEX_INIT(&sync->lock);

    switch (layout & BLADERF_DIRECTION_MASK) {
        case BLADERF_TX:
            sync->buf_mgmt.submitter = SYNC_TX_SUBMITTER_FN;
            break;
        case BLADERF_RX:
            sync->buf_mgmt.submitter = SYNC_TX_SUBMITTER_INVALID;
            break;
    }

    sync->dev = dev;
    sync->state = SYNC_STATE_CHECK_WORKER;

    sync->buf_mgmt.num_buffers = num_buffers;
    sync->buf_mgmt.resubmit_count = 0;

    sync->stream_config.layout = layout;
    sync->stream_config.format = format;
    sync->stream_config.samples_per_buffer = (unsigned int)buffer_size;
    sync->stream_config.num_xfers = num_transfers;
    sync->stream_config.timeout_ms = stream_timeout;
    sync->stream_config.bytes_per_sample = bytes_per_sample;

    sync->meta.state = SYNC_META_STATE_HEADER;
    sync->meta.msg_size = msg_size;
    sync->meta.msg_per_buf = msg_per_buf(msg_size, buffer_size, bytes_per_sample);
    sync->meta.samples_per_msg = samples_per_msg(msg_size, bytes_per_sample);

    log_verbose("%s: Buffer size: %u\n",
                __FUNCTION__, buffer_size);

    log_verbose("%s: Msg per buffer: %u\n",
                __FUNCTION__, sync->meta.msg_per_buf);

    log_verbose("%s: Samples per msg: %u\n",
                __FUNCTION__, sync->meta.samples_per_msg);

    MUTEX_INIT(&sync->buf_mgmt.lock);
    pthread_cond_init(&sync->buf_mgmt.buf_ready, NULL);

    sync->buf_mgmt.status = (sync_buffer_status*) malloc(num_buffers * sizeof(sync_buffer_status));
    if (sync->buf_mgmt.status == NULL) {
        status = BLADERF_ERR_MEM;
        goto error;
    }

    switch (layout & BLADERF_DIRECTION_MASK) {
        case BLADERF_RX:
            /* When starting up an RX stream, the first 'num_transfers'
             * transfers will be submitted to the USB layer to grab data */
            sync->buf_mgmt.prod_i = num_transfers;
            sync->buf_mgmt.cons_i = 0;
            sync->buf_mgmt.partial_off = 0;

            for (i = 0; i < num_buffers; i++) {
                if (i < num_transfers) {
                    sync->buf_mgmt.status[i] = SYNC_BUFFER_IN_FLIGHT;
                } else {
                    sync->buf_mgmt.status[i] = SYNC_BUFFER_EMPTY;
                }
            }

            sync->meta.msg_timestamp = 0;
            sync->meta.msg_flags = 0;

            break;

        case BLADERF_TX:
            sync->buf_mgmt.prod_i = 0;
            sync->buf_mgmt.cons_i = BUFFER_MGMT_INVALID_INDEX;
            sync->buf_mgmt.partial_off = 0;

            for (i = 0; i < num_buffers; i++) {
                sync->buf_mgmt.status[i] = SYNC_BUFFER_EMPTY;
            }

            sync->meta.in_burst = false;
            sync->meta.now = false;
            break;
    }

    status = sync_worker_init(sync);
    if (status < 0) {
        goto error;
    }

    sync->initialized = true;

    return 0;

error:
    sync_deinit(sync);
    return status;
}