|
1 | 1 | //! # General Purpose I/Os
|
2 | 2 | //!
|
| 3 | +//! The GPIO pins are organised into groups of 16 pins callled 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 chagne 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 debugger has been turned off |
| 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 `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` 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 |
| -//! |
| 73 | +
|
16 | 74 |
|
17 | 75 | use core::marker::PhantomData;
|
18 | 76 |
|
@@ -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,
|
|
0 commit comments