Skip to content

Commit 8440c24

Browse files
committed
gpio field enums
1 parent 11ada00 commit 8440c24

File tree

5 files changed

+116
-122
lines changed

5 files changed

+116
-122
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2424
- Fix flash error flag clearing [#489]
2525
- Clarify README for windows users [#496]
2626
- Check "device selected" in `build.rs`
27+
- Use gpio field enums internally
2728
- Unmacro `dma.rs`
2829

2930
### Added

src/adc.rs

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,10 @@ macro_rules! adc_hal {
400400
self.rb.sqr3().modify(|_, w| unsafe { w.sq1().bits(chan) });
401401

402402
// ADC start conversion of regular sequence
403-
self.rb.cr2().modify(|_, w|
404-
w
405-
.swstart().set_bit()
406-
.align().bit(self.align.into())
407-
);
403+
self.rb.cr2().modify(|_, w| {
404+
w.swstart().set_bit();
405+
w.align().bit(self.align.into())
406+
});
408407
while self.rb.cr2().read().swstart().bit_is_set() {}
409408
// ADC wait for conversion results
410409
while self.rb.sr().read().eoc().bit_is_clear() {}
@@ -680,14 +679,10 @@ macro_rules! adcdma {
680679
Self: SetChannels<PINS>,
681680
{
682681
self.rb.cr2().modify(|_, w| {
683-
w.adon()
684-
.clear_bit()
685-
.dma()
686-
.clear_bit()
687-
.cont()
688-
.clear_bit()
689-
.align()
690-
.bit(self.align.into())
682+
w.adon().clear_bit();
683+
w.dma().clear_bit();
684+
w.cont().clear_bit();
685+
w.align().bit(self.align.into())
691686
});
692687
self.rb
693688
.cr1()
@@ -761,18 +756,12 @@ macro_rules! adcdma {
761756
atomic::compiler_fence(Ordering::Release);
762757

763758
self.channel.ch().cr().modify(|_, w| {
764-
w.mem2mem()
765-
.clear_bit()
766-
.pl()
767-
.medium()
768-
.msize()
769-
.bits16()
770-
.psize()
771-
.bits16()
772-
.circ()
773-
.set_bit()
774-
.dir()
775-
.clear_bit()
759+
w.mem2mem().clear_bit();
760+
w.pl().medium();
761+
w.msize().bits16();
762+
w.psize().bits16();
763+
w.circ().set_bit();
764+
w.dir().clear_bit()
776765
});
777766

778767
self.start();
@@ -799,18 +788,12 @@ macro_rules! adcdma {
799788

800789
atomic::compiler_fence(Ordering::Release);
801790
self.channel.ch().cr().modify(|_, w| {
802-
w.mem2mem()
803-
.clear_bit()
804-
.pl()
805-
.medium()
806-
.msize()
807-
.bits16()
808-
.psize()
809-
.bits16()
810-
.circ()
811-
.clear_bit()
812-
.dir()
813-
.clear_bit()
791+
w.mem2mem().clear_bit();
792+
w.pl().medium();
793+
w.msize().bits16();
794+
w.psize().bits16();
795+
w.circ().clear_bit();
796+
w.dir().clear_bit()
814797
});
815798
self.start();
816799

src/gpio.rs

Lines changed: 84 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ use crate::pac::EXTI;
8282
mod partially_erased;
8383
pub use partially_erased::{PEPin, PartiallyErasedPin};
8484
mod erased;
85-
pub use erased::{EPin, ErasedPin};
85+
pub use erased::{AnyPin, ErasedPin};
8686

8787
mod hal_02;
8888
mod hal_1;
@@ -99,6 +99,16 @@ pub enum IOPinSpeed {
9999
Mhz50 = 0b11,
100100
}
101101

102+
impl From<IOPinSpeed> for Mode {
103+
fn from(value: IOPinSpeed) -> Self {
104+
match value {
105+
IOPinSpeed::Mhz10 => Self::Output,
106+
IOPinSpeed::Mhz2 => Self::Output2,
107+
IOPinSpeed::Mhz50 => Self::Output50,
108+
}
109+
}
110+
}
111+
102112
pub trait PinExt {
103113
type Mode;
104114

@@ -202,12 +212,14 @@ mod sealed {
202212
pub trait Interruptable {}
203213

204214
pub trait PinMode: Default {
205-
const CNF: u32;
206-
const MODE: u32;
215+
const CNF: super::Cnf;
216+
const MODE: super::Mode;
207217
const PULL: Option<bool> = None;
208218
}
209219
}
210220

221+
use crate::pac::gpioa::crl::{CNF0 as Cnf, MODE0 as Mode};
222+
211223
use sealed::Interruptable;
212224
pub(crate) use sealed::PinMode;
213225

@@ -270,10 +282,10 @@ where
270282
.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << pin_number)) });
271283
}
272284
Edge::Falling => {
273-
exti.ftsr()
274-
.modify(|r, w| unsafe { w.bits(r.bits() | (1 << pin_number)) });
275285
exti.rtsr()
276286
.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << pin_number)) });
287+
exti.ftsr()
288+
.modify(|r, w| unsafe { w.bits(r.bits() | (1 << pin_number)) });
277289
}
278290
Edge::RisingFalling => {
279291
exti.rtsr()
@@ -439,10 +451,6 @@ pub struct Pin<const P: char, const N: u8, MODE = Input<Floating>> {
439451
mode: MODE,
440452
}
441453

442-
impl<const P: char, const N: u8, MODE> Pin<P, N, MODE> {
443-
const OFFSET: u32 = (4 * (N as u32)) % 32;
444-
}
445-
446454
/// Represents high or low configuration register
447455
pub trait HL {
448456
/// Configuration register associated to pin
@@ -518,25 +526,29 @@ impl<const P: char, const N: u8, MODE> Pin<P, N, MODE> {
518526
#[inline(always)]
519527
fn _set_high(&mut self) {
520528
// NOTE(unsafe) atomic write to a stateless register
521-
unsafe { (*Gpio::<P>::ptr()).bsrr().write(|w| w.bits(1 << N)) }
529+
let gpio = unsafe { &(*gpiox::<P>()) };
530+
gpio.bsrr().write(|w| w.bs(N).set_bit())
522531
}
523532

524533
#[inline(always)]
525534
fn _set_low(&mut self) {
526535
// NOTE(unsafe) atomic write to a stateless register
527-
unsafe { (*Gpio::<P>::ptr()).bsrr().write(|w| w.bits(1 << (16 + N))) }
536+
let gpio = unsafe { &(*gpiox::<P>()) };
537+
gpio.bsrr().write(|w| w.br(N).set_bit())
528538
}
529539

530540
#[inline(always)]
531541
fn _is_set_low(&self) -> bool {
532542
// NOTE(unsafe) atomic read with no side effects
533-
unsafe { (*Gpio::<P>::ptr()).odr().read().bits() & (1 << N) == 0 }
543+
let gpio = unsafe { &(*gpiox::<P>()) };
544+
gpio.odr().read().odr(N).bit_is_clear()
534545
}
535546

536547
#[inline(always)]
537548
fn _is_low(&self) -> bool {
538549
// NOTE(unsafe) atomic read with no side effects
539-
unsafe { (*Gpio::<P>::ptr()).idr().read().bits() & (1 << N) == 0 }
550+
let gpio = unsafe { &(*gpiox::<P>()) };
551+
gpio.idr().read().idr(N).bit_is_clear()
540552
}
541553
}
542554

@@ -816,26 +828,20 @@ where
816828
Self: HL,
817829
{
818830
#[inline(always)]
819-
fn cr_modify(&mut self, _cr: &mut <Self as HL>::Cr, f: impl FnOnce(u32) -> u32) {
820-
let gpio = unsafe { &(*Gpio::<P>::ptr()) };
831+
fn _set_speed(&mut self, _cr: &mut <Self as HL>::Cr, speed: IOPinSpeed) {
832+
let gpio = unsafe { &(*gpiox::<P>()) };
821833

822834
match N {
823835
0..=7 => {
824-
gpio.crl().modify(|r, w| unsafe { w.bits(f(r.bits())) });
836+
gpio.crl().modify(|_, w| w.mode(N).variant(speed.into()));
825837
}
826838
8..=15 => {
827-
gpio.crh().modify(|r, w| unsafe { w.bits(f(r.bits())) });
839+
gpio.crh()
840+
.modify(|_, w| unsafe { w.mode(N - 16).bits(speed as u8) });
828841
}
829842
_ => unreachable!(),
830843
}
831844
}
832-
833-
#[inline(always)]
834-
fn _set_speed(&mut self, cr: &mut <Self as HL>::Cr, speed: IOPinSpeed) {
835-
self.cr_modify(cr, |r_bits| {
836-
(r_bits & !(0b11 << Self::OFFSET)) | ((speed as u32) << Self::OFFSET)
837-
});
838-
}
839845
}
840846

841847
impl<const P: char, const N: u8, MODE> OutputSpeed for Pin<P, N, Output<MODE>>
@@ -898,69 +904,79 @@ where
898904
}
899905
}
900906

907+
impl PinMode for Analog {
908+
const MODE: Mode = Mode::Input;
909+
const CNF: Cnf = Cnf::PushPull;
910+
}
911+
901912
impl PinMode for Input<Floating> {
902-
const CNF: u32 = 0b01;
903-
const MODE: u32 = 0b00;
913+
const MODE: Mode = Mode::Input;
914+
const CNF: Cnf = Cnf::OpenDrain;
904915
}
905916

906917
impl PinMode for Input<PullDown> {
907-
const CNF: u32 = 0b10;
908-
const MODE: u32 = 0b00;
918+
const MODE: Mode = Mode::Input;
919+
const CNF: Cnf = Cnf::AltPushPull;
909920
const PULL: Option<bool> = Some(false);
910921
}
911922

912923
impl PinMode for Input<PullUp> {
913-
const CNF: u32 = 0b10;
914-
const MODE: u32 = 0b00;
924+
const MODE: Mode = Mode::Input;
925+
const CNF: Cnf = Cnf::AltPushPull;
915926
const PULL: Option<bool> = Some(true);
916927
}
917928

918-
impl PinMode for Output<OpenDrain> {
919-
const CNF: u32 = 0b01;
920-
const MODE: u32 = 0b11;
921-
}
922-
923929
impl PinMode for Output<PushPull> {
924-
const CNF: u32 = 0b00;
925-
const MODE: u32 = 0b11;
930+
const MODE: Mode = Mode::Output50;
931+
const CNF: Cnf = Cnf::PushPull;
926932
}
927933

928-
impl PinMode for Analog {
929-
const CNF: u32 = 0b00;
930-
const MODE: u32 = 0b00;
934+
impl PinMode for Output<OpenDrain> {
935+
const MODE: Mode = Mode::Output50;
936+
const CNF: Cnf = Cnf::OpenDrain;
931937
}
932938

933939
impl PinMode for Alternate<PushPull> {
934-
const CNF: u32 = 0b10;
935-
const MODE: u32 = 0b11;
940+
const MODE: Mode = Mode::Output50;
941+
const CNF: Cnf = Cnf::AltPushPull;
936942
}
937943

938944
impl PinMode for Alternate<OpenDrain> {
939-
const CNF: u32 = 0b11;
940-
const MODE: u32 = 0b11;
945+
const MODE: Mode = Mode::Output50;
946+
const CNF: Cnf = Cnf::AltOpenDrain;
941947
}
942948

943949
impl<const P: char, const N: u8, M> Pin<P, N, M>
944950
where
945951
Self: HL,
946952
{
947-
fn mode<MODE: PinMode>(&mut self, cr: &mut <Self as HL>::Cr) {
948-
let gpio = unsafe { &(*Gpio::<P>::ptr()) };
953+
fn mode<MODE: PinMode>(&mut self, _cr: &mut <Self as HL>::Cr) {
954+
let gpio = unsafe { &(*gpiox::<P>()) };
949955

950956
// Input<PullUp> or Input<PullDown> mode
951957
if let Some(pull) = MODE::PULL {
952-
if pull {
953-
gpio.bsrr().write(|w| unsafe { w.bits(1 << N) });
954-
} else {
955-
gpio.bsrr().write(|w| unsafe { w.bits(1 << (16 + N)) });
956-
}
958+
gpio.bsrr().write(|w| {
959+
if pull {
960+
w.bs(N).set_bit()
961+
} else {
962+
w.br(N).set_bit()
963+
}
964+
})
957965
}
958966

959-
let bits = (MODE::CNF << 2) | MODE::MODE;
960-
961-
self.cr_modify(cr, |r_bits| {
962-
(r_bits & !(0b1111 << Self::OFFSET)) | (bits << Self::OFFSET)
963-
});
967+
match N {
968+
0..=7 => {
969+
gpio.crl()
970+
.modify(|_, w| w.mode(N).variant(MODE::MODE).cnf(N).variant(MODE::CNF));
971+
}
972+
8..=15 => {
973+
gpio.crh().modify(|_, w| unsafe {
974+
w.mode(N - 16).bits(MODE::MODE as u8);
975+
w.cnf(N - 16).bits(MODE::CNF as u8)
976+
});
977+
}
978+
_ => unreachable!(),
979+
}
964980
}
965981

966982
#[inline]
@@ -1105,20 +1121,17 @@ gpio!(GPIOG, gpiog, PGx, 'G', [
11051121
PG15: (pg15, 15),
11061122
]);
11071123

1108-
struct Gpio<const P: char>;
1109-
impl<const P: char> Gpio<P> {
1110-
const fn ptr() -> *const crate::pac::gpioa::RegisterBlock {
1111-
match P {
1112-
'A' => crate::pac::GPIOA::ptr(),
1113-
'B' => crate::pac::GPIOB::ptr() as _,
1114-
'C' => crate::pac::GPIOC::ptr() as _,
1115-
'D' => crate::pac::GPIOD::ptr() as _,
1116-
'E' => crate::pac::GPIOE::ptr() as _,
1117-
#[cfg(any(feature = "xl", feature = "high"))]
1118-
'F' => crate::pac::GPIOF::ptr() as _,
1119-
#[cfg(any(feature = "xl", feature = "high"))]
1120-
'G' => crate::pac::GPIOG::ptr() as _,
1121-
_ => unreachable!(),
1122-
}
1124+
const fn gpiox<const P: char>() -> *const crate::pac::gpioa::RegisterBlock {
1125+
match P {
1126+
'A' => crate::pac::GPIOA::ptr(),
1127+
'B' => crate::pac::GPIOB::ptr() as _,
1128+
'C' => crate::pac::GPIOC::ptr() as _,
1129+
'D' => crate::pac::GPIOD::ptr() as _,
1130+
'E' => crate::pac::GPIOE::ptr() as _,
1131+
#[cfg(any(feature = "xl", feature = "high"))]
1132+
'F' => crate::pac::GPIOF::ptr() as _,
1133+
#[cfg(any(feature = "xl", feature = "high"))]
1134+
'G' => crate::pac::GPIOG::ptr() as _,
1135+
_ => unreachable!(),
11231136
}
11241137
}

src/gpio/erased.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::*;
22

3-
pub type EPin<MODE> = ErasedPin<MODE>;
3+
pub type AnyPin<MODE> = ErasedPin<MODE>;
44

55
macro_rules! impl_pxx {
66
($(($port_id:literal :: $pin:ident)),*) => {

0 commit comments

Comments
 (0)