diff --git a/examples/rtfm_blinky_msg1.rs b/examples/rtfm_blinky_msg1.rs new file mode 100644 index 0000000000000000000000000000000000000000..48d45745d74f781a38b724af2dddeb9aef1f40cb --- /dev/null +++ b/examples/rtfm_blinky_msg1.rs @@ -0,0 +1,67 @@ +#![deny(unsafe_code)] +// #![deny(warnings)] +#![no_main] +#![no_std] + +use cortex_m::peripheral::DWT; +use cortex_m_semihosting::hprintln; +use panic_halt as _; +use rtfm::cyccnt::{Instant, U32Ext as _}; +use stm32f4xx_hal::stm32; + +#[rtfm::app(device = stm32f4xx_hal::stm32, monotonic = rtfm::cyccnt::CYCCNT, peripherals = true)] +const APP: () = { + struct Resources { + // late resources + GPIOA: stm32::GPIOA, + } + #[init(schedule = [toggle])] + fn init(mut cx: init::Context) -> init::LateResources { + let mut core = cx.core; + let mut device = cx.device; + + // Initialize (enable) the monotonic timer (CYCCNT) + core.DCB.enable_trace(); + // required on Cortex-M7 devices that software lock the DWT (e.g. STM32F7) + DWT::unlock(); + core.DWT.enable_cycle_counter(); + + // semantically, the monotonic timer is frozen at time "zero" during `init` + // NOTE do *not* call `Instant::now` in this context; it will return a nonsense value + let now = cx.start; // the start time of the system + + // Schedule `toggle` to run 8e6 cycles (clock cycles) in the future + cx.schedule.toggle(now + 8_000_000.cycles()).unwrap(); + + // 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)); + + // pass on late resources + init::LateResources { + GPIOA: device.GPIOA, + } + } + + #[task(resources = [GPIOA], schedule = [toggle])] + fn toggle(cx: toggle::Context) { + static mut TOGGLE: bool = false; + hprintln!("foo @ {:?}", Instant::now()).unwrap(); + + if *TOGGLE { + cx.resources.GPIOA.bsrr.write(|w| w.bs5().set_bit()); + } else { + cx.resources.GPIOA.bsrr.write(|w| w.br5().set_bit()); + } + + *TOGGLE = !*TOGGLE; + cx.schedule + .toggle(cx.scheduled + 8_000_000.cycles()) + .unwrap(); + } + + extern "C" { + fn EXTI0(); + } +}; diff --git a/examples/rtfm_blinky_msg2.rs b/examples/rtfm_blinky_msg2.rs index 81f2858b4e1cffe3b3a190e227135d27caa8615e..18867aafb2f0600f53e904367dabbfd13b5a5cd1 100644 --- a/examples/rtfm_blinky_msg2.rs +++ b/examples/rtfm_blinky_msg2.rs @@ -11,8 +11,12 @@ use stm32f4xx_hal::stm32; #[rtfm::app(device = stm32f4xx_hal::stm32, monotonic = rtfm::cyccnt::CYCCNT, peripherals = true)] const APP: () = { + struct Resources { + // late resources + GPIOA: stm32::GPIOA, + } #[init(schedule = [toggle])] - fn init(mut cx: init::Context) { + fn init(mut cx: init::Context) -> init::LateResources { let mut core = cx.core; let mut device = cx.device; @@ -26,27 +30,33 @@ const APP: () = { // NOTE do *not* call `Instant::now` in this context; it will return a nonsense value let now = cx.start; // the start time of the system + // Schedule `toggle` to run 8e6 cycles (clock cycles) in the future + cx.schedule.toggle(now + 8_000_000.cycles(), true).unwrap(); + // 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)); - cx.schedule - .toggle(now + 8_000_000.cycles(), true, device.GPIOA); + // pass on late resources + init::LateResources { + GPIOA: device.GPIOA, + } } - #[task(schedule = [toggle])] - fn toggle(cx: toggle::Context, toggle: bool, gpioa: stm32::GPIOA) { - hprintln!("toggle @ {:?}", Instant::now()).unwrap(); + #[task(resources = [GPIOA], schedule = [toggle])] + fn toggle(cx: toggle::Context, toggle: bool) { + hprintln!("foo @ {:?}", Instant::now()).unwrap(); if toggle { - gpioa.bsrr.write(|w| w.bs5().set_bit()); + cx.resources.GPIOA.bsrr.write(|w| w.bs5().set_bit()); } else { - gpioa.bsrr.write(|w| w.br5().set_bit()); + cx.resources.GPIOA.bsrr.write(|w| w.br5().set_bit()); } cx.schedule - .toggle(cx.scheduled + 8_000_000.cycles(), !toggle, gpioa); + .toggle(cx.scheduled + 8_000_000.cycles(), !toggle) + .unwrap(); } extern "C" { diff --git a/examples/rtfm_blinky_msg3.rs b/examples/rtfm_blinky_msg3.rs new file mode 100644 index 0000000000000000000000000000000000000000..81f2858b4e1cffe3b3a190e227135d27caa8615e --- /dev/null +++ b/examples/rtfm_blinky_msg3.rs @@ -0,0 +1,55 @@ +#![deny(unsafe_code)] +// #![deny(warnings)] +#![no_main] +#![no_std] + +use cortex_m::peripheral::DWT; +use cortex_m_semihosting::hprintln; +use panic_halt as _; +use rtfm::cyccnt::{Instant, U32Ext as _}; +use stm32f4xx_hal::stm32; + +#[rtfm::app(device = stm32f4xx_hal::stm32, monotonic = rtfm::cyccnt::CYCCNT, peripherals = true)] +const APP: () = { + #[init(schedule = [toggle])] + fn init(mut cx: init::Context) { + let mut core = cx.core; + let mut device = cx.device; + + // Initialize (enable) the monotonic timer (CYCCNT) + core.DCB.enable_trace(); + // required on Cortex-M7 devices that software lock the DWT (e.g. STM32F7) + DWT::unlock(); + core.DWT.enable_cycle_counter(); + + // semantically, the monotonic timer is frozen at time "zero" during `init` + // NOTE do *not* call `Instant::now` in this context; it will return a nonsense value + let now = cx.start; // the start time of the system + + // 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)); + + cx.schedule + .toggle(now + 8_000_000.cycles(), true, device.GPIOA); + } + + #[task(schedule = [toggle])] + fn toggle(cx: toggle::Context, toggle: bool, gpioa: stm32::GPIOA) { + hprintln!("toggle @ {:?}", Instant::now()).unwrap(); + + if toggle { + gpioa.bsrr.write(|w| w.bs5().set_bit()); + } else { + gpioa.bsrr.write(|w| w.br5().set_bit()); + } + + cx.schedule + .toggle(cx.scheduled + 8_000_000.cycles(), !toggle, gpioa); + } + + extern "C" { + fn EXTI0(); + } +};