diff --git a/examples/serial-dma-tx.rs b/examples/serial-dma-tx.rs
index f9087ae91a9257aa4788f45fade820d54e393119..40cc1df827396910178cbbdaa38a56def9819afa 100644
--- a/examples/serial-dma-tx.rs
+++ b/examples/serial-dma-tx.rs
@@ -19,7 +19,7 @@ fn main() {
     let mut rcc = p.RCC.constrain();
     let mut gpioa = p.GPIOA.split(&mut rcc.ahb1);
     let streams = p.DMA1.split(&mut rcc.ahb1);
-    let tx_stream = streams.1.into_channel4(); // S5<C4>
+    let tx_stream = streams.1.into_channel4(); // S6<C4>
 
     let clocks = rcc.cfgr.freeze(&mut flash.acr);
 
diff --git a/src/dma.rs b/src/dma.rs
index 4754ced1883d272936f0df7edb3054a1bf21bc1d..edd76b654559204da71e4434d71250f305f91941 100644
--- a/src/dma.rs
+++ b/src/dma.rs
@@ -2,7 +2,7 @@
 #![allow(unused_code)]
 #![allow(missing_docs)]
 
-use core::marker::PhantomData;
+use core::marker::{PhantomData, Unsize};
 use core::ops;
 
 use rcc::AHB1;
@@ -68,27 +68,10 @@ pub trait DmaExt {
 }
 
 pub unsafe trait StartTransfer {
-    fn start_transfer(&mut self);
-}
-
-pub trait Dma {
-    // sXcr 	stream x configuration register
-    fn cr(&mut self) -> &dma2::S5CR;
-
-    // sXfcr 	stream x FIFO control register
-    fn fcr(&mut self) -> &dma2::S5FCR;
-
-    // sXm0ar 	stream x memory 0 address register
-    fn m0ar(&mut self) -> &dma2::S5M0AR;
-
-    // sXm1ar 	stream x memory 0 address register
-    fn m1ar(&mut self) -> &dma2::S5M1AR;
-
-    // sXndtr 	stream x number of data register
-    fn ndtr(&mut self) -> &dma2::S5NDTR;
-
-    // sXpar 	stream x peripheral address register
-    fn par(&mut self) -> &dma2::S5PAR;
+    fn start_transfer<A, B>(&mut self, B)
+    where
+        A: Unsize<[u8]>,
+        B: Static<A>;
 }
 
 pub struct Transfer<MODE, BUFFER, STREAM, PAYLOAD> {
@@ -140,22 +123,23 @@ pub struct Output<MODE> {
 }
 
 //
-pub unsafe trait Usart1TxStream<USART> {}
+pub unsafe trait UsartTxStream<USART> {}
+pub unsafe trait UsartRxStream<USART> {}
 
 pub mod dma1 {
-    use core::marker::PhantomData;
+    use core::marker::{PhantomData, Unsize};
+
+    use cast::u16;
     use stm32f4x::{DMA1, dma2};
     use stm32f4x::USART2;
     use dma::{CircBuffer, DmaExt, Error, Event, Half, Transfer};
     use rcc::AHB1;
 
-    // Stream === Pin
+    // Stream
     pub struct S0<CHANNEL> {
         _channel: PhantomData<CHANNEL>,
     }
-    // pub struct S1<CHANNEL> {}
-    // pub struct S2<CHANNEL> {}
-    // pub struct S3<CHANNEL> {}
+
     pub struct S4<CHANNEL> {
         _channel: PhantomData<CHANNEL>,
     }
@@ -165,6 +149,9 @@ pub mod dma1 {
     pub struct S6<CHANNEL> {
         _channel: PhantomData<CHANNEL>,
     }
+    pub struct S7<CHANNEL> {
+        _channel: PhantomData<CHANNEL>,
+    }
     //pub struct S7<CHANNEL> {}
 
     // Channels === Alternate function
@@ -188,9 +175,27 @@ pub mod dma1 {
         }
     }
 
-    unsafe impl super::Usart1TxStream<USART2> for S5<C4> {}
+    impl<CHANNEL> S6<CHANNEL> {
+        pub fn into_channel4(self) -> S6<C4> {
+            S6 {
+                _channel: PhantomData,
+            }
+        }
+    }
 
-    pub struct Streams(pub S4<C0>, pub S5<C0>);
+    impl<CHANNEL> S7<CHANNEL> {
+        pub fn into_channel6(self) -> S7<C6> {
+            S7 {
+                _channel: PhantomData,
+            }
+        }
+    }
+
+    unsafe impl super::UsartTxStream<USART2> for S6<C4> {}
+    unsafe impl super::UsartRxStream<USART2> for S5<C4> {}
+    unsafe impl super::UsartRxStream<USART2> for S7<C6> {}
+
+    pub struct Streams(pub S5<C0>, pub S6<C0>, pub S7<C0>);
 
     impl<CHANNEL> S5<CHANNEL> {
         pub fn listen(&mut self, event: Event) {
@@ -203,10 +208,18 @@ pub mod dma1 {
         }
     }
 
-    unsafe impl<CHANNEL> super::StartTransfer for S0<CHANNEL> {
-        fn start_transfer(&mut self) {
-            // self.cr().write(..);
-            // self.cndtr().write(..);
+    unsafe impl super::StartTransfer for S6<C4> {
+        fn start_transfer<A, B>(&mut self, buffer: B)
+        where
+            A: Unsize<[u8]>,
+            B: super::Static<A>,
+        {
+            let buf: &[u8] = buffer.borrow();
+            unsafe {
+                (*DMA1::ptr())
+                    .s6ndtr
+                    .write(|w| unsafe { w.ndt().bits(u16(buf.len()).unwrap()) })
+            };
         }
     }
 
@@ -215,38 +228,7 @@ pub mod dma1 {
     // lifcr 	low interrupt flag clear register
     // lisr 	low interrupt status register
 
-    //    impl<CHANNEL> S5<CHANNEL> {
-    impl super::Dma for S5<C4> {
-        // sXcr 	stream x configuration register
-        fn cr(&mut self) -> &dma2::S5CR {
-            unsafe { &(*DMA1::ptr()).s5cr }
-        }
-
-        // sXfcr 	stream x FIFO control register
-        fn fcr(&mut self) -> &dma2::S5FCR {
-            unsafe { &(*DMA1::ptr()).s5fcr }
-        }
-
-        // sXm0ar 	stream x memory 0 address register
-        fn m0ar(&mut self) -> &dma2::S5M0AR {
-            unsafe { &(*DMA1::ptr()).s5m0ar }
-        }
-
-        // sXm1ar 	stream x memory 0 address register
-        fn m1ar(&mut self) -> &dma2::S5M1AR {
-            unsafe { &(*DMA1::ptr()).s5m1ar }
-        }
-
-        // sXndtr 	stream x number of data register
-        fn ndtr(&mut self) -> &dma2::S5NDTR {
-            unsafe { &(*DMA1::ptr()).s5ndtr }
-        }
-
-        // sXpar 	stream x peripheral address register
-        fn par(&mut self) -> &dma2::S5PAR {
-            unsafe { &(*DMA1::ptr()).s5par }
-        }
-    }
+    //    impl<CHANNEL> S5<CHANNEL>
 
     impl DmaExt for DMA1 {
         type Streams = Streams;
@@ -261,18 +243,21 @@ pub mod dma1 {
 
             // Channels((), $($CX { _0: () }),+)
             Streams(
-                S4 {
+                S5 {
                     _channel: PhantomData,
                 },
-                S5 {
+                S6 {
+                    _channel: PhantomData,
+                },
+                S7 {
                     _channel: PhantomData,
                 },
             )
         }
     }
 
-    impl<BUFFER, PAYLOAD, MODE> Transfer<MODE, BUFFER, S5<C4>, PAYLOAD> {
-        pub fn wait(mut self) -> (BUFFER, S5<C4>, PAYLOAD) {
+    impl<BUFFER, PAYLOAD, MODE> Transfer<MODE, BUFFER, S6<C4>, PAYLOAD> {
+        pub fn wait(mut self) -> (BUFFER, S6<C4>, PAYLOAD) {
             // // XXX should we check for transfer errors here?
             // // The manual says "A DMA transfer error can be generated by reading
             // // from or writing to a reserved address space". I think it's impossible
diff --git a/src/serial.rs b/src/serial.rs
index dad679f4a5b2dec281306b6e07430fe254d13acc..e3e958c6ef407d68746191818419ad413e6f7b6b 100644
--- a/src/serial.rs
+++ b/src/serial.rs
@@ -13,7 +13,7 @@ use cast::u16;
 use hal::serial;
 use nb;
 use stm32f4x::{USART1, USART2, USART6};
-use dma::{Dma, Static, Transfer, Usart1TxStream, R};
+use dma::{Static, Transfer, UsartTxStream, R};
 
 // usart2
 use gpio::gpioa::{PA2, PA3};
@@ -250,16 +250,16 @@ macro_rules! hal {
                 where
                     A: Unsize<[u8]>,
                     B: Static<A>,
-                    S: Usart1TxStream<$USARTX> + Dma
+                    S: UsartTxStream<$USARTX>
                 {
                     {
                         let buffer1 :&[u8] = buffer.borrow();
-                        stream.ndtr()
-                            .write(|w| unsafe { w.ndt().bits(u16(buffer1.len()).unwrap()) });
-                        stream.par()
-                            .write(|w| unsafe { w.bits(&(*$USARTX::ptr()).dr as *const _ as usize as u32) });
-                        stream.m0ar()
-                            .write(|w| unsafe { w.bits(buffer1.as_ptr() as u32) });
+                        // stream.ndtr()
+                        //     .write(|w| unsafe { w.ndt().bits(u16(buffer1.len()).unwrap()) });
+                        // stream.par()
+                        //     .write(|w| unsafe { w.bits(&(*$USARTX::ptr()).dr as *const _ as usize as u32) });
+                        // stream.m0ar()
+                        //     .write(|w| unsafe { w.bits(buffer1.as_ptr() as u32) });
                     // dma1.s6cr.modify(|_, w| w.en().set_bit());