Skip to content

Commit b1b1087

Browse files
jbeaurivagesajattack
authored andcommitted
changed(eic)!: EIC pins no longer need to take a reference to the underlying peripheral (#635)
1 parent 4782ad2 commit b1b1087

File tree

6 files changed

+156
-101
lines changed

6 files changed

+156
-101
lines changed

hal/src/gpio/dynpin.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@
3636
//! Users may try to convert value-level pins back to their type-level
3737
//! equivalents. However, this option is fallible, because the compiler cannot
3838
//! guarantee the pin has the correct ID or is in the correct mode at
39-
//! compile-time. Use [`TryFrom`](core::convert::TryFrom)/
40-
//! [`TryInto`](core::convert::TryInto) for this conversion.
39+
//! compile-time. Use [`TryFrom`]/[`TryInto`] for this conversion.
4140
//!
4241
//! ```
4342
//! // Convert to a `DynPin`

hal/src/gpio/pin.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
//! struct.
4040
//!
4141
//! To create the [`Pins`] struct, users must supply the PAC
42-
//! [`Port`](crate::pac::Port) peripheral. The [`Pins`] struct takes
42+
//! [`Port`] peripheral. The [`Pins`] struct takes
4343
//! ownership of the [`Port`] and provides the corresponding pins. Each [`Pin`]
4444
//! within the [`Pins`] struct can be moved out and used individually.
4545
//!
@@ -123,7 +123,7 @@ use super::reg::RegisterInterface;
123123
///
124124
/// [type-level enum]: crate::typelevel#type-level-enum
125125
pub trait DisabledConfig: Sealed {
126-
/// Corresponding [`DynDisabled`](super::DynDisabled)
126+
/// Corresponding [`DynDisabled`]
127127
const DYN: DynDisabled;
128128
}
129129

@@ -181,7 +181,7 @@ pub type Reset = FloatingDisabled;
181181
///
182182
/// [type-level enum]: crate::typelevel#type-level-enum
183183
pub trait InputConfig: Sealed {
184-
/// Corresponding [`DynInput`](super::DynInput)
184+
/// Corresponding [`DynInput`]
185185
const DYN: DynInput;
186186
}
187187

@@ -220,7 +220,7 @@ pub type PullUpInput = Input<PullUp>;
220220

221221
/// Type-level `enum` for Interrupt configurations
222222
pub trait InterruptConfig: Sealed {
223-
/// Corresponding [`DynInterrupt`](super::DynInterrupt)
223+
/// Corresponding [`DynInterrupt`]
224224
const DYN: DynInterrupt;
225225
}
226226

@@ -264,7 +264,7 @@ pub type PullUpInterrupt = Interrupt<PullUp>;
264264
///
265265
/// [type-level enum]: crate::typelevel#type-level-enum
266266
pub trait OutputConfig: Sealed {
267-
/// Corresponding [`DynOutput`](super::DynOutput)
267+
/// Corresponding [`DynOutput`]
268268
const DYN: DynOutput;
269269
}
270270

@@ -309,7 +309,7 @@ pub type ReadableOutput = Output<Readable>;
309309
///
310310
/// [type-level enum]: crate::typelevel#type-level-enum
311311
pub trait AlternateConfig: Sealed {
312-
/// Corresponding [`DynAlternate`](super::DynAlternate)
312+
/// Corresponding [`DynAlternate`]
313313
const DYN: DynAlternate;
314314
}
315315

@@ -368,7 +368,7 @@ impl<C: AlternateConfig> Sealed for Alternate<C> {}
368368
///
369369
/// [type-level enum]: crate::typelevel#type-level-enum
370370
pub trait PinMode: Sealed {
371-
/// Corresponding [`DynPinMode`](super::DynPinMode)
371+
/// Corresponding [`DynPinMode`]
372372
const DYN: DynPinMode;
373373
}
374374

@@ -404,7 +404,7 @@ impl<C: AlternateConfig> PinMode for Alternate<C> {
404404
///
405405
/// [type-level enum]: crate::typelevel#type-level-enum
406406
pub trait PinId: Sealed {
407-
/// Corresponding [`DynPinId`](super::DynPinId)
407+
/// Corresponding [`DynPinId`]
408408
const DYN: DynPinId;
409409
}
410410

hal/src/peripherals/eic/d11/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use crate::clock::EicClock;
2-
use crate::pac;
1+
use crate::{clock::EicClock, pac};
32

43
pub mod pin;
54

hal/src/peripherals/eic/d11/pin.rs

+30-23
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::gpio::{
44
};
55
use crate::pac;
66
use atsamd_hal_macros::hal_cfg;
7+
use core::mem::ManuallyDrop;
78

89
use super::EIC;
910

@@ -18,13 +19,13 @@ pub trait EicPin {
1819
type PullDown;
1920

2021
/// Configure a pin as a floating external interrupt
21-
fn into_floating_ei(self) -> Self::Floating;
22+
fn into_floating_ei(self, eic: &mut EIC) -> Self::Floating;
2223

2324
/// Configure a pin as pulled-up external interrupt
24-
fn into_pull_up_ei(self) -> Self::PullUp;
25+
fn into_pull_up_ei(self, eic: &mut EIC) -> Self::PullUp;
2526

2627
/// Configure a pin as pulled-down external interrupt
27-
fn into_pull_down_ei(self) -> Self::PullDown;
28+
fn into_pull_down_ei(self, eic: &mut EIC) -> Self::PullDown;
2829
}
2930

3031
pub type Sense = pac::eic::config::Sense0select;
@@ -56,6 +57,7 @@ crate::paste::item! {
5657
where
5758
GPIO: AnyPin,
5859
{
60+
eic: ManuallyDrop<EIC>,
5961
_pin: Pin<GPIO::Id, GPIO::Mode>,
6062
}
6163

@@ -66,33 +68,38 @@ crate::paste::item! {
6668
/// Construct pad from the appropriate pin in any mode.
6769
/// You may find it more convenient to use the `into_pad` trait
6870
/// and avoid referencing the pad type.
69-
pub fn new(pin: GPIO) -> Self {
71+
pub fn new(pin: GPIO, eic: &mut super::EIC) -> [<$PadType $num>]<GPIO> {
72+
let eic = unsafe {
73+
ManuallyDrop::new(core::ptr::read(eic as *const _))
74+
};
75+
7076
[<$PadType $num>]{
71-
_pin:pin.into()
77+
_pin:pin.into(),
78+
eic,
7279
}
7380
}
7481

7582
/// Configure the eic with options for this external interrupt
76-
pub fn enable_event(&mut self, eic: &mut EIC) {
77-
eic.eic.evctrl().modify(|_, w| {
83+
pub fn enable_event(&mut self) {
84+
self.eic.eic.evctrl().modify(|_, w| {
7885
w.[<extinteo $num>]().set_bit()
7986
});
8087
}
8188

82-
pub fn enable_interrupt(&mut self, eic: &mut EIC) {
83-
eic.eic.intenset().write(|w| {
89+
pub fn enable_interrupt(&mut self) {
90+
self.eic.eic.intenset().write(|w| {
8491
w.[<extint $num>]().set_bit()
8592
});
8693
}
8794

88-
pub fn enable_interrupt_wake(&mut self, eic: &mut EIC) {
89-
eic.eic.wakeup().modify(|_, w| {
95+
pub fn enable_interrupt_wake(&mut self) {
96+
self.eic.eic.wakeup().modify(|_, w| {
9097
w.[<wakeupen $num>]().set_bit()
9198
})
9299
}
93100

94-
pub fn disable_interrupt(&mut self, eic: &mut EIC) {
95-
eic.eic.intenclr().write(|w| {
101+
pub fn disable_interrupt(&mut self) {
102+
self.eic.eic.intenclr().write(|w| {
96103
w.[<extint $num>]().set_bit()
97104
});
98105
}
@@ -107,10 +114,10 @@ crate::paste::item! {
107114
});
108115
}
109116

110-
pub fn sense(&mut self, _eic: &mut EIC, sense: Sense) {
117+
pub fn sense(&mut self, sense: Sense) {
111118
// Which of the two config blocks this eic config is in
112119
let offset = ($num >> 3) & 0b0001;
113-
let config = unsafe { &(*pac::Eic::ptr()).config(offset) };
120+
let config = &self.eic.eic.config(offset);
114121

115122
config.modify(|_, w| unsafe {
116123
// Which of the eight eic configs in this config block
@@ -128,10 +135,10 @@ crate::paste::item! {
128135
});
129136
}
130137

131-
pub fn filter(&mut self, _eic: &mut EIC, filter: bool) {
138+
pub fn filter(&mut self, filter: bool) {
132139
// Which of the two config blocks this eic config is in
133140
let offset = ($num >> 3) & 0b0001;
134-
let config = unsafe { &(*pac::Eic::ptr()).config(offset) };
141+
let config = &self.eic.eic.config(offset);
135142

136143
config.modify(|_, w| {
137144
// Which of the eight eic configs in this config block
@@ -179,16 +186,16 @@ crate::paste::item! {
179186
type PullUp = [<$PadType $num>]<Pin<gpio::$PinType, PullUpInterrupt>>;
180187
type PullDown = [<$PadType $num>]<Pin<gpio::$PinType, PullDownInterrupt>>;
181188

182-
fn into_floating_ei(self) -> Self::Floating {
183-
[<$PadType $num>]::new(self.into_floating_interrupt())
189+
fn into_floating_ei(self, eic: &mut super::EIC) -> Self::Floating {
190+
[<$PadType $num>]::new(self.into_floating_interrupt(), eic)
184191
}
185192

186-
fn into_pull_up_ei(self) -> Self::PullUp {
187-
[<$PadType $num>]::new(self.into_pull_up_interrupt())
193+
fn into_pull_up_ei(self, eic: &mut super::EIC) -> Self::PullUp {
194+
[<$PadType $num>]::new(self.into_pull_up_interrupt(), eic)
188195
}
189196

190-
fn into_pull_down_ei(self) -> Self::PullDown {
191-
[<$PadType $num>]::new(self.into_pull_down_interrupt())
197+
fn into_pull_down_ei(self, eic: &mut super::EIC) -> Self::PullDown {
198+
[<$PadType $num>]::new(self.into_pull_down_interrupt(), eic)
192199
}
193200
}
194201

hal/src/peripherals/eic/d5x/mod.rs

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use crate::clock::EicClock;
2-
use crate::pac;
1+
use crate::{clock::EicClock, pac};
32

43
pub mod pin;
54

@@ -59,7 +58,32 @@ pub fn init_with_ulp32k(mclk: &mut pac::Mclk, _clock: EicClock, eic: pac::Eic) -
5958

6059
/// A configured External Interrupt Controller.
6160
pub struct EIC {
62-
_eic: pac::Eic,
61+
eic: pac::Eic,
62+
}
63+
64+
impl EIC {
65+
/// Run the provided closure with the EIC peripheral disabled. The
66+
/// enable-protected registers, such as CONFIGx, should be accessed through
67+
/// this method.
68+
///
69+
/// # Caution
70+
///
71+
/// You should not re-enable the provided EIC PAC object inside the provided
72+
/// closure.
73+
fn with_disable(&mut self, fun: impl Fn(&mut pac::Eic)) {
74+
self.eic.ctrla().modify(|_, w| w.enable().clear_bit());
75+
self.enable_sync();
76+
fun(&mut self.eic);
77+
self.eic.ctrla().modify(|_, w| w.enable().set_bit());
78+
self.enable_sync();
79+
}
80+
81+
/// Busy-wait until SYNCBUSY.ENABLE clears
82+
fn enable_sync(&mut self) {
83+
while self.eic.syncbusy().read().enable().bit_is_set() {
84+
core::hint::spin_loop();
85+
}
86+
}
6387
}
6488

6589
impl From<ConfigurableEIC> for EIC {
@@ -69,6 +93,6 @@ impl From<ConfigurableEIC> for EIC {
6993
cortex_m::asm::nop();
7094
}
7195

72-
Self { _eic: eic.eic }
96+
Self { eic: eic.eic }
7397
}
7498
}

0 commit comments

Comments
 (0)