Skip to content

Commit

Permalink
Embedded-Hal PR - incoorparate e-hal master changes in spi / i2c / gp…
Browse files Browse the repository at this point in the history
…io / delay (#224)

* embedded-hal::delay no longer returns Error

* embedded_hal::digital add generic GpioError

* spi: init work: from closure to Operation pattern

* first full implementation

* i2c: remove iter fn droped by e-hal master

* make ci work by temp. refere to e-hal master

* more ci fix

* make clippy happy

* more ci fighting

* gpio: cursed repair of ulp_processor

* fmt

* spi: repair example + get rid of generic's

* dep: change to new e-hal release

* fix e-hal 0.2 comp &  fix bus

* fmt

* clippy

* remove debug artifacts

* test ci with e-hal-nb-alpha.1

* e-hal-nb to alpha.2

* modified comments

* impl e-hal delay to general purpose provider

* use embedded_hal_error macro for riscv-ulp-hal

* typo

* impl pwm alpha10

* fixed wrong return error on async gpio

* duplicated impl error macro for ulp
  • Loading branch information
Vollbrecht committed May 8, 2023
1 parent b388e67 commit b739c46
Show file tree
Hide file tree
Showing 10 changed files with 489 additions and 224 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ nightly = ["embedded-hal-async"]
[dependencies]
nb = "1.0.0"
embedded-can = "0.4.1"
embedded-hal = "=1.0.0-alpha.9"
embedded-hal = "=1.0.0-alpha.10"
embedded-hal-0-2 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] }
embedded-hal-nb = "=1.0.0-alpha.1"
embedded-hal-nb = "=1.0.0-alpha.2"
esp-idf-sys = { version = "0.32.1", optional = true, default-features = false, features = ["native"] }
critical-section = { version = "1.1", optional = true }
heapless = "0.7"
embassy-sync = { version = "0.1", optional = true }
edge-executor = { version = "0.3", optional = true, default-features = false }
enumset = { version = "1", default-features = false }
embedded-hal-async = { version = "0.2.0-alpha.0", optional = true }
embedded-hal-async = { version = "0.2.0-alpha.1", optional = true }
futures-util = { version = "0.3", default-features = false }

[build-dependencies]
Expand Down
18 changes: 13 additions & 5 deletions examples/spi_loopback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//! This example transfers data via SPI.
//! Connect SDI and SDO pins to see the outgoing data is read as incoming data.

use embedded_hal::spi::Operation;
use esp_idf_hal::delay::FreeRtos;
use esp_idf_hal::peripherals::Peripherals;
use esp_idf_hal::prelude::*;
Expand Down Expand Up @@ -42,16 +43,23 @@ fn main() -> anyhow::Result<()> {
let mut read = [0u8; 4];
let write = [0xde, 0xad, 0xbe, 0xef];

let mut in_place_buf = [0xde, 0xad, 0xbe, 0xef];

loop {
// we are using thread::sleep here to make sure the watchdog isn't triggered
FreeRtos::delay_ms(500);
device_1.transfer(&mut read, &write)?;
println!("Device 1: Wrote {write:x?}, read {read:x?}");

println!("Device 2: To write {in_place_buf:x?} ... ");
device_2.transaction(|bus| bus.transfer_in_place(&mut in_place_buf))?;
println!("... read {in_place_buf:x?}");
let write_buf = [0xde, 0xad, 0xbe, 0xef];
let mut write_in_place_buf = [0xde, 0xad, 0xbe, 0xef];
let mut read_buf = [0; 8];

println!("Device 2: To write {write_in_place_buf:x?} ... ");
// cascade multiple operations with different buffer length into one transaction
device_2.transaction(&mut [
Operation::Write(&write_buf),
Operation::TransferInPlace(&mut write_in_place_buf),
Operation::Read(&mut read_buf),
])?;
println!("... read {write_in_place_buf:x?}");
}
}
10 changes: 10 additions & 0 deletions src/delay/general_purpose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ impl Delay {
}
}

impl embedded_hal::delay::DelayUs for Delay {
fn delay_us(&mut self, us: u32) {
Delay::delay_us(us)
}

fn delay_ms(&mut self, ms: u32) {
Delay::delay_ms(ms)
}
}

impl embedded_hal_0_2::blocking::delay::DelayUs<u16> for Delay {
fn delay_us(&mut self, us: u16) {
Delay::delay_us(us as _);
Expand Down
29 changes: 8 additions & 21 deletions src/delay/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
//! use [`Delay`]. Otherwise use [`Ets`] for delays <10ms and
//! [`FreeRtos`] for delays >=10ms.

use core::convert::Infallible;
use core::time::Duration;

use esp_idf_sys::*;
Expand Down Expand Up @@ -123,18 +122,12 @@ impl embedded_hal_0_2::blocking::delay::DelayMs<u8> for Ets {
}

impl embedded_hal::delay::DelayUs for Ets {
type Error = Infallible;

fn delay_us(&mut self, us: u32) -> Result<(), Self::Error> {
Ets::delay_us(us);

Ok(())
fn delay_us(&mut self, us: u32) {
Ets::delay_us(us)
}

fn delay_ms(&mut self, ms: u32) -> Result<(), Self::Error> {
Ets::delay_ms(ms);

Ok(())
fn delay_ms(&mut self, ms: u32) {
Ets::delay_ms(ms)
}
}

Expand Down Expand Up @@ -199,17 +192,11 @@ impl embedded_hal_0_2::blocking::delay::DelayMs<u8> for FreeRtos {
}

impl embedded_hal::delay::DelayUs for FreeRtos {
type Error = Infallible;

fn delay_us(&mut self, us: u32) -> Result<(), Self::Error> {
FreeRtos::delay_us(us);

Ok(())
fn delay_us(&mut self, us: u32) {
FreeRtos::delay_us(us)
}

fn delay_ms(&mut self, ms: u32) -> Result<(), Self::Error> {
FreeRtos::delay_ms(ms);

Ok(())
fn delay_ms(&mut self, ms: u32) {
FreeRtos::delay_ms(ms)
}
}
44 changes: 28 additions & 16 deletions src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1107,8 +1107,19 @@ where
}
}

use crate::embedded_hal_error;
embedded_hal_error!(
GpioError,
embedded_hal::digital::Error,
embedded_hal::digital::ErrorKind
);

fn to_gpio_err(err: EspError) -> GpioError {
GpioError::other(err)
}

impl<'d, T: Pin, MODE> embedded_hal::digital::ErrorType for PinDriver<'d, T, MODE> {
type Error = EspError;
type Error = GpioError;
}

impl<'d, T: Pin, MODE> embedded_hal::digital::InputPin for PinDriver<'d, T, MODE>
Expand All @@ -1128,14 +1139,14 @@ impl<'d, T: Pin, MODE> embedded_hal_0_2::digital::v2::OutputPin for PinDriver<'d
where
MODE: OutputMode,
{
type Error = EspError;
type Error = GpioError;

fn set_high(&mut self) -> Result<(), Self::Error> {
self.set_level(Level::High)
self.set_level(Level::High).map_err(to_gpio_err)
}

fn set_low(&mut self) -> Result<(), Self::Error> {
self.set_level(Level::Low)
self.set_level(Level::Low).map_err(to_gpio_err)
}
}

Expand All @@ -1144,11 +1155,11 @@ where
MODE: OutputMode,
{
fn set_high(&mut self) -> Result<(), Self::Error> {
self.set_level(Level::High)
self.set_level(Level::High).map_err(to_gpio_err)
}

fn set_low(&mut self) -> Result<(), Self::Error> {
self.set_level(Level::Low)
self.set_level(Level::Low).map_err(to_gpio_err)
}
}

Expand Down Expand Up @@ -1195,6 +1206,7 @@ where
{
fn toggle(&mut self) -> Result<(), Self::Error> {
self.set_level(Level::from(!bool::from(self.get_output_level())))
.map_err(to_gpio_err)
}
}

Expand Down Expand Up @@ -1379,27 +1391,27 @@ macro_rules! pin {

#[cfg(all(not(feature = "riscv-ulp-hal"), feature = "alloc"))]
impl<T: Pin, MODE: InputMode> PinDriver<'_, T, MODE> {
pub async fn wait_for_high(&mut self) -> Result<(), EspError> {
pub async fn wait_for_high(&mut self) -> Result<(), GpioError> {
InputFuture::new(self, InterruptType::HighLevel)?.await;
Ok(())
}

pub async fn wait_for_low(&mut self) -> Result<(), EspError> {
pub async fn wait_for_low(&mut self) -> Result<(), GpioError> {
InputFuture::new(self, InterruptType::LowLevel)?.await;
Ok(())
}

pub async fn wait_for_rising_edge(&mut self) -> Result<(), EspError> {
pub async fn wait_for_rising_edge(&mut self) -> Result<(), GpioError> {
InputFuture::new(self, InterruptType::PosEdge)?.await;
Ok(())
}

pub async fn wait_for_falling_edge(&mut self) -> Result<(), EspError> {
pub async fn wait_for_falling_edge(&mut self) -> Result<(), GpioError> {
InputFuture::new(self, InterruptType::NegEdge)?.await;
Ok(())
}

pub async fn wait_for_any_edge(&mut self) -> Result<(), EspError> {
pub async fn wait_for_any_edge(&mut self) -> Result<(), GpioError> {
InputFuture::new(self, InterruptType::AnyEdge)?.await;
Ok(())
}
Expand Down Expand Up @@ -1453,23 +1465,23 @@ mod asynch {
mod eha_wait_impl {
use super::*;
impl<T: Pin, MODE: InputMode> embedded_hal_async::digital::Wait for PinDriver<'_, T, MODE> {
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
async fn wait_for_high(&mut self) -> Result<(), GpioError> {
self.wait_for_high().await
}

async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
async fn wait_for_low(&mut self) -> Result<(), GpioError> {
self.wait_for_low().await
}

async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
async fn wait_for_rising_edge(&mut self) -> Result<(), GpioError> {
self.wait_for_rising_edge().await
}

async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
async fn wait_for_falling_edge(&mut self) -> Result<(), GpioError> {
self.wait_for_falling_edge().await
}

async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
async fn wait_for_any_edge(&mut self) -> Result<(), GpioError> {
self.wait_for_any_edge().await
}
}
Expand Down
26 changes: 0 additions & 26 deletions src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,39 +378,13 @@ impl<'d> embedded_hal::i2c::I2c<embedded_hal::i2c::SevenBitAddress> for I2cDrive
I2cDriver::write_read(self, addr, bytes, buffer, BLOCK).map_err(to_i2c_err)
}

fn write_iter<B>(&mut self, _address: u8, _bytes: B) -> Result<(), Self::Error>
where
B: IntoIterator<Item = u8>,
{
todo!()
}

fn write_iter_read<B>(
&mut self,
_address: u8,
_bytes: B,
_buffer: &mut [u8],
) -> Result<(), Self::Error>
where
B: IntoIterator<Item = u8>,
{
todo!()
}

fn transaction(
&mut self,
address: u8,
operations: &mut [embedded_hal::i2c::Operation<'_>],
) -> Result<(), Self::Error> {
I2cDriver::transaction(self, address, operations, BLOCK).map_err(to_i2c_err)
}

fn transaction_iter<'a, O>(&mut self, _address: u8, _operations: O) -> Result<(), Self::Error>
where
O: IntoIterator<Item = embedded_hal::i2c::Operation<'a>>,
{
todo!()
}
}

fn to_i2c_err(err: EspError) -> I2cError {
Expand Down
61 changes: 41 additions & 20 deletions src/ledc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ const IDLE_LEVEL: u32 = 0;
static FADE_FUNC_INSTALLED: AtomicBool = AtomicBool::new(false);
static FADE_FUNC_INSTALLED_CS: CriticalSection = CriticalSection::new();

crate::embedded_hal_error!(
PwmError,
embedded_hal::pwm::Error,
embedded_hal::pwm::ErrorKind
);

/// Types for configuring the LED Control peripheral
pub mod config {
use super::*;
Expand Down Expand Up @@ -310,31 +316,46 @@ impl<'d> Drop for LedcDriver<'d> {

unsafe impl<'d> Send for LedcDriver<'d> {}

// PwmPin temporarily removed from embedded-hal-1.0.alpha7 in anticipation of e-hal 1.0 release
// impl<'d> embedded_hal::pwm::blocking::PwmPin for LedcDriver<'d> {
// type Duty = Duty;
// type Error = EspError;
impl<'d> embedded_hal::pwm::ErrorType for LedcDriver<'d> {
type Error = PwmError;
}

// fn disable(&mut self) -> Result<(), Self::Error> {
// self.disable()
// }
fn to_pwm_err(err: EspError) -> PwmError {
PwmError::other(err)
}

// fn enable(&mut self) -> Result<(), Self::Error> {
// self.enable()
// }
impl<'d> embedded_hal::pwm::SetDutyCycle for LedcDriver<'d> {
fn get_max_duty_cycle(&self) -> u16 {
let duty = self.get_max_duty();
let duty_cap: u16 = if duty > u16::MAX as u32 {
u16::MAX
} else {
duty as u16
};
duty_cap
}

// fn get_duty(&self) -> Result<Self::Duty, Self::Error> {
// Ok(self.get_duty())
// }
fn set_duty_cycle(&mut self, duty: u16) -> Result<(), PwmError> {
self.set_duty(duty as u32).map_err(to_pwm_err)
}

// fn get_max_duty(&self) -> Result<Self::Duty, Self::Error> {
// Ok(self.get_max_duty())
// }
fn set_duty_cycle_fully_on(&mut self) -> Result<(), PwmError> {
self.set_duty(self.get_max_duty()).map_err(to_pwm_err)
}

// fn set_duty(&mut self, duty: Duty) -> Result<(), Self::Error> {
// self.set_duty(duty)
// }
// }
fn set_duty_cycle_fully_off(&mut self) -> Result<(), PwmError> {
self.set_duty(0).map_err(to_pwm_err)
}

fn set_duty_cycle_fraction(&mut self, num: u16, denom: u16) -> Result<(), PwmError> {
let duty = num as u32 * self.get_max_duty_cycle() as u32 / denom as u32;
self.set_duty_cycle(duty as u16)
}

fn set_duty_cycle_percent(&mut self, percent: u8) -> Result<(), PwmError> {
self.set_duty_cycle_fraction(percent as u16, 100)
}
}

impl<'d> embedded_hal_0_2::PwmPin for LedcDriver<'d> {
type Duty = Duty;
Expand Down
Loading

0 comments on commit b739c46

Please sign in to comment.