pounder_test/src/hardware/afe.rs

97 lines
2.2 KiB
Rust
Raw Normal View History

2021-03-01 21:46:12 +08:00
use miniconf::Miniconf;
use serde::{Deserialize, Serialize};
2020-06-03 23:36:43 +08:00
use core::convert::TryFrom;
use enum_iterator::IntoEnumIterator;
#[derive(
2021-03-01 21:46:12 +08:00
Copy, Clone, Debug, Serialize, Deserialize, IntoEnumIterator, Miniconf,
)]
pub enum Gain {
G1 = 0b00,
G2 = 0b01,
G5 = 0b10,
2020-06-16 22:22:12 +08:00
G10 = 0b11,
}
2020-06-11 17:51:52 +08:00
/// A programmable gain amplifier that allows for setting the gain via GPIO.
pub struct ProgrammableGainAmplifier<A0, A1> {
a0: A0,
2020-06-16 22:22:12 +08:00
a1: A1,
}
2021-04-29 22:22:06 +08:00
impl Gain {
2021-05-06 18:33:07 +08:00
/// Get the AFE gain as a numerical value.
2021-05-06 18:35:04 +08:00
pub fn as_multiplier(self) -> f32 {
2021-04-29 22:22:06 +08:00
match self {
2021-05-06 18:33:07 +08:00
Gain::G1 => 1.0,
Gain::G2 => 2.0,
Gain::G5 => 5.0,
Gain::G10 => 10.0,
2021-04-29 22:22:06 +08:00
}
}
}
2020-06-03 23:36:43 +08:00
impl TryFrom<u8> for Gain {
type Error = ();
fn try_from(value: u8) -> Result<Self, Self::Error> {
for gain in Gain::into_enum_iter() {
if value == gain as u8 {
2020-06-16 22:22:12 +08:00
return Ok(gain);
2020-06-03 23:36:43 +08:00
}
}
Err(())
}
}
impl<A0, A1> ProgrammableGainAmplifier<A0, A1>
where
A0: embedded_hal::digital::v2::StatefulOutputPin,
A0::Error: core::fmt::Debug,
A1: embedded_hal::digital::v2::StatefulOutputPin,
A1::Error: core::fmt::Debug,
{
2020-06-11 17:51:52 +08:00
/// Construct a new programmable gain driver.
///
/// Args:
/// * `a0` - An output connected to the A0 input of the amplifier.
/// * `a1` - An output connected to the A1 input of the amplifier.
2020-06-16 22:22:12 +08:00
pub fn new(a0: A0, a1: A1) -> Self {
let mut afe = Self { a0, a1 };
afe.set_gain(Gain::G1);
afe
}
2020-06-11 17:51:52 +08:00
/// Set the gain of the front-end.
pub fn set_gain(&mut self, gain: Gain) {
2020-06-03 16:36:35 +08:00
if (gain as u8 & 0b01) != 0 {
self.a0.set_high().unwrap();
} else {
self.a0.set_low().unwrap();
}
if (gain as u8 & 0b10) != 0 {
self.a1.set_high().unwrap()
} else {
self.a1.set_low().unwrap();
}
}
2020-06-11 17:51:52 +08:00
/// Get the programmed gain of the analog front-end.
2020-06-03 23:36:43 +08:00
pub fn get_gain(&self) -> Result<Gain, ()> {
let mut code: u8 = 0;
if self.a0.is_set_high().unwrap() {
code |= 0b1;
}
if self.a1.is_set_high().unwrap() {
code |= 0b10;
}
2020-06-03 23:36:43 +08:00
Gain::try_from(code)
}
}