diff --git a/.vscode/launch.json b/.vscode/launch.json
index 2b76fa0e1cf361a7bbfb2eee245abd53f26d41cc..130ad1f0c000ab9d02cc1deeb69508ef50d8cc66 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -9,10 +9,8 @@
             "request": "attach",
             "name": "Debug hello",
             "gdbpath": "/usr/bin/arm-none-eabi-gdb",
-            //"executable": ".target/thumbv7em-none-eabihf/debug/examples/hello",
             "target": ":3333",
             "remote": true,
-            //"debugger_args": [],
             "autorun": [
                 "monitor reset halt",
                 "monitor arm semihosting enable",
@@ -26,10 +24,8 @@
             "request": "attach",
             "name": "Debug gpio",
             "gdbpath": "/usr/bin/arm-none-eabi-gdb",
-            //"executable": ".target/thumbv7em-none-eabihf/debug/examples/hello",
             "target": ":3333",
             "remote": true,
-            //"debugger_args": [],
             "autorun": [
                 "monitor reset halt",
                 "monitor arm semihosting enable",
@@ -41,19 +37,51 @@
         {
             "type": "gdb",
             "request": "attach",
-            "name": "Debug usart1",
+            "name": "Debug itm",
             "gdbpath": "/usr/bin/arm-none-eabi-gdb",
-            //"executable": ".target/thumbv7em-none-eabihf/debug/examples/hello",
             "target": ":3333",
             "remote": true,
-            //"debugger_args": [],
             "autorun": [
                 "monitor reset halt",
                 "monitor arm semihosting enable",
-                "file ./target/thumbv7em-none-eabihf/debug/examples/usart1",
+                "monitor tpiu config external uart off 8000000 2000000",
+                "monitor itm port 0 on",
+                "file ./target/thumbv7em-none-eabihf/debug/examples/itm",
+                "load"
+            ],
+            "cwd": "${workspaceRoot}"
+        },
+        {
+            "type": "gdb",
+            "request": "attach",
+            "name": "Debug ble_hid",
+            "gdbpath": "/usr/bin/arm-none-eabi-gdb",
+            "target": ":3333",
+            "remote": true,
+            "autorun": [
+                "monitor reset init",
+                "monitor arm semihosting enable",
+                "file ./target/thumbv7em-none-eabihf/debug/examples/ble_hid",
                 "load"
             ],
             "cwd": "${workspaceRoot}"
+        },
+        {
+            "type": "gdb",
+            "request": "attach",
+            "name": "Debug usart1",
+            "gdbpath": "/usr/bin/arm-none-eabi-gdb",
+            "target": ":3333",
+            "remote": true,
+            "autorun": [
+                "monitor reset-init",
+                "monitor arm semihosting enable",
+                "file ./target/thumbv7em-none-eabihf/debug/examples/usart1",
+                "load",
+                "monitor reset-init",
+                "info target"
+            ],
+            "cwd": "${workspaceRoot}"
         }
     ]
 }
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index a490cda5dae2e78433f2b335578169fc2e3be2a7..5b92a69c579dceef58622eaa08c90cc7b0fadb73 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -31,6 +31,22 @@
             "taskName": "xargo build --example usart1",
             "type": "shell",
             "command": "xargo build --example usart1",
+            "problemMatcher": [
+                "$rustc"
+            ]
+        },
+        {
+            "taskName": "xargo build --example itm",
+            "type": "shell",
+            "command": "xargo build --example itm",
+            "problemMatcher": [
+                "$rustc"
+            ]
+        },
+        {
+            "taskName": "xargo build --example ble_hid",
+            "type": "shell",
+            "command": "xargo build --example ble_hid",
             "problemMatcher": [
                 "$rustc"
             ],
diff --git a/Cargo.toml b/Cargo.toml
index 3f06ac7dfbd53ada79d30055cabd4d911799763c..797c6a6afd3fdebee1fa703f62eb024e447a7751 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -37,6 +37,9 @@ cortex-m-semihosting = "0.2.0"
 features = ["abort-on-panic"]
 version = "0.3.5"
 
+[dev-dependencies.hal]
+path = "hal"
+
 [profile.release]
 debug = true
 lto = true
diff --git a/examples/ble_hid.rs b/examples/ble_hid.rs
new file mode 100644
index 0000000000000000000000000000000000000000..dad30a573d2da5851fabed138a9dc8fb8f6e757f
--- /dev/null
+++ b/examples/ble_hid.rs
@@ -0,0 +1,374 @@
+//! Example application
+//#![deny(unsafe_code)]
+//#![deny(warnings)]
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate cortex_m_rtfm as rtfm;
+extern crate hal;
+#[macro_use]
+extern crate nucleo_64;
+
+use hal::usart::USART;
+
+use rtfm::app;
+
+app! {
+    device: nucleo_64::stm32f40x,
+}
+
+fn init(p: init::Peripherals) {
+    p.DWT.enable_cycle_counter();
+    unsafe {
+        p.DWT.cyccnt.write(0);
+    }
+
+    p.FLASH.acr.reset(); //////////latency().write().bits(2);
+    p.FLASH.acr.modify(|_, w| unsafe {w.latency().bits(2)} ); //////////latency().write().bits(2);
+
+    //modify(|_, w | w.latency().set_bits(2));
+    println!("Init! {:x}", p.FLASH.acr.read().latency().bits());
+
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+    //                                      Clock stuff!
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+    //													 PP	  PLLN	    PLLM
+    //rcc().pllcfgr.write(|w| w.bits(0b0000 0000 0000 00 01 0 101010000 010000));
+
+    
+
+	rtfm::bkpt();
+	p.RCC.cfgr.modify(|_, w| w.sw0().clear_bit()); //Switch to HSI
+	p.RCC.cfgr.modify(|_, w| w.sw1().clear_bit()); //Switch to HSI
+	rtfm::bkpt();
+	p.RCC.cfgr.modify(|_, w| unsafe { w.ppre1().bits(4) }); //Configure apb1 prescaler = 2
+	p.RCC.apb1enr.modify(|_, w| w.pwren().set_bit());
+	p.RCC.cr.write(|w| w.pllon().clear_bit()); //Enable PLL
+	p.RCC
+		.pllcfgr
+		.write(|w| unsafe { w.bits(0b00000000000000010101010000010000) }); //Configure PLL
+
+	p.RCC.cr.modify(|_, w| w.pllon().set_bit()); //Enable PLL
+
+	while p.RCC.cr.read().pllrdy().bit_is_clear() {}
+
+	p.RCC.cfgr.modify(|_, w| w.sw0().clear_bit()); //Switch to PLL
+	rtfm::bkpt();
+	p.RCC.cfgr.modify(|_, w| w.sw1().set_bit()); //Switch to PLL
+	rtfm::bkpt();
+	p.RCC.apb2enr.modify(|_, w| w.syscfgen().set_bit());
+	rtfm::bkpt();
+
+	p.RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit()); //Enable GPIOA clock
+	p.RCC.ahb1enr.modify(|_, w| w.gpioben().set_bit()); //Enable GPIOB clock
+
+	////////////////////////////////////////////////////////////////////////////////////////////////
+ //										USART2 stuff
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+
+	rtfm::bkpt();
+	USART::initialize(p.GPIOA, p.RCC, p.USART2);
+	USART::send(p.USART2, "\n\n\nUSART initialized\n\r");
+	////////////////////////////////////////////////////////////////////////////////////////////////
+
+	//spi.initialize();
+ //i2c.initialize();
+ 
+}
+
+fn idle() -> ! {
+    rtfm::bkpt();
+
+    rtfm::bkpt();
+
+    println!("Hello, world!");
+
+    rtfm::bkpt();
+    loop {
+        rtfm::wfi();
+    }
+}
+
+/*
+//#[macro_use]
+extern crate hal_core;
+use hal_core::*;
+
+extern crate hal;
+use hal::spi::*;
+use hal::bt::*;
+use hal::usart::*;
+use hal::i2c::*;
+
+extern crate stm32f401;
+use stm32f401::base::*;
+use stm32f401::gpioa::*;
+use stm32f401::gpiob::*;
+use stm32f401::rcc::*;
+use stm32f401::usart2::*;
+use stm32f401::spi1::*;
+use stm32f401::exti::*;
+use stm32f401::i2c1::*;
+
+extern crate cortex_m;
+//use cortex_m::peripheral::*;
+use cortex_m::interrupt;
+
+use jap::{exceptions, interrupts};
+
+pub fn usart2() -> &'static mut Usart2 {
+    unsafe { &mut *(USART2_BASE as *mut Usart2) }
+}
+
+pub fn i2c1() -> &'static mut I2c1 {
+    unsafe { &mut *(I2C1_BASE as *mut I2c1) }
+}
+
+pub fn spi1() -> &'static mut Spi1 {
+    unsafe { &mut *(SPI1_BASE as *mut Spi1) }
+}
+
+pub fn gpioa() -> &'static mut Gpioa {
+    unsafe { &mut *(GPIOA_BASE as *mut Gpioa) }
+}
+
+pub fn gpiob() -> &'static mut Gpiob {
+    unsafe { &mut *(GPIOB_BASE as *mut Gpiob) }
+}
+
+pub fn p.RCC -> &'static mut Rcc {
+    unsafe { &mut *(RCC_BASE as *mut Rcc) }
+}
+
+pub fn exti() -> &'static mut Exti {
+    unsafe { &mut *(EXTI_BASE as *mut Exti) }
+}
+
+pub extern "C" fn exti0_handler() {
+    unsafe { usart.send("Received data: \n\r") };
+
+    exti().pr.modify(|_, w| unsafe { w.pr0().bits(1) }); // clr interrupt
+}
+
+// We need a `main` function, just like every other Rust program
+fn main() {
+    let mut hid_service_handle: [u8; 2] = [0; 2];
+    let mut hid_report_char_handle: [u8; 2] = [0; 2];
+    let mut mode: bool = true;
+
+    interrupt::free(|_| {
+        //nvic().set_priority(interrupts::Interrupt::Exti0, 0); // highest
+        //nvic().enable(interrupts::Interrupt::Exti0);
+    });
+
+    dwt_driver::set_cyccntena();
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+    //                                      Clock stuff!
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+    //													 PP	  PLLN	    PLLM
+    //p.RCC.pllcfgr.write(|w| w.bits(0b0000 0000 0000 00 01 0 101010000 010000));
+    p.RCC.cfgr.modify(|_, w| unsafe { w.sw0().bits(0) }); //Switch to HSI
+    p.RCC.cfgr.modify(|_, w| unsafe { w.sw1().bits(0) }); //Switch to HSI
+    p.RCC.cfgr.modify(|_, w| unsafe { w.ppre1().bits(4) }); //Configure apb1 prescaler = 2
+    p.RCC.apb1enr.modify(|_, w| unsafe { w.pwren().bits(1) });
+    p.RCC.cr.write(|w| unsafe { w.pllon().bits(0) }); //Enable PLL
+    p.RCC
+        .pllcfgr
+        .write(|w| unsafe { w.bits(0b00000000000000010101010000010000) }); //Configure PLL
+    p.RCC.cr.modify(|_, w| unsafe { w.pllon().bits(1) }); //Enable PLL
+    p.RCC.cfgr.modify(|_, w| unsafe { w.sw0().bits(0) }); //Switch to PLL
+    p.RCC.cfgr.modify(|_, w| unsafe { w.sw1().bits(1) });
+
+    p.RCC.apb2enr.modify(|_, w| unsafe { w.syscfgen().bits(1) });
+
+    p.RCC.ahb1enr.modify(|_, w| unsafe { w.gpioaen().bits(1) }); //Enable GPIOA clock
+    p.RCC.ahb1enr.modify(|_, w| unsafe { w.gpioben().bits(1) }); //Enable GPIOB clock
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+    //										USART2 stuff
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+
+    unsafe { usart.initialize() };
+    unsafe { usart.send("\n\n\nUSART initialized\n\r") };
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+
+    spi.initialize();
+    i2c.initialize();
+
+    //exti().imr.modify(|_, w| unsafe { w.mr0().bits(1) }); // interrupt mask
+    //exti().rtsr.modify(|_, w| unsafe { w.tr0().bits(1) }); // rising edge
+
+    loop {
+        if mode == true {
+            bt.restart_bt();
+
+            bt.configure_bt_address();
+            dwt_driver::wait_cycles(30_000);
+
+            bt.gatt_service_init();
+            dwt_driver::wait_cycles(30_000);
+
+            bt.gap_service_init();
+            dwt_driver::wait_cycles(30_000);
+
+            bt.gap_set_io_capability();
+            dwt_driver::wait_cycles(30_000);
+
+            bt.gap_set_auth_requirments();
+            dwt_driver::wait_cycles(30_000);
+
+            hid_service_handle = bt.start_hid_service();
+            dwt_driver::wait_cycles(30_000);
+
+            let hid_protocol_mode_char_handle =
+                bt.hid_add_protocol_mode_characteristic(hid_service_handle);
+            dwt_driver::wait_cycles(30_000);
+
+            bt.hid_set_protocol_mode_characteristic(
+                hid_service_handle,
+                hid_protocol_mode_char_handle,
+            );
+            dwt_driver::wait_cycles(30_000);
+
+            /*let hid_boot_mouse_report_char_handle = */
+            bt.hid_add_boot_mouse_input_report_characteristic(
+                hid_service_handle,
+            );
+            dwt_driver::wait_cycles(30_000);
+
+            let hid_information_char_handle =
+                bt.hid_add_information_characteristic(hid_service_handle);
+            dwt_driver::wait_cycles(30_000);
+
+            bt.hid_set_information_characteristic(
+                hid_service_handle,
+                hid_information_char_handle,
+            );
+            dwt_driver::wait_cycles(30_000);
+
+            /*let HIDControlPointCharactersiticHandle = */
+            bt.hid_add_control_point_characteristic(hid_service_handle);
+            dwt_driver::wait_cycles(30_000);
+
+            let hid_report_map_char_handle =
+                bt.hid_add_report_map_characteristic(hid_service_handle);
+            dwt_driver::wait_cycles(30_000);
+
+            bt.hid_set_report_map_characteristic(
+                hid_service_handle,
+                hid_report_map_char_handle,
+            );
+            dwt_driver::wait_cycles(30_000);
+
+            hid_report_char_handle =
+                bt.hid_add_report_characteristic(hid_service_handle);
+            dwt_driver::wait_cycles(30_000);
+
+            bt.hid_add_report_description(
+                hid_service_handle,
+                hid_report_char_handle,
+            );
+            dwt_driver::wait_cycles(30_000);
+
+            let battery_level_service_handle = bt.start_battery_level_service();
+            dwt_driver::wait_cycles(30_000);
+
+            let battery_level_char_handle =
+                bt.add_battery_level_characteristic(
+                    battery_level_service_handle,
+                );
+            dwt_driver::wait_cycles(30_000);
+
+            bt.add_presentation_format_description(
+                battery_level_service_handle,
+                battery_level_char_handle,
+            );
+            dwt_driver::wait_cycles(30_000);
+
+            let device_information_service_handle =
+                bt.start_device_information_service();
+            dwt_driver::wait_cycles(30_000);
+
+            bt.add_pnp_id_characteristic(device_information_service_handle);
+            dwt_driver::wait_cycles(30_000);
+
+            bt.gap_set_discoverable();
+            dwt_driver::wait_cycles(30_000);
+
+            mode = false;
+        } else {
+            let mut data: [u8; 128] = [0; 128];
+
+            data[0] = 0x60;
+
+            i2c.write_memory(data, 1);
+
+            let ident = i2c.read_memory(0x0f);
+            if ident != 104 {
+                loop {}
+            }
+            let xindata = i2c.read_memory(0x28);
+            let xindata2 = i2c.read_memory(0x29);
+            let yindata = i2c.read_memory(0x2A);
+            let yindata2 = i2c.read_memory(0x2B);
+
+            let xvalue: i16 =
+                (((xindata2 as i16) << 8) + (xindata as i16)) / 500; // 100;
+            let yvalue: i16 =
+                (((yindata2 as i16) << 8) + (yindata as i16)) / 500; // 100;
+
+            bt.set_report_characteristic(
+                hid_service_handle,
+                hid_report_char_handle,
+                xvalue,
+                yvalue,
+            );
+            dwt_driver::wait_cycles(84_000_000);
+        }
+
+        let response = bt.spi_read();
+
+        if response[0] == 4 && response[1] == 5 && response[2] == 4
+        /*&& response[3] == 0 && response[4] == 1 && response[5] == 8 && response[6] == 19*/
+        {
+            unsafe { usart.send("Disconnected\n\r") };
+            mode = true;
+        } else if response[0] == 4 && response[1] == 255 && response[2] == 3
+            && response[3] == 1 && response[4] == 0
+            && response[5] == 1
+        {
+            unsafe { usart.send("Restarted BT\n\r") };
+        } else if response[0] == 4 && response[1] == 62 && response[2] == 19
+            && response[3] == 1
+        {
+            unsafe { usart.send("Connected complete event!\n\r") };
+        } else if response[0] == 4 && response[1] == 62 && response[2] == 10
+            && response[3] == 3
+        {
+            unsafe { usart.send("Connection update complete\n\r") };
+        } else if response[0] == 4 && response[1] == 8 && response[2] == 4 {
+            unsafe { usart.send("Encryption change\n\r") };
+        } else {
+            //Nothing we bother with
+            //unsafe { usart.send("Received data: unknown\n\r") };
+        }
+    }
+}
+
+// The program must specify how exceptions will be handled
+// Here we just use the default handler to handle all the exceptions
+#[no_mangle]
+pub static _EXCEPTIONS: exceptions::Handlers = exceptions::Handlers {
+    ..exceptions::DEFAULT_HANDLERS
+};
+
+// Likewise with interrupts
+#[no_mangle]
+pub static _INTERRUPTS: interrupts::Handlers = interrupts::Handlers {
+    exti0: exti0_handler,
+    ..interrupts::DEFAULT_HANDLERS
+};
+*/
diff --git a/examples/itm.1.rs b/examples/itm.1.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ab913ecf9c0650108474963bd9cfb71ddeaf59a3
--- /dev/null
+++ b/examples/itm.1.rs
@@ -0,0 +1,52 @@
+//! Sends "Hello" and then "World" through the ITM port 0
+//!
+//! You'll need to run these lines in your GDB session
+//!
+//! ``` text
+//! > monitor tpiu config external uart off 8000000 2000000
+//! > monitor itm port 0 on
+//! ```
+//!
+//! And connect the SWO (PB3) pin to an UART adapter, or read it by some other
+//! means.
+//!
+//! Finally you should see the output if you monitor the UART adapter device
+//! file.
+//!
+//! ``` console
+//! $ cat /dev/ttyUSB0
+//! Hello
+//! World
+//! ```
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate blue_pill;
+#[macro_use(iprint, iprintln)]
+extern crate cortex_m;
+extern crate cortex_m_rtfm as rtfm;
+
+use rtfm::{app, Threshold};
+
+app! {
+    device: blue_pill::stm32f103xx,
+
+    idle: {
+        resources: [ITM],
+    },
+}
+
+fn init(p: init::Peripherals) {
+    iprintln!(&p.ITM.stim[0], "Hello");
+}
+
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
+    iprintln!(&r.ITM.stim[0], "World");
+
+    // Sleep
+    loop {
+        rtfm::wfi();
+    }
+}
diff --git a/examples/itm.rs b/examples/itm.rs
index ab913ecf9c0650108474963bd9cfb71ddeaf59a3..503ed097f04f411ac55eb590e5bb245bd29394d0 100644
--- a/examples/itm.rs
+++ b/examples/itm.rs
@@ -23,15 +23,15 @@
 #![feature(proc_macro)]
 #![no_std]
 
-extern crate blue_pill;
 #[macro_use(iprint, iprintln)]
 extern crate cortex_m;
 extern crate cortex_m_rtfm as rtfm;
+extern crate nucleo_64;
 
 use rtfm::{app, Threshold};
 
 app! {
-    device: blue_pill::stm32f103xx,
+    device: nucleo_64::stm32f40x,
 
     idle: {
         resources: [ITM],
@@ -46,6 +46,7 @@ fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     iprintln!(&r.ITM.stim[0], "World");
 
     // Sleep
+    rtfm::bkpt();
     loop {
         rtfm::wfi();
     }
diff --git a/hal/Cargo.toml b/hal/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..797e5a4075aeb85feef4ae781954841dc42f84dd
--- /dev/null
+++ b/hal/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+authors = [
+	"Bjorn Paulstrom <bjornpaulstrom@hotmail.se>",
+]
+description = "hal"
+
+license = "MIT OR Apache-2.0"
+name = "hal"
+version = "0.1.0"
+
+[dependencies.stm32f40x]
+git = "https://gitlab.henriktjader.com/pln/STM32F40x"
+features = ["rt"]
diff --git a/hal/src/bt.rs b/hal/src/bt.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7c6da7c0b1bb7fa3b5061e5bcfc0798f2861e902
--- /dev/null
+++ b/hal/src/bt.rs
@@ -0,0 +1,964 @@
+extern crate hal_core;
+use self::hal_core::*;
+
+extern crate stm32f401;
+use self::stm32f401::base::*;
+use self::stm32f401::gpioa::*;
+use self::stm32f401::exti::*;
+
+use spi::*;
+use usart::*;
+
+pub static bt: BT = BT
+{
+};
+
+pub struct BT {}
+
+pub struct BluetoothWriteStatus 
+{
+    pub status: bool,
+    pub bytes: u8,
+}
+
+pub struct BluetoothReadStatus 
+{
+    pub status: bool,
+    pub bytes: u8,
+}
+
+pub struct HCICommand 
+{
+    pub ogf: u8,
+    pub ocf: u16,
+    pub length: u8,
+    pub command: [u8; 128],
+}
+
+pub struct HCIResponse 
+{
+    //eventcode: u8,
+    //length: u8,
+    pub params: [u8; 128],
+}
+
+pub fn gpioa() -> &'static mut Gpioa 
+{
+    unsafe { &mut *(GPIOA_BASE as *mut Gpioa) }
+}
+
+pub fn exti() -> &'static mut Exti {
+    unsafe { &mut *(EXTI_BASE as *mut Exti) }
+}
+
+
+impl BT
+{
+	pub fn restart_bt(&self)
+	{
+		unsafe { usart.send("Restarting Bluetooth...\n\r") };
+		
+	    gpioa().bsrr.write(|w| w.br8().bits(1)); // turn off bt
+	    dwt_driver::wait_cycles(84_000 * 5); //5 msec
+	    gpioa().bsrr.write(|w| w.bs8().bits(1)); // turn on bt
+	    dwt_driver::wait_cycles(84_000 * 5); // 5msec
+	    
+	    let data = self.spi_read();
+	}
+	
+	pub fn send_hci_command(&self, hci: HCICommand) -> [u8; 128]
+	{
+		
+        let mut hc: [u8; 128] = [0; 128];
+        let mut response: [u8; 128] = [0; 128];
+        let mut bws = BluetoothWriteStatus { status: false, bytes: 0 };
+
+        hc[0] = 0x01;
+        hc[1] = hci.ocf as u8;
+        hc[2] = hci.ogf << 2;
+        hc[3] = hci.length;
+
+        if hci.ocf > 255 {
+            if hci.ocf & 0b1000000000 != 0 {
+                hc[2] = hc[2] + 2;
+            }
+            if hci.ocf & 0b0100000000 != 0 {
+                hc[2] = hc[2] + 1;
+            }
+        }
+
+        let mut i = 0;
+        while i < hci.length 
+        {
+            hc[4 + i as usize] = hci.command[i as usize];
+            i = i + 1;
+        }
+	
+		//exti().imr.modify(|_, w| unsafe { w.mr0().bits(0) }); // interrupt mask
+		loop 
+		{
+			self.spi_select_bt();
+			self.bluetooth_write_status(&mut bws);
+			if bws.status == true
+			{
+				if bws.bytes > hci.length
+				{
+					spi.spi1sendreceive(hc, &mut response, hci.length+4);
+					self.spi_deselect_bt();
+					response = self.spi_read();
+					//exti().imr.modify(|_, w| unsafe { w.mr0().bits(1) }); // interrupt mask
+					return response;
+				}
+						
+			}
+			self.spi_deselect_bt();
+		}	
+	}
+	
+    pub fn spi_read(&self) -> [u8; 128]
+    {
+        let mut response: [u8; 128] = [0; 128];
+        let mut brs = BluetoothReadStatus { status: false, bytes: 0 };
+		dwt_driver::wait_cycles(10 * 84_000); //1msec
+        while gpioa().idr.read().idr0().bits() == 1 
+        {
+            self.spi_select_bt();
+            dwt_driver::wait_cycles(500 * 84); //500 usec
+            self.bluetooth_read_status(&mut brs);
+            if brs.status == true && brs.bytes > 0 
+            {
+                response = spi.spi1receive(brs.bytes);
+                self.spi_deselect_bt();
+                //dwt_driver::wait_cycles(50 * 84_000); //50msec
+                break;
+            }
+            self.spi_deselect_bt();
+            dwt_driver::wait_cycles(10 * 84_000); //1msec
+        }
+        response
+    }
+
+    pub fn configure_bt_address(&self) 
+    {
+    	unsafe { usart.send("Setting config data, bdaddress: ") };
+    	
+        let mut hcicommand: HCICommand = HCICommand { ogf: 0x3f, ocf: 0x000C, length: 8, command: [0; 128] };
+        hcicommand.command[0] = 0x00;
+        hcicommand.command[1] = 0x06;
+        hcicommand.command[2] = 0xaa;
+        hcicommand.command[3] = 0x00;
+        hcicommand.command[4] = 0x00;
+        hcicommand.command[5] = 0xe1;
+        hcicommand.command[6] = 0x80;
+        hcicommand.command[7] = 0x02;
+
+        //self.bt_send_hci_command(hc);
+        let hciresponse = self.send_hci_command(hcicommand);
+        
+        //The controller will generate a command complete event. BT Core specification Vol 2, Part E, 7.7.14 - Command Complete Event
+        if hciresponse[6] == 0x00
+        {
+        	unsafe { usart.send("Success\n\r") };
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn gatt_service_init(&self) 
+    {
+    	unsafe { usart.send("Initializing GATT service: ") };
+    	
+        let hcicommand: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000001, length: 0, command: [0; 128] };
+
+        //self.bt_send_hci_command(hc);
+        let hciresponse = self.send_hci_command(hcicommand);
+        
+        //The controller will generate a command complete event. BT Core specification Vol 2, Part E, 7.7.14 - Command Complete Event
+        if hciresponse[6] == 0x00
+        {
+        	unsafe { usart.send("Success\n\r") };
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn gap_service_init(&self) 
+    {
+    	unsafe { usart.send("Initializing GAP service: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0x008A, length: 3, command: [0; 128] };
+        hc.command[0] = 0x01;
+        hc.command[1] = 0x00;
+        hc.command[2] = 0x07;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        //The controller will generate a command complete event. BT Core specification Vol 2, Part E, 7.7.14 - Command Complete Event
+        if hciresponse[6] == 0x00
+        {
+        	unsafe { usart.send("Success\n\r") };
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn gap_set_io_capability(&self) 
+    {
+    	unsafe { usart.send("Setting GAP IO capability: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0x85, length: 1, command: [0; 128] };
+        hc.command[0] = 0x03;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        //The controller will generate a command complete event. BT Core specification Vol 2, Part E, 7.7.14 - Command Complete Event
+        if hciresponse[6] == 0x00
+        {
+        	unsafe { usart.send("Success\n\r") };
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn gap_set_auth_requirments(&self) 
+    {
+    	unsafe { usart.send("Setting GAP auth requirments: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0x86, length: 26, command: [0; 128] };
+        hc.command[0] = 0x00;
+        hc.command[1] = 0x00;
+        hc.command[2] = 0x00;
+        hc.command[3] = 0x00;
+        hc.command[4] = 0x00;
+        hc.command[5] = 0x00;
+        hc.command[6] = 0x00;
+        hc.command[7] = 0x00;
+        hc.command[8] = 0x00;
+        hc.command[9] = 0x00;
+        hc.command[10] = 0x00;
+        hc.command[11] = 0x00;
+        hc.command[12] = 0x00;
+        hc.command[13] = 0x00;
+        hc.command[14] = 0x00;
+        hc.command[15] = 0x00;
+        hc.command[16] = 0x00;
+        hc.command[17] = 0x00;
+        hc.command[18] = 0x07;
+        hc.command[19] = 0x10;
+        hc.command[20] = 0x00;
+        hc.command[21] = 0x01;
+        hc.command[22] = 0x00;
+        hc.command[23] = 0x00;
+        hc.command[24] = 0x00;
+        hc.command[25] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        //The controller will generate a command complete event. BT Core specification Vol 2, Part E, 7.7.14 - Command Complete Event
+        if hciresponse[6] == 0x00
+        {
+        	unsafe { usart.send("Success\n\r") };
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn start_hid_service(&self) -> [u8;2]
+    {
+    	unsafe { usart.send("Starting HID service: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000010, length: 5, command: [0; 128] };
+        hc.command[0] = 0x01;
+        hc.command[1] = 0x12;
+        hc.command[2] = 0x18;
+        hc.command[3] = 0x01;
+        hc.command[4] = 0x10;
+	
+        let hciresponse = self.send_hci_command(hc);
+        
+        if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn hid_add_protocol_mode_characteristic(&self, HIDServiceHandle: [u8;2]) -> [u8;2] 
+    {
+    	unsafe { usart.send("Adding HID protocol mode characteristic: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000100, length: 12, command: [0; 128] };
+        hc.command[0] = HIDServiceHandle[0];
+        hc.command[1] = HIDServiceHandle[1];
+        hc.command[2] = 0x01;
+        hc.command[3] = 0x4e;
+        hc.command[4] = 0x2a;
+        hc.command[5] = 0x01;
+        hc.command[6] = 0x00;
+        hc.command[7] = 0x06;
+        hc.command[8] = 0x00;
+        hc.command[9] = 0x00;
+        hc.command[10] = 0x10;
+        hc.command[11] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn hid_set_protocol_mode_characteristic(&self, HIDServiceHandle: [u8;2], HIDProtocolModeCharactersiticHandle: [u8;2]) 
+    {
+    	
+    	unsafe { usart.send("Setting HID protocol mode characteristic: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000110, length: 7, command: [0; 128] };
+                
+        hc.command[0] = HIDServiceHandle[0];
+        hc.command[1] = HIDServiceHandle[1];
+        hc.command[2] = HIDProtocolModeCharactersiticHandle[0];
+        hc.command[3] = HIDProtocolModeCharactersiticHandle[1];
+        hc.command[4] = 0x00;
+        hc.command[5] = 0x01;
+        hc.command[6] = 0x01;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn hid_add_boot_mouse_input_report_characteristic(&self, HIDServiceHandle: [u8;2]) -> [u8;2]
+    {
+    	unsafe { usart.send("Adding boot mouse input report characteristic: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000100, length: 12, command: [0; 128] };
+        hc.command[0] = HIDServiceHandle[0];
+        hc.command[1] = HIDServiceHandle[1];
+        hc.command[2] = 0x01;
+        hc.command[3] = 0x33;
+        hc.command[4] = 0x2a;
+        hc.command[5] = 0x03;
+        hc.command[6] = 0x00;
+        hc.command[7] = 0x1a;
+        hc.command[8] = 0x00;
+        hc.command[9] = 0x01;
+        hc.command[10] = 0x10;
+        hc.command[11] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn hid_add_information_characteristic(&self, HIDServiceHandle: [u8;2]) -> [u8;2]
+    {
+    	unsafe { usart.send("Adding HID information characteristic: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000100, length: 12, command: [0; 128] };
+        hc.command[0] = HIDServiceHandle[0];
+        hc.command[1] = HIDServiceHandle[1];
+        hc.command[2] = 0x01;
+        hc.command[3] = 0x4a;
+        hc.command[4] = 0x2a;
+        hc.command[5] = 0x04;
+        hc.command[6] = 0x00;
+        hc.command[7] = 0x02;
+        hc.command[8] = 0x00;
+        hc.command[9] = 0x01;
+        hc.command[10] = 0x10;
+        hc.command[11] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn hid_set_information_characteristic(&self, HIDServiceHandle: [u8;2], HIDInformationCharactersiticHandle: [u8;2]) 
+    {
+    	unsafe { usart.send("Setting HID information characteristic: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000110, length: 10, command: [0; 128] };
+        hc.command[0] = HIDServiceHandle[0];
+        hc.command[1] = HIDServiceHandle[1];
+        hc.command[2] = HIDInformationCharactersiticHandle[0];
+        hc.command[3] = HIDInformationCharactersiticHandle[1];
+        hc.command[4] = 0x00;
+        hc.command[5] = 0x04;
+        hc.command[6] = 0x01;
+        hc.command[7] = 0x12;
+        hc.command[8] = 0x00;
+        hc.command[9] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn hid_add_control_point_characteristic(&self, HIDServiceHandle: [u8;2]) -> [u8;2]
+    {
+    	unsafe { usart.send("Adding HID control point characteristic: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000100, length: 12, command: [0; 128] };
+        hc.command[0] = HIDServiceHandle[0];
+        hc.command[1] = HIDServiceHandle[1];
+        hc.command[2] = 0x01;
+        hc.command[3] = 0x4c;
+        hc.command[4] = 0x2a;
+        hc.command[5] = 0x01;
+        hc.command[6] = 0x00;
+        hc.command[7] = 0x04;
+        hc.command[8] = 0x00;
+        hc.command[9] = 0x01;
+        hc.command[10] = 0x10;
+        hc.command[11] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn hid_add_report_map_characteristic(&self, HIDServiceHandle: [u8;2]) -> [u8;2]  
+    {
+    	unsafe { usart.send("Adding HID report map characteristic: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000100, length: 12, command: [0; 128] };
+        hc.command[0] = HIDServiceHandle[0];
+        hc.command[1] = HIDServiceHandle[1];
+        hc.command[2] = 0x01;
+        hc.command[3] = 0x4b;
+        hc.command[4] = 0x2a;
+        hc.command[5] = 0x34;
+        hc.command[6] = 0x00;
+        hc.command[7] = 0x02;
+        hc.command[8] = 0x00;
+        hc.command[9] = 0x00;
+        hc.command[10] = 0x10;
+        hc.command[11] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn hid_set_report_map_characteristic(&self, HIDServiceHandle: [u8;2], HIDReportMapCharactersiticHandle: [u8;2]) 
+    {
+    	unsafe { usart.send("Setting report map characteristic: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000110, length: 58, command: [0; 128] };
+        hc.command[0] = HIDServiceHandle[0];
+        hc.command[1] = HIDServiceHandle[1];
+        hc.command[2] = HIDReportMapCharactersiticHandle[0];
+        hc.command[3] = HIDReportMapCharactersiticHandle[1];
+		hc.command[4] = 0x00;
+		hc.command[5] = 0x34;
+		hc.command[6] = 0x05; //
+		hc.command[7] = 0x01; //
+		hc.command[8] = 0x09; //
+		hc.command[9] = 0x02; //
+		hc.command[10] = 0xA1;//
+		hc.command[11] = 0x01;//
+		hc.command[12] = 0x09;//
+		hc.command[13] = 0x01;//
+		hc.command[14] = 0xA1;//
+		hc.command[15] = 0x00;//
+		hc.command[16] = 0x85;//
+		hc.command[17] = 0x01;//
+		hc.command[18] = 0x05;//
+		hc.command[19] = 0x09;//
+		hc.command[20] = 0x19;//
+		hc.command[21] = 0x01;//
+		hc.command[22] = 0x29;//
+		hc.command[23] = 0x03;//
+		hc.command[24] = 0x15;//
+		hc.command[25] = 0x00;//
+		hc.command[26] = 0x25;//
+		hc.command[27] = 0x01;//
+		hc.command[28] = 0x95;//
+		hc.command[29] = 0x03;//
+		hc.command[30] = 0x75;//
+		hc.command[31] = 0x01;//
+		hc.command[32] = 0x81;//
+		hc.command[33] = 0x02;//
+		hc.command[34] = 0x95;//
+		hc.command[35] = 0x01;//
+		hc.command[36] = 0x75;//
+		hc.command[37] = 0x05;//
+		hc.command[38] = 0x81;//
+		hc.command[39] = 0x03;//
+		hc.command[40] = 0x05;//
+		hc.command[41] = 0x01;//
+		hc.command[42] = 0x09;//
+		hc.command[43] = 0x30;//
+		hc.command[44] = 0x09;//
+		hc.command[45] = 0x31;//
+		hc.command[46] = 0x15;//
+		hc.command[47] = 0x81;//
+		hc.command[48] = 0x25;//
+		hc.command[49] = 0x7F;//
+		hc.command[50] = 0x75;//
+		hc.command[51] = 0x08;//
+		hc.command[52] = 0x95;//
+		hc.command[53] = 0x02;//
+		hc.command[54] = 0x81;//
+		hc.command[55] = 0x06;//
+		hc.command[56] = 0xC0;//
+		hc.command[57] = 0xC0;//
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn hid_add_report_characteristic(&self, HIDServiceHandle: [u8;2]) -> [u8;2]    
+    {
+    	unsafe { usart.send("Adding HID report characteristic: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000100, length: 12, command: [0; 128] };
+        hc.command[0] = HIDServiceHandle[0];
+        hc.command[1] = HIDServiceHandle[1];
+        hc.command[2] = 0x01;
+        hc.command[3] = 0x4d;
+        hc.command[4] = 0x2a;
+        hc.command[5] = 0x03;
+        hc.command[6] = 0x00;
+        hc.command[7] = 0x12;
+        hc.command[8] = 0x00;
+        hc.command[9] = 0x01;
+        hc.command[10] = 0x10;
+        hc.command[11] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+        if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn hid_add_report_description(&self, HIDServiceHandle: [u8;2], HIDReportCharactersiticHandle: [u8;2]) -> [u8;2]
+	{
+		unsafe { usart.send("Adding HID report description: ") };
+		
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000101, length: 16, command: [0; 128] };
+        hc.command[0] = HIDServiceHandle[0];
+        hc.command[1] = HIDServiceHandle[1];
+        hc.command[2] = HIDReportCharactersiticHandle[0];
+        hc.command[3] = HIDReportCharactersiticHandle[1];
+        hc.command[4] = 0x01;
+        hc.command[5] = 0x08;
+        hc.command[6] = 0x29;
+        hc.command[7] = 0x02;
+        hc.command[8] = 0x02;
+        hc.command[9] = 0x01;
+        hc.command[10] = 0x01;
+        hc.command[11] = 0x00;
+        hc.command[12] = 0x01;
+        hc.command[13] = 0x01;
+        hc.command[14] = 0x10;
+        hc.command[15] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+	    if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn start_battery_level_service(&self) -> [u8;2]
+    {
+    	unsafe { usart.send("Starting battery level service: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000010, length: 5, command: [0; 128] };
+        hc.command[0] = 0x01;
+        hc.command[1] = 0x0F;
+        hc.command[2] = 0x18;
+        hc.command[3] = 0x01;
+        hc.command[4] = 0x04;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+	    if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn add_battery_level_characteristic(&self, BatteryLevelServiceHandle: [u8;2]) -> [u8;2]
+    {
+    	unsafe { usart.send("Adding battery level characteristic: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000100, length: 12, command: [0; 128] };
+        hc.command[0] = BatteryLevelServiceHandle[0];
+        hc.command[1] = BatteryLevelServiceHandle[1];
+        hc.command[2] = 0x01;
+        hc.command[3] = 0x19;
+        hc.command[4] = 0x2a;
+        hc.command[5] = 0x01;
+        hc.command[6] = 0x00;
+        hc.command[7] = 0x02;
+        hc.command[8] = 0x00;
+        hc.command[9] = 0x01;
+        hc.command[10] = 0x10;
+        hc.command[11] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+	    if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn add_presentation_format_description(&self, BatteryLevelServiceHandle: [u8;2], BatteryLevelCharactersiticHandle: [u8;2]) -> [u8;2] 
+    {
+    	unsafe { usart.send("Adding battery level format description: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000101, length: 21, command: [0; 128] };
+        hc.command[0] = BatteryLevelServiceHandle[0];
+        hc.command[1] = BatteryLevelServiceHandle[1];
+        hc.command[2] = BatteryLevelCharactersiticHandle[0];
+        hc.command[3] = BatteryLevelCharactersiticHandle[1];
+        hc.command[4] = 0x01;
+        hc.command[5] = 0x04;
+        hc.command[6] = 0x29;
+        hc.command[7] = 0x07;
+        hc.command[8] = 0x07;
+        hc.command[9] = 0x04;
+        hc.command[10] = 0x00;
+        hc.command[11] = 0xad;
+        hc.command[12] = 0x27;
+        hc.command[13] = 0x01;
+        hc.command[14] = 0x00;
+        hc.command[15] = 0x01;
+        hc.command[16] = 0x00;
+        hc.command[17] = 0x01;
+        hc.command[18] = 0x01;
+        hc.command[19] = 0x10;
+        hc.command[20] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+	    if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+
+    pub fn start_device_information_service(&self) -> [u8;2]
+    {
+    	unsafe { usart.send("Starting device information service: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000010, length: 5, command: [0; 128] };
+        hc.command[0] = 0x01;
+        hc.command[1] = 0x0A;
+        hc.command[2] = 0x18;
+        hc.command[3] = 0x01;
+        hc.command[4] = 0x15;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+	    if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        	let mut ret: [u8;2] = [0;2];
+			ret[0] = hciresponse[7];
+			ret[1] = hciresponse[8];
+			return ret;
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn add_pnp_id_characteristic(&self, DeviceInformationServiceHandle: [u8;2]) 
+    {
+    	unsafe { usart.send("Adding device info PNP ID characteristic: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000100, length: 12, command: [0; 128] };
+        hc.command[0] = DeviceInformationServiceHandle[0];
+        hc.command[1] = DeviceInformationServiceHandle[1];
+        hc.command[2] = 0x01;
+        hc.command[3] = 0x50;
+        hc.command[4] = 0x2a;
+        hc.command[5] = 0x07;
+        hc.command[6] = 0x00;
+        hc.command[7] = 0x02;
+        hc.command[8] = 0x00;
+        hc.command[9] = 0x01;
+        hc.command[10] = 0x10;
+        hc.command[11] = 0x00;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+	    if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+
+    pub fn gap_set_discoverable(&self) 
+    {
+    	unsafe { usart.send("GAP set discoverable: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0x83, length: 16, command: [0; 128] };
+        hc.command[0] = 0x00;
+        hc.command[1] = 0x00;
+        hc.command[2] = 0x00;
+        hc.command[3] = 0x00;
+        hc.command[4] = 0x00;
+        hc.command[5] = 0x00;
+        hc.command[6] = 0x00;
+        hc.command[7] = 0x03;
+        hc.command[8] = 0x09;
+        hc.command[9] = 0x42;
+        hc.command[10] = 0x50;
+        hc.command[11] = 0x00;
+        hc.command[12] = 0x06;
+        hc.command[13] = 0x00;
+        hc.command[14] = 0x00;
+        hc.command[15] = 0x0c;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+	    if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	loop {}
+        }
+    }
+    
+    pub fn set_report_characteristic(&self, HIDServiceHandle: [u8;2], HIDReportCharactersiticHandle: [u8;2], x: i16, y: i16)
+    {
+    	unsafe { usart.send("Sending data: ") };
+    	
+        let mut hc: HCICommand = HCICommand { ogf: 0x3f, ocf: 0b0100000110, length: 9, command: [0; 128] };
+        hc.command[0] = HIDServiceHandle[0];
+        hc.command[1] = HIDServiceHandle[1];
+        hc.command[2] = HIDReportCharactersiticHandle[0];
+        hc.command[3] = HIDReportCharactersiticHandle[1];
+        hc.command[4] = 0x00;
+        hc.command[5] = 0x03;
+        hc.command[6] = 0x00;
+        hc.command[7] = -x as u8;
+        hc.command[8] = y as u8;
+
+        let hciresponse = self.send_hci_command(hc);
+        
+	    if hciresponse[6] == 0
+        {
+        	unsafe { usart.send("Success\n\r") };
+        }
+        else
+        {
+        	unsafe { usart.send("Failure\n\r") };
+        	//loop {}
+        }
+    }
+
+    //Brief: Selects the BT device for SPI transfer
+    pub fn spi_select_bt(&self) {
+        gpioa().bsrr.write(|w| w.br1().bits(1)); // clear ODR1 (BT select)
+        //gpioa().odr.write(unsafe { |w| w.odr1().bits(0) } );
+    }
+
+    //Brief: Deselects the BT device for SPI transfer
+    pub fn spi_deselect_bt(&self) {
+        gpioa().bsrr.write(|w| w.bs1().bits(1));
+        //gpioa().odr.write(unsafe { |w| w.odr1().bits(1) } );
+    }
+
+    //Brief:	Writes to BT device expecting response on how many bytes can be written as a command
+    //return:	struct containing info on bt device, if it is ready for receiving command and how many bytes can be written
+    pub fn bluetooth_write_status(&self, bws: &mut BluetoothWriteStatus) 
+    {
+        let mut response: [u8; 128] = [0; 128];
+        let mut data = [0; 128];
+        data[0] = 0x0a;
+
+        unsafe { spi.spi1sendreceive(data, &mut response, 5) };
+        if response[0] == 0x02 
+        {
+            bws.status = true;
+            bws.bytes = response[1];
+        }
+    }
+
+    pub fn bluetooth_read_status(&self, brs: &mut BluetoothReadStatus)
+    {  
+        let mut data: [u8; 128] = [0; 128];
+        let mut response: [u8; 128] = [0; 128];
+        data[0] = 0x0b;
+
+        spi.spi1sendreceive(data, &mut response, 5);
+
+        if response[0] == 0x02 
+        {
+            brs.status = true;
+            brs.bytes = response[3];
+        }
+    }
+}
diff --git a/hal/src/i2c.rs b/hal/src/i2c.rs
new file mode 100644
index 0000000000000000000000000000000000000000..052f721fb91489f1442ac854c1842b835b80044f
--- /dev/null
+++ b/hal/src/i2c.rs
@@ -0,0 +1,183 @@
+extern crate stm32f401;
+use self::stm32f401::gpioa::*;
+use self::stm32f401::gpiob::*;
+use self::stm32f401::base::*;
+use self::stm32f401::rcc::*;
+use self::stm32f401::i2c1::*;
+
+extern crate hal_core;
+use self::hal_core::*;
+
+pub struct I2C {}
+
+pub fn gpioa() -> &'static mut Gpioa {
+    unsafe { &mut *(GPIOA_BASE as *mut Gpioa) }
+}
+
+pub fn gpiob() -> &'static mut Gpiob {
+    unsafe { &mut *(GPIOB_BASE as *mut Gpiob) }
+}
+
+pub fn rcc() -> &'static mut Rcc {
+    unsafe { &mut *(RCC_BASE as *mut Rcc) }
+}
+
+pub fn i2c1() -> &'static mut I2c1 {
+    unsafe { &mut *(I2C1_BASE as *mut I2c1) }
+}
+
+pub static i2c: I2C = I2C {};
+
+impl I2C
+{
+	pub fn initialize(&self)
+	{
+		rcc().apb1enr.modify(|_, w| unsafe { w.i2c1en().bits(1) });
+        
+        i2c1().cr2.modify(|_, w| unsafe { w.freq().bits(0x2a) });
+        i2c1().trise.modify(|_, w| unsafe { w.trise().bits(0x0d) });
+        i2c1().ccr.modify(|_, w| unsafe { w.f_s().bits(1) });
+        i2c1().ccr.modify(|_, w| unsafe { w.ccr().bits(0x23) });
+        i2c1().oar1.modify(|_, w| unsafe { w.bits(0x4033) });
+        i2c1().cr1.modify(|_, w| unsafe { w.pe().bits(1) });
+        
+        gpiob().moder.modify(|_, w| unsafe { w.moder8().bits(2) }); 
+        gpiob().otyper.modify(|_, w| unsafe { w.ot8().bits(1) });
+        gpiob().ospeedr.modify(|_, w| unsafe { w.ospeedr8().bits(3) });
+        gpiob().afrh.modify(|_, w| unsafe { w.afrh8().bits(4) });
+        gpiob().pupdr.modify(|_, w| unsafe { w.pupdr8().bits(1) });
+        
+        gpiob().moder.modify(|_, w| unsafe { w.moder9().bits(2) }); 
+        gpiob().otyper.modify(|_, w| unsafe { w.ot9().bits(1) });
+        gpiob().ospeedr.modify(|_, w| unsafe { w.ospeedr9().bits(3) });
+        gpiob().afrh.modify(|_, w| unsafe { w.afrh9().bits(4) });
+        gpiob().pupdr.modify(|_, w| unsafe { w.pupdr9().bits(1) });
+        
+        //rcc().apb1rstr.modify(|_, w| unsafe { w.i2c1rst().bits(1) });
+        //rcc().apb1rstr.modify(|_, w| unsafe { w.i2c1rst().bits(0) });
+        
+        i2c1().cr1.modify(|_, w| unsafe { w.pe().bits(1) });
+	}
+	
+	pub fn read_memory(&self, memory_address: u32) -> u32
+	{
+	    /* Disable Pos */
+	    i2c1().cr1.modify(|_, w| unsafe { w.pos().bits(0) });
+	    
+	    /* Send Slave Address and Memory Address */
+	    self.request_memory_read(memory_address);
+	    
+	    //Disable Acknowledge
+		i2c1().cr1.modify(|_, w| unsafe { w.ack().bits(0) });
+	    
+		//Clear ADDR flag; This bit is cleared by software reading SR1 register followed reading SR2, or by hardware when PE=0.
+		i2c1().sr1.read();
+		i2c1().sr2.read();
+	    
+		//Generate stop
+		i2c1().cr1.modify(|_, w| unsafe { w.stop().bits(1) });
+		
+		/* Wait until RXNE flag is set */
+		while i2c1().sr1.read().rx_ne().bits() == 0 {}
+		
+		let value :u32 = i2c1().dr.read().bits();
+		
+		value
+		
+	}
+	
+	pub fn request_memory_read(&self, memory_address: u32)
+	{
+		//Enable Acknowledge
+		i2c1().cr1.modify(|_, w| unsafe { w.ack().bits(1) });
+
+		//Generate Start
+		i2c1().cr1.modify(|_, w| unsafe { w.start().bits(1) });
+		
+		/* Wait until SB flag is set */
+		while i2c1().sr1.read().sb().bits() == 0 {}
+		
+		/* Send slave address */
+		i2c1().dr.write(|w| unsafe { w.bits(214) });
+		
+		// Wait until ADDR flag is set 
+		while i2c1().sr1.read().addr().bits() == 0 {}
+		
+		//Clear ADDR flag; This bit is cleared by software reading SR1 register followed reading SR2, or by hardware when PE=0.
+		i2c1().sr1.read();
+		i2c1().sr2.read();
+		
+		//Wait until TXE flag is set
+		while i2c1().sr1.read().tx_e().bits() == 0 {}
+		
+		//Send Memory Address
+		i2c1().dr.write(|w| unsafe { w.bits(memory_address as u32) });
+		
+		//Wait until TXE flag is set
+		while i2c1().sr1.read().tx_e().bits() == 0 {}
+		
+		/* Generate Restart */
+		i2c1().cr1.modify(|_, w| unsafe { w.start().bits(1) });
+		
+		//Loop until start condition is set
+		while i2c1().sr1.read().sb().bits() == 0 {}
+		
+		/* Send slave address */
+		i2c1().dr.write(|w| unsafe { w.bits(215) });
+		
+		// Wait until ADDR flag is set 
+		while i2c1().sr1.read().addr().bits() == 0 {}
+	}
+	
+	pub fn write_memory(&self, data: [u8; 128], len: u8)
+	{
+	    /* Disable Pos */
+	    i2c1().cr1.modify(|_, w| unsafe { w.pos().bits(0) });
+	    
+	    self.request_memory_write();
+	    
+	    //Send data
+	    let mut x: u8 = 0;
+	    while x < len
+	    {
+			//Wait until TXE flag is set
+			while i2c1().sr1.read().tx_e().bits() == 0 {}
+	    	i2c1().dr.write(|w| unsafe { w.bits(data[x as usize] as u32) });
+	    	x = x + 1;
+	    }
+	    
+	    //Wait until BTF flag is set
+	    while i2c1().sr1.read().btf().bits() == 0 {}
+	    
+	    i2c1().cr1.modify(|_, w| unsafe { w.stop().bits(1) });
+	    
+	    dwt_driver::wait_cycles(30_000);
+	}
+	
+	pub fn request_memory_write(&self) -> bool
+	{
+		/* Generate Start */
+		i2c1().cr1.modify(|_, w| unsafe { w.start().bits(1) });
+		
+		//Loop until start condition is set
+		while i2c1().sr1.read().sb().bits() == 0 {}
+		
+		//Send slave address
+		i2c1().dr.write(|w| unsafe { w.bits(214) });
+		
+		// Wait until ADDR flag is set 
+		while i2c1().sr1.read().addr().bits() == 0 {}
+		
+		//Clear ADDR flag; This bit is cleared by software reading SR1 register followed reading SR2, or by hardware when PE=0.
+		i2c1().sr1.read();
+		i2c1().sr2.read();
+		
+		//Wait until TXE flag is set
+		while i2c1().sr1.read().tx_e().bits() == 0 {}
+		
+		//Send Memory Address
+		i2c1().dr.write(|w| unsafe { w.bits(32) });
+		
+		true
+	}
+}
\ No newline at end of file
diff --git a/hal/src/lib.rs b/hal/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7e016144531cc2ce99674d165d706f2509320590
--- /dev/null
+++ b/hal/src/lib.rs
@@ -0,0 +1,9 @@
+#![no_std]
+//#![feature(asm)]
+//#![feature(plugin)]
+
+extern crate stm32f40x;
+//pub mod spi;
+// pub mod bt;
+pub mod usart;
+// pub mod i2c;
diff --git a/hal/src/spi.rs b/hal/src/spi.rs
new file mode 100644
index 0000000000000000000000000000000000000000..3c5ccd2013a0309d5ff90876e5f02fa60151c83e
--- /dev/null
+++ b/hal/src/spi.rs
@@ -0,0 +1,128 @@
+extern crate stm32f401;
+use self::stm32f401::spi1::*;
+use self::stm32f401::gpioa::*;
+use self::stm32f401::gpiob::*;
+use self::stm32f401::base::*;
+use self::stm32f401::rcc::*;
+
+pub struct SPI {
+    pub receivebuffer: [u8; 128],
+    pub sendbuffer: [u8; 128],
+    pub receiveindex: u8,
+    pub sendindex: u8,
+    pub sendlength: u8,
+    pub receivelength: u8,
+}
+
+pub fn spi1() -> &'static mut Spi1 {
+    unsafe { &mut *(SPI1_BASE as *mut Spi1) }
+}
+
+pub fn gpioa() -> &'static mut Gpioa {
+    unsafe { &mut *(GPIOA_BASE as *mut Gpioa) }
+}
+
+pub fn gpiob() -> &'static mut Gpiob {
+    unsafe { &mut *(GPIOB_BASE as *mut Gpiob) }
+}
+
+pub fn rcc() -> &'static mut Rcc {
+    unsafe { &mut *(RCC_BASE as *mut Rcc) }
+}
+
+pub static spi: SPI = SPI {
+    receivebuffer: [0; 128],
+    sendbuffer: [0; 128],
+    receiveindex: 0,
+    sendindex: 0,
+    sendlength: 0,
+    receivelength: 0,
+};
+
+impl SPI {
+    pub fn initialize(&self) {
+        rcc().apb2enr.modify(|_, w| unsafe { w.spi1en().bits(1) });
+        spi1().cr1.modify(|_, w| unsafe { w.spe().bits(0) }); //enable SPI
+
+        gpioa().moder.modify(|_, w| w.moder6().bits(2)); //TX,RX
+        gpioa().moder.modify(|_, w| w.moder7().bits(2));
+        gpioa().otyper.modify(|_, w| w.ot6().bits(0));
+        gpioa().otyper.modify(|_, w| w.ot7().bits(0));
+        gpioa().ospeedr.modify(|_, w| w.ospeedr6().bits(3));
+        gpioa().ospeedr.modify(|_, w| w.ospeedr7().bits(3));
+        gpioa().afrl.modify(|_, w| w.afrl6().bits(5));
+        gpioa().afrl.modify(|_, w| w.afrl7().bits(5));
+
+        gpioa().moder.modify(|_, w| w.moder1().bits(1)); //CS
+        gpioa().otyper.modify(|_, w| w.ot1().bits(0));
+        gpioa().ospeedr.modify(|_, w| w.ospeedr1().bits(3));
+        gpioa().pupdr.modify(|_, w| w.pupdr1().bits(1));
+
+        gpioa().moder.modify(|_, w| w.moder8().bits(1)); //restart pin
+        gpioa().otyper.modify(|_, w| w.ot8().bits(0));
+        gpioa().pupdr.modify(|_, w| w.pupdr8().bits(1));
+
+        gpioa().moder.modify(|_, w| w.moder0().bits(0)); //BT chip got data pin
+        gpioa().otyper.modify(|_, w| w.ot0().bits(0));
+        gpioa().pupdr.modify(|_, w| w.pupdr0().bits(0));
+
+        gpiob().moder.modify(|_, w| unsafe { w.moder3().bits(2) }); //SPI clock
+        gpiob().otyper.modify(|_, w| unsafe { w.ot3().bits(0) });
+        gpiob().ospeedr.modify(|_, w| unsafe { w.ospeedr3().bits(3) });
+        gpiob().afrl.modify(|_, w| unsafe { w.afrl3().bits(5) });
+        gpiob().pupdr.modify(|_, w| unsafe { w.pupdr3().bits(2) });
+
+        spi1().cr1.modify(|_, w| unsafe { w.br().bits(0b100) }); // CLK / 32 prescaler
+        spi1().cr1.modify(|_, w| unsafe { w.ssi().bits(1) }); // NSS
+        spi1().cr1.modify(|_, w| unsafe { w.ssm().bits(1) }); // Software chip select
+        spi1().cr1.modify(|_, w| unsafe { w.mstr().bits(1) }); //Master
+        spi1().cr1.modify(|_, w| unsafe { w.spe().bits(1) }); //enable SPI
+    }
+
+    //Brief:	Send a series of uint8 through spi1
+    //data: 	u8 to send
+    //len:		length of data
+    pub fn spi1send(&self, data: [u8; 128], len: u8) {
+        let mut x: u8 = 0;
+        while x < len {
+            while spi1().sr.read().txe().bits() == 0 {}
+            spi1().dr.write(|w| unsafe { w.bits(data[x as usize] as u32) });
+            while spi1().sr.read().rxne().bits() == 0 {}
+            let _ = spi1().dr.read().dr().bits() as u8;
+            x = x + 1;
+        }
+    }
+
+    pub fn spi1receive(&self, length: u8) -> [u8; 128] 
+    {
+    	let mut response: [u8; 128] = [0; 128];
+        let mut x: u8 = 0;
+
+        while x < length 
+        {
+            while spi1().sr.read().txe().bits() == 0 {}
+            spi1().dr.write(|w| unsafe { w.bits(0 as u32) });
+            while spi1().sr.read().rxne().bits() == 0 {}
+            response[x as usize] = spi1().dr.read().dr().bits() as u8;
+            x = x + 1;
+        }
+        response
+    }
+
+    //Brief:	Send a series of uint8 through spi1 returning answer
+    //data: 	u8 to send
+    //len:		length of data
+    //return:	return bytes from spi
+    pub fn spi1sendreceive(&self, data: [u8; 128], response: &mut [u8; 128], len: u8)
+    {
+        let mut x: u8 = 0;
+        while x < len 
+        {
+            while spi1().sr.read().txe().bits() == 0 {}
+            spi1().dr.write(|w| unsafe { w.bits(data[x as usize] as u32) });
+            while spi1().sr.read().rxne().bits() == 0 {}
+            response[x as usize] = spi1().dr.read().dr().bits() as u8;
+            x = x + 1;
+        }
+    }
+}
diff --git a/hal/src/usart.rs b/hal/src/usart.rs
new file mode 100644
index 0000000000000000000000000000000000000000..dfcf7e4a4432b5d00849d60a9623bddca0f2d17a
--- /dev/null
+++ b/hal/src/usart.rs
@@ -0,0 +1,40 @@
+
+
+use stm32f40x::{USART2, GPIOA, RCC};
+pub static mut usart: USART = USART {};
+
+pub struct USART {}
+
+impl USART {
+	pub fn initialize(gpioa: &GPIOA, rcc: &RCC, usart2: &USART2) {
+		gpioa.moder.modify(|_, w| w.moder2().bits(2));
+		gpioa.moder.modify(|_, w| w.moder3().bits(2));
+		gpioa.otyper.modify(|_, w| w.ot2().clear_bit());
+		gpioa.otyper.modify(|_, w| w.ot3().clear_bit());
+		gpioa.afrl.modify(|_, w| w.afrl2().bits(7));
+		gpioa.afrl.modify(|_, w| w.afrl3().bits(7));
+
+		rcc.apb1enr.modify(|_, w| w.usart2en().set_bit()); //enable usart2
+		usart2.cr1.modify(|_, w| w.over8().clear_bit()); //16bitoversampling
+		usart2
+			.brr
+			.modify(|_, w| unsafe { w.div_fraction().bits(0x7) }); //Baudrate fraction
+		usart2
+			.brr
+			.modify(|_, w| unsafe { w.div_mantissa().bits(0x111) }); //Baudrate Mantissa
+		usart2.cr1.modify(|_, w| w.ue().set_bit()); //USART enable
+		usart2.cr1.modify(|_, w| w.te().set_bit()); //Transmit enable
+		usart2.cr1.modify(|_, w| w.re().set_bit()); //Receieve enable
+	}
+
+	//Brief:	Send a series of chars through usart2
+ //data: 	chars to send
+ //return:	none
+
+	pub fn send(usart2: &USART2, data: &str) {
+		for c in data.chars() {
+			while usart2.sr.read().txe().bit_is_clear() {}
+			usart2.dr.write(|w| unsafe { w.bits(c as u32) });
+		}
+	}
+}
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644
index 0000000000000000000000000000000000000000..1f26f3f49ea15543fd1d23cf361768b57d5128dd
--- /dev/null
+++ b/rustfmt.toml
@@ -0,0 +1 @@
+line_width = 100
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index eaf53f27f210c718b23339bef5c582479dc855db..1e492244655cfe7f072deb0b0b26fcade2704c09 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -144,9 +144,9 @@ pub mod apb2 {
 #[macro_export]
 macro_rules! println {
     ($($e:tt)*) => {
-        {  
+        {
             extern crate cortex_m_semihosting;
-            use core::fmt::Write;            
+            use core::fmt::Write;
             writeln!(cortex_m_semihosting::hio::hstdout().unwrap(), $($e)*).unwrap();
         }
     }