Skip to content

Commit

Permalink
Add Pull-Up/Pull-Down traits and implement them for the PI4IOE5V6408
Browse files Browse the repository at this point in the history
  • Loading branch information
t-moe committed Feb 16, 2024
1 parent 57538d8 commit 009f779
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ pub trait PortDriverPolarity: PortDriver {
fn set_polarity(&mut self, mask: u32, inverted: bool) -> Result<(), Self::Error>;
}

pub trait PortDriverPullDown: PortDriver {
/// Enable pull-downs for pins in mask or set the pin to floating if enable is false.
fn set_pull_down(&mut self, mask: u32, enable: bool) -> Result<(), Self::Error>;
}

pub trait PortDriverPullUp: PortDriver {
/// Enable pull-ups for pins in mask or set the pin to floating if enable is false.
fn set_pull_up(&mut self, mask: u32, enable: bool) -> Result<(), Self::Error>;
}

/// Pin Modes
pub mod mode {
/// Trait for pin-modes which can be used to set a logic level.
Expand Down
53 changes: 52 additions & 1 deletion src/dev/pi4ioe5v6408.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,36 @@ impl<I2C: crate::I2cBus> crate::PortDriverTotemPole for Driver<I2C> {
}
}

impl<I2C: crate::I2cBus> crate::PortDriverPullDown for Driver<I2C> {
fn set_pull_down(&mut self, mask: u32, enable: bool) -> Result<(), Self::Error> {
if enable {
self.i2c
.update_reg(self.addr, Regs::PullUpPullDownSelection, 0, mask as u8)?;
self.i2c
.update_reg(self.addr, Regs::PullUpPullDownEnable, mask as u8, 0)?;
} else {
self.i2c
.update_reg(self.addr, Regs::PullUpPullDownEnable, 0, mask as u8)?;
}
Ok(())
}
}

impl<I2C: crate::I2cBus> crate::PortDriverPullUp for Driver<I2C> {
fn set_pull_up(&mut self, mask: u32, enable: bool) -> Result<(), Self::Error> {
if enable {
self.i2c
.update_reg(self.addr, Regs::PullUpPullDownSelection, mask as u8, 0)?;
self.i2c
.update_reg(self.addr, Regs::PullUpPullDownEnable, mask as u8, 0)?;
} else {
self.i2c
.update_reg(self.addr, Regs::PullUpPullDownEnable, 0, mask as u8)?;
}
Ok(())
}
}

#[cfg(test)]
mod tests {
use embedded_hal_mock::eh1::i2c as mock_i2c;
Expand Down Expand Up @@ -225,6 +255,22 @@ mod tests {
// io0 reads
mock_i2c::Transaction::write_read(0x43, vec![0x0f], vec![0b00000001]),
mock_i2c::Transaction::write_read(0x43, vec![0x0f], vec![0b00000000]),
// io0 activate pull-up
mock_i2c::Transaction::write_read(0x43, vec![0x0d], vec![0b10101010]),
mock_i2c::Transaction::write(0x43, vec![0x0d, 0b10101011]),
mock_i2c::Transaction::write_read(0x43, vec![0x0b], vec![0b00001010]),
mock_i2c::Transaction::write(0x43, vec![0x0b, 0b00001011]),
// io0 disable pull-up
mock_i2c::Transaction::write_read(0x43, vec![0x0b], vec![0b00001011]),
mock_i2c::Transaction::write(0x43, vec![0x0b, 0b00001010]),
// io0 activate pull-down
mock_i2c::Transaction::write_read(0x43, vec![0x0d], vec![0b10101011]),
mock_i2c::Transaction::write(0x43, vec![0x0d, 0b10101010]),
mock_i2c::Transaction::write_read(0x43, vec![0x0b], vec![0b00001010]),
mock_i2c::Transaction::write(0x43, vec![0x0b, 0b00001011]),
// io0 disable pull-down
mock_i2c::Transaction::write_read(0x43, vec![0x0b], vec![0b00001011]),
mock_i2c::Transaction::write(0x43, vec![0x0b, 0b00001010]),
];
let mut bus = mock_i2c::Mock::new(&expectations);

Expand All @@ -234,7 +280,7 @@ mod tests {
let io0 = pca_pins.io0.into_output().unwrap();
let mut io1 = pca_pins.io1.into_output_high().unwrap();

let io0 = io0.into_input().unwrap();
let mut io0 = io0.into_input().unwrap();

io1.set_low().unwrap();
io1.set_high().unwrap();
Expand All @@ -243,6 +289,11 @@ mod tests {
assert!(io0.is_high().unwrap());
assert!(io0.is_low().unwrap());

io0.enable_pull_up(true).unwrap();
io0.enable_pull_up(false).unwrap();
io0.enable_pull_down(true).unwrap();
io0.enable_pull_down(false).unwrap();

bus.done();
}

Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ pub(crate) use bus::I2cExt;
pub(crate) use common::Direction;
pub(crate) use common::PortDriver;
pub(crate) use common::PortDriverPolarity;
pub(crate) use common::PortDriverPullDown;
pub(crate) use common::PortDriverPullUp;
pub(crate) use common::PortDriverTotemPole;

pub use dev::max7321::Max7321;
Expand Down
22 changes: 22 additions & 0 deletions src/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,28 @@ where
}
}

impl<'a, MODE: crate::mode::HasInput, MUTEX, PD> Pin<'a, MODE, MUTEX>
where
PD: crate::PortDriver + crate::PortDriverPullUp,
MUTEX: shared_bus::BusMutex<Bus = PD>,
{
pub fn enable_pull_up(&mut self, enable: bool) -> Result<(), PD::Error> {
self.port_driver
.lock(|drv| drv.set_pull_up(self.pin_mask, enable))
}
}

impl<'a, MODE: crate::mode::HasInput, MUTEX, PD> Pin<'a, MODE, MUTEX>
where
PD: crate::PortDriver + crate::PortDriverPullDown,
MUTEX: shared_bus::BusMutex<Bus = PD>,
{
pub fn enable_pull_down(&mut self, enable: bool) -> Result<(), PD::Error> {
self.port_driver
.lock(|drv| drv.set_pull_down(self.pin_mask, enable))
}
}

impl<'a, MODE: crate::mode::HasInput, MUTEX, PD> hal_digital::InputPin for Pin<'a, MODE, MUTEX>
where
PD: crate::PortDriver + crate::PortDriverTotemPole,
Expand Down

0 comments on commit 009f779

Please sign in to comment.