Skip to content

Commit

Permalink
Correct docs (#18)
Browse files Browse the repository at this point in the history
* Test monotonic feature in CI.

* needs testing

* remove excessive unsafe

* Fix build.

* correct docs

---------

Co-authored-by: Andrew Walbran <qwandor@google.com>
  • Loading branch information
ivajon and qwandor authored May 23, 2024
1 parent 3c353da commit c8bf535
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 11 deletions.
8 changes: 2 additions & 6 deletions examples/monotonic-blinky/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@ for software task scheduling. This example shows how to use the different clocks

## How to run

To run the default blinky example
```bash
cargo embed --release
```
To run the example using the `rtc`
```bash
cargo embed --release --example rtc
cargo embed --release --bin rtc
```
To run the example using the `timer`
```bash
cargo embed --release --example timer
cargo embed --release --bin timer
```

49 changes: 44 additions & 5 deletions nrf-hal-common/src/monotonic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,16 @@ mod sealed {

pub trait RtcInstance: Instance<RegBlock = super::RtcRegBlock> {}

pub trait TimerInstance: Instance<RegBlock = super::TimerRegBlock> {}
pub trait TimerInstance: Instance<RegBlock = super::TimerRegBlock> {
/// Sets the compare value for the [`Instance`].
fn set_compare<const IDX: usize>(compare: u32);

/// Clears the compare event.
fn clear_compare_flag<const IDX: usize>();

/// Enables the comparator for this [`Instance`].
fn enable_compare<const IDX: usize>();
}
}

pub use sealed::{Instance, RtcInstance, TimerInstance};
Expand Down Expand Up @@ -283,19 +292,21 @@ impl<T: TimerInstance, const FREQ: u32> MonotonicTimer<T, FREQ> {
impl<T: TimerInstance, const FREQ: u32> Monotonic for MonotonicTimer<T, FREQ> {
type Instant = fugit::TimerInstantU32<FREQ>;
type Duration = fugit::TimerDurationU32<FREQ>;

fn now(&mut self) -> Self::Instant {
let reg: &TimerRegBlock = T::reg();
reg.tasks_capture[1].write(|w| w.tasks_capture().set_bit());
T::enable_compare::<1>();

let ticks = reg.cc[1].read().bits();
fugit::TimerInstantU32::<FREQ>::from_ticks(ticks.into())
}

fn set_compare(&mut self, instant: Self::Instant) {
T::reg().cc[2].write(|w| w.cc().variant(instant.duration_since_epoch().ticks()));
T::set_compare::<2>(instant.duration_since_epoch().ticks())
}

fn clear_compare_flag(&mut self) {
T::reg().events_compare[2].write(|w| w.events_compare().clear_bit());
T::clear_compare_flag::<2>();
}

fn zero() -> Self::Instant {
Expand All @@ -312,7 +323,35 @@ impl<T: TimerInstance, const FREQ: u32> Monotonic for MonotonicTimer<T, FREQ> {

macro_rules! impl_instance {
(TimerRegBlock,$peripheral:ident) => {
impl TimerInstance for $peripheral {}
impl TimerInstance for $peripheral {
fn set_compare<const IDX:usize>(compare:u32){
#[cfg(feature = "51")]
Self::reg().cc[IDX].write(|w| unsafe{w.bits(compare)});

#[cfg(not(feature = "51"))]
Self::reg().cc[IDX].write(|w| w.cc().variant(compare));
}

fn clear_compare_flag<const IDX:usize>(){
// We clear the top bits manually.
#[cfg(any(feature = "52832", feature = "51"))]
Self::reg().events_compare[2].write(|w| unsafe { w.bits(0) });

#[cfg(not(any(feature = "52832", feature = "51")))]
Self::reg().events_compare[2].write(|w| w.events_compare().clear_bit());

}

fn enable_compare<const IDX:usize>() {
// Bit idx 31 is the same as enabling tasks_capture.
#[cfg(any(feature = "52832", feature = "51"))]
Self::reg().tasks_capture[IDX].write(|w| unsafe { w.bits(1 << 31) });

#[cfg(not(any(feature = "52832", feature = "51")))]
Self::reg().tasks_capture[IDX].write(|w| w.tasks_capture().set_bit());

}
}
};
(RtcRegBlock,$peripheral:ident) => {
impl RtcInstance for $peripheral {}
Expand Down
20 changes: 20 additions & 0 deletions xtask/tests/ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,26 @@ fn main() {
"command exited with error status: {:?}",
cargo
);
// With default features plus `monotonic`.
let mut cargo = Command::new("cargo");
let status = cargo
.args(&[
"build",
"--manifest-path",
&toml_path,
"--target",
target,
"--features",
"monotonic",
])
.status()
.map_err(|e| format!("could not execute {:?}: {}", cargo, e))
.unwrap();
assert!(
status.success(),
"command exited with error status: {:?}",
cargo
);
// Without default features.
let mut cargo = Command::new("cargo");
let status = cargo
Expand Down

0 comments on commit c8bf535

Please sign in to comment.