diff --git a/examples/usart2-dma.rs b/examples/usart2-dma.rs index e49e4abd76c78fca8e4d78d7adcaad25a324d99e..1e946cd3ce12291d0b121b91aada7b07750048e1 100644 --- a/examples/usart2-dma.rs +++ b/examples/usart2-dma.rs @@ -3,14 +3,17 @@ #![deny(warnings)] #![feature(const_fn)] #![feature(proc_macro)] +#![feature(lang_items)] #![no_std] extern crate cortex_m_rtfm as rtfm; extern crate f4; extern crate heapless; +use core::fmt::Write; use core::ops::Deref; use f4::Serial; +use f4::Writer as w; use f4::prelude::*; use f4::dma::{Buffer, Dma1Channel5, Dma1Channel6}; use f4::time::Hertz; @@ -33,13 +36,14 @@ app! { static CMD_BUFFER: Vec<u8, [u8; MAX_CMD_LEN]> = Vec::new([0; MAX_CMD_LEN]); static RX_BUFFER: Buffer<[u8; MAX_RX_LEN], Dma1Channel5> = Buffer::new([0; MAX_RX_LEN]); static TX_BUFFER: Buffer<[u8; MAX_TX_LEN], Dma1Channel6> = Buffer::new([0; MAX_TX_LEN]); + static CNT: u8 = 1; }, tasks: { DMA1_STREAM5: { path: rx_done, priority: 1, - resources: [CMD_BUFFER, RX_BUFFER, TX_BUFFER, DMA1, USART2], + resources: [CMD_BUFFER, RX_BUFFER, TX_BUFFER, DMA1, USART2, CNT], }, DMA1_STREAM6: { path: tx_done, @@ -48,15 +52,21 @@ app! { }, }, } - fn init(p: init::Peripherals, r: init::Resources) { // There is no need to claim() resources in the init. // Start the serial port let serial = Serial(p.USART2); serial.init(BAUD_RATE.invert(), Some(p.DMA1), p.GPIOA, p.RCC); - // Send a welcome message. We can only clone slices of equal length, else panic. - r.TX_BUFFER.borrow_mut()[..15].clone_from_slice(b"Hello, world!\r\n"); + + // Send a welcome message by borrowing transmit buffer and writing a formatted string into it + let x = 1.0; + write!( + w::out(&mut r.TX_BUFFER.borrow_mut()[..MAX_TX_LEN]), + "Hello, world! {}\r\n", + x + ).unwrap(); serial.write_all(p.DMA1, r.TX_BUFFER).unwrap(); + // Listen to serial input on the receive DMA serial.read_exact(p.DMA1, r.RX_BUFFER).unwrap(); } @@ -102,7 +112,7 @@ fn rx_done(t: &mut Threshold, mut r: DMA1_STREAM5::Resources) { if byte == b'\r' { // End of command match &***cmd { - b"hi" => { + b"hi" | b"Hi" => { say_hello = true; } _ => {} @@ -118,11 +128,18 @@ fn rx_done(t: &mut Threshold, mut r: DMA1_STREAM5::Resources) { }); // If user wrote 'hi' and pressed enter, respond appropriately if say_hello { + // Increment 'hi' counter + **r.CNT = **r.CNT + 1; + let cnt: u8 = **r.CNT; + // Claim the transmit buffer and write a formatted string into it r.TX_BUFFER.claim_mut(t, |tx, _| { - let array = &**tx.deref(); - // We can only clone slices of equal length, else panic - array.borrow_mut()[..15].clone_from_slice(b"Hello, there!\r\n"); + write!( + w::out(&mut (*tx).deref().borrow_mut()[..MAX_TX_LEN]), + "Hello, there! {}\r\n", + cnt + ).unwrap(); }); + // Transmit the response r.TX_BUFFER.claim(t, |tx, t| { r.DMA1.claim(t, |dma, t| { @@ -132,6 +149,7 @@ fn rx_done(t: &mut Threshold, mut r: DMA1_STREAM5::Resources) { }); }); }); + // r.CNT.claim_mut(t, |cnt,_| cnt.wrapping_add(1)); } } @@ -147,4 +165,4 @@ fn tx_done(t: &mut Threshold, r: DMA1_STREAM6::Resources) { let array = &**tx.deref(); array.borrow_mut()[..MAX_TX_LEN].clone_from_slice(&[0; MAX_TX_LEN]); }); -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index e8b7554749979033079e4eabf92f2d2f73bb2641..25060109bf0bf1dd19f2fb9bdc4f2a8b8a549281 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,6 +50,7 @@ use frequency::*; pub use hal::prelude; pub use serial::Serial; +pub use serial::Writer; pub use timer::{Channel, Timer}; pub use pwm::Pwm; pub use capture::Capture; diff --git a/src/serial.rs b/src/serial.rs index 262d30a35fc1ef006cba9edb5476eca943e3fbb6..c0f7e824b59d1d806f1d7fdbdc97d7910aa1452f 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -21,6 +21,40 @@ use stm32f40x::{gpioa, DMA1, USART2, usart6, GPIOA, RCC}; use dma::{self, Buffer, Dma1Channel5, Dma1Channel6}; +use core::fmt; +use core::iter; + +/// +pub struct Writer<'a> { + buf: &'a mut [u8], + offset: usize, +} + +impl<'a> Writer<'a> { + /// + pub fn out(buf: &'a mut [u8]) -> Self { + Writer { + buf: buf, + offset: 0, + } + } +} + +impl<'a> fmt::Write for Writer<'a> { + fn write_str(&mut self, s: &str) -> fmt::Result { + let bytes = s.as_bytes(); + // Skip over already-copied data + let remainder = &mut self.buf[self.offset..]; + // Make the two slices the same length + let remainder = &mut remainder[..bytes.len()]; + // Copy + remainder.copy_from_slice(bytes); + // Increment offset by number of copied bytes + self.offset += bytes.len(); + Ok(()) + } +} + /// Specialized `Result` type pub type Result<T> = ::core::result::Result<T, nb::Error<Error>>;