diff options
Diffstat (limited to 'Radio/HW/BladeRF/src/backend/backend.c')
-rw-r--r-- | Radio/HW/BladeRF/src/backend/backend.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/Radio/HW/BladeRF/src/backend/backend.c b/Radio/HW/BladeRF/src/backend/backend.c new file mode 100644 index 0000000..28b5a6d --- /dev/null +++ b/Radio/HW/BladeRF/src/backend/backend.c @@ -0,0 +1,172 @@ +/* + * This file is part of the bladeRF project: + * http://www.github.com/nuand/bladeRF + * + * Copyright (C) 2013 Nuand LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <string.h> + +#include "rel_assert.h" +#include "log.h" + +#include "devinfo.h" + +#include "backend/backend.h" +#include "backend/backend_config.h" + +static const struct backend_fns *backend_list[] = BLADERF_BACKEND_LIST; + +int open_with_any_backend(struct bladerf *dev, + struct bladerf_devinfo *info) +{ + size_t i; + int status = BLADERF_ERR_NODEV; + const size_t n_backends = ARRAY_SIZE(backend_list); + + for (i = 0; i < n_backends && status != 0; i++) { + status = backend_list[i]->open(dev, info); + } + + return status; +} + +int backend_open(struct bladerf *dev, struct bladerf_devinfo *info) +{ + size_t i; + int status = BLADERF_ERR_NODEV; + const size_t n_backends = ARRAY_SIZE(backend_list); + + if (info->backend == BLADERF_BACKEND_ANY) { + status = open_with_any_backend(dev, info); + } else { + for (i = 0; i < n_backends; i++) { + if (backend_list[i]->matches(info->backend)) { + status = backend_list[i]->open(dev, info); + break; + } + } + } + + return status; +} + +int backend_probe(backend_probe_target probe_target, + struct bladerf_devinfo **devinfo_items, size_t *num_items) +{ + int status; + int first_backend_error = 0; + struct bladerf_devinfo_list list; + size_t i; + const size_t n_backends = ARRAY_SIZE(backend_list); + + *devinfo_items = NULL; + *num_items = 0; + + status = bladerf_devinfo_list_init(&list); + if (status != 0) { + log_debug("Failed to initialize devinfo list: %s\n", + bladerf_strerror(status)); + return status; + } + + for (i = 0; i < n_backends; i++) { + status = backend_list[i]->probe(probe_target, &list); + + if (status < 0 && status != BLADERF_ERR_NODEV) { + log_debug("Probe failed on backend %d: %s\n", + i, bladerf_strerror(status)); + + if (!first_backend_error) { + first_backend_error = status; + } + } + } + + *num_items = list.num_elt; + + if (*num_items != 0) { + *devinfo_items = list.elt; + } else { + /* For no items, we end up passing back a NULL list to the + * API caller, so we'll just free this up now */ + free(list.elt); + + /* Report the first error that occurred if we couldn't find anything */ + status = + first_backend_error == 0 ? BLADERF_ERR_NODEV : first_backend_error; + } + + return status; +} + +int backend_load_fw_from_bootloader(bladerf_backend backend, + uint8_t bus, uint8_t addr, + struct fx3_firmware *fw) +{ + int status = BLADERF_ERR_NODEV; + size_t i; + const size_t n_backends = ARRAY_SIZE(backend_list); + + for (i = 0; i < n_backends; i++) { + if (backend_list[i]->matches(backend)) { + status = backend_list[i]->load_fw_from_bootloader(backend, bus, + addr, fw); + break; + } + } + + return status; +} + +const char *backend2str(bladerf_backend backend) +{ + switch (backend) { + case BLADERF_BACKEND_LIBUSB: + return BACKEND_STR_LIBUSB; + + case BLADERF_BACKEND_LINUX: + return BACKEND_STR_LINUX; + + case BLADERF_BACKEND_CYPRESS: + return BACKEND_STR_CYPRESS; + + default: + return BACKEND_STR_ANY; + } +} + +int str2backend(const char *str, bladerf_backend *backend) +{ + int status = 0; + + if (!strcasecmp(BACKEND_STR_LIBUSB, str)) { + *backend = BLADERF_BACKEND_LIBUSB; + } else if (!strcasecmp(BACKEND_STR_LINUX, str)) { + *backend = BLADERF_BACKEND_LINUX; + } else if (!strcasecmp(BACKEND_STR_CYPRESS, str)) { + *backend = BLADERF_BACKEND_CYPRESS; + } else if (!strcasecmp(BACKEND_STR_ANY, str)) { + *backend = BLADERF_BACKEND_ANY; + } else { + log_debug("Invalid backend: %s\n", str); + status = BLADERF_ERR_INVAL; + *backend = BLADERF_BACKEND_ANY; + } + + return status; +} |