From ca0453df54ac9f7a614c129731bb520b70b45e92 Mon Sep 17 00:00:00 2001 From: topquark12 Date: Sun, 23 Oct 2022 20:07:44 +0800 Subject: [PATCH] rtic implementation --- .gitignore | 2 +- Cargo.lock | 258 ++++++++++++++++++++++++++++- Cargo.toml | 5 +- src/device/boot.rs | 12 +- src/device/delay.rs | 46 +++++ src/device/mod.rs | 2 +- src/device/sys_timer.rs | 43 ----- src/laser_diode/current_sources.rs | 12 +- src/main.rs | 68 ++++++-- 9 files changed, 372 insertions(+), 76 deletions(-) create mode 100644 src/device/delay.rs delete mode 100644 src/device/sys_timer.rs diff --git a/.gitignore b/.gitignore index d6964cf..15c7dc8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ target/ result - +.vscode* *.jdebug* diff --git a/Cargo.lock b/Cargo.lock index abde382..0b9a12a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 219b846..f5afaab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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"] diff --git a/src/device/boot.rs b/src/device/boot.rs index 6133c01..1e688f6 100644 --- a/src/device/boot.rs +++ b/src/device/boot.rs @@ -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) } diff --git a/src/device/delay.rs b/src/device/delay.rs new file mode 100644 index 0000000..7698854 --- /dev/null +++ b/src/device/delay.rs @@ -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 DelayUs for AsmDelay +where + U: Into, +{ + fn delay_us(&mut self, us: U) { + cortex_m::asm::delay(self.frequency_us * us.into()) + } +} + +impl DelayMs for AsmDelay +where + U: Into, +{ + fn delay_ms(&mut self, ms: U) { + cortex_m::asm::delay(self.frequency_ms * ms.into()) + } +} \ No newline at end of file diff --git a/src/device/mod.rs b/src/device/mod.rs index acfea46..baaface 100644 --- a/src/device/mod.rs +++ b/src/device/mod.rs @@ -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; diff --git a/src/device/sys_timer.rs b/src/device/sys_timer.rs deleted file mode 100644 index 04abbf3..0000000 --- a/src/device/sys_timer.rs +++ /dev/null @@ -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> = 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 {} -} diff --git a/src/laser_diode/current_sources.rs b/src/laser_diode/current_sources.rs index 143de88..5e84c28 100644 --- a/src/laser_diode/current_sources.rs +++ b/src/laser_diode/current_sources.rs @@ -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>, NoMiso, PB15>), TransferModeNormal>; } +use crate::device::delay; + impl CurrentSource { - 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( diff --git a/src/main.rs b/src/main.rs index 7ffde0b..67dd3c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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(); + } + } + } +