Fix TX gain gating corruption with multi-device TX mute state sharing#1065
Open
MrCry0 wants to merge 2 commits into
Open
Fix TX gain gating corruption with multi-device TX mute state sharing#1065MrCry0 wants to merge 2 commits into
MrCry0 wants to merge 2 commits into
Conversation
bladerf_set_gain(dev, BLADERF_CHANNEL_TX(*), ...) branches in
_rfic_host_set_gain() on the current TX mute state: when unmuted it issues
an AD9361 SPI write through set_gain_stage("dsa"), and when muted it only
updates the cached attenuation. That decision was driven by txmute_get(),
which reads a process-wide file-scope static (tx_mute_state[2]) in
fpga_common/src/ad936x_helpers.c.
With two bladeRFs open in the same process, both phys share that single
2-element array. txmute_set() additionally short-circuits whenever the
requested state already matches the global, so the second device's
init/enable_module mute toggles are silently skipped. The two phys'
actual hardware state then drifts from the gating variable, and a
subsequent bladerf_set_gain() on one device can take the wrong branch:
the requested device's hardware is not written while the other device's
TX attenuation is the most recent SPI write to land, surfacing as "I set
gain on A and B's gain changed."
Move the gating state into struct bladerf2_board_data as
tx_mute_state[2] and introduce _host_txmute_get / _host_txmute_set in
rfic_host.c that read and write that per-device field while keeping the
existing AD9361 attenuation behaviour. Repoint every host call site
(_rfic_host_enable_module, _rfic_host_get_gain, _rfic_host_set_gain,
_rfic_host_get_txmute, _rfic_host_set_txmute) at the new wrappers. The
fpga_common helpers remain in place and continue to serve the NIOS II
RFIC controller, which only ever sees one device.
Signed-off-by: Oleksandr Suvorov <cryosay@gmail.com>
The static tx_mute_state[2] array and the txmute_get/txmute_set helpers in fpga_common/src/ad936x_helpers.c are only correct when at most one bladeRF exists in the address space, because the gating state lives in file scope and is keyed solely by RFIC channel. That holds on the NIOS II RFIC controller (one device per FPGA) but not in the host library, where multiple bladeRFs can be open concurrently. The host library now keeps its own per-device state and wrappers in struct bladerf2_board_data / rfic_host.c, so the fpga_common variants have no remaining host callers. Gate the static and both function bodies/prototypes with #if defined(BLADERF_NIOS_BUILD) so they are only built into the NIOS firmware. The cached-attenuation helpers (txmute_get_cached / txmute_set_cached) are inherently per-phy and stay available to both targets. Signed-off-by: Oleksandr Suvorov <cryosay@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
When multiple bladeRF2 devices are opened in the same process, TX gain updates may be silently skipped due to shared TX mute state stored in a process-wide static (
tx_mute_state[2]infpga_common)._rfic_host_set_gain()decides whether to perform an AD9361 SPI write based on the current TX mute state. Because this state is shared across all devices, one device can incorrectly influence gain handling on another.This leads to incorrect gating decisions where valid gain updates are dropped without error.
How to reproduce
Open two devices in the same process:
Set divergent TX mute states:
Apply gain on device A:
Observe:
This happens because
tx_mute_state[]is shared globally and reflects device B’s mute state when A performs the gain update.Fix
Result
TX gain operations are now correctly evaluated per device. Device A no longer depends on device B’s mute state, eliminating silent gain suppression in multi-device configurations.