Skip to content

Commit

Permalink
Implement embedded-hal 1.0.0-alpha.7 traits (#298)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
jannic authored Feb 26, 2022
1 parent b7e56d0 commit 7750781
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 192 deletions.
2 changes: 1 addition & 1 deletion rp2040-hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion rp2040-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
16 changes: 9 additions & 7 deletions rp2040-hal/src/gpio/dynpin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

//==============================================================================
Expand Down Expand Up @@ -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()
Expand All @@ -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()
Expand All @@ -571,16 +574,15 @@ 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()
}
}

#[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()
Expand Down
30 changes: 22 additions & 8 deletions rp2040-hal/src/gpio/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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())
Expand All @@ -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())
Expand All @@ -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();
Expand All @@ -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,
Expand Down
99 changes: 84 additions & 15 deletions rp2040-hal/src/i2c/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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;
Expand All @@ -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();
Expand Down Expand Up @@ -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> {
Expand All @@ -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> {
Expand All @@ -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(())
}
}
Loading

0 comments on commit 7750781

Please sign in to comment.