@@ -2,11 +2,24 @@ use super::*;
2
2
use core:: marker:: PhantomData ;
3
3
use stm32f7:: stm32f7x6:: { gpioa, gpiob, gpiod} ;
4
4
5
+ /// Abstraction for a GPIO port that allows safe configuration of the port's pins.
5
6
pub struct GpioPort < T > {
6
7
pub ( super ) pin_in_use : [ bool ; 16 ] ,
7
8
register_block : T ,
8
9
}
9
10
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.
10
23
pub struct RegisterBlock < ' a , I : ' a , O : ' a , M : ' a , P : ' a , B : ' a , T : ' a , S : ' a , AH : ' a , AL : ' a > {
11
24
idr : & ' a I ,
12
25
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
19
32
afrl : & ' a AL ,
20
33
}
21
34
35
+ /// An instantiation of the generic `RegisterBlock` for GPIO port A.
22
36
pub type RegisterBlockA < ' a > = RegisterBlock <
23
37
' a ,
24
38
gpioa:: IDR ,
@@ -31,6 +45,8 @@ pub type RegisterBlockA<'a> = RegisterBlock<
31
45
gpioa:: AFRH ,
32
46
gpioa:: AFRL ,
33
47
> ;
48
+
49
+ /// An instantiation of the generic `RegisterBlock` for GPIO port B.
34
50
pub type RegisterBlockB < ' a > = RegisterBlock <
35
51
' a ,
36
52
gpiob:: IDR ,
@@ -43,6 +59,8 @@ pub type RegisterBlockB<'a> = RegisterBlock<
43
59
gpiob:: AFRH ,
44
60
gpiob:: AFRL ,
45
61
> ;
62
+
63
+ /// An instantiation of the generic `RegisterBlock` for the remaining GPIO ports.
46
64
pub type RegisterBlockD < ' a > = RegisterBlock <
47
65
' a ,
48
66
gpiod:: IDR ,
@@ -76,39 +94,64 @@ macro_rules! new_gpio_port {
76
94
}
77
95
78
96
impl < ' a > GpioPort < RegisterBlockA < ' a > > {
97
+ /// Create a new `RegisterBlockA` from the hardware register block.
79
98
pub fn new_a ( register_block : & ' a gpioa:: RegisterBlock ) -> Self {
80
99
new_gpio_port ! ( register_block)
81
100
}
82
101
}
83
102
84
103
impl < ' a > GpioPort < RegisterBlockB < ' a > > {
104
+ /// Create a new `RegisterBlockB` from the hardware register block.
85
105
pub fn new_b ( register_block : & ' a gpiob:: RegisterBlock ) -> Self {
86
106
new_gpio_port ! ( register_block)
87
107
}
88
108
}
89
109
90
110
impl < ' a > GpioPort < RegisterBlockD < ' a > > {
111
+ /// Create a new `RegisterBlockD` from the hardware register block.
91
112
pub fn new ( register_block : & ' a gpiod:: RegisterBlock ) -> Self {
92
113
new_gpio_port ! ( register_block)
93
114
}
94
115
}
95
116
117
+ /// This trait allows generic functions that work on all three register block types.
96
118
pub trait RegisterBlockTrait < ' a > {
119
+ /// The IDR (input data register) type, returned by the `idr` function.
97
120
type Idr : IdrTrait + ' a ;
121
+
122
+ /// The ODR (output data register) type, returned by the `odr` function.
98
123
type Odr : OdrTrait + ' a ;
124
+
125
+ /// The BSRR (bit set and reset register) type, returned by the `bsrr` function.
99
126
type Bsrr : BsrrTrait + ' a ;
100
127
128
+ /// Returns a reference to the input data register.
101
129
fn idr ( & self ) -> & ' a Self :: Idr ;
130
+
131
+ /// Returns a reference to the output data register.
102
132
fn odr ( & self ) -> & ' a Self :: Odr ;
133
+
134
+ /// Returns a reference to the bit set and reset register.
103
135
fn bsrr ( & self ) -> & ' a Self :: Bsrr ;
136
+
137
+ /// Set the mode register for the specified pins to the given `Mode`.
104
138
fn set_mode ( & mut self , pins : & [ PinNumber ] , mode : Mode ) ;
139
+
140
+ /// Set the resistor register for the specified pins to the given `Resistor`.
105
141
fn set_resistor ( & mut self , pins : & [ PinNumber ] , resistor : Resistor ) ;
142
+
143
+ /// Set the output type register for the specified pins to the given `OutputType`.
106
144
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`.
107
147
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`.
108
150
fn set_alternate_fn ( & mut self , pins : & [ PinNumber ] , alternate_fn : AlternateFunction ) ;
109
151
}
110
152
111
153
impl < ' a , T : RegisterBlockTrait < ' a > > GpioPort < T > {
154
+ /// Initialize the specified pin as an input pin.
112
155
pub fn to_input (
113
156
& mut self ,
114
157
pin : PinNumber ,
@@ -125,6 +168,7 @@ impl<'a, T: RegisterBlockTrait<'a>> GpioPort<T> {
125
168
} )
126
169
}
127
170
171
+ /// Initialize the specified pin as an output pin.
128
172
pub fn to_output (
129
173
& mut self ,
130
174
pin : PinNumber ,
@@ -150,6 +194,7 @@ impl<'a, T: RegisterBlockTrait<'a>> GpioPort<T> {
150
194
Ok ( output_pin)
151
195
}
152
196
197
+ /// Initialize the specified pin as an alternate function pin.
153
198
pub fn to_alternate_function (
154
199
& mut self ,
155
200
pin : PinNumber ,
@@ -161,6 +206,7 @@ impl<'a, T: RegisterBlockTrait<'a>> GpioPort<T> {
161
206
self . to_alternate_function_all ( & [ pin] , alternate_fn, typ, speed, resistor)
162
207
}
163
208
209
+ /// Initialize the specified pins as alternate function pins.
164
210
pub fn to_alternate_function_all (
165
211
& mut self ,
166
212
pins : & [ PinNumber ] ,
0 commit comments