From 57c2c1e3f83ad04dd0e62e75c2e34e2ba48378ab Mon Sep 17 00:00:00 2001 From: Per Lindgren <per.lindgren@ltu.se> Date: Fri, 18 Jan 2019 22:53:36 +0100 Subject: [PATCH] eq implemented and tested --- .vscode/.cortex-debug.peripherals.state.json | 2 +- .vscode/launch.json | 32 +++ examples/bare8.rs | 12 +- examples/equivalence.rs | 200 +++++++++++-------- examples/marcus.rs | 12 +- 5 files changed, 165 insertions(+), 93 deletions(-) diff --git a/.vscode/.cortex-debug.peripherals.state.json b/.vscode/.cortex-debug.peripherals.state.json index e2f2139..0637a08 100644 --- a/.vscode/.cortex-debug.peripherals.state.json +++ b/.vscode/.cortex-debug.peripherals.state.json @@ -1 +1 @@ -[{"node":"UART9","expanded":true,"format":0},{"node":"USART2.SR","expanded":true,"format":0}] \ No newline at end of file +[] \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 6ff145f..43a8c5e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -733,5 +733,37 @@ "svdFile": "STM32F413.svd", "cwd": "${workspaceRoot}" }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "name": "equivalence (release)", + "preLaunchTask": "cargo build --example equivalence --release", + "executable": "./target/thumbv7em-none-eabihf/release/examples/equivalence", + "configFiles": [ + "interface/stlink.cfg", + "target/stm32f4x.cfg" + ], + "swoConfig": { + "enabled": true, + "cpuFrequency": 16000000, + "swoFrequency": 2000000, + "source": "probe", + "decoders": [ + { + "type": "console", + "label": "ITM0", + "port": 0 + }, + { + "type": "console", + "label": "ITM1", + "port": 1 + } + ] + }, + "svdFile": "STM32F413.svd", + "cwd": "${workspaceRoot}" + }, ] } \ No newline at end of file diff --git a/examples/bare8.rs b/examples/bare8.rs index c1a4ae8..f3bbc4b 100644 --- a/examples/bare8.rs +++ b/examples/bare8.rs @@ -11,7 +11,7 @@ extern crate panic_halt; -use cortex_m::iprintln; +use cortex_m::{asm, iprintln}; use nb::block; extern crate stm32f4xx_hal as hal; @@ -44,6 +44,8 @@ const APP: () = { let tx = gpioa.pa2.into_alternate_af7(); let rx = gpioa.pa3.into_alternate_af7(); // try comment out + asm::bkpt(); + let serial = Serial::usart2( device.USART2, (tx, rx), @@ -72,6 +74,7 @@ const APP: () = { match block!(rx.read()) { Ok(byte) => { iprintln!(stim, "Ok {:?}", byte); + test(byte); let _ = tx.write(byte); } Err(err) => { @@ -82,6 +85,13 @@ const APP: () = { } }; +#[inline(never)] +fn test(byte: u8) { + unsafe { + core::ptr::read_volatile(&byte); + } +} + // 1. Compile and run the example. // Verify that it has the same behavior as bare7. // diff --git a/examples/equivalence.rs b/examples/equivalence.rs index f629b00..7fa95cf 100644 --- a/examples/equivalence.rs +++ b/examples/equivalence.rs @@ -12,17 +12,16 @@ extern crate panic_halt; use cortex_m::{asm, iprintln}; extern crate stm32f4xx_hal as hal; -// use stm32f4::stm32f413::GPIOA; use crate::hal::prelude::*; use crate::hal::serial::{self, config::Config, Rx, Serial, Tx}; -use hal::{gpio::Alternate, gpio::AF0, stm32::ITM}; - -// use heapless::consts::*; -// use heapless::spsc::{Consumer, Producer, Queue}; +use hal::{ + gpio::{gpioa, Output, PushPull}, + stm32::ITM, +}; use nb::block; -use rtfm::{app, Instant}; +use rtfm::app; // Our error type #[derive(Debug)] @@ -32,22 +31,30 @@ pub enum Error { UsartReceiveOverflow, } -#[derive(Debug)] -pub enum Event { - Timout, - ChannelA, - ChannelB, -} - #[derive(Debug, Copy, Clone)] pub struct Data { a: bool, b: bool, - event_counter: u32, - out: bool, } -const TIMEOUT: u32 = 16_000_000; +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum State { + S8000, + S8001, + S8004, + S8014, + S8005, + C001, + C002, + C003, +} + +use State::*; + +const PERIOD: u32 = 16_000_000; +const DISCREPENCY: u32 = 10; +const T: bool = true; +const F: bool = false; #[app(device = hal::stm32)] const APP: () = { @@ -55,26 +62,15 @@ const APP: () = { static mut TX: Tx<hal::stm32::USART2> = (); static mut RX: Rx<hal::stm32::USART2> = (); static mut ITM: ITM = (); - static mut LED: hal::gpio::gpioa::PA5<Alternate<AF0>> = (); + static mut LED: gpioa::PA5<Output<PushPull>> = (); - // app resources - static mut DATA: Data = Data { - a: false, - b: false, - event_counter: 0, - out: false, - }; + static mut DATA: Data = Data { a: F, b: F }; // init runs in an interrupt free section> - #[init] + #[init(resources = [DATA], schedule = [periodic])] fn init() { let stim = &mut core.ITM.stim[0]; - iprintln!(stim, "start"); - - // power on GPIOA, RM0368 6.3.11 - device.RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit()); - // configure PA5 as output, RM0368 8.4.1 - device.GPIOA.moder.modify(|_, w| w.moder5().bits(1)); + iprintln!(stim, "start: {:?}", resources.DATA); let rcc = device.RCC.constrain(); @@ -85,7 +81,7 @@ const APP: () = { let tx = gpioa.pa2.into_alternate_af7(); let rx = gpioa.pa3.into_alternate_af7(); - let led = gpioa.pa5.into_alternate_af0(); + let led = gpioa.pa5.into_push_pull_output(); let mut serial = Serial::usart2( device.USART2, @@ -99,6 +95,8 @@ const APP: () = { serial.listen(serial::Event::Rxne); // Separate out the sender and receiver of the serial port let (tx, rx) = serial.split(); + // Start periodic task + schedule.periodic(start).unwrap(); // pass on late resources LED = led; @@ -132,7 +130,7 @@ const APP: () = { iprintln!(stim, "{:?}", error); } - #[interrupt(priority = 3, resources = [RX], spawn = [trace_data, trace_error, echo])] + #[interrupt(priority = 2, resources = [RX], spawn = [trace_data, trace_error, echo])] fn USART2() { match resources.RX.read() { Ok(byte) => { @@ -141,13 +139,11 @@ const APP: () = { spawn.trace_error(Error::RingBufferOverflow).unwrap(); } } - Err(_err) => { - spawn.trace_error(Error::UsartReceiveOverflow).unwrap() - } + Err(_err) => spawn.trace_error(Error::UsartReceiveOverflow).unwrap(), } } - #[task(priority = 2, resources = [TX], spawn = [trace_error, event_a, event_b])] + #[task(priority = 1, resources = [TX, DATA], spawn = [trace_error])] fn echo(byte: u8) { let tx = resources.TX; @@ -155,61 +151,101 @@ const APP: () = { spawn.trace_error(Error::UsartSendOverflow).unwrap(); } + let mut data = resources.DATA; + match byte { - b'a' => spawn.event_a(false).unwrap(), - b'b' => spawn.event_b(false).unwrap(), - b'A' => spawn.event_a(true).unwrap(), - b'B' => spawn.event_b(true).unwrap(), + b'a' => data.a = false, + b'b' => data.b = false, + b'A' => data.a = true, + b'B' => data.b = true, _ => (), } } - #[task(priority = 1, resources = [ITM, DATA], schedule = [discrepency])] - fn event_a(val: bool) { - let stim = &mut resources.ITM.stim[0]; - iprintln!(stim, "event a {}", val); - - let data = &mut resources.DATA; - data.a = val; - // evaluate equivalenc. - data.event_counter += 1; - if data.a ^ data.b { - schedule - .discrepency(scheduled + TIMEOUT.cycles(), data.clone()) - .unwrap(); - data.out = false; - iprintln!(stim, "disc {:?}", data); - } - } - - #[task(priority = 1, resources = [ITM, DATA], spawn = [discrepency])] - fn event_b(val: bool) { - let stim = &mut resources.ITM.stim[0]; - iprintln!(stim, "event b {}", val); - //evaluate_equivalence(scheduled, &mut resources.DATA); - } - - #[task(priority = 1, resources = [ITM, DATA])] - fn discrepency(data: Data) { - let stim = &mut resources.ITM.stim[0]; - iprintln!(stim, "a {} b {}", data.a, data.b); - if data.event_counter == resources.DATA.event_counter { - iprintln!(stim, "timeout"); - // data.force_reinit = - } - } - - #[task (priority = 1, resources = [LED])] + #[task (priority = 1, resources = [LED, ITM, DATA], schedule = [periodic])] fn periodic() { - static mut TOGGLE: bool = false; + // we start directly in the init state S80001 + static mut STATE: State = State::S8001; + static mut TIMEOUT: u32 = 0; - if *TOGGLE { - resources.LED.set_low(); - } else { + let stim = &mut resources.ITM.stim[0]; + let data = resources.DATA; + + iprintln!(stim, "Old State {:?}", STATE); + iprintln!(stim, "Timeout {:?}", TIMEOUT); + iprintln!(stim, "{:?}", data); + + *STATE = match STATE { + S8000 => match (data.a, data.b) { + (F, F) => S8001, + (F, T) | (T, F) => { + *TIMEOUT = DISCREPENCY; + S8005 + } + (T, T) => S8000, + }, + S8001 => match (data.a, data.b) { + (F, F) => S8001, + (F, T) => { + *TIMEOUT = DISCREPENCY; + S8014 + } + (T, F) => { + *TIMEOUT = DISCREPENCY; + S8004 + } + (T, T) => S8000, + }, + S8004 => { + *TIMEOUT -= 1; + match *TIMEOUT { + 0 => C001, + _ => match (data.a, data.b) { + (F, _) => S8001, + (_, T) => S8000, + _ => S8004, + }, + } + } + S8014 => { + *TIMEOUT -= 1; + match *TIMEOUT { + 0 => C002, + _ => match (data.a, data.b) { + (_, F) => S8001, + (T, _) => S8000, + _ => S8014, + }, + } + } + S8005 => { + *TIMEOUT -= 1; + match *TIMEOUT { + 0 => C003, + _ => match (data.a, data.b) { + (F, F) => S8001, + _ => S8005, + }, + } + } + C001 | C002 => match (data.a, data.b) { + (F, F) => S8001, + _ => C002, + }, + C003 => match (data.a, data.b) { + (F, F) => S8001, + _ => C003, + }, + }; + iprintln!(stim, "New State {:?}\n", STATE); + + if *STATE == S8000 { resources.LED.set_high(); + } else { + resources.LED.set_low(); } - *TOGGLE = !*TOGGLE; + schedule.periodic(scheduled + PERIOD.cycles()).unwrap(); } extern "C" { diff --git a/examples/marcus.rs b/examples/marcus.rs index 0114062..abf8e81 100644 --- a/examples/marcus.rs +++ b/examples/marcus.rs @@ -16,9 +16,6 @@ use crate::hal::prelude::*; use crate::hal::serial::{self, config::Config, Rx, Serial, Tx}; use hal::stm32::ITM; -// use heapless::consts::*; -// use heapless::spsc::{Consumer, Producer, Queue}; - use nb::block; use rtfm::{app, Instant}; @@ -144,9 +141,7 @@ const APP: () = { spawn.trace_error(Error::RingBufferOverflow).unwrap(); } } - Err(_err) => { - spawn.trace_error(Error::UsartReceiveOverflow).unwrap() - } + Err(_err) => spawn.trace_error(Error::UsartReceiveOverflow).unwrap(), } } @@ -172,7 +167,6 @@ const APP: () = { let stim = &mut resources.ITM.stim[0]; iprintln!(stim, "event a {}", val); - let data = &mut resources.DATA; data.a = val; iprintln!(stim, "Start {:?}", data); @@ -266,7 +260,7 @@ const APP: () = { let data = &mut resources.DATA; data.b = val; iprintln!(stim, "Start {:?}", data); - + match data.state { State::S8000 => { if data.a ^ data.b { @@ -347,7 +341,7 @@ const APP: () = { } #[task(priority = 1, resources = [ITM])] - fn discrepency(counter: u32, state:State) { + fn discrepency(counter: u32, state: State) { let stim = &mut resources.ITM.stim[0]; iprintln!(stim, "counter {} state {:?}", counter, state); // if data.event_counter == resources.DATA.event_counter { -- GitLab