diff --git a/Cargo.lock b/Cargo.lock index 6ff6d68..14a7cb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,35 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "paste" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "paste-impl" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro2" version = "0.4.30" @@ -8,6 +38,14 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro2" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "quote" version = "0.6.13" @@ -16,21 +54,30 @@ dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quote" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ruspiro-interrupt" -version = "0.1.1" +version = "0.2.0" dependencies = [ - "ruspiro-interrupt-macros 0.1.0", + "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ruspiro-interrupt-macros 0.2.0", "ruspiro-register 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "ruspiro-singleton 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ruspiro-interrupt-macros" -version = "0.1.0" +version = "0.2.0" dependencies = [ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.43 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -53,7 +100,7 @@ dependencies = [ [[package]] name = "syn" -version = "0.15.43" +version = "0.15.44" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", @@ -61,16 +108,38 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [metadata] +"checksum paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4a4a1c555c6505821f9d58b8779d0f630a6b7e4e1be24ba718610acf01fa79" +"checksum paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26e796e623b8b257215f27e6c80a5478856cae305f5b59810ff9acdaa34570e6" +"checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +"checksum proc-macro2 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "19f287c234c9b2d0308d692dee5c449c1a171167a6f8150f7cf2a49d8fd96967" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +"checksum quote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ab938ebe6f1c82426b5fb82eaf10c3e3028c53deaa3fbe38f5904b37cf4d767" "checksum ruspiro-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5655fe05fe4b90dc84698371cf0d7db487c6826933017ae199d908cb2a96e9bc" "checksum ruspiro-register 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b980f28994eba9f2f2a7e539acdc2daf7903cd38dd173c24153d4a2a69f23414" "checksum ruspiro-singleton 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03fbde4c1f1bc3a4cc88ad0e8f33e20ff7397a87a11b9856edea412e4bef863d" -"checksum syn 0.15.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ee06ea4b620ab59a2267c6b48be16244a3389f8bfa0986bdd15c35b890b00af3" +"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +"checksum syn 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "863ecbce06044c8380458360b4146d7372edadfedd77f120ba8c193da427b708" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" diff --git a/Cargo.toml b/Cargo.toml index 7bd92bc..51f71a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,24 +1,29 @@ [package] name = "ruspiro-interrupt" -authors = ["André Borrmann "] -version = "0.1.1" # remember to update html_root_url +authors = ["Andre Borrmann "] +version = "0.2.0" # remember to update html_root_url description = "Providing a simple and convinient way to implement interrupt handler for Raspberry Pi interrupts." license = "Apache-2.0" -repository = "https://github.com/RusPiRo/ruspiro-interrupt/tree/v0.1.1" -documentation = "https://docs.rs/ruspiro-interrupt/0.1.1" +repository = "https://github.com/RusPiRo/ruspiro-interrupt/tree/v0.2.0" +documentation = "https://docs.rs/ruspiro-interrupt/0.2.0" readme = "README.md" keywords = ["RusPiRo", "baremetal", "raspberrypi", "interrupt"] categories = ["no-std", "embedded"] edition = "2018" +[badges] +travis-ci = { repository = "RusPiRo/ruspiro-interrupt", branch = "master" } +maintenance = { status = "actively-developed" } + [workspace] members = ["macros"] [lib] [dependencies] +paste = "0.1.5" ruspiro-register = "0.1.1" -ruspiro-interrupt-macros = { path = "./macros", version = "0.1.0" } +ruspiro-interrupt-macros = { path = "./macros", version = "0.2.0" } ruspiro-singleton = "0.1.0" [features] diff --git a/README.md b/README.md index 9f6a119..2c566ee 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ script providing all the necessary linker symbols and entrypoints calling into t To use the crate just add the following dependency to your ``Cargo.toml`` file: ``` [dependencies] -ruspiro-interrupt = "0.1.1" +ruspiro-interrupt = "0.2.0" ``` Once done the access to the features/attribute of the interrupt crate is available in your rust files like so: @@ -30,5 +30,13 @@ unsafe fn my_handler() { } ``` +In rare cases the interrupt line is shared for different sources, in this case the attribute need to specify the source: +``` +#[IrqHandler(, )] +unsafe fn my_handler_for_source() { + +} +``` + ## License Licensed under Apache License, Version 2.0, ([LICENSE](LICENSE) or http://www.apache.org/licenses/LICENSE-2.0) \ No newline at end of file diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 911418a..33749e8 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "ruspiro-interrupt-macros" -authors = ["André Borrmann "] -version = "0.1.0" # remember to update html_root_url +authors = ["Andre Borrmann "] +version = "0.2.0" # remember to update html_root_url description = "Macros used to implement interrupt handler. !!This crate is only useful in conjunction with the `ruspiro-interrupt` crate and shall never be used standalone!!" license = "Apache-2.0" -repository = "https://github.com/RusPiRo/ruspiro-interrupt/tree/v0.1.0" -documentation = "https://docs.rs/ruspiro-interrupt/0.1.0" +repository = "https://github.com/RusPiRo/ruspiro-interrupt/tree/v0.2.0" +documentation = "https://docs.rs/ruspiro-interrupt/0.2.0" readme = "README.md" keywords = ["RusPiRo", "baremetal", "raspberrypi", "interrupt"] categories = ["no-std", "embedded"] diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 3275a95..13b3be6 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -4,11 +4,11 @@ * Author: André Borrmann * License: Apache License 2.0 **********************************************************************************************************************/ -#![doc(html_root_url = "https://docs.rs/ruspiro-interrupt-macros/0.1.0")] +#![doc(html_root_url = "https://docs.rs/ruspiro-interrupt-macros/0.2.0")] //! # Interrupt Macros //! -//! This crate provides the custom attribute ``#[IrqHandler()]`` to be used when implementing an +//! This crate provides the custom attribute ``#[IrqHandler([, ])]`` to be used when implementing an //! interrupt handler. //! //! # Usage @@ -26,6 +26,16 @@ //! define_registers! ( TIMERIRQ: WriteOnly @ 0x3F00_B40C => [] ); //! ``` //! +//! In some rare cases the interrupt line is shared between specific interrupt sources. In this case the source of +//! the interrupt need to be passed as well as an identifier. +//! ``` +//! #[IrqHandler(Aux, Uart1)] +//! unsafe fn my_aux_uart1_handler() { +//! // handle Uart1 interrupt here - this usually has no "acknowledge" register... +//! } +//! ``` +//! +//! extern crate proc_macro; extern crate syn; @@ -67,7 +77,33 @@ pub fn IrqHandler(attr: TokenStream, item: TokenStream) -> TokenStream { }; let irq_id_s = irq_name.to_string(); - match &*irq_id_s { + let irq_func_suffix = match &*irq_id_s { + "Aux" => { + // Aux IrqHandler tag signature is: IrqHandler(Aux,Uart1) + let aux_source = match args.get(1) { + Some(NestedMeta::Meta(Meta::Word(meta))) => meta, + _=> return syn::Error::new(syn::export::Span::call_site(), "`Aux` interrupt source missing in `#[IrqHandler(Aux, )`. could be one of: `Uart1` | `Spi1` | `Spi2`.") + .to_compile_error() + .into() + }; + let aux_source_s = aux_source.to_string(); + // check for valid Aux types + if &*aux_source_s != "Uart1" && &*aux_source_s != "Spi1" && &*aux_source_s != "Spi2" { + return syn::Error::new(syn::export::Span::call_site(), "Wrong source for `Aux` interrupt in `#[IrqHandler(Aux, )`. could be one of: `Uart1` | `Spi1` | `Spi2`.") + .to_compile_error() + .into() + } + let valid_signature = valid_common_signature + && func.decl.inputs.is_empty(); + + if !valid_signature { + return syn::Error::new(syn::export::Span::call_site(), "interrupt handler must have signature `[unsafe] fn()`") + .to_compile_error() + .into() + } + + format!("{}_{}", irq_name.to_string(), aux_source.to_string()) + }, _ => { let valid_signature = valid_common_signature && func.decl.inputs.is_empty(); @@ -77,6 +113,8 @@ pub fn IrqHandler(attr: TokenStream, item: TokenStream) -> TokenStream { .to_compile_error() .into() } + + irq_name.to_string() }, }; @@ -85,7 +123,7 @@ pub fn IrqHandler(attr: TokenStream, item: TokenStream) -> TokenStream { let block = func.block; // function block let stmts = block.stmts; // function statements - let irq_name_s = format!("__irq_handler__{}", irq_name.to_string()); + let irq_name_s = format!("__irq_handler__{}", irq_func_suffix); quote!( // use a fixed export name to ensure the same irq handler is not implemented twice #[allow(non_snake_case)] diff --git a/src/auxhandler.rs b/src/auxhandler.rs new file mode 100644 index 0000000..6d99140 --- /dev/null +++ b/src/auxhandler.rs @@ -0,0 +1,38 @@ +/*********************************************************************************************************************** + * Copyright (c) 2019 by the authors + * + * Author: André Borrmann + * License: Apache License 2.0 + **********************************************************************************************************************/ +//! # Aux interrupt line special handler +//! +//! The Aux interrupt line is shared between Uart1, Spi1 and Spi2. Therefore the +//! + +use ruspiro_register::define_registers; + +#[cfg(feature="ruspiro_pi3")] +const PERIPHERAL_BASE: u32 = 0x3F00_0000; + +pub(crate) fn aux_handler() { + // special Aux handling, as one IRQ line shares interrupts between Uart1, SPI1 and SPI2 + if AUX_IRQ::Register.read(AUX_IRQ::UART1) == 1 { + crate::__irq_handler__Aux_Uart1(); + } + + if AUX_IRQ::Register.read(AUX_IRQ::SPI1) == 1 { + crate::__irq_handler__Aux_Spi1(); + } + + if AUX_IRQ::Register.read(AUX_IRQ::SPI2) == 1 { + crate::__irq_handler__Aux_Spi2(); + } +} + +define_registers! [ + AUX_IRQ: ReadWrite @ PERIPHERAL_BASE + 0x0021_5000 => [ + SPI2 OFFSET(2), + SPI1 OFFSET(1), + UART1 OFFSET(0) + ] +]; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 30c138b..7dbc9f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ * Author: André Borrmann * License: Apache License 2.0 **********************************************************************************************************************/ -#![doc(html_root_url = "https://docs.rs/ruspiro-interrupt/0.1.1")] +#![doc(html_root_url = "https://docs.rs/ruspiro-interrupt/0.2.0")] #![no_std] #![feature(asm)] #![feature(linkage)] @@ -17,6 +17,7 @@ //! # Usage //! //! ``` +//! extern crate ruspiro_interrupt; // <- this kind of usage is VERY IMPORTANT to ensure linking works as expected! //! use ruspiro_interrupt::*; //! //! #[IrqHandler(ArmTimer)] @@ -41,13 +42,16 @@ //! extern crate alloc; +extern crate paste; pub use ruspiro_interrupt_macros::*; pub mod irqtypes; pub use irqtypes::*; use ruspiro_singleton::Singleton; + mod interface; +mod auxhandler; use alloc::vec::*; @@ -147,7 +151,7 @@ unsafe fn __interrupt_h(_core: u32) { 13 => __irq_handler__CoreSync1(), 14 => __irq_handler__CoreSync2(), 15 => __irq_handler__CoreSync3(), - 29 => __irq_handler__Aux(), + 29 => auxhandler::aux_handler(),//__irq_handler__Aux(), 30 => __irq_handler__Arm(), 31 => __irq_handler__GpuDma(), 49 => __irq_handler__GpioBank0(), @@ -156,7 +160,7 @@ unsafe fn __interrupt_h(_core: u32) { 52 => __irq_handler__GpioBank3(), 53 => __irq_handler__I2c(), 54 => __irq_handler__Spi(), - 55 =>__irq_handler__I2sPcm(), + 55 => __irq_handler__I2sPcm(), 56 => __irq_handler__Sdio(), 57 => __irq_handler__Pl011(), 64 => __irq_handler__ArmTimer(), @@ -188,6 +192,53 @@ fn set_bits_to_vec(value: u32, base: u8) -> Vec { v } +macro_rules! default_handler_impl { + ($($name:ident),*) => {$( + paste::item!{ + #[allow(non_snake_case)] + #[linkage="weak"] + #[no_mangle] + extern "C" fn [<__irq_handler__ $name>](){ + __irq_handler_Default(); + } + } + )*}; +} + +default_handler_impl![ + SystemTimer1, + SystemTimer3, + Isp, + Usb, + CoreSync0, + CoreSync1, + CoreSync2, + CoreSync3, + Aux_Uart1, + Aux_Spi1, + Aux_Spi2, + Arm, + GpuDma, + GpioBank0, + GpioBank1, + GpioBank2, + GpioBank3, + I2c, + Spi, + I2sPcm, + Sdio, + Pl011, + ArmTimer, + ArmMailbox, + ArmDoorbell0, + ArmDoorbell1, + ArmGpu0Halted, + ArmGpu1Halted, + ArmIllegalType1, + ArmIllegalType0, + ArmPending1, + ArmPending2 +]; #[allow(non_snake_case)] #[no_mangle] @@ -195,6 +246,7 @@ fn __irq_handler_Default() { } +/* #[allow(non_snake_case)] #[linkage="weak"] #[no_mangle] @@ -404,3 +456,4 @@ extern "C" fn __irq_handler__ArmPending1(){ extern "C" fn __irq_handler__ArmPending2(){ __irq_handler_Default(); } +*/ \ No newline at end of file