Skip to content
Snippets Groups Projects
Commit 57c2c1e3 authored by Per Lindgren's avatar Per Lindgren
Browse files

eq implemented and tested

parent 032a54c7
No related branches found
No related tags found
No related merge requests found
[{"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
...@@ -733,5 +733,37 @@ ...@@ -733,5 +733,37 @@
"svdFile": "STM32F413.svd", "svdFile": "STM32F413.svd",
"cwd": "${workspaceRoot}" "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
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
extern crate panic_halt; extern crate panic_halt;
use cortex_m::iprintln; use cortex_m::{asm, iprintln};
use nb::block; use nb::block;
extern crate stm32f4xx_hal as hal; extern crate stm32f4xx_hal as hal;
...@@ -44,6 +44,8 @@ const APP: () = { ...@@ -44,6 +44,8 @@ const APP: () = {
let tx = gpioa.pa2.into_alternate_af7(); let tx = gpioa.pa2.into_alternate_af7();
let rx = gpioa.pa3.into_alternate_af7(); // try comment out let rx = gpioa.pa3.into_alternate_af7(); // try comment out
asm::bkpt();
let serial = Serial::usart2( let serial = Serial::usart2(
device.USART2, device.USART2,
(tx, rx), (tx, rx),
...@@ -72,6 +74,7 @@ const APP: () = { ...@@ -72,6 +74,7 @@ const APP: () = {
match block!(rx.read()) { match block!(rx.read()) {
Ok(byte) => { Ok(byte) => {
iprintln!(stim, "Ok {:?}", byte); iprintln!(stim, "Ok {:?}", byte);
test(byte);
let _ = tx.write(byte); let _ = tx.write(byte);
} }
Err(err) => { Err(err) => {
...@@ -82,6 +85,13 @@ const APP: () = { ...@@ -82,6 +85,13 @@ const APP: () = {
} }
}; };
#[inline(never)]
fn test(byte: u8) {
unsafe {
core::ptr::read_volatile(&byte);
}
}
// 1. Compile and run the example. // 1. Compile and run the example.
// Verify that it has the same behavior as bare7. // Verify that it has the same behavior as bare7.
// //
......
...@@ -12,17 +12,16 @@ extern crate panic_halt; ...@@ -12,17 +12,16 @@ extern crate panic_halt;
use cortex_m::{asm, iprintln}; use cortex_m::{asm, iprintln};
extern crate stm32f4xx_hal as hal; extern crate stm32f4xx_hal as hal;
// use stm32f4::stm32f413::GPIOA;
use crate::hal::prelude::*; use crate::hal::prelude::*;
use crate::hal::serial::{self, config::Config, Rx, Serial, Tx}; use crate::hal::serial::{self, config::Config, Rx, Serial, Tx};
use hal::{gpio::Alternate, gpio::AF0, stm32::ITM}; use hal::{
gpio::{gpioa, Output, PushPull},
// use heapless::consts::*; stm32::ITM,
// use heapless::spsc::{Consumer, Producer, Queue}; };
use nb::block; use nb::block;
use rtfm::{app, Instant}; use rtfm::app;
// Our error type // Our error type
#[derive(Debug)] #[derive(Debug)]
...@@ -32,22 +31,30 @@ pub enum Error { ...@@ -32,22 +31,30 @@ pub enum Error {
UsartReceiveOverflow, UsartReceiveOverflow,
} }
#[derive(Debug)]
pub enum Event {
Timout,
ChannelA,
ChannelB,
}
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Data { pub struct Data {
a: bool, a: bool,
b: 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)] #[app(device = hal::stm32)]
const APP: () = { const APP: () = {
...@@ -55,26 +62,15 @@ const APP: () = { ...@@ -55,26 +62,15 @@ const APP: () = {
static mut TX: Tx<hal::stm32::USART2> = (); static mut TX: Tx<hal::stm32::USART2> = ();
static mut RX: Rx<hal::stm32::USART2> = (); static mut RX: Rx<hal::stm32::USART2> = ();
static mut ITM: ITM = (); 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: F, b: F };
static mut DATA: Data = Data {
a: false,
b: false,
event_counter: 0,
out: false,
};
// init runs in an interrupt free section> // init runs in an interrupt free section>
#[init] #[init(resources = [DATA], schedule = [periodic])]
fn init() { fn init() {
let stim = &mut core.ITM.stim[0]; let stim = &mut core.ITM.stim[0];
iprintln!(stim, "start"); iprintln!(stim, "start: {:?}", resources.DATA);
// 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));
let rcc = device.RCC.constrain(); let rcc = device.RCC.constrain();
...@@ -85,7 +81,7 @@ const APP: () = { ...@@ -85,7 +81,7 @@ const APP: () = {
let tx = gpioa.pa2.into_alternate_af7(); let tx = gpioa.pa2.into_alternate_af7();
let rx = gpioa.pa3.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( let mut serial = Serial::usart2(
device.USART2, device.USART2,
...@@ -99,6 +95,8 @@ const APP: () = { ...@@ -99,6 +95,8 @@ const APP: () = {
serial.listen(serial::Event::Rxne); serial.listen(serial::Event::Rxne);
// Separate out the sender and receiver of the serial port // Separate out the sender and receiver of the serial port
let (tx, rx) = serial.split(); let (tx, rx) = serial.split();
// Start periodic task
schedule.periodic(start).unwrap();
// pass on late resources // pass on late resources
LED = led; LED = led;
...@@ -132,7 +130,7 @@ const APP: () = { ...@@ -132,7 +130,7 @@ const APP: () = {
iprintln!(stim, "{:?}", error); 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() { fn USART2() {
match resources.RX.read() { match resources.RX.read() {
Ok(byte) => { Ok(byte) => {
...@@ -141,13 +139,11 @@ const APP: () = { ...@@ -141,13 +139,11 @@ const APP: () = {
spawn.trace_error(Error::RingBufferOverflow).unwrap(); spawn.trace_error(Error::RingBufferOverflow).unwrap();
} }
} }
Err(_err) => { Err(_err) => spawn.trace_error(Error::UsartReceiveOverflow).unwrap(),
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) { fn echo(byte: u8) {
let tx = resources.TX; let tx = resources.TX;
...@@ -155,61 +151,101 @@ const APP: () = { ...@@ -155,61 +151,101 @@ const APP: () = {
spawn.trace_error(Error::UsartSendOverflow).unwrap(); spawn.trace_error(Error::UsartSendOverflow).unwrap();
} }
let mut data = resources.DATA;
match byte { match byte {
b'a' => spawn.event_a(false).unwrap(), b'a' => data.a = false,
b'b' => spawn.event_b(false).unwrap(), b'b' => data.b = false,
b'A' => spawn.event_a(true).unwrap(), b'A' => data.a = true,
b'B' => spawn.event_b(true).unwrap(), b'B' => data.b = true,
_ => (), _ => (),
} }
} }
#[task(priority = 1, resources = [ITM, DATA], schedule = [discrepency])] #[task (priority = 1, resources = [LED, ITM, DATA], schedule = [periodic])]
fn event_a(val: bool) { fn periodic() {
// we start directly in the init state S80001
static mut STATE: State = State::S8001;
static mut TIMEOUT: u32 = 0;
let stim = &mut resources.ITM.stim[0]; let stim = &mut resources.ITM.stim[0];
iprintln!(stim, "event a {}", val); let data = resources.DATA;
let data = &mut resources.DATA; iprintln!(stim, "Old State {:?}", STATE);
data.a = val; iprintln!(stim, "Timeout {:?}", TIMEOUT);
// evaluate equivalenc. iprintln!(stim, "{:?}", data);
data.event_counter += 1;
if data.a ^ data.b { *STATE = match STATE {
schedule S8000 => match (data.a, data.b) {
.discrepency(scheduled + TIMEOUT.cycles(), data.clone()) (F, F) => S8001,
.unwrap(); (F, T) | (T, F) => {
data.out = false; *TIMEOUT = DISCREPENCY;
iprintln!(stim, "disc {:?}", data); S8005
} }
(T, T) => S8000,
},
S8001 => match (data.a, data.b) {
(F, F) => S8001,
(F, T) => {
*TIMEOUT = DISCREPENCY;
S8014
} }
(T, F) => {
#[task(priority = 1, resources = [ITM, DATA], spawn = [discrepency])] *TIMEOUT = DISCREPENCY;
fn event_b(val: bool) { S8004
let stim = &mut resources.ITM.stim[0];
iprintln!(stim, "event b {}", val);
//evaluate_equivalence(scheduled, &mut resources.DATA);
} }
(T, T) => S8000,
#[task(priority = 1, resources = [ITM, DATA])] },
fn discrepency(data: Data) { S8004 => {
let stim = &mut resources.ITM.stim[0]; *TIMEOUT -= 1;
iprintln!(stim, "a {} b {}", data.a, data.b); match *TIMEOUT {
if data.event_counter == resources.DATA.event_counter { 0 => C001,
iprintln!(stim, "timeout"); _ => match (data.a, data.b) {
// data.force_reinit = (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);
#[task (priority = 1, resources = [LED])] if *STATE == S8000 {
fn periodic() {
static mut TOGGLE: bool = false;
if *TOGGLE {
resources.LED.set_low();
} else {
resources.LED.set_high(); resources.LED.set_high();
} else {
resources.LED.set_low();
} }
*TOGGLE = !*TOGGLE; schedule.periodic(scheduled + PERIOD.cycles()).unwrap();
} }
extern "C" { extern "C" {
......
...@@ -16,9 +16,6 @@ use crate::hal::prelude::*; ...@@ -16,9 +16,6 @@ use crate::hal::prelude::*;
use crate::hal::serial::{self, config::Config, Rx, Serial, Tx}; use crate::hal::serial::{self, config::Config, Rx, Serial, Tx};
use hal::stm32::ITM; use hal::stm32::ITM;
// use heapless::consts::*;
// use heapless::spsc::{Consumer, Producer, Queue};
use nb::block; use nb::block;
use rtfm::{app, Instant}; use rtfm::{app, Instant};
...@@ -144,9 +141,7 @@ const APP: () = { ...@@ -144,9 +141,7 @@ const APP: () = {
spawn.trace_error(Error::RingBufferOverflow).unwrap(); spawn.trace_error(Error::RingBufferOverflow).unwrap();
} }
} }
Err(_err) => { Err(_err) => spawn.trace_error(Error::UsartReceiveOverflow).unwrap(),
spawn.trace_error(Error::UsartReceiveOverflow).unwrap()
}
} }
} }
...@@ -172,7 +167,6 @@ const APP: () = { ...@@ -172,7 +167,6 @@ const APP: () = {
let stim = &mut resources.ITM.stim[0]; let stim = &mut resources.ITM.stim[0];
iprintln!(stim, "event a {}", val); iprintln!(stim, "event a {}", val);
let data = &mut resources.DATA; let data = &mut resources.DATA;
data.a = val; data.a = val;
iprintln!(stim, "Start {:?}", data); iprintln!(stim, "Start {:?}", data);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment