1
+ use core:: { marker:: PhantomData , ops:: Deref } ;
2
+
1
3
use super :: { marker, Edge , Pin , PinExt } ;
2
- use crate :: pac:: { Interrupt , EXTI } ;
4
+ use crate :: {
5
+ gpio,
6
+ pac:: { Interrupt , EXTI } ,
7
+ } ;
8
+
9
+ pub trait ExtiExt {
10
+ fn split ( self ) -> ( Exti , ExtiChannels ) ;
11
+ }
12
+
13
+ impl ExtiExt for EXTI {
14
+ fn split ( self ) -> ( Exti , ExtiChannels ) {
15
+ (
16
+ Exti ( self ) ,
17
+ ExtiChannels {
18
+ ch0 : ExtiChannel ,
19
+ ch1 : ExtiChannel ,
20
+ ch2 : ExtiChannel ,
21
+ ch3 : ExtiChannel ,
22
+ ch4 : ExtiChannel ,
23
+ ch5 : ExtiChannel ,
24
+ ch6 : ExtiChannel ,
25
+ ch7 : ExtiChannel ,
26
+ ch8 : ExtiChannel ,
27
+ ch9 : ExtiChannel ,
28
+ ch10 : ExtiChannel ,
29
+ ch11 : ExtiChannel ,
30
+ ch12 : ExtiChannel ,
31
+ ch13 : ExtiChannel ,
32
+ ch14 : ExtiChannel ,
33
+ ch15 : ExtiChannel ,
34
+ } ,
35
+ )
36
+ }
37
+ }
38
+
39
+ pub struct Exti ( pub ( crate ) EXTI ) ;
40
+
41
+ impl Deref for Exti {
42
+ type Target = EXTI ;
43
+
44
+ fn deref ( & self ) -> & Self :: Target {
45
+ & self . 0
46
+ }
47
+ }
48
+
49
+ #[ non_exhaustive]
50
+ pub struct ExtiChannel < const N : u8 > ;
51
+
52
+ pub struct ExtiChannels {
53
+ pub ch0 : ExtiChannel < 0 > ,
54
+ pub ch1 : ExtiChannel < 1 > ,
55
+ pub ch2 : ExtiChannel < 2 > ,
56
+ pub ch3 : ExtiChannel < 3 > ,
57
+ pub ch4 : ExtiChannel < 4 > ,
58
+ pub ch5 : ExtiChannel < 5 > ,
59
+ pub ch6 : ExtiChannel < 6 > ,
60
+ pub ch7 : ExtiChannel < 7 > ,
61
+ pub ch8 : ExtiChannel < 8 > ,
62
+ pub ch9 : ExtiChannel < 9 > ,
63
+ pub ch10 : ExtiChannel < 10 > ,
64
+ pub ch11 : ExtiChannel < 11 > ,
65
+ pub ch12 : ExtiChannel < 12 > ,
66
+ pub ch13 : ExtiChannel < 13 > ,
67
+ pub ch14 : ExtiChannel < 14 > ,
68
+ pub ch15 : ExtiChannel < 15 > ,
69
+ }
3
70
4
71
impl < const P : char , const N : u8 , MODE > Pin < P , N , MODE > {
5
72
/// NVIC interrupt number of interrupt from this pin
@@ -30,25 +97,38 @@ impl<const P: char, const N: u8, MODE> Pin<P, N, MODE> {
30
97
}
31
98
32
99
/// External Interrupt Pin
33
- pub trait ExtiPin {
34
- fn make_interrupt_source ( & mut self , exti : & mut EXTI ) ;
35
- fn trigger_on_edge ( & mut self , exti : & mut EXTI , level : Edge ) ;
36
- fn enable_event ( & mut self , exti : & mut EXTI ) ;
37
- fn disable_event ( & mut self , exti : & mut EXTI ) ;
38
- fn enable_interrupt ( & mut self , exti : & mut EXTI ) ;
39
- fn disable_interrupt ( & mut self , exti : & mut EXTI ) ;
100
+ pub trait ExtiPin < const P : char , const N : u8 , M > {
101
+ fn make_interrupt_source (
102
+ self ,
103
+ _ch : ExtiChannel < N > ,
104
+ ch : & mut Exti ,
105
+ ) -> Pin < P , N , M , true > ;
106
+ }
107
+
108
+ // TODO: Find better name
109
+ /// Only available on pins where interrupts have been enabled by the user
110
+ pub trait ExtiedPin < const N : u8 > {
111
+ fn trigger_on_edge ( & mut self , exti : & mut Exti , level : Edge ) ;
112
+ fn enable_event ( & mut self , exti : & mut Exti ) ;
113
+ fn disable_event ( & mut self , exti : & mut Exti ) ;
114
+ fn enable_interrupt ( & mut self , exti : & mut Exti ) ;
115
+ fn disable_interrupt ( & mut self , exti : & mut Exti ) ;
40
116
fn clear_interrupt_pending_bit ( & mut self , edge : Edge ) ;
41
117
fn check_interrupt ( & self , edge : Edge ) -> bool ;
42
118
}
43
119
44
- impl < PIN > ExtiPin for PIN
120
+ impl < const P : char , const N : u8 , M > ExtiPin < P , N , M >
121
+ for gpio:: Pin < P , N , M , false >
45
122
where
46
- PIN : PinExt ,
47
- PIN :: Mode : marker:: Interruptable ,
123
+ M : marker:: Interruptable ,
48
124
{
49
125
/// Make corresponding EXTI line sensitive to this pin
50
126
#[ inline( always) ]
51
- fn make_interrupt_source ( & mut self , exti : & mut EXTI ) {
127
+ fn make_interrupt_source (
128
+ self ,
129
+ _ch : ExtiChannel < N > ,
130
+ exti : & mut Exti ,
131
+ ) -> Pin < P , N , M , true > {
52
132
let i = self . pin_id ( ) ;
53
133
let port = self . port_id ( ) as u32 ;
54
134
let offset = 8 * ( i % 4 ) ;
@@ -75,12 +155,16 @@ where
75
155
}
76
156
_ => unreachable ! ( ) ,
77
157
}
158
+
159
+ Pin { _mode : PhantomData }
78
160
}
161
+ }
79
162
163
+ impl < const P : char , const N : u8 , M > ExtiedPin < N > for gpio:: Pin < P , N , M , true > {
80
164
/// Generate interrupt on rising edge, falling edge or both
81
165
#[ inline( always) ]
82
- fn trigger_on_edge ( & mut self , exti : & mut EXTI , edge : Edge ) {
83
- let i = self . pin_id ( ) ;
166
+ fn trigger_on_edge ( & mut self , exti : & mut Exti , edge : Edge ) {
167
+ let i = N ;
84
168
match edge {
85
169
Edge :: Rising => {
86
170
exti. rtsr1 ( )
@@ -105,30 +189,30 @@ where
105
189
106
190
/// Enable external interrupts from this pin.
107
191
#[ inline( always) ]
108
- fn enable_event ( & mut self , exti : & mut EXTI ) {
192
+ fn enable_event ( & mut self , exti : & mut Exti ) {
109
193
exti. emr1 ( )
110
- . modify ( |r, w| unsafe { w. bits ( r. bits ( ) | ( 1 << self . pin_id ( ) ) ) } ) ;
194
+ . modify ( |r, w| unsafe { w. bits ( r. bits ( ) | ( 1 << N ) ) } ) ;
111
195
}
112
196
113
197
/// Disable external interrupts from this pin
114
198
#[ inline( always) ]
115
- fn disable_event ( & mut self , exti : & mut EXTI ) {
199
+ fn disable_event ( & mut self , exti : & mut Exti ) {
116
200
exti. emr1 ( )
117
- . modify ( |r, w| unsafe { w. bits ( r. bits ( ) & !( 1 << self . pin_id ( ) ) ) } ) ;
201
+ . modify ( |r, w| unsafe { w. bits ( r. bits ( ) & !( 1 << N ) ) } ) ;
118
202
}
119
203
120
204
/// Enable external interrupts from this pin.
121
205
#[ inline( always) ]
122
- fn enable_interrupt ( & mut self , exti : & mut EXTI ) {
206
+ fn enable_interrupt ( & mut self , exti : & mut Exti ) {
123
207
exti. imr1 ( )
124
- . modify ( |r, w| unsafe { w. bits ( r. bits ( ) | ( 1 << self . pin_id ( ) ) ) } ) ;
208
+ . modify ( |r, w| unsafe { w. bits ( r. bits ( ) | ( 1 << N ) ) } ) ;
125
209
}
126
210
127
211
/// Disable external interrupts from this pin
128
212
#[ inline( always) ]
129
- fn disable_interrupt ( & mut self , exti : & mut EXTI ) {
213
+ fn disable_interrupt ( & mut self , exti : & mut Exti ) {
130
214
exti. imr1 ( )
131
- . modify ( |r, w| unsafe { w. bits ( r. bits ( ) & !( 1 << self . pin_id ( ) ) ) } ) ;
215
+ . modify ( |r, w| unsafe { w. bits ( r. bits ( ) & !( 1 << N ) ) } ) ;
132
216
}
133
217
134
218
/// Clear the interrupt pending bit for this pin
@@ -137,7 +221,7 @@ where
137
221
unsafe {
138
222
let exti = & ( * EXTI :: ptr ( ) ) ;
139
223
140
- let mask = 1 << self . pin_id ( ) ;
224
+ let mask = 1 << N ;
141
225
match edge {
142
226
Edge :: Rising => exti. rpr1 ( ) . write ( |w| w. bits ( mask) ) ,
143
227
Edge :: Falling => exti. fpr1 ( ) . write ( |w| w. bits ( mask) ) ,
@@ -158,7 +242,7 @@ where
158
242
_ => panic ! ( "Must choose a rising or falling edge" ) ,
159
243
} ;
160
244
161
- bits & ( 1 << self . pin_id ( ) ) != 0
245
+ bits & ( 1 << N ) != 0
162
246
}
163
247
}
164
248
}
0 commit comments