Skip to content

Commit

Permalink
Added MODE register impls
Browse files Browse the repository at this point in the history
  • Loading branch information
BLM16 committed Nov 10, 2024
1 parent ea70a00 commit 2621498
Show file tree
Hide file tree
Showing 3 changed files with 338 additions and 20 deletions.
80 changes: 65 additions & 15 deletions crates/ads126x/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,22 @@ mod error;
mod register;

use error::ADS126xError;
use register::{Register, IdRegister, PowerRegister, InterfaceRegister};
use register::{
IdRegister,
InterfaceRegister,
Mode0Register,
Mode1Register,
Mode2Register,
PowerRegister,
Register
};

use embedded_hal::spi::FullDuplex;
use heapless::Vec;

/// The [`Result`] type for ADS126x operations.
pub type Result<T> = core::result::Result<T, ADS126xError>;

pub struct ADS126x<SPI>
where
SPI: FullDuplex<u8>,
Expand Down Expand Up @@ -44,7 +55,7 @@ where
Self { spi }
}

pub fn send_command(&mut self, command: ADCCommand) -> Result<(), ADS126xError> {
pub fn send_command(&mut self, command: ADCCommand) -> Result<()> {
let (opcode1, opcode2) = match command {
ADCCommand::NOP => (0x00, None),
ADCCommand::RESET => (0x06, None),
Expand Down Expand Up @@ -72,8 +83,8 @@ where
}

/// Reads data from multiple registers starting at the provided register.
/// To read a single register, see [read_register](ADS126x::read_register).
pub fn read_multiple_registers(&mut self, reg: Register, num: u8) -> Result<Vec<u8, 27>, ADS126xError> {
/// To read a single register, see [`ADS126x::read_register`].
pub fn read_multiple_registers(&mut self, reg: Register, num: u8) -> Result<Vec<u8, 27>> {
if num > 27 {
return Err(ADS126xError::InvalidInputData);
}
Expand All @@ -88,17 +99,17 @@ where
}

/// Reads data from only the single provided register.
/// To read multiple registers, see [read_multiple_registers](ADS126x::read_multiple_registers).
pub fn read_register(&mut self, reg: Register) -> Result<u8, ADS126xError> {
/// To read multiple registers, see [`ADS126x::read_multiple_registers`].
pub fn read_register(&mut self, reg: Register) -> Result<u8> {
// zero since number of registers read - 1, so 1-1=0.
self.send_command(ADCCommand::RREG(reg, 0))?;
let data = self.spi.read().map_err(|_| ADS126xError::IO)?;
Ok(data)
}

/// Writes data to multiple registers starting at the provided register.
/// To write data to a single register, see [write_register](ADS126x::write_register).
pub fn write_multiple_registers(&mut self, reg: Register, data: &[u8]) -> Result<(), ADS126xError> {
/// To write data to a single register, see [`ADS126x::write_register`].
pub fn write_multiple_registers(&mut self, reg: Register, data: &[u8]) -> Result<()> {
if data.len() > 27 {
return Err(ADS126xError::InvalidInputData);
}
Expand All @@ -110,13 +121,13 @@ where
}

/// Writes data to only the single provided register.
/// To write data to multiple registers, see [write_multiple_registers](ADS126x::write_multiple_registers).
pub fn write_register(&mut self, reg: Register, data: u8) -> Result<(), ADS126xError> {
/// To write data to multiple registers, see [`ADS126x::write_multiple_registers`].
pub fn write_register(&mut self, reg: Register, data: u8) -> Result<()> {
self.send_command(ADCCommand::WREG(reg, 0))?;
self.spi.send(data).map_err(|_| ADS126xError::IO)
}

pub fn get_id(&mut self) -> Result<IdRegister, ADS126xError> {
pub fn get_id(&mut self) -> Result<IdRegister> {
let bits = self.read_register(Register::ID)?;
let data = IdRegister::from_bits(bits);
match data {
Expand All @@ -125,7 +136,7 @@ where
}
}

pub fn get_power(&mut self) -> Result<PowerRegister, ADS126xError> {
pub fn get_power(&mut self) -> Result<PowerRegister> {
let bits = self.read_register(Register::POWER)?;
let data = PowerRegister::from_bits(bits);
match data {
Expand All @@ -134,11 +145,11 @@ where
}
}

pub fn set_power(&mut self, reg: &PowerRegister) -> Result<(), ADS126xError> {
pub fn set_power(&mut self, reg: &PowerRegister) -> Result<()> {
self.write_register(Register::POWER, reg.bits())
}

pub fn get_interface(&mut self) -> Result<InterfaceRegister, ADS126xError> {
pub fn get_interface(&mut self) -> Result<InterfaceRegister> {
let bits = self.read_register(Register::INTERFACE)?;
let data = InterfaceRegister::from_bits(bits);
match data {
Expand All @@ -147,7 +158,46 @@ where
}
}

pub fn set_interface(&mut self, reg: &InterfaceRegister) -> Result<(), ADS126xError> {
pub fn set_interface(&mut self, reg: &InterfaceRegister) -> Result<()> {
self.write_register(Register::INTERFACE, reg.bits())
}

pub fn get_mode0(&mut self) -> Result<Mode0Register> {
let bits = self.read_register(Register::MODE0)?;
let data = Mode0Register::from_bits(bits);
match data {
Some(reg) => Ok(reg),
None => Err(ADS126xError::InvalidInputData),
}
}

pub fn set_mode0(&mut self, reg: &Mode0Register) -> Result<()> {
self.write_register(Register::MODE0, reg.bits())
}

pub fn get_mode1(&mut self) -> Result<Mode1Register> {
let bits = self.read_register(Register::MODE1)?;
let data = Mode1Register::from_bits(bits);
match data {
Some(reg) => Ok(reg),
None => Err(ADS126xError::InvalidInputData),
}
}

pub fn set_mode1(&mut self, reg: &Mode1Register) -> Result<()> {
self.write_register(Register::MODE1, reg.bits())
}

pub fn get_mode2(&mut self) -> Result<Mode2Register> {
let bits = self.read_register(Register::MODE2)?;
let data = Mode2Register::from_bits(bits);
match data {
Some(reg) => Ok(reg),
None => Err(ADS126xError::InvalidInputData),
}
}

pub fn set_mode2(&mut self, reg: &Mode2Register) -> Result<()> {
self.write_register(Register::MODE2, reg.bits())
}
}
166 changes: 161 additions & 5 deletions crates/ads126x/src/register.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
mod enums;

pub use enums::*;
use bitflags::bitflags;

#[repr(u8)]
Expand Down Expand Up @@ -84,11 +87,6 @@ bitflags! {
}
}

pub enum DevId {
ADS1262 = 0b000,
ADS1263 = 0b001,
}

impl IdRegister {
pub fn get_rev_id(&self) -> u8 {
self.bits() & 0b0001_1111
Expand Down Expand Up @@ -121,3 +119,161 @@ bitflags! {
const TIMEOUT = 0b0000_1000;
}
}

bitflags! {
pub struct Mode0Register: u8 {
const RUNMODE = 0b0100_0000;
const REFREV = 0b1000_0000;

const _ = !0; // Source may set any bits
}
}

impl Mode0Register {
pub fn get_delay(&self) -> ConversionDelay {
match self.bits() & 0b0000_1111 {
0b0000 => ConversionDelay::DNone,
0b0001 => ConversionDelay::D8_7us,
0b0010 => ConversionDelay::D17us,
0b0011 => ConversionDelay::D35us,
0b0100 => ConversionDelay::D69us,
0b0101 => ConversionDelay::D139us,
0b0110 => ConversionDelay::D278us,
0b0111 => ConversionDelay::D555us,
0b1000 => ConversionDelay::D1_1ms,
0b1001 => ConversionDelay::D2_2ms,
0b1010 => ConversionDelay::D4_4ms,
0b1011 => ConversionDelay::D8_8ms,

0b1100..=0b1111 => panic!("Unknown conversion delay"),
_ => unreachable!(),
}
}

pub fn set_delay(&mut self, delay: ConversionDelay) {
let bits = delay as u8;
self.insert(Mode0Register::from_bits_retain(bits));
}

pub fn get_chop(&self) -> ChopMode {
match (self.bits() & 0b0011_0000) >> 4 {
0b00 => ChopMode::Disabled,
0b01 => ChopMode::InChopEnabled,
0b10 => ChopMode::IdacEnabled,
0b11 => ChopMode::InChopAndIdacEnabled,

_ => unreachable!(),
}
}

pub fn set_chop(&mut self, chop: ChopMode) {
let bits = chop as u8;
self.insert(Mode0Register::from_bits_retain(bits << 4));
}
}

bitflags! {
pub struct Mode1Register: u8 {
const SBPOL = 0b0000_1000;
const SBADC = 0b0001_0000;

const _ = !0; // Source may set any bits
}
}

impl Mode1Register {
pub fn get_sbmag(&self) -> SensorBiasMagnitude {
match self.bits() & 0b0000_0111 {
0b000 => SensorBiasMagnitude::BNone,
0b001 => SensorBiasMagnitude::B0_5uA,
0b010 => SensorBiasMagnitude::B2uA,
0b011 => SensorBiasMagnitude::B10uA,
0b100 => SensorBiasMagnitude::B50uA,
0b101 => SensorBiasMagnitude::B200uA,
0b110 => SensorBiasMagnitude::R10MOhm,

0b111 => panic!("Reserved SBMAG"),
_ => unreachable!()
}
}

pub fn set_sbmag(&mut self, sbmag: SensorBiasMagnitude) {
let bits = sbmag as u8;
self.insert(Mode1Register::from_bits_retain(bits));
}

pub fn get_filter(&self) -> DigitalFilter {
match (self.bits() & 0b1110_0000) >> 5 {
0b000 => DigitalFilter::Sinc1,
0b001 => DigitalFilter::Sinc2,
0b010 => DigitalFilter::Sinc3,
0b011 => DigitalFilter::Sinc4,
0b100 => DigitalFilter::FIR,

0b101..=0b111 => panic!("Reserved filter"),
_ => unreachable!()
}
}

pub fn set_filter(&mut self, filter: DigitalFilter) {
let bits = filter as u8;
self.insert(Mode1Register::from_bits_retain(bits << 5));
}
}

bitflags! {
pub struct Mode2Register: u8 {
const BYPASS = 0b1000_0000;

const _ = !0; // Source may set any bits
}
}

impl Mode2Register {
pub fn get_dr(&self) -> DataRate {
match self.bits() & 0b0000_1111 {
0b0000 => DataRate::SPS2_5,
0b0001 => DataRate::SPS5,
0b0010 => DataRate::SPS10,
0b0011 => DataRate::SPS16_6,
0b0100 => DataRate::SPS20,
0b0101 => DataRate::SPS50,
0b0110 => DataRate::SPS60,
0b0111 => DataRate::SPS100,
0b1000 => DataRate::SPS400,
0b1001 => DataRate::SPS1200,
0b1010 => DataRate::SPS2400,
0b1011 => DataRate::SPS4800,
0b1100 => DataRate::SPS7200,
0b1101 => DataRate::SPS14400,
0b1110 => DataRate::SPS19200,
0b1111 => DataRate::SPS38400,

_ => unreachable!()
}
}

pub fn set_dr(&mut self, rate: DataRate) {
let bits = rate as u8;
self.insert(Mode2Register::from_bits_retain(bits));
}

pub fn get_gain(&self) -> PGAGain {
match (self.bits() & 0b0111_0000) >> 4 {
0b000 => PGAGain::VV1,
0b001 => PGAGain::VV2,
0b010 => PGAGain::VV4,
0b011 => PGAGain::VV8,
0b100 => PGAGain::VV16,
0b101 => PGAGain::VV32,

0b110 | 0b111 => panic!("Reserved gain"),
_ => unreachable!()
}
}

pub fn set_gain(&mut self, gain: PGAGain) {
let bits = gain as u8;
self.insert(Mode2Register::from_bits_retain(bits << 4));
}
}
Loading

0 comments on commit 2621498

Please sign in to comment.