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,40 @@ 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
+ marker:: Interruptable
102
+ {
103
+ fn make_interrupt_source (
104
+ self ,
105
+ _ch : ExtiChannel < N > ,
106
+ ch : & mut Exti ,
107
+ ) -> Pin < P , N , M , true > ;
108
+ }
109
+
110
+ // TODO: Find better name
111
+ /// Only available on pins where interrupts have been enabled by the user
112
+ pub trait ExtiedPin < const N : u8 > {
113
+ fn trigger_on_edge ( & mut self , exti : & mut Exti , level : Edge ) ;
114
+ fn enable_event ( & mut self , exti : & mut Exti ) ;
115
+ fn disable_event ( & mut self , exti : & mut Exti ) ;
116
+ fn enable_interrupt ( & mut self , exti : & mut Exti ) ;
117
+ fn disable_interrupt ( & mut self , exti : & mut Exti ) ;
40
118
fn clear_interrupt_pending_bit ( & mut self , edge : Edge ) ;
41
119
fn check_interrupt ( & self , edge : Edge ) -> bool ;
42
120
}
43
121
44
- impl < PIN > ExtiPin for PIN
122
+ impl < const P : char , const N : u8 , M > ExtiPin < P , N , M >
123
+ for gpio:: Pin < P , N , M , false >
45
124
where
46
- PIN : PinExt ,
47
- PIN :: Mode : marker:: Interruptable ,
125
+ Self : marker:: Interruptable ,
48
126
{
49
127
/// Make corresponding EXTI line sensitive to this pin
50
128
#[ inline( always) ]
51
- fn make_interrupt_source ( & mut self , exti : & mut EXTI ) {
129
+ fn make_interrupt_source (
130
+ self ,
131
+ _ch : ExtiChannel < N > ,
132
+ exti : & mut Exti ,
133
+ ) -> Pin < P , N , M , true > {
52
134
let i = self . pin_id ( ) ;
53
135
let port = self . port_id ( ) as u32 ;
54
136
let offset = 8 * ( i % 4 ) ;
@@ -75,12 +157,16 @@ where
75
157
}
76
158
_ => unreachable ! ( ) ,
77
159
}
160
+
161
+ Pin { _mode : PhantomData }
78
162
}
163
+ }
79
164
165
+ impl < const P : char , const N : u8 , M > ExtiedPin < N > for gpio:: Pin < P , N , M , true > {
80
166
/// Generate interrupt on rising edge, falling edge or both
81
167
#[ inline( always) ]
82
- fn trigger_on_edge ( & mut self , exti : & mut EXTI , edge : Edge ) {
83
- let i = self . pin_id ( ) ;
168
+ fn trigger_on_edge ( & mut self , exti : & mut Exti , edge : Edge ) {
169
+ let i = N ;
84
170
match edge {
85
171
Edge :: Rising => {
86
172
exti. rtsr1 ( )
@@ -105,30 +191,30 @@ where
105
191
106
192
/// Enable external interrupts from this pin.
107
193
#[ inline( always) ]
108
- fn enable_event ( & mut self , exti : & mut EXTI ) {
194
+ fn enable_event ( & mut self , exti : & mut Exti ) {
109
195
exti. emr1 ( )
110
- . modify ( |r, w| unsafe { w. bits ( r. bits ( ) | ( 1 << self . pin_id ( ) ) ) } ) ;
196
+ . modify ( |r, w| unsafe { w. bits ( r. bits ( ) | ( 1 << N ) ) } ) ;
111
197
}
112
198
113
199
/// Disable external interrupts from this pin
114
200
#[ inline( always) ]
115
- fn disable_event ( & mut self , exti : & mut EXTI ) {
201
+ fn disable_event ( & mut self , exti : & mut Exti ) {
116
202
exti. emr1 ( )
117
- . modify ( |r, w| unsafe { w. bits ( r. bits ( ) & !( 1 << self . pin_id ( ) ) ) } ) ;
203
+ . modify ( |r, w| unsafe { w. bits ( r. bits ( ) & !( 1 << N ) ) } ) ;
118
204
}
119
205
120
206
/// Enable external interrupts from this pin.
121
207
#[ inline( always) ]
122
- fn enable_interrupt ( & mut self , exti : & mut EXTI ) {
208
+ fn enable_interrupt ( & mut self , exti : & mut Exti ) {
123
209
exti. imr1 ( )
124
- . modify ( |r, w| unsafe { w. bits ( r. bits ( ) | ( 1 << self . pin_id ( ) ) ) } ) ;
210
+ . modify ( |r, w| unsafe { w. bits ( r. bits ( ) | ( 1 << N ) ) } ) ;
125
211
}
126
212
127
213
/// Disable external interrupts from this pin
128
214
#[ inline( always) ]
129
- fn disable_interrupt ( & mut self , exti : & mut EXTI ) {
215
+ fn disable_interrupt ( & mut self , exti : & mut Exti ) {
130
216
exti. imr1 ( )
131
- . modify ( |r, w| unsafe { w. bits ( r. bits ( ) & !( 1 << self . pin_id ( ) ) ) } ) ;
217
+ . modify ( |r, w| unsafe { w. bits ( r. bits ( ) & !( 1 << N ) ) } ) ;
132
218
}
133
219
134
220
/// Clear the interrupt pending bit for this pin
@@ -137,7 +223,7 @@ where
137
223
unsafe {
138
224
let exti = & ( * EXTI :: ptr ( ) ) ;
139
225
140
- let mask = 1 << self . pin_id ( ) ;
226
+ let mask = 1 << N ;
141
227
match edge {
142
228
Edge :: Rising => exti. rpr1 ( ) . write ( |w| w. bits ( mask) ) ,
143
229
Edge :: Falling => exti. fpr1 ( ) . write ( |w| w. bits ( mask) ) ,
@@ -158,7 +244,7 @@ where
158
244
_ => panic ! ( "Must choose a rising or falling edge" ) ,
159
245
} ;
160
246
161
- bits & ( 1 << self . pin_id ( ) ) != 0
247
+ bits & ( 1 << N ) != 0
162
248
}
163
249
}
164
250
}
0 commit comments