diff --git a/examples/bare6.rs b/examples/bare6.rs
index 493b814787224ae0d6cc27937fdf71ee22dcb496..d7c42b9d73f9b613298d26101b6d496888a8d755 100644
--- a/examples/bare6.rs
+++ b/examples/bare6.rs
@@ -5,39 +5,158 @@
 #![feature(use_nested_groups)]
 #![no_std]
 
-extern crate cortex_m;
-extern crate cortex_m_rt;
+extern crate stm32f40x;
 
 #[macro_use]
 extern crate cortex_m_debug;
 
-use cortex_m::{asm::bkpt, peripheral::DWT};
+use stm32f40x::{DWT, GPIOA, GPIOC, RCC};
+
+fn main() {
+    ipln!("init");
+    let dwt = unsafe { &mut *DWT.get() }; // get the reference to DWD in memory
+    let rcc = unsafe { &mut *RCC.get() }; // get the reference to RCC in memory
+    let gpioa = unsafe { &mut *GPIOA.get() }; // get the reference to GPIOA in memory
+    let gpioc = unsafe { &mut *GPIOC.get() }; // get the reference to GPIOC in memory
+
+    dwt.enable_cycle_counter();
+    clock_out(rcc, gpioc);
+    idle(dwt, rcc, gpioa);
+}
 
 // uses the DWT.CYCNT
 // doc: ARM trm_100166_0001_00_en.pdf, chapter 9.2
-// we use the `cortex-m` abstraction
-fn wait_cycles(nr_cycles: u32) {
-    unsafe {
-        let t = (*DWT.get()).cyccnt.read().wrapping_add(nr_cycles);
-        while ((*DWT.get()).cyccnt.read().wrapping_sub(t) as i32) < 0 {}
-    }
+// we use the `cortex-m` abstraction, as re-exported by the stm32f40x
+fn wait_cycles(dwt: &mut DWT, nr_cycles: u32) {
+    let t = dwt.cyccnt.read().wrapping_add(nr_cycles);
+    while (dwt.cyccnt.read().wrapping_sub(t) as i32) < 0 {}
 }
 
-fn main() {
-    unsafe { (*DWT.get()).enable_cycle_counter() };
-    let mut i = 0;
-    loop {
-        ipln!("tick {}", i);
-        wait_cycles(64_000_000);
-        i += 1; // this will eventually cause a panic, when the counter wraps.
-    }
+// see the Reference Manual RM0368 (www.st.com/resource/en/reference_manual/dm00096844.pdf)
+// rcc,     chapter 6
+// gpio,    chapter 8
+fn clock_out(rcc: &mut RCC, gpioc: &mut GPIOC) {
+    // output MCO2 to pin PC9
+
+    // mco2 	: SYSCLK = 0b00
+    // mcopre 	: divide by 4 = 0b110
+    rcc.cfgr
+        .modify(|_, w| unsafe { w.mco2().bits(0b00).mco2pre().bits(0b110) });
+
+    // power on GPIOC, RM0368 6.3.11
+    rcc.ahb1enr.modify(|_, w| w.gpiocen().set_bit());
+
+    // MCO_2 alternate function AF0, STM32F401xD STM32F401xE data sheet
+    // table 9
+    // AF0, gpioc reset value = AF0
+
+    // configure PC9 as alternate function 0b10, RM0368 6.2.10
+    gpioc.moder.modify(|_, w| unsafe { w.moder9().bits(0b10) });
+
+    // otyper reset state push/pull, in reset state (don't need to change)
+
+    // ospeedr 0b11 = high speed
+    gpioc
+        .ospeedr
+        .modify(|_, w| unsafe { w.ospeedr9().bits(0b11) });
 }
+// user application
+fn idle(dwt: &mut DWT, rcc: &mut RCC, gpioa: &mut GPIOA) {
+    ipln!("idle");
+    // power on GPIOA, RM0368 6.3.11
+    rcc.ahb1enr.modify(|_, w| w.gpioaen().set_bit());
 
-// 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];
+    // configure PA5 as output, RM0368 8.4.1
+    gpioa.moder.modify(|_, w| w.moder5().bits(1));
 
-extern "C" fn default_handler() {
-    cortex_m::asm::bkpt();
+    // at 16 Mhz, 8000_0000 cycles = 0.5s
+    // at 64 Mhz, 8000_0000 cycles = 0.125s
+    loop {
+        ipln!("led on");
+        // set PA5 high, RM0368 8.4.7
+        gpioa.bsrr.write(|w| w.bs5().set_bit());
+        wait_cycles(dwt, 8000_000);
+
+        ipln!("led off");
+        // set PA5 low, RM0368 8.4.7
+        gpioa.bsrr.write(|w| w.br5().set_bit());
+        wait_cycles(dwt, 8000_000);
+    }
 }
+
+// 1. compile and run the example, in 16Mhz
+// the processor SYSCLK defaults to HCI 16Mhz
+// (this is what you get after a `monitor reset halt`)
+//
+// confirm that your ITM dump traces the init, idle and led on/off
+// make sure your TPIU is set to a system clock at 16Mhz
+//
+// you may use either ITM tracing using ITM dump or internally in
+// vscode using the new "cortex debug" plugin
+//
+// what is the frequency of blinking
+// ** your answer here **
+//
+// commit your answers (bare6_1)
+//
+// 2. now connect an oscilloscope to PC9, which is set to
+// output the MCO2
+//
+// what is the frequency of MCO2 read by the oscilloscope
+// ** your answer here **
+//
+// compute the value of SYSCLK based on the oscilloscope reading
+// ** your answer here **
+//
+// what is the peak to peak reading of the signal
+// ** your answer here **
+//
+// make a folder called "pictures" in your git project
+// make a screen dump or photo of the oscilloscope output
+// sove the the picture as "bare_6_16mhz_high_speed"
+//
+// commit your answaaasers (bare6_2)
+//
+// 3. now run the example in 64Mz
+// you can do that by issuing a `monitor reset init`
+// which reprograms SYSCLK to 4*HCI
+// (make sure you have the latest openocd v 0.10)
+//
+// confirm that your ITM dump traces the init, idle and led on/off
+// (make sure your TPIU is set to a system clock at 64Mhz)
+//
+// what is the frequency of blinking
+// ** your answer here **
+//
+// commit your answers (bare6_3)
+//
+// 4. repeat the experiment 2
+// what is the frequency of MCO2 read by the oscilloscope
+// ** your answer here **
+//
+// compute the value of SYSCLK based on the oscilloscope reading
+// ** your answer here **
+// what is the peak to peak reading of the signal
+//
+// ** your answer here **
+//
+// make a screen dump or photo of the oscilloscope output
+// sove the the picture as "bare_6_64mhz_high_speed"
+//
+// commit your answers (bare6_4)
+//
+// 5. now reprogram the PC9 to be "Low Speed", and re-run at 64Mz
+//
+// did the frequency change in comparison to assignment 4.
+// ** your answer here **
+//
+// what is the peak to peak reading of the signal
+// ** your answer here **
+//
+// why does it differ?
+// ** your answer here **
+//
+// make a screen dump or photo of the oscilloscope output
+// sove the the picture as "bare_6_64mhz_low_speed"
+//
+// commit your answers (bare6_24)