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); } }
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; }
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; }
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); } }
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); } }
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, ®)); #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, ®)); 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; }
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; }
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; }