use pros_core::bail_on;
use pros_sys::PROS_ERR;
use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort};
#[derive(Debug, Eq, PartialEq)]
pub struct AdiAnalogIn {
port: AdiPort,
}
impl AdiAnalogIn {
pub fn new(port: AdiPort) -> Result<Self, AdiError> {
bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_port_set_config(
port.internal_expander_index(),
port.index(),
pros_sys::E_ADI_ANALOG_IN,
)
});
Ok(Self { port })
}
pub fn calibrate(&mut self) -> Result<(), AdiError> {
bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_analog_calibrate(
self.port.internal_expander_index(),
self.port.index(),
)
});
Ok(())
}
pub fn value(&self) -> Result<u16, AdiError> {
Ok(bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_analog_read(self.port.internal_expander_index(), self.port.index())
}) as u16)
}
pub fn voltage(&self) -> Result<f64, AdiError> {
Ok(self.value()? as f64 / 4095.0 * 5.0)
}
pub fn calibrated_value(&self) -> Result<i16, AdiError> {
Ok(bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_analog_read_calibrated(
self.port.internal_expander_index(),
self.port.index(),
)
}) as i16)
}
pub fn high_precision_calibrated_value(&self) -> Result<i16, AdiError> {
Ok(bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_analog_read_calibrated_HR(
self.port.internal_expander_index(),
self.port.index(),
)
}) as i16)
}
}
impl AdiDevice for AdiAnalogIn {
type PortIndexOutput = u8;
fn port_index(&self) -> Self::PortIndexOutput {
self.port.index()
}
fn expander_port_index(&self) -> Option<u8> {
self.port.expander_index()
}
fn device_type(&self) -> AdiDeviceType {
AdiDeviceType::AnalogIn
}
}