Skip to content

Commit

Permalink
update to i2c-write-iter
Browse files Browse the repository at this point in the history
  • Loading branch information
ithinuel committed Nov 28, 2023
1 parent 66830b1 commit 9fb1daf
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 114 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
43 changes: 12 additions & 31 deletions adafruit-featherwing-oled128x64/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -23,26 +18,11 @@ pub enum Destination {
Frame2,
}

pub trait ValidBus:
sh1107::WriteIter<SevenBitAddress, Error = <<Self as ValidBus>::I2c as ErrorType>::Error>
+ Deref<Target = Self::I2c>
+ DerefMut
{
type I2c: I2c<SevenBitAddress>;
}
impl<T, U> ValidBus for T
where
T: sh1107::WriteIter<SevenBitAddress, Error = U::Error> + Deref<Target = U> + DerefMut,
U: I2c<SevenBitAddress>,
{
type I2c = U;
}

pub struct Display<T, const ADDRESS: SevenBitAddress>(Sh1107<T, ADDRESS>);

impl<T, const ADDRESS: SevenBitAddress> Display<T, ADDRESS>
where
T: ValidBus,
T: sh1107::WriteIter<SevenBitAddress>,
{
pub async fn new(i2c_bus: T) -> Result<Self, (T, T::Error)> {
let mut sh1107 = Sh1107::new(i2c_bus);
Expand Down Expand Up @@ -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;
Expand All @@ -222,19 +198,24 @@ mod embedded_graphics {
bitmask: [u8; 128 * 64],
bitmap: [u8; 128 * 64],
}
impl<T, const ADDRESS: SevenBitAddress> Deref for BufferedDisplay<T, ADDRESS> {
impl<T: sh1107::WriteIter<SevenBitAddress>, const ADDRESS: SevenBitAddress> core::ops::Deref
for BufferedDisplay<T, ADDRESS>
{
type Target = Display<T, ADDRESS>;

fn deref(&self) -> &Self::Target {
fn deref(&self) -> &Display<T, ADDRESS> {
&self.display
}
}
impl<T, const ADDRESS: SevenBitAddress> DerefMut for BufferedDisplay<T, ADDRESS> {
fn deref_mut(&mut self) -> &mut Self::Target {
impl<T: sh1107::WriteIter<SevenBitAddress>, const ADDRESS: SevenBitAddress> core::ops::DerefMut
for BufferedDisplay<T, ADDRESS>
{
fn deref_mut(&mut self) -> &mut Display<T, ADDRESS> {
&mut self.display
}
}
impl<T: ValidBus, const ADDRESS: SevenBitAddress> BufferedDisplay<T, ADDRESS> {
impl<T: sh1107::WriteIter<SevenBitAddress>, const ADDRESS: SevenBitAddress>
BufferedDisplay<T, ADDRESS>
{
pub async fn new(i2c_bus: T) -> Result<Self, (T, T::Error)> {
// on startup the whole display is considered dirty
Ok(Self {
Expand Down
7 changes: 2 additions & 5 deletions pico-explorer-boilerplate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,14 @@ 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<bank0::Gpio20, FunctionI2C, PullUp>,
Pin<bank0::Gpio21, FunctionI2C, PullUp>,
),
>;

pub struct I2CPeriph(I2CPeriphInner);
sh1107::impl_write_iter!(I2CPeriph => I2CPeriphInner: write_iter);

type Alarm0WakerCTX = (Alarm0, Option<Waker>);
static ALARM0_WAKER: Mutex<RefCell<Option<Alarm0WakerCTX>>> = Mutex::new(RefCell::new(None));
pub async fn wait_for(timer: &Timer, delay: u32) {
Expand Down Expand Up @@ -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)
}
7 changes: 2 additions & 5 deletions pico-explorer-minimal-boilerplate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,14 @@ 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<bank0::Gpio20, FunctionI2C, PullUp>,
Pin<bank0::Gpio21, FunctionI2C, PullUp>,
),
>;

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| {
Expand Down Expand Up @@ -89,5 +86,5 @@ pub fn init() -> (Timer, I2CPeriph) {
clocks.system_clock.freq(),
);

(timer, I2CPeriph(i2c_ctrl))
(timer, i2c_ctrl)
}
7 changes: 2 additions & 5 deletions pico-explorer-pio-boilerplate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,14 @@ 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,
Pin<bank0::Gpio20, FunctionNull, PullUp>,
Pin<bank0::Gpio21, FunctionNull, PullUp>,
>;

pub struct I2CPeriph(I2CPeriphInner);
sh1107::impl_write_iter!(I2CPeriph => I2CPeriphInner: write_iter);

type Alarm0WakerCTX = (Alarm0, Option<Waker>);
static ALARM0_WAKER: Mutex<RefCell<Option<Alarm0WakerCTX>>> = Mutex::new(RefCell::new(None));
pub async fn wait_for(timer: &Timer, delay: u32) {
Expand Down Expand Up @@ -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)
}
7 changes: 2 additions & 5 deletions promicro-rp2040-boilerplate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,14 @@ 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<bank0::Gpio16, FunctionI2C, PullUp>,
Pin<bank0::Gpio17, FunctionI2C, PullUp>,
),
>;

pub struct I2CPeriph(I2CPeriphInner);
sh1107::impl_write_iter!(I2CPeriph => I2CPeriphInner: write_iter);

type Alarm0WakerCTX = (Alarm0, Option<Waker>);
static ALARM0_WAKER: Mutex<RefCell<Option<Alarm0WakerCTX>>> = Mutex::new(RefCell::new(None));
pub async fn wait_for(timer: &Timer, delay: u32) {
Expand Down Expand Up @@ -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)
}
7 changes: 2 additions & 5 deletions rpi-pico-boilerplate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,14 @@ 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<bank0::Gpio14, FunctionI2C, PullUp>,
Pin<bank0::Gpio15, FunctionI2C, PullUp>,
),
>;

pub struct I2CPeriph(I2CPeriphInner);
sh1107::impl_write_iter!(I2CPeriph => I2CPeriphInner: write_iter);

type Alarm0WakerCTX = (Alarm0, Option<Waker>);
static ALARM0_WAKER: Mutex<RefCell<Option<Alarm0WakerCTX>>> = Mutex::new(RefCell::new(None));
pub async fn wait_for(timer: &Timer, delay: u32) {
Expand Down Expand Up @@ -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)
}
1 change: 1 addition & 0 deletions sh1107/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
71 changes: 13 additions & 58 deletions sh1107/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<A: I2CAddressMode>: ErrorType {
/// Writes bytes obtained form the iterator.
fn write_iter<'a, U>(
&'a mut self,
address: A,
bytes: U,
) -> impl core::future::Future<Output = Result<(), Self::Error>>
where
U: IntoIterator<Item = u8> + 'a;
}

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum DisplayState {
Expand Down Expand Up @@ -164,16 +151,18 @@ impl Command {

pub struct Sh1107<T, const ADDRESS: SevenBitAddress>(T);

impl<T, U, V, const ADDRESS: SevenBitAddress> Sh1107<T, ADDRESS>
impl<T, const ADDRESS: SevenBitAddress> Sh1107<T, ADDRESS>
where
T: WriteIter<SevenBitAddress, Error = V> + Deref<Target = U> + DerefMut,
U: I2c<SevenBitAddress, Error = V>,
T: WriteIter<SevenBitAddress>,
{
pub fn new(i2c: T) -> Self {
Self(i2c)
}

pub async fn run(&mut self, commands: impl IntoIterator<Item = Command>) -> Result<(), V> {
pub async fn run(
&mut self,
commands: impl IntoIterator<Item = Command>,
) -> Result<(), T::Error> {
self.0
.write_iter(
ADDRESS,
Expand All @@ -185,7 +174,7 @@ where
pub async fn write_to_ram(
&mut self,
buf: impl IntoIterator<Item = u8>,
) -> Result<(), <T as ErrorType>::Error> {
) -> Result<(), T::Error> {
self.0
.write_iter(
ADDRESS, // Write data, no other control byte
Expand All @@ -198,7 +187,7 @@ where
&mut self,
commands: impl IntoIterator<Item = Command>,
data: impl IntoIterator<Item = u8>,
) -> Result<(), V> {
) -> Result<(), T::Error> {
self.0
.write_iter(
ADDRESS,
Expand All @@ -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<bool, V> {
pub async fn is_busy(&mut self) -> Result<bool, T::Error> {
let mut res = 0u8;
self.0
.write_read(ADDRESS, &[0x80], core::slice::from_mut(&mut res))
Expand All @@ -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<SevenBitAddress> for I2CPeriph {
async fn write_iter<'a, U>(
&'a mut self,
address: SevenBitAddress,
bytes: U,
) -> Result<(), Self::Error>
where
U: IntoIterator<Item = u8> + 'a,
{
self.0.$method(address, bytes).await
}
}
};
}

0 comments on commit 9fb1daf

Please sign in to comment.