Skip to content

Commit

Permalink
Merge pull request #3 from RusPiRo/feature/specialized_shared_irq_han…
Browse files Browse the repository at this point in the history
…dling

enable irq handler for shared interrupt lines like Aux
  • Loading branch information
2ndTaleStudio authored Aug 15, 2019
2 parents 4cc60d7 + 4c4660b commit 5a9701e
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 23 deletions.
81 changes: 75 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 10 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
[package]
name = "ruspiro-interrupt"
authors = ["André Borrmann <[email protected]>"]
version = "0.1.1" # remember to update html_root_url
authors = ["Andre Borrmann <[email protected]>"]
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]
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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(<irq-type-name>, <source>)]
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)
8 changes: 4 additions & 4 deletions macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[package]
name = "ruspiro-interrupt-macros"
authors = ["André Borrmann <[email protected]>"]
version = "0.1.0" # remember to update html_root_url
authors = ["Andre Borrmann <[email protected]>"]
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"]
Expand Down
46 changes: 42 additions & 4 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(<interrupt type>)]`` to be used when implementing an
//! This crate provides the custom attribute ``#[IrqHandler(<interrupt type>[, <source>])]`` to be used when implementing an
//! interrupt handler.
//!
//! # Usage
Expand All @@ -26,6 +26,16 @@
//! define_registers! ( TIMERIRQ: WriteOnly<u32> @ 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;
Expand Down Expand Up @@ -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, <SOURCE>)`. <SOURCE> 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, <SOURCE>)`. <SOURCE> 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();
Expand All @@ -77,6 +113,8 @@ pub fn IrqHandler(attr: TokenStream, item: TokenStream) -> TokenStream {
.to_compile_error()
.into()
}

irq_name.to_string()
},
};

Expand All @@ -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)]
Expand Down
38 changes: 38 additions & 0 deletions src/auxhandler.rs
Original file line number Diff line number Diff line change
@@ -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<u32> @ PERIPHERAL_BASE + 0x0021_5000 => [
SPI2 OFFSET(2),
SPI1 OFFSET(1),
UART1 OFFSET(0)
]
];
Loading

0 comments on commit 5a9701e

Please sign in to comment.