diff --git a/examples/bare10.rs b/examples/bare10.rs new file mode 100644 index 0000000000000000000000000000000000000000..2f39b89373a2b3a270932f4f66f77770f466757d --- /dev/null +++ b/examples/bare10.rs @@ -0,0 +1,124 @@ +//! The RTFM framework +//! +//! What it covers: +//! - Priority based scheduling +//! - Message passing + +#![no_main] +#![no_std] + +extern crate panic_halt; + +use cortex_m::{asm, iprintln}; + +extern crate stm32f4xx_hal as hal; +use crate::hal::prelude::*; +use crate::hal::serial::{config::Config, Event, Rx, Serial, Tx}; +use hal::stm32::ITM; + +use nb::block; +use rtfm::app; + +// Our error type +#[derive(Debug)] +pub enum Error { + RingBufferOverflow, + UsartSendOverflow, + UsartReceiveOverflow, +} + +#[app(device = hal::stm32)] +const APP: () = { + // Late resources + static mut TX: Tx<hal::stm32::USART2> = (); + static mut RX: Rx<hal::stm32::USART2> = (); + static mut ITM: ITM = (); + + // init runs in an interrupt free section> + #[init] + fn init() { + let stim = &mut core.ITM.stim[0]; + iprintln!(stim, "start"); + + let rcc = device.RCC.constrain(); + + // 16 MHz (default, all clocks) + let clocks = rcc.cfgr.freeze(); + + let gpioa = device.GPIOA.split(); + + let tx = gpioa.pa2.into_alternate_af7(); + let rx = gpioa.pa3.into_alternate_af7(); // try comment out + + let mut serial = Serial::usart2( + device.USART2, + (tx, rx), + Config::default().baudrate(115_200.bps()), + clocks, + ) + .unwrap(); + + // generate interrupt on Rxne + serial.listen(Event::Rxne); + // Separate out the sender and receiver of the serial port + let (tx, rx) = serial.split(); + + // Our split serial + TX = tx; + RX = rx; + + // For debugging + ITM = core.ITM; + } + + // idle may be interrupted by other interrupt/tasks in the system + #[idle] + fn idle() -> ! { + loop { + asm::wfi(); + } + } + + #[task(priority = 1, resources = [ITM])] + fn trace_data(byte: u8) { + let stim = &mut resources.ITM.stim[0]; + iprintln!(stim, "data {}", byte); + } + + #[task(priority = 1, resources = [ITM])] + fn trace_error(error: Error) { + let stim = &mut resources.ITM.stim[0]; + iprintln!(stim, "{:?}", error); + } + + #[task(priority = 2, resources = [TX], spawn = [trace_error])] + fn echo(byte: u8) { + let tx = resources.TX; + + if block!(tx.write(byte)).is_err() { + spawn.trace_error(Error::UsartSendOverflow).unwrap(); + } + } + + #[interrupt(priority = 3, resources = [RX], spawn = [trace_data, trace_error, echo])] + fn USART2() { + let rx = resources.RX; + + match rx.read() { + Ok(byte) => { + spawn.echo(byte).unwrap(); + if spawn.trace_data(byte).is_err() { + spawn.trace_error(Error::RingBufferOverflow).unwrap(); + } + } + Err(_err) => { + spawn.trace_error(Error::UsartReceiveOverflow).unwrap() + } + } + } + + extern "C" { + fn EXTI0(); + fn EXTI1(); + } +};