Skip to content

Commit 8b18b78

Browse files
sundbom-grepittmplt
authored andcommitted
pio: implement open-drain/multi-drive API
1 parent c9fef17 commit 8b18b78

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- [Integration](https://crates.io/crates/mcan-core) with the
88
[`mcan`](https://crates.io/crates/mcan) crate.
99
- Implementation of blocking::i2c::Transactional trait from [embedded-hal](https://crates.io/crates/embedded-hal) for TWI device.
10+
- PIO: open-drain/multi-driver support
1011

1112
### Changed
1213

hal/src/pio/dynpin.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ pub enum DynPinMode {
7373
Reset,
7474
Peripheral(DynPeripheral),
7575
Output,
76+
OpenDrain,
7677
Input,
7778
}
7879

hal/src/pio/pin.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ impl generics::Sealed for Input {}
5555
pub enum Output {}
5656
impl generics::Sealed for Output {}
5757

58+
/// Type indicating that the [`Pin`] is an open drain
59+
pub enum OpenDrain {}
60+
impl generics::Sealed for OpenDrain {}
61+
5862
//================================================================================
5963
// Peripheral configurations
6064
//================================================================================
@@ -117,6 +121,10 @@ impl PinMode for Output {
117121
const DYN: DynPinMode = DynPinMode::Output;
118122
}
119123

124+
impl PinMode for OpenDrain {
125+
const DYN: DynPinMode = DynPinMode::OpenDrain;
126+
}
127+
120128
impl PinMode for Input {
121129
const DYN: DynPinMode = DynPinMode::Input;
122130
}
@@ -207,6 +215,15 @@ where
207215
pin
208216
}
209217

218+
/// Configures tis pin to operate as an [`OpenDrain`] [`Pin`].
219+
#[inline]
220+
pub fn into_opendrain(self, cfg: PullDir) -> Pin<I, OpenDrain> {
221+
let mut pin: Pin<I, OpenDrain> = self.into_mode();
222+
pin.set_pull_dir(cfg);
223+
224+
pin
225+
}
226+
210227
/// Configures this [`Pin`] to operate as an [`Input`] [`Pin`].
211228
#[inline]
212229
pub fn into_input(self, cfg: PullDir) -> Pin<I, Input> {
@@ -423,6 +440,25 @@ where
423440
}
424441
}
425442

443+
impl<I> OutputPin for Pin<I, OpenDrain>
444+
where
445+
I: PinId,
446+
{
447+
type Error = Infallible;
448+
449+
#[inline]
450+
fn set_high(&mut self) -> Result<(), Self::Error> {
451+
self.set_pull_dir(PullDir::PullUp);
452+
Ok(())
453+
}
454+
455+
#[inline]
456+
fn set_low(&mut self) -> Result<(), Self::Error> {
457+
self.set_pull_dir(PullDir::Floating);
458+
Ok(())
459+
}
460+
}
461+
426462
#[cfg(feature = "unproven")]
427463
impl<I> ToggleableOutputPin for Pin<I, Output>
428464
where

hal/src/pio/reg.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub(in crate::pio) trait RegisterInterface {
2323
DynPinMode::Reset => unimplemented!(),
2424
DynPinMode::Peripheral(a) => self.as_peripheral(a),
2525
DynPinMode::Output => self.as_output(),
26+
DynPinMode::OpenDrain => self.as_opendrain(),
2627
DynPinMode::Input => self.as_input(),
2728
}
2829
}
@@ -67,6 +68,18 @@ pub(in crate::pio) trait RegisterInterface {
6768
self.reg().oer.write(|w| unsafe { w.bits(self.mask()) });
6869
}
6970

71+
#[inline]
72+
fn as_opendrain(&mut self) {
73+
// take pin from peripheral
74+
self.reg().per.write(|w| unsafe { w.bits(self.mask()) });
75+
76+
// Enable multidrive
77+
self.reg().mder.write(|w| unsafe { w.bits(self.mask()) });
78+
79+
// disable pin output, driver should not be connected
80+
self.reg().odr.write(|w| unsafe { w.bits(self.mask()) });
81+
}
82+
7083
#[inline]
7184
fn as_input(&mut self) {
7285
// take pin from peripheral

0 commit comments

Comments
 (0)