1
1
//! # General Purpose I/Os
2
2
//!
3
+ //! The GPIO pins are organised into groups of 16 pins which can be accessed through the
4
+ //! `gpioa`, `gpiob`... modules. To get access to the pins, you first need to convert them into a
5
+ //! HAL designed struct from the `pac` struct using the `spilit` function.
6
+ //! ```rust
7
+ //! // Acquire the GPIOC peripheral
8
+ //! // NOTE: `dp` is the device peripherals from the `PAC` crate
9
+ //! let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
10
+ //! ```
11
+ //!
12
+ //! This gives you a struct containing two control registers `crl` and `crh`, and all the pins
13
+ //! `px0..px15`. These structs are what you use to interract with the pins to change their modes,
14
+ //! or their inputs or outputs. For example, to set `pa5` high, you would call
15
+ //!
16
+ //! ```rust
17
+ //! let output = gpioa.pa5.into_push_pull_output(&mut gpioa.crl);
18
+ //! output.set_high();
19
+ //! ```
20
+ //!
21
+ //! Each GPIO pin can be set to various modes:
22
+ //!
23
+ //! - **Alternate**: Pin mode required when the pin is driven by other peripherals
24
+ //! - **Dynamic**: Pin mode is selected at runtime. See changing configurations for more details
25
+ //! - Input
26
+ //! - **PullUp**: Input connected to high with a weak pull up resistor. Will be high when nothing
27
+ //! is connected
28
+ //! - **PullDown**: Input connected to high with a weak pull up resistor. Will be low when nothing
29
+ //! is connected
30
+ //! - **Floating**: Input not pulled to high or low. Will be undefined when nothing is connected
31
+ //! - Output
32
+ //! - **PushPull**: Output which either drives the pin high or low
33
+ //! - **OpenDrain**: Output which leaves the gate floating, or pulls it do ground in drain
34
+ //! mode. Can be used as an input in the `open` configuration
35
+ //! - **Debugger**: Some pins start out being used by the debugger. A pin in this mode can only be
36
+ //! used if the [JTAG peripheral has been turned off](#accessing-pa15-pb3-and-pb14).
37
+ //!
38
+ //! ## Changing modes
39
+ //! The simplest way to change the pin mode is to use the `into_<mode>` functions. These return a
40
+ //! new struct with the correct mode that you can use the input or output functions on.
41
+ //!
42
+ //! If you need a more temporary mode change, and can not use the `into_<mode>` functions for
43
+ //! ownership reasons, you can use the `as_<mode>` functions to temporarily change the pin type, do
44
+ //! some output or input, and then have it change back once done.
45
+ //!
46
+ //! ### Dynamic Mode Change
47
+ //! The above mode change methods guarantee that you can only call input functions when the pin is
48
+ //! in input mode, and output when in output modes, but can lead to some issues. Therefore, there
49
+ //! is also a mode where the state is kept track of at runtime, allowing you to change the mode
50
+ //! often, and without problems with ownership, or references, at the cost of some performance and
51
+ //! the risk of runtime errors.
52
+ //!
53
+ //! To make a pin dynamic, use the `into_dynamic` function, and then use the `make_<mode>` functions to
54
+ //! change the mode
55
+ //!
56
+ //! ## Accessing PA15, PB3, and PB14
57
+ //!
58
+ //! These pins are used by the JTAG peripheral by default. To use them in your program, you need to
59
+ //! disable that peripheral. This is done using the [afio::MAPR::disable_jtag](../afio/struct.MAPR.html#method.disable_jtag) function
60
+ //!
3
61
//! # Interfacing with v1 traits
4
62
//!
5
- //! `embedded-hal` has two versions of the digital traits, `v2` which is used
6
- //! by this crate and `v1` which is deprecated but still used by a lot of drivers.
7
- //! If you want to use such a driver with this crate, you need to convert the digital pins to the `v1` type.
63
+ //! `embedded-hal` has two versions of the digital traits, `v2` which is used by this crate and
64
+ //! `v1` which is deprecated but still used by a lot of drivers. If you want to use such a driver
65
+ //! with this crate, you need to convert the digital pins to the `v1` type.
8
66
//!
9
67
//! This is done using `embedded-hal::digital::v1_compat::OldOutputPin`. For example:
10
68
//!
11
69
//! ```rust
12
70
//! let nss = gpioa.pa4.into_push_pull_output(&mut gpioa.crl);
13
71
//! let mut mfrc522 = Mfrc522::new(spi, OldOutputPin::from(nss)).unwrap();
14
72
//! ```
15
- //!
16
73
17
74
use core:: marker:: PhantomData ;
18
75
@@ -96,6 +153,7 @@ pub trait ExtiPin {
96
153
fn check_interrupt ( & mut self ) -> bool ;
97
154
}
98
155
156
+ /// Tracks the current pin state for dynamic pins
99
157
pub enum Dynamic {
100
158
InputFloating ,
101
159
InputPullUp ,
@@ -104,6 +162,8 @@ pub enum Dynamic {
104
162
OutputOpenDrain ,
105
163
}
106
164
165
+ impl Active for Dynamic { }
166
+
107
167
#[ derive( Debug , PartialEq ) ]
108
168
pub enum PinModeError {
109
169
IncorrectMode ,
@@ -134,22 +194,22 @@ pub trait PinMode<CR> {
134
194
135
195
// These impls are needed because a macro can not brace initialise a ty token
136
196
impl < MODE > Input < MODE > {
137
- fn _new ( ) -> Self {
197
+ const fn _new ( ) -> Self {
138
198
Self { _mode : PhantomData }
139
199
}
140
200
}
141
201
impl < MODE > Output < MODE > {
142
- fn _new ( ) -> Self {
202
+ const fn _new ( ) -> Self {
143
203
Self { _mode : PhantomData }
144
204
}
145
205
}
146
206
impl < MODE > Alternate < MODE > {
147
- fn _new ( ) -> Self {
207
+ const fn _new ( ) -> Self {
148
208
Self { _mode : PhantomData }
149
209
}
150
210
}
151
211
impl Debugger {
152
- fn _new ( ) -> Self {
212
+ const fn _new ( ) -> Self {
153
213
Self { }
154
214
}
155
215
}
@@ -516,7 +576,6 @@ macro_rules! gpio {
516
576
}
517
577
}
518
578
519
-
520
579
/// Configures the pin to operate as an analog input pin
521
580
pub fn into_analog( self , cr: & mut $CR) -> $PXi<Analog > {
522
581
unsafe {
@@ -533,6 +592,8 @@ macro_rules! gpio {
533
592
}
534
593
}
535
594
595
+ // These macros are defined here instead of at the top level in order
596
+ // to be able to refer to macro variables from the outer layers.
536
597
macro_rules! impl_temp_output {
537
598
(
538
599
$fn_name: ident,
@@ -626,7 +687,6 @@ macro_rules! gpio {
626
687
) ;
627
688
}
628
689
629
-
630
690
impl <MODE > $PXi<MODE > where MODE : Active {
631
691
/// Erases the pin number from the type
632
692
fn into_generic( self ) -> Generic <MODE > {
0 commit comments