Skip to content

Commit 1e0afae

Browse files
committed
into_mode for ErasedPin and PartiallyErasedPin
1 parent 0654d98 commit 1e0afae

File tree

3 files changed

+62
-12
lines changed

3 files changed

+62
-12
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
9+
910
- Integrate new version of stm32_i2s (v0.5) to enable full-duplex operation
1011
- Add a rtic example to show how to do full-duplex i2s
1112

@@ -16,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1617

1718
### Added
1819

20+
- `into_mode` for `ErasedPin` and `PartiallyErasedPin`
1921
- Extended 64-bit monotonic timer [#640]
2022
- Basic blocking QSPI interface [#645]
2123

src/gpio/convert.rs

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -204,45 +204,84 @@ impl<const P: char, const N: u8, MODE: PinMode> Pin<P, N, MODE> {
204204
/// ensure they use this properly.
205205
#[inline(always)]
206206
pub(super) fn mode<M: PinMode>(&mut self) {
207-
let offset = 2 * N;
207+
change_mode!((*Gpio::<P>::ptr()), N);
208+
}
209+
210+
#[inline(always)]
211+
/// Converts pin into specified mode
212+
pub fn into_mode<M: PinMode>(mut self) -> Pin<P, N, M> {
213+
self.mode::<M>();
214+
Pin::new()
215+
}
216+
}
217+
218+
macro_rules! change_mode {
219+
($block:expr, $N:ident) => {
220+
let offset = 2 * $N;
208221
unsafe {
209222
if MODE::OTYPER != M::OTYPER {
210223
if let Some(otyper) = M::OTYPER {
211-
(*Gpio::<P>::ptr())
224+
$block
212225
.otyper
213-
.modify(|r, w| w.bits(r.bits() & !(0b1 << N) | (otyper << N)));
226+
.modify(|r, w| w.bits(r.bits() & !(0b1 << $N) | (otyper << $N)));
214227
}
215228
}
216229

217230
if MODE::AFR != M::AFR {
218231
if let Some(afr) = M::AFR {
219-
if N < 8 {
220-
let offset2 = 4 * { N };
221-
(*Gpio::<P>::ptr()).afrl.modify(|r, w| {
232+
if $N < 8 {
233+
let offset2 = 4 * { $N };
234+
$block.afrl.modify(|r, w| {
222235
w.bits((r.bits() & !(0b1111 << offset2)) | (afr << offset2))
223236
});
224237
} else {
225-
let offset2 = 4 * { N - 8 };
226-
(*Gpio::<P>::ptr()).afrh.modify(|r, w| {
238+
let offset2 = 4 * { $N - 8 };
239+
$block.afrh.modify(|r, w| {
227240
w.bits((r.bits() & !(0b1111 << offset2)) | (afr << offset2))
228241
});
229242
}
230243
}
231244
}
232245

233246
if MODE::MODER != M::MODER {
234-
(*Gpio::<P>::ptr())
247+
$block
235248
.moder
236249
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (M::MODER << offset)));
237250
}
238251
}
252+
};
253+
}
254+
use change_mode;
255+
256+
use super::ErasedPin;
257+
impl<MODE: PinMode> ErasedPin<MODE> {
258+
#[inline(always)]
259+
pub(super) fn mode<M: PinMode>(&mut self) {
260+
let n = self.pin_id();
261+
change_mode!(self.block(), n);
239262
}
240263

241264
#[inline(always)]
242265
/// Converts pin into specified mode
243-
pub fn into_mode<M: PinMode>(mut self) -> Pin<P, N, M> {
266+
pub fn into_mode<M: PinMode>(mut self) -> ErasedPin<M> {
244267
self.mode::<M>();
245-
Pin::new()
268+
ErasedPin::from_pin_port(self.into_pin_port())
269+
}
270+
}
271+
272+
use super::PartiallyErasedPin;
273+
impl<const P: char, MODE: PinMode> PartiallyErasedPin<P, MODE> {
274+
#[inline(always)]
275+
pub(super) fn mode<M: PinMode>(&mut self) {
276+
let n = self.pin_id();
277+
change_mode!((*Gpio::<P>::ptr()), n);
278+
}
279+
280+
#[inline(always)]
281+
/// Converts pin into specified mode
282+
pub fn into_mode<M: PinMode>(mut self) -> PartiallyErasedPin<P, M> {
283+
self.mode::<M>();
284+
PartiallyErasedPin::new(self.i)
246285
}
247286
}
248287

src/gpio/erased.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ impl<MODE> PinExt for ErasedPin<MODE> {
4949
}
5050

5151
impl<MODE> ErasedPin<MODE> {
52+
pub(crate) fn from_pin_port(pin_port: u8) -> Self {
53+
Self {
54+
pin_port,
55+
_mode: PhantomData,
56+
}
57+
}
58+
pub(crate) fn into_pin_port(self) -> u8 {
59+
self.pin_port
60+
}
5261
pub(crate) fn new(port: u8, pin: u8) -> Self {
5362
Self {
5463
pin_port: port << 4 | pin,
@@ -64,7 +73,7 @@ impl<MODE> ErasedPin<MODE> {
6473
}
6574

6675
#[inline]
67-
fn block(&self) -> &crate::pac::gpioa::RegisterBlock {
76+
pub(crate) fn block(&self) -> &crate::pac::gpioa::RegisterBlock {
6877
// This function uses pointer arithmetic instead of branching to be more efficient
6978

7079
// The logic relies on the following assumptions:

0 commit comments

Comments
 (0)