diff --git a/src/dma.rs b/src/dma.rs index edd76b654559204da71e4434d71250f305f91941..fdec5c916e4893d6824a116e9f70aeb373e8806c 100644 --- a/src/dma.rs +++ b/src/dma.rs @@ -67,11 +67,10 @@ pub trait DmaExt { fn split(self, ahb: &mut AHB1) -> Self::Streams; } +// +// ndtr: u16, par: u32, m0: u32 pub unsafe trait StartTransfer { - fn start_transfer<A, B>(&mut self, B) - where - A: Unsize<[u8]>, - B: Static<A>; + fn _start_transfer(&mut self, u16, u32, u32); } pub struct Transfer<MODE, BUFFER, STREAM, PAYLOAD> { @@ -123,10 +122,14 @@ pub struct Output<MODE> { } // -pub unsafe trait UsartTxStream<USART> {} +pub unsafe trait UsartTxStream<USART> { + fn start_transfer(&mut self, ndtr: u16, par: u32, m0: u32); +} + pub unsafe trait UsartRxStream<USART> {} pub mod dma1 { + use core::sync::atomic::{self, Ordering}; use core::marker::{PhantomData, Unsize}; use cast::u16; @@ -191,7 +194,11 @@ pub mod dma1 { } } - unsafe impl super::UsartTxStream<USART2> for S6<C4> {} + unsafe impl super::UsartTxStream<USART2> for S6<C4> { + fn start_transfer(&mut self, ndtr: u16, par: u32, m0: u32) { + start_transfer_s6_c4(ndtr, par, m0); + } + } unsafe impl super::UsartRxStream<USART2> for S5<C4> {} unsafe impl super::UsartRxStream<USART2> for S7<C6> {} @@ -208,33 +215,20 @@ pub mod dma1 { } } - 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()) }) - }; - } + fn start_transfer_s6_c4(ndtr: u16, par: u32, m0: u32) { + let dma = unsafe { &*DMA1::ptr() }; + dma.s6ndtr.write(|w| unsafe { w.ndt().bits(ndtr) }); + dma.s6par.write(|w| unsafe { w.bits(par) }); + dma.s6m0ar.write(|w| unsafe { w.bits(m0) }); + dma.s6cr.modify(|_, w| w.en().set_bit()); } - // hifcr high interrupt flag clear register - // hisr high interrupt status register - // lifcr low interrupt flag clear register - // lisr low interrupt status register - - // impl<CHANNEL> S5<CHANNEL> - impl DmaExt for DMA1 { type Streams = Streams; - fn split(self, ahb: &mut AHB1) -> Streams { - // ahb.enr().modify(|_, w| w.$dmaXen().enabled()); + fn split(self, ahb1: &mut AHB1) -> Streams { + //ahb.ahb1enr().modify(|_, w| w.dma1en().set_bit()); + ahb1.enr().modify(|_, w| w.dma1en().set_bit()); // // reset the DMA control registers (stops all on-going transfers) // $( @@ -258,20 +252,20 @@ pub mod dma1 { 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 - // // to get to that state with our type safe API and *safe* Rust. - // while self.channel.isr().$tcifX().bit_is_clear() {} - - // self.channel.ifcr().write(|w| w.$cgifX().set_bit()); - - // self.channel.ccr().modify(|_, w| w.en().clear_bit()); - - // // TODO can we weaken this compiler barrier? - // // NOTE(compiler_fence) operations on `buffer` should not be reordered - // // before the previous statement, which marks the DMA transfer as done - // atomic::compiler_fence(Ordering::SeqCst); + // 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 + // to get to that state with our type safe API and *safe* Rust. + let dma = unsafe { &*DMA1::ptr() }; + + while dma.hisr.read().tcif6().bit_is_clear() {} + dma.hifcr.write(|w| w.ctcif6().set_bit()); + dma.s2cr.modify(|_, w| w.en().clear_bit()); + + // TODO can we weaken this compiler barrier? + // NOTE(compiler_fence) operations on `buffer` should not be reordered + // before the previous statement, which marks the DMA transfer as done + atomic::compiler_fence(Ordering::SeqCst); (self.buffer, self.stream, self.payload) } diff --git a/src/serial.rs b/src/serial.rs index e3e958c6ef407d68746191818419ad413e6f7b6b..5fa5335115348d03fed4bdaa37c285322611a47e 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -243,8 +243,8 @@ macro_rules! hal { } impl Tx<$USARTX> { pub fn write_all<A, B, S>( - self, - mut stream: S, + self, // should be mutable? + mut tx_stream: S, buffer: B, ) -> Transfer<R, B, S, Self> where @@ -253,7 +253,13 @@ macro_rules! hal { S: UsartTxStream<$USARTX> { { - let buffer1 :&[u8] = buffer.borrow(); + let buf :&[u8] = buffer.borrow(); + tx_stream.start_transfer( + u16(buf.len()).unwrap(), + unsafe { &(*$USARTX::ptr()).dr as *const _ as usize as u32 }, + buf.as_ptr() as u32 + ); + // stream.ndtr() // .write(|w| unsafe { w.ndt().bits(u16(buffer1.len()).unwrap()) }); // stream.par() @@ -302,7 +308,7 @@ macro_rules! hal { // }); } - Transfer::r(buffer, stream, self) + Transfer::r(buffer, tx_stream, self) } }