diff --git a/examples/one-task.rs b/examples/one-task.rs
index 07def59ba7bbae917a72271ef8365069a2d8fa8a..c62fbbfed8a4936b4a21efc6b1fbeb19ffe24f0c 100644
--- a/examples/one-task.rs
+++ b/examples/one-task.rs
@@ -43,7 +43,7 @@ app! {
     }
 }
 
-fn init(p: init::Peripherals, r: init::Resources) {
+fn init(mut p: init::Peripherals, r: init::Resources) {
     // `init` can modify all the `resources` declared in `app!`
     r.ON;
 
diff --git a/macros/src/trans.rs b/macros/src/trans.rs
index b50c73df29149844057b7a8beeb0c8ec9b05ef98..42f7487d06bbba30709ff62e34fc4e951dfcb1f3 100644
--- a/macros/src/trans.rs
+++ b/macros/src/trans.rs
@@ -370,10 +370,10 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
                 });
             }
             Kind::Interrupt { enabled } => {
-                // Interrupt. These can be enabled / disabled through the NVIC
+                // Interrupt. These are enabled / disabled through the NVIC
                 if interrupts.is_empty() {
                     interrupts.push(quote! {
-                        let nvic = &*#device::NVIC::ptr();
+                        let mut nvic: #device::NVIC = core::mem::transmute(());
                     });
                 }
 
diff --git a/src/examples/_0_zero_tasks.rs b/src/examples/_0_zero_tasks.rs
index 7ea085979a6d228db7e06e0df217e6baa70fd9c5..90f16d485f673a7cb606eeb20c59929dc70c00be 100644
--- a/src/examples/_0_zero_tasks.rs
+++ b/src/examples/_0_zero_tasks.rs
@@ -2,6 +2,7 @@
 //!
 //! ```
 //! #![deny(unsafe_code)]
+//! #![deny(warnings)]
 //! // IMPORTANT always include this feature gate
 //! #![feature(proc_macro)]
 //! #![no_std]
@@ -27,8 +28,9 @@
 //! // this function.
 //! fn init(p: init::Peripherals) {
 //!     // This function has access to all the peripherals of the device
-//!     p.GPIOA;
-//!     p.RCC;
+//!     p.core.SYST;
+//!     p.device.GPIOA;
+//!     p.device.RCC;
 //!     // ..
 //! }
 //! 
diff --git a/src/examples/_1_one_task.rs b/src/examples/_1_one_task.rs
index 614db2aa8d3bbdf6a86976a0418eb9a455d6b863..c9004e86ac19b2f08317a2d7df8a05ce53e03d30 100644
--- a/src/examples/_1_one_task.rs
+++ b/src/examples/_1_one_task.rs
@@ -2,6 +2,7 @@
 //!
 //! ```
 //! #![deny(unsafe_code)]
+//! #![deny(warnings)]
 //! #![feature(proc_macro)]
 //! #![no_std]
 //! 
@@ -9,8 +10,9 @@
 //! extern crate cortex_m_rtfm as rtfm;
 //! extern crate stm32f103xx;
 //! 
-//! use cortex_m::peripheral::SystClkSource;
+//! use cortex_m::peripheral::syst::SystClkSource;
 //! use rtfm::{app, Threshold};
+//! use stm32f103xx::GPIOC;
 //! 
 //! app! {
 //!     device: stm32f103xx,
@@ -37,31 +39,31 @@
 //! 
 //!             // These are the resources this task has access to.
 //!             //
-//!             // A resource can be a peripheral like `GPIOC` or a static variable
-//!             // like `ON`
-//!             resources: [GPIOC, ON],
+//!             // The resources listed here must also appear in `app.resources`
+//!             resources: [ON],
 //!         },
 //!     }
 //! }
 //! 
-//! fn init(p: init::Peripherals, r: init::Resources) {
+//! fn init(mut p: init::Peripherals, r: init::Resources) {
 //!     // `init` can modify all the `resources` declared in `app!`
 //!     r.ON;
 //! 
 //!     // power on GPIOC
-//!     p.RCC.apb2enr.modify(|_, w| w.iopcen().enabled());
+//!     p.device.RCC.apb2enr.modify(|_, w| w.iopcen().enabled());
 //! 
 //!     // configure PC13 as output
-//!     p.GPIOC.bsrr.write(|w| w.bs13().set());
-//!     p.GPIOC
+//!     p.device.GPIOC.bsrr.write(|w| w.bs13().set());
+//!     p.device
+//!         .GPIOC
 //!         .crh
 //!         .modify(|_, w| w.mode13().output().cnf13().push());
 //! 
 //!     // configure the system timer to generate one interrupt every second
-//!     p.SYST.set_clock_source(SystClkSource::Core);
-//!     p.SYST.set_reload(8_000_000); // 1s
-//!     p.SYST.enable_interrupt();
-//!     p.SYST.enable_counter();
+//!     p.core.SYST.set_clock_source(SystClkSource::Core);
+//!     p.core.SYST.set_reload(8_000_000); // 1s
+//!     p.core.SYST.enable_interrupt();
+//!     p.core.SYST.enable_counter();
 //! }
 //! 
 //! fn idle() -> ! {
@@ -76,16 +78,23 @@
 //! //
 //! // `r` is the set of resources this task has access to. `SYS_TICK::Resources`
 //! // has one field per resource declared in `app!`.
-//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
+//! #[allow(unsafe_code)]
+//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
 //!     // toggle state
-//!     **r.ON = !**r.ON;
+//!     *r.ON = !*r.ON;
 //! 
-//!     if **r.ON {
+//!     if *r.ON {
 //!         // set the pin PC13 high
-//!         r.GPIOC.bsrr.write(|w| w.bs13().set());
+//!         // NOTE(unsafe) atomic write to a stateless register
+//!         unsafe {
+//!             (*GPIOC::ptr()).bsrr.write(|w| w.bs13().set());
+//!         }
 //!     } else {
 //!         // set the pin PC13 low
-//!         r.GPIOC.bsrr.write(|w| w.br13().reset());
+//!         // NOTE(unsafe) atomic write to a stateless register
+//!         unsafe {
+//!             (*GPIOC::ptr()).bsrr.write(|w| w.br13().reset());
+//!         }
 //!     }
 //! }
 //! ```
diff --git a/src/examples/_2_two_tasks.rs b/src/examples/_2_two_tasks.rs
index 5db991b0e2f10e6a4c98d8042f6369b5e879c0f2..cf6b33d638f85d44d3f0329514af3c0fe3752275 100644
--- a/src/examples/_2_two_tasks.rs
+++ b/src/examples/_2_two_tasks.rs
@@ -2,6 +2,7 @@
 //!
 //! ```
 //! #![deny(unsafe_code)]
+//! #![deny(warnings)]
 //! #![feature(proc_macro)]
 //! #![no_std]
 //! 
@@ -43,18 +44,18 @@
 //! 
 //! // As both tasks are running at the same priority one can't preempt the other.
 //! // Thus both tasks have direct access to the resource
-//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
+//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
 //!     // ..
 //! 
-//!     **r.COUNTER += 1;
+//!     *r.COUNTER += 1;
 //! 
 //!     // ..
 //! }
 //! 
-//! fn tim2(_t: &mut Threshold, r: TIM2::Resources) {
+//! fn tim2(_t: &mut Threshold, mut r: TIM2::Resources) {
 //!     // ..
 //! 
-//!     **r.COUNTER += 1;
+//!     *r.COUNTER += 1;
 //! 
 //!     // ..
 //! }
diff --git a/src/examples/_3_preemption.rs b/src/examples/_3_preemption.rs
index 9dc8983b5a7d43afa17f0b4cf9a7dbd61c4e08b4..4360185afc7bea02f21bdb845aa4ff4539bafbbf 100644
--- a/src/examples/_3_preemption.rs
+++ b/src/examples/_3_preemption.rs
@@ -2,6 +2,7 @@
 //!
 //! ```
 //! #![deny(unsafe_code)]
+//! #![deny(warnings)]
 //! #![feature(proc_macro)]
 //! #![no_std]
 //! 
@@ -43,12 +44,12 @@
 //!     }
 //! }
 //! 
-//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
+//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
 //!     // ..
 //! 
 //!     // This task can't be preempted by `tim2` so it has direct access to the
 //!     // resource data
-//!     **r.COUNTER += 1;
+//!     *r.COUNTER += 1;
 //! 
 //!     // ..
 //! }
@@ -62,7 +63,7 @@
 //!     // lead to undefined behavior.
 //!     r.COUNTER.claim_mut(t, |counter, _t| {
 //!         // `claim_mut` creates a critical section
-//!         **counter += 1;
+//!         *counter += 1;
 //!     });
 //! 
 //!     // ..
diff --git a/src/examples/_4_nested.rs b/src/examples/_4_nested.rs
index 94af0bee6d2a95285d7308bcfb05ef28cebe01db..e211cf878cee86f594535521d0b2a4f941fd7f08 100644
--- a/src/examples/_4_nested.rs
+++ b/src/examples/_4_nested.rs
@@ -5,6 +5,7 @@
 //!
 //! ```
 //! #![deny(unsafe_code)]
+//! #![deny(warnings)]
 //! #![feature(proc_macro)]
 //! #![no_std]
 //! 
diff --git a/src/examples/_5_late_resources.rs b/src/examples/_5_late_resources.rs
index 8df6716cbac546cc8368012223b04b5ac70f9ea2..8958e85489b46ccc1846d1a0aa9cb805b09ca40a 100644
--- a/src/examples/_5_late_resources.rs
+++ b/src/examples/_5_late_resources.rs
@@ -1,8 +1,8 @@
 //! Demonstrates initialization of resources in `init`.
 //!
 //! ```
-//! 
 //! #![deny(unsafe_code)]
+//! #![deny(warnings)]
 //! #![feature(proc_macro)]
 //! #![no_std]
 //! 
diff --git a/src/examples/_6_generics.rs b/src/examples/_6_generics.rs
index 82ecdf99c7141702101074ae12908e751393e38c..22bb777af1362df4987a500539a05b50a7f734e5 100644
--- a/src/examples/_6_generics.rs
+++ b/src/examples/_6_generics.rs
@@ -2,6 +2,7 @@
 //!
 //! ```
 //! #![deny(unsafe_code)]
+//! #![deny(warnings)]
 //! #![feature(proc_macro)]
 //! #![no_std]
 //! 
@@ -14,6 +15,11 @@
 //! app! {
 //!     device: stm32f103xx,
 //! 
+//!     resources: {
+//!         static GPIOA: GPIOA;
+//!         static SPI1: SPI1;
+//!     },
+//! 
 //!     tasks: {
 //!         EXTI0: {
 //!             path: exti0,
@@ -29,7 +35,12 @@
 //!     },
 //! }
 //! 
-//! fn init(_p: init::Peripherals) {}
+//! fn init(p: init::Peripherals) -> init::LateResources {
+//!     init::LateResources {
+//!         GPIOA: p.device.GPIOA,
+//!         SPI1: p.device.SPI1,
+//!     }
+//! }
 //! 
 //! fn idle() -> ! {
 //!     loop {
@@ -61,7 +72,7 @@
 //! 
 //! // This task has direct access to the resources
 //! fn exti1(t: &mut Threshold, r: EXTI1::Resources) {
-//!     work(t, r.GPIOA, r.SPI1);
+//!     work(t, &r.GPIOA, &r.SPI1);
 //! }
 //! ```
 // Auto-generated. Do not modify.
diff --git a/src/examples/_7_full_syntax.rs b/src/examples/_7_full_syntax.rs
index 805206578d357303e96b9afe542656d928f177e4..f8db408753b6ac44852b2407c1f337c475406625 100644
--- a/src/examples/_7_full_syntax.rs
+++ b/src/examples/_7_full_syntax.rs
@@ -2,6 +2,7 @@
 //!
 //! ```
 //! #![deny(unsafe_code)]
+//! #![deny(warnings)]
 //! #![feature(proc_macro)]
 //! #![no_std]
 //! 
@@ -64,24 +65,24 @@
 //!             *r.OWNED != *r.OWNED;
 //! 
 //!             if *r.OWNED {
-//!                 if r.SHARED.claim(t, |shared, _| **shared) {
+//!                 if r.SHARED.claim(t, |shared, _| *shared) {
 //!                     rtfm::wfi();
 //!                 }
 //!             } else {
-//!                 r.SHARED.claim_mut(t, |shared, _| **shared = !**shared);
+//!                 r.SHARED.claim_mut(t, |shared, _| *shared = !*shared);
 //!             }
 //!         }
 //!     }
 //! }
 //! 
-//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
-//!     **r.ON = !**r.ON;
+//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
+//!     *r.ON = !*r.ON;
 //! 
-//!     **r.CO_OWNED += 1;
+//!     *r.CO_OWNED += 1;
 //! }
 //! 
-//! fn tim2(_t: &mut Threshold, r: TIM2::Resources) {
-//!     **r.CO_OWNED += 1;
+//! fn tim2(_t: &mut Threshold, mut r: TIM2::Resources) {
+//!     *r.CO_OWNED += 1;
 //! }
 //! ```
 // Auto-generated. Do not modify.
diff --git a/src/lib.rs b/src/lib.rs
index 986a7c9ad204cc189f4dcfc0b8add9dd76a91851..697dca65dbf29da900aa0036f8053517119b2ab5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -87,11 +87,12 @@ extern crate cortex_m_rtfm_macros;
 extern crate rtfm_core;
 extern crate untagged_option;
 
-use core::u8;
+use core::{mem, u8};
 
-pub use rtfm_core::{Resource, Threshold};
 pub use cortex_m::asm::{bkpt, wfi};
+pub use cortex_m::peripheral::NVIC;
 pub use cortex_m_rtfm_macros::app;
+pub use rtfm_core::{Resource, Threshold};
 #[doc(hidden)]
 pub use untagged_option::UntaggedOption;
 
@@ -165,6 +166,6 @@ where
     I: Nr,
 {
     // NOTE(safe) atomic write
-    let nvic = unsafe { &*cortex_m::peripheral::NVIC::ptr() };
+    let mut nvic: NVIC = unsafe { mem::transmute(()) };
     nvic.set_pending(interrupt);
 }