Skip to content

Commit

Permalink
formatting and config read function
Browse files Browse the repository at this point in the history
too many keywords

Invalid keywords...
  • Loading branch information
deltronix committed Feb 4, 2024
1 parent f486739 commit c150b64
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 45 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ homepage = "https://github.com/deltronix/ad57xx"
repository = "https://github.com/deltronix/ad57xx"
readme = "README.md"
categories = ["embedded", "no-std"]
keywords = ["analog", "devices", "driver", "ad5754", "ad5734", "ad5724"]
keywords = ["spi", "embedded-hal", "driver"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
21 changes: 12 additions & 9 deletions examples/stm32_shared_bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ use core::cell::RefCell;

use embedded_hal_bus::spi::{NoDelay, RefCellDevice};
use hal::prelude::*;
use hal::spi::{Spi, Mode};
use hal::spi::{Mode, Spi};

use stm32f4xx_hal as hal;
use cortex_m_rt::entry;
use stm32f4xx_hal as hal;

use defmt_rtt as _;
use panic_probe as _;


#[entry]
fn main() -> ! {
// Take peripherals and set up the clocks.
Expand All @@ -30,12 +29,17 @@ fn main() -> ! {
let spi3_miso = gpioc.pc11.into_alternate();
let spi3_mosi = gpioc.pc12.into_alternate();
let gpioa = p.GPIOA.split();
let spi3_dac_sync = gpioa.pa15.into_push_pull_output_in_state(hal::gpio::PinState::High);
let spi3_dac_sync = gpioa
.pa15
.into_push_pull_output_in_state(hal::gpio::PinState::High);
// SPI Instance initialization in MODE 2
let spi3 = Spi::new(
p.SPI3,
(spi3_sclk, spi3_miso, spi3_mosi),
Mode{phase: hal::spi::Phase::CaptureOnFirstTransition, polarity: hal::spi::Polarity::IdleHigh},
Mode {
phase: hal::spi::Phase::CaptureOnFirstTransition,
polarity: hal::spi::Polarity::IdleHigh,
},
1.MHz(),
&ccdr,
);
Expand All @@ -48,16 +52,15 @@ fn main() -> ! {

// Setup the DAC as desired.
dac.set_power(ad57xx::Channel::AllDacs, true).unwrap();
dac.set_output_range(ad57xx::Channel::AllDacs, ad57xx::OutputRange::Bipolar5V).unwrap();
dac.set_output_range(ad57xx::Channel::AllDacs, ad57xx::OutputRange::Bipolar5V)
.unwrap();
dac.set_dac_output(ad57xx::Channel::DacA, 0x9000).unwrap();
let mut val: u16 = 0x0000;
loop {
delay.delay_ms(250);
dac.set_dac_output(ad57xx::Channel::DacA, val).unwrap();

val = val.wrapping_add(0x1000);
continue;
}
}


81 changes: 49 additions & 32 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
use embedded_hal::spi::SpiDevice;


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


impl<DEV, E> Ad57xxShared <DEV>
impl<DEV, E> Ad57xxShared<DEV>
where
DEV: SpiDevice<Error = E>,
{
///
///
pub fn new(spi: DEV) -> Self {
Self {
spi,
cfg: Config::default(),
pcfg: PowerConfig::default(),
}

}
/// 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
Expand All @@ -38,37 +36,47 @@ where
}
self.write(Command::PowerControlRegister, Data::PowerControl(self.pcfg))
}
/// Write a 16 bit value to the selected DAC register.
/// 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.
///
/// To push the value to the output it has to be loaded through the ~LDAC
/// and ~SYNC pins or through the load function in the control register.
/// The actual output voltage will depend on the reference voltage, output
/// To push the value to the output it has to be loaded through the ~LDAC
/// and ~SYNC pins or through the load function in the control register.
/// The actual output voltage will depend on the reference voltage, output
/// range and for bipolar ranges on the state of the BIN/~2sCOMPLEMENT pin.
/// ```
/// ad5754.set_dac_output(Channel::DacA, 0x8000);
/// ```
///
pub fn set_dac_output(&mut self, chan: Channel, val: u16) -> Result<(), Error<E>>{
pub fn set_dac_output(&mut self, chan: Channel, val: u16) -> Result<(), Error<E>> {
self.write(Command::DacRegister(chan), Data::DacValue(val))
}

/// Set the device configuration
pub fn set_config(&mut self, cfg: Config) -> Result<(), Error<E>>{
pub fn set_config(&mut self, cfg: Config) -> Result<(), Error<E>> {
self.cfg = cfg;
self.write(Command::ControlRegister(Function::Config), Data::Control(self.cfg))
self.write(
Command::ControlRegister(Function::Config),
Data::Control(self.cfg),
)
}
/// Get the device configuration
pub fn get_config(&mut self) -> Result<Config, Error<E>> {
match self.read(Command::ControlRegister(Function::Config))? {
Data::Control(cfg) => Ok(cfg),
_ => Err(Error::ReadError),
}
}

/// Set the output range of the selected DAC channel
pub fn set_output_range(&mut self, chan: Channel, range: OutputRange) -> Result<(), Error<E>>{
pub fn set_output_range(&mut self, chan: Channel, range: OutputRange) -> Result<(), Error<E>> {
self.write(Command::RangeSelectRegister(chan), Data::OutputRange(range))
}

/// This function sets the DAC registers to the clear code and updates the outputs.
pub fn clear_dacs(&mut self) -> Result<(), Error<E>>{
pub fn clear_dacs(&mut self) -> Result<(), Error<E>> {
self.write(Command::ControlRegister(Function::Clear), Data::None)
}
/// This function updates the DAC registers and, consequently, the DAC outputs.
/// This function updates the DAC registers and, consequently, the DAC outputs.
pub fn load_dacs(&mut self) -> Result<(), Error<E>> {
self.write(Command::ControlRegister(Function::Load), Data::None)
}
Expand Down Expand Up @@ -106,9 +114,7 @@ where
Command::PowerControlRegister => {
if let Data::PowerControl(pc) = data {
[
CommandByte::new()
.with_reg(u8::from(cmd))
.into(),
CommandByte::new().with_reg(u8::from(cmd)).into(),
(u16::from(pc) >> 8) as u8,
(u16::from(pc)) as u8,
]
Expand All @@ -129,47 +135,58 @@ where
} else {
return Err(Error::InvalidArgument);
}
},
}
Command::ControlRegister(func) => {
if let Data::None = data {
[
CommandByte::new()
.with_reg(u8::from(cmd))
.with_addr(func as u8)
.into(),
CommandByte::new()
.with_reg(u8::from(cmd))
.with_addr(func as u8)
.into(),
0x00,
0x00,
]
} else {
return Err(Error::InvalidArgument)
return Err(Error::InvalidArgument);
}
}
};
self.spi_write(&payload)
}
fn spi_write(&mut self, payload: &[u8]) -> Result<(), 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) -> Result<Data, Error<E>>{
fn read(&mut self, cmd: Command) -> Result<Data, Error<E>> {
let addr = match cmd {
Command::DacRegister(addr) => addr as u8,
Command::RangeSelectRegister(addr) => addr as u8,
Command::PowerControlRegister => 0,
Command::ControlRegister(function) => function as u8,
};
// The register to be read with the read bit set
let cmd_byte = CommandByte::new().with_rw(true).with_reg(u8::from(cmd)).with_reg(addr);
self.spi.write(&[u8::from(cmd_byte), 0, 0]).map_err(Error::Spi)?;
let cmd_byte = CommandByte::new()
.with_rw(true)
.with_reg(u8::from(cmd))
.with_reg(addr);
self.spi
.write(&[u8::from(cmd_byte), 0, 0])
.map_err(Error::Spi)?;
let mut rx: [u8; 3] = [0x00; 3];
// Send a NOP instruction while reading
let nop = CommandByte::new().with_reg(u8::from(Command::ControlRegister(Function::Nop))).with_addr(Function::Nop as u8);
self.spi.transfer(&mut [u8::from(nop),0,0], &mut rx).map_err(Error::Spi)?;
let nop = CommandByte::new()
.with_reg(u8::from(Command::ControlRegister(Function::Nop)))
.with_addr(Function::Nop as u8);
self.spi
.transfer(&mut [u8::from(nop), 0, 0], &mut rx)
.map_err(Error::Spi)?;
let data: u16 = (rx[1] as u16) << 8 + rx[0] as u16;
match cmd {
Command::DacRegister(_) => Ok(Data::DacValue(data)),
Command::RangeSelectRegister(_) => Ok(Data::OutputRange(OutputRange::from(data))),
Command::PowerControlRegister => Ok(Data::PowerControl(PowerConfig::from(data))),
Command::ControlRegister(func) if func == Function::Config => Ok(Data::Control(Config::from(data))),
Command::ControlRegister(func) if func == Function::Config => {
Ok(Data::Control(Config::from(data)))
}
Command::ControlRegister(_) => Err(Error::ReadError),
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//! Driver for Analog Devices AD57xx series of dual and quad channel 16/14/12bit DACs
//!
//! For now only AD57x4 series are supported. However
//!
//!
//!
#![deny(unsafe_code, missing_docs)]
#![no_std]
Expand Down Expand Up @@ -48,7 +47,6 @@ impl From<Command> for u8 {
}
}


#[derive(Debug)]
enum Data {
DacValue(u16),
Expand Down

0 comments on commit c150b64

Please sign in to comment.