Closed seanybaggins closed 1 year ago
Good idea. I personally haven't used Monotomic (have been using RTIC just for the interrupt and shared-state functionality), but agree that would be a good addition. Perhaps instead of an example, actually implementing it for timers, although I'm not sure that's how it works.
In the latest release. I think there's a bug with it; can't get it to work properly. Hopefully an easy fix; LMK if you have any ideas, or if you're able to get it working as-is.
I did manage to implement my own timer. Here is the code. Might circle back and open up a PR for an example. Currently don't have the bandwidth to check the default implementation for the stm32. I might be able to take a look at it during a weekend during the holidays.
use rtic::Monotonic;
use stm32_hal2::clocks::Clocks;
use stm32_hal2::pac::TIM2;
use stm32_hal2::timer::{Alignment, CaptureCompareDma, CountDir, Timer, TimerConfig, UpdateReqSrc};
pub struct MonoTimer<T, const FREQ: u32>(Timer<T>);
impl<const FREQ: u32> MonoTimer<TIM2, FREQ> {
pub fn new(timer: TIM2, clocks: &Clocks) -> Self {
let timer_config = TimerConfig {
one_pulse_mode: false,
update_request_source: UpdateReqSrc::Any,
auto_reload_preload: false,
alignment: Alignment::Edge,
capture_compare_dma: CaptureCompareDma::Update,
direction: CountDir::Up,
};
let mut timer = Timer::new_tim2(timer, FREQ as f32, timer_config, &clocks);
let prescaler = clocks.sysclk() / FREQ - 1;
timer.set_auto_reload(u32::MAX);
timer.set_prescaler(prescaler as u16);
timer.regs.egr.write(|w| w.ug().set_bit());
timer.regs.sr.write(|w| w.uif().clear_bit());
timer.regs.cr1.write(|w| w.cen().set_bit().udis().set_bit());
Self(timer)
}
pub fn counts(&self) -> u32 {
self.0.read_count()
}
}
impl<const FREQ: u32> Monotonic for MonoTimer<TIM2, FREQ> {
type Instant = fugit::TimerInstantU32<FREQ>;
type Duration = fugit::TimerDurationU32<FREQ>;
#[inline(always)]
fn now(&mut self) -> Self::Instant {
let ticks = self.0.read_count();
Self::Instant::from_ticks(ticks)
}
fn set_compare(&mut self, instant: Self::Instant) {
// No idea. Taken from https://github.com/kalkyl/f411-rtic/blob/a696fce7d6d19fda2356c37642c4d53547982cca/src/mono.rs#L87
self.0
.regs
.ccr1()
.write(|w| w.ccr().bits(instant.duration_since_epoch().ticks()))
}
fn clear_compare_flag(&mut self) {
self.0.regs.sr.write(|w| w.cc1if().clear_bit())
}
#[inline(always)]
fn zero() -> Self::Instant {
Self::Instant::from_ticks(0)
}
unsafe fn reset(&mut self) {
self.0.regs.dier.write(|w| w.cc1ie().set_bit())
}
}
Nice! Check the current impl here: https://github.com/David-OConnor/stm32-hal/blob/main/src/timer.rs#L791
Overall, same idea as what you posted, with the following exceptions:
core::Duration
, and a custom Instant
type (see the newly-added instant
module in this lib)now
to a non-trait-requiring time_elapsed
fn: I think this function will be useful even without using Monotonic
, for getting the time in seconds, ms, us, or ns since timer start.Are you calling spawn_after
or spawn
? It could be the timer is hitting the auto_reload value and resetting before it hits the value you asked to wait for.
Looks like spawn
works; tried increasing the timer timeout period, but something is still not working with spawn_after
.
I'm dropping further integration due to the direction RTIC is moving.
Can you elaborate on due to the direction RTIC is moving
?
Async for RTIC 2.
I wonder if it will play nice with embassy. It would be cool if you could use an RTIC 2 executor with embassy hals. Never used embassy's hals but have wanted to give them a try.
From what I gather from some chats, it should play nice with Embassy, although I don't know how the interactions will work. I think the intent is to keep the core RTIC functionality (Resource sharing and interrupts) the same, but to move everything else, which would include monotonic, to async.
It would be nice if there was an example to implement the Monotonic trait using the hal api calls.
Here is an example using the peripheral access crate. https://github.com/kalkyl/f411-rtic/blob/c1c74d887e3620bddcaf9217c93767e9f743d7b1/src/mono.rs