Refactoring AD9959 errors
This commit is contained in:
parent
67b7dbcb70
commit
58bd61afd5
|
@ -85,23 +85,17 @@ pub enum Channel {
|
||||||
|
|
||||||
/// Possible errors generated by the AD9959 driver.
|
/// Possible errors generated by the AD9959 driver.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error<InterfaceE> {
|
pub enum Error {
|
||||||
Interface(InterfaceE),
|
Interface,
|
||||||
Check,
|
Check,
|
||||||
Bounds,
|
Bounds,
|
||||||
Pin,
|
Pin,
|
||||||
Frequency,
|
Frequency,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <InterfaceE> From<InterfaceE> for Error<InterfaceE> {
|
impl <PinE, INTERFACE, DELAY, UPDATE> Ad9959<INTERFACE, DELAY, UPDATE>
|
||||||
fn from(interface_error: InterfaceE) -> Self {
|
|
||||||
Error::Interface(interface_error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl <PinE, InterfaceE, INTERFACE, DELAY, UPDATE> Ad9959<INTERFACE, DELAY, UPDATE>
|
|
||||||
where
|
where
|
||||||
INTERFACE: Interface<Error = InterfaceE>,
|
INTERFACE: Interface,
|
||||||
DELAY: DelayMs<u8>,
|
DELAY: DelayMs<u8>,
|
||||||
UPDATE: OutputPin<Error = PinE>,
|
UPDATE: OutputPin<Error = PinE>,
|
||||||
|
|
||||||
|
@ -123,7 +117,7 @@ where
|
||||||
delay: DELAY,
|
delay: DELAY,
|
||||||
desired_mode: Mode,
|
desired_mode: Mode,
|
||||||
clock_frequency: f32,
|
clock_frequency: f32,
|
||||||
multiplier: u8) -> Result<Self, Error<InterfaceE>>
|
multiplier: u8) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
RST: OutputPin,
|
RST: OutputPin,
|
||||||
{
|
{
|
||||||
|
@ -145,24 +139,21 @@ where
|
||||||
|
|
||||||
reset_pin.set_low().or_else(|_| Err(Error::Pin))?;
|
reset_pin.set_low().or_else(|_| Err(Error::Pin))?;
|
||||||
|
|
||||||
ad9959.interface.configure_mode(Mode::SingleBitTwoWire)?;
|
ad9959.interface.configure_mode(Mode::SingleBitTwoWire).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
// Program the interface configuration in the AD9959. Default to all channels enabled.
|
// Program the interface configuration in the AD9959. Default to all channels enabled.
|
||||||
let mut csr: [u8; 1] = [0xF0];
|
let mut csr: [u8; 1] = [0xF0];
|
||||||
csr[0].set_bits(1..3, desired_mode as u8);
|
csr[0].set_bits(1..3, desired_mode as u8);
|
||||||
ad9959.interface.write(Register::CSR as u8, &csr)?;
|
ad9959.interface.write(Register::CSR as u8, &csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
// Configure the interface to the desired mode.
|
|
||||||
ad9959.interface.configure_mode(Mode::FourBitSerial)?;
|
|
||||||
|
|
||||||
// Latch the configuration registers to make them active.
|
// Latch the configuration registers to make them active.
|
||||||
ad9959.latch_configuration()?;
|
ad9959.latch_configuration()?;
|
||||||
|
|
||||||
ad9959.interface.configure_mode(desired_mode)?;
|
ad9959.interface.configure_mode(desired_mode).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
// Read back the CSR to ensure it specifies the mode correctly.
|
// Read back the CSR to ensure it specifies the mode correctly.
|
||||||
let mut updated_csr: [u8; 1] = [0];
|
let mut updated_csr: [u8; 1] = [0];
|
||||||
ad9959.interface.read(Register::CSR as u8, &mut updated_csr)?;
|
ad9959.interface.read(Register::CSR as u8, &mut updated_csr).map_err(|_| Error::Interface)?;
|
||||||
if updated_csr[0] != csr[0] {
|
if updated_csr[0] != csr[0] {
|
||||||
return Err(Error::Check);
|
return Err(Error::Check);
|
||||||
}
|
}
|
||||||
|
@ -173,7 +164,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Latch the DDS configuration to ensure it is active on the output channels.
|
/// Latch the DDS configuration to ensure it is active on the output channels.
|
||||||
fn latch_configuration(&mut self) -> Result<(), Error<InterfaceE>> {
|
fn latch_configuration(&mut self) -> Result<(), Error> {
|
||||||
self.io_update.set_high().or_else(|_| Err(Error::Pin))?;
|
self.io_update.set_high().or_else(|_| Err(Error::Pin))?;
|
||||||
// The SYNC_CLK is 1/4 the system clock frequency. The IO_UPDATE pin must be latched for one
|
// The SYNC_CLK is 1/4 the system clock frequency. The IO_UPDATE pin must be latched for one
|
||||||
// full SYNC_CLK pulse to register. For safety, we latch for 5 here.
|
// full SYNC_CLK pulse to register. For safety, we latch for 5 here.
|
||||||
|
@ -193,7 +184,7 @@ where
|
||||||
/// The actual frequency configured for the internal system clock.
|
/// The actual frequency configured for the internal system clock.
|
||||||
pub fn configure_system_clock(&mut self,
|
pub fn configure_system_clock(&mut self,
|
||||||
reference_clock_frequency: f32,
|
reference_clock_frequency: f32,
|
||||||
multiplier: u8) -> Result<f64, Error<InterfaceE>>
|
multiplier: u8) -> Result<f64, Error>
|
||||||
{
|
{
|
||||||
self.reference_clock_frequency = reference_clock_frequency;
|
self.reference_clock_frequency = reference_clock_frequency;
|
||||||
|
|
||||||
|
@ -208,13 +199,13 @@ where
|
||||||
|
|
||||||
// TODO: Update / disable any enabled channels?
|
// TODO: Update / disable any enabled channels?
|
||||||
let mut fr1: [u8; 3] = [0, 0, 0];
|
let mut fr1: [u8; 3] = [0, 0, 0];
|
||||||
self.interface.read(Register::FR1 as u8, &mut fr1)?;
|
self.interface.read(Register::FR1 as u8, &mut fr1).map_err(|_| Error::Interface)?;
|
||||||
fr1[0].set_bits(2..=6, multiplier);
|
fr1[0].set_bits(2..=6, multiplier);
|
||||||
|
|
||||||
let vco_range = frequency > 255e6;
|
let vco_range = frequency > 255e6;
|
||||||
fr1[0].set_bit(7, vco_range);
|
fr1[0].set_bit(7, vco_range);
|
||||||
|
|
||||||
self.interface.write(Register::FR1 as u8, &fr1)?;
|
self.interface.write(Register::FR1 as u8, &fr1).map_err(|_| Error::Interface)?;
|
||||||
self.system_clock_multiplier = multiplier;
|
self.system_clock_multiplier = multiplier;
|
||||||
|
|
||||||
Ok(self.system_clock_frequency())
|
Ok(self.system_clock_frequency())
|
||||||
|
@ -226,9 +217,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current reference clock multiplier.
|
/// Get the current reference clock multiplier.
|
||||||
pub fn get_reference_clock_multiplier(&mut self) -> Result<u8, Error<InterfaceE>> {
|
pub fn get_reference_clock_multiplier(&mut self) -> Result<u8, Error> {
|
||||||
let mut fr1: [u8; 3] = [0, 0, 0];
|
let mut fr1: [u8; 3] = [0, 0, 0];
|
||||||
self.interface.read(Register::FR1 as u8, &mut fr1)?;
|
self.interface.read(Register::FR1 as u8, &mut fr1).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
Ok(fr1[0].get_bits(2..=6) as u8)
|
Ok(fr1[0].get_bits(2..=6) as u8)
|
||||||
}
|
}
|
||||||
|
@ -240,36 +231,36 @@ where
|
||||||
///
|
///
|
||||||
/// Returns:
|
/// Returns:
|
||||||
/// True if the self test succeeded. False otherwise.
|
/// True if the self test succeeded. False otherwise.
|
||||||
pub fn self_test(&mut self) -> Result<bool, Error<InterfaceE>> {
|
pub fn self_test(&mut self) -> Result<bool, Error> {
|
||||||
let mut csr: [u8; 1] = [0];
|
let mut csr: [u8; 1] = [0];
|
||||||
self.interface.read(Register::CSR as u8, &mut csr)?;
|
self.interface.read(Register::CSR as u8, &mut csr).map_err(|_| Error::Interface)?;
|
||||||
let old_csr = csr[0];
|
let old_csr = csr[0];
|
||||||
|
|
||||||
// Enable all channels.
|
// Enable all channels.
|
||||||
csr[0].set_bits(4..8, 0xF);
|
csr[0].set_bits(4..8, 0xF);
|
||||||
self.interface.write(Register::CSR as u8, &csr)?;
|
self.interface.write(Register::CSR as u8, &csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
// Read back the enable.
|
// Read back the enable.
|
||||||
csr[0] = 0;
|
csr[0] = 0;
|
||||||
self.interface.read(Register::CSR as u8, &mut csr)?;
|
self.interface.read(Register::CSR as u8, &mut csr).map_err(|_| Error::Interface)?;
|
||||||
if csr[0].get_bits(4..8) != 0xF {
|
if csr[0].get_bits(4..8) != 0xF {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all channel enables.
|
// Clear all channel enables.
|
||||||
csr[0].set_bits(4..8, 0x0);
|
csr[0].set_bits(4..8, 0x0);
|
||||||
self.interface.write(Register::CSR as u8, &csr)?;
|
self.interface.write(Register::CSR as u8, &csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
// Read back the enable.
|
// Read back the enable.
|
||||||
csr[0] = 0xFF;
|
csr[0] = 0xFF;
|
||||||
self.interface.read(Register::CSR as u8, &mut csr)?;
|
self.interface.read(Register::CSR as u8, &mut csr).map_err(|_| Error::Interface)?;
|
||||||
if csr[0].get_bits(4..8) != 0 {
|
if csr[0].get_bits(4..8) != 0 {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore the CSR.
|
// Restore the CSR.
|
||||||
csr[0] = old_csr;
|
csr[0] = old_csr;
|
||||||
self.interface.write(Register::CSR as u8, &csr)?;
|
self.interface.write(Register::CSR as u8, &csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
@ -280,29 +271,29 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enable an output channel.
|
/// Enable an output channel.
|
||||||
pub fn enable_channel(&mut self, channel: Channel) -> Result<(), Error<InterfaceE>> {
|
pub fn enable_channel(&mut self, channel: Channel) -> Result<(), Error> {
|
||||||
let mut csr: [u8; 1] = [0];
|
let mut csr: [u8; 1] = [0];
|
||||||
self.interface.read(Register::CSR as u8, &mut csr)?;
|
self.interface.read(Register::CSR as u8, &mut csr).map_err(|_| Error::Interface)?;
|
||||||
csr[0].set_bit(channel as usize + 4, true);
|
csr[0].set_bit(channel as usize + 4, true);
|
||||||
self.interface.write(Register::CSR as u8, &csr)?;
|
self.interface.write(Register::CSR as u8, &csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disable an output channel.
|
/// Disable an output channel.
|
||||||
pub fn disable_channel(&mut self, channel: Channel) -> Result<(), Error<InterfaceE>> {
|
pub fn disable_channel(&mut self, channel: Channel) -> Result<(), Error> {
|
||||||
let mut csr: [u8; 1] = [0];
|
let mut csr: [u8; 1] = [0];
|
||||||
self.interface.read(Register::CSR as u8, &mut csr)?;
|
self.interface.read(Register::CSR as u8, &mut csr).map_err(|_| Error::Interface)?;
|
||||||
csr[0].set_bit(channel as usize + 4, false);
|
csr[0].set_bit(channel as usize + 4, false);
|
||||||
self.interface.write(Register::CSR as u8, &csr)?;
|
self.interface.write(Register::CSR as u8, &csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine if an output channel is enabled.
|
/// Determine if an output channel is enabled.
|
||||||
pub fn is_enabled(&mut self, channel: Channel) -> Result<bool, Error<InterfaceE>> {
|
pub fn is_enabled(&mut self, channel: Channel) -> Result<bool, Error> {
|
||||||
let mut csr: [u8; 1] = [0; 1];
|
let mut csr: [u8; 1] = [0; 1];
|
||||||
self.interface.read(Register::CSR as u8, &mut csr)?;
|
self.interface.read(Register::CSR as u8, &mut csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
Ok(csr[0].get_bit(channel as usize + 4))
|
Ok(csr[0].get_bit(channel as usize + 4))
|
||||||
}
|
}
|
||||||
|
@ -313,24 +304,24 @@ where
|
||||||
/// * `channel` - The channel to configure.
|
/// * `channel` - The channel to configure.
|
||||||
/// * `register` - The register to update.
|
/// * `register` - The register to update.
|
||||||
/// * `data` - The contents to write to the provided register.
|
/// * `data` - The contents to write to the provided register.
|
||||||
fn modify_channel(&mut self, channel: Channel, register: Register, data: &[u8]) -> Result<(), Error<InterfaceE>> {
|
fn modify_channel(&mut self, channel: Channel, register: Register, data: &[u8]) -> Result<(), Error> {
|
||||||
// Disable all other outputs so that we can update the configuration register of only the
|
// Disable all other outputs so that we can update the configuration register of only the
|
||||||
// specified channel.
|
// specified channel.
|
||||||
let mut csr: [u8; 1] = [0];
|
let mut csr: [u8; 1] = [0];
|
||||||
self.interface.read(Register::CSR as u8, &mut csr)?;
|
self.interface.read(Register::CSR as u8, &mut csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
let mut new_csr = csr;
|
let mut new_csr = csr;
|
||||||
new_csr[0].set_bits(4..8, 0);
|
new_csr[0].set_bits(4..8, 0);
|
||||||
new_csr[0].set_bit(4 + channel as usize, true);
|
new_csr[0].set_bit(4 + channel as usize, true);
|
||||||
|
|
||||||
self.interface.write(Register::CSR as u8, &new_csr)?;
|
self.interface.write(Register::CSR as u8, &new_csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
self.interface.write(register as u8, &data)?;
|
self.interface.write(register as u8, &data).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
// Latch the configuration and restore the previous CSR. Note that the re-enable of the
|
// Latch the configuration and restore the previous CSR. Note that the re-enable of the
|
||||||
// channel happens immediately, so the CSR update does not need to be latched.
|
// channel happens immediately, so the CSR update does not need to be latched.
|
||||||
self.latch_configuration()?;
|
self.latch_configuration()?;
|
||||||
self.interface.write(Register::CSR as u8, &csr)?;
|
self.interface.write(Register::CSR as u8, &csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -341,23 +332,23 @@ where
|
||||||
/// * `channel` - The channel to read.
|
/// * `channel` - The channel to read.
|
||||||
/// * `register` - The register to read.
|
/// * `register` - The register to read.
|
||||||
/// * `data` - A location to store the read register contents.
|
/// * `data` - A location to store the read register contents.
|
||||||
fn read_channel(&mut self, channel: Channel, register: Register, mut data: &mut [u8]) -> Result<(), Error<InterfaceE>> {
|
fn read_channel(&mut self, channel: Channel, register: Register, mut data: &mut [u8]) -> Result<(), Error> {
|
||||||
// Disable all other channels in the CSR so that we can read the configuration register of
|
// Disable all other channels in the CSR so that we can read the configuration register of
|
||||||
// only the desired channel.
|
// only the desired channel.
|
||||||
let mut csr: [u8; 1] = [0];
|
let mut csr: [u8; 1] = [0];
|
||||||
self.interface.read(Register::CSR as u8, &mut csr)?;
|
self.interface.read(Register::CSR as u8, &mut csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
let mut new_csr = csr;
|
let mut new_csr = csr;
|
||||||
new_csr[0].set_bits(4..8, 0);
|
new_csr[0].set_bits(4..8, 0);
|
||||||
new_csr[0].set_bit(4 + channel as usize, true);
|
new_csr[0].set_bit(4 + channel as usize, true);
|
||||||
|
|
||||||
self.interface.write(Register::CSR as u8, &new_csr)?;
|
self.interface.write(Register::CSR as u8, &new_csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
self.interface.read(register as u8, &mut data)?;
|
self.interface.read(register as u8, &mut data).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
// Restore the previous CSR. Note that the re-enable of the channel happens immediately, so
|
// Restore the previous CSR. Note that the re-enable of the channel happens immediately, so
|
||||||
// the CSR update does not need to be latched.
|
// the CSR update does not need to be latched.
|
||||||
self.interface.write(Register::CSR as u8, &csr)?;
|
self.interface.write(Register::CSR as u8, &csr).map_err(|_| Error::Interface)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -370,7 +361,7 @@ where
|
||||||
///
|
///
|
||||||
/// Returns:
|
/// Returns:
|
||||||
/// The actual programmed phase offset of the channel in turns.
|
/// The actual programmed phase offset of the channel in turns.
|
||||||
pub fn set_phase(&mut self, channel: Channel, phase_turns: f32) -> Result<f32, Error<InterfaceE>> {
|
pub fn set_phase(&mut self, channel: Channel, phase_turns: f32) -> Result<f32, Error> {
|
||||||
let phase_offset: u16 = (phase_turns * (1 << 14) as f32) as u16 & 0x3FFFu16;
|
let phase_offset: u16 = (phase_turns * (1 << 14) as f32) as u16 & 0x3FFFu16;
|
||||||
|
|
||||||
self.modify_channel(channel, Register::CPOW0, &phase_offset.to_be_bytes())?;
|
self.modify_channel(channel, Register::CPOW0, &phase_offset.to_be_bytes())?;
|
||||||
|
@ -385,7 +376,7 @@ where
|
||||||
///
|
///
|
||||||
/// Returns:
|
/// Returns:
|
||||||
/// The phase of the channel in turns.
|
/// The phase of the channel in turns.
|
||||||
pub fn get_phase(&mut self, channel: Channel) -> Result<f32, Error<InterfaceE>> {
|
pub fn get_phase(&mut self, channel: Channel) -> Result<f32, Error> {
|
||||||
let mut phase_offset: [u8; 2] = [0; 2];
|
let mut phase_offset: [u8; 2] = [0; 2];
|
||||||
self.read_channel(channel, Register::CPOW0, &mut phase_offset)?;
|
self.read_channel(channel, Register::CPOW0, &mut phase_offset)?;
|
||||||
|
|
||||||
|
@ -402,7 +393,7 @@ where
|
||||||
///
|
///
|
||||||
/// Returns:
|
/// Returns:
|
||||||
/// The actual normalized amplitude of the channel relative to full-scale range.
|
/// The actual normalized amplitude of the channel relative to full-scale range.
|
||||||
pub fn set_amplitude(&mut self, channel: Channel, amplitude: f32) -> Result<f32, Error<InterfaceE>> {
|
pub fn set_amplitude(&mut self, channel: Channel, amplitude: f32) -> Result<f32, Error> {
|
||||||
if amplitude < 0.0 || amplitude > 1.0 {
|
if amplitude < 0.0 || amplitude > 1.0 {
|
||||||
return Err(Error::Bounds);
|
return Err(Error::Bounds);
|
||||||
}
|
}
|
||||||
|
@ -436,7 +427,7 @@ where
|
||||||
///
|
///
|
||||||
/// Returns:
|
/// Returns:
|
||||||
/// The normalized amplitude of the channel.
|
/// The normalized amplitude of the channel.
|
||||||
pub fn get_amplitude(&mut self, channel: Channel) -> Result<f32, Error<InterfaceE>> {
|
pub fn get_amplitude(&mut self, channel: Channel) -> Result<f32, Error> {
|
||||||
let mut acr: [u8; 3] = [0; 3];
|
let mut acr: [u8; 3] = [0; 3];
|
||||||
self.read_channel(channel, Register::ACR, &mut acr)?;
|
self.read_channel(channel, Register::ACR, &mut acr)?;
|
||||||
|
|
||||||
|
@ -456,7 +447,7 @@ where
|
||||||
///
|
///
|
||||||
/// Returns:
|
/// Returns:
|
||||||
/// The actual programmed frequency of the channel.
|
/// The actual programmed frequency of the channel.
|
||||||
pub fn set_frequency(&mut self, channel: Channel, frequency: f64) -> Result<f64, Error<InterfaceE>> {
|
pub fn set_frequency(&mut self, channel: Channel, frequency: f64) -> Result<f64, Error> {
|
||||||
if frequency < 0.0 || frequency > self.system_clock_frequency() {
|
if frequency < 0.0 || frequency > self.system_clock_frequency() {
|
||||||
return Err(Error::Bounds);
|
return Err(Error::Bounds);
|
||||||
}
|
}
|
||||||
|
@ -477,7 +468,7 @@ where
|
||||||
///
|
///
|
||||||
/// Returns:
|
/// Returns:
|
||||||
/// The frequency of the channel in Hz.
|
/// The frequency of the channel in Hz.
|
||||||
pub fn get_frequency(&mut self, channel: Channel) -> Result<f64, Error<InterfaceE>> {
|
pub fn get_frequency(&mut self, channel: Channel) -> Result<f64, Error> {
|
||||||
// Read the frequency tuning word for the channel.
|
// Read the frequency tuning word for the channel.
|
||||||
let mut tuning_word: [u8; 4] = [0; 4];
|
let mut tuning_word: [u8; 4] = [0; 4];
|
||||||
self.read_channel(channel, Register::CFTW0, &mut tuning_word)?;
|
self.read_channel(channel, Register::CFTW0, &mut tuning_word)?;
|
||||||
|
|
Loading…
Reference in New Issue