diff --git a/examples/mco.rs b/examples/mco.rs
index ecd85c9b558e0904730915cd2203a91bac85f1b2..0d8673b992f09e6b004c8ba4927336385dff1263 100644
--- a/examples/mco.rs
+++ b/examples/mco.rs
@@ -21,23 +21,27 @@ fn init(p: init::Peripherals) {
     // RM0368 6.2.10
     // Configure PA8 as MCO_1 alternate function to output HSI clock
     p.RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit()); //Enable GPIOA clock
-    p.GPIOA.ospeedr.modify(|_,w| w.ospeedr8().bits(0b11)); //Highest output speed
-    p.GPIOA.afrh.modify(|_,w| w.afrh8().bits(0)); //Alternate function AF0 MCO_1 on pin 8
-    p.GPIOA.moder.modify(|_,w| w.moder8().bits(0b10)); //Alternate function push-pull
-    p.RCC.cfgr.modify(|_, w| unsafe {w.mco1().bits(0b00)}); //HSI clock selected
-    p.RCC.cfgr.modify(|_, w| unsafe {w.mco1pre().bits(0)}); //No division
+    p.GPIOA.ospeedr.modify(|_, w| w.ospeedr8().bits(0b11)); //Highest output speed
+    p.GPIOA.afrh.modify(|_, w| w.afrh8().bits(0)); //Alternate function AF0 MCO_1 on pin 8
+    p.GPIOA.moder.modify(|_, w| w.moder8().bits(0b10)); //Alternate function push-pull
+    p.RCC.cfgr.modify(|_, w| unsafe { w.mco1().bits(0b00) }); //HSI clock selected
+    p.RCC.cfgr.modify(|_, w| unsafe { w.mco1pre().bits(0) }); //No division
 
     // Configure PC9 as MCO_2 alternate function to output System clock
     p.RCC.ahb1enr.modify(|_, w| w.gpiocen().set_bit()); //Enable GPIOC clock
-    p.GPIOC.ospeedr.modify(|_,w| unsafe {w.ospeedr9().bits(0b11)}); //Highest output speed
-    p.GPIOC.afrh.modify(|_,w| unsafe {w.afrh9().bits(0)}); //Alternate function AF0 MCO_2 on pin 9
-    p.GPIOC.moder.modify(|_,w| unsafe {w.moder9().bits(0b10)}); //Alternate function push-pull
-    p.RCC.cfgr.modify(|_, w| unsafe {w.mco2().bits(0b00)}); //MCO2 SYSCLK clock selected
-    p.RCC.cfgr.modify(|_, w| unsafe {w.mco2pre().bits(0b110)}); //Divide SYSCLK by 4
+    p.GPIOC
+        .ospeedr
+        .modify(|_, w| unsafe { w.ospeedr9().bits(0b11) }); //Highest output speed
+    p.GPIOC.afrh.modify(|_, w| unsafe { w.afrh9().bits(0) }); //Alternate function AF0 MCO_2 on pin 9
+    p.GPIOC
+        .moder
+        .modify(|_, w| unsafe { w.moder9().bits(0b10) }); //Alternate function push-pull
+    p.RCC.cfgr.modify(|_, w| unsafe { w.mco2().bits(0b00) }); //MCO2 SYSCLK clock selected
+    p.RCC.cfgr.modify(|_, w| unsafe { w.mco2pre().bits(0b110) }); //Divide SYSCLK by 4
 
     let sysclk = clock::set_100_mhz(&p.RCC, &p.FLASH);
     println!("SYSCLK set to {}", sysclk);
-    // PC9 should now output sysclk/4 MHz and PA8 the frequency of the HSI RC
+    // PC9 should now output SYSCLK/4 MHz and PA8 the frequency of the HSI RC
 
     led::init(&p.GPIOA, &p.RCC);
 }
diff --git a/examples/usart2-rx-dma.rs b/examples/usart2-rx-dma.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e704972a234ca5bcc64933459a4d870bf403d4d4
--- /dev/null
+++ b/examples/usart2-rx-dma.rs
@@ -0,0 +1,51 @@
+//! Test receiving serial data using the DMA. Program will stop at breakpoint after 8 bytes are received.
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![feature(const_fn)]
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate cortex_m_rtfm as rtfm;
+extern crate f4;
+
+use f4::Serial;
+use f4::dma::{Buffer, Dma1Channel5};
+use f4::time::Hertz;
+use rtfm::{app, Threshold};
+
+const BAUD_RATE: Hertz = Hertz(115_200);
+
+app! {
+    device: f4::stm32f40x,
+
+    resources: {
+        static BUFFER: Buffer<[u8; 8], Dma1Channel5> = Buffer::new([0; 8]);
+    },
+
+    tasks: {
+        DMA1_STREAM5: {
+            path: transfer_done,
+            resources: [BUFFER, DMA1],
+        },
+    },
+}
+
+fn init(p: init::Peripherals, r: init::Resources) {
+    let serial = Serial(p.USART2);
+
+    serial.init(BAUD_RATE.invert(), Some(p.DMA1), p.GPIOA, p.RCC);
+
+    serial.read_exact(p.DMA1, r.BUFFER).unwrap();
+}
+
+fn idle() -> ! {
+    loop {
+        rtfm::wfi();
+    }
+}
+
+fn transfer_done(_t: &mut Threshold, r: DMA1_STREAM5::Resources) {
+    r.BUFFER.release(r.DMA1).unwrap();
+
+    rtfm::bkpt();
+}
diff --git a/examples/usart2-tx-dma.rs b/examples/usart2-tx-dma.rs
new file mode 100644
index 0000000000000000000000000000000000000000..5d36f40f8fe3a4e0c0be328ec59f284918540437
--- /dev/null
+++ b/examples/usart2-tx-dma.rs
@@ -0,0 +1,52 @@
+//! Test sending serial data using the DMA
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![feature(const_fn)]
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate cortex_m_rtfm as rtfm;
+extern crate f4;
+
+use f4::Serial;
+use f4::dma::{Buffer, Dma1Channel6};
+use f4::time::Hertz;
+use rtfm::{app, Threshold};
+
+const BAUD_RATE: Hertz = Hertz(115_200);
+
+app! {
+    device: f4::stm32f40x,
+
+    resources: {
+        static BUFFER: Buffer<[u8; 15], Dma1Channel6> = Buffer::new([0; 15]);
+    },
+
+    tasks: {
+        DMA1_STREAM6: {
+            path: transfer_done,
+            resources: [BUFFER, DMA1],
+        },
+    },
+}
+
+fn init(p: init::Peripherals, r: init::Resources) {
+    let serial = Serial(p.USART2);
+
+    serial.init(BAUD_RATE.invert(), Some(p.DMA1), p.GPIOA, p.RCC);
+    r.BUFFER.borrow_mut().clone_from_slice(b"Hello, world!\r\n");
+
+    serial.write_all(p.DMA1, r.BUFFER).unwrap();
+}
+
+fn idle() -> ! {
+    loop {
+        rtfm::wfi();
+    }
+}
+
+fn transfer_done(_t: &mut Threshold, r: DMA1_STREAM6::Resources) {
+    r.BUFFER.release(r.DMA1).unwrap();
+
+    rtfm::bkpt();
+}
diff --git a/examples/ws2812.rs b/examples/ws2812.rs
index 5a9bb77561535f675dbb4084d6e32bfdc68ea8d3..7465d34b9805f1409ffbefa50be826fcc91b54a0 100644
--- a/examples/ws2812.rs
+++ b/examples/ws2812.rs
@@ -7,8 +7,8 @@
 #![feature(proc_macro)]
 #![no_std]
 
-extern crate f4;
 extern crate cortex_m_rtfm as rtfm;
+extern crate f4;
 #[macro_use]
 extern crate nb;
 
@@ -38,7 +38,15 @@ app! {
 fn init(p: init::Peripherals, r: init::Resources) {
     let pwm = Pwm(p.TIM3);
 
-    pwm.init(FREQUENCY.invert(), Channel::_1, Some(p.DMA1), p.GPIOA, p.GPIOB, p.GPIOC, p.RCC);
+    pwm.init(
+        FREQUENCY.invert(),
+        Channel::_1,
+        Some(p.DMA1),
+        p.GPIOA,
+        p.GPIOB,
+        p.GPIOC,
+        p.RCC,
+    );
     pwm.enable(Channel::_1);
 
     // end of frame
diff --git a/src/capture.rs b/src/capture.rs
index 44604d64c98d9719dac42b163974171d0fa96560..6f04cac67739e79d9f77540131bc8427ceaca786 100644
--- a/src/capture.rs
+++ b/src/capture.rs
@@ -36,7 +36,7 @@
 use core::any::{Any, TypeId};
 use core::u32;
 
-use cast::{u32};
+use cast::u32;
 use hal;
 use nb;
 use stm32f40x::{TIM1, TIM2, TIM3, TIM4, GPIOA, GPIOB, GPIOC, RCC};
diff --git a/src/clock.rs b/src/clock.rs
index 4b581212bbf9fab4b7163fe3de36ac57e61c1354..a1dc1caf5c29c9920f1bb5ff141e662d8802ff5a 100644
--- a/src/clock.rs
+++ b/src/clock.rs
@@ -37,8 +37,6 @@ fn calculate_pll(m: u8, n: u16, p: u8) -> (u32, u32) {
     (pll_bitmask, pll_output)
 }
 
-
-
 /// Set system clock
 pub fn set(rcc: &RCC, flash: &FLASH, m: u8, n: u16, p: u8) -> u32 {
     let (pll_bitmask, sysclk) = calculate_pll(m, n, p);
diff --git a/src/led.rs b/src/led.rs
index dc691f0a03ea912fce5d53c1497733b7eeb86a0f..bca68e662ee293ce0ca1672b989afcd22e681c2b 100644
--- a/src/led.rs
+++ b/src/led.rs
@@ -14,21 +14,21 @@ pub fn init(gpioa: &GPIOA, rcc: &RCC) {
     rcc.ahb1enr.modify(|_, w| w.gpioaen().set_bit());
 
     // configure PA5 as output
-    gpioa.moder.modify(|_,w| w.moder5().bits(1));
+    gpioa.moder.modify(|_, w| w.moder5().bits(1));
 }
 
 impl PA5 {
     /// Turns the LED on
     pub fn on(&self) {
         unsafe {
-            (*GPIOA.get()).odr.modify(|_,w| w.odr5().bit(true));
+            (*GPIOA.get()).odr.modify(|_, w| w.odr5().bit(true));
         }
     }
 
     /// Turns the LED off
     pub fn off(&self) {
         unsafe {
-            (*GPIOA.get()).odr.modify(|_,w| w.odr5().bit(false));
+            (*GPIOA.get()).odr.modify(|_, w| w.odr5().bit(false));
         }
     }
 }
diff --git a/src/pwm.rs b/src/pwm.rs
index 980cd5844c4195e45743b1e45993f67b2f4096ae..d741f1bfd2063b30a4400ddde746ff878445bb86 100644
--- a/src/pwm.rs
+++ b/src/pwm.rs
@@ -244,6 +244,7 @@ macro_rules! impl_Pwm {
 
                     if tim.get_type_id() == TypeId::of::<TIM3>() {
                         // TIM3_CH4/UP
+                        // chsel: Channel 5 (RM0368 9.3.3 Table 27)
                         // pl: Medium priority
                         // msize: Memory size = 8 bits
                         // psize: Peripheral size = 16 bits
@@ -254,7 +255,9 @@ macro_rules! impl_Pwm {
                         // tceie: Transfer complete interrupt enabled
                         // en: Disabled
                         dma1.s2cr.write(|w| unsafe {
-                            w.pl()
+                            w.chsel()
+                                .bits(5)
+                                .pl()
                                 .bits(0b01)
                                 .msize()
                                 .bits(0b00)
diff --git a/src/serial.rs b/src/serial.rs
index 254082011f9cc55e7725a46395d1ba3696a6850c..262d30a35fc1ef006cba9edb5476eca943e3fbb6 100644
--- a/src/serial.rs
+++ b/src/serial.rs
@@ -118,17 +118,19 @@ where
         // set output mode for GPIOA
         // PA2 = TX (output mode), PA3 = RX (input mode)
         if usart.get_type_id() == TypeId::of::<USART2>() {
-                // we don't care about the speed register atm
+            // we don't care about the speed register atm
             // DM00102166
             // AF7, Table 9
             // PA2 and PA3 is connected to USART2 TX and RX respectively
             gpio.afrl.modify(|_, w| w.afrl2().bits(7).afrl3().bits(7));
-            gpio.moder.modify(|_, w| w.moder2().bits(2).moder3().bits(2));
+            gpio.moder
+                .modify(|_, w| w.moder2().bits(2).moder3().bits(2));
         }
 
         if let Some(dma1) = dma1 {
             if usart.get_type_id() == TypeId::of::<USART2>() {
                 // TX DMA transfer
+                // chsel: Channel 4 (RM0368 9.3.3 Table 27)
                 // pl: Medium priority
                 // msize: Memory size = 8 bits
                 // psize: Peripheral size = 8 bits
@@ -136,10 +138,12 @@ where
                 // pinc: Peripheral increment mode disabled
                 // circ: Circular mode disabled
                 // dir: Transfer from memory to peripheral
-                // tceie: Transfer complete interrupt enabled
+                // tcie: Transfer complete interrupt enabled
                 // en: Disabled
                 dma1.s6cr.write(|w| unsafe {
-                    w.pl()
+                    w.chsel()
+                        .bits(4)
+                        .pl()
                         .bits(0b01)
                         .msize()
                         .bits(0b00)
@@ -160,6 +164,7 @@ where
                 });
 
                 // RX DMA transfer
+                // chsel: Channel 4 (RM0368 9.3.3 Table 27)
                 // pl: Medium priority
                 // msize: Memory size = 8 bits
                 // psize: Peripheral size = 8 bits
@@ -167,10 +172,12 @@ where
                 // pinc: Peripheral increment mode disabled
                 // circ: Circular mode disabled
                 // dir: Transfer from peripheral to memory
-                // tceie: Transfer complete interrupt enabled
+                // tcie: Transfer complete interrupt enabled
                 // en: Disabled
                 dma1.s5cr.write(|w| unsafe {
-                    w.pl()
+                    w.chsel()
+                        .bits(4)
+                        .pl()
                         .bits(0b01)
                         .msize()
                         .bits(0b00)