2020-06-16 22:22:12 +08:00
|
|
|
use serde::{Deserialize, Serialize};
|
2020-04-29 17:59:04 +08:00
|
|
|
|
2020-06-03 23:36:43 +08:00
|
|
|
use core::convert::TryFrom;
|
|
|
|
use enum_iterator::IntoEnumIterator;
|
2020-04-29 17:59:04 +08:00
|
|
|
|
2020-06-09 01:13:55 +08:00
|
|
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, IntoEnumIterator)]
|
2020-04-29 17:59:04 +08:00
|
|
|
pub enum Gain {
|
|
|
|
G1 = 0b00,
|
|
|
|
G2 = 0b01,
|
|
|
|
G5 = 0b10,
|
2020-06-16 22:22:12 +08:00
|
|
|
G10 = 0b11,
|
2020-04-29 17:59:04 +08:00
|
|
|
}
|
|
|
|
|
2020-06-11 17:51:52 +08:00
|
|
|
/// A programmable gain amplifier that allows for setting the gain via GPIO.
|
2020-04-29 17:59:04 +08:00
|
|
|
pub struct ProgrammableGainAmplifier<A0, A1> {
|
|
|
|
a0: A0,
|
2020-06-16 22:22:12 +08:00
|
|
|
a1: A1,
|
2020-04-29 17:59:04 +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(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-29 17:59:04 +08:00
|
|
|
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 {
|
2020-06-17 20:57:09 +08:00
|
|
|
let mut afe = Self { a0, a1 };
|
2020-04-29 17:59:04 +08:00
|
|
|
|
|
|
|
afe.set_gain(Gain::G1);
|
|
|
|
|
|
|
|
afe
|
|
|
|
}
|
|
|
|
|
2020-06-11 17:51:52 +08:00
|
|
|
/// Set the gain of the front-end.
|
2020-04-29 17:59:04 +08:00
|
|
|
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-04-29 17:59:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-04-29 17:59:04 +08:00
|
|
|
}
|
2020-06-03 23:36:43 +08:00
|
|
|
|
|
|
|
Gain::try_from(code)
|
2020-04-29 17:59:04 +08:00
|
|
|
}
|
|
|
|
}
|