rtic implementation

rtic
topquark12 2022-10-23 20:07:44 +08:00
parent 1b3b121a2d
commit ca0453df54
9 changed files with 372 additions and 76 deletions

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
target/
result
.vscode*
*.jdebug*

258
Cargo.lock generated
View File

@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
dependencies = [
"memchr",
]
[[package]]
name = "aligned"
version = "0.3.5"
@ -41,6 +50,15 @@ dependencies = [
"stable_deref_trait",
]
[[package]]
name = "atomic-polyfill"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c041a8d9751a520ee19656232a18971f18946a7900f1520ee4400002244dd89"
dependencies = [
"critical-section",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -53,7 +71,7 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
dependencies = [
"rustc_version",
"rustc_version 0.2.3",
]
[[package]]
@ -62,6 +80,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
[[package]]
name = "bit_field"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
[[package]]
name = "bitfield"
version = "0.13.2"
@ -142,6 +166,34 @@ dependencies = [
"syn",
]
[[package]]
name = "cortex-m-rtic"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6b82f1c39acd6c3a35c2013b6110c20f5bc534522791fabadeed49ccada2dce"
dependencies = [
"bare-metal 1.0.0",
"cortex-m 0.7.6",
"cortex-m-rtic-macros",
"heapless",
"rtic-core",
"rtic-monotonic",
"version_check",
]
[[package]]
name = "cortex-m-rtic-macros"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8e9645ef54bec1cf70ac33e9bf9566e6507ab5b41ae6baf3735662194e8607"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"rtic-syntax",
"syn",
]
[[package]]
name = "cortex-m-semihosting"
version = "0.3.7"
@ -160,6 +212,18 @@ dependencies = [
"cortex-m 0.7.6",
]
[[package]]
name = "critical-section"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95da181745b56d4bd339530ec393508910c909c784e8962d15d722bacf0bcbcd"
dependencies = [
"bare-metal 1.0.0",
"cfg-if",
"cortex-m 0.7.6",
"riscv",
]
[[package]]
name = "embedded-dma"
version = "0.2.0"
@ -250,6 +314,44 @@ dependencies = [
"version_check",
]
[[package]]
name = "hash32"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
dependencies = [
"byteorder",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "heapless"
version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
dependencies = [
"atomic-polyfill",
"hash32",
"rustc_version 0.4.0",
"spin",
"stable_deref_trait",
]
[[package]]
name = "indexmap"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "kirdy"
version = "0.0.0"
@ -258,6 +360,7 @@ dependencies = [
"cortex-m 0.7.6",
"cortex-m-log",
"cortex-m-rt",
"cortex-m-rtic",
"cortex-m-semihosting 0.5.0",
"fugit",
"log",
@ -268,10 +371,17 @@ dependencies = [
"smoltcp",
"stm32-eth",
"stm32f4xx-hal",
"systick-monotonic",
"usb-device",
"usbd-serial",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.135"
@ -284,6 +394,16 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565"
[[package]]
name = "lock_api"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.17"
@ -299,6 +419,12 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "nb"
version = "0.1.3"
@ -345,6 +471,30 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.47"
@ -369,6 +519,68 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "regex"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "riscv"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6907ccdd7a31012b70faf2af85cd9e5ba97657cc3987c4f13f8e4d2c2a088aba"
dependencies = [
"bare-metal 1.0.0",
"bit_field",
"riscv-target",
]
[[package]]
name = "riscv-target"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222"
dependencies = [
"lazy_static",
"regex",
]
[[package]]
name = "rtic-core"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42"
[[package]]
name = "rtic-monotonic"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb8b0b822d1a366470b9cea83a1d4e788392db763539dc4ba022bcc787fece82"
[[package]]
name = "rtic-syntax"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ad3ae243dd8d0a1b064615f664d4fa7e63929939074c564cbe5efdc4c503065"
dependencies = [
"indexmap",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "rtt-target"
version = "0.3.1"
@ -385,9 +597,24 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
"semver 0.9.0",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver 1.0.14",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
version = "0.9.0"
@ -397,6 +624,12 @@ dependencies = [
"semver-parser",
]
[[package]]
name = "semver"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
[[package]]
name = "semver-parser"
version = "0.7.0"
@ -415,6 +648,15 @@ dependencies = [
"managed",
]
[[package]]
name = "spin"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
dependencies = [
"lock_api",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
@ -463,6 +705,7 @@ dependencies = [
"fugit-timer",
"nb 1.0.0",
"rand_core",
"rtic-monotonic",
"stm32f4",
"synopsys-usb-otg",
"time",
@ -491,6 +734,17 @@ dependencies = [
"vcell",
]
[[package]]
name = "systick-monotonic"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57e71d8e4587d8f434b88b9aef901987f46164df813a3a1d6bdf3a58debf67f0"
dependencies = [
"cortex-m 0.7.6",
"fugit",
"rtic-monotonic",
]
[[package]]
name = "time"
version = "0.3.15"

View File

@ -22,7 +22,7 @@ log = "0.4.17"
bare-metal = "1"
nb = "1"
cortex-m-log = { version = "0.7.0", features = ["log-integration", "semihosting"] }
stm32f4xx-hal = { version = "0.13.2", features = ["rt", "stm32f407", "usb_fs"] }
stm32f4xx-hal = { version = "0.13.2", features = ["rt", "stm32f407", "usb_fs", "rtic-monotonic"] }
stm32-eth = { version = "0.3.0", features = ["stm32f407"] }
smoltcp = { version = "0.8.0", default-features = false, features = ["proto-ipv4", "socket-tcp", "log", "medium-ethernet"] }
num-traits = { version = "0.2.15", default-features = false, features = ["libm"] }
@ -30,7 +30,8 @@ usb-device = "0.2.9"
usbd-serial = "0.1.1"
fugit = "0.3.6"
rtt-target = { version = "0.3.1", features = ["cortex-m"] }
cortex-m-rtic = "1.0.0"
systick-monotonic = "1.0.0"
[features]
semihosting = ["cortex-m-log/semihosting"]

View File

@ -1,5 +1,6 @@
use super::{gpio, sys_timer, usb};
use super::{gpio, usb, delay};
use crate::laser_diode::current_sources::*;
use systick_monotonic::Systick;
use fugit::ExtU32;
use log::info;
use stm32f4xx_hal::{
@ -14,7 +15,7 @@ const WATCHDOG_PERIOD: u32 = 1000;
#[cfg(feature = "semihosting")]
const WATCHDOG_PERIOD: u32 = 30000;
pub fn bootup(mut core_perif: CorePeripherals, perif: Peripherals) -> IndependentWatchdog {
pub fn bootup(mut core_perif: CorePeripherals, perif: Peripherals) -> (IndependentWatchdog, Systick<1000_u32>) {
core_perif.SCB.enable_icache();
core_perif.SCB.enable_dcache(&mut core_perif.CPUID);
@ -29,7 +30,8 @@ pub fn bootup(mut core_perif: CorePeripherals, perif: Peripherals) -> Independen
.pclk2(MegaHertz::from_raw(64).convert())
.freeze();
sys_timer::setup(core_perif.SYST, clocks);
let systick = Systick::new(core_perif.SYST, clocks.hclk().to_Hz());
let delay = delay::AsmDelay::new(clocks.sysclk().to_Hz());
let (_eth_pins, usb, current_source_phy) = gpio::setup(
clocks,
@ -53,7 +55,7 @@ pub fn bootup(mut core_perif: CorePeripherals, perif: Peripherals) -> Independen
},
};
laser.setup();
laser.setup(delay);
laser.set_current(0.1).unwrap();
let mut wd = IndependentWatchdog::new(perif.IWDG);
@ -62,5 +64,5 @@ pub fn bootup(mut core_perif: CorePeripherals, perif: Peripherals) -> Independen
info!("Kirdy setup complete");
wd
(wd, systick)
}

46
src/device/delay.rs Normal file
View File

@ -0,0 +1,46 @@
//! Basic blocking delay
//!
//! This module provides a basic asm-based blocking delay.
//! Borrowed from our good friends at Quartiq:
//! https://github.com/quartiq/stabilizer/blob/master/src/hardware/delay.rs
//!
use stm32f4xx_hal::hal::blocking::delay::{DelayMs, DelayUs};
// use stm32f4xx_hal::block;
/// A basic delay implementation.
pub struct AsmDelay {
frequency_us: u32,
frequency_ms: u32,
}
impl AsmDelay {
/// Create a new delay.
///
/// # Args
/// * `freq` - The CPU core frequency.
pub fn new(freq: u32) -> AsmDelay {
AsmDelay {
frequency_us: (freq / 1_000_000),
frequency_ms: (freq / 1_000),
}
}
}
impl<U> DelayUs<U> for AsmDelay
where
U: Into<u32>,
{
fn delay_us(&mut self, us: U) {
cortex_m::asm::delay(self.frequency_us * us.into())
}
}
impl<U> DelayMs<U> for AsmDelay
where
U: Into<u32>,
{
fn delay_ms(&mut self, ms: U) {
cortex_m::asm::delay(self.frequency_ms * ms.into())
}
}

View File

@ -2,5 +2,5 @@ pub mod boot;
pub mod gpio;
pub mod log_setup;
pub mod rtt_logger;
pub mod sys_timer;
pub mod delay;
pub mod usb;

View File

@ -1,43 +0,0 @@
use core::cell::RefCell;
use core::ops::Deref;
use cortex_m::interrupt::Mutex;
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m_rt::exception;
use stm32f4xx_hal::{pac::SYST, rcc::Clocks};
/// Rate in Hz
const TIMER_RATE: u32 = 1000;
/// Interval duration in milliseconds
const TIMER_DELTA: u32 = 1000 / TIMER_RATE;
/// Elapsed time in milliseconds
static TIMER_MS: Mutex<RefCell<u32>> = Mutex::new(RefCell::new(0));
/// Setup SysTick exception
pub fn setup(mut syst: SYST, clocks: Clocks) {
syst.set_clock_source(SystClkSource::Core);
syst.set_reload(clocks.hclk().to_Hz() / TIMER_RATE - 1);
syst.enable_counter();
syst.enable_interrupt();
}
/// SysTick exception (Timer)
#[exception]
fn SysTick() {
cortex_m::interrupt::free(|cs| {
*TIMER_MS.borrow(cs).borrow_mut() += TIMER_DELTA;
});
}
/// Obtain current time in milliseconds
pub fn now() -> u32 {
cortex_m::interrupt::free(|cs| *TIMER_MS.borrow(cs).borrow().deref())
}
/// block for `amount` milliseconds
pub fn sleep(amount: u32) {
if amount == 0 {
return;
}
let start = now();
while now() - start <= amount - 1 {}
}

View File

@ -1,11 +1,11 @@
use cortex_m::prelude::_embedded_hal_blocking_delay_DelayMs;
use stm32f4xx_hal::{
gpio::{gpioa::*, gpiob::*, gpiod::*, Alternate, Output, PushPull, PD9},
hal::{blocking::spi::Write, digital::v2::OutputPin},
pac::SPI2,
spi::{NoMiso, Spi, TransferModeNormal},
spi::{NoMiso, Spi, TransferModeNormal}
};
use crate::device::sys_timer::sleep;
pub trait CurrentSourcePhy {
type CurrentSourceLdoEn: OutputPin;
type CurrentSourceShort: OutputPin;
@ -40,14 +40,16 @@ impl CurrentSourcePhy for CurrentSourcePhyCh0 {
Spi<SPI2, (PB10<Alternate<5>>, NoMiso, PB15<Alternate<5>>), TransferModeNormal>;
}
use crate::device::delay;
impl<C: CurrentSourcePhy> CurrentSource<C> {
pub fn setup(&mut self) {
pub fn setup(&mut self, mut delay : delay::AsmDelay) {
let _ = self.phy.max5719_load.set_high();
let _ = self.phy.max5719_cs.set_high();
let _ = self.phy.current_source_ldo_en.set_high();
sleep(10_u32);
delay.delay_ms(10_u32);
let _ = self.phy.current_source_short.set_high();
sleep(10_u32);
delay.delay_ms(10_u32);
}
pub fn set_current(

View File

@ -1,13 +1,9 @@
#![no_main]
#![no_std]
use cortex_m_rt::entry;
use log::info;
use stm32f4xx_hal::pac::{CorePeripherals, Peripherals};
use rtic::app;
mod device;
mod laser_diode;
use device::{boot::bootup, log_setup, sys_timer};
// If RTT is used, print panic info through RTT
#[cfg(feature = "RTT")]
@ -25,20 +21,58 @@ fn panic(info: &PanicInfo) -> ! {
#[cfg(not(feature = "RTT"))]
use panic_halt as _;
#[entry]
fn main() -> ! {
log_setup::init_log();
info!("Kirdy init");
// #[entry]
#[app(device = stm32f4xx_hal::pac, peripherals = true, dispatchers = [TIM8_CC])]
mod app {
let core_perif = CorePeripherals::take().unwrap();
let perif = Peripherals::take().unwrap();
use log::info;
use systick_monotonic::Systick;
use fugit::ExtU32;
use stm32f4xx_hal::watchdog::IndependentWatchdog;
use crate::device::{boot::bootup, log_setup};
let mut wd = bootup(core_perif, perif);
#[monotonic(binds = SysTick, default = true)]
type SystickTimer = Systick<1000>;
#[shared]
struct Shared {
loop {
wd.feed();
info!("looping");
sys_timer::sleep(10);
}
#[local]
struct Local {
wd: IndependentWatchdog,
}
#[init]
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
log_setup::init_log();
info!("Kirdy init");
let core_perif = cx.core;
let perif = cx.device;
let (wd, systick) = bootup(core_perif, perif);
wd_feed::spawn().unwrap();
(Shared {}, Local {wd}, init::Monotonics(systick))
}
#[task(priority = 5, local = [wd])]
fn wd_feed (cx: wd_feed::Context) {
let start = monotonics::now();
let wd = cx.local.wd;
info!("feed wd");
wd.feed();
wd_feed::spawn_at(start + 10_u32.millis()).unwrap();
}
#[idle]
fn idle(_: idle::Context) -> ! {
loop {
cortex_m::asm::nop();
}
}
}