Skip to content
Snippets Groups Projects
Commit eff15834 authored by Johannes Sjölund's avatar Johannes Sjölund
Browse files

Usart DMA demo formats strings

parent 4e7c2ba0
Branches
No related tags found
No related merge requests found
...@@ -3,14 +3,17 @@ ...@@ -3,14 +3,17 @@
#![deny(warnings)] #![deny(warnings)]
#![feature(const_fn)] #![feature(const_fn)]
#![feature(proc_macro)] #![feature(proc_macro)]
#![feature(lang_items)]
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate f4; extern crate f4;
extern crate heapless; extern crate heapless;
use core::fmt::Write;
use core::ops::Deref; use core::ops::Deref;
use f4::Serial; use f4::Serial;
use f4::Writer as w;
use f4::prelude::*; use f4::prelude::*;
use f4::dma::{Buffer, Dma1Channel5, Dma1Channel6}; use f4::dma::{Buffer, Dma1Channel5, Dma1Channel6};
use f4::time::Hertz; use f4::time::Hertz;
...@@ -33,13 +36,14 @@ app! { ...@@ -33,13 +36,14 @@ app! {
static CMD_BUFFER: Vec<u8, [u8; MAX_CMD_LEN]> = Vec::new([0; MAX_CMD_LEN]); 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 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 TX_BUFFER: Buffer<[u8; MAX_TX_LEN], Dma1Channel6> = Buffer::new([0; MAX_TX_LEN]);
static CNT: u8 = 1;
}, },
tasks: { tasks: {
DMA1_STREAM5: { DMA1_STREAM5: {
path: rx_done, path: rx_done,
priority: 1, priority: 1,
resources: [CMD_BUFFER, RX_BUFFER, TX_BUFFER, DMA1, USART2], resources: [CMD_BUFFER, RX_BUFFER, TX_BUFFER, DMA1, USART2, CNT],
}, },
DMA1_STREAM6: { DMA1_STREAM6: {
path: tx_done, path: tx_done,
...@@ -48,15 +52,21 @@ app! { ...@@ -48,15 +52,21 @@ app! {
}, },
}, },
} }
fn init(p: init::Peripherals, r: init::Resources) { fn init(p: init::Peripherals, r: init::Resources) {
// There is no need to claim() resources in the init. // There is no need to claim() resources in the init.
// Start the serial port // Start the serial port
let serial = Serial(p.USART2); let serial = Serial(p.USART2);
serial.init(BAUD_RATE.invert(), Some(p.DMA1), p.GPIOA, p.RCC); 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(); serial.write_all(p.DMA1, r.TX_BUFFER).unwrap();
// Listen to serial input on the receive DMA // Listen to serial input on the receive DMA
serial.read_exact(p.DMA1, r.RX_BUFFER).unwrap(); serial.read_exact(p.DMA1, r.RX_BUFFER).unwrap();
} }
...@@ -102,7 +112,7 @@ fn rx_done(t: &mut Threshold, mut r: DMA1_STREAM5::Resources) { ...@@ -102,7 +112,7 @@ fn rx_done(t: &mut Threshold, mut r: DMA1_STREAM5::Resources) {
if byte == b'\r' { if byte == b'\r' {
// End of command // End of command
match &***cmd { match &***cmd {
b"hi" => { b"hi" | b"Hi" => {
say_hello = true; say_hello = true;
} }
_ => {} _ => {}
...@@ -118,11 +128,18 @@ fn rx_done(t: &mut Threshold, mut r: DMA1_STREAM5::Resources) { ...@@ -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 user wrote 'hi' and pressed enter, respond appropriately
if say_hello { 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, _| { r.TX_BUFFER.claim_mut(t, |tx, _| {
let array = &**tx.deref(); write!(
// We can only clone slices of equal length, else panic w::out(&mut (*tx).deref().borrow_mut()[..MAX_TX_LEN]),
array.borrow_mut()[..15].clone_from_slice(b"Hello, there!\r\n"); "Hello, there! {}\r\n",
cnt
).unwrap();
}); });
// Transmit the response // Transmit the response
r.TX_BUFFER.claim(t, |tx, t| { r.TX_BUFFER.claim(t, |tx, t| {
r.DMA1.claim(t, |dma, t| { r.DMA1.claim(t, |dma, t| {
...@@ -132,6 +149,7 @@ fn rx_done(t: &mut Threshold, mut r: DMA1_STREAM5::Resources) { ...@@ -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));
} }
} }
......
...@@ -50,6 +50,7 @@ use frequency::*; ...@@ -50,6 +50,7 @@ use frequency::*;
pub use hal::prelude; pub use hal::prelude;
pub use serial::Serial; pub use serial::Serial;
pub use serial::Writer;
pub use timer::{Channel, Timer}; pub use timer::{Channel, Timer};
pub use pwm::Pwm; pub use pwm::Pwm;
pub use capture::Capture; pub use capture::Capture;
......
...@@ -21,6 +21,40 @@ use stm32f40x::{gpioa, DMA1, USART2, usart6, GPIOA, RCC}; ...@@ -21,6 +21,40 @@ use stm32f40x::{gpioa, DMA1, USART2, usart6, GPIOA, RCC};
use dma::{self, Buffer, Dma1Channel5, Dma1Channel6}; 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 /// Specialized `Result` type
pub type Result<T> = ::core::result::Result<T, nb::Error<Error>>; pub type Result<T> = ::core::result::Result<T, nb::Error<Error>>;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment