Skip to content

Commit

Permalink
Update to embedded-hal v1.0.0-alpha.1
Browse files Browse the repository at this point in the history
  • Loading branch information
maxekman committed Sep 13, 2020
1 parent eaefada commit a1316e8
Show file tree
Hide file tree
Showing 18 changed files with 329 additions and 237 deletions.
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ default-features = false
version = "1.0.2"

[dependencies.embedded-hal]
features = ["unproven"]
version = "0.2.3"
version = "=1.0.0-alpha.1"

[dev-dependencies]
panic-semihosting = "0.5.3"
Expand Down
8 changes: 4 additions & 4 deletions examples/delay-blinky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ fn main() -> ! {

loop {
// On for 1s, off for 1s.
led.set_high().unwrap();
delay.delay_ms(1000_u32);
led.set_low().unwrap();
delay.delay_ms(1000_u32);
led.try_set_high().unwrap();
delay.try_delay_ms(1000_u32).unwrap();
led.try_set_low().unwrap();
delay.try_delay_ms(1000_u32).unwrap();
}
}

Expand Down
6 changes: 3 additions & 3 deletions examples/pwm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ fn main() -> ! {

let pwm = pwm::tim1(dp.TIM1, channels, clocks, 20u32.khz());
let (mut ch1, _ch2) = pwm;
let max_duty = ch1.get_max_duty();
ch1.set_duty(max_duty / 2);
ch1.enable();
let max_duty = ch1.try_get_max_duty().unwrap();
ch1.try_set_duty(max_duty / 2);
ch1.try_enable();
}

loop {
Expand Down
2 changes: 1 addition & 1 deletion examples/rng-display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ fn main() -> ! {
}
disp.flush().unwrap();
//delay a little while between refreshes so the display is readable
delay_source.delay_ms(100u8);
delay_source.try_delay_ms(100u8).unwrap();
}
}

Expand Down
18 changes: 9 additions & 9 deletions examples/timer-syst.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Start and stop a periodic system timer.
//! Start and stop a periodic system timer.try_
//!
//! This example should run on all stm32f4xx boards but it was tested with
//! stm32f4-discovery board (model STM32F407G-DISC1).
Expand Down Expand Up @@ -36,29 +36,29 @@ fn main() -> ! {

hprintln!("hello!").unwrap();
// wait until timer expires
nb::block!(timer.wait()).unwrap();
nb::block!(timer.try_wait()).unwrap();
hprintln!("timer expired 1").unwrap();

// the function syst() creates a periodic timer, so it is automatically
// restarted
nb::block!(timer.wait()).unwrap();
nb::block!(timer.try_wait()).unwrap();
hprintln!("timer expired 2").unwrap();

// cancel current timer
timer.cancel().unwrap();
timer.try_cancel().unwrap();

// start it again
timer.start(24.hz());
nb::block!(timer.wait()).unwrap();
timer.try_start(24.hz());
nb::block!(timer.try_wait()).unwrap();
hprintln!("timer expired 3").unwrap();

timer.cancel().unwrap();
let cancel_outcome = timer.cancel();
timer.try_cancel().unwrap();
let cancel_outcome = timer.try_cancel();
assert_eq!(cancel_outcome, Err(timer::Error::Disabled));
hprintln!("ehy, you cannot cancel a timer two times!").unwrap();
// this time the timer was not restarted, therefore this function should
// wait forever
nb::block!(timer.wait()).unwrap();
nb::block!(timer.try_wait()).unwrap();
// you should never see this print
hprintln!("if you see this there is something wrong").unwrap();
panic!();
Expand Down
8 changes: 4 additions & 4 deletions src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ macro_rules! adc_pins {
$(
impl Channel<stm32::$adc> for $pin {
type ID = u8;
fn channel() -> u8 { $chan }
const CHANNEL: Self::ID = $chan;
}
)+
};
Expand Down Expand Up @@ -665,7 +665,7 @@ macro_rules! adc {
}

let vref_cal = VrefCal::get().read();
let vref_samp = self.read(&mut Vref).unwrap(); //This can't actually fail, it's just in a result to satisfy hal trait
let vref_samp = self.try_read(&mut Vref).unwrap(); //This can't actually fail, it's just in a result to satisfy hal trait

self.calibrated_vdda = (VDDA_CALIB * u32::from(vref_cal)) / u32::from(vref_samp);
if !vref_en {
Expand Down Expand Up @@ -873,7 +873,7 @@ macro_rules! adc {
}
});

let channel = CHANNEL::channel();
let channel = CHANNEL::CHANNEL;

//Set the channel in the right sequence field
match sequence {
Expand Down Expand Up @@ -976,7 +976,7 @@ macro_rules! adc {
{
type Error = ();

fn read(&mut self, pin: &mut PIN) -> nb::Result<u16, Self::Error> {
fn try_read(&mut self, pin: &mut PIN) -> nb::Result<u16, Self::Error> {
let enabled = self.is_enabled();
if !enabled {
self.enable();
Expand Down
38 changes: 27 additions & 11 deletions src/delay.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Delays

use cast::u32;
use core::convert::Infallible;

use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::peripheral::SYST;

Expand Down Expand Up @@ -28,25 +30,33 @@ impl Delay {
}

impl DelayMs<u32> for Delay {
fn delay_ms(&mut self, ms: u32) {
self.delay_us(ms * 1_000);
type Error = Infallible;

fn try_delay_ms(&mut self, ms: u32) -> Result<(), Self::Error> {
self.try_delay_us(ms * 1_000)
}
}

impl DelayMs<u16> for Delay {
fn delay_ms(&mut self, ms: u16) {
self.delay_ms(u32(ms));
type Error = Infallible;

fn try_delay_ms(&mut self, ms: u16) -> Result<(), Self::Error> {
self.try_delay_ms(u32(ms))
}
}

impl DelayMs<u8> for Delay {
fn delay_ms(&mut self, ms: u8) {
self.delay_ms(u32(ms));
type Error = Infallible;

fn try_delay_ms(&mut self, ms: u8) -> Result<(), Self::Error> {
self.try_delay_ms(u32(ms))
}
}

impl DelayUs<u32> for Delay {
fn delay_us(&mut self, us: u32) {
type Error = Infallible;

fn try_delay_us(&mut self, us: u32) -> Result<(), Self::Error> {
// The SysTick Reload Value register supports values between 1 and 0x00FFFFFF.
const MAX_RVR: u32 = 0x00FF_FFFF;

Expand All @@ -70,17 +80,23 @@ impl DelayUs<u32> for Delay {

self.syst.disable_counter();
}

Ok(())
}
}

impl DelayUs<u16> for Delay {
fn delay_us(&mut self, us: u16) {
self.delay_us(u32(us))
type Error = Infallible;

fn try_delay_us(&mut self, us: u16) -> Result<(), Self::Error> {
self.try_delay_us(u32(us))
}
}

impl DelayUs<u8> for Delay {
fn delay_us(&mut self, us: u8) {
self.delay_us(u32(us))
type Error = Infallible;

fn try_delay_us(&mut self, us: u8) -> Result<(), Self::Error> {
self.try_delay_us(u32(us))
}
}
23 changes: 16 additions & 7 deletions src/dwt.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
//! Debug and trace and stuff

use core::convert::Infallible;

use crate::rcc::Clocks;
use crate::time::Hertz;
use cortex_m::peripheral::{DCB, DWT};

use embedded_hal::blocking::delay::{DelayMs, DelayUs};

pub trait DwtExt {
Expand Down Expand Up @@ -65,13 +68,13 @@ pub struct Delay {
}
impl Delay {
/// Delay for `ClockDuration::ticks`
pub fn delay(duration: ClockDuration) {
pub fn try_delay(duration: ClockDuration) -> Result<(), Infallible> {
let ticks = duration.ticks as u64;
Delay::delay_ticks(DWT::get_cycle_count(), ticks);
Delay::try_delay_ticks(DWT::get_cycle_count(), ticks)
}
/// Delay ticks
/// NOTE DCB and DWT need to be set up for this to work, so it is private
fn delay_ticks(mut start: u32, ticks: u64) {
fn try_delay_ticks(mut start: u32, ticks: u64) -> Result<(), Infallible> {
if ticks < (core::u32::MAX / 2) as u64 {
// Simple delay
let ticks = ticks as u32;
Expand All @@ -96,24 +99,30 @@ impl Delay {
while (DWT::get_cycle_count().wrapping_sub(start)) > ticks {}
}
}

Ok(())
}
}

// Implement DelayUs/DelayMs for various integer types
impl<T: Into<u64>> DelayUs<T> for Delay {
fn delay_us(&mut self, us: T) {
type Error = Infallible;

fn try_delay_us(&mut self, us: T) -> Result<(), Self::Error> {
// Convert us to ticks
let start = DWT::get_cycle_count();
let ticks = (us.into() * self.clock.0 as u64) / 1_000_000;
Delay::delay_ticks(start, ticks);
Delay::try_delay_ticks(start, ticks)
}
}
impl<T: Into<u64>> DelayMs<T> for Delay {
fn delay_ms(&mut self, ms: T) {
type Error = Infallible;

fn try_delay_ms(&mut self, ms: T) -> Result<(), Self::Error> {
// Convert ms to ticks
let start = DWT::get_cycle_count();
let ticks = (ms.into() * self.clock.0 as u64) / 1_000;
Delay::delay_ticks(start, ticks);
Delay::try_delay_ticks(start, ticks)
}
}

Expand Down
46 changes: 23 additions & 23 deletions src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ macro_rules! gpio {
use core::marker::PhantomData;
use core::convert::Infallible;

use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, toggleable};
use embedded_hal::digital::{InputPin, OutputPin, StatefulOutputPin, toggleable};
use crate::stm32::$GPIOX;

use crate::stm32::{RCC, EXTI, SYSCFG};
Expand Down Expand Up @@ -293,25 +293,25 @@ macro_rules! gpio {
impl<MODE> OutputPin for $PXx<Output<MODE>> {
type Error = Infallible;

fn set_high(&mut self) -> Result<(), Self::Error> {
fn try_set_high(&mut self) -> Result<(), Self::Error> {
// NOTE(unsafe) atomic write to a stateless register
unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << self.i)) };
Ok(())
}

fn set_low(&mut self) -> Result<(), Self::Error> {
fn try_set_low(&mut self) -> Result<(), Self::Error> {
// NOTE(unsafe) atomic write to a stateless register
unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (self.i + 16))) };
Ok(())
}
}

impl<MODE> StatefulOutputPin for $PXx<Output<MODE>> {
fn is_set_high(&self) -> Result<bool, Self::Error> {
self.is_set_low().map(|v| !v)
fn try_is_set_high(&self) -> Result<bool, Self::Error> {
self.try_is_set_low().map(|v| !v)
}

fn is_set_low(&self) -> Result<bool, Self::Error> {
fn try_is_set_low(&self) -> Result<bool, Self::Error> {
// NOTE(unsafe) atomic read with no side effects
Ok(unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << self.i) == 0 })
}
Expand All @@ -322,11 +322,11 @@ macro_rules! gpio {
impl<MODE> InputPin for $PXx<Output<MODE>> {
type Error = Infallible;

fn is_high(&self) -> Result<bool, Self::Error> {
self.is_low().map(|v| !v)
fn try_is_high(&self) -> Result<bool, Self::Error> {
self.try_is_low().map(|v| !v)
}

fn is_low(&self) -> Result<bool, Self::Error> {
fn try_is_low(&self) -> Result<bool, Self::Error> {
// NOTE(unsafe) atomic read with no side effects
Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 })
}
Expand All @@ -335,11 +335,11 @@ macro_rules! gpio {
impl<MODE> InputPin for $PXx<Input<MODE>> {
type Error = Infallible;

fn is_high(&self) -> Result<bool, Self::Error> {
self.is_low().map(|v| !v)
fn try_is_high(&self) -> Result<bool, Self::Error> {
self.try_is_low().map(|v| !v)
}

fn is_low(&self) -> Result<bool, Self::Error> {
fn try_is_low(&self) -> Result<bool, Self::Error> {
// NOTE(unsafe) atomic read with no side effects
Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 })
}
Expand Down Expand Up @@ -754,25 +754,25 @@ macro_rules! gpio {
impl<MODE> OutputPin for $PXi<Output<MODE>> {
type Error = Infallible;

fn set_high(&mut self) -> Result<(), Self::Error> {
fn try_set_high(&mut self) -> Result<(), Self::Error> {
// NOTE(unsafe) atomic write to a stateless register
unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) };
Ok(())
}

fn set_low(&mut self) -> Result<(), Self::Error> {
fn try_set_low(&mut self) -> Result<(), Self::Error> {
// NOTE(unsafe) atomic write to a stateless register
unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << ($i + 16))) };
Ok(())
}
}

impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> {
fn is_set_high(&self) -> Result<bool, Self::Error> {
self.is_set_low().map(|v| !v)
fn try_is_set_high(&self) -> Result<bool, Self::Error> {
self.try_is_set_low().map(|v| !v)
}

fn is_set_low(&self) -> Result<bool, Self::Error> {
fn try_is_set_low(&self) -> Result<bool, Self::Error> {
// NOTE(unsafe) atomic read with no side effects
Ok(unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 })
}
Expand All @@ -783,11 +783,11 @@ macro_rules! gpio {
impl<MODE> InputPin for $PXi<Output<MODE>> {
type Error = Infallible;

fn is_high(&self) -> Result<bool, Self::Error> {
self.is_low().map(|v| !v)
fn try_is_high(&self) -> Result<bool, Self::Error> {
self.try_is_low().map(|v| !v)
}

fn is_low(&self) -> Result<bool, Self::Error> {
fn try_is_low(&self) -> Result<bool, Self::Error> {
// NOTE(unsafe) atomic read with no side effects
Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 })
}
Expand All @@ -796,11 +796,11 @@ macro_rules! gpio {
impl<MODE> InputPin for $PXi<Input<MODE>> {
type Error = Infallible;

fn is_high(&self) -> Result<bool, Self::Error> {
self.is_low().map(|v| !v)
fn try_is_high(&self) -> Result<bool, Self::Error> {
self.try_is_low().map(|v| !v)
}

fn is_low(&self) -> Result<bool, Self::Error> {
fn try_is_low(&self) -> Result<bool, Self::Error> {
// NOTE(unsafe) atomic read with no side effects
Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 })
}
Expand Down
Loading

0 comments on commit a1316e8

Please sign in to comment.