libbladerf-rs 0.5.0

Fully Rust native BladeRF driver
//! Loopback mode control for BladeRF1.
//!
//! Configures internal loopback paths on the LMS6002D for testing and
//! calibration without external cabling. Baseband loopback routes signals
//! internally between the TX and RX digital analog paths. RF loopback
//! routes signals between the TX output and RX input at radio frequency,
//! passing through the antenna port connectors. Firmware loopback operates
//! at the USB transport level, returning transmitted samples as received
//! without passing through the RF chain.

use crate::bladerf1::board::RfLinkSession;
/// Loopback mode for routing signals internally for testing.
///
/// Re-exported from the LMS6002D driver. Includes baseband loopback
/// (BB variants), RF loopback (LNA variants), and firmware loopback.
pub use crate::bladerf1::hardware::lms6002d::loopback::Loopback;
use crate::error::Result;
use crate::maybe_future::Op;
use crate::usb::BladeRf1UsbInterfaceCommands;
use nusb::MaybeFuture;
impl RfLinkSession<'_> {
    /// Sets the loopback mode.
    ///
    /// `Loopback::Firmware` enables USB-level firmware loopback while
    /// configuring the LMS6002D RF loopback through LNA3. All other modes
    /// first disable firmware loopback if it was active, then configure the
    /// LMS6002D loopback path.
    ///
    /// Returns `Error::NotInitialized` if the board has not been initialized.
    pub fn set_loopback(&mut self, lb: Loopback) -> impl MaybeFuture<Output = Result<()>> {
        Op::new(async move {
            self.require_initialized().await?;
            match lb {
                Loopback::Firmware => {
                    self.lms().set_loopback_mode(Loopback::Lna3).await?;
                    self.nios.usb_set_firmware_loopback(true).await
                }
                _ => {
                    let fw_lb_enabled: bool =
                        self.nios.interface().usb_get_firmware_loopback().await?;
                    if fw_lb_enabled {
                        self.nios.usb_set_firmware_loopback(false).await?;
                    }
                    self.lms().set_loopback_mode(lb).await
                }
            }
        })
    }
    /// Sets the loopback mode on the LMS6002D only, without affecting firmware loopback.
    ///
    /// Returns `Error::NotInitialized` if the board has not been initialized.
    pub fn set_lms_loopback(&mut self, lb: Loopback) -> impl MaybeFuture<Output = Result<()>> {
        Op::new(async move {
            self.require_initialized().await?;
            self.lms().set_loopback_mode(lb).await
        })
    }
    /// Returns the current LMS6002D loopback mode, independent of firmware loopback.
    ///
    /// Returns `Error::NotInitialized` if the board has not been initialized.
    pub fn get_lms_loopback(&mut self) -> impl MaybeFuture<Output = Result<Loopback>> {
        Op::new(async move {
            self.require_initialized().await?;
            self.lms().get_loopback_mode().await
        })
    }
    /// Returns the current effective loopback mode.
    ///
    /// Checks for firmware loopback first; if not active, returns the
    /// LMS6002D loopback mode.
    ///
    /// Returns `Error::NotInitialized` if the board has not been initialized.
    pub fn get_loopback(&mut self) -> impl MaybeFuture<Output = Result<Loopback>> {
        Op::new(async move {
            self.require_initialized().await?;
            let mut lb = Loopback::None;
            let fw_lb_enabled = self.nios.interface().usb_get_firmware_loopback().await?;
            if fw_lb_enabled {
                lb = Loopback::Firmware;
            }
            if lb == Loopback::None {
                lb = self.lms().get_loopback_mode().await?;
            }
            Ok(lb)
        })
    }
    /// Returns true if the given loopback mode is supported on BladeRF1.
    pub fn is_loopback_mode_supported(&self, lb: Loopback) -> bool {
        let supported_modes = [
            Loopback::None,
            Loopback::BbTxlpfRxvga2,
            Loopback::BbTxlpfRxlpf,
            Loopback::BbTxvga1Rxlpf,
            Loopback::BbTxvga1Rxvga2,
            Loopback::Firmware,
            Loopback::Lna1,
            Loopback::Lna2,
            Loopback::Lna3,
        ];
        supported_modes.contains(&lb)
    }
}