forked from M-Labs/humpback-dds
dds: add RAM mode
This commit is contained in:
parent
a5dbfdaf4f
commit
25f8363e54
13
Cargo.toml
13
Cargo.toml
|
@ -13,7 +13,6 @@ embedded-hal = "0.2.4"
|
||||||
stm32h7xx-hal = {version = "0.7.1", features = [ "stm32h743v", "rt", "unproven", "ethernet", "phy_lan8742a" ] }
|
stm32h7xx-hal = {version = "0.7.1", features = [ "stm32h743v", "rt", "unproven", "ethernet", "phy_lan8742a" ] }
|
||||||
smoltcp = { version = "0.6.0", default-features = false, features = [ "ethernet", "proto-ipv4", "proto-ipv6", "socket-tcp", "log" ] }
|
smoltcp = { version = "0.6.0", default-features = false, features = [ "ethernet", "proto-ipv4", "proto-ipv6", "socket-tcp", "log" ] }
|
||||||
nb = "1.0.0"
|
nb = "1.0.0"
|
||||||
libm = "0.2.0"
|
|
||||||
|
|
||||||
embedded-nal = "0.1.0"
|
embedded-nal = "0.1.0"
|
||||||
minimq = { git = "https://github.com/quartiq/minimq.git", branch = "master" }
|
minimq = { git = "https://github.com/quartiq/minimq.git", branch = "master" }
|
||||||
|
@ -33,6 +32,18 @@ branch = "issue-4"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = [ "build-info", "unit-frequency", "unit-angle" ]
|
features = [ "build-info", "unit-frequency", "unit-angle" ]
|
||||||
|
|
||||||
|
# [dependencies.uom]
|
||||||
|
# version = "0.29.0"
|
||||||
|
# default-features = false
|
||||||
|
# features = [
|
||||||
|
# "autoconvert",
|
||||||
|
# "usize", "u8", "u16", "u32", "u64",
|
||||||
|
# "isize", "i8", "i16", "i32", "i64",
|
||||||
|
# "f32", "f64",
|
||||||
|
# "si",
|
||||||
|
# "try-from"
|
||||||
|
# ]
|
||||||
|
|
||||||
# Use below SCPI dependency when need to modify SCPI fork offline
|
# Use below SCPI dependency when need to modify SCPI fork offline
|
||||||
# [dependencies.scpi]
|
# [dependencies.scpi]
|
||||||
# path = "../scpi-fork/scpi"
|
# path = "../scpi-fork/scpi"
|
||||||
|
|
158
src/dds.rs
158
src/dds.rs
|
@ -1,7 +1,8 @@
|
||||||
use embedded_hal::blocking::spi::Transfer;
|
use embedded_hal::blocking::spi::Transfer;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
use libm::round;
|
use core::convert::TryInto;
|
||||||
|
use arrayvec::ArrayVec;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bitmask for all configurations (Order: CFR3, CFR2, CFR1)
|
* Bitmask for all configurations (Order: CFR3, CFR2, CFR1)
|
||||||
|
@ -63,6 +64,23 @@ construct_bitmask!(DDSCFRMask; u32;
|
||||||
const WRITE_MASK :u8 = 0x00;
|
const WRITE_MASK :u8 = 0x00;
|
||||||
const READ_MASK :u8 = 0x80;
|
const READ_MASK :u8 = 0x80;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum RAMDestination {
|
||||||
|
Frequency = 0,
|
||||||
|
Phase = 1,
|
||||||
|
Amplitude = 2,
|
||||||
|
Polar = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum RAMOperationMode {
|
||||||
|
DirectSwitch = 0,
|
||||||
|
RampUp = 1,
|
||||||
|
BidirectionalRamp = 2,
|
||||||
|
ContinuousBidirectionalRamp = 3,
|
||||||
|
ContinuousRecirculate = 4,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct DDS<SPI> {
|
pub struct DDS<SPI> {
|
||||||
spi: SPI,
|
spi: SPI,
|
||||||
f_ref_clk: f64,
|
f_ref_clk: f64,
|
||||||
|
@ -143,7 +161,7 @@ where
|
||||||
// Get a divider
|
// Get a divider
|
||||||
let divider = (f_sys_clk / self.f_ref_clk) as u64;
|
let divider = (f_sys_clk / self.f_ref_clk) as u64;
|
||||||
// Reject extreme divider values. However, accept no frequency division
|
// Reject extreme divider values. However, accept no frequency division
|
||||||
if ((divider > 127 || divider < 12) && divider != 1) {
|
if (divider > 127 || divider < 12) && divider != 1 {
|
||||||
// panic!("Invalid divider value for PLL!");
|
// panic!("Invalid divider value for PLL!");
|
||||||
return Err(Error::DDSCLKError);
|
return Err(Error::DDSCLKError);
|
||||||
}
|
}
|
||||||
|
@ -345,16 +363,10 @@ where
|
||||||
} else {
|
} else {
|
||||||
((resolutions[2] as f64) * amp_scale_factor) as u16
|
((resolutions[2] as f64) * amp_scale_factor) as u16
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup configuration registers before writing single tone register
|
// Setup configuration registers before writing single tone register
|
||||||
self.set_configurations(&mut [
|
self.enable_single_tone_configuration()?;
|
||||||
(DDSCFRMask::RAM_ENABLE, 0),
|
|
||||||
(DDSCFRMask::DIGITAL_RAMP_ENABLE, 0),
|
|
||||||
(DDSCFRMask::OSK_ENABLE, 0),
|
|
||||||
(DDSCFRMask::PARALLEL_DATA_PORT_ENABLE, 0),
|
|
||||||
])?;
|
|
||||||
self.set_configurations(&mut [
|
|
||||||
(DDSCFRMask::EN_AMP_SCALE_SINGLE_TONE_PRO, 1),
|
|
||||||
])?;
|
|
||||||
// Transfer single tone profile data
|
// Transfer single tone profile data
|
||||||
self.write_register(0x0E + profile, &mut [
|
self.write_register(0x0E + profile, &mut [
|
||||||
((asf >> 8 ) & 0xFF) as u8,
|
((asf >> 8 ) & 0xFF) as u8,
|
||||||
|
@ -376,15 +388,7 @@ where
|
||||||
pub fn set_single_tone_profile_frequency(&mut self, profile: u8, f_out: f64) -> Result<(), Error<E>> {
|
pub fn set_single_tone_profile_frequency(&mut self, profile: u8, f_out: f64) -> Result<(), Error<E>> {
|
||||||
|
|
||||||
// Setup configuration registers before writing single tone register
|
// Setup configuration registers before writing single tone register
|
||||||
self.set_configurations(&mut [
|
self.enable_single_tone_configuration()?;
|
||||||
(DDSCFRMask::RAM_ENABLE, 0),
|
|
||||||
(DDSCFRMask::DIGITAL_RAMP_ENABLE, 0),
|
|
||||||
(DDSCFRMask::OSK_ENABLE, 0),
|
|
||||||
(DDSCFRMask::PARALLEL_DATA_PORT_ENABLE, 0),
|
|
||||||
])?;
|
|
||||||
self.set_configurations(&mut [
|
|
||||||
(DDSCFRMask::EN_AMP_SCALE_SINGLE_TONE_PRO, 1),
|
|
||||||
])?;
|
|
||||||
|
|
||||||
// Calculate frequency tuning work (FTW)
|
// Calculate frequency tuning work (FTW)
|
||||||
let f_res: u64 = 1 << 32;
|
let f_res: u64 = 1 << 32;
|
||||||
|
@ -412,15 +416,7 @@ where
|
||||||
pub fn set_single_tone_profile_phase(&mut self, profile: u8, phase_offset: f64) -> Result<(), Error<E>> {
|
pub fn set_single_tone_profile_phase(&mut self, profile: u8, phase_offset: f64) -> Result<(), Error<E>> {
|
||||||
|
|
||||||
// Setup configuration registers before writing single tone register
|
// Setup configuration registers before writing single tone register
|
||||||
self.set_configurations(&mut [
|
self.enable_single_tone_configuration()?;
|
||||||
(DDSCFRMask::RAM_ENABLE, 0),
|
|
||||||
(DDSCFRMask::DIGITAL_RAMP_ENABLE, 0),
|
|
||||||
(DDSCFRMask::OSK_ENABLE, 0),
|
|
||||||
(DDSCFRMask::PARALLEL_DATA_PORT_ENABLE, 0),
|
|
||||||
])?;
|
|
||||||
self.set_configurations(&mut [
|
|
||||||
(DDSCFRMask::EN_AMP_SCALE_SINGLE_TONE_PRO, 1),
|
|
||||||
])?;
|
|
||||||
|
|
||||||
// Calculate phase offset work (POW)
|
// Calculate phase offset work (POW)
|
||||||
let phase_res: u64 = 1 << 16;
|
let phase_res: u64 = 1 << 16;
|
||||||
|
@ -446,15 +442,7 @@ where
|
||||||
pub fn set_single_tone_profile_amplitude(&mut self, profile: u8, amp_scale_factor: f64) -> Result<(), Error<E>> {
|
pub fn set_single_tone_profile_amplitude(&mut self, profile: u8, amp_scale_factor: f64) -> Result<(), Error<E>> {
|
||||||
|
|
||||||
// Setup configuration registers before writing single tone register
|
// Setup configuration registers before writing single tone register
|
||||||
self.set_configurations(&mut [
|
self.enable_single_tone_configuration()?;
|
||||||
(DDSCFRMask::RAM_ENABLE, 0),
|
|
||||||
(DDSCFRMask::DIGITAL_RAMP_ENABLE, 0),
|
|
||||||
(DDSCFRMask::OSK_ENABLE, 0),
|
|
||||||
(DDSCFRMask::PARALLEL_DATA_PORT_ENABLE, 0),
|
|
||||||
])?;
|
|
||||||
self.set_configurations(&mut [
|
|
||||||
(DDSCFRMask::EN_AMP_SCALE_SINGLE_TONE_PRO, 1),
|
|
||||||
])?;
|
|
||||||
|
|
||||||
// Calculate amplitude_scale_factor (ASF)
|
// Calculate amplitude_scale_factor (ASF)
|
||||||
let amp_res: u64 = 1 << 14;
|
let amp_res: u64 = 1 << 14;
|
||||||
|
@ -476,6 +464,96 @@ where
|
||||||
self.write_register(0x0E + profile, &mut register)
|
self.write_register(0x0E + profile, &mut register)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to switch into single tone mode
|
||||||
|
// Need to setup configuration registers before writing single tone register
|
||||||
|
fn enable_single_tone_configuration(&mut self) -> Result<(), Error<E>> {
|
||||||
|
|
||||||
|
self.set_configurations(&mut [
|
||||||
|
(DDSCFRMask::RAM_ENABLE, 0),
|
||||||
|
(DDSCFRMask::DIGITAL_RAMP_ENABLE, 0),
|
||||||
|
(DDSCFRMask::OSK_ENABLE, 0),
|
||||||
|
(DDSCFRMask::PARALLEL_DATA_PORT_ENABLE, 0),
|
||||||
|
])?;
|
||||||
|
self.set_configurations(&mut [
|
||||||
|
(DDSCFRMask::EN_AMP_SCALE_SINGLE_TONE_PRO, 1),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to switch into RAM mode
|
||||||
|
// Need to setup configuration registers before writing into RAM profile register
|
||||||
|
fn enable_ram_configuration(&mut self, ram_dst: RAMDestination) -> Result<(), Error<E>> {
|
||||||
|
self.set_configurations(&mut [
|
||||||
|
(DDSCFRMask::RAM_ENABLE, 1),
|
||||||
|
(DDSCFRMask::RAM_PLAYBACK_DST, ram_dst as u32),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to switch out of RAM mode
|
||||||
|
// Need to setup configuration registers before writing into RAM profile register
|
||||||
|
fn disable_ram_configuration(&mut self) -> Result<(), Error<E>> {
|
||||||
|
self.set_configurations(&mut [
|
||||||
|
(DDSCFRMask::RAM_ENABLE, 0),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure a RAM mode profile
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
pub fn set_ram_profile(&mut self, profile: u8, start_addr: u16, end_addr: u16,
|
||||||
|
ram_dst: RAMDestination, no_dwell_high: bool, zero_crossing: bool,
|
||||||
|
op_mode: RAMOperationMode, playback_rate: f64, data: &[u8]
|
||||||
|
) -> Result<(), Error<E>> {
|
||||||
|
|
||||||
|
// Check the legality of this setup
|
||||||
|
assert!(profile < 7);
|
||||||
|
assert!(end_addr >= start_addr);
|
||||||
|
assert!(end_addr < 1024);
|
||||||
|
assert_eq!(data.len() as u16, (end_addr - start_addr + 1) * 4);
|
||||||
|
|
||||||
|
// Calculate address step rate, and check legality
|
||||||
|
let step_rate = (self.f_sys_clk/(4.0 * playback_rate)) as u64;
|
||||||
|
if (step_rate == 0 || step_rate > 0xFFFF) {
|
||||||
|
return Err(Error::ParameterError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before setting up RAM, disable RAM_ENABLE
|
||||||
|
self.enable_ram_configuration(ram_dst.clone())?;
|
||||||
|
|
||||||
|
// Write a RAM profile, but include all data in RAM
|
||||||
|
self.write_register(0x0E + profile, &mut [
|
||||||
|
0x00,
|
||||||
|
((step_rate >> 8) & 0xFF).try_into().unwrap(),
|
||||||
|
((step_rate >> 0) & 0xFF).try_into().unwrap(),
|
||||||
|
((end_addr >> 2) & 0xFF).try_into().unwrap(),
|
||||||
|
((end_addr & 0x3) << 6).try_into().unwrap(),
|
||||||
|
((start_addr >> 2) & 0xFF).try_into().unwrap(),
|
||||||
|
((start_addr & 0x3) << 6).try_into().unwrap(),
|
||||||
|
((no_dwell_high as u8) << 5) | ((zero_crossing as u8) << 3) | (op_mode as u8)
|
||||||
|
])?;
|
||||||
|
|
||||||
|
// Temporarily disable RAM mode while accessing into RAM
|
||||||
|
self.disable_ram_configuration();
|
||||||
|
self.write_ram(data)?;
|
||||||
|
|
||||||
|
// Properly configure start_addr and end_addr
|
||||||
|
self.enable_ram_configuration(ram_dst)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to write data in RAM
|
||||||
|
// Need address range for data size check
|
||||||
|
fn write_ram(&mut self, data: &[u8]) -> Result<(), Error<E>> {
|
||||||
|
let mut vec: ArrayVec<[u8; 8192]> = ArrayVec::new();
|
||||||
|
vec.try_push(0x16)
|
||||||
|
.map_err(|_| Error::DDSRAMError)?;
|
||||||
|
vec.try_extend_from_slice(data)
|
||||||
|
.map_err(|_| Error::DDSRAMError)?;
|
||||||
|
let mut data_slice = vec.as_mut_slice();
|
||||||
|
self.spi.transfer(&mut data_slice)
|
||||||
|
.map(|_| ())
|
||||||
|
.map_err(Error::SPI)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test method for DDS.
|
* Test method for DDS.
|
||||||
|
@ -497,9 +575,9 @@ where
|
||||||
}
|
}
|
||||||
Ok(error_count)
|
Ok(error_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strong check for bytes passed to a register
|
||||||
macro_rules! impl_register_io {
|
macro_rules! impl_register_io {
|
||||||
($($reg_addr: expr, $reg_byte_size: expr),+) => {
|
($($reg_addr: expr, $reg_byte_size: expr),+) => {
|
||||||
impl<SPI, E> DDS<SPI>
|
impl<SPI, E> DDS<SPI>
|
||||||
|
@ -572,6 +650,4 @@ impl_register_io!(
|
||||||
0x13, 8,
|
0x13, 8,
|
||||||
0x14, 8,
|
0x14, 8,
|
||||||
0x15, 8
|
0x15, 8
|
||||||
// RAM works in other way
|
|
||||||
// 0x16, 4
|
|
||||||
);
|
);
|
||||||
|
|
64
src/lib.rs
64
src/lib.rs
|
@ -1,29 +1,14 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(generic_associated_types)]
|
|
||||||
#![feature(str_strip)]
|
#![feature(str_strip)]
|
||||||
extern crate embedded_hal;
|
extern crate embedded_hal;
|
||||||
use embedded_hal::{
|
use embedded_hal::{
|
||||||
digital::v2::OutputPin,
|
|
||||||
blocking::spi::Transfer,
|
blocking::spi::Transfer,
|
||||||
};
|
};
|
||||||
use core::{
|
|
||||||
cell,
|
|
||||||
marker::PhantomData,
|
|
||||||
};
|
|
||||||
use cortex_m;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod bitmask_macro;
|
pub mod bitmask_macro;
|
||||||
|
|
||||||
pub mod spi_slave;
|
pub mod spi_slave;
|
||||||
use crate::spi_slave::{
|
|
||||||
Parts,
|
|
||||||
SPISlave,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub mod cpld;
|
pub mod cpld;
|
||||||
use crate::cpld::CPLD;
|
|
||||||
use crate::cpld::DoOnGetRefMutData;
|
|
||||||
|
|
||||||
pub mod config_register;
|
pub mod config_register;
|
||||||
use crate::config_register::ConfigRegister;
|
use crate::config_register::ConfigRegister;
|
||||||
|
@ -36,11 +21,12 @@ use crate::attenuator::Attenuator;
|
||||||
pub mod dds;
|
pub mod dds;
|
||||||
use crate::dds::DDS;
|
use crate::dds::DDS;
|
||||||
|
|
||||||
pub mod scpi;
|
// pub mod scpi;
|
||||||
|
|
||||||
pub mod translation;
|
pub mod translation;
|
||||||
|
|
||||||
pub mod nal_tcp_client;
|
pub mod nal_tcp_client;
|
||||||
|
pub mod flash;
|
||||||
|
|
||||||
|
pub mod mqtt_mux;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enum for structuring error
|
* Enum for structuring error
|
||||||
|
@ -55,7 +41,9 @@ pub enum Error<E> {
|
||||||
DDSError,
|
DDSError,
|
||||||
ConfigRegisterError,
|
ConfigRegisterError,
|
||||||
DDSCLKError,
|
DDSCLKError,
|
||||||
|
DDSRAMError,
|
||||||
ParameterError,
|
ParameterError,
|
||||||
|
MqttCommandError,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -156,28 +144,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait UrukulTraits {
|
impl<SPI, E> Urukul<SPI>
|
||||||
type Error;
|
|
||||||
fn get_channel_switch_status(&mut self, channel: u32) -> Result<bool, Self::Error>;
|
|
||||||
fn set_channel_switch(&mut self, channel: u32, status: bool) -> Result<(), Self::Error>;
|
|
||||||
fn set_clock_source(&mut self, source: ClockSource, frequency: f64) -> Result<(), Self::Error>;
|
|
||||||
fn set_clock_division(&mut self, division: u8) -> Result<(), Self::Error>;
|
|
||||||
fn set_channel_attenuation(&mut self, channel: u8, attenuation: f32) -> Result<(), Self::Error>;
|
|
||||||
fn set_profile(&mut self, profile: u8) -> Result<(), Self::Error>;
|
|
||||||
fn set_channel_single_tone_profile(&mut self, channel: u8, profile: u8, frequency: f64, phase: f64, amplitude: f64) -> Result<(), Self::Error>;
|
|
||||||
fn set_channel_single_tone_profile_frequency(&mut self, channel: u8, profile: u8, frequency: f64)-> Result<(), Self::Error>;
|
|
||||||
fn set_channel_single_tone_profile_phase(&mut self, channel: u8, profile: u8, phase: f64)-> Result<(), Self::Error>;
|
|
||||||
fn set_channel_single_tone_profile_amplitude(&mut self, channel: u8, profile: u8, amplitude: f64)-> Result<(), Self::Error>;
|
|
||||||
fn set_channel_sys_clk(&mut self, channel: u8, sys_clk: f64) -> Result<(), Self::Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<SPI, E> UrukulTraits for Urukul<SPI>
|
|
||||||
where
|
where
|
||||||
SPI: Transfer<u8, Error = E>
|
SPI: Transfer<u8, Error = E>
|
||||||
{
|
{
|
||||||
type Error = Error<E>;
|
|
||||||
|
|
||||||
fn get_channel_switch_status(&mut self, channel: u32) -> Result<bool, Self::Error> {
|
fn get_channel_switch_status(&mut self, channel: u32) -> Result<bool, Error<E>> {
|
||||||
if channel < 4 {
|
if channel < 4 {
|
||||||
self.config_register.get_status(StatusMask::RF_SW).map(|val| (val & (1 << channel)) != 0)
|
self.config_register.get_status(StatusMask::RF_SW).map(|val| (val & (1 << channel)) != 0)
|
||||||
} else {
|
} else {
|
||||||
|
@ -185,7 +157,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_channel_switch(&mut self, channel: u32, status: bool) -> Result<(), Self::Error> {
|
fn set_channel_switch(&mut self, channel: u32, status: bool) -> Result<(), Error<E>> {
|
||||||
if channel < 4 {
|
if channel < 4 {
|
||||||
let prev = u32::from(self.config_register.get_status(StatusMask::RF_SW)?);
|
let prev = u32::from(self.config_register.get_status(StatusMask::RF_SW)?);
|
||||||
let next = {
|
let next = {
|
||||||
|
@ -203,7 +175,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_clock_source(&mut self, source: ClockSource, frequency: f64) -> Result<(), Self::Error> {
|
fn set_clock_source(&mut self, source: ClockSource, frequency: f64) -> Result<(), Error<E>> {
|
||||||
// Change clock source through configuration register
|
// Change clock source through configuration register
|
||||||
match source {
|
match source {
|
||||||
ClockSource::OSC => self.config_register.set_configurations(&mut [
|
ClockSource::OSC => self.config_register.set_configurations(&mut [
|
||||||
|
@ -232,7 +204,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_clock_division(&mut self, division: u8) -> Result<(), Self::Error> {
|
fn set_clock_division(&mut self, division: u8) -> Result<(), Error<E>> {
|
||||||
match division {
|
match division {
|
||||||
1 => self.config_register.set_configurations(&mut [
|
1 => self.config_register.set_configurations(&mut [
|
||||||
(CFGMask::DIV, 1),
|
(CFGMask::DIV, 1),
|
||||||
|
@ -256,33 +228,33 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_channel_attenuation(&mut self, channel: u8, attenuation: f32) -> Result<(), Self::Error> {
|
fn set_channel_attenuation(&mut self, channel: u8, attenuation: f32) -> Result<(), Error<E>> {
|
||||||
self.attenuator.set_channel_attenuation(channel, attenuation)
|
self.attenuator.set_channel_attenuation(channel, attenuation)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_profile(&mut self, profile: u8) -> Result<(), Self::Error> {
|
fn set_profile(&mut self, profile: u8) -> Result<(), Error<E>> {
|
||||||
self.config_register.set_configurations(&mut [
|
self.config_register.set_configurations(&mut [
|
||||||
(CFGMask::PROFILE, profile.into())
|
(CFGMask::PROFILE, profile.into())
|
||||||
]).map(|_| ())
|
]).map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_channel_single_tone_profile(&mut self, channel: u8, profile: u8, frequency: f64, phase: f64, amplitude: f64) -> Result<(), Self::Error> {
|
fn set_channel_single_tone_profile(&mut self, channel: u8, profile: u8, frequency: f64, phase: f64, amplitude: f64) -> Result<(), Error<E>> {
|
||||||
self.dds[usize::from(channel)].set_single_tone_profile(profile, frequency, phase, amplitude)
|
self.dds[usize::from(channel)].set_single_tone_profile(profile, frequency, phase, amplitude)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_channel_single_tone_profile_frequency(&mut self, channel: u8, profile: u8, frequency: f64)-> Result<(), Self::Error> {
|
fn set_channel_single_tone_profile_frequency(&mut self, channel: u8, profile: u8, frequency: f64)-> Result<(), Error<E>> {
|
||||||
self.dds[usize::from(channel)].set_single_tone_profile_frequency(profile, frequency)
|
self.dds[usize::from(channel)].set_single_tone_profile_frequency(profile, frequency)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_channel_single_tone_profile_phase(&mut self, channel: u8, profile: u8, phase: f64)-> Result<(), Self::Error> {
|
fn set_channel_single_tone_profile_phase(&mut self, channel: u8, profile: u8, phase: f64)-> Result<(), Error<E>> {
|
||||||
self.dds[usize::from(channel)].set_single_tone_profile_phase(profile, phase)
|
self.dds[usize::from(channel)].set_single_tone_profile_phase(profile, phase)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_channel_single_tone_profile_amplitude(&mut self, channel: u8, profile: u8, amplitude: f64)-> Result<(), Self::Error> {
|
fn set_channel_single_tone_profile_amplitude(&mut self, channel: u8, profile: u8, amplitude: f64)-> Result<(), Error<E>> {
|
||||||
self.dds[usize::from(channel)].set_single_tone_profile_amplitude(profile, amplitude)
|
self.dds[usize::from(channel)].set_single_tone_profile_amplitude(profile, amplitude)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_channel_sys_clk(&mut self, channel: u8, f_sys_clk: f64) -> Result<(), Self::Error> {
|
fn set_channel_sys_clk(&mut self, channel: u8, f_sys_clk: f64) -> Result<(), Error<E>> {
|
||||||
self.dds[usize::from(channel)].set_sys_clk_frequency(f_sys_clk)
|
self.dds[usize::from(channel)].set_sys_clk_frequency(f_sys_clk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue