diff --git a/.gdbinit_old b/.gdbinit_old
deleted file mode 100644
index 098ff6f90cac5691f155e0dfba1ce4e87be3f7f3..0000000000000000000000000000000000000000
--- a/.gdbinit_old
+++ /dev/null
@@ -1,18 +0,0 @@
-target remote :3333
-
-monitor arm semihosting enable
-
-# # send captured ITM to the file itm.fifo
-# # (the microcontroller SWO pin must be connected to the programmer SWO pin)
-# # 8000000 must match the core clock frequency
-# monitor tpiu config internal itm.fifo uart off 8000000
-
-# # OR: make the microcontroller SWO pin output compatible with UART (8N1)
-# # 2000000 is the frequency of the SWO pin
-# monitor tpiu config external uart off 8000000 2000000
-
-# # enable ITM port 0
-# monitor itm port 0 on
-
-load
-step
diff --git a/.settings/com.github.rustdt.ide.core.prefs b/.settings/com.github.rustdt.ide.core.prefs
deleted file mode 100644
index 53355d97c505b4b5b165835dea2e14621f73a377..0000000000000000000000000000000000000000
--- a/.settings/com.github.rustdt.ide.core.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-build_targets=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\n<build_targets xmlns\="com.github.rustdt.ide.core">\n<target auto_enabled\="false" config\="build" n_enabled\="true" version2\="true">\n<command_invocation append_env\="true" command_arguments\="xargo build --release --message-format\=json">\n<env_vars/>\n</command_invocation>\n</target>\n<target auto_enabled\="true" config\="check" n_enabled\="false" version2\="true">\n<command_invocation append_env\="true" command_arguments\="xargo build --message-format\=json">\n<env_vars/>\n</command_invocation>\n</target>\n<target auto_enabled\="false" config\="clean" n_enabled\="false" version2\="true"/>\n</build_targets>\n
-eclipse.preferences.version=1
diff --git a/.vscode/launch.json b/.vscode/launch.json
index efdb5fba0f9622a0060235bc1f5cbe9ca0525eaa..4d3db06af30967169546cbc8aacc1d56347bac14 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -9,13 +9,13 @@
             "request": "attach",
             "name": "Release",
             "gdbpath": "/usr/bin/arm-none-eabi-gdb",
-            //"executable": "./target/thumbv7em-none-eabihf/release/bluepill",
+            //"executable": "./target/thumbv7em-none-eabihf/release/nucleo",
             "target": ":3333",
             "remote": true,
             "autorun": [
                 "monitor arm semihosting enable",
                 "monitor reset init",
-                "file ./target/thumbv7em-none-eabihf/release/bluepill",
+                "file ./target/thumbv7em-none-eabihf/release/nucleo",
                 "load"
             ],
             "cwd": "${workspaceRoot}"
@@ -25,13 +25,79 @@
             "request": "attach",
             "name": "Debug",
             "gdbpath": "/usr/bin/arm-none-eabi-gdb",
-            //"executable": "./target/thumbv7em-none-eabihf/debug/bluepill",
+            //"executable": "./target/thumbv7em-none-eabihf/debug/nucleo",
             "target": ":3333",
             "remote": true,
             "autorun": [
                 "monitor reset init",
                 "monitor arm semihosting enable",
-                "file ./target/thumbv7em-none-eabihf/debug/bluepill",
+                "file ./target/thumbv7em-none-eabihf/debug/nucleo",
+                "load"
+            ],
+            "cwd": "${workspaceRoot}"
+        },
+        {
+            "type": "gdb",
+            "request": "attach",
+            "name": "Debug hello",
+            "gdbpath": "/usr/bin/arm-none-eabi-gdb",
+            //"executable": "./target/thumbv7em-none-eabihf/debug/nucleo",
+            "target": ":3333",
+            "remote": true,
+            "autorun": [
+                "monitor reset init",
+                "monitor arm semihosting enable",
+                "file ./target/thumbv7em-none-eabihf/debug/examples/hello",
+                "load"
+            ],
+            "cwd": "${workspaceRoot}"
+        },
+        {
+            "type": "gdb",
+            "request": "attach",
+            "name": "Debug crash",
+            "gdbpath": "/usr/bin/arm-none-eabi-gdb",
+            //"executable": "./target/thumbv7em-none-eabihf/debug/nucleo",
+            "target": ":3333",
+            "remote": true,
+            "autorun": [
+                "monitor reset init",
+                "monitor arm semihosting enable",
+                "file ./target/thumbv7em-none-eabihf/debug/examples/crash",
+                "load"
+            ],
+            "cwd": "${workspaceRoot}"
+        },
+        {
+            "type": "gdb",
+            "request": "attach",
+            "name": "Debug itm",
+            "gdbpath": "/usr/bin/arm-none-eabi-gdb",
+            //"executable": "./target/thumbv7em-none-eabihf/debug/nucleo",
+            "target": ":3333",
+            "remote": true,
+            "autorun": [
+                "monitor reset init",
+                //"monitor arm semihosting enable",
+                "monitor tpiu config internal /tmp/itm.fifo uart off 64000000",
+                //"monitor tpiu config internal /tmp/itm.fifo uart off 16000000",
+                "file ./target/thumbv7em-none-eabihf/debug/examples/itm",
+                "load"
+            ],
+            "cwd": "${workspaceRoot}"
+        },
+        {
+            "type": "gdb",
+            "request": "attach",
+            "name": "Debug override",
+            "gdbpath": "/usr/bin/arm-none-eabi-gdb",
+            //"executable": "./target/thumbv7em-none-eabihf/debug/nucleo",
+            "target": ":3333",
+            "remote": true,
+            "autorun": [
+                "monitor reset init",
+                "monitor arm semihosting enable",
+                "file ./target/thumbv7em-none-eabihf/debug/examples/override-exception-handler",
                 "load"
             ],
             "cwd": "${workspaceRoot}"
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index fd45ed4de64e4f64aa56fa194d28be23413ebf32..33cf0d3d09cacac47287d179f3ee96e4f7654e55 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -7,6 +7,10 @@
             "taskName": "xargo build --release",
             "type": "shell",
             "command": "xargo build --release",
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            },
             "problemMatcher": [
                 "$rustc"
             ]
@@ -22,6 +26,54 @@
             "problemMatcher": [
                 "$rustc"
             ]
+        },
+        {
+            "taskName": "xargo build --example hello",
+            "type": "shell",
+            "command": "xargo build --example hello",
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            },
+            "problemMatcher": [
+                "$rustc"
+            ]
+        },
+        {
+            "taskName": "xargo build --example crash",
+            "type": "shell",
+            "command": "xargo build --example crash",
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            },
+            "problemMatcher": [
+                "$rustc"
+            ]
+        },
+        {
+            "taskName": "xargo build --example itm",
+            "type": "shell",
+            "command": "xargo build --example itm",
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            },
+            "problemMatcher": [
+                "$rustc"
+            ]
+        },
+        {
+            "taskName": "xargo build --example override-exception-handler",
+            "type": "shell",
+            "command": "xargo build --example override-exception-handler",
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            },
+            "problemMatcher": [
+                "$rustc"
+            ]
         }
     ]
 }
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index 09d6f7f02c7d94c3a86b2aaa8eef80ea6b3dcc85..e432a0681dc0a7b452ba1a0d175894547afec3db 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,18 +11,15 @@
 # will likely look very different (and much more reasonable)
 
 [package]
-name = "bluepill"
+name = "nucleo"
 version = "0.2.1"
 authors = ["per lindgren"]
-description = "are we blue yet"
+description = "are we nucleo yet"
 keywords = ["arm", "cortex-m", "template"]
 categories = ["embedded", "no-std"]
 license = "MIT OR Apache-2.0"
 repository = "not defined"
 
-[dependencies.blue-pill]
-git = "https://github.com/japaric/blue-pill"
-
 [dependencies.cortex-m-semihosting]
 version = "0.2.0"
 
@@ -33,10 +30,6 @@ features = ["abort-on-panic"]
 [dependencies.cortex-m]
 version = "0.3.0"
 
-[dependencies.stm32f103xx]
-features = ["rt"]
-version = "0.7.4"
-
 [profile.release]
 lto = true
 debug = true
\ No newline at end of file
diff --git a/examples/allocator.rs b/examples/allocator.rs
deleted file mode 100644
index 7f61af14dcc56667c1b721615d00ea67082a7c4a..0000000000000000000000000000000000000000
--- a/examples/allocator.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-//! How to use the heap and a dynamic memory allocator
-//!
-//! To compile this example you'll need to build the collections crate as part
-//! of the Xargo sysroot. To do that change the Xargo.toml file to look like
-//! this:
-//!
-//! ``` text
-//! [dependencies.core]
-//! stage = 0
-//!
-//! [dependencies.collections] # NEW
-//! stage = 0
-//!
-//! [dependencies.compiler_builtins]
-//! stage = 1
-//! ```
-//!
-//! This example depends on the alloc-cortex-m crate so you'll have to add it
-//! to your Cargo.toml:
-//!
-//! ``` text
-//! # or edit the Cargo.toml file manually
-//! $ cargo add alloc-cortex-m
-//! ```
-//!
-//! ---
-
-#[allow(deprecated)]
-#![feature(collections)]
-#![feature(used)]
-#![no_std]
-
-// This is the allocator crate; you can use a different one
-extern crate alloc_cortex_m;
-#[macro_use]
-extern crate collections;
-extern crate cortex_m;
-extern crate cortex_m_rt;
-extern crate cortex_m_semihosting;
-
-use core::fmt::Write;
-
-use cortex_m::asm;
-use cortex_m_semihosting::hio;
-
-fn main() {
-    // Initialize the allocator
-    unsafe {
-        extern "C" {
-            // Start of the heap
-            static mut _sheap: usize;
-        }
-
-        // Size of the heap in words (1 word = 4 bytes)
-        // NOTE The bigger the heap the greater the chance to run into a stack
-        // overflow (collision between the stack and the heap)
-        const SIZE: isize = 256;
-
-        // End of the heap
-        let _eheap = (&mut _sheap as *mut _).offset(SIZE);
-
-        alloc_cortex_m::init(&mut _sheap, _eheap);
-    }
-
-    // Growable array allocated on the heap
-    let xs = vec![0, 1, 2];
-
-    let mut stdout = hio::hstdout().unwrap();
-    writeln!(stdout, "{:?}", xs).unwrap();
-}
-
-// As we are not using interrupts, we just register a dummy catch all handler
-#[link_section = ".vector_table.interrupts"]
-#[used]
-static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
-
-extern "C" fn default_handler() {
-    asm::bkpt();
-}
diff --git a/examples/device.rs b/examples/device.rs
deleted file mode 100644
index 0b28e19bde27a2c40994ac39f136004625d558fa..0000000000000000000000000000000000000000
--- a/examples/device.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-//! Using a device crate
-//!
-//! Crates generated using [`svd2rust`] are referred to as device crates. These
-//! crates provides an API to access the peripherals of a device. When you
-//! depend on one of these crates and the "rt" feature is enabled you don't need
-//! link to the cortex-m-rt crate.
-//!
-//! [`svd2rust`]: https://crates.io/crates/svd2rust
-//!
-//! Device crates also provide an `interrupt!` macro to register interrupt
-//! handlers.
-//!
-//! This example depends on the [`stm32f103xx`] crate so you'll have to add it
-//! to your Cargo.toml.
-//!
-//! [`stm32f103xx`]: https://crates.io/crates/stm32f103xx
-//!
-//! ```
-//! $ edit Cargo.toml && cat $_
-//! [dependencies.stm32f103xx]
-//! features = ["rt"]
-//! version = "0.7.0"
-//! ```
-//!
-//! ---
-
-#![deny(warnings)]
-#![feature(const_fn)]
-#![no_std]
-
-extern crate cortex_m;
-extern crate cortex_m_semihosting;
-#[macro_use(exception, interrupt)]
-extern crate stm32f103xx;
-
-use core::cell::RefCell;
-use core::fmt::Write;
-
-use cortex_m::interrupt::{self, Mutex};
-use cortex_m::peripheral::SystClkSource;
-use cortex_m_semihosting::hio::{self, HStdout};
-use stm32f103xx::Interrupt;
-
-static HSTDOUT: Mutex<RefCell<Option<HStdout>>> =
-    Mutex::new(RefCell::new(None));
-
-fn main() {
-    interrupt::free(|cs| {
-        let hstdout = HSTDOUT.borrow(cs);
-        if let Ok(fd) = hio::hstdout() {
-            *hstdout.borrow_mut() = Some(fd);
-        }
-
-        let nvic = stm32f103xx::NVIC.borrow(cs);
-        nvic.enable(Interrupt::TIM2);
-
-        let syst = stm32f103xx::SYST.borrow(cs);
-        syst.set_clock_source(SystClkSource::Core);
-        syst.set_reload(8_000_000); // 1s
-        syst.enable_counter();
-        syst.enable_interrupt();
-    });
-}
-
-exception!(SYS_TICK, tick);
-
-fn tick() {
-    interrupt::free(|cs| {
-        let hstdout = HSTDOUT.borrow(cs);
-        if let Some(hstdout) = hstdout.borrow_mut().as_mut() {
-            writeln!(*hstdout, "Tick").ok();
-        }
-
-        let nvic = stm32f103xx::NVIC.borrow(cs);
-
-        nvic.set_pending(Interrupt::TIM2);
-    });
-}
-
-interrupt!(TIM2, tock, locals: {
-    tocks: u32 = 0;
-});
-
-fn tock(l: &mut TIM2::Locals) {
-    l.tocks += 1;
-
-    interrupt::free(|cs| {
-        let hstdout = HSTDOUT.borrow(cs);
-        if let Some(hstdout) = hstdout.borrow_mut().as_mut() {
-            writeln!(*hstdout, "Tock ({})", l.tocks).ok();
-        }
-    });
-}
diff --git a/src/main.rs b/src/main.rs
index 6f74b52b6981ae8d219b6dc8a6bed2d91a632e89..170a2eae809ce59edb88af07066de7674a57e7e9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -228,17 +228,19 @@ fn decode(wordarr: &[u32], bytearr: &mut [u8], seed: &mut u32) -> u32 {
 #[inline(never)]
 fn main() {
     let mut stdout = hio::hstdout().unwrap();
+
+    // *0xe000_1004
     // test that codgen works
     let mut seed = 0x3e944b9f;
     writeln!(stdout, "{:#08x}", codgen(&mut seed)).unwrap();
 
     seed = 0x0e0657c1;
-    asm::bkpt();
+    //asm::bkpt();
     unsafe {
         (*DWT.get()).enable_cycle_counter();
         (*DWT.get()).cyccnt.write(0);
     }
-    asm::bkpt();
+    //asm::bkpt();
     decode(&ABC, unsafe { &mut PLAIN }, &mut seed);
     asm::bkpt();
     writeln!(
@@ -246,6 +248,9 @@ fn main() {
         "plain string {}",
         from_utf8(unsafe { &PLAIN }).unwrap()
     ).unwrap();
+    loop {
+        asm::bkpt();
+    }
 }
 
 // As we are not using interrupts, we just register a dummy catch all handler