Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,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
12 changes: 7 additions & 5 deletions src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/

use crate::{gpio::*, signature::VrefCal, signature::VDDA_CALIB, stm32};
use core::convert::Infallible;
use core::fmt;
use embedded_hal::adc::{Channel, OneShot};

Expand All @@ -26,7 +27,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 @@ -633,6 +634,7 @@ macro_rules! adc {

//Probably unnecessary to disable the ADC in most cases but it shouldn't do any harm either
s.disable();

s.apply_config(config);

s.enable();
Expand Down Expand Up @@ -665,7 +667,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 +875,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 @@ -974,9 +976,9 @@ macro_rules! adc {
where
PIN: Channel<stm32::$adc_type, ID=u8>,
{
type Error = ();
type Error = Infallible;

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
40 changes: 29 additions & 11 deletions src/delay.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! 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 +29,36 @@ 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)?;
Ok(())
}
}

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))?;
Ok(())
}
}

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))?;
Ok(())
}
}

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 +82,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))
}
}
11 changes: 9 additions & 2 deletions src/dwt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use crate::rcc::Clocks;
use crate::time::Hertz;
use core::convert::Infallible;
use cortex_m::peripheral::{DCB, DWT};
use embedded_hal::blocking::delay::{DelayMs, DelayUs};

Expand Down Expand Up @@ -101,19 +102,25 @@ impl Delay {

// 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<(), Infallible> {
// 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);
Ok(())
}
}
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<(), Infallible> {
// 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);
Ok(())
}
}

Expand Down
46 changes: 23 additions & 23 deletions src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,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 @@ -150,25 +150,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 @@ -179,11 +179,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 @@ -192,11 +192,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 @@ -670,25 +670,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 @@ -699,11 +699,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 @@ -712,11 +712,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
15 changes: 10 additions & 5 deletions src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -739,9 +739,14 @@ where
{
type Error = Error;

fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
self.write(addr, bytes)?;
self.read(addr, buffer)?;
fn try_write_read(
&mut self,
addr: u8,
bytes: &[u8],
buffer: &mut [u8],
) -> Result<(), Self::Error> {
self.try_write(addr, bytes)?;
self.try_read(addr, buffer)?;

Ok(())
}
Expand All @@ -753,7 +758,7 @@ where
{
type Error = Error;

fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
fn try_write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
// Send a START condition
self.i2c.cr1.modify(|_, w| w.start().set_bit());

Expand Down Expand Up @@ -793,7 +798,7 @@ where
{
type Error = Error;

fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
fn try_read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
if let Some((last, buffer)) = buffer.split_last_mut() {
// Send a START condition and set ACK bit
self.i2c
Expand Down
4 changes: 3 additions & 1 deletion src/otg_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ unsafe impl UsbPeripheral for USB {
const HIGH_SPEED: bool = false;
const FIFO_DEPTH_WORDS: usize = 320;

fn enable() {
fn try_enable() -> Result<(), Infallible> {
let rcc = unsafe { &*stm32::RCC::ptr() };

cortex_m::interrupt::free(|_| {
Expand All @@ -40,6 +40,8 @@ unsafe impl UsbPeripheral for USB {
rcc.ahb2rstr.modify(|_, w| w.otgfsrst().set_bit());
rcc.ahb2rstr.modify(|_, w| w.otgfsrst().clear_bit());
});

Ok(())
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/otg_hs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ unsafe impl UsbPeripheral for USB {
const HIGH_SPEED: bool = true;
const FIFO_DEPTH_WORDS: usize = 1024;

fn enable() {
fn try_enable() -> Result<(), Infallible> {
let rcc = unsafe { &*stm32::RCC::ptr() };

cortex_m::interrupt::free(|_| {
Expand All @@ -43,6 +43,8 @@ unsafe impl UsbPeripheral for USB {
rcc.ahb1rstr.modify(|_, w| w.otghsrst().set_bit());
rcc.ahb1rstr.modify(|_, w| w.otghsrst().clear_bit());
});

Ok(())
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub use embedded_hal::digital::v2::InputPin as _embedded_hal_digital_v2_InputPin;
pub use embedded_hal::digital::v2::OutputPin as _embedded_hal_digital_v2_OutputPin;
pub use embedded_hal::digital::v2::StatefulOutputPin as _embedded_hal_digital_v2_StatefulOutputPin;
pub use embedded_hal::digital::v2::ToggleableOutputPin as _embedded_hal_digital_v2_ToggleableOutputPin;
pub use embedded_hal::digital::InputPin as _embedded_hal_digital_v2_InputPin;
pub use embedded_hal::digital::OutputPin as _embedded_hal_digital_v2_OutputPin;
pub use embedded_hal::digital::StatefulOutputPin as _embedded_hal_digital_v2_StatefulOutputPin;
pub use embedded_hal::digital::ToggleableOutputPin as _embedded_hal_digital_v2_ToggleableOutputPin;
pub use embedded_hal::prelude::*;

pub use crate::gpio::GpioExt as _stm32f4xx_hal_gpio_GpioExt;
Expand Down
Loading