Skip to content

Commit 36a479e

Browse files
authored
Merge pull request #431 from qwandor/embedded-hal
Implement embedded-hal 1.0 traits
2 parents ceb90bb + a2f7254 commit 36a479e

File tree

15 files changed

+595
-114
lines changed

15 files changed

+595
-114
lines changed

nrf-hal-common/Cargo.toml

+8-1
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,17 @@ version = "0.12.2"
7676
version = "0.2.0"
7777
optional = true
7878

79-
[dependencies.embedded-hal]
79+
[dependencies.embedded-hal-02]
80+
package = "embedded-hal"
8081
features = ["unproven"]
8182
version = "0.2.4"
8283

84+
[dependencies.embedded-hal]
85+
version = "1.0.0"
86+
87+
[dependencies.embedded-io]
88+
version = "0.6.1"
89+
8390
[features]
8491
doc = []
8592
51 = ["nrf51-pac"]

nrf-hal-common/src/adc.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! API for the Analog to Digital converter.
22
3-
use embedded_hal::adc::{Channel, OneShot};
3+
use embedded_hal_02::adc::{Channel, OneShot};
44

55
use core::hint::unreachable_unchecked;
66

@@ -128,7 +128,7 @@ macro_rules! channel_mappings {
128128
impl Channel<Adc> for $pin {
129129
type ID = u8;
130130

131-
fn channel() -> <Self as embedded_hal::adc::Channel<Adc>>::ID {
131+
fn channel() -> <Self as embedded_hal_02::adc::Channel<Adc>>::ID {
132132
$n
133133
}
134134
}

nrf-hal-common/src/delay.rs

+29-20
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
//! Delays.
2-
use cast::u32;
3-
use cortex_m::peripheral::syst::SystClkSource;
4-
use cortex_m::peripheral::SYST;
52
63
use crate::clocks::HFCLK_FREQ;
7-
use crate::hal::blocking::delay::{DelayMs, DelayUs};
4+
use core::convert::TryInto;
5+
use cortex_m::peripheral::syst::SystClkSource;
6+
use cortex_m::peripheral::SYST;
7+
use embedded_hal::delay::DelayNs;
8+
use embedded_hal_02::blocking::delay::{DelayMs, DelayUs};
89

910
/// System timer (SysTick) as a delay provider.
1011
pub struct Delay {
@@ -27,28 +28,48 @@ impl Delay {
2728

2829
impl DelayMs<u32> for Delay {
2930
fn delay_ms(&mut self, ms: u32) {
30-
self.delay_us(ms * 1_000);
31+
DelayNs::delay_ms(self, ms);
3132
}
3233
}
3334

3435
impl DelayMs<u16> for Delay {
3536
fn delay_ms(&mut self, ms: u16) {
36-
self.delay_ms(u32(ms));
37+
DelayNs::delay_ms(self, ms.into());
3738
}
3839
}
3940

4041
impl DelayMs<u8> for Delay {
4142
fn delay_ms(&mut self, ms: u8) {
42-
self.delay_ms(u32(ms));
43+
DelayNs::delay_ms(self, ms.into());
4344
}
4445
}
4546

4647
impl DelayUs<u32> for Delay {
4748
fn delay_us(&mut self, us: u32) {
49+
DelayNs::delay_us(self, us);
50+
}
51+
}
52+
53+
impl DelayUs<u16> for Delay {
54+
fn delay_us(&mut self, us: u16) {
55+
DelayNs::delay_us(self, us.into());
56+
}
57+
}
58+
59+
impl DelayUs<u8> for Delay {
60+
fn delay_us(&mut self, us: u8) {
61+
DelayNs::delay_us(self, us.into());
62+
}
63+
}
64+
65+
impl DelayNs for Delay {
66+
fn delay_ns(&mut self, ns: u32) {
4867
// The SysTick Reload Value register supports values between 1 and 0x00FFFFFF.
4968
const MAX_RVR: u32 = 0x00FF_FFFF;
5069

51-
let mut total_rvr = us * (HFCLK_FREQ / 1_000_000);
70+
let mut total_rvr: u32 = (u64::from(ns) * u64::from(HFCLK_FREQ) / 1_000_000_000)
71+
.try_into()
72+
.unwrap();
5273

5374
while total_rvr != 0 {
5475
let current_rvr = if total_rvr <= MAX_RVR {
@@ -70,15 +91,3 @@ impl DelayUs<u32> for Delay {
7091
}
7192
}
7293
}
73-
74-
impl DelayUs<u16> for Delay {
75-
fn delay_us(&mut self, us: u16) {
76-
self.delay_us(u32(us))
77-
}
78-
}
79-
80-
impl DelayUs<u8> for Delay {
81-
fn delay_us(&mut self, us: u8) {
82-
self.delay_us(u32(us))
83-
}
84-
}

nrf-hal-common/src/gpio.rs

+117-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::marker::PhantomData;
1+
use core::{convert::Infallible, marker::PhantomData};
22

33
/// Disconnected pin in input mode (type state, reset value).
44
pub struct Disconnected;
@@ -85,7 +85,7 @@ use crate::pac::P1;
8585
#[cfg(feature = "5340-net")]
8686
use crate::pac::P1_NS as P1;
8787

88-
use crate::hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
88+
use embedded_hal::digital::{ErrorType, InputPin, OutputPin, StatefulOutputPin};
8989
use void::Void;
9090

9191
impl<MODE> Pin<MODE> {
@@ -348,7 +348,63 @@ impl<MODE> Pin<MODE> {
348348
}
349349
}
350350

351+
impl<MODE> ErrorType for Pin<MODE> {
352+
type Error = Infallible;
353+
}
354+
351355
impl<MODE> InputPin for Pin<Input<MODE>> {
356+
fn is_high(&mut self) -> Result<bool, Self::Error> {
357+
self.is_low().map(|v| !v)
358+
}
359+
360+
fn is_low(&mut self) -> Result<bool, Self::Error> {
361+
Ok(self.block().in_.read().bits() & (1 << self.pin()) == 0)
362+
}
363+
}
364+
365+
impl InputPin for Pin<Output<OpenDrainIO>> {
366+
fn is_high(&mut self) -> Result<bool, Self::Error> {
367+
self.is_low().map(|v| !v)
368+
}
369+
370+
fn is_low(&mut self) -> Result<bool, Self::Error> {
371+
Ok(self.block().in_.read().bits() & (1 << self.pin()) == 0)
372+
}
373+
}
374+
375+
impl<MODE> OutputPin for Pin<Output<MODE>> {
376+
fn set_high(&mut self) -> Result<(), Self::Error> {
377+
// NOTE(unsafe) atomic write to a stateless register - TODO(AJM) verify?
378+
// TODO - I wish I could do something like `.pins$i()`...
379+
unsafe {
380+
self.block().outset.write(|w| w.bits(1u32 << self.pin()));
381+
}
382+
Ok(())
383+
}
384+
385+
fn set_low(&mut self) -> Result<(), Self::Error> {
386+
// NOTE(unsafe) atomic write to a stateless register - TODO(AJM) verify?
387+
// TODO - I wish I could do something like `.pins$i()`...
388+
unsafe {
389+
self.block().outclr.write(|w| w.bits(1u32 << self.pin()));
390+
}
391+
Ok(())
392+
}
393+
}
394+
395+
impl<MODE> StatefulOutputPin for Pin<Output<MODE>> {
396+
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
397+
self.is_set_low().map(|v| !v)
398+
}
399+
400+
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
401+
// NOTE(unsafe) atomic read with no side effects - TODO(AJM) verify?
402+
// TODO - I wish I could do something like `.pins$i()`...
403+
Ok(self.block().out.read().bits() & (1 << self.pin()) == 0)
404+
}
405+
}
406+
407+
impl<MODE> embedded_hal_02::digital::v2::InputPin for Pin<Input<MODE>> {
352408
type Error = Void;
353409

354410
fn is_high(&self) -> Result<bool, Self::Error> {
@@ -360,7 +416,7 @@ impl<MODE> InputPin for Pin<Input<MODE>> {
360416
}
361417
}
362418

363-
impl InputPin for Pin<Output<OpenDrainIO>> {
419+
impl embedded_hal_02::digital::v2::InputPin for Pin<Output<OpenDrainIO>> {
364420
type Error = Void;
365421

366422
fn is_high(&self) -> Result<bool, Self::Error> {
@@ -372,7 +428,7 @@ impl InputPin for Pin<Output<OpenDrainIO>> {
372428
}
373429
}
374430

375-
impl<MODE> OutputPin for Pin<Output<MODE>> {
431+
impl<MODE> embedded_hal_02::digital::v2::OutputPin for Pin<Output<MODE>> {
376432
type Error = Void;
377433

378434
/// Set the output as high.
@@ -396,7 +452,7 @@ impl<MODE> OutputPin for Pin<Output<MODE>> {
396452
}
397453
}
398454

399-
impl<MODE> StatefulOutputPin for Pin<Output<MODE>> {
455+
impl<MODE> embedded_hal_02::digital::v2::StatefulOutputPin for Pin<Output<MODE>> {
400456
/// Is the output pin set as high?
401457
fn is_set_high(&self) -> Result<bool, Self::Error> {
402458
self.is_set_low().map(|v| !v)
@@ -482,10 +538,10 @@ macro_rules! gpio {
482538
$PX
483539
};
484540

485-
use crate::hal::digital::v2::{OutputPin, StatefulOutputPin, InputPin};
541+
use core::convert::Infallible;
542+
use embedded_hal::digital::{ErrorType, InputPin, OutputPin, StatefulOutputPin};
486543
use void::Void;
487544

488-
489545
// ===============================================================
490546
// This chunk allows you to obtain an nrf-hal gpio from the
491547
// upstream nrf52 gpio definitions by defining a trait
@@ -695,7 +751,58 @@ macro_rules! gpio {
695751
}
696752
}
697753

754+
impl<MODE> ErrorType for $PXi<MODE> {
755+
type Error = Infallible;
756+
}
757+
698758
impl<MODE> InputPin for $PXi<Input<MODE>> {
759+
fn is_high(&mut self) -> Result<bool, Self::Error> {
760+
self.is_low().map(|v| !v)
761+
}
762+
763+
fn is_low(&mut self) -> Result<bool, Self::Error> {
764+
Ok(unsafe { ((*$PX::ptr()).in_.read().bits() & (1 << $i)) == 0 })
765+
}
766+
}
767+
768+
impl InputPin for $PXi<Output<OpenDrainIO>> {
769+
fn is_high(&mut self) -> Result<bool, Self::Error> {
770+
self.is_low().map(|v| !v)
771+
}
772+
773+
fn is_low(&mut self) -> Result<bool, Self::Error> {
774+
Ok(unsafe { ((*$PX::ptr()).in_.read().bits() & (1 << $i)) == 0 })
775+
}
776+
}
777+
impl<MODE> OutputPin for $PXi<Output<MODE>> {
778+
fn set_high(&mut self) -> Result<(), Self::Error> {
779+
// NOTE(unsafe) atomic write to a stateless register - TODO(AJM) verify?
780+
// TODO - I wish I could do something like `.pins$i()`...
781+
unsafe { (*$PX::ptr()).outset.write(|w| w.bits(1u32 << $i)); }
782+
Ok(())
783+
}
784+
785+
fn set_low(&mut self) -> Result<(), Self::Error> {
786+
// NOTE(unsafe) atomic write to a stateless register - TODO(AJM) verify?
787+
// TODO - I wish I could do something like `.pins$i()`...
788+
unsafe { (*$PX::ptr()).outclr.write(|w| w.bits(1u32 << $i)); }
789+
Ok(())
790+
}
791+
}
792+
793+
impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> {
794+
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
795+
self.is_set_low().map(|v| !v)
796+
}
797+
798+
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
799+
// NOTE(unsafe) atomic read with no side effects - TODO(AJM) verify?
800+
// TODO - I wish I could do something like `.pins$i()`...
801+
Ok(unsafe { ((*$PX::ptr()).out.read().bits() & (1 << $i)) == 0 })
802+
}
803+
}
804+
805+
impl<MODE> embedded_hal_02::digital::v2::InputPin for $PXi<Input<MODE>> {
699806
type Error = Void;
700807

701808
fn is_high(&self) -> Result<bool, Self::Error> {
@@ -707,7 +814,7 @@ macro_rules! gpio {
707814
}
708815
}
709816

710-
impl InputPin for $PXi<Output<OpenDrainIO>> {
817+
impl embedded_hal_02::digital::v2::InputPin for $PXi<Output<OpenDrainIO>> {
711818
type Error = Void;
712819

713820
fn is_high(&self) -> Result<bool, Self::Error> {
@@ -725,7 +832,7 @@ macro_rules! gpio {
725832
}
726833
}
727834

728-
impl<MODE> OutputPin for $PXi<Output<MODE>> {
835+
impl<MODE> embedded_hal_02::digital::v2::OutputPin for $PXi<Output<MODE>> {
729836
type Error = Void;
730837

731838
/// Set the output as high
@@ -745,7 +852,7 @@ macro_rules! gpio {
745852
}
746853
}
747854

748-
impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> {
855+
impl<MODE> embedded_hal_02::digital::v2::StatefulOutputPin for $PXi<Output<MODE>> {
749856
/// Is the output pin set as high?
750857
fn is_set_high(&self) -> Result<bool, Self::Error> {
751858
self.is_set_low().map(|v| !v)

nrf-hal-common/src/ieee802154.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use core::{
66
sync::atomic::{self, Ordering},
77
};
88

9-
use embedded_hal::timer::CountDown as _;
9+
use embedded_hal_02::timer::CountDown as _;
1010

1111
use crate::{
1212
clocks::{Clocks, ExternalOscillator},

nrf-hal-common/src/lib.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
#![doc(html_root_url = "https://docs.rs/nrf-hal-common/0.16.1")]
55
#![no_std]
66

7-
use embedded_hal as hal;
8-
97
#[cfg(feature = "51")]
108
pub use nrf51_pac as pac;
119

@@ -114,8 +112,8 @@ pub mod usbd;
114112
pub mod wdt;
115113

116114
pub mod prelude {
117-
pub use crate::hal::digital::v2::*;
118-
pub use crate::hal::prelude::*;
115+
pub use embedded_hal_02::digital::v2::*;
116+
pub use embedded_hal_02::prelude::*;
119117

120118
#[cfg(not(any(feature = "9160", feature = "5340-app", feature = "5340-net")))]
121119
pub use crate::ppi::{ConfigurablePpi, Ppi};

0 commit comments

Comments
 (0)