summaryrefslogtreecommitdiff
path: root/Radio/HW/BladeRF/src/board/bladerf2/common.h
diff options
context:
space:
mode:
Diffstat (limited to 'Radio/HW/BladeRF/src/board/bladerf2/common.h')
-rw-r--r--Radio/HW/BladeRF/src/board/bladerf2/common.h494
1 files changed, 494 insertions, 0 deletions
diff --git a/Radio/HW/BladeRF/src/board/bladerf2/common.h b/Radio/HW/BladeRF/src/board/bladerf2/common.h
new file mode 100644
index 0000000..5a88cb4
--- /dev/null
+++ b/Radio/HW/BladeRF/src/board/bladerf2/common.h
@@ -0,0 +1,494 @@
+/*
+ * This file is part of the bladeRF project:
+ * http://www.github.com/nuand/bladeRF
+ *
+ * Copyright (C) 2018 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
+ */
+
+#ifndef BLADERF2_COMMON_H_
+#define BLADERF2_COMMON_H_
+
+#if !defined(BLADERF_NIOS_BUILD) && !defined(BLADERF_NIOS_PC_SIMULATION)
+#include "log.h"
+#endif
+
+#include "bladerf2_common.h"
+#include "helpers/version.h"
+#include "streaming/sync.h"
+
+
+/******************************************************************************/
+/* Types */
+/******************************************************************************/
+
+enum bladerf2_vctcxo_trim_source {
+ TRIM_SOURCE_NONE,
+ TRIM_SOURCE_TRIM_DAC,
+ TRIM_SOURCE_PLL,
+ TRIM_SOURCE_AUXDAC
+};
+
+enum bladerf2_rfic_command_mode {
+ RFIC_COMMAND_HOST, /**< Host-based control */
+ RFIC_COMMAND_FPGA, /**< FPGA-based control */
+};
+
+struct controller_fns {
+ bool (*is_present)(struct bladerf *dev);
+ bool (*is_initialized)(struct bladerf *dev);
+ bool (*is_standby)(struct bladerf *dev);
+ int (*get_init_state)(struct bladerf *dev, bladerf_rfic_init_state *state);
+
+ int (*initialize)(struct bladerf *dev);
+ int (*standby)(struct bladerf *dev);
+ int (*deinitialize)(struct bladerf *dev);
+
+ int (*enable_module)(struct bladerf *dev, bladerf_channel ch, bool enable);
+
+ int (*get_sample_rate)(struct bladerf *dev,
+ bladerf_channel ch,
+ bladerf_sample_rate *rate);
+ int (*set_sample_rate)(struct bladerf *dev,
+ bladerf_channel ch,
+ bladerf_sample_rate rate);
+
+ int (*get_frequency)(struct bladerf *dev,
+ bladerf_channel ch,
+ bladerf_frequency *frequency);
+ int (*set_frequency)(struct bladerf *dev,
+ bladerf_channel ch,
+ bladerf_frequency frequency);
+ int (*select_band)(struct bladerf *dev,
+ bladerf_channel ch,
+ bladerf_frequency frequency);
+
+ int (*get_bandwidth)(struct bladerf *dev,
+ bladerf_channel ch,
+ bladerf_bandwidth *bandwidth);
+ int (*set_bandwidth)(struct bladerf *dev,
+ bladerf_channel ch,
+ bladerf_bandwidth bandwidth,
+ bladerf_bandwidth *actual);
+
+ int (*get_gain_mode)(struct bladerf *dev,
+ bladerf_channel ch,
+ bladerf_gain_mode *mode);
+ int (*set_gain_mode)(struct bladerf *dev,
+ bladerf_channel ch,
+ bladerf_gain_mode mode);
+
+ int (*get_gain)(struct bladerf *dev, bladerf_channel ch, int *gain);
+ int (*set_gain)(struct bladerf *dev, bladerf_channel ch, int gain);
+
+ int (*get_gain_stage)(struct bladerf *dev,
+ bladerf_channel ch,
+ char const *stage,
+ int *gain);
+ int (*set_gain_stage)(struct bladerf *dev,
+ bladerf_channel ch,
+ char const *stage,
+ int gain);
+
+ int (*get_rssi)(struct bladerf *dev,
+ bladerf_channel ch,
+ int *pre_rssi,
+ int *sym_rssi);
+
+ int (*get_filter)(struct bladerf *dev,
+ bladerf_channel ch,
+ bladerf_rfic_rxfir *rxfir,
+ bladerf_rfic_txfir *txfir);
+ int (*set_filter)(struct bladerf *dev,
+ bladerf_channel ch,
+ bladerf_rfic_rxfir rxfir,
+ bladerf_rfic_txfir txfir);
+
+ int (*get_txmute)(struct bladerf *dev, bladerf_channel ch, bool *state);
+ int (*set_txmute)(struct bladerf *dev, bladerf_channel ch, bool state);
+
+ int (*store_fastlock_profile)(struct bladerf *dev,
+ bladerf_channel ch,
+ uint32_t profile);
+
+ int (*save_fastlock_profile)(struct bladerf *dev,
+ bladerf_channel ch,
+ uint32_t profile,
+ uint8_t *values);
+
+ enum bladerf2_rfic_command_mode const command_mode;
+};
+
+struct bladerf2_board_data {
+ /* Board state */
+ enum {
+ STATE_UNINITIALIZED,
+ STATE_FIRMWARE_LOADED,
+ STATE_FPGA_LOADED,
+ STATE_INITIALIZED,
+ } state;
+
+ /* AD9361 PHY Handle */
+ struct ad9361_rf_phy *phy;
+
+ /* RFIC configuration parameters */
+ void *rfic_init_params;
+
+ /* Bitmask of capabilities determined by version numbers */
+ uint64_t capabilities;
+
+ /* Format currently being used with a module, or -1 if module is not used */
+ bladerf_format module_format[NUM_MODULES];
+
+ /* Which mode of operation we use for tuning */
+ bladerf_tuning_mode tuning_mode;
+
+ /* Board properties */
+ bladerf_fpga_size fpga_size;
+ /* Data message size */
+ size_t msg_size;
+
+ /* Version information */
+ struct bladerf_version fpga_version;
+ struct bladerf_version fw_version;
+ char fpga_version_str[BLADERF_VERSION_STR_MAX + 1];
+ char fw_version_str[BLADERF_VERSION_STR_MAX + 1];
+
+ /* Synchronous interface handles */
+ struct bladerf_sync sync[2];
+
+ /* VCTCXO trim state */
+ enum bladerf2_vctcxo_trim_source trim_source;
+ uint16_t trimdac_last_value; /**< saved running value */
+ uint16_t trimdac_stored_value; /**< cached value read from SPI flash */
+
+ /* Quick Tune Profile Status */
+ uint16_t quick_tune_tx_profile;
+ uint16_t quick_tune_rx_profile;
+
+ /* RFIC backend command handling */
+ struct controller_fns const *rfic;
+
+ /* RFIC FIR Filter status */
+ bladerf_rfic_rxfir rxfir;
+ bladerf_rfic_txfir txfir;
+
+ /* If true, RFIC control will be fully de-initialized on close, instead of
+ * just put into a standby state. */
+ bool rfic_reset_on_close;
+};
+
+struct bladerf_rfic_status_register {
+ bool rfic_initialized;
+ size_t write_queue_length;
+};
+
+
+/******************************************************************************/
+/* Externs */
+/******************************************************************************/
+
+extern AD9361_InitParam bladerf2_rfic_init_params;
+extern AD9361_InitParam bladerf2_rfic_init_params_fastagc_burst;
+extern AD9361_RXFIRConfig bladerf2_rfic_rx_fir_config;
+extern AD9361_TXFIRConfig bladerf2_rfic_tx_fir_config;
+extern AD9361_RXFIRConfig bladerf2_rfic_rx_fir_config_dec2;
+extern AD9361_TXFIRConfig bladerf2_rfic_tx_fir_config_int2;
+extern AD9361_RXFIRConfig bladerf2_rfic_rx_fir_config_dec4;
+extern AD9361_TXFIRConfig bladerf2_rfic_tx_fir_config_int4;
+extern const float ina219_r_shunt;
+
+
+/******************************************************************************/
+/* Constants */
+/******************************************************************************/
+
+extern char const *bladerf2_state_to_string[4];
+
+
+/******************************************************************************/
+/* Macros */
+/******************************************************************************/
+
+/* Macro for logging and returning an error status. This should be used for
+ * errors defined in the \ref RETCODES list. */
+#define RETURN_ERROR_STATUS(_what, _status) \
+ do { \
+ log_error("%s: %s failed: %s\n", __FUNCTION__, _what, \
+ bladerf_strerror(_status)); \
+ return _status; \
+ } while (0)
+
+/* Macro for converting, logging, and returning libad9361 error codes. */
+#define RETURN_ERROR_AD9361(_what, _status) \
+ do { \
+ RETURN_ERROR_STATUS(_what, errno_ad9361_to_bladerf(_status)); \
+ } while (0)
+
+/* Macro for logging and returning ::BLADERF_ERR_INVAL */
+#define RETURN_INVAL_ARG(_what, _arg, _why) \
+ do { \
+ log_error("%s: %s '%s' invalid: %s\n", __FUNCTION__, _what, #_arg, \
+ _why); \
+ return BLADERF_ERR_INVAL; \
+ } while (0)
+
+#define RETURN_INVAL(_what, _why) \
+ do { \
+ log_error("%s: %s invalid: %s\n", __FUNCTION__, _what, _why); \
+ return BLADERF_ERR_INVAL; \
+ } while (0)
+
+/**
+ * @brief Null test
+ *
+ * @param _var The variable to check
+ *
+ * @return RETURN_INVAL if _var is null, continues otherwise
+ */
+#define NULL_CHECK(_var) \
+ do { \
+ if (NULL == _var) { \
+ RETURN_INVAL(#_var, "is null"); \
+ } \
+ } while (0)
+
+/**
+ * @brief Null test, with mutex unlock on failure
+ *
+ * @param _var The variable to check
+ *
+ * @return RETURN_INVAL if _var is null, continues otherwise
+ */
+#define NULL_CHECK_LOCKED(_var) \
+ do { \
+ NULL_CHECK(dev); \
+ \
+ if (NULL == _var) { \
+ MUTEX_UNLOCK(__lock); \
+ RETURN_INVAL(#_var, "is null"); \
+ } \
+ } while (0)
+
+/**
+ * @brief Board state check
+ *
+ * @param _state Minimum sufficient board state
+ *
+ * @return BLADERF_ERR_NOT_INIT if board's state is less than _state, continues
+ * otherwise
+ */
+#define CHECK_BOARD_STATE(_state) \
+ do { \
+ NULL_CHECK(dev); \
+ NULL_CHECK(dev->board); \
+ \
+ struct bladerf2_board_data *_bd = dev->board_data; \
+ \
+ if (_bd->state < _state) { \
+ log_error("%s: Board state insufficient for operation " \
+ "(current \"%s\", requires \"%s\").\n", \
+ __FUNCTION__, bladerf2_state_to_string[_bd->state], \
+ bladerf2_state_to_string[_state]); \
+ \
+ return BLADERF_ERR_NOT_INIT; \
+ } \
+ } while (0)
+
+/**
+ * @brief Test if board is a bladeRF 2
+ *
+ * @param _dev Device handle
+ *
+ * @return BLADERF_ERR_UNSUPPORTED if board is not a bladeRF 2, continues
+ * otherwise
+ */
+#define CHECK_BOARD_IS_BLADERF2(_dev) \
+ do { \
+ NULL_CHECK(_dev); \
+ NULL_CHECK(_dev->board); \
+ \
+ if (_dev->board != &bladerf2_board_fns) { \
+ log_error("%s: Board type \"%s\" not supported\n", __FUNCTION__, \
+ _dev->board->name); \
+ return BLADERF_ERR_UNSUPPORTED; \
+ } \
+ } while (0)
+
+/**
+ * @brief Call a function and return early if it fails
+ *
+ * @param _fn The function
+ *
+ * @return function return value if less than zero; continues otherwise
+ */
+#define CHECK_STATUS(_fn) \
+ do { \
+ int _s = _fn; \
+ if (_s < 0) { \
+ RETURN_ERROR_STATUS(#_fn, _s); \
+ } \
+ } while (0)
+
+/**
+ * @brief Call a function and goto error if it fails
+ *
+ * @param _fn The function
+ *
+ * @note `int status` must be declared in the including scope
+ */
+#define CHECK_STATUS_GOTO(_fn) \
+ do { \
+ status = _fn; \
+ if (status < 0) { \
+ log_error("%s: %i failed: %s\n", #_fn, status, \
+ bladerf_strerror(status)); \
+ goto error; \
+ } \
+ } while (0)
+
+/**
+ * @brief Call a function and, if it fails, unlock the mutex and return
+ *
+ * @param _fn The function
+ *
+ * @return function return value if less than zero; continues otherwise
+ */
+#define CHECK_STATUS_LOCKED(_fn) \
+ do { \
+ int _s = _fn; \
+ if (_s < 0) { \
+ MUTEX_UNLOCK(__lock); \
+ RETURN_ERROR_STATUS(#_fn, _s); \
+ } \
+ } while (0)
+
+/**
+ * @brief Call a function and return early if it fails, with error translation
+ * from AD936x to bladeRF return codes
+ *
+ * @param _fn The function
+ *
+ * @return function return value if less than zero; continues otherwise
+ */
+#define CHECK_AD936X(_fn) \
+ do { \
+ int _s = _fn; \
+ if (_s < 0) { \
+ RETURN_ERROR_AD9361(#_fn, _s); \
+ } \
+ } while (0)
+
+/**
+ * @brief Call a function and, if it fails, unlock the mutex and return, with
+ * error translation from AD936x to bladeRF return codes
+ *
+ * @param _fn The function
+ *
+ * @return function return value if less than zero; continues otherwise
+ */
+#define CHECK_AD936X_LOCKED(_fn) \
+ do { \
+ int _s = _fn; \
+ if (_s < 0) { \
+ MUTEX_UNLOCK(__lock); \
+ RETURN_ERROR_AD9361(#_fn, _s); \
+ } \
+ } while (0)
+
+/**
+ * @brief Execute a command block with a mutex lock
+ *
+ * @note Variables declared within the including scope must be declared
+ * one-per-line.
+ *
+ * @param _lock Lock to hold
+ * @param _thing Block to execute
+ */
+#define WITH_MUTEX(_lock, _thing) \
+ do { \
+ MUTEX *__lock = _lock; \
+ \
+ MUTEX_LOCK(__lock); \
+ _thing; \
+ MUTEX_UNLOCK(__lock); \
+ } while (0)
+
+/**
+ * @brief Execute command block, conditional to _mode
+ *
+ * @param _dev Device handle
+ * @param _mode Command mode
+ * @param _thing Block to do if it happens
+ */
+#define IF_COMMAND_MODE(_dev, _mode, _thing) \
+ do { \
+ NULL_CHECK(_dev); \
+ NULL_CHECK(_dev->board_data); \
+ \
+ struct bladerf2_board_data *bd = _dev->board_data; \
+ \
+ if (bd->rfic->command_mode == _mode) { \
+ _thing; \
+ }; \
+ } while (0)
+
+
+/******************************************************************************/
+/* Functions */
+/******************************************************************************/
+
+/**
+ * Perform the neccessary device configuration for the specified format
+ * (e.g., enabling/disabling timestamp support), first checking that the
+ * requested format would not conflict with the other stream direction.
+ *
+ * @param dev Device handle
+ * @param[in] dir Direction that is currently being configured
+ * @param[in] format Format the channel is being configured for
+ *
+ * @return 0 on success, BLADERF_ERR_* on failure
+ */
+int perform_format_config(struct bladerf *dev,
+ bladerf_direction dir,
+ bladerf_format format);
+
+/**
+ * Deconfigure and update any state pertaining what a format that a stream
+ * direction is no longer using.
+ *
+ * @param dev Device handle
+ * @param[in] dir Direction that is currently being deconfigured
+ *
+ * @return 0 on success, BLADERF_ERR_* on failure
+ */
+int perform_format_deconfig(struct bladerf *dev, bladerf_direction dir);
+
+bool is_valid_fpga_size(struct bladerf *dev,
+ bladerf_fpga_size fpga,
+ size_t len);
+
+bool is_valid_fw_size(size_t len);
+
+bladerf_tuning_mode default_tuning_mode(struct bladerf *dev);
+
+bool check_total_sample_rate(struct bladerf *dev);
+
+bool does_rffe_dir_have_enabled_ch(uint32_t reg, bladerf_direction dir);
+
+int get_gain_offset(struct bladerf *dev, bladerf_channel ch, float *offset);
+
+#endif // BLADERF2_COMMON_H_