Implement embedded-hal 1.0.0-alpha.7 traits (#298)

* embedded-hal v1.0.0-alpha.7 removed several traits

* bump dependency to embedded-hal 1.0.0-alpha.7

* Mention embedded-hal alpha changes in changelog
This commit is contained in:
Jan Niehusmann 2022-02-26 11:06:55 +01:00 committed by GitHub
parent b7e56d0869
commit 7750781650
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 137 additions and 192 deletions

View file

@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- None
- Updated embedded-hal alpha support to version 1.0.0-alpha.7
## [0.3.0] - 2021-12-19

View file

@ -12,7 +12,7 @@ license = "MIT OR Apache-2.0"
[dependencies]
cortex-m = "0.7.2"
embedded-hal = { version = "0.2.5", features = ["unproven"] }
eh1_0_alpha = { version = "=1.0.0-alpha.6", package="embedded-hal", optional=true }
eh1_0_alpha = { version = "=1.0.0-alpha.7", package="embedded-hal", optional=true }
embedded-time = "0.12.0"
itertools = { version = "0.10.1", default-features = false }
nb = "1.0"

View file

@ -79,7 +79,7 @@ use super::reg::RegisterInterface;
use core::convert::TryFrom;
#[cfg(feature = "eh1_0_alpha")]
use eh1_0_alpha::digital::blocking as eh1;
use eh1_0_alpha::digital as eh1;
use hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
//==============================================================================
@ -545,8 +545,12 @@ impl StatefulOutputPin for DynPin {
}
#[cfg(feature = "eh1_0_alpha")]
impl eh1::OutputPin for DynPin {
impl eh1::ErrorType for DynPin {
type Error = Error;
}
#[cfg(feature = "eh1_0_alpha")]
impl eh1::blocking::OutputPin for DynPin {
#[inline]
fn set_high(&mut self) -> Result<(), Self::Error> {
self._set_high()
@ -558,8 +562,7 @@ impl eh1::OutputPin for DynPin {
}
#[cfg(feature = "eh1_0_alpha")]
impl eh1::InputPin for DynPin {
type Error = Error;
impl eh1::blocking::InputPin for DynPin {
#[inline]
fn is_high(&self) -> Result<bool, Self::Error> {
self._is_high()
@ -571,8 +574,7 @@ impl eh1::InputPin for DynPin {
}
#[cfg(feature = "eh1_0_alpha")]
impl eh1::ToggleableOutputPin for DynPin {
type Error = Error;
impl eh1::blocking::ToggleableOutputPin for DynPin {
#[inline]
fn toggle(&mut self) -> Result<(), Self::Error> {
self._toggle()
@ -580,7 +582,7 @@ impl eh1::ToggleableOutputPin for DynPin {
}
#[cfg(feature = "eh1_0_alpha")]
impl eh1::StatefulOutputPin for DynPin {
impl eh1::blocking::StatefulOutputPin for DynPin {
#[inline]
fn is_set_high(&self) -> Result<bool, Self::Error> {
self._is_set_high()

View file

@ -104,7 +104,7 @@ use core::marker::PhantomData;
use crate::gpio::dynpin::DynFunction;
#[cfg(feature = "eh1_0_alpha")]
use eh1_0_alpha::digital::blocking as eh1;
use eh1_0_alpha::digital as eh1;
use hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
use core::mem::transmute;
@ -845,12 +845,20 @@ where
}
#[cfg(feature = "eh1_0_alpha")]
impl<I, C> eh1::OutputPin for Pin<I, Output<C>>
impl<I, C> eh1::ErrorType for Pin<I, Output<C>>
where
I: PinId,
C: OutputConfig,
{
type Error = Infallible;
}
#[cfg(feature = "eh1_0_alpha")]
impl<I, C> eh1::blocking::OutputPin for Pin<I, Output<C>>
where
I: PinId,
C: OutputConfig,
{
#[inline]
fn set_high(&mut self) -> Result<(), Self::Error> {
self._set_high();
@ -864,11 +872,10 @@ where
}
#[cfg(feature = "eh1_0_alpha")]
impl<I> eh1::InputPin for Pin<I, ReadableOutput>
impl<I> eh1::blocking::InputPin for Pin<I, ReadableOutput>
where
I: PinId,
{
type Error = Infallible;
#[inline]
fn is_high(&self) -> Result<bool, Self::Error> {
Ok(self._is_high())
@ -880,12 +887,20 @@ where
}
#[cfg(feature = "eh1_0_alpha")]
impl<I, C> eh1::InputPin for Pin<I, Input<C>>
impl<I, C> eh1::ErrorType for Pin<I, Input<C>>
where
I: PinId,
C: InputConfig,
{
type Error = Infallible;
}
#[cfg(feature = "eh1_0_alpha")]
impl<I, C> eh1::blocking::InputPin for Pin<I, Input<C>>
where
I: PinId,
C: InputConfig,
{
#[inline]
fn is_high(&self) -> Result<bool, Self::Error> {
Ok(self._is_high())
@ -897,12 +912,11 @@ where
}
#[cfg(feature = "eh1_0_alpha")]
impl<I, C> eh1::ToggleableOutputPin for Pin<I, Output<C>>
impl<I, C> eh1::blocking::ToggleableOutputPin for Pin<I, Output<C>>
where
I: PinId,
C: OutputConfig,
{
type Error = Infallible;
#[inline]
fn toggle(&mut self) -> Result<(), Self::Error> {
self._toggle();
@ -911,7 +925,7 @@ where
}
#[cfg(feature = "eh1_0_alpha")]
impl<I, C> eh1::StatefulOutputPin for Pin<I, Output<C>>
impl<I, C> eh1::blocking::StatefulOutputPin for Pin<I, Output<C>>
where
I: PinId,
C: OutputConfig,

View file

@ -10,7 +10,7 @@ use hal::blocking::i2c::{Read, Write, WriteRead};
use pac::{i2c0::RegisterBlock as Block, RESETS};
#[cfg(feature = "eh1_0_alpha")]
use eh1_0_alpha::i2c::blocking as eh1;
use eh1_0_alpha::i2c as eh1;
use super::{i2c_reserved_addr, Controller, Error, SclPin, SdaPin, I2C};
@ -160,7 +160,12 @@ impl<T: Deref<Target = Block>, PINS> I2C<T, PINS, Controller> {
}
}
fn read_internal(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
fn read_internal(
&mut self,
buffer: &mut [u8],
force_restart: bool,
do_stop: bool,
) -> Result<(), Error> {
let lastindex = buffer.len() - 1;
for (i, byte) in buffer.iter_mut().enumerate() {
let first = i == 0;
@ -170,13 +175,13 @@ impl<T: Deref<Target = Block>, PINS> I2C<T, PINS, Controller> {
while self.tx_fifo_full() {}
self.i2c.ic_data_cmd.write(|w| {
if first {
if force_restart && first {
w.restart().enable();
} else {
w.restart().disable();
}
if last {
if do_stop && last {
w.stop().enable();
} else {
w.stop().disable();
@ -246,7 +251,7 @@ impl<T: Deref<Target = Block>, PINS> Read for I2C<T, PINS, Controller> {
Self::validate(addr, None, Some(buffer.is_empty()))?;
self.setup(addr);
self.read_internal(buffer)
self.read_internal(buffer, true, true)
}
}
impl<T: Deref<Target = Block>, PINS> WriteRead for I2C<T, PINS, Controller> {
@ -259,7 +264,7 @@ impl<T: Deref<Target = Block>, PINS> WriteRead for I2C<T, PINS, Controller> {
self.setup(addr);
self.write_internal(tx, false)?;
self.read_internal(rx)
self.read_internal(rx, true, true)
}
}
impl<T: Deref<Target = Block>, PINS> Write for I2C<T, PINS, Controller> {
@ -275,26 +280,90 @@ impl<T: Deref<Target = Block>, PINS> Write for I2C<T, PINS, Controller> {
}
#[cfg(feature = "eh1_0_alpha")]
impl<T: Deref<Target = Block>, PINS> eh1::Write for I2C<T, PINS, Controller> {
impl<T: Deref<Target = Block>, PINS> eh1::ErrorType for I2C<T, PINS, Controller> {
type Error = Error;
}
#[cfg(feature = "eh1_0_alpha")]
impl<T: Deref<Target = Block>, PINS> eh1::blocking::I2c for I2C<T, PINS, Controller> {
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
Write::write(self, addr, bytes)
}
}
#[cfg(feature = "eh1_0_alpha")]
impl<T: Deref<Target = Block>, PINS> eh1::WriteRead for I2C<T, PINS, Controller> {
type Error = Error;
fn write_iter<B>(&mut self, address: u8, bytes: B) -> Result<(), Self::Error>
where
B: IntoIterator<Item = u8>,
{
let mut peekable = bytes.into_iter().peekable();
let addr: u16 = address.into();
Self::validate(addr, Some(peekable.peek().is_none()), None)?;
self.setup(addr);
while let Some(tx) = peekable.next() {
self.write_internal(&[tx], peekable.peek().is_none())?
}
Ok(())
}
fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
WriteRead::write_read(self, addr, bytes, buffer)
}
}
#[cfg(feature = "eh1_0_alpha")]
impl<T: Deref<Target = Block>, PINS> eh1::Read for I2C<T, PINS, Controller> {
type Error = Error;
fn write_iter_read<B>(
&mut self,
address: u8,
bytes: B,
buffer: &mut [u8],
) -> Result<(), Self::Error>
where
B: IntoIterator<Item = u8>,
{
let mut peekable = bytes.into_iter().peekable();
let addr: u16 = address.into();
Self::validate(addr, Some(peekable.peek().is_none()), None)?;
self.setup(addr);
for tx in peekable {
self.write_internal(&[tx], false)?
}
self.read_internal(buffer, true, true)
}
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
Read::read(self, addr, buffer)
}
fn transaction<'a>(
&mut self,
address: u8,
operations: &mut [eh1::blocking::Operation<'a>],
) -> Result<(), Self::Error> {
let addr: u16 = address.into();
self.setup(addr);
for i in 0..operations.len() {
let last = i == operations.len() - 1;
match &mut operations[i] {
eh1::blocking::Operation::Read(buf) => self.read_internal(buf, false, last)?,
eh1::blocking::Operation::Write(buf) => self.write_internal(buf, last)?,
}
}
Ok(())
}
fn transaction_iter<'a, O>(&mut self, address: u8, operations: O) -> Result<(), Self::Error>
where
O: IntoIterator<Item = eh1::blocking::Operation<'a>>,
{
let addr: u16 = address.into();
self.setup(addr);
let mut peekable = operations.into_iter().peekable();
while let Some(operation) = peekable.next() {
let last = peekable.peek().is_none();
match operation {
eh1::blocking::Operation::Read(buf) => self.read_internal(buf, false, last)?,
eh1::blocking::Operation::Write(buf) => self.write_internal(buf, last)?,
}
}
Ok(())
}
}

View file

@ -87,8 +87,6 @@ use crate::{
resets::SubsystemReset,
typelevel::Sealed,
};
#[cfg(feature = "eh1_0_alpha")]
use eh1_0_alpha::pwm::blocking as eh1;
use embedded_hal::PwmPin;
use pac::PWM;
@ -616,38 +614,6 @@ impl<S: SliceId, M: SliceMode> PwmPin for Channel<S, M, A> {
}
}
#[cfg(feature = "eh1_0_alpha")]
impl<S: SliceId, M: SliceMode> eh1::PwmPin for Channel<S, M, A> {
type Duty = u16;
type Error = core::convert::Infallible;
/// We cant disable the channel without disturbing the other channel.
/// So this just sets the duty cycle to zero
fn disable(&mut self) -> Result<(), Self::Error> {
self.duty_cycle = self.regs.read_cc_a();
self.regs.write_cc_a(0);
Ok(())
}
fn enable(&mut self) -> Result<(), Self::Error> {
self.regs.write_cc_a(self.duty_cycle);
Ok(())
}
fn get_duty(&self) -> Result<Self::Duty, Self::Error> {
Ok(self.regs.read_cc_a())
}
fn get_max_duty(&self) -> Result<Self::Duty, Self::Error> {
Ok(self.regs.read_top())
}
fn set_duty(&mut self, duty: Self::Duty) -> Result<(), Self::Error> {
self.regs.write_cc_a(duty);
Ok(())
}
}
impl<S: SliceId, M: SliceMode> PwmPin for Channel<S, M, B> {
type Duty = u16;
@ -674,37 +640,6 @@ impl<S: SliceId, M: SliceMode> PwmPin for Channel<S, M, B> {
self.regs.write_cc_b(duty)
}
}
#[cfg(feature = "eh1_0_alpha")]
impl<S: SliceId, M: SliceMode> eh1::PwmPin for Channel<S, M, B> {
type Duty = u16;
type Error = core::convert::Infallible;
/// We cant disable the channel without disturbing the other channel.
/// So this just sets the duty cycle to zero
fn disable(&mut self) -> Result<(), Self::Error> {
self.duty_cycle = self.regs.read_cc_b();
self.regs.write_cc_b(0);
Ok(())
}
fn enable(&mut self) -> Result<(), Self::Error> {
self.regs.write_cc_b(self.duty_cycle);
Ok(())
}
fn get_duty(&self) -> Result<Self::Duty, Self::Error> {
Ok(self.regs.read_cc_b())
}
fn get_max_duty(&self) -> Result<Self::Duty, Self::Error> {
Ok(self.regs.read_top())
}
fn set_duty(&mut self, duty: Self::Duty) -> Result<(), Self::Error> {
self.regs.write_cc_b(duty);
Ok(())
}
}
impl<S: SliceId, M: SliceMode + ValidSliceMode<S>> Channel<S, M, A> {
/// Capture a gpio pin and use it as pwm output for channel A

View file

@ -243,9 +243,12 @@ macro_rules! impl_write {
impl<D: SpiDevice> spi::write_iter::Default<$type> for Spi<Enabled, D, $nr> {}
#[cfg(feature = "eh1_0_alpha")]
impl<D: SpiDevice> eh1::nb::FullDuplex<$type> for Spi<Enabled, D, $nr> {
impl<D: SpiDevice> eh1::ErrorType for Spi<Enabled, D, $nr> {
type Error = SpiInfallible;
}
#[cfg(feature = "eh1_0_alpha")]
impl<D: SpiDevice> eh1::nb::FullDuplex<$type> for Spi<Enabled, D, $nr> {
fn read(&mut self) -> Result<$type, nb::Error<SpiInfallible>> {
if !self.is_readable() {
return Err(nb::Error::WouldBlock);

View file

@ -133,38 +133,7 @@ impl embedded_hal::timer::CountDown for CountDown<'_> {
}
}
#[cfg(feature = "eh1_0_alpha")]
impl eh1_0_alpha::timer::nb::CountDown for CountDown<'_> {
type Time = embedded_time::duration::Microseconds<u64>;
type Error = &'static str;
fn start<T>(&mut self, count: T) -> Result<(), Self::Error>
where
T: Into<Self::Time>,
{
self.period = count.into();
self.next_end = Some(self.timer.get_counter().wrapping_add(self.period.0));
Ok(())
}
fn wait(&mut self) -> nb::Result<(), Self::Error> {
if let Some(end) = self.next_end {
let ts = self.timer.get_counter();
if ts >= end {
self.next_end = Some(end.wrapping_add(self.period.0));
Ok(())
} else {
Err(nb::Error::WouldBlock)
}
} else {
panic!("CountDown is not running!");
}
}
}
impl embedded_hal::timer::Periodic for CountDown<'_> {}
#[cfg(feature = "eh1_0_alpha")]
impl eh1_0_alpha::timer::Periodic for CountDown<'_> {}
impl embedded_hal::timer::Cancel for CountDown<'_> {
type Error = &'static str;
@ -178,17 +147,6 @@ impl embedded_hal::timer::Cancel for CountDown<'_> {
}
}
}
#[cfg(feature = "eh1_0_alpha")]
impl eh1_0_alpha::timer::nb::Cancel for CountDown<'_> {
fn cancel(&mut self) -> Result<(), Self::Error> {
if self.next_end.is_none() {
Err("CountDown is not running.")
} else {
self.next_end = None;
Ok(())
}
}
}
macro_rules! impl_alarm {
($name:ident { rb: $timer_alarm:ident, int: $int_alarm:ident, int_name: $int_name:tt, armed_bit_mask: $armed_bit_mask: expr }) => {

View file

@ -15,7 +15,7 @@ use nb::Error::{Other, WouldBlock};
use rp2040_pac::{UART0, UART1};
#[cfg(feature = "eh1_0_alpha")]
use eh1_0_alpha::serial::nb as eh1;
use eh1_0_alpha::serial as eh1;
/// An UART Peripheral based on an underlying UART device.
pub struct UartPeripheral<S: State, D: UartDevice, P: ValidUartPinout<D>> {
@ -345,9 +345,12 @@ impl<D: UartDevice, P: ValidUartPinout<D>> Read<u8> for UartPeripheral<Enabled,
}
#[cfg(feature = "eh1_0_alpha")]
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::Read<u8> for UartPeripheral<Enabled, D, P> {
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::ErrorType for UartPeripheral<Enabled, D, P> {
type Error = ReadErrorType;
}
#[cfg(feature = "eh1_0_alpha")]
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::nb::Read<u8> for UartPeripheral<Enabled, D, P> {
fn read(&mut self) -> nb::Result<u8, Self::Error> {
let byte: &mut [u8] = &mut [0; 1];
@ -377,9 +380,7 @@ impl<D: UartDevice, P: ValidUartPinout<D>> Write<u8> for UartPeripheral<Enabled,
}
#[cfg(feature = "eh1_0_alpha")]
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::Write<u8> for UartPeripheral<Enabled, D, P> {
type Error = SerialInfallible;
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::nb::Write<u8> for UartPeripheral<Enabled, D, P> {
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
if self.write_raw(&[word]).is_err() {
Err(WouldBlock)

View file

@ -10,7 +10,7 @@ use embedded_time::rate::Baud;
use nb::Error::*;
#[cfg(feature = "eh1_0_alpha")]
use eh1_0_alpha::serial::nb as eh1;
use eh1_0_alpha::serial as eh1;
/// When there's a read error.
pub struct ReadError<'err> {
@ -217,9 +217,12 @@ impl<D: UartDevice, P: ValidUartPinout<D>> Read<u8> for Reader<D, P> {
}
#[cfg(feature = "eh1_0_alpha")]
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::Read<u8> for Reader<D, P> {
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::ErrorType for Reader<D, P> {
type Error = ReadErrorType;
}
#[cfg(feature = "eh1_0_alpha")]
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::nb::Read<u8> for Reader<D, P> {
fn read(&mut self) -> nb::Result<u8, Self::Error> {
let byte: &mut [u8] = &mut [0; 1];

View file

@ -10,7 +10,7 @@ use nb::Error::*;
use rp2040_pac::uart0::RegisterBlock;
#[cfg(feature = "eh1_0_alpha")]
use eh1_0_alpha::serial::nb as eh1;
use eh1_0_alpha::serial as eh1;
/// Returns `Err(WouldBlock)` if the UART TX FIFO still has data in it or
/// `Ok(())` if the FIFO is empty.
@ -169,9 +169,12 @@ impl<D: UartDevice, P: ValidUartPinout<D>> Write<u8> for Writer<D, P> {
}
#[cfg(feature = "eh1_0_alpha")]
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::Write<u8> for Writer<D, P> {
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::ErrorType for Writer<D, P> {
type Error = super::utils::SerialInfallible;
}
#[cfg(feature = "eh1_0_alpha")]
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::nb::Write<u8> for Writer<D, P> {
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
if self.write_raw(&[word]).is_err() {
Err(WouldBlock)

View file

@ -35,8 +35,6 @@
//! See [examples/watchdog.rs](https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal/examples/watchdog.rs) for a more complete example
use crate::pac::WATCHDOG;
#[cfg(feature = "eh1_0_alpha")]
use eh1_0_alpha::watchdog::blocking as eh1;
use embedded_hal::watchdog;
use embedded_time::{duration, fixed_point::FixedPoint};
@ -114,15 +112,6 @@ impl watchdog::Watchdog for Watchdog {
self.load_counter(self.delay_ms)
}
}
#[cfg(feature = "eh1_0_alpha")]
impl eh1::Watchdog for Watchdog {
type Error = core::convert::Infallible;
fn feed(&mut self) -> Result<(), Self::Error> {
self.load_counter(self.delay_ms);
Ok(())
}
}
impl watchdog::WatchdogEnable for Watchdog {
type Time = duration::Microseconds;
@ -146,41 +135,9 @@ impl watchdog::WatchdogEnable for Watchdog {
self.enable(true);
}
}
#[cfg(feature = "eh1_0_alpha")]
impl eh1::Enable for Watchdog {
type Error = core::convert::Infallible;
type Target = Self;
type Time = duration::Microseconds;
fn start<T: Into<Self::Time>>(mut self, period: T) -> Result<Self::Target, Self::Error> {
const MAX_PERIOD: u32 = 0xFFFFFF;
// Due to a logic error, the watchdog decrements by 2 and
// the load value must be compensated; see RP2040-E1
self.delay_ms = period.into().integer() * 2;
if self.delay_ms > MAX_PERIOD {
panic!("Period cannot exceed maximum load value of {}", MAX_PERIOD);
}
self.enable(false);
self.load_counter(self.delay_ms);
self.enable(true);
Ok(self)
}
}
impl watchdog::WatchdogDisable for Watchdog {
fn disable(&mut self) {
self.enable(false)
}
}
#[cfg(feature = "eh1_0_alpha")]
impl eh1::Disable for Watchdog {
type Error = core::convert::Infallible;
type Target = Self;
fn disable(self) -> Result<Self::Target, Self::Error> {
self.enable(false);
Ok(self)
}
}