Skip to content

Commit

Permalink
bugfix: PowerConfig differs for the dual channel chips
Browse files Browse the repository at this point in the history
  • Loading branch information
deltronix committed Feb 7, 2024
1 parent 35b0607 commit 823791e
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 125 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ad57xx"
version = "0.2.0"
version = "0.2.1"
edition = "2021"
license = "MIT"
description = "Analog Devices AD57xx SPI DAC driver"
Expand Down
60 changes: 44 additions & 16 deletions src/ad57x2.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
//! Dual channel implementation
use bitfield_struct::bitfield;
use embedded_hal::spi::SpiDevice;

use crate::{
Ad57xxShared, CommandByte, Command, Config, Data, Error, Function, OutputRange,
PowerConfig,
Ad57xxShared, CommandByte, Command, Config, Data, Error, Function, OutputRange
};

/// Dac Channel
Expand All @@ -18,6 +17,35 @@ pub enum Channel {
/// All DAC Channels
AllDacs = 2,
}
/// Definition of the power configuration register
#[bitfield(u16)]
pub struct PowerConfig {
#[bits(1)]
pu_a: bool,
#[bits(1)]
_unused: bool,
#[bits(1)]
pu_b: bool,
#[bits(1)]
_unused: bool,
#[bits(1)]
_unused: bool,
#[bits(1)]
tsd: bool,
#[bits(1)]
_unused: bool,
#[bits(1)]
oc_a: bool,
#[bits(1)]
_unused: bool,
#[bits(1)]
oc_b: bool,
#[bits(1)]
_unused: bool,
#[bits(5)]
_unused: u8,
}


impl<DEV, E> Ad57xxShared<DEV, crate::marker::Ad57x2> where
DEV: SpiDevice<Error = E>{
Expand All @@ -28,7 +56,7 @@ DEV: SpiDevice<Error = E>{
fn spi_write(&mut self, payload: &[u8]) -> Result<(), Error<E>> {
self.spi.write(&payload).map_err(Error::Spi)
}
fn read(&mut self, cmd: Command<Channel>) -> Result<Data, Error<E>> {
fn read(&mut self, cmd: Command<Channel>) -> Result<Data<PowerConfig>, Error<E>> {
let addr = match cmd {
Command::DacRegister(addr) => addr as u8,
Command::RangeSelectRegister(addr) => addr as u8,
Expand All @@ -39,7 +67,7 @@ DEV: SpiDevice<Error = E>{
let cmd_byte = CommandByte::new()
.with_rw(true)
.with_reg(u8::from(cmd))
.with_reg(addr);
.with_addr(addr);
self.spi
.write(&[u8::from(cmd_byte), 0, 0])
.map_err(Error::Spi)?;
Expand All @@ -62,7 +90,7 @@ DEV: SpiDevice<Error = E>{
Command::ControlRegister(_) => Err(Error::ReadError),
}
}
fn write(&mut self, cmd: Command<Channel>, data: Data) -> Result<(), Error<E>> {
fn write(&mut self, cmd: Command<Channel>, data: Data<PowerConfig>) -> Result<(), Error<E>> {
let payload: [u8; 3] = match cmd {
Command::DacRegister(addr) => {
if let Data::DacValue(val) = data {
Expand Down Expand Up @@ -137,17 +165,17 @@ DEV: SpiDevice<Error = E>{
/// Power up or down a single or all DAC channels
/// After power up a timeout of 10us is required before loading the corresponding DAC register
pub fn set_power(&mut self, chan: Channel, pwr: bool) -> Result<(), Error<E>> {
match chan {
Channel::DacA => self.pcfg.set_pu_a(pwr),
Channel::DacB => self.pcfg.set_pu_b(pwr),
Channel::AllDacs => {
self.pcfg = self
.pcfg
.with_pu_a(pwr)
.with_pu_b(pwr)
}
if let Data::PowerControl(pcfg) = self.read(Command::PowerControlRegister)?{
let pcfg = match chan {
Channel::DacA => pcfg.with_pu_a(pwr),
Channel::DacB => pcfg.with_pu_b(pwr),
Channel::AllDacs => pcfg.with_pu_a(pwr).with_pu_b(pwr),
};
self.write(Command::PowerControlRegister, Data::PowerControl(pcfg))
}
else {
Err(Error::ReadError)
}
self.write(Command::PowerControlRegister, Data::PowerControl(self.pcfg))
}
/// Write a 16 bit value to the selected DAC register.
/// > Note that the devices with a bit depth smaller than 16 use a left-aligned data format.
Expand Down
88 changes: 59 additions & 29 deletions src/ad57x4.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
//! Quad channel implementation
use bitfield_struct::bitfield;
use embedded_hal::spi::SpiDevice;

use crate::{
Ad57xxShared, CommandByte, Command, Config, Data, Error, Function, OutputRange,
PowerConfig,
Ad57xxShared, Command, CommandByte, Config, Data, Error, Function, OutputRange
};

/// Dac Channel
Expand All @@ -20,19 +21,49 @@ pub enum Channel {
/// All DAC Channels
AllDacs = 4,
}
/// Definition of the power configuration register
#[bitfield(u16)]
pub struct PowerConfig {
#[bits(1)]
pu_a: bool,
#[bits(1)]
pu_b: bool,
#[bits(1)]
pu_c: bool,
#[bits(1)]
pu_d: bool,
#[bits(1)]
_unused: bool,
#[bits(1)]
tsd: bool,
#[bits(1)]
_unused: bool,
#[bits(1)]
oc_a: bool,
#[bits(1)]
oc_b: bool,
#[bits(1)]
oc_c: bool,
#[bits(1)]
oc_d: bool,
#[bits(5)]
_unused: u8,
}


#[doc(hidden)]
impl<DEV, E> Ad57xxShared<DEV, crate::marker::Ad57x4> where
DEV: SpiDevice<Error = E>
impl<DEV, E> Ad57xxShared<DEV, crate::marker::Ad57x4>
where
DEV: SpiDevice<Error = E>,
{
/// Create a new quad channel AD57xx DAC SPI Device on a shared bus
pub fn new_ad57x4(spi: DEV) -> Self {
Self::create(spi)
}
}
fn spi_write(&mut self, payload: &[u8]) -> Result<(), Error<E>> {
self.spi.write(&payload).map_err(Error::Spi)
}
fn read(&mut self, cmd: Command<Channel>) -> Result<Data, Error<E>> {
fn read(&mut self, cmd: Command<Channel>) -> Result<Data<PowerConfig>, Error<E>> {
let addr = match cmd {
Command::DacRegister(addr) => addr as u8,
Command::RangeSelectRegister(addr) => addr as u8,
Expand All @@ -43,7 +74,7 @@ DEV: SpiDevice<Error = E>
let cmd_byte = CommandByte::new()
.with_rw(true)
.with_reg(u8::from(cmd))
.with_reg(addr);
.with_addr(addr);
self.spi
.write(&[u8::from(cmd_byte), 0, 0])
.map_err(Error::Spi)?;
Expand All @@ -66,7 +97,7 @@ DEV: SpiDevice<Error = E>
Command::ControlRegister(_) => Err(Error::ReadError),
}
}
fn write(&mut self, cmd: Command<Channel>, data: Data) -> Result<(), Error<E>> {
fn write(&mut self, cmd: Command<Channel>, data: Data<PowerConfig>) -> Result<(), Error<E>> {
let payload: [u8; 3] = match cmd {
Command::DacRegister(addr) => {
if let Data::DacValue(val) = data {
Expand All @@ -81,7 +112,7 @@ DEV: SpiDevice<Error = E>
} else {
return Err(Error::InvalidArgument);
}
},
}
Command::RangeSelectRegister(addr) => {
if let Data::OutputRange(val) = data {
[
Expand All @@ -95,7 +126,7 @@ DEV: SpiDevice<Error = E>
} else {
return Err(Error::InvalidArgument);
}
},
}
Command::PowerControlRegister => {
if let Data::PowerControl(pc) = data {
[
Expand All @@ -106,7 +137,7 @@ DEV: SpiDevice<Error = E>
} else {
return Err(Error::InvalidArgument);
}
},
}
Command::ControlRegister(func) if func == Function::Config => {
if let Data::Control(cfg) = data {
[
Expand All @@ -120,7 +151,7 @@ DEV: SpiDevice<Error = E>
} else {
return Err(Error::InvalidArgument);
}
}
}
Command::ControlRegister(func) => {
if let Data::None = data {
[
Expand All @@ -141,21 +172,23 @@ DEV: SpiDevice<Error = E>
/// Power up or down a single or all DAC channels
/// After power up a timeout of 10us is required before loading the corresponding DAC register
pub fn set_power(&mut self, chan: Channel, pwr: bool) -> Result<(), Error<E>> {
match chan {
Channel::DacA => self.pcfg.set_pu_a(pwr),
Channel::DacB => self.pcfg.set_pu_b(pwr),
Channel::DacC => self.pcfg.set_pu_c(pwr),
Channel::DacD => self.pcfg.set_pu_d(pwr),
Channel::AllDacs => {
self.pcfg = self
.pcfg
.with_pu_a(pwr)
.with_pu_b(pwr)
.with_pu_c(pwr)
.with_pu_d(pwr)
}
if let Data::PowerControl(pcfg) = self.read(Command::PowerControlRegister)? {
let pcfg = match chan {
Channel::DacA => pcfg.with_pu_a(pwr),
Channel::DacB => pcfg.with_pu_b(pwr),
Channel::DacC => pcfg.with_pu_c(pwr),
Channel::DacD => pcfg.with_pu_d(pwr),
Channel::AllDacs => {
pcfg
.with_pu_a(pwr)
.with_pu_b(pwr)
.with_pu_c(pwr)
.with_pu_d(pwr)
}
};
self.write(Command::PowerControlRegister, Data::PowerControl(pcfg))?
}
self.write(Command::PowerControlRegister, Data::PowerControl(self.pcfg))
Err(Error::ReadError)
}
/// Write a 16 bit value to the selected DAC register.
/// > Note that the devices with a bit depth smaller than 16 use a left-aligned data format.
Expand Down Expand Up @@ -200,7 +233,4 @@ DEV: SpiDevice<Error = E>
pub fn load_dacs(&mut self) -> Result<(), Error<E>> {
self.write(Command::ControlRegister(Function::Load), Data::None)
}



}
41 changes: 0 additions & 41 deletions src/common.rs

This file was deleted.

Loading

0 comments on commit 823791e

Please sign in to comment.