Skip to content

Commit 1044bec

Browse files
committed
PinMode on MODE
1 parent 9063533 commit 1044bec

File tree

2 files changed

+79
-143
lines changed

2 files changed

+79
-143
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
- `gpio`: port and pin generics first, then mode, `PinMode` for modes instead of pins
11+
1012
## [v0.9.0] - 2022-03-02
1113

1214
### Added

src/gpio.rs

Lines changed: 77 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ pub trait PinExt {
107107
/// Allow setting of the slew rate of an IO pin
108108
///
109109
/// Initially all pins are set to the maximum slew rate
110-
pub trait OutputSpeed<CR> {
111-
fn set_speed(&mut self, cr: &mut CR, speed: IOPinSpeed);
110+
pub trait OutputSpeed<const P: char, const H: bool> {
111+
fn set_speed(&mut self, cr: &mut Cr<P, H>, speed: IOPinSpeed);
112112
}
113113

114114
/// Extension trait to split a GPIO peripheral in independent pins and registers
@@ -181,8 +181,10 @@ mod sealed {
181181
pub trait Interruptable {}
182182

183183
pub trait PinMode {
184-
type CR;
185-
fn set_mode(cr: &mut Self::CR) -> Self;
184+
const CNF: u32;
185+
const MODE: u32;
186+
const PULL: Option<bool> = None;
187+
fn new() -> Self;
186188
}
187189
}
188190
use sealed::PinMode;
@@ -809,8 +811,7 @@ macro_rules! impl_temp_input {
809811

810812
impl<const P: char, const N: u8, const H: bool, MODE> Pin<P, N, H, MODE>
811813
where
812-
MODE: Active,
813-
Self: PinMode<CR = Cr<P, H>>,
814+
MODE: Active + PinMode,
814815
{
815816
impl_temp_output!(
816817
as_push_pull_output,
@@ -827,7 +828,7 @@ where
827828
impl_temp_input!(as_pull_down_input, Input<PullDown>);
828829
}
829830

830-
impl<const P: char, const N: u8, const H: bool, MODE> OutputSpeed<Cr<P, H>>
831+
impl<const P: char, const N: u8, const H: bool, MODE> OutputSpeed<P, H>
831832
for Pin<P, N, H, Output<MODE>>
832833
{
833834
fn set_speed(&mut self, _cr: &mut Cr<P, H>, speed: IOPinSpeed) {
@@ -844,7 +845,7 @@ impl<const P: char, const N: u8, const H: bool, MODE> OutputSpeed<Cr<P, H>>
844845
}
845846
}
846847

847-
impl<const P: char, const N: u8, const H: bool> OutputSpeed<Cr<P, H>>
848+
impl<const P: char, const N: u8, const H: bool> OutputSpeed<P, H>
848849
for Pin<P, N, H, Alternate<PushPull>>
849850
{
850851
fn set_speed(&mut self, _cr: &mut Cr<P, H>, speed: IOPinSpeed) {
@@ -896,167 +897,100 @@ impl<const P: char, const N: u8, const H: bool> Pin<P, N, H, Dynamic> {
896897
}
897898
}
898899

899-
macro_rules! mode {
900-
($gpio:ident, $bits:ident) => {
901-
if H {
902-
$gpio.crh.modify(|r, w| unsafe {
903-
w.bits((r.bits() & !(0b1111 << Self::OFFSET)) | ($bits << Self::OFFSET))
904-
});
905-
} else {
906-
$gpio.crl.modify(|r, w| unsafe {
907-
w.bits((r.bits() & !(0b1111 << Self::OFFSET)) | ($bits << Self::OFFSET))
908-
});
909-
}
910-
};
900+
impl PinMode for Input<Floating> {
901+
const CNF: u32 = 0b01;
902+
const MODE: u32 = 0b00;
903+
fn new() -> Self {
904+
Self::_new()
905+
}
911906
}
912907

913-
impl<const P: char, const N: u8, const H: bool> PinMode for Pin<P, N, H, Input<Floating>> {
914-
type CR = Cr<P, H>;
915-
916-
fn set_mode(_cr: &mut Self::CR) -> Self {
917-
// Floating input
918-
const CNF: u32 = 0b01;
919-
// Input mode
920-
const MODE: u32 = 0b00;
921-
const BITS: u32 = (CNF << 2) | MODE;
922-
923-
// input mode
924-
let gpio = unsafe { &(*Gpio::<P>::ptr()) };
925-
mode!(gpio, BITS);
926-
927-
Self::new(Input::_new())
908+
impl PinMode for Input<PullDown> {
909+
const CNF: u32 = 0b10;
910+
const MODE: u32 = 0b00;
911+
const PULL: Option<bool> = Some(false);
912+
fn new() -> Self {
913+
Self::_new()
928914
}
929915
}
930916

931-
impl<const P: char, const N: u8, const H: bool> PinMode for Pin<P, N, H, Input<PullDown>> {
932-
type CR = Cr<P, H>;
933-
934-
fn set_mode(_cr: &mut Self::CR) -> Self {
935-
// Pull up/down input
936-
const CNF: u32 = 0b10;
937-
// Input mode
938-
const MODE: u32 = 0b00;
939-
const BITS: u32 = (CNF << 2) | MODE;
940-
941-
let gpio = unsafe { &(*Gpio::<P>::ptr()) };
942-
//pull down:
943-
// NOTE(unsafe) atomic write to a stateless register
944-
gpio.bsrr.write(|w| unsafe { w.bits(1 << (16 + N)) });
945-
946-
// input mode
947-
mode!(gpio, BITS);
948-
949-
Self::new(Input::_new())
917+
impl PinMode for Input<PullUp> {
918+
const CNF: u32 = 0b10;
919+
const MODE: u32 = 0b00;
920+
const PULL: Option<bool> = Some(true);
921+
fn new() -> Self {
922+
Self::_new()
950923
}
951924
}
952925

953-
impl<const P: char, const N: u8, const H: bool> PinMode for Pin<P, N, H, Input<PullUp>> {
954-
type CR = Cr<P, H>;
955-
956-
fn set_mode(_cr: &mut Self::CR) -> Self {
957-
// Pull up/down input
958-
const CNF: u32 = 0b10;
959-
// Input mode
960-
const MODE: u32 = 0b00;
961-
const BITS: u32 = (CNF << 2) | MODE;
962-
963-
let gpio = unsafe { &(*Gpio::<P>::ptr()) };
964-
//pull up:
965-
// NOTE(unsafe) atomic write to a stateless register
966-
gpio.bsrr.write(|w| unsafe { w.bits(1 << N) });
967-
968-
// input mode
969-
mode!(gpio, BITS);
970-
971-
Self::new(Input::_new())
926+
impl PinMode for Output<OpenDrain> {
927+
const CNF: u32 = 0b01;
928+
const MODE: u32 = 0b11;
929+
fn new() -> Self {
930+
Self::_new()
972931
}
973932
}
974933

975-
impl<const P: char, const N: u8, const H: bool> PinMode for Pin<P, N, H, Output<OpenDrain>> {
976-
type CR = Cr<P, H>;
977-
978-
fn set_mode(_cr: &mut Self::CR) -> Self {
979-
// General purpose output open-drain
980-
const CNF: u32 = 0b01;
981-
// Open-Drain Output mode, max speed 50 MHz
982-
const MODE: u32 = 0b11;
983-
const BITS: u32 = (CNF << 2) | MODE;
984-
985-
let gpio = unsafe { &(*Gpio::<P>::ptr()) };
986-
mode!(gpio, BITS);
987-
988-
Self::new(Output::_new())
934+
impl PinMode for Output<PushPull> {
935+
const CNF: u32 = 0b00;
936+
const MODE: u32 = 0b11;
937+
fn new() -> Self {
938+
Self::_new()
989939
}
990940
}
991941

992-
impl<const P: char, const N: u8, const H: bool> PinMode for Pin<P, N, H, Output<PushPull>> {
993-
type CR = Cr<P, H>;
994-
995-
fn set_mode(_cr: &mut Self::CR) -> Self {
996-
// General purpose output push-pull
997-
const CNF: u32 = 0b00;
998-
// Output mode, max speed 50 MHz
999-
const MODE: u32 = 0b11;
1000-
const BITS: u32 = (CNF << 2) | MODE;
1001-
1002-
let gpio = unsafe { &(*Gpio::<P>::ptr()) };
1003-
mode!(gpio, BITS);
1004-
1005-
Self::new(Output::_new())
942+
impl PinMode for Analog {
943+
const CNF: u32 = 0b00;
944+
const MODE: u32 = 0b00;
945+
fn new() -> Self {
946+
Self {}
1006947
}
1007948
}
1008949

1009-
impl<const P: char, const N: u8, const H: bool> PinMode for Pin<P, N, H, Analog> {
1010-
type CR = Cr<P, H>;
1011-
1012-
fn set_mode(_cr: &mut Self::CR) -> Self {
1013-
// Analog input
1014-
const CNF: u32 = 0b00;
1015-
// Input mode
1016-
const MODE: u32 = 0b00;
1017-
const BITS: u32 = (CNF << 2) | MODE;
1018-
1019-
// analog mode
1020-
let gpio = unsafe { &(*Gpio::<P>::ptr()) };
1021-
mode!(gpio, BITS);
1022-
1023-
Self::new(Analog {})
950+
impl PinMode for Alternate<PushPull> {
951+
const CNF: u32 = 0b10;
952+
const MODE: u32 = 0b11;
953+
fn new() -> Self {
954+
Self::_new()
1024955
}
1025956
}
1026957

1027-
impl<const P: char, const N: u8, const H: bool> PinMode for Pin<P, N, H, Alternate<PushPull>> {
1028-
type CR = Cr<P, H>;
1029-
1030-
fn set_mode(_cr: &mut Self::CR) -> Self {
1031-
// Alternate function output push pull
1032-
const CNF: u32 = 0b10;
1033-
// Output mode, max speed 50 MHz
1034-
const MODE: u32 = 0b11;
1035-
const BITS: u32 = (CNF << 2) | MODE;
1036-
1037-
// input mode
1038-
let gpio = unsafe { &(*Gpio::<P>::ptr()) };
1039-
mode!(gpio, BITS);
1040-
1041-
Pin::new(Alternate::_new())
958+
impl PinMode for Alternate<OpenDrain> {
959+
const CNF: u32 = 0b11;
960+
const MODE: u32 = 0b11;
961+
fn new() -> Self {
962+
Self::_new()
1042963
}
1043964
}
1044965

1045-
impl<const P: char, const N: u8, const H: bool> PinMode for Pin<P, N, H, Alternate<OpenDrain>> {
1046-
type CR = Cr<P, H>;
1047-
1048-
fn set_mode(_cr: &mut Self::CR) -> Self {
1049-
// Alternate function output open drain
1050-
const CNF: u32 = 0b11;
1051-
// Output mode, max speed 50 MHz
1052-
const MODE: u32 = 0b11;
1053-
const BITS: u32 = (CNF << 2) | MODE;
1054-
966+
impl<const P: char, const N: u8, const H: bool, MODE> Pin<P, N, H, MODE>
967+
where
968+
MODE: PinMode,
969+
{
970+
fn set_mode(_cr: &mut Cr<P, H>) -> Self {
1055971
// input mode
1056972
let gpio = unsafe { &(*Gpio::<P>::ptr()) };
1057-
mode!(gpio, BITS);
973+
if let Some(pull) = MODE::PULL {
974+
if pull {
975+
gpio.bsrr.write(|w| unsafe { w.bits(1 << N) });
976+
} else {
977+
gpio.bsrr.write(|w| unsafe { w.bits(1 << (16 + N)) });
978+
}
979+
}
980+
981+
let bits = (MODE::CNF << 2) | MODE::MODE;
982+
983+
if H {
984+
gpio.crh.modify(|r, w| unsafe {
985+
w.bits((r.bits() & !(0b1111 << Self::OFFSET)) | (bits << Self::OFFSET))
986+
});
987+
} else {
988+
gpio.crl.modify(|r, w| unsafe {
989+
w.bits((r.bits() & !(0b1111 << Self::OFFSET)) | (bits << Self::OFFSET))
990+
});
991+
}
1058992

1059-
Pin::new(Alternate::_new())
993+
Pin::new(MODE::new())
1060994
}
1061995
}
1062996

0 commit comments

Comments
 (0)