diff --git a/fpga_common/include/ad936x_helpers.h b/fpga_common/include/ad936x_helpers.h index bd0037a55..043483593 100644 --- a/fpga_common/include/ad936x_helpers.h +++ b/fpga_common/include/ad936x_helpers.h @@ -59,6 +59,11 @@ int txmute_set_cached(struct ad9361_rf_phy *phy, bladerf_channel ch, uint32_t atten); +/* txmute_get/txmute_set track mute state in a file-scope static and are only + * safe when a single bladeRF exists per process. They remain available to the + * NIOS II RFIC controller (one device per FPGA); the host library uses + * per-device equivalents declared in board/bladerf2/rfic_host.c. */ +#if defined(BLADERF_NIOS_BUILD) /** * @brief Get the transmit mute state * @@ -85,6 +90,7 @@ int txmute_get(struct ad9361_rf_phy *phy, bladerf_channel ch, bool *state); * @return 0 on success, value from \ref RETCODES list on failure */ int txmute_set(struct ad9361_rf_phy *phy, bladerf_channel ch, bool state); +#endif /** * @brief Set AD9361 RFIC RF port diff --git a/fpga_common/src/ad936x_helpers.c b/fpga_common/src/ad936x_helpers.c index 15982faa5..9c882ea98 100644 --- a/fpga_common/src/ad936x_helpers.c +++ b/fpga_common/src/ad936x_helpers.c @@ -33,7 +33,15 @@ #include "ad936x_helpers.h" #include "bladerf2_common.h" +/* The NIOS II RFIC controller only ever serves one bladeRF, so a single + * file-scope state array suffices there. On the host, where multiple + * bladeRFs may be open in the same process, the equivalent per-device + * bookkeeping lives in struct bladerf2_board_data (see _host_txmute_get/ + * _host_txmute_set in board/bladerf2/rfic_host.c); the symbols below are + * therefore not built into the host library. */ +#if defined(BLADERF_NIOS_BUILD) static bool tx_mute_state[2] = { false }; +#endif uint32_t txmute_get_cached(struct ad9361_rf_phy *phy, bladerf_channel ch) { @@ -63,6 +71,7 @@ int txmute_set_cached(struct ad9361_rf_phy *phy, } } +#if defined(BLADERF_NIOS_BUILD) int txmute_get(struct ad9361_rf_phy *phy, bladerf_channel ch, bool *state) { int rfic_ch = (ch >> 1); @@ -115,6 +124,7 @@ int txmute_set(struct ad9361_rf_phy *phy, bladerf_channel ch, bool state) return 0; } +#endif /* BLADERF_NIOS_BUILD */ int set_ad9361_port_by_freq(struct ad9361_rf_phy *phy, bladerf_channel ch, diff --git a/host/libraries/libbladeRF/src/board/bladerf2/common.h b/host/libraries/libbladeRF/src/board/bladerf2/common.h index 4f86f0f33..37c7dfa88 100644 --- a/host/libraries/libbladeRF/src/board/bladerf2/common.h +++ b/host/libraries/libbladeRF/src/board/bladerf2/common.h @@ -186,6 +186,11 @@ struct bladerf2_board_data { bladerf_rfic_rxfir rxfir; bladerf_rfic_txfir txfir; + /* Per-device TX mute state, indexed by RFIC channel (0,1). Tracked here + * rather than as a process-wide static so that multiple bladeRFs opened in + * the same process don't share the same mute-gating bookkeeping. */ + bool tx_mute_state[2]; + /* If true, RFIC control will be fully de-initialized on close, instead of * just put into a standby state. */ bool rfic_reset_on_close; diff --git a/host/libraries/libbladeRF/src/board/bladerf2/rfic_host.c b/host/libraries/libbladeRF/src/board/bladerf2/rfic_host.c index 6e61c8fba..88d44aff1 100644 --- a/host/libraries/libbladeRF/src/board/bladerf2/rfic_host.c +++ b/host/libraries/libbladeRF/src/board/bladerf2/rfic_host.c @@ -229,6 +229,71 @@ int rfic_host_start_tx_recal_update(struct bladerf *dev, return 0; } +/******************************************************************************/ +/* TX mute (per-device) */ +/* */ +/* These mirror txmute_get/txmute_set in fpga_common/src/ad936x_helpers.c, */ +/* but keep the gating state in struct bladerf2_board_data rather than a */ +/* process-wide static so that two bladeRFs opened in the same process do not */ +/* alias each other's mute-state bookkeeping. The fpga_common variants remain */ +/* in use by the NIOS II RFIC controller, which only ever sees one device. */ +/******************************************************************************/ + +static int _host_txmute_get(struct bladerf *dev, + bladerf_channel ch, + bool *state) +{ + struct bladerf2_board_data *board_data = dev->board_data; + int rfic_ch = (ch >> 1); + + *state = board_data->tx_mute_state[rfic_ch]; + return 0; +} + +static int _host_txmute_set(struct bladerf *dev, + bladerf_channel ch, + bool state) +{ + struct bladerf2_board_data *board_data = dev->board_data; + struct ad9361_rf_phy *phy = board_data->phy; + int rfic_ch = (ch >> 1); + uint32_t const MUTED_ATTEN = 89750; + uint32_t atten, cached; + int status; + + if (board_data->tx_mute_state[rfic_ch] == state) { + return 0; + } + + if (state) { + uint32_t readval; + + status = ad9361_get_tx_attenuation(phy, rfic_ch, &readval); + if (status < 0) { + return errno_ad9361_to_bladerf(status); + } + + cached = readval; + atten = MUTED_ATTEN; + } else { + cached = txmute_get_cached(phy, ch); + atten = cached; + } + + status = ad9361_set_tx_attenuation(phy, rfic_ch, atten); + if (status < 0) { + return errno_ad9361_to_bladerf(status); + } + + status = txmute_set_cached(phy, ch, cached); + if (status < 0) { + return status; + } + + board_data->tx_mute_state[rfic_ch] = state; + return 0; +} + static int _rfic_host_initialize(struct bladerf *dev) { struct bladerf2_board_data *board_data = dev->board_data; @@ -425,7 +490,7 @@ static int _rfic_host_enable_module(struct bladerf *dev, /* Set/unset TX mute */ if (BLADERF_CHANNEL_IS_TX(ch)) { - txmute_set(phy, ch, !enable); + _host_txmute_set(dev, ch, !enable); } } @@ -786,7 +851,7 @@ static int _rfic_host_get_gain(struct bladerf *dev, if (BLADERF_CHANNEL_IS_TX(ch)) { bool muted; - CHECK_STATUS(txmute_get(phy, ch, &muted)); + CHECK_STATUS(_host_txmute_get(dev, ch, &muted)); if (muted) { struct bladerf_range const *range = NULL; @@ -824,7 +889,7 @@ static int _rfic_host_set_gain(struct bladerf *dev, if (BLADERF_CHANNEL_IS_TX(ch)) { bool muted; - CHECK_STATUS(txmute_get(phy, ch, &muted)); + CHECK_STATUS(_host_txmute_get(dev, ch, &muted)); if (muted) { struct bladerf_range const *range = NULL; @@ -1091,11 +1156,8 @@ static int _rfic_host_get_txmute(struct bladerf *dev, bladerf_channel ch, bool *state) { - struct bladerf2_board_data *board_data = dev->board_data; - struct ad9361_rf_phy *phy = board_data->phy; - if (BLADERF_CHANNEL_IS_TX(ch)) { - return txmute_get(phy, ch, state); + return _host_txmute_get(dev, ch, state); } return BLADERF_ERR_UNSUPPORTED; @@ -1105,11 +1167,8 @@ static int _rfic_host_set_txmute(struct bladerf *dev, bladerf_channel ch, bool state) { - struct bladerf2_board_data *board_data = dev->board_data; - struct ad9361_rf_phy *phy = board_data->phy; - if (BLADERF_CHANNEL_IS_TX(ch)) { - return txmute_set(phy, ch, state); + return _host_txmute_set(dev, ch, state); } return BLADERF_ERR_UNSUPPORTED;