libbladerf-rs 0.3.0

Fully Rust native BladeRF driver
use crate::bladerf1::BladeRf1;
use crate::error::Result;
pub(crate) const BLADERF_XB_AUX_EN: u32 = 0x000002;
pub(crate) const BLADERF_XB_TX_LED: u32 = 0x000010;
pub(crate) const BLADERF_XB_RX_LED: u32 = 0x000020;
pub(crate) const BLADERF_XB_TRX_TXN: u32 = 0x000040;
pub(crate) const BLADERF_XB_TRX_RXN: u32 = 0x000080;
pub(crate) const BLADERF_XB_TRX_MASK: u32 = 0x0000c0;
pub(crate) const BLADERF_XB_PA_EN: u32 = 0x000200;
pub(crate) const BLADERF_XB_LNA_EN: u32 = 0x000400;
pub(crate) const BLADERF_XB_CS: u32 = 0x010000;
pub(crate) const BLADERF_XB_CSEL: u32 = 0x040000;
pub(crate) const BLADERF_XB_DOUT: u32 = 0x100000;
pub(crate) const BLADERF_XB_SCLK: u32 = 0x400000;
pub(crate) const XB300_DETECT_MASK: u32 = BLADERF_XB_CS | BLADERF_XB_CSEL | BLADERF_XB_LNA_EN;
#[derive(Debug)]
pub enum BladeRfXb300Trx {
    Tx = 0,
    Rx,
    Unset,
}
#[derive(Debug)]
pub enum BladeRfXb300Amplifier {
    Pa = 0,
    Lna,
    Aux,
}
impl BladeRf1 {
    pub fn xb300_attach(&mut self) -> Result<()> {
        let mut val = BLADERF_XB_TX_LED
            | BLADERF_XB_RX_LED
            | BLADERF_XB_TRX_MASK
            | BLADERF_XB_PA_EN
            | BLADERF_XB_LNA_EN
            | BLADERF_XB_CSEL
            | BLADERF_XB_SCLK
            | BLADERF_XB_CS;
        self.nios.nios_expansion_gpio_dir_write(0xffffffff, val)?;
        val = BLADERF_XB_CS | BLADERF_XB_LNA_EN;
        self.nios.nios_expansion_gpio_write(0xffffffff, val)?;
        Ok(())
    }
    pub fn xb300_enable(&mut self, _enable: bool) -> Result<()> {
        let val = BLADERF_XB_CS | BLADERF_XB_CSEL | BLADERF_XB_LNA_EN;
        self.nios.nios_expansion_gpio_write(0xffffffff, val)?;
        let _pwr = self.xb300_get_output_power()?;
        Ok(())
    }
    pub fn xb300_init(&mut self) -> Result<()> {
        log::debug!("Setting TRX path to TX");
        self.xb300_set_trx(BladeRfXb300Trx::Tx)
    }
    pub fn xb300_set_trx(&mut self, trx: BladeRfXb300Trx) -> Result<()> {
        let mut val = self.nios.nios_expansion_gpio_read()?;
        val &= !BLADERF_XB_TRX_MASK;
        match trx {
            BladeRfXb300Trx::Rx => val |= BLADERF_XB_TRX_RXN,
            BladeRfXb300Trx::Tx => val |= BLADERF_XB_TRX_TXN,
            BladeRfXb300Trx::Unset => {}
        }
        self.nios.nios_expansion_gpio_write(0xffffffff, val)
    }
    pub fn xb300_get_trx(&mut self) -> Result<BladeRfXb300Trx> {
        let mut val = self.nios.nios_expansion_gpio_read()?;
        val &= BLADERF_XB_TRX_MASK;
        let trx = if val == 0 {
            BladeRfXb300Trx::Unset
        } else if val & BLADERF_XB_TRX_RXN != 0 {
            BladeRfXb300Trx::Rx
        } else {
            BladeRfXb300Trx::Tx
        };
        Ok(trx)
    }
    pub fn xb300_set_amplifier_enable(
        &mut self,
        amp: BladeRfXb300Amplifier,
        enable: bool,
    ) -> Result<()> {
        let mut val = self.nios.nios_expansion_gpio_read()?;
        match amp {
            BladeRfXb300Amplifier::Pa => {
                if enable {
                    val |= BLADERF_XB_TX_LED;
                    val |= BLADERF_XB_PA_EN;
                } else {
                    val &= !BLADERF_XB_TX_LED;
                    val &= !BLADERF_XB_PA_EN;
                }
            }
            BladeRfXb300Amplifier::Lna => {
                if enable {
                    val |= BLADERF_XB_RX_LED;
                    val &= !BLADERF_XB_LNA_EN;
                } else {
                    val &= !BLADERF_XB_RX_LED;
                    val |= BLADERF_XB_LNA_EN;
                }
            }
            BladeRfXb300Amplifier::Aux => {
                if enable {
                    val |= BLADERF_XB_AUX_EN;
                } else {
                    val &= !BLADERF_XB_AUX_EN;
                }
            }
        }
        self.nios.nios_expansion_gpio_write(0xffffffff, val)
    }
    pub fn xb300_get_amplifier_enable(&mut self, amp: BladeRfXb300Amplifier) -> Result<bool> {
        let val = self.nios.nios_expansion_gpio_read()?;
        match amp {
            BladeRfXb300Amplifier::Pa => Ok(val & BLADERF_XB_PA_EN != 0),
            BladeRfXb300Amplifier::Lna => Ok(val & BLADERF_XB_LNA_EN != 0),
            BladeRfXb300Amplifier::Aux => Ok(val & BLADERF_XB_AUX_EN != 0),
        }
    }
    pub fn xb300_get_output_power(&mut self) -> Result<f32> {
        let mut ret = 0;
        let mut val = self.nios.nios_expansion_gpio_read()?;
        val &= !(BLADERF_XB_CS | BLADERF_XB_SCLK | BLADERF_XB_CSEL);
        self.nios
            .nios_expansion_gpio_write(0xffffffff, BLADERF_XB_SCLK | val)?;
        self.nios
            .nios_expansion_gpio_write(0xffffffff, BLADERF_XB_CS | BLADERF_XB_SCLK | val)?;
        for i in 1u32..=14u32 {
            self.nios.nios_expansion_gpio_write(0xffffffff, val)?;
            self.nios
                .nios_expansion_gpio_write(0xffffffff, BLADERF_XB_SCLK | val)?;
            let rval = self.nios.nios_expansion_gpio_read()?;
            if (2..=11).contains(&i) {
                ret |= (!!(rval & BLADERF_XB_DOUT)) << (11 - i);
            }
        }
        let volt = (1.8f32 / 1_024.0f32) * ret as f32;
        let volt2 = volt * volt;
        let volt3 = volt2 * volt;
        let volt4 = volt3 * volt;
        let pwr = -503.933f32 * volt4 + 1_409.489f32 * volt3 - 1_487.84f32 * volt2
            + 722.9793f32 * volt
            - 114.7529f32;
        Ok(pwr)
    }
}