int fpga_load_from_file(struct bladerf *dev, const char *fpga_file) { uint8_t *buf = NULL; size_t buf_size; int status; status = file_read_buffer(fpga_file, &buf, &buf_size); if (status != 0) { goto error; } if (!valid_fpga_size(dev->fpga_size, buf_size)) { status = BLADERF_ERR_INVAL; goto error; } status = dev->fn->load_fpga(dev, buf, buf_size); if (status != 0) { goto error; } status = fpga_check_version(dev); if (status != 0) { goto error; } status = init_device(dev); if (status != 0) { goto error; } error: free(buf); return status; }
int bladerf_open_with_devinfo(struct bladerf **opened_device, struct bladerf_devinfo *devinfo) { struct bladerf *dev; int status; *opened_device = NULL; dev = (struct bladerf *)calloc(1, sizeof(struct bladerf)); if (dev == NULL) { return BLADERF_ERR_MEM; } MUTEX_INIT(&dev->ctrl_lock); MUTEX_INIT(&dev->sync_lock[BLADERF_MODULE_RX]); MUTEX_INIT(&dev->sync_lock[BLADERF_MODULE_TX]); dev->fpga_version.describe = calloc(1, BLADERF_VERSION_STR_MAX + 1); if (dev->fpga_version.describe == NULL) { free(dev); return BLADERF_ERR_MEM; } dev->fw_version.describe = calloc(1, BLADERF_VERSION_STR_MAX + 1); if (dev->fw_version.describe == NULL) { free((void*)dev->fpga_version.describe); free(dev); return BLADERF_ERR_MEM; } status = backend_open(dev, devinfo); if (status != 0) { free((void*)dev->fw_version.describe); free((void*)dev->fpga_version.describe); free(dev); return status; } status = dev->fn->get_device_speed(dev, &dev->usb_speed); if (status < 0) { log_debug("Failed to get device speed: %s\n", bladerf_strerror(status)); goto error; } if (dev->usb_speed != BLADERF_DEVICE_SPEED_HIGH && dev->usb_speed != BLADERF_DEVICE_SPEED_SUPER) { log_debug("Unsupported device speed: %d\n", dev->usb_speed); goto error; } /* Verify that we have a sufficent firmware version before continuing. */ status = version_check_fw(dev); if (status != 0) { #ifdef LOGGING_ENABLED if (status == BLADERF_ERR_UPDATE_FW) { struct bladerf_version req; const unsigned int dev_maj = dev->fw_version.major; const unsigned int dev_min = dev->fw_version.minor; const unsigned int dev_pat = dev->fw_version.patch; unsigned int req_maj, req_min, req_pat; version_required_fw(dev, &req, false); req_maj = req.major; req_min = req.minor; req_pat = req.patch; log_warning("Firmware v%u.%u.%u was detected. libbladeRF v%s " "requires firmware v%u.%u.%u or later. An upgrade via " "the bootloader is required.\n\n", dev_maj, dev_min, dev_pat, LIBBLADERF_VERSION, req_maj, req_min, req_pat); } #endif goto error; } /* VCTCXO trim and FPGA size are non-fatal indicators that we've * trashed the calibration region of flash. If these were made fatal, * we wouldn't be able to open the device to restore them. */ status = get_and_cache_vctcxo_trim(dev); if (status < 0) { log_warning("Failed to get VCTCXO trim value: %s\n", bladerf_strerror(status)); } status = get_and_cache_fpga_size(dev); if (status < 0) { log_warning("Failed to get FPGA size %s\n", bladerf_strerror(status)); } status = FPGA_IS_CONFIGURED(dev); if (status > 0) { /* If the FPGA version check fails, just warn, but don't error out. * * If an error code caused this function to bail out, it would prevent a * user from being able to unload and reflash a bitstream being * "autoloaded" from SPI flash. */ fpga_check_version(dev); status = init_device(dev); if (status != 0) { goto error; } } dev->rx_filter = -1; dev->tx_filter = -1; /* Load any configuration files or FPGA images that a user has stored * for this device in their bladerf config directory */ status = config_load_all(dev); error: if (status < 0) { bladerf_close(dev); } else { *opened_device = dev; } return status; }