Skip to content

Commit

Permalink
Add initial support for embedded-hal version 1.0
Browse files Browse the repository at this point in the history
This adds a dependency and feature for embedded-hal v1.0 and a basic
implementation for the `DelayNs` trait.
  • Loading branch information
tgross35 committed Jan 13, 2024
1 parent 40680e7 commit ae531a4
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 3 deletions.
1 change: 1 addition & 0 deletions hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Update the PACs to svd2rust 0.30.2.
- Fix warnings for thumbv7 targets
- Update README.md - moves some content to wiki
- Add basic support for `embedded-hal` version 1.0 under the feature `embedded-hal-1`.

# v0.16.0

Expand Down
3 changes: 3 additions & 0 deletions hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ bitflags = "1.2.1"
cipher = "0.3"
cortex-m = "0.7"
embedded-hal = "0.2"
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-rc.1", optional = true }
fugit = "0.3"
modular-bitfield = "0.11"
nb = "1.0"
Expand Down Expand Up @@ -371,3 +372,5 @@ periph-e53n = ["periph-d51n", "has-ethernet"]

periph-e54n = ["periph-d51n", "has-ethernet", "has-can0", "has-can1"]
periph-e54p = ["periph-d51p", "has-ethernet", "has-can0", "has-can1"]

embedded-hal-1 = ["dep:embedded-hal-1"]
2 changes: 2 additions & 0 deletions hal/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#![no_std]

pub use embedded_hal as ehal;
#[cfg(feature = "embedded-hal-1")]
pub use embedded_hal_1 as ehal1;
pub use fugit;
pub use paste;
pub mod typelevel;
Expand Down
11 changes: 9 additions & 2 deletions hal/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,19 @@ pub use fugit::RateExtU32 as _;

// embedded-hal doesn’t yet have v2 in its prelude, so we need to
// export it ourselves
#[cfg(feature = "unproven")]
//
// We only have embedded-hal v0.2 items inour prelude if v1 is not enabled.
#[cfg(all(not(feature = "embedded-hal-1"), feature = "unproven"))]
pub use crate::ehal::digital::v2::InputPin as _atsamd_hal_embedded_hal_digital_v2_InputPin;
#[cfg(not(feature = "embedded-hal-1"))]
pub use crate::ehal::digital::v2::OutputPin as _atsamd_hal_embedded_hal_digital_v2_OutputPin;
#[cfg(feature = "unproven")]
#[cfg(all(not(feature = "embedded-hal-1"), feature = "unproven"))]
pub use crate::ehal::digital::v2::ToggleableOutputPin as _atsamd_hal_embedded_hal_digital_v2_ToggleableOutputPin;

#[cfg(not(feature = "embedded-hal-1"))]
pub use crate::ehal::prelude::*;

#[cfg(feature = "embedded-hal-1")]
pub use crate::ehal::digital::{Error as _, InputPin as _, OutputPin as _, StatefulOutputPin as _};

pub use nb;
35 changes: 34 additions & 1 deletion hal/src/sleeping_delay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ use cortex_m::asm;
use fugit::ExtU32;

use crate::ehal::blocking::delay::{DelayMs, DelayUs};
#[cfg(feature = "embedded-hal-1")]
use crate::ehal1::delay::DelayNs;
use crate::timer_traits::InterruptDrivenTimer;

const NUM_US_IN_S: u32 = 1_000_000;
#[cfg(feature = "embedded-hal-1")]
const NUM_NS_IN_S: u32 = 1_000_000_000;

/// Delay and sleep while we do (WFI) using a timer
pub struct SleepingDelay<TIM> {
Expand Down Expand Up @@ -35,6 +39,34 @@ where
}
}

#[cfg(feature = "embedded-hal-1")]
impl<TIM> DelayNs for SleepingDelay<TIM>
where
TIM: InterruptDrivenTimer,
{
fn delay_ns(&mut self, ns: u32) {
// Determine how many cycles we need to run for this delay, if any
// Avoid timers that run longer than a second because for 48 MHz-based timers,
// there is no valid divisor + cycle count greater than ~1.3s, so we'd panic.
let mut loop_count: u32 = 1 + (ns / NUM_NS_IN_S);

// Start the timer and sleep!
self.timer.start((ns / loop_count).nanos());
self.timer.enable_interrupt();
loop {
asm::wfi();
if self.timer.wait().is_ok() || self.interrupt_fired.load(atomic::Ordering::Relaxed) {
self.interrupt_fired.store(false, atomic::Ordering::Relaxed);
loop_count -= 1;
if loop_count == 0 {
break;
}
}
}
self.timer.disable_interrupt();
}
}

impl<TIM, TYPE> DelayUs<TYPE> for SleepingDelay<TIM>
where
TIM: InterruptDrivenTimer,
Expand All @@ -49,6 +81,7 @@ where
let mut count: u32 = 1 + (us / NUM_US_IN_S);

// Start the timer and sleep!
// TODO: why does this use nanos?
self.timer.start((us / count).nanos());
self.timer.enable_interrupt();
loop {
Expand All @@ -71,6 +104,6 @@ where
TYPE: Into<u32>,
{
fn delay_ms(&mut self, ms: TYPE) {
self.delay_us(ms.into() * 1_000_u32);
<Self as DelayUs<_>>::delay_us(self, ms.into() * 1_000_u32);
}
}

0 comments on commit ae531a4

Please sign in to comment.