libbladerf-rs 0.3.0

Fully Rust native BladeRF driver
use crate::bladerf1::hardware::lms6002d::{Band, Tune};
use crate::bladerf1::protocol::{nios_decode_retune, nios_encode_retune};
use crate::channel::Channel;
use crate::error::{Error, Result};
use crate::nios_client::NiosCore;
use crate::protocol::nios::NiosPkt8x32Target;
use crate::protocol::nios::packet_generic::NiosNum;
use crate::transport::Transport;
use crate::transport::usb::UsbTransport;
use crate::transport::usb::{BladeRf1UsbInterfaceCommands, UsbInterfaceCommands};
use crate::version::SemanticVersion;
use nusb::Interface;
impl From<Interface> for NiosClient {
    fn from(interface: Interface) -> Self {
        NiosClient::new(UsbTransport::new(interface))
    }
}
pub struct RetuneResult {
    pub duration: u64,
}

pub struct NiosClient(NiosCore<UsbTransport>);
impl NiosClient {
    pub fn new(transport: UsbTransport) -> Self {
        Self(NiosCore::new(transport))
    }
    pub fn transport(&self) -> &UsbTransport {
        self.0.transport()
    }
    pub fn get_alt_setting(&self) -> u8 {
        self.0.get_alt_setting()
    }
    pub fn nios_read<A: NiosNum + Send, D: NiosNum + Send>(
        &mut self,
        id: impl Into<u8>,
        addr: A,
    ) -> Result<D> {
        self.0.nios_read(id, addr)
    }
    pub fn nios_write<A: NiosNum + Send, D: NiosNum + Send>(
        &mut self,
        id: impl Into<u8>,
        addr: A,
        data: D,
    ) -> Result<()> {
        self.0.nios_write(id, addr, data)
    }
    pub fn nios_config_read(&mut self) -> Result<u32> {
        self.0.nios_config_read()
    }
    pub fn nios_config_write(&mut self, value: u32) -> Result<()> {
        self.0.nios_config_write(value)
    }
    pub fn nios_expansion_gpio_read(&mut self) -> Result<u32> {
        self.0.nios_expansion_gpio_read()
    }
    pub fn nios_expansion_gpio_write(&mut self, mask: u32, val: u32) -> Result<()> {
        self.0.nios_expansion_gpio_write(mask, val)
    }
    pub fn nios_expansion_gpio_dir_read(&mut self) -> Result<u32> {
        self.0.nios_expansion_gpio_dir_read()
    }
    pub fn nios_expansion_gpio_dir_write(&mut self, mask: u32, val: u32) -> Result<()> {
        self.0.nios_expansion_gpio_dir_write(mask, val)
    }
    pub fn nios_get_fpga_version(&mut self) -> Result<SemanticVersion> {
        self.0.nios_get_fpga_version()
    }
    pub fn nios_get_iq_gain_correction(&mut self, ch: Channel) -> Result<i16> {
        self.0.nios_get_iq_gain_correction(ch)
    }
    pub fn nios_get_iq_phase_correction(&mut self, ch: Channel) -> Result<i16> {
        self.0.nios_get_iq_phase_correction(ch)
    }
    pub fn nios_set_iq_gain_correction(&mut self, ch: Channel, value: i16) -> Result<()> {
        self.0.nios_set_iq_gain_correction(ch, value)
    }
    pub fn nios_set_iq_phase_correction(&mut self, ch: Channel, value: i16) -> Result<()> {
        self.0.nios_set_iq_phase_correction(ch, value)
    }
    #[allow(clippy::too_many_arguments)]
    pub fn nios_retune(
        &mut self,
        channel: Channel,
        timestamp: u64,
        nint: u16,
        nfrac: u32,
        freqsel: u8,
        vcocap: u8,
        band: Band,
        tune: Tune,
        xb_gpio: u8,
    ) -> Result<RetuneResult> {
        const RETUNE_NOW: u64 = 0x00;
        if timestamp == RETUNE_NOW {
            log::trace!("Clearing Retune Queue");
        }
        let out_buf = self.0.transport_mut().out_buffer()?;
        nios_encode_retune(
            out_buf, channel, timestamp, nint, nfrac, freqsel, vcocap, band, tune, xb_gpio,
        )?;
        let response = self.0.transport_mut().submit(None)?;
        let response_pkt = nios_decode_retune(response)?;
        if !response_pkt.is_success() {
            let is_immediate = response_pkt.duration() == RETUNE_NOW;
            return if is_immediate {
                Err(Error::TuningFailed)
            } else {
                Err(Error::RetuneQueueFull)
            };
        }
        Ok(RetuneResult {
            duration: response_pkt.duration(),
        })
    }
    pub fn nios_xb200_synth_write(&mut self, value: u32) -> Result<()> {
        self.nios_write::<u8, u32>(NiosPkt8x32Target::Adf4_351, 0, value)
    }
}
impl UsbInterfaceCommands for NiosClient {
    fn usb_vendor_cmd_int(&self, cmd: u8) -> Result<u32> {
        self.transport().usb_vendor_cmd_int(cmd)
    }
    fn usb_vendor_cmd_int_w_value(&self, cmd: u8, wvalue: u16) -> Result<u32> {
        self.transport().usb_vendor_cmd_int_w_value(cmd, wvalue)
    }
    fn usb_vendor_cmd_int_w_index(&self, cmd: u8, windex: u16) -> Result<u32> {
        self.transport().usb_vendor_cmd_int_w_index(cmd, windex)
    }
    fn usb_vendor_cmd_out_w_index(&self, cmd: u8, windex: u16, data: &[u8]) -> Result<()> {
        self.transport()
            .usb_vendor_cmd_out_w_index(cmd, windex, data)
    }
    fn usb_vendor_cmd_in_w_index_data(&self, cmd: u8, windex: u16, buf: &mut [u8]) -> Result<()> {
        self.transport()
            .usb_vendor_cmd_in_w_index_data(cmd, windex, buf)
    }
    fn usb_change_setting(&mut self, setting: u8) -> Result<()> {
        self.0.transport_mut().usb_change_setting(setting)
    }
}
impl BladeRf1UsbInterfaceCommands for NiosClient {
    fn usb_enable_module(&self, channel: Channel, enable: bool) -> Result<()> {
        self.transport().usb_enable_module(channel, enable)
    }
    fn usb_set_firmware_loopback(&mut self, enable: bool) -> Result<()> {
        self.0.transport_mut().usb_set_firmware_loopback(enable)
    }
    fn usb_get_firmware_loopback(&self) -> Result<bool> {
        self.transport().usb_get_firmware_loopback()
    }
    fn usb_device_reset(&self) -> Result<()> {
        self.transport().usb_device_reset()
    }
    fn usb_is_firmware_ready(&self) -> Result<bool> {
        self.transport().usb_is_firmware_ready()
    }
}