1+ use core:: { marker:: PhantomData , ops:: Deref } ;
2+
13use 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+ }
370
471impl < const P : char , const N : u8 , MODE > Pin < P , N , MODE > {
572 /// NVIC interrupt number of interrupt from this pin
@@ -30,25 +97,40 @@ impl<const P: char, const N: u8, MODE> Pin<P, N, MODE> {
3097}
3198
3299/// 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 ) ;
40118 fn clear_interrupt_pending_bit ( & mut self , edge : Edge ) ;
41119 fn check_interrupt ( & self , edge : Edge ) -> bool ;
42120}
43121
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 >
45124where
46- PIN : PinExt ,
47- PIN :: Mode : marker:: Interruptable ,
125+ Self : marker:: Interruptable ,
48126{
49127 /// Make corresponding EXTI line sensitive to this pin
50128 #[ 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 > {
52134 let i = self . pin_id ( ) ;
53135 let port = self . port_id ( ) as u32 ;
54136 let offset = 8 * ( i % 4 ) ;
@@ -75,12 +157,16 @@ where
75157 }
76158 _ => unreachable ! ( ) ,
77159 }
160+
161+ Pin { _mode : PhantomData }
78162 }
163+ }
79164
165+ impl < const P : char , const N : u8 , M > ExtiedPin < N > for gpio:: Pin < P , N , M , true > {
80166 /// Generate interrupt on rising edge, falling edge or both
81167 #[ 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 ;
84170 match edge {
85171 Edge :: Rising => {
86172 exti. rtsr1 ( )
@@ -105,30 +191,30 @@ where
105191
106192 /// Enable external interrupts from this pin.
107193 #[ inline( always) ]
108- fn enable_event ( & mut self , exti : & mut EXTI ) {
194+ fn enable_event ( & mut self , exti : & mut Exti ) {
109195 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 ) ) } ) ;
111197 }
112198
113199 /// Disable external interrupts from this pin
114200 #[ inline( always) ]
115- fn disable_event ( & mut self , exti : & mut EXTI ) {
201+ fn disable_event ( & mut self , exti : & mut Exti ) {
116202 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 ) ) } ) ;
118204 }
119205
120206 /// Enable external interrupts from this pin.
121207 #[ inline( always) ]
122- fn enable_interrupt ( & mut self , exti : & mut EXTI ) {
208+ fn enable_interrupt ( & mut self , exti : & mut Exti ) {
123209 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 ) ) } ) ;
125211 }
126212
127213 /// Disable external interrupts from this pin
128214 #[ inline( always) ]
129- fn disable_interrupt ( & mut self , exti : & mut EXTI ) {
215+ fn disable_interrupt ( & mut self , exti : & mut Exti ) {
130216 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 ) ) } ) ;
132218 }
133219
134220 /// Clear the interrupt pending bit for this pin
@@ -137,7 +223,7 @@ where
137223 unsafe {
138224 let exti = & ( * EXTI :: ptr ( ) ) ;
139225
140- let mask = 1 << self . pin_id ( ) ;
226+ let mask = 1 << N ;
141227 match edge {
142228 Edge :: Rising => exti. rpr1 ( ) . write ( |w| w. bits ( mask) ) ,
143229 Edge :: Falling => exti. fpr1 ( ) . write ( |w| w. bits ( mask) ) ,
@@ -158,7 +244,7 @@ where
158244 _ => panic ! ( "Must choose a rising or falling edge" ) ,
159245 } ;
160246
161- bits & ( 1 << self . pin_id ( ) ) != 0
247+ bits & ( 1 << N ) != 0
162248 }
163249 }
164250}
0 commit comments