11use std:: collections:: HashMap ;
2+ use std:: fmt:: Write ;
23
34use cast:: u64;
45use quote:: Tokens ;
@@ -10,7 +11,11 @@ use util::{self, ToSanitizedUpperCase};
1011use Target ;
1112
1213/// Generates code for `src/interrupt.rs`
13- pub fn render ( target : & Target , peripherals : & [ Peripheral ] ) -> Result < Vec < Tokens > > {
14+ pub fn render (
15+ target : & Target ,
16+ peripherals : & [ Peripheral ] ,
17+ device_x : & mut String ,
18+ ) -> Result < Vec < Tokens > > {
1419 let interrupts = peripherals
1520 . iter ( )
1621 . flat_map ( |p| p. interrupt . iter ( ) )
@@ -32,7 +37,7 @@ pub fn render(target: &Target, peripherals: &[Peripheral]) -> Result<Vec<Tokens>
3237 let mut mod_items = vec ! [ ] ;
3338 for interrupt in & interrupts {
3439 while pos < interrupt. value {
35- elements. push ( quote ! ( None ) ) ;
40+ elements. push ( quote ! ( Vector { _reserved : 0 } ) ) ;
3641 pos += 1 ;
3742 }
3843 pos += 1 ;
@@ -63,42 +68,87 @@ pub fn render(target: &Target, peripherals: &[Peripheral]) -> Result<Vec<Tokens>
6368 #value => Ok ( Interrupt :: #name_uc) ,
6469 } ) ;
6570
66- elements. push ( quote ! ( Some ( #name_uc) ) ) ;
71+ elements. push ( quote ! ( Vector { _handler : #name_uc } ) ) ;
6772 names. push ( name_uc) ;
6873 }
6974
70- let aliases = names
71- . iter ( )
72- . map ( |n| {
73- format ! (
74- "
75- .weak {0}
76- {0} = DH_TRAMPOLINE" ,
77- n
78- )
79- } )
80- . collect :: < Vec < _ > > ( )
81- . concat ( ) ;
82-
8375 let n = util:: unsuffixed ( u64 ( pos) ) ;
8476 match * target {
8577 Target :: CortexM => {
78+ for name in & names {
79+ writeln ! ( device_x, "PROVIDE({} = DefaultHandler);" , name) . unwrap ( ) ;
80+ }
81+
8682 root. push ( quote ! {
8783 #[ cfg( feature = "rt" ) ]
8884 extern "C" {
8985 #( fn #names( ) ; ) *
9086 }
9187
88+ #[ doc( hidden) ]
89+ pub union Vector {
90+ _handler: unsafe extern "C" fn ( ) ,
91+ _reserved: u32 ,
92+ }
93+
9294 #[ cfg( feature = "rt" ) ]
9395 #[ doc( hidden) ]
9496 #[ link_section = ".vector_table.interrupts" ]
9597 #[ no_mangle]
96- pub static __INTERRUPTS: [ Option < unsafe extern "C" fn ( ) > ; #n] = [
98+ pub static __INTERRUPTS: [ Vector ; #n] = [
9799 #( #elements, ) *
98100 ] ;
101+
102+ /// Macro to override a device specific interrupt handler
103+ #[ cfg( feature = "rt" ) ]
104+ #[ macro_export]
105+ macro_rules! interrupt {
106+ ( $Name : ident, $handler: path, state: $State : ty = $initial_state: expr) => {
107+ #[ allow( unsafe_code) ]
108+ #[ no_mangle]
109+ pub unsafe extern "C" fn $Name ( ) {
110+ static mut STATE : $State = $initial_state;
111+
112+ // check that this interrupt exists
113+ let _ = $crate :: Interrupt :: $Name ;
114+
115+ // validate the signature of the user provided handler
116+ let f: fn ( & mut $State ) = $handler;
117+
118+ f( & mut STATE )
119+ }
120+ } ;
121+
122+ ( $Name : ident, $handler: path) => {
123+ #[ allow( unsafe_code) ]
124+ #[ no_mangle]
125+ pub unsafe extern "C" fn $Name ( ) {
126+ // check that this interrupt exists
127+ let _ = $crate :: Interrupt :: $Name ;
128+
129+ // validate the signature of the user provided handler
130+ let f: fn ( ) = $handler;
131+
132+ f( )
133+ }
134+ } ;
135+ }
99136 } ) ;
100137 }
101138 Target :: Msp430 => {
139+ let aliases = names
140+ . iter ( )
141+ . map ( |n| {
142+ format ! (
143+ "
144+ .weak {0}
145+ {0} = DH_TRAMPOLINE" ,
146+ n
147+ )
148+ } )
149+ . collect :: < Vec < _ > > ( )
150+ . concat ( ) ;
151+
102152 mod_items. push ( quote ! {
103153 #[ cfg( feature = "rt" ) ]
104154 global_asm!( "
@@ -114,14 +164,20 @@ pub fn render(target: &Target, peripherals: &[Peripheral]) -> Result<Vec<Tokens>
114164 #( fn #names( ) ; ) *
115165 }
116166
167+ #[ doc( hidden) ]
168+ pub union Vector {
169+ _handler: unsafe extern "msp430-interrupt" fn ( ) ,
170+ _reserved: u32 ,
171+ }
172+
117173 #[ allow( private_no_mangle_statics) ]
118174 #[ cfg( feature = "rt" ) ]
119175 #[ doc( hidden) ]
120176 #[ link_section = ".vector_table.interrupts" ]
121177 #[ no_mangle]
122178 #[ used]
123179 pub static INTERRUPTS :
124- [ Option < unsafe extern "msp430-interrupt" fn ( ) > ; #n] = [
180+ [ Vector ; #n] = [
125181 #( #elements, ) *
126182 ] ;
127183 } ) ;
@@ -152,6 +208,8 @@ pub fn render(target: &Target, peripherals: &[Peripheral]) -> Result<Vec<Tokens>
152208 mod_items. push ( quote ! {
153209 use core:: convert:: TryFrom ;
154210
211+ #interrupt_enum
212+
155213 #[ derive( Debug , Copy , Clone ) ]
156214 pub struct TryFromInterruptError ( ( ) ) ;
157215
0 commit comments