Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTIC monotonic implementation #384

Open
barafael opened this issue Feb 18, 2022 · 2 comments
Open

RTIC monotonic implementation #384

barafael opened this issue Feb 18, 2022 · 2 comments

Comments

@barafael
Copy link

There is already a working implementation of RTIC monotonic timer for TIMER{0,1,2} here: https://github.com/kalkyl/nrf-play/blob/47f4410d4e39374c18ff58dc17c25159085fb526/src/mono.rs
It would be nice for this to be part of the HAL so that the implementation does not need to be copied every time :) I'm trying to do this, but I'm not sure how.

@ivario123
Copy link
Contributor

I realize that this might be stale but, It would be relatively simple to add this. I made a draft implementation making the abstraction agnostic to whether you are using the RTC or the TIMER. Using the RTC yields much better power efficiency.

Using this would look something like this:

use nrf5284_hal as hal;
use hal::monotonic::*;
use hal::rtc::RTC0;
use hal::timer::TIMER0;

#[rtic::app(device = nrf52840_hal::pac,dispatchers=[TIMER2,TIMER3])]
mod app {

    use super::*;
    #[monotonic(binds = RTC0, default = true)]
    type MyMono = MonotonicTimer<RTC0>;
    // Or this if using timer
    #[monotonic(binds = TIMER0, default = true)]
    type MyMono = MonotonicTimer<TIMER0>;
    

    #[shared]
    struct Shared {}

    #[local]
    struct Local {}

    #[init]
    fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
        let mono = MonotonicTimer::new(cx.device.RTC0);
        // Or this if using timer
        let mono = MonotonicTimer::new(cx.device.TIMER0);


        // Return shared, local and mono
        (
            Shared {},
            Local {},
            init::Monotonics(mono),
        )
   }
}

Making it trivial to change clocks when writing your app

@ivario123
Copy link
Contributor

@barafael I think that I have finished an implementation for this

The API looks like this at the time of writing and it will not change much.

#![no_main]
#![no_std]
use core::panic::PanicInfo;
use nrf52840_hal as hal;
use hal::monotonic::MonotonicTimer;
use hal::pac;
#[panic_handler]
fn panic(_panic: &PanicInfo<'_>) -> ! {
    loop {}
}
#[rtic::app(device = pac, dispatchers = [TIMER2, TIMER3])]
mod app {
    use super::*;
    #[monotonic(binds = RTC0, default = true)]
    type Mono = MonotonicTimer<pac::RTC0, 32_768u32>;
    // Conversely
    #[monotonic(binds = TIMER0, default = true)]
    type Mono = MonotonicTimer<pac::TIMER0, 1_000_000u32>;
    #[shared]
    struct Shared {}
    #[local]
    struct Local {}
    #[init]
    fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
        let clocks = hal::clocks::Clocks::new(cx.device.CLOCK)
        .set_lfclk_src_external(hal::clocks::LfOscConfiguration::NoExternalNoBypass)
        .start_lfclk()
        .enable_ext_hfosc();
        let mono = Mono::new(cx.device.RTC0, &clocks).unwrap();
        // Conversely
        let mono = Mono::new(cx.device.TIMER0, &clocks).unwrap();

        // Return shared, local and mono
        (Shared {}, Local {}, init::Monotonics(mono))
    }
    #[idle()]
    fn idle(_cx: idle::Context) -> ! {
        loop {}
    }
}

I am still to test it as I do not have any hardware at hand but feel free to try it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants