mirror of
https://github.com/italicsjenga/rp-hal-boards.git
synced 2025-01-11 13:01:30 +11:00
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:
parent
b7e56d0869
commit
7750781650
|
@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- None
|
- Updated embedded-hal alpha support to version 1.0.0-alpha.7
|
||||||
|
|
||||||
## [0.3.0] - 2021-12-19
|
## [0.3.0] - 2021-12-19
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ license = "MIT OR Apache-2.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cortex-m = "0.7.2"
|
cortex-m = "0.7.2"
|
||||||
embedded-hal = { version = "0.2.5", features = ["unproven"] }
|
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"
|
embedded-time = "0.12.0"
|
||||||
itertools = { version = "0.10.1", default-features = false }
|
itertools = { version = "0.10.1", default-features = false }
|
||||||
nb = "1.0"
|
nb = "1.0"
|
||||||
|
|
|
@ -79,7 +79,7 @@ use super::reg::RegisterInterface;
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[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 hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
@ -545,8 +545,12 @@ impl StatefulOutputPin for DynPin {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[cfg(feature = "eh1_0_alpha")]
|
||||||
impl eh1::OutputPin for DynPin {
|
impl eh1::ErrorType for DynPin {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "eh1_0_alpha")]
|
||||||
|
impl eh1::blocking::OutputPin for DynPin {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
self._set_high()
|
self._set_high()
|
||||||
|
@ -558,8 +562,7 @@ impl eh1::OutputPin for DynPin {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[cfg(feature = "eh1_0_alpha")]
|
||||||
impl eh1::InputPin for DynPin {
|
impl eh1::blocking::InputPin for DynPin {
|
||||||
type Error = Error;
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
self._is_high()
|
self._is_high()
|
||||||
|
@ -571,8 +574,7 @@ impl eh1::InputPin for DynPin {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[cfg(feature = "eh1_0_alpha")]
|
||||||
impl eh1::ToggleableOutputPin for DynPin {
|
impl eh1::blocking::ToggleableOutputPin for DynPin {
|
||||||
type Error = Error;
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||||
self._toggle()
|
self._toggle()
|
||||||
|
@ -580,7 +582,7 @@ impl eh1::ToggleableOutputPin for DynPin {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[cfg(feature = "eh1_0_alpha")]
|
||||||
impl eh1::StatefulOutputPin for DynPin {
|
impl eh1::blocking::StatefulOutputPin for DynPin {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||||
self._is_set_high()
|
self._is_set_high()
|
||||||
|
|
|
@ -104,7 +104,7 @@ use core::marker::PhantomData;
|
||||||
|
|
||||||
use crate::gpio::dynpin::DynFunction;
|
use crate::gpio::dynpin::DynFunction;
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[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 hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
|
||||||
|
|
||||||
use core::mem::transmute;
|
use core::mem::transmute;
|
||||||
|
@ -845,12 +845,20 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[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
|
where
|
||||||
I: PinId,
|
I: PinId,
|
||||||
C: OutputConfig,
|
C: OutputConfig,
|
||||||
{
|
{
|
||||||
type Error = Infallible;
|
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]
|
#[inline]
|
||||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
self._set_high();
|
self._set_high();
|
||||||
|
@ -864,11 +872,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[cfg(feature = "eh1_0_alpha")]
|
||||||
impl<I> eh1::InputPin for Pin<I, ReadableOutput>
|
impl<I> eh1::blocking::InputPin for Pin<I, ReadableOutput>
|
||||||
where
|
where
|
||||||
I: PinId,
|
I: PinId,
|
||||||
{
|
{
|
||||||
type Error = Infallible;
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
Ok(self._is_high())
|
Ok(self._is_high())
|
||||||
|
@ -880,12 +887,20 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[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
|
where
|
||||||
I: PinId,
|
I: PinId,
|
||||||
C: InputConfig,
|
C: InputConfig,
|
||||||
{
|
{
|
||||||
type Error = Infallible;
|
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]
|
#[inline]
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
Ok(self._is_high())
|
Ok(self._is_high())
|
||||||
|
@ -897,12 +912,11 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[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
|
where
|
||||||
I: PinId,
|
I: PinId,
|
||||||
C: OutputConfig,
|
C: OutputConfig,
|
||||||
{
|
{
|
||||||
type Error = Infallible;
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||||
self._toggle();
|
self._toggle();
|
||||||
|
@ -911,7 +925,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[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
|
where
|
||||||
I: PinId,
|
I: PinId,
|
||||||
C: OutputConfig,
|
C: OutputConfig,
|
||||||
|
|
|
@ -10,7 +10,7 @@ use hal::blocking::i2c::{Read, Write, WriteRead};
|
||||||
use pac::{i2c0::RegisterBlock as Block, RESETS};
|
use pac::{i2c0::RegisterBlock as Block, RESETS};
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[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};
|
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;
|
let lastindex = buffer.len() - 1;
|
||||||
for (i, byte) in buffer.iter_mut().enumerate() {
|
for (i, byte) in buffer.iter_mut().enumerate() {
|
||||||
let first = i == 0;
|
let first = i == 0;
|
||||||
|
@ -170,13 +175,13 @@ impl<T: Deref<Target = Block>, PINS> I2C<T, PINS, Controller> {
|
||||||
while self.tx_fifo_full() {}
|
while self.tx_fifo_full() {}
|
||||||
|
|
||||||
self.i2c.ic_data_cmd.write(|w| {
|
self.i2c.ic_data_cmd.write(|w| {
|
||||||
if first {
|
if force_restart && first {
|
||||||
w.restart().enable();
|
w.restart().enable();
|
||||||
} else {
|
} else {
|
||||||
w.restart().disable();
|
w.restart().disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if last {
|
if do_stop && last {
|
||||||
w.stop().enable();
|
w.stop().enable();
|
||||||
} else {
|
} else {
|
||||||
w.stop().disable();
|
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::validate(addr, None, Some(buffer.is_empty()))?;
|
||||||
|
|
||||||
self.setup(addr);
|
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> {
|
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.setup(addr);
|
||||||
|
|
||||||
self.write_internal(tx, false)?;
|
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> {
|
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")]
|
#[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;
|
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> {
|
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||||
Write::write(self, addr, bytes)
|
Write::write(self, addr, bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(())
|
||||||
}
|
}
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
|
||||||
impl<T: Deref<Target = Block>, PINS> eh1::WriteRead for I2C<T, PINS, Controller> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
|
fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
|
||||||
WriteRead::write_read(self, addr, bytes, buffer)
|
WriteRead::write_read(self, addr, bytes, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
|
||||||
impl<T: Deref<Target = Block>, PINS> eh1::Read for I2C<T, PINS, Controller> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
|
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
|
||||||
Read::read(self, addr, buffer)
|
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(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,8 +87,6 @@ use crate::{
|
||||||
resets::SubsystemReset,
|
resets::SubsystemReset,
|
||||||
typelevel::Sealed,
|
typelevel::Sealed,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
|
||||||
use eh1_0_alpha::pwm::blocking as eh1;
|
|
||||||
use embedded_hal::PwmPin;
|
use embedded_hal::PwmPin;
|
||||||
use pac::PWM;
|
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> {
|
impl<S: SliceId, M: SliceMode> PwmPin for Channel<S, M, B> {
|
||||||
type Duty = u16;
|
type Duty = u16;
|
||||||
|
|
||||||
|
@ -674,37 +640,6 @@ impl<S: SliceId, M: SliceMode> PwmPin for Channel<S, M, B> {
|
||||||
self.regs.write_cc_b(duty)
|
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> {
|
impl<S: SliceId, M: SliceMode + ValidSliceMode<S>> Channel<S, M, A> {
|
||||||
/// Capture a gpio pin and use it as pwm output for channel A
|
/// Capture a gpio pin and use it as pwm output for channel A
|
||||||
|
|
|
@ -243,9 +243,12 @@ macro_rules! impl_write {
|
||||||
impl<D: SpiDevice> spi::write_iter::Default<$type> for Spi<Enabled, D, $nr> {}
|
impl<D: SpiDevice> spi::write_iter::Default<$type> for Spi<Enabled, D, $nr> {}
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[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;
|
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>> {
|
fn read(&mut self) -> Result<$type, nb::Error<SpiInfallible>> {
|
||||||
if !self.is_readable() {
|
if !self.is_readable() {
|
||||||
return Err(nb::Error::WouldBlock);
|
return Err(nb::Error::WouldBlock);
|
||||||
|
|
|
@ -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<'_> {}
|
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<'_> {
|
impl embedded_hal::timer::Cancel for CountDown<'_> {
|
||||||
type Error = &'static str;
|
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 {
|
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 }) => {
|
($name:ident { rb: $timer_alarm:ident, int: $int_alarm:ident, int_name: $int_name:tt, armed_bit_mask: $armed_bit_mask: expr }) => {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use nb::Error::{Other, WouldBlock};
|
||||||
use rp2040_pac::{UART0, UART1};
|
use rp2040_pac::{UART0, UART1};
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[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.
|
/// An UART Peripheral based on an underlying UART device.
|
||||||
pub struct UartPeripheral<S: State, D: UartDevice, P: ValidUartPinout<D>> {
|
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")]
|
#[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;
|
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> {
|
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||||
let byte: &mut [u8] = &mut [0; 1];
|
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")]
|
#[cfg(feature = "eh1_0_alpha")]
|
||||||
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::Write<u8> for UartPeripheral<Enabled, D, P> {
|
impl<D: UartDevice, P: ValidUartPinout<D>> eh1::nb::Write<u8> for UartPeripheral<Enabled, D, P> {
|
||||||
type Error = SerialInfallible;
|
|
||||||
|
|
||||||
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
||||||
if self.write_raw(&[word]).is_err() {
|
if self.write_raw(&[word]).is_err() {
|
||||||
Err(WouldBlock)
|
Err(WouldBlock)
|
||||||
|
|
|
@ -10,7 +10,7 @@ use embedded_time::rate::Baud;
|
||||||
use nb::Error::*;
|
use nb::Error::*;
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[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.
|
/// When there's a read error.
|
||||||
pub struct ReadError<'err> {
|
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")]
|
#[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;
|
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> {
|
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||||
let byte: &mut [u8] = &mut [0; 1];
|
let byte: &mut [u8] = &mut [0; 1];
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ use nb::Error::*;
|
||||||
use rp2040_pac::uart0::RegisterBlock;
|
use rp2040_pac::uart0::RegisterBlock;
|
||||||
|
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
#[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
|
/// Returns `Err(WouldBlock)` if the UART TX FIFO still has data in it or
|
||||||
/// `Ok(())` if the FIFO is empty.
|
/// `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")]
|
#[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;
|
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> {
|
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
||||||
if self.write_raw(&[word]).is_err() {
|
if self.write_raw(&[word]).is_err() {
|
||||||
Err(WouldBlock)
|
Err(WouldBlock)
|
||||||
|
|
|
@ -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
|
//! 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;
|
use crate::pac::WATCHDOG;
|
||||||
#[cfg(feature = "eh1_0_alpha")]
|
|
||||||
use eh1_0_alpha::watchdog::blocking as eh1;
|
|
||||||
use embedded_hal::watchdog;
|
use embedded_hal::watchdog;
|
||||||
use embedded_time::{duration, fixed_point::FixedPoint};
|
use embedded_time::{duration, fixed_point::FixedPoint};
|
||||||
|
|
||||||
|
@ -114,15 +112,6 @@ impl watchdog::Watchdog for Watchdog {
|
||||||
self.load_counter(self.delay_ms)
|
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 {
|
impl watchdog::WatchdogEnable for Watchdog {
|
||||||
type Time = duration::Microseconds;
|
type Time = duration::Microseconds;
|
||||||
|
@ -146,41 +135,9 @@ impl watchdog::WatchdogEnable for Watchdog {
|
||||||
self.enable(true);
|
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 {
|
impl watchdog::WatchdogDisable for Watchdog {
|
||||||
fn disable(&mut self) {
|
fn disable(&mut self) {
|
||||||
self.enable(false)
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue