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,38 @@ 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+ 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 ) ;
40116 fn clear_interrupt_pending_bit ( & mut self , edge : Edge ) ;
41117 fn check_interrupt ( & self , edge : Edge ) -> bool ;
42118}
43119
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 >
45122where
46- PIN : PinExt ,
47- PIN :: Mode : marker:: Interruptable ,
123+ M : marker:: Interruptable ,
48124{
49125 /// Make corresponding EXTI line sensitive to this pin
50126 #[ 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 > {
52132 let i = self . pin_id ( ) ;
53133 let port = self . port_id ( ) as u32 ;
54134 let offset = 8 * ( i % 4 ) ;
@@ -75,12 +155,16 @@ where
75155 }
76156 _ => unreachable ! ( ) ,
77157 }
158+
159+ Pin { _mode : PhantomData }
78160 }
161+ }
79162
163+ impl < const P : char , const N : u8 , M > ExtiedPin < N > for gpio:: Pin < P , N , M , true > {
80164 /// Generate interrupt on rising edge, falling edge or both
81165 #[ 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 ;
84168 match edge {
85169 Edge :: Rising => {
86170 exti. rtsr1 ( )
@@ -105,30 +189,30 @@ where
105189
106190 /// Enable external interrupts from this pin.
107191 #[ inline( always) ]
108- fn enable_event ( & mut self , exti : & mut EXTI ) {
192+ fn enable_event ( & mut self , exti : & mut Exti ) {
109193 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 ) ) } ) ;
111195 }
112196
113197 /// Disable external interrupts from this pin
114198 #[ inline( always) ]
115- fn disable_event ( & mut self , exti : & mut EXTI ) {
199+ fn disable_event ( & mut self , exti : & mut Exti ) {
116200 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 ) ) } ) ;
118202 }
119203
120204 /// Enable external interrupts from this pin.
121205 #[ inline( always) ]
122- fn enable_interrupt ( & mut self , exti : & mut EXTI ) {
206+ fn enable_interrupt ( & mut self , exti : & mut Exti ) {
123207 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 ) ) } ) ;
125209 }
126210
127211 /// Disable external interrupts from this pin
128212 #[ inline( always) ]
129- fn disable_interrupt ( & mut self , exti : & mut EXTI ) {
213+ fn disable_interrupt ( & mut self , exti : & mut Exti ) {
130214 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 ) ) } ) ;
132216 }
133217
134218 /// Clear the interrupt pending bit for this pin
@@ -137,7 +221,7 @@ where
137221 unsafe {
138222 let exti = & ( * EXTI :: ptr ( ) ) ;
139223
140- let mask = 1 << self . pin_id ( ) ;
224+ let mask = 1 << N ;
141225 match edge {
142226 Edge :: Rising => exti. rpr1 ( ) . write ( |w| w. bits ( mask) ) ,
143227 Edge :: Falling => exti. fpr1 ( ) . write ( |w| w. bits ( mask) ) ,
@@ -158,7 +242,7 @@ where
158242 _ => panic ! ( "Must choose a rising or falling edge" ) ,
159243 } ;
160244
161- bits & ( 1 << self . pin_id ( ) ) != 0
245+ bits & ( 1 << N ) != 0
162246 }
163247 }
164248}
0 commit comments