Skip to content

Instantly share code, notes, and snippets.

@therealprof
Created January 29, 2019 16:19
Show Gist options
  • Save therealprof/f97fdfc9ee8b5de9e00149c8fded5a08 to your computer and use it in GitHub Desktop.
Save therealprof/f97fdfc9ee8b5de9e00149c8fded5a08 to your computer and use it in GitHub Desktop.
#![no_main]
#![no_std]
extern crate cortex_m;
extern crate cortex_m_rt;
extern crate stm32f407g_disc as board;
#[macro_use(block)]
extern crate nb;
#[macro_use]
extern crate log;
use log::{Level, LevelFilter, Metadata, Record};
use board::hal::prelude::*;
use board::hal::stm32;
use board::hal::serial::{config::Config, Serial};
use cortex_m_rt::entry;
use core::cell::RefCell;
use core::ops::DerefMut;
use cortex_m::interrupt::Mutex;
use core::fmt::Write;
// Make the write part of our serial port globally available
static SERIAL: Mutex<RefCell<Option<board::serial::Tx<board::USART2>>>> =
Mutex::new(RefCell::new(None));
struct SerialLogger {}
impl log::Log for SerialLogger {
fn enabled(&self, _metadata: &Metadata) -> bool {
true
}
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
cortex_m::interrupt::free(|cs| {
// Obtain mutex protected write part of serial port
if let &mut Some(ref mut tx) = SERIAL.borrow(cs).borrow_mut().deref_mut() {
writeln!(tx, "\r\n{} - {}\r", record.level(), record.args()).unwrap();
}
});
}
}
fn flush(&self) {}
}
use core::panic::PanicInfo;
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
error!("{}", info);
loop {}
}
#[entry]
fn main() -> ! {
if let Some(p) = stm32::Peripherals::take() {
let gpioa = p.GPIOA.split();
let mut rcc = p.RCC.constrain();
let clocks = rcc.cfgr.sysclk(48.mhz()).freeze();
// USART2 at PA2 (TX) and PA3(RX) are connected to ST-Link
// (well, not really, you're supposed to wire them yourself!)
let tx = gpioa.pa2.into_alternate_af7();
let rx = gpioa.pa3.into_alternate_af7();
// Set up USART 2 configured pins and a baudrate of 115200 baud
let serial = Serial::usart2(
p.USART2,
(tx, rx),
Config::default().baudrate(115_200.bps()),
clocks,
)
.unwrap();
// Separate out the sender and receiver of the serial port
let (mut tx, mut rx) = serial.split();
// Transfer write part of serial port into Mutex
cortex_m::interrupt::free(|cs| {
*SERIAL.borrow(cs).borrow_mut() = Some(tx);
});
// Create a new logger using the just transferred serial port
log::set_logger(&SerialLogger {}).unwrap();
log::set_max_level(LevelFilter::Trace);
log!(Level::Info, "Welcome to this demo!");
log!(
Level::Info,
"Type a few characters to see this application crash..."
);
let mut counter = 0;
loop {
// Read character and echo it back
let received = block!(rx.read()).unwrap();
// Obtain write part of serial port via Mutex
cortex_m::interrupt::free(|cs| {
if let &mut Some(ref mut tx) = SERIAL.borrow(cs).borrow_mut().deref_mut() {
block!(tx.write(received)).ok();
}
});
// Increment counter
counter += 1;
// Panic after 20 bytes written
if counter > 20 {
panic!("Too many bytes written!");
}
}
}
loop {
continue;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment