use std::marker::PhantomData;
use num_enum::{IntoPrimitive, TryFromPrimitive};
use crate::ffi;
use crate::util::PhantomLifetime;
use crate::{try_d3xx, Device, Result};
pub struct Gpio<'a> {
handle: ffi::FT_HANDLE,
pin: GpioPin,
_lifetime_marker: PhantomLifetime<'a>,
}
impl<'a> Gpio<'a> {
pub(crate) fn new(device: &'a Device, pin: GpioPin) -> Self {
Self {
handle: device.handle(),
pin,
_lifetime_marker: PhantomData,
}
}
pub fn enable(&self, direction: Direction) -> Result<()> {
try_d3xx!(unsafe {
ffi::FT_EnableGPIO(
self.handle,
1u32 << u8::from(self.pin),
u32::from(u8::from(direction) << u8::from(self.pin)),
)
})
}
pub fn set_pull(&self, pull: PullMode) -> Result<()> {
try_d3xx!(unsafe {
ffi::FT_SetGPIOPull(
self.handle,
1u32 << u8::from(self.pin),
u32::from(u8::from(pull) << u8::from(self.pin)),
)
})
}
pub fn write(&self, level: Level) -> Result<()> {
try_d3xx!(unsafe {
ffi::FT_WriteGPIO(
self.handle,
1u32 << u8::from(self.pin),
u32::from(u8::from(level) << u8::from(self.pin)),
)
})
}
#[allow(clippy::missing_panics_doc)]
pub fn read(&self) -> Result<Level> {
let mut value: u32 = 0;
try_d3xx!(unsafe { ffi::FT_ReadGPIO(self.handle, &mut value) })?;
let bit = ((value >> u8::from(self.pin)) & 1) as u8;
Ok(Level::try_from(bit).unwrap())
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
pub enum GpioPin {
Pin0 = 0,
Pin1 = 1,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
pub enum Direction {
Input = 0,
Output = 1,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
pub enum Level {
Low = 0,
High = 1,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
pub enum PullMode {
PullDown = 0,
HighImpedance = 1,
PullUp = 2,
}