Skip to content

Commit 9794418

Browse files
committed
Document the gpio module and tweak visibility
1 parent fbf56b0 commit 9794418

File tree

3 files changed

+107
-6
lines changed

3 files changed

+107
-6
lines changed

src/gpio/mod.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Abstractions for GPIO ports.
2+
13
use core::marker::PhantomData;
24

35
pub use self::port::*;
@@ -6,32 +8,41 @@ pub use self::traits::*;
68
mod port;
79
mod traits;
810

9-
#[derive(Debug)]
10-
pub enum Error {
11-
PinAlreadyInUse(PinNumber),
12-
}
13-
11+
/// The different possible modes of a GPIO pin.
1412
#[derive(Debug, Clone, Copy)]
1513
pub enum Mode {
14+
/// Use the pin for receiving data.
1615
Input,
16+
/// Use the pin for sending data.
1717
Output,
18+
/// Activate an alternate function of the pin to make it usable to some connected device.
1819
Alternate,
20+
/// Use the pin in analog mode.
1921
Analog,
2022
}
2123

24+
/// Pull the pin value up or down.
2225
#[derive(Debug, Clone, Copy)]
2326
pub enum Resistor {
27+
/// Don't pull the value.
2428
NoPull,
29+
/// Pull the value to 1 if no data is sent/received.
2530
PullUp,
31+
/// Pull the value to 0 if no data is sent/received.
2632
PullDown,
2733
}
2834

35+
/// The output mode of the pin.
2936
#[derive(Debug, Clone, Copy)]
3037
pub enum OutputType {
38+
/// Use push-pull mode.
3139
PushPull,
40+
/// Use open drain mode.
3241
OpenDrain,
3342
}
3443

44+
/// The different output speeds.
45+
#[allow(missing_docs)]
3546
#[derive(Debug, Clone, Copy)]
3647
pub enum OutputSpeed {
3748
Low,
@@ -40,6 +51,10 @@ pub enum OutputSpeed {
4051
VeryHigh,
4152
}
4253

54+
/// The possible alternate functions.
55+
///
56+
/// The alternate function number that a device uses is specified in the manual.
57+
#[allow(missing_docs)]
4358
#[derive(Debug, Clone, Copy)]
4459
pub enum AlternateFunction {
4560
AF0,
@@ -60,6 +75,8 @@ pub enum AlternateFunction {
6075
AF15,
6176
}
6277

78+
/// The 16 possible pin numbers.
79+
#[allow(missing_docs)]
6380
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6481
#[repr(u8)]
6582
pub enum PinNumber {
@@ -81,10 +98,13 @@ pub enum PinNumber {
8198
Pin15,
8299
}
83100

101+
/// High level abstraction of a GPIO pin configured as input.
84102
pub trait InputPin: Sized {
103+
/// Get the current input value of the pin.
85104
fn get(&self) -> bool;
86105
}
87106

107+
/// An implementation of the `InputPin` trait for the IDR abstractions of this module.
88108
pub struct InputPinImpl<'a, IDR: IdrTrait + 'a> {
89109
pin: PinNumber,
90110
input_data: ReadOnlyIdr<'a, IDR>,
@@ -111,17 +131,22 @@ impl<'a, IDR: IdrTrait> ReadOnlyIdr<'a, IDR> {
111131
unsafe impl<'a, IDR: IdrTrait> Sync for ReadOnlyIdr<'a, IDR> {}
112132
unsafe impl<'a, IDR: IdrTrait> Send for ReadOnlyIdr<'a, IDR> {}
113133

134+
/// High level abstraction of a GPIO pin configured as output.
114135
pub trait OutputPin: Sized {
136+
/// Get the current output value of the pin.
115137
fn get(&self) -> bool;
116138

139+
/// Set the output value of the pin.
117140
fn set(&mut self, value: bool);
118141

142+
/// Toggle the output value of the pin.
119143
fn toggle(&mut self) {
120144
let current = self.get();
121145
self.set(!current);
122146
}
123147
}
124148

149+
/// An implementation of the `OutputPin` trait for the ODR and BSRR abstractions of this module.
125150
pub struct OutputPinImpl<'a, ODR: OdrTrait + 'a, BSRR: BsrrTrait + 'a> {
126151
pin: PinNumber,
127152
output_data: ReadOnlyOdr<'a, ODR>,
@@ -143,7 +168,7 @@ where
143168
}
144169
}
145170

146-
pub struct ReadOnlyOdr<'a, ODR: OdrTrait>(&'a ODR);
171+
struct ReadOnlyOdr<'a, ODR: OdrTrait>(&'a ODR);
147172

148173
impl<'a, ODR: OdrTrait> ReadOnlyOdr<'a, ODR> {
149174
fn read(&self) -> ODR::R {

src/gpio/port.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,24 @@ use super::*;
22
use core::marker::PhantomData;
33
use stm32f7::stm32f7x6::{gpioa, gpiob, gpiod};
44

5+
/// Abstraction for a GPIO port that allows safe configuration of the port's pins.
56
pub struct GpioPort<T> {
67
pub(super) pin_in_use: [bool; 16],
78
register_block: T,
89
}
910

11+
/// Errors that can occur during pin initialization.
12+
#[derive(Debug)]
13+
pub enum Error {
14+
/// The specified GPIO pin is already in use.
15+
PinAlreadyInUse(PinNumber),
16+
}
17+
18+
/// A generic struct representing a hardware GPIO register block.
19+
///
20+
/// This struct is needed because the GPIO A, GPIO B, and the other GPIO ports have slight
21+
/// differences in their reset values so that the SVD file and svd2rust use different types
22+
/// for them.
1023
pub struct RegisterBlock<'a, I: 'a, O: 'a, M: 'a, P: 'a, B: 'a, T: 'a, S: 'a, AH: 'a, AL: 'a> {
1124
idr: &'a I,
1225
odr: &'a O,
@@ -19,6 +32,7 @@ pub struct RegisterBlock<'a, I: 'a, O: 'a, M: 'a, P: 'a, B: 'a, T: 'a, S: 'a, AH
1932
afrl: &'a AL,
2033
}
2134

35+
/// An instantiation of the generic `RegisterBlock` for GPIO port A.
2236
pub type RegisterBlockA<'a> = RegisterBlock<
2337
'a,
2438
gpioa::IDR,
@@ -31,6 +45,8 @@ pub type RegisterBlockA<'a> = RegisterBlock<
3145
gpioa::AFRH,
3246
gpioa::AFRL,
3347
>;
48+
49+
/// An instantiation of the generic `RegisterBlock` for GPIO port B.
3450
pub type RegisterBlockB<'a> = RegisterBlock<
3551
'a,
3652
gpiob::IDR,
@@ -43,6 +59,8 @@ pub type RegisterBlockB<'a> = RegisterBlock<
4359
gpiob::AFRH,
4460
gpiob::AFRL,
4561
>;
62+
63+
/// An instantiation of the generic `RegisterBlock` for the remaining GPIO ports.
4664
pub type RegisterBlockD<'a> = RegisterBlock<
4765
'a,
4866
gpiod::IDR,
@@ -76,39 +94,64 @@ macro_rules! new_gpio_port {
7694
}
7795

7896
impl<'a> GpioPort<RegisterBlockA<'a>> {
97+
/// Create a new `RegisterBlockA` from the hardware register block.
7998
pub fn new_a(register_block: &'a gpioa::RegisterBlock) -> Self {
8099
new_gpio_port!(register_block)
81100
}
82101
}
83102

84103
impl<'a> GpioPort<RegisterBlockB<'a>> {
104+
/// Create a new `RegisterBlockB` from the hardware register block.
85105
pub fn new_b(register_block: &'a gpiob::RegisterBlock) -> Self {
86106
new_gpio_port!(register_block)
87107
}
88108
}
89109

90110
impl<'a> GpioPort<RegisterBlockD<'a>> {
111+
/// Create a new `RegisterBlockD` from the hardware register block.
91112
pub fn new(register_block: &'a gpiod::RegisterBlock) -> Self {
92113
new_gpio_port!(register_block)
93114
}
94115
}
95116

117+
/// This trait allows generic functions that work on all three register block types.
96118
pub trait RegisterBlockTrait<'a> {
119+
/// The IDR (input data register) type, returned by the `idr` function.
97120
type Idr: IdrTrait + 'a;
121+
122+
/// The ODR (output data register) type, returned by the `odr` function.
98123
type Odr: OdrTrait + 'a;
124+
125+
/// The BSRR (bit set and reset register) type, returned by the `bsrr` function.
99126
type Bsrr: BsrrTrait + 'a;
100127

128+
/// Returns a reference to the input data register.
101129
fn idr(&self) -> &'a Self::Idr;
130+
131+
/// Returns a reference to the output data register.
102132
fn odr(&self) -> &'a Self::Odr;
133+
134+
/// Returns a reference to the bit set and reset register.
103135
fn bsrr(&self) -> &'a Self::Bsrr;
136+
137+
/// Set the mode register for the specified pins to the given `Mode`.
104138
fn set_mode(&mut self, pins: &[PinNumber], mode: Mode);
139+
140+
/// Set the resistor register for the specified pins to the given `Resistor`.
105141
fn set_resistor(&mut self, pins: &[PinNumber], resistor: Resistor);
142+
143+
/// Set the output type register for the specified pins to the given `OutputType`.
106144
fn set_out_type(&mut self, pins: &[PinNumber], out_type: OutputType);
145+
146+
/// Set the output speed register for the specified pins to the given `OutputSpeed`.
107147
fn set_out_speed(&mut self, pins: &[PinNumber], out_speed: OutputSpeed);
148+
149+
/// Set the alternate function register for the specified pins to the given `AlternateFunction`.
108150
fn set_alternate_fn(&mut self, pins: &[PinNumber], alternate_fn: AlternateFunction);
109151
}
110152

111153
impl<'a, T: RegisterBlockTrait<'a>> GpioPort<T> {
154+
/// Initialize the specified pin as an input pin.
112155
pub fn to_input(
113156
&mut self,
114157
pin: PinNumber,
@@ -125,6 +168,7 @@ impl<'a, T: RegisterBlockTrait<'a>> GpioPort<T> {
125168
})
126169
}
127170

171+
/// Initialize the specified pin as an output pin.
128172
pub fn to_output(
129173
&mut self,
130174
pin: PinNumber,
@@ -150,6 +194,7 @@ impl<'a, T: RegisterBlockTrait<'a>> GpioPort<T> {
150194
Ok(output_pin)
151195
}
152196

197+
/// Initialize the specified pin as an alternate function pin.
153198
pub fn to_alternate_function(
154199
&mut self,
155200
pin: PinNumber,
@@ -161,6 +206,7 @@ impl<'a, T: RegisterBlockTrait<'a>> GpioPort<T> {
161206
self.to_alternate_function_all(&[pin], alternate_fn, typ, speed, resistor)
162207
}
163208

209+
/// Initialize the specified pins as alternate function pins.
164210
pub fn to_alternate_function_all(
165211
&mut self,
166212
pins: &[PinNumber],

src/gpio/traits.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,67 @@
11
use super::PinNumber;
22
use stm32f7::stm32f7x6::{gpioa, gpiob, gpiod};
33

4+
/// Abstracts over the three different types of input data registers (IDRs).
5+
///
6+
/// The GPIO ports A and B have separate IDR types because they use slightly different
7+
/// reset values. This trait allows to create generic functions that work with all three
8+
/// IDR types.
49
pub trait IdrTrait {
10+
/// Represents an IDR value.
511
type R: IdrR;
612

13+
/// Read the current value from the IDR register.
714
fn read(&self) -> Self::R;
815
}
916

17+
/// Represents an IDR value that specifies the input value of all pins of the port.
1018
pub trait IdrR {
19+
/// Returns the input value of the specified pin.
1120
fn get(&self, pin: PinNumber) -> bool;
1221
}
1322

23+
/// Abstracts over the three different types of output data registers (ODRs).
24+
///
25+
/// The GPIO ports A and B have separate ODR types because they use slightly different
26+
/// reset values. This trait allows to create generic functions that work with all three
27+
/// ODR types.
1428
pub trait OdrTrait {
29+
/// Represents an ODR value.
1530
type R: OdrR;
1631

32+
/// Read the current value from the ODR register.
1733
fn read(&self) -> Self::R;
1834
}
1935

36+
/// Represents an ODR value that specifies the output value of all pins of the port.
2037
pub trait OdrR {
38+
/// Returns the output value of the specified pin.
2139
fn get(&self, pin: PinNumber) -> bool;
2240
}
2341

42+
/// Abstracts over the three different types of bit set and reset registers (BSRRs).
43+
///
44+
/// The GPIO ports A and B have separate BSRR types because they use slightly different
45+
/// reset values. This trait allows to create generic functions that work with all three
46+
/// BSRR types.
2447
pub trait BsrrTrait {
48+
/// A type that allows BSRR write operations.
2549
type W: BsrrW;
2650

51+
/// Perform write operations on the BSRR register.
2752
fn write<F>(&mut self, f: F)
2853
where
2954
F: FnOnce(&mut Self::W) -> &mut Self::W;
3055
}
3156

57+
/// Allows writing the BSRR register.
58+
///
59+
/// Bits that are neither `set` or `reset` keep their previous value.
3260
pub trait BsrrW {
61+
/// Set the output value of the specified pin to 1.
3362
fn set(&mut self, pin: PinNumber) -> &mut Self;
3463

64+
/// Set the output value of the specified pin to 0.
3565
fn reset(&mut self, pin: PinNumber) -> &mut Self;
3666
}
3767

0 commit comments

Comments
 (0)