From 9fb1daf136884b15bed90b98754d375949e827fa Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Tue, 28 Nov 2023 22:41:38 +0000 Subject: [PATCH] update to i2c-write-iter --- Cargo.toml | 2 + adafruit-featherwing-oled128x64/src/lib.rs | 43 ++++-------- pico-explorer-boilerplate/src/lib.rs | 7 +- pico-explorer-minimal-boilerplate/src/lib.rs | 7 +- pico-explorer-pio-boilerplate/src/lib.rs | 7 +- promicro-rp2040-boilerplate/src/lib.rs | 7 +- rpi-pico-boilerplate/src/lib.rs | 7 +- sh1107/Cargo.toml | 1 + sh1107/src/lib.rs | 71 ++++---------------- 9 files changed, 38 insertions(+), 114 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f500881..eb89f86 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,3 +19,5 @@ opt-level = 2 [patch.crates-io] rp2040-hal = { git = "https://github.com/rp-rs/rp-hal" } +[patch.'https://github.com/ithinuel/rp2040-async-i2C'] +rp2040-async-i2c = { path = "../rp2040-async-i2c" } diff --git a/adafruit-featherwing-oled128x64/src/lib.rs b/adafruit-featherwing-oled128x64/src/lib.rs index e8c8120..cc69982 100644 --- a/adafruit-featherwing-oled128x64/src/lib.rs +++ b/adafruit-featherwing-oled128x64/src/lib.rs @@ -1,10 +1,5 @@ #![no_std] -use core::ops::Deref; -use core::ops::DerefMut; - -use embedded_hal_async::i2c::ErrorType; -use embedded_hal_async::i2c::I2c; use embedded_hal_async::i2c::SevenBitAddress; use sh1107::Direction; use sh1107::{AddressMode, Sh1107}; @@ -23,26 +18,11 @@ pub enum Destination { Frame2, } -pub trait ValidBus: - sh1107::WriteIter::I2c as ErrorType>::Error> - + Deref - + DerefMut -{ - type I2c: I2c; -} -impl ValidBus for T -where - T: sh1107::WriteIter + Deref + DerefMut, - U: I2c, -{ - type I2c = U; -} - pub struct Display(Sh1107); impl Display where - T: ValidBus, + T: sh1107::WriteIter, { pub async fn new(i2c_bus: T) -> Result { let mut sh1107 = Sh1107::new(i2c_bus); @@ -200,10 +180,6 @@ pub use self::embedded_graphics::BufferedDisplay; #[cfg(feature = "embedded-graphics")] mod embedded_graphics { - use core::ops::Deref; - use core::ops::DerefMut; - - use crate::ValidBus; use crate::COLUMN; use crate::PAGE; use crate::ROW; @@ -222,19 +198,24 @@ mod embedded_graphics { bitmask: [u8; 128 * 64], bitmap: [u8; 128 * 64], } - impl Deref for BufferedDisplay { + impl, const ADDRESS: SevenBitAddress> core::ops::Deref + for BufferedDisplay + { type Target = Display; - - fn deref(&self) -> &Self::Target { + fn deref(&self) -> &Display { &self.display } } - impl DerefMut for BufferedDisplay { - fn deref_mut(&mut self) -> &mut Self::Target { + impl, const ADDRESS: SevenBitAddress> core::ops::DerefMut + for BufferedDisplay + { + fn deref_mut(&mut self) -> &mut Display { &mut self.display } } - impl BufferedDisplay { + impl, const ADDRESS: SevenBitAddress> + BufferedDisplay + { pub async fn new(i2c_bus: T) -> Result { // on startup the whole display is considered dirty Ok(Self { diff --git a/pico-explorer-boilerplate/src/lib.rs b/pico-explorer-boilerplate/src/lib.rs index b98c278..7fd94a9 100644 --- a/pico-explorer-boilerplate/src/lib.rs +++ b/pico-explorer-boilerplate/src/lib.rs @@ -28,7 +28,7 @@ pub use embedded_hal_async::i2c::SevenBitAddress; pub use hal::timer::Timer; pub use pimoroni_pico_explorer::entry; -type I2CPeriphInner = I2C< +pub type I2CPeriph = I2C< pac::I2C0, ( Pin, @@ -36,9 +36,6 @@ type I2CPeriphInner = I2C< ), >; -pub struct I2CPeriph(I2CPeriphInner); -sh1107::impl_write_iter!(I2CPeriph => I2CPeriphInner: write_iter); - type Alarm0WakerCTX = (Alarm0, Option); static ALARM0_WAKER: Mutex>> = Mutex::new(RefCell::new(None)); pub async fn wait_for(timer: &Timer, delay: u32) { @@ -176,5 +173,5 @@ pub fn init() -> (Timer, I2CPeriph) { *ALARM0_WAKER.borrow_ref_mut(cs) = Some((alarm, None)); }); - (timer, I2CPeriph(i2c_ctrl)) + (timer, i2c_ctrl) } diff --git a/pico-explorer-minimal-boilerplate/src/lib.rs b/pico-explorer-minimal-boilerplate/src/lib.rs index 454faef..1845f58 100644 --- a/pico-explorer-minimal-boilerplate/src/lib.rs +++ b/pico-explorer-minimal-boilerplate/src/lib.rs @@ -25,7 +25,7 @@ pub use embedded_hal_async::i2c::SevenBitAddress; pub use hal::timer::Timer; pub use pimoroni_pico_explorer::entry; -type I2CPeriphInner = I2C< +pub type I2CPeriph = I2C< pac::I2C0, ( Pin, @@ -33,9 +33,6 @@ type I2CPeriphInner = I2C< ), >; -pub struct I2CPeriph(I2CPeriphInner); -sh1107::impl_write_iter!(I2CPeriph => I2CPeriphInner: write_iter); - pub async fn wait_for(timer: &Timer, delay: u32) { let target = timer.get_counter() + delay.micros(); future::poll_fn(|cx| { @@ -89,5 +86,5 @@ pub fn init() -> (Timer, I2CPeriph) { clocks.system_clock.freq(), ); - (timer, I2CPeriph(i2c_ctrl)) + (timer, i2c_ctrl) } diff --git a/pico-explorer-pio-boilerplate/src/lib.rs b/pico-explorer-pio-boilerplate/src/lib.rs index 3e454cb..6786a6c 100644 --- a/pico-explorer-pio-boilerplate/src/lib.rs +++ b/pico-explorer-pio-boilerplate/src/lib.rs @@ -37,7 +37,7 @@ pub use embedded_hal_async::i2c::SevenBitAddress; pub use hal::timer::Timer; pub use pimoroni_pico_explorer::entry; -type I2CPeriphInner = I2C< +pub type I2CPeriph = I2C< 'static, PIO0, SM0, @@ -45,9 +45,6 @@ type I2CPeriphInner = I2C< Pin, >; -pub struct I2CPeriph(I2CPeriphInner); -sh1107::impl_write_iter!(I2CPeriph => I2CPeriphInner: write_iter); - type Alarm0WakerCTX = (Alarm0, Option); static ALARM0_WAKER: Mutex>> = Mutex::new(RefCell::new(None)); pub async fn wait_for(timer: &Timer, delay: u32) { @@ -187,5 +184,5 @@ pub fn init() -> (Timer, I2CPeriph) { *ALARM0_WAKER.borrow_ref_mut(cs) = Some((alarm, None)); }); - (timer, I2CPeriph(i2c_ctrl)) + (timer, i2c_ctrl) } diff --git a/promicro-rp2040-boilerplate/src/lib.rs b/promicro-rp2040-boilerplate/src/lib.rs index 362fb15..2b35220 100644 --- a/promicro-rp2040-boilerplate/src/lib.rs +++ b/promicro-rp2040-boilerplate/src/lib.rs @@ -28,7 +28,7 @@ pub use embedded_hal_async::i2c::SevenBitAddress; pub use hal::timer::Timer; pub use sparkfun_pro_micro_rp2040::entry; -type I2CPeriphInner = I2C< +pub type I2CPeriph = I2C< pac::I2C0, ( Pin, @@ -36,9 +36,6 @@ type I2CPeriphInner = I2C< ), >; -pub struct I2CPeriph(I2CPeriphInner); -sh1107::impl_write_iter!(I2CPeriph => I2CPeriphInner: write_iter); - type Alarm0WakerCTX = (Alarm0, Option); static ALARM0_WAKER: Mutex>> = Mutex::new(RefCell::new(None)); pub async fn wait_for(timer: &Timer, delay: u32) { @@ -176,5 +173,5 @@ pub fn init() -> (Timer, I2CPeriph) { *ALARM0_WAKER.borrow_ref_mut(cs) = Some((alarm, None)); }); - (timer, I2CPeriph(i2c_ctrl)) + (timer, i2c_ctrl) } diff --git a/rpi-pico-boilerplate/src/lib.rs b/rpi-pico-boilerplate/src/lib.rs index be0e232..ec4826b 100644 --- a/rpi-pico-boilerplate/src/lib.rs +++ b/rpi-pico-boilerplate/src/lib.rs @@ -28,7 +28,7 @@ pub use embedded_hal_async::i2c::SevenBitAddress; pub use hal::timer::Timer; pub use rp_pico::entry; -type I2CPeriphInner = I2C< +pub type I2CPeriph = I2C< pac::I2C1, ( Pin, @@ -36,9 +36,6 @@ type I2CPeriphInner = I2C< ), >; -pub struct I2CPeriph(I2CPeriphInner); -sh1107::impl_write_iter!(I2CPeriph => I2CPeriphInner: write_iter); - type Alarm0WakerCTX = (Alarm0, Option); static ALARM0_WAKER: Mutex>> = Mutex::new(RefCell::new(None)); pub async fn wait_for(timer: &Timer, delay: u32) { @@ -176,5 +173,5 @@ pub fn init() -> (Timer, I2CPeriph) { *ALARM0_WAKER.borrow_ref_mut(cs) = Some((alarm, None)); }); - (timer, I2CPeriph(i2c_ctrl)) + (timer, i2c_ctrl) } diff --git a/sh1107/Cargo.toml b/sh1107/Cargo.toml index f533802..f15a65e 100644 --- a/sh1107/Cargo.toml +++ b/sh1107/Cargo.toml @@ -11,4 +11,5 @@ repository = "https://github.com/ithinuel/sh1107-rs" either = { version = "1.9.0", default-features = false } itertools = { version = "0.11.0", default-features = false } embedded-hal-async = "1.0.0-rc.1" +i2c-write-iter = { version = "1.0.0-rc.1.3", features = ["async"] } defmt = { version = "0.3.5", optional = true } diff --git a/sh1107/src/lib.rs b/sh1107/src/lib.rs index 867bbf3..687cc4f 100644 --- a/sh1107/src/lib.rs +++ b/sh1107/src/lib.rs @@ -2,25 +2,12 @@ //! See the [datasheet](https://www.displayfuture.com/Display/datasheet/controller/SH1107.pdf) for //! further details -use core::{ - iter::once, - ops::{Deref, DerefMut}, -}; +use core::iter::once; -use embedded_hal_async::i2c::{AddressMode as I2CAddressMode, ErrorType, I2c, SevenBitAddress}; +use embedded_hal_async::i2c::SevenBitAddress; +pub use i2c_write_iter::non_blocking::WriteIter; use itertools::Itertools; -pub trait WriteIter: ErrorType { - /// Writes bytes obtained form the iterator. - fn write_iter<'a, U>( - &'a mut self, - address: A, - bytes: U, - ) -> impl core::future::Future> - where - U: IntoIterator + 'a; -} - #[derive(Clone, Copy, PartialEq, Eq, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum DisplayState { @@ -164,16 +151,18 @@ impl Command { pub struct Sh1107(T); -impl Sh1107 +impl Sh1107 where - T: WriteIter + Deref + DerefMut, - U: I2c, + T: WriteIter, { pub fn new(i2c: T) -> Self { Self(i2c) } - pub async fn run(&mut self, commands: impl IntoIterator) -> Result<(), V> { + pub async fn run( + &mut self, + commands: impl IntoIterator, + ) -> Result<(), T::Error> { self.0 .write_iter( ADDRESS, @@ -185,7 +174,7 @@ where pub async fn write_to_ram( &mut self, buf: impl IntoIterator, - ) -> Result<(), ::Error> { + ) -> Result<(), T::Error> { self.0 .write_iter( ADDRESS, // Write data, no other control byte @@ -198,7 +187,7 @@ where &mut self, commands: impl IntoIterator, data: impl IntoIterator, - ) -> Result<(), V> { + ) -> Result<(), T::Error> { self.0 .write_iter( ADDRESS, @@ -214,11 +203,11 @@ where .await } - pub async fn read_from_ram(&mut self, buf: &mut [u8]) -> Result<(), V> { + pub async fn read_from_ram(&mut self, buf: &mut [u8]) -> Result<(), T::Error> { self.0.write_read(ADDRESS, &[0x40], buf).await } - pub async fn is_busy(&mut self) -> Result { + pub async fn is_busy(&mut self) -> Result { let mut res = 0u8; self.0 .write_read(ADDRESS, &[0x80], core::slice::from_mut(&mut res)) @@ -230,37 +219,3 @@ where self.0 } } - -/// Helper macro to implement Deref, DerefMut and sh1107::WriteIter on a new type. -#[macro_export] -macro_rules! impl_write_iter { - ($outer:ty => $inner:ty : $method:ident) => { - impl Deref for $outer { - type Target = $inner; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl DerefMut for $outer { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } - } - impl ErrorType for $outer { - type Error = <$inner as ErrorType>::Error; - } - impl sh1107::WriteIter for I2CPeriph { - async fn write_iter<'a, U>( - &'a mut self, - address: SevenBitAddress, - bytes: U, - ) -> Result<(), Self::Error> - where - U: IntoIterator + 'a, - { - self.0.$method(address, bytes).await - } - } - }; -}