11//! General purpose input-output pins
22
33use crate :: { adc, pac} ;
4- use core:: ptr:: { read_volatile, write_volatile} ;
54use cortex_m:: interrupt:: CriticalSection ;
65
76pub use embedded_hal:: digital:: v2:: PinState ;
@@ -55,7 +54,6 @@ pub enum Speed {
5554#[ repr( u8 ) ]
5655#[ derive( Debug , PartialEq , Eq , Clone , Copy ) ]
5756#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
58-
5957pub enum Pull {
6058 /// No pull-up, no pull-down.
6159 None = 0b00 ,
@@ -65,6 +63,10 @@ pub enum Pull {
6563 Down = 0b10 ,
6664}
6765
66+ const GPIOA_BASE : usize = 0x4800_0000 ;
67+ const GPIOB_BASE : usize = 0x4800_0400 ;
68+ const GPIOC_BASE : usize = 0x4800_0800 ;
69+
6870#[ derive( Debug ) ]
6971#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
7072struct Pin < const BASE : usize , const N : u8 > { }
@@ -73,6 +75,10 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
7375 const _NPANIC: ( ) = if N > 15 {
7476 core:: panic!( "Pin index is out of range" )
7577 } ;
78+ const _BASEPANIC: ( ) = match BASE {
79+ GPIOA_BASE | GPIOB_BASE | GPIOC_BASE => ( ) ,
80+ _ => core:: panic!( "Base address is invalid" ) ,
81+ } ;
7682
7783 const MODER_R : * const u32 = BASE as * const u32 ;
7884 const MODER_W : * mut u32 = BASE as * mut u32 ;
@@ -97,41 +103,41 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
97103
98104 #[ inline( always) ]
99105 pub ( crate ) fn set_mode ( & mut self , _cs : & CriticalSection , mode : sealed:: Mode ) {
100- let mut val: u32 = unsafe { read_volatile ( Self :: MODER_R ) } ;
106+ let mut val: u32 = unsafe { Self :: MODER_R . read_volatile ( ) } ;
101107 val &= !( 0b11 << ( N * 2 ) ) ;
102108 val |= ( mode as u8 as u32 ) << ( N * 2 ) ;
103- unsafe { write_volatile ( Self :: MODER_W , val) } ;
109+ unsafe { Self :: MODER_W . write_volatile ( val) } ;
104110 }
105111
106112 #[ inline( always) ]
107113 pub ( crate ) fn set_output_type ( & mut self , _cs : & CriticalSection , ot : OutputType ) {
108- let mut val: u32 = unsafe { read_volatile ( Self :: OTYPER_R ) } ;
114+ let mut val: u32 = unsafe { Self :: OTYPER_R . read_volatile ( ) } ;
109115 match ot {
110116 OutputType :: PushPull => val &= !( 1 << N ) ,
111117 OutputType :: OpenDrain => val |= 1 << N ,
112118 }
113- unsafe { write_volatile ( Self :: OTYPER_W , val) } ;
119+ unsafe { Self :: OTYPER_W . write_volatile ( val) } ;
114120 }
115121
116122 #[ inline( always) ]
117123 pub ( crate ) fn set_speed ( & mut self , _cs : & CriticalSection , speed : Speed ) {
118- let mut val: u32 = unsafe { read_volatile ( Self :: OSPEEDR_R ) } ;
124+ let mut val: u32 = unsafe { Self :: OSPEEDR_R . read_volatile ( ) } ;
119125 val &= !( 0b11 << ( N * 2 ) ) ;
120126 val |= ( speed as u8 as u32 ) << ( N * 2 ) ;
121- unsafe { write_volatile ( Self :: OSPEEDR_W , val) } ;
127+ unsafe { Self :: OSPEEDR_W . write_volatile ( val) } ;
122128 }
123129
124130 #[ inline( always) ]
125131 pub ( crate ) fn set_pull ( & mut self , _cs : & CriticalSection , pull : Pull ) {
126- let mut val: u32 = unsafe { read_volatile ( Self :: PUPDR_R ) } ;
132+ let mut val: u32 = unsafe { Self :: PUPDR_R . read_volatile ( ) } ;
127133 val &= !( 0b11 << ( N * 2 ) ) ;
128134 val |= ( pull as u8 as u32 ) << ( N * 2 ) ;
129- unsafe { write_volatile ( Self :: PUPDR_W , val) } ;
135+ unsafe { Self :: PUPDR_W . write_volatile ( val) } ;
130136 }
131137
132138 #[ inline( always) ]
133139 pub ( crate ) fn input_level ( & self ) -> PinState {
134- if unsafe { read_volatile ( Self :: IDR ) } & ( 1 << N ) == 0 {
140+ if unsafe { Self :: IDR . read_volatile ( ) } & ( 1 << N ) == 0 {
135141 PinState :: Low
136142 } else {
137143 PinState :: High
@@ -140,7 +146,7 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
140146
141147 #[ inline( always) ]
142148 pub ( crate ) fn output_level ( & self ) -> PinState {
143- if unsafe { read_volatile ( Self :: ODR ) } & ( 1 << N ) == 0 {
149+ if unsafe { Self :: ODR . read_volatile ( ) } & ( 1 << N ) == 0 {
144150 PinState :: Low
145151 } else {
146152 PinState :: High
@@ -153,16 +159,16 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
153159 PinState :: Low => 1 << ( N + 16 ) ,
154160 PinState :: High => 1 << N ,
155161 } ;
156- unsafe { write_volatile ( Self :: BSRR , val) }
162+ unsafe { Self :: BSRR . write_volatile ( val) }
157163 }
158164
159165 #[ inline( always) ]
160166 pub ( crate ) fn set_alternate_function ( & mut self , cs : & CriticalSection , af : u8 ) {
161167 self . set_mode ( cs, sealed:: Mode :: Alternate ) ;
162- let mut val: u32 = unsafe { read_volatile ( Self :: AF_R ) } ;
168+ let mut val: u32 = unsafe { Self :: AF_R . read_volatile ( ) } ;
163169 val &= !( 0b1111 << Self :: AF_SHIFT ) ;
164170 val |= ( af as u8 as u32 ) << Self :: AF_SHIFT ;
165- unsafe { write_volatile ( Self :: AF_W , val) } ;
171+ unsafe { Self :: AF_W . write_volatile ( val) } ;
166172 }
167173}
168174
@@ -442,17 +448,10 @@ pub trait Exti {
442448
443449/// GPIO pins
444450pub mod pins {
445- // Switch to this when avaliable on stable
446- // https://github.com/rust-lang/rust/issues/51910
447- // const GPIOA_BASE: usize = pac::GPIOA::PTR as *const _ as usize;
448- // const GPIOB_BASE: usize = pac::GPIOB::PTR as *const _ as usize;
449- // const GPIOC_BASE: usize = pac::GPIOC::PTR as *const _ as usize;
450-
451- const GPIOA_BASE : usize = 0x4800_0000 ;
452- const GPIOB_BASE : usize = 0x4800_0400 ;
453- const GPIOC_BASE : usize = 0x4800_0800 ;
454-
455- use super :: { adc, pac, CriticalSection , OutputType , Pin , PinState , Pull , Speed } ;
451+ use super :: {
452+ adc, pac, CriticalSection , OutputType , Pin , PinState , Pull , Speed , GPIOA_BASE , GPIOB_BASE ,
453+ GPIOC_BASE ,
454+ } ;
456455
457456 macro_rules! gpio_struct {
458457 ( $name: ident, $base: expr, $n: expr, $doc: expr) => {
0 commit comments