Skip to content

Commit

Permalink
Merge pull request #287 from braun-embedded/embedded-hal-alpha
Browse files Browse the repository at this point in the history
Add partial support for embedded-hal 1.0.0-alpha.1
  • Loading branch information
hannobraun authored Oct 15, 2020
2 parents cb653bf + fe6a305 commit 39c548a
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 8 deletions.
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"rust-analyzer.cargo.features": [
"845-rt"
],
"rust-analyzer.checkOnSave.allTargets": false,
"editor.formatOnSave": true
}
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ optional = true
version = "0.2.4"
features = ["unproven"]

[dependencies.embedded-hal-alpha]
version = "1.0.0-alpha.1"
package = "embedded-hal"

[dependencies.lpc82x-pac]
optional = true
version = "0.7.0"
Expand Down
66 changes: 62 additions & 4 deletions src/delay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ use cortex_m::peripheral::syst::SystClkSource;

use crate::pac::SYST;
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use embedded_hal_alpha::blocking::delay::{
DelayMs as DelayMsAlpha, DelayUs as DelayUsAlpha,
};
use void::Void;

const SYSTICK_RANGE: u32 = 0x0100_0000;
const SYSTEM_CLOCK: u32 = 12_000_000;
Expand Down Expand Up @@ -72,6 +76,15 @@ impl DelayMs<u32> for Delay {
}
}

impl DelayMsAlpha<u32> for Delay {
type Error = Void;

/// Pauses execution for `ms` milliseconds
fn try_delay_ms(&mut self, ms: u32) -> Result<(), Self::Error> {
Ok(self.delay_ms(ms))
}
}

impl DelayMs<u16> for Delay {
/// Pauses execution for `ms` milliseconds
fn delay_ms(&mut self, ms: u16) {
Expand All @@ -81,16 +94,34 @@ impl DelayMs<u16> for Delay {
}
}

impl DelayMsAlpha<u16> for Delay {
type Error = Void;

/// Pauses execution for `ms` milliseconds
fn try_delay_ms(&mut self, ms: u16) -> Result<(), Self::Error> {
Ok(self.delay_ms(ms))
}
}

impl DelayMs<u8> for Delay {
/// Pauses execution for `ms` milliseconds
fn delay_ms(&mut self, ms: u8) {
self.delay_ms(ms as u16);
}
}

impl DelayMsAlpha<u8> for Delay {
type Error = Void;

/// Pauses execution for `ms` milliseconds
fn try_delay_ms(&mut self, ms: u8) -> Result<(), Self::Error> {
Ok(self.delay_ms(ms))
}
}

// At 30MHz (the maximum frequency), this overflows at approx. 2^32 / 30 = 146 seconds
impl DelayUs<u32> for Delay {
/// Pauses execution for `us` milliseconds
/// Pauses execution for `us` microseconds
fn delay_us(&mut self, us: u32) {
// The SysTick Reload Value register supports values between 1 and 0x00FFFFFF.
// Here half the maximum is used so we have some play if there's a long running interrupt.
Expand All @@ -108,7 +139,7 @@ impl DelayUs<u32> for Delay {
let start_count = SYST::get_current();
total_ticks -= current_ticks;

// Use the wrapping substraction and the modulo to deal with the systick wrapping around
// Use the wrapping subtraction and the modulo to deal with the systick wrapping around
// from 0 to 0xFFFF
while (start_count.wrapping_sub(SYST::get_current())
% SYSTICK_RANGE)
Expand All @@ -118,16 +149,43 @@ impl DelayUs<u32> for Delay {
}
}

impl DelayUsAlpha<u32> for Delay {
type Error = Void;

/// Pauses execution for `us` microseconds
fn try_delay_us(&mut self, us: u32) -> Result<(), Self::Error> {
Ok(self.delay_us(us))
}
}

impl DelayUs<u16> for Delay {
/// Pauses execution for `us` milliseconds
/// Pauses execution for `us` microseconds
fn delay_us(&mut self, us: u16) {
self.delay_us(us as u32)
}
}

impl DelayUsAlpha<u16> for Delay {
type Error = Void;

/// Pauses execution for `us` microseconds
fn try_delay_us(&mut self, us: u16) -> Result<(), Self::Error> {
Ok(self.delay_us(us))
}
}

impl DelayUs<u8> for Delay {
/// Pauses execution for `us` milliseconds
/// Pauses execution for `us` microseconds
fn delay_us(&mut self, us: u8) {
self.delay_us(us as u32)
}
}

impl DelayUsAlpha<u8> for Delay {
type Error = Void;

/// Pauses execution for `us` microseconds
fn try_delay_us(&mut self, us: u8) -> Result<(), Self::Error> {
Ok(self.delay_us(us))
}
}
66 changes: 66 additions & 0 deletions src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ use core::marker::PhantomData;
use embedded_hal::digital::v2::{
InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin,
};
use embedded_hal_alpha::digital::{
InputPin as InputPinAlpha, OutputPin as OutputPinAlpha,
StatefulOutputPin as StatefulOutputPinAlpha,
ToggleableOutputPin as ToggleableOutputPinAlpha,
};
use void::Void;

use crate::{
Expand Down Expand Up @@ -427,6 +432,23 @@ where
}
}

impl<T> InputPinAlpha for GpioPin<T, direction::Input>
where
T: pins::Trait,
{
type Error = Void;

fn try_is_high(&self) -> Result<bool, Self::Error> {
// Call the inherent method defined above.
Ok(self.is_high())
}

fn try_is_low(&self) -> Result<bool, Self::Error> {
// Call the inherent method defined above.
Ok(self.is_low())
}
}

impl<T> OutputPin for GpioPin<T, direction::Output>
where
T: pins::Trait,
Expand All @@ -444,6 +466,23 @@ where
}
}

impl<T> OutputPinAlpha for GpioPin<T, direction::Output>
where
T: pins::Trait,
{
type Error = Void;

fn try_set_high(&mut self) -> Result<(), Self::Error> {
// Call the inherent method defined above.
Ok(self.set_high())
}

fn try_set_low(&mut self) -> Result<(), Self::Error> {
// Call the inherent method defined above.
Ok(self.set_low())
}
}

impl<T> StatefulOutputPin for GpioPin<T, direction::Output>
where
T: pins::Trait,
Expand All @@ -459,6 +498,21 @@ where
}
}

impl<T> StatefulOutputPinAlpha for GpioPin<T, direction::Output>
where
T: pins::Trait,
{
fn try_is_set_high(&self) -> Result<bool, Self::Error> {
// Call the inherent method defined above.
Ok(self.is_set_high())
}

fn try_is_set_low(&self) -> Result<bool, Self::Error> {
// Call the inherent method defined above.
Ok(self.is_set_low())
}
}

impl<T> ToggleableOutputPin for GpioPin<T, direction::Output>
where
T: pins::Trait,
Expand All @@ -471,6 +525,18 @@ where
}
}

impl<T> ToggleableOutputPinAlpha for GpioPin<T, direction::Output>
where
T: pins::Trait,
{
type Error = Void;

fn try_toggle(&mut self) -> Result<(), Self::Error> {
// Call the inherent method defined above.
Ok(self.toggle())
}
}

/// The voltage level of a pin
#[derive(Debug)]
pub enum Level {
Expand Down
7 changes: 3 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ pub extern crate cortex_m;
#[cfg(feature = "rt-selected")]
pub extern crate cortex_m_rt;
pub extern crate embedded_hal;
pub extern crate embedded_hal_alpha;
pub extern crate nb;
pub extern crate void;

Expand Down Expand Up @@ -144,7 +145,7 @@ pub mod prelude {
pub use core::fmt::Write as _;

pub use crate::clock::{Enabled as _, Frequency as _};
pub use crate::hal::{digital::v2::*, prelude::*};
pub use crate::embedded_hal::{digital::v2::*, prelude::*};
pub use crate::sleep::Sleep as _;
}

Expand All @@ -171,8 +172,6 @@ pub use self::wkt::WKT;

pub use pac::CorePeripherals;

use embedded_hal as hal;

/// Provides access to all peripherals
///
/// This is the entry point to the HAL API. Before you can do anything else, you
Expand Down Expand Up @@ -490,7 +489,7 @@ impl Peripherals {
/// into a type state that allows you to execute operations that are known
/// to put the hardware in a safe state. Like forcing the type state for a
/// peripheral API to the "disabled" state, then enabling it, to make sure
/// it is enabled, regardless of wheter it was enabled before.
/// it is enabled, regardless of whether it was enabled before.
///
/// Since there are no means within this API to forcibly change type state,
/// you will need to resort to something like [`core::mem::transmute`].
Expand Down

0 comments on commit 39c548a

Please sign in to comment.