Skip to content

Commit

Permalink
factorise a bit the example's boilerplate
Browse files Browse the repository at this point in the history
  • Loading branch information
ithinuel committed Nov 28, 2023
1 parent 9fb1daf commit d57715a
Show file tree
Hide file tree
Showing 18 changed files with 127 additions and 467 deletions.
5 changes: 0 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ resolver = "2"
members = [
"adafruit-featherwing-oled128x64",
"sh1107",
"promicro-rp2040-boilerplate",
"pico-explorer-boilerplate",
"pico-explorer-pio-boilerplate",
"pico-explorer-minimal-boilerplate",
"rpi-pico-boilerplate",
]

[profile.release]
Expand Down
15 changes: 9 additions & 6 deletions adafruit-featherwing-oled128x64/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ cortex-m = "0.7.7"
cortex-m-rt = "0.7"

embedded-hal = { version = "1.0.0-rc.1" }

promicro-rp2040-boilerplate = { path = "../promicro-rp2040-boilerplate" }
pico-explorer-boilerplate = { path = "../pico-explorer-boilerplate" }
pico-explorer-pio-boilerplate = { path = "../pico-explorer-pio-boilerplate" }
pico-explorer-minimal-boilerplate = { path = "../pico-explorer-minimal-boilerplate" }
rpi-pico-boilerplate = { path = "../rpi-pico-boilerplate" }
critical-section = "1.1.2"
fugit = "0.3.7"
rp2040-async-i2c = { git = "https://github.com/ithinuel/rp2040-async-i2c", features = ["pio"] }
panic-probe = { version = "0.3.1", features = ["print-defmt"] }

arrayvec = { version = "0.7.4", default-features = false }
nostd_async = { version = "0.6.1", features = ["cortex_m"] }
Expand All @@ -37,6 +35,11 @@ futures = { version = "0.3.29", default-features = false, features = [
"async-await",
] }

pimoroni-pico-explorer = { version = "0.7.0" }
rp-pico = { version = "0.8.0" }
sparkfun-pro-micro-rp2040 = { version = "0.7.0" }


[features]
promicro = []
pico-explorer = []
Expand Down
16 changes: 1 addition & 15 deletions adafruit-featherwing-oled128x64/examples/basic.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
#![no_std]
#![no_main]

cfg_if::cfg_if! {
if #[cfg(feature = "pico-explorer")] {
use pico_explorer_boilerplate as bsp;
} else if #[cfg(feature = "pico-explorer-pio")] {
use pico_explorer_pio_boilerplate as bsp;
} else if #[cfg(feature = "pico-explorer-minimal")] {
use pico_explorer_minimal_boilerplate as bsp;
} else if #[cfg(feature = "promicro")] {
use promicro_rp2040_boilerplate as bsp;
} else if #[cfg(feature = "rpi-pico")] {
use rpi_pico_boilerplate as bsp;
} else {
compile_error!("One platform feature must be selected");
}
}
mod bsp;

use adafruit_featherwing_oled128x64::{Destination, Display, DisplayState};
use defmt_rtt as _;
Expand Down
16 changes: 16 additions & 0 deletions adafruit-featherwing-oled128x64/examples/bsp/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cfg_if::cfg_if! {
if #[cfg(feature = "pico-explorer")] {
include!("pico-explorer-boilerplate.rs");
} else if #[cfg(feature = "pico-explorer-pio")] {
include!("pico-explorer-pio-boilerplate.rs");
} else if #[cfg(feature = "pico-explorer-minimal")] {
include!("pico-explorer-minimal-boilerplate.rs");
} else if #[cfg(feature = "promicro")] {
include!("promicro-rp2040-boilerplate.rs");
} else if #[cfg(feature = "rpi-pico")] {
include!("rpi-pico-boilerplate.rs");
} else {
compile_error!("One platform feature must be selected");
}
}

Original file line number Diff line number Diff line change
@@ -1,31 +1,21 @@
#![no_std]

use core::{
cell::RefCell,
ops::{Deref, DerefMut},
task::{Poll, Waker},
};
use core::{cell::RefCell, task::Waker};

use critical_section::Mutex;
use embedded_hal_async::i2c::ErrorType;
use fugit::{MicrosDurationU32, RateExtU32};
use futures::{future, Future};
use fugit::RateExtU32;
use panic_probe as _;
use pimoroni_pico_explorer::{all_pins::Pins, hal};

use hal::{
gpio::{bank0, FunctionI2C, Pin, PullUp},
pac::{self, interrupt},
sio::Sio,
timer::{Alarm, Alarm0},
watchdog::Watchdog,
Clock,
};

use rp2040_async_i2c::i2c::I2C;

pub use embedded_hal_async::i2c::SevenBitAddress;
pub use hal::timer::Timer;
pub use pimoroni_pico_explorer::entry;

pub type I2CPeriph = I2C<
Expand All @@ -36,69 +26,8 @@ pub type I2CPeriph = I2C<
),
>;

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) {
if delay < 20 {
let start = timer.get_counter_low();
future::poll_fn(|cx| {
if timer.get_counter_low().wrapping_sub(start) < delay {
cx.waker().wake_by_ref();
Poll::Pending
} else {
Poll::Ready(())
}
})
.await;
} else {
let mut started = false;
future::poll_fn(move |cx| {
critical_section::with(|cs| {
if let Some((alarm, waker)) = ALARM0_WAKER.borrow_ref_mut(cs).as_mut() {
if !started {
alarm.clear_interrupt();
alarm.enable_interrupt();
alarm.schedule(MicrosDurationU32::micros(delay)).unwrap();
started = true;
*waker = Some(cx.waker().clone());
Poll::Pending
} else if alarm.finished() {
Poll::Ready(())
} else {
*waker = Some(cx.waker().clone());
Poll::Pending
}
} else {
unreachable!()
}
})
})
.await;
}
}

pub async fn timed<T>(op: &str, timer: &Timer, fut: impl Future<Output = T>) -> T {
let start = timer.get_counter_low();
let res = fut.await;
let diff = timer.get_counter_low().wrapping_sub(start);
defmt::info!("{} took {}us", op, diff);
res
}

#[interrupt]
#[allow(non_snake_case)]
fn TIMER_IRQ_0() {
critical_section::with(|cs| {
ALARM0_WAKER
.borrow_ref_mut(cs)
.as_mut()
.and_then(|(alarm, waker)| {
alarm.disable_interrupt();
waker.take()
})
.map(|waker| waker.wake())
});
}
mod timer;
pub use timer::*;

static I2C_WAKER: Mutex<RefCell<Option<Waker>>> = Mutex::new(RefCell::new(None));
pub fn waker_setter(waker: Waker) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
#![no_std]
use core::task::Poll;

use core::{
ops::{Deref, DerefMut},
task::Poll,
};

use embedded_hal_async::i2c::ErrorType;
use fugit::{ExtU32, RateExtU32};
use futures::{future, Future};
use panic_probe as _;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
#![no_std]

use core::{
cell::RefCell,
ops::{Deref, DerefMut},
task::{Poll, Waker},
};
use core::cell::RefCell;

use critical_section::Mutex;
use embedded_hal_async::i2c::ErrorType;
use fugit::{MicrosDurationU32, RateExtU32};
use futures::{future, Future};
use fugit::RateExtU32;
use panic_probe as _;
use pimoroni_pico_explorer::{
all_pins::Pins,
hal::{
self,
gpio::{FunctionNull, PullUp, Pin},
gpio::{FunctionNull, Pin, PullUp},
pio::PIOExt,
pio::SM0,
},
Expand All @@ -26,17 +18,18 @@ use hal::{
gpio::bank0,
pac::{self, interrupt},
sio::Sio,
timer::{Alarm, Alarm0},
watchdog::Watchdog,
Clock,
};

use rp2040_async_i2c::pio::I2C;

pub use embedded_hal_async::i2c::SevenBitAddress;
pub use hal::timer::Timer;
pub use pimoroni_pico_explorer::entry;

mod timer;
pub use timer::*;

pub type I2CPeriph = I2C<
'static,
PIO0,
Expand All @@ -45,70 +38,6 @@ pub type I2CPeriph = I2C<
Pin<bank0::Gpio21, FunctionNull, PullUp>,
>;

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) {
if delay < 20 {
let start = timer.get_counter_low();
future::poll_fn(|cx| {
if timer.get_counter_low().wrapping_sub(start) < delay {
cx.waker().wake_by_ref();
Poll::Pending
} else {
Poll::Ready(())
}
})
.await;
} else {
let mut started = false;
future::poll_fn(move |cx| {
critical_section::with(|cs| {
if let Some((alarm, waker)) = ALARM0_WAKER.borrow_ref_mut(cs).as_mut() {
if !started {
alarm.clear_interrupt();
alarm.enable_interrupt();
alarm.schedule(MicrosDurationU32::micros(delay)).unwrap();
started = true;
*waker = Some(cx.waker().clone());
Poll::Pending
} else if alarm.finished() {
Poll::Ready(())
} else {
*waker = Some(cx.waker().clone());
Poll::Pending
}
} else {
unreachable!()
}
})
})
.await;
}
}

pub async fn timed<T>(op: &str, timer: &Timer, fut: impl Future<Output = T>) -> T {
let start = timer.get_counter_low();
let res = fut.await;
let diff = timer.get_counter_low().wrapping_sub(start);
defmt::info!("{} took {}us", op, diff);
res
}

#[interrupt]
#[allow(non_snake_case)]
fn TIMER_IRQ_0() {
critical_section::with(|cs| {
ALARM0_WAKER
.borrow_ref_mut(cs)
.as_mut()
.and_then(|(alarm, waker)| {
alarm.disable_interrupt();
waker.take()
})
.map(|waker| waker.wake())
});
}

static mut PIO: Option<hal::pio::PIO<PIO0>> = None;
static PIO_WAKER: Mutex<RefCell<Option<core::task::Waker>>> = Mutex::new(RefCell::new(None));
fn waker_setter(waker: core::task::Waker) {
Expand Down
Loading

0 comments on commit d57715a

Please sign in to comment.