mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 14:44:42 +00:00
Optionally type-erased GPIO drivers (#2075)
* Remove type erased gpio structs * Implement Peripheral for ErasedPin * Simpler type erasing, accept ErasedPin in pin drivers, remove type erased drivers * Reformulate pin drivers using Flex * Erase gpio types by default * Accept any pin in AnyPin * Add changelog and migration guide * Fix tests and examples * Undo rename of clone_unchecked
This commit is contained in:
parent
a5ab73959e
commit
f11c18a6b9
@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Implement `embedded-hal` output pin traits for `DummyPin` (#2019)
|
||||
- Added `esp_hal::init` to simplify HAL initialisation (#1970, #1999)
|
||||
- Added GpioPin::degrade to create ErasePins easily. Same for AnyPin by accident. (#2075)
|
||||
- Added missing functions to `Flex`: `unlisten`, `is_interrupt_set`, `wakeup_enable`, `wait_for_high`, `wait_for_low`, `wait_for_rising_edge`, `wait_for_falling_edge`, `wait_for_any_edge`. (#2075)
|
||||
- `Flex` now implements `Wait`. (#2075)
|
||||
- Added sleep and wakeup support for esp32c2 (#1922)
|
||||
|
||||
### Changed
|
||||
@ -18,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- `Delay::new()` is now a `const` function (#1999)
|
||||
- You can now create an `AnyPin` out of an `ErasedPin`. (#2072)
|
||||
- `Input`, `Output`, `OutputOpenDrain` and `Flex` are now type-erased by default. Use the new `new_typed` constructor to keep using the ZST pin types. (#2075)
|
||||
|
||||
### Fixed
|
||||
- SHA driver can now be safely used in multiple contexts concurrently (#2049)
|
||||
|
@ -41,3 +41,13 @@ Instead of manually grabbing peripherals and setting up clocks, you should now c
|
||||
- The `GpioN` type aliasses are no longer available. You can use `GpioPin<N>` instead.
|
||||
- The `AnyInputOnlyPin` has been removed. Replace any use with `AnyPin`.
|
||||
- The `NoPinType` has been removed. You can use `DummyPin` in its place.
|
||||
|
||||
### Type-erased GPIO drivers
|
||||
|
||||
You no longer have to spell out the GPIO pin type for `Input`, `Output`, `OutputOpenDrain` or `Flex`.
|
||||
However, if you want to, you can keep using their typed form!
|
||||
|
||||
```rust
|
||||
let pin = Input::new(io.gpio0); // pin will have the type `Input<'some>` (or `Input<'some, ErasedPin>` if you want to be explicit about it)
|
||||
let pin = Input::new_typed(io.gpio0); // pin will have the type `Input<'some, GpioPin<0>>`
|
||||
```
|
||||
|
@ -13,9 +13,12 @@ pub struct AnyPin<'d> {
|
||||
impl<'d> AnyPin<'d> {
|
||||
/// Create wrapper for the given pin.
|
||||
#[inline]
|
||||
pub fn new<P: CreateErasedPin>(pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self {
|
||||
pub fn new<P>(pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||
where
|
||||
P: Pin,
|
||||
{
|
||||
crate::into_ref!(pin);
|
||||
let pin = pin.erased_pin(private::Internal);
|
||||
let pin = pin.degrade_internal(private::Internal);
|
||||
|
||||
Self {
|
||||
pin,
|
||||
@ -27,11 +30,12 @@ impl<'d> AnyPin<'d> {
|
||||
/// Create wrapper for the given pin. The peripheral signal will be
|
||||
/// inverted.
|
||||
#[inline]
|
||||
pub fn new_inverted<P: OutputPin + InputPin + CreateErasedPin>(
|
||||
pin: impl crate::peripheral::Peripheral<P = P> + 'd,
|
||||
) -> Self {
|
||||
pub fn new_inverted<P>(pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||
where
|
||||
P: Pin,
|
||||
{
|
||||
crate::into_ref!(pin);
|
||||
let pin = pin.erased_pin(private::Internal);
|
||||
let pin = pin.degrade_internal(private::Internal);
|
||||
|
||||
Self {
|
||||
pin,
|
||||
@ -59,6 +63,7 @@ impl<'d> Pin for AnyPin<'d> {
|
||||
delegate::delegate! {
|
||||
to self.pin {
|
||||
fn number(&self, _internal: private::Internal) -> u8;
|
||||
fn degrade_internal(&self, _internal: private::Internal) -> ErasedPin;
|
||||
fn sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||
fn set_alternate_function(&mut self, alternate: AlternateFunction, _internal: private::Internal);
|
||||
fn is_listening(&self, _internal: private::Internal) -> bool;
|
||||
|
@ -32,6 +32,10 @@ impl Pin for DummyPin {
|
||||
panic!("DummyPin not supported here!");
|
||||
}
|
||||
|
||||
fn degrade_internal(&self, _: private::Internal) -> ErasedPin {
|
||||
panic!("Can not type erase the DummyPin!");
|
||||
}
|
||||
|
||||
fn sleep_mode(&mut self, _on: bool, _: private::Internal) {}
|
||||
|
||||
fn set_alternate_function(&mut self, _alternate: AlternateFunction, _: private::Internal) {}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
delay::Delay,
|
||||
gpio::{AnyInput, AnyOutput, Io, Level, Pull},
|
||||
gpio::{ErasedPin, Input, Io, Level, Output, Pin, Pull},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
@ -25,17 +25,17 @@ fn main() -> ! {
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
// Set LED GPIOs as an output:
|
||||
let led1 = AnyOutput::new(io.pins.gpio2, Level::Low);
|
||||
let led2 = AnyOutput::new(io.pins.gpio4, Level::Low);
|
||||
let led3 = AnyOutput::new(io.pins.gpio5, Level::Low);
|
||||
let led1 = Output::new(io.pins.gpio2.degrade(), Level::Low);
|
||||
let led2 = Output::new(io.pins.gpio4.degrade(), Level::Low);
|
||||
let led3 = Output::new(io.pins.gpio5.degrade(), Level::Low);
|
||||
|
||||
// Use boot button as an input:
|
||||
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
||||
let button = io.pins.gpio0;
|
||||
let button = io.pins.gpio0.degrade();
|
||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
|
||||
let button = io.pins.gpio9;
|
||||
let button = io.pins.gpio9.degrade();
|
||||
|
||||
let button = AnyInput::new(button, Pull::Up);
|
||||
let button = Input::new(button, Pull::Up);
|
||||
|
||||
let mut pins = [led1, led2, led3];
|
||||
|
||||
@ -47,7 +47,7 @@ fn main() -> ! {
|
||||
}
|
||||
}
|
||||
|
||||
fn toggle_pins(leds: &mut [AnyOutput], button: &AnyInput) {
|
||||
fn toggle_pins(leds: &mut [Output<ErasedPin>], button: &Input<ErasedPin>) {
|
||||
for pin in leds.iter_mut() {
|
||||
pin.toggle();
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
cpu_control::{CpuControl, Stack},
|
||||
get_core,
|
||||
gpio::{AnyOutput, Io, Level},
|
||||
gpio::{ErasedPin, Io, Level, Output, Pin},
|
||||
timer::{timg::TimerGroup, ErasedTimer},
|
||||
};
|
||||
use esp_hal_embassy::Executor;
|
||||
@ -34,7 +34,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new();
|
||||
/// duration of time.
|
||||
#[embassy_executor::task]
|
||||
async fn control_led(
|
||||
mut led: AnyOutput<'static>,
|
||||
mut led: Output<'static, ErasedPin>,
|
||||
control: &'static Signal<CriticalSectionRawMutex, bool>,
|
||||
) {
|
||||
println!("Starting control_led() on core {}", get_core() as usize);
|
||||
@ -65,7 +65,7 @@ async fn main(_spawner: Spawner) {
|
||||
static LED_CTRL: StaticCell<Signal<CriticalSectionRawMutex, bool>> = StaticCell::new();
|
||||
let led_ctrl_signal = &*LED_CTRL.init(Signal::new());
|
||||
|
||||
let led = AnyOutput::new(io.pins.gpio0, Level::Low);
|
||||
let led = Output::new(io.pins.gpio0.degrade(), Level::Low);
|
||||
|
||||
let _guard = cpu_control
|
||||
.start_app_core(unsafe { &mut *addr_of_mut!(APP_CORE_STACK) }, move || {
|
||||
|
@ -20,7 +20,7 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
cpu_control::{CpuControl, Stack},
|
||||
get_core,
|
||||
gpio::{AnyOutput, Io, Level},
|
||||
gpio::{ErasedPin, Io, Level, Output, Pin},
|
||||
interrupt::{software::SoftwareInterruptControl, Priority},
|
||||
prelude::*,
|
||||
timer::{timg::TimerGroup, ErasedTimer},
|
||||
@ -35,7 +35,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new();
|
||||
/// duration of time.
|
||||
#[embassy_executor::task]
|
||||
async fn control_led(
|
||||
mut led: AnyOutput<'static>,
|
||||
mut led: Output<'static, ErasedPin>,
|
||||
control: &'static Signal<CriticalSectionRawMutex, bool>,
|
||||
) {
|
||||
println!("Starting control_led() on core {}", get_core() as usize);
|
||||
@ -87,7 +87,7 @@ fn main() -> ! {
|
||||
static LED_CTRL: StaticCell<Signal<CriticalSectionRawMutex, bool>> = StaticCell::new();
|
||||
let led_ctrl_signal = &*LED_CTRL.init(Signal::new());
|
||||
|
||||
let led = AnyOutput::new(io.pins.gpio0, Level::Low);
|
||||
let led = Output::new(io.pins.gpio0.degrade(), Level::Low);
|
||||
|
||||
static EXECUTOR_CORE_1: StaticCell<InterruptExecutor<1>> = StaticCell::new();
|
||||
let executor_core1 = InterruptExecutor::new(sw_ints.software_interrupt1);
|
||||
|
@ -13,7 +13,7 @@ use embassy_executor::Spawner;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
gpio::{GpioPin, Io, Level, Output},
|
||||
gpio::{Io, Level, Output},
|
||||
prelude::*,
|
||||
rmt::{asynch::RxChannelAsync, PulseCode, Rmt, RxChannelConfig, RxChannelCreatorAsync},
|
||||
timer::timg::TimerGroup,
|
||||
@ -26,7 +26,7 @@ const WIDTH: usize = 80;
|
||||
compile_error!("Run this example in release mode");
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn signal_task(mut pin: Output<'static, GpioPin<5>>) {
|
||||
async fn signal_task(mut pin: Output<'static>) {
|
||||
loop {
|
||||
for _ in 0..10 {
|
||||
pin.toggle();
|
||||
|
@ -17,20 +17,12 @@ use critical_section::Mutex;
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
delay::Delay,
|
||||
gpio::{Event, GpioPin, Input, Io, Level, Output, Pull},
|
||||
gpio::{Event, Input, Io, Level, Output, Pull},
|
||||
macros::ram,
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] {
|
||||
const BUTTON_PIN: u8 = 0;
|
||||
} else {
|
||||
const BUTTON_PIN: u8 = 9;
|
||||
}
|
||||
}
|
||||
|
||||
static BUTTON: Mutex<RefCell<Option<Input<GpioPin<BUTTON_PIN>>>>> = Mutex::new(RefCell::new(None));
|
||||
static BUTTON: Mutex<RefCell<Option<Input>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
|
@ -34,7 +34,7 @@ use esp_hal::{
|
||||
delay::Delay,
|
||||
dma::{Dma, DmaPriority},
|
||||
dma_buffers,
|
||||
gpio::{GpioPin, Input, Io, Level, Output, Pull},
|
||||
gpio::{Input, Io, Level, Output, Pull},
|
||||
prelude::*,
|
||||
spi::{
|
||||
slave::{prelude::*, Spi},
|
||||
@ -48,17 +48,16 @@ fn main() -> ! {
|
||||
let peripherals = esp_hal::init(esp_hal::Config::default());
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let slave_sclk = io.pins.gpio0;
|
||||
|
||||
let mut master_sclk = Output::new(io.pins.gpio4, Level::Low);
|
||||
let slave_miso = io.pins.gpio1;
|
||||
let master_miso = Input::new(io.pins.gpio5, Pull::None);
|
||||
let slave_mosi = io.pins.gpio2;
|
||||
let mut master_mosi = Output::new(io.pins.gpio8, Level::Low);
|
||||
let mut master_cs = Output::new(io.pins.gpio9, Level::High);
|
||||
|
||||
let slave_sclk = io.pins.gpio0;
|
||||
let slave_miso = io.pins.gpio1;
|
||||
let slave_mosi = io.pins.gpio2;
|
||||
let slave_cs = io.pins.gpio3;
|
||||
let mut master_cs = Output::new(io.pins.gpio9, Level::Low);
|
||||
master_cs.set_high();
|
||||
master_sclk.set_low();
|
||||
master_mosi.set_low();
|
||||
|
||||
let dma = Dma::new(peripherals.DMA);
|
||||
cfg_if::cfg_if! {
|
||||
@ -189,10 +188,10 @@ fn main() -> ! {
|
||||
fn bitbang_master(
|
||||
master_send: &[u8],
|
||||
master_receive: &mut [u8],
|
||||
master_cs: &mut Output<GpioPin<9>>,
|
||||
master_mosi: &mut Output<GpioPin<8>>,
|
||||
master_sclk: &mut Output<GpioPin<4>>,
|
||||
master_miso: &Input<GpioPin<5>>,
|
||||
master_cs: &mut Output,
|
||||
master_mosi: &mut Output,
|
||||
master_sclk: &mut Output,
|
||||
master_miso: &Input,
|
||||
) {
|
||||
// Bit-bang out the contents of master_send and read into master_receive
|
||||
// as quickly as manageable. MSB first. Mode 0, so sampled on the rising
|
||||
|
@ -49,8 +49,7 @@ macro_rules! common_test_pins {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(esp32s2, esp32s3))] {
|
||||
($io.pins.gpio9, $io.pins.gpio10)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
($io.pins.gpio2, $io.pins.gpio3)
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ use esp_hal::{
|
||||
dma::{Dma, DmaPriority},
|
||||
dma_buffers,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
};
|
||||
use hil_test as _;
|
||||
|
||||
|
@ -20,7 +20,7 @@ mod tests {
|
||||
|
||||
#[init]
|
||||
fn init() -> Context {
|
||||
let peripherals = esp_hal::init(esp_hal::Config::default());
|
||||
let _peripherals = esp_hal::init(esp_hal::Config::default());
|
||||
let delay = Delay::new();
|
||||
|
||||
Context { delay }
|
||||
|
@ -61,7 +61,7 @@ mod tests {
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
fn test_current_time_construct_timg0(ctx: Context) {
|
||||
time_moves_forward_during(ctx, |ctx| {
|
||||
time_moves_forward_during(ctx, |_| {
|
||||
// construct the timer in between calls to current_time
|
||||
let _ = esp_hal::timer::timg::TimerGroup::new(unsafe {
|
||||
esp_hal::peripherals::TIMG0::steal()
|
||||
|
@ -15,7 +15,7 @@ use core::cell::RefCell;
|
||||
use critical_section::Mutex;
|
||||
use esp_hal::{
|
||||
delay::Delay,
|
||||
gpio::{AnyPin, GpioPin, Input, Io, Level, Output, Pull},
|
||||
gpio::{AnyPin, ErasedPin, Input, Io, Level, Output, Pin, Pull},
|
||||
macros::handler,
|
||||
timer::timg::TimerGroup,
|
||||
InterruptConfigurable,
|
||||
@ -23,22 +23,11 @@ use esp_hal::{
|
||||
use hil_test as _;
|
||||
|
||||
static COUNTER: Mutex<RefCell<u32>> = Mutex::new(RefCell::new(0));
|
||||
static INPUT_PIN: Mutex<RefCell<Option<Input<'static, TestGpio1>>>> =
|
||||
Mutex::new(RefCell::new(None));
|
||||
static INPUT_PIN: Mutex<RefCell<Option<Input>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(not(any(esp32s2, esp32s3)))] {
|
||||
pub type TestGpio1 = GpioPin<2>;
|
||||
pub type TestGpio2 = GpioPin<3>;
|
||||
} else if #[cfg(any(esp32s2, esp32s3))] {
|
||||
pub type TestGpio1 = GpioPin<9>;
|
||||
pub type TestGpio2 = GpioPin<10>;
|
||||
}
|
||||
}
|
||||
|
||||
struct Context<'d> {
|
||||
test_gpio1: Input<'d, TestGpio1>,
|
||||
test_gpio2: Output<'d, TestGpio2>,
|
||||
struct Context {
|
||||
test_gpio1: ErasedPin,
|
||||
test_gpio2: ErasedPin,
|
||||
delay: Delay,
|
||||
}
|
||||
|
||||
@ -64,7 +53,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[init]
|
||||
fn init() -> Context<'static> {
|
||||
fn init() -> Context {
|
||||
let peripherals = esp_hal::init(esp_hal::Config::default());
|
||||
|
||||
let mut io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
@ -78,20 +67,22 @@ mod tests {
|
||||
esp_hal_embassy::init(timg0.timer0);
|
||||
|
||||
Context {
|
||||
test_gpio1: Input::new(gpio1, Pull::Down),
|
||||
test_gpio2: Output::new(gpio2, Level::Low),
|
||||
test_gpio1: gpio1.degrade(),
|
||||
test_gpio2: gpio2.degrade(),
|
||||
delay,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn test_async_edge(ctx: Context<'static>) {
|
||||
async fn test_async_edge(ctx: Context) {
|
||||
let counter = AtomicUsize::new(0);
|
||||
let Context {
|
||||
mut test_gpio1,
|
||||
mut test_gpio2,
|
||||
test_gpio1,
|
||||
test_gpio2,
|
||||
..
|
||||
} = ctx;
|
||||
let mut test_gpio1 = Input::new(test_gpio1, Pull::Down);
|
||||
let mut test_gpio2 = Output::new(test_gpio2, Level::Low);
|
||||
embassy_futures::select::select(
|
||||
async {
|
||||
loop {
|
||||
@ -113,8 +104,8 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn test_a_pin_can_wait(_ctx: Context<'static>) {
|
||||
let mut first = Input::new(unsafe { GpioPin::<0>::steal() }, Pull::Down);
|
||||
async fn test_a_pin_can_wait(ctx: Context) {
|
||||
let mut first = Input::new(ctx.test_gpio1, Pull::Down);
|
||||
|
||||
embassy_futures::select::select(
|
||||
first.wait_for_rising_edge(),
|
||||
@ -126,69 +117,74 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpio_input(ctx: Context<'static>) {
|
||||
fn test_gpio_input(ctx: Context) {
|
||||
let test_gpio1 = Input::new(ctx.test_gpio1, Pull::Down);
|
||||
// `InputPin`:
|
||||
assert_eq!(ctx.test_gpio1.is_low(), true);
|
||||
assert_eq!(ctx.test_gpio1.is_high(), false);
|
||||
assert_eq!(test_gpio1.is_low(), true);
|
||||
assert_eq!(test_gpio1.is_high(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpio_output(mut ctx: Context<'static>) {
|
||||
fn test_gpio_output(ctx: Context) {
|
||||
let mut test_gpio2 = Output::new(ctx.test_gpio2, Level::Low);
|
||||
|
||||
// `StatefulOutputPin`:
|
||||
assert_eq!(ctx.test_gpio2.is_set_low(), true);
|
||||
assert_eq!(ctx.test_gpio2.is_set_high(), false);
|
||||
ctx.test_gpio2.set_high();
|
||||
assert_eq!(ctx.test_gpio2.is_set_low(), false);
|
||||
assert_eq!(ctx.test_gpio2.is_set_high(), true);
|
||||
assert_eq!(test_gpio2.is_set_low(), true);
|
||||
assert_eq!(test_gpio2.is_set_high(), false);
|
||||
test_gpio2.set_high();
|
||||
assert_eq!(test_gpio2.is_set_low(), false);
|
||||
assert_eq!(test_gpio2.is_set_high(), true);
|
||||
|
||||
// `ToggleableOutputPin`:
|
||||
ctx.test_gpio2.toggle();
|
||||
assert_eq!(ctx.test_gpio2.is_set_low(), true);
|
||||
assert_eq!(ctx.test_gpio2.is_set_high(), false);
|
||||
ctx.test_gpio2.toggle();
|
||||
assert_eq!(ctx.test_gpio2.is_set_low(), false);
|
||||
assert_eq!(ctx.test_gpio2.is_set_high(), true);
|
||||
test_gpio2.toggle();
|
||||
assert_eq!(test_gpio2.is_set_low(), true);
|
||||
assert_eq!(test_gpio2.is_set_high(), false);
|
||||
test_gpio2.toggle();
|
||||
assert_eq!(test_gpio2.is_set_low(), false);
|
||||
assert_eq!(test_gpio2.is_set_high(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpio_interrupt(mut ctx: Context<'static>) {
|
||||
fn test_gpio_interrupt(ctx: Context) {
|
||||
let mut test_gpio1 = Input::new(ctx.test_gpio1, Pull::Down);
|
||||
let mut test_gpio2 = Output::new(ctx.test_gpio2, Level::Low);
|
||||
|
||||
critical_section::with(|cs| {
|
||||
*COUNTER.borrow_ref_mut(cs) = 0;
|
||||
ctx.test_gpio1.listen(Event::AnyEdge);
|
||||
INPUT_PIN.borrow_ref_mut(cs).replace(ctx.test_gpio1);
|
||||
test_gpio1.listen(Event::AnyEdge);
|
||||
INPUT_PIN.borrow_ref_mut(cs).replace(test_gpio1);
|
||||
});
|
||||
ctx.test_gpio2.set_high();
|
||||
test_gpio2.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
ctx.test_gpio2.set_low();
|
||||
test_gpio2.set_low();
|
||||
ctx.delay.delay_millis(1);
|
||||
ctx.test_gpio2.set_high();
|
||||
test_gpio2.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
ctx.test_gpio2.set_low();
|
||||
test_gpio2.set_low();
|
||||
ctx.delay.delay_millis(1);
|
||||
ctx.test_gpio2.set_high();
|
||||
test_gpio2.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
ctx.test_gpio2.set_low();
|
||||
test_gpio2.set_low();
|
||||
ctx.delay.delay_millis(1);
|
||||
ctx.test_gpio2.set_high();
|
||||
test_gpio2.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
ctx.test_gpio2.set_low();
|
||||
test_gpio2.set_low();
|
||||
ctx.delay.delay_millis(1);
|
||||
ctx.test_gpio2.set_high();
|
||||
test_gpio2.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
|
||||
let count = critical_section::with(|cs| *COUNTER.borrow_ref(cs));
|
||||
assert_eq!(count, 9);
|
||||
|
||||
ctx.test_gpio1 = critical_section::with(|cs| INPUT_PIN.borrow_ref_mut(cs).take().unwrap());
|
||||
ctx.test_gpio1.unlisten();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpio_od(ctx: Context<'static>) {
|
||||
let mut test_gpio1 =
|
||||
OutputOpenDrain::new(unsafe { TestGpio1::steal() }, Level::High, Pull::Up);
|
||||
let mut test_gpio2 =
|
||||
OutputOpenDrain::new(unsafe { TestGpio2::steal() }, Level::High, Pull::Up);
|
||||
critical_section::with(|cs| INPUT_PIN.borrow_ref_mut(cs).take().unwrap());
|
||||
test_gpio1.unlisten();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpio_od(ctx: Context) {
|
||||
let mut test_gpio1 = OutputOpenDrain::new(ctx.test_gpio1, Level::High, Pull::Up);
|
||||
let mut test_gpio2 = OutputOpenDrain::new(ctx.test_gpio2, Level::High, Pull::Up);
|
||||
|
||||
ctx.delay.delay_millis(1);
|
||||
|
||||
@ -232,9 +228,9 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpio_flex(ctx: Context<'static>) {
|
||||
let mut test_gpio1 = Flex::new(unsafe { TestGpio1::steal() });
|
||||
let mut test_gpio2 = Flex::new(unsafe { TestGpio2::steal() });
|
||||
fn test_gpio_flex(ctx: Context) {
|
||||
let mut test_gpio1 = Flex::new(ctx.test_gpio1);
|
||||
let mut test_gpio2 = Flex::new(ctx.test_gpio2);
|
||||
|
||||
test_gpio1.set_high();
|
||||
test_gpio1.set_as_output();
|
||||
@ -274,9 +270,9 @@ mod tests {
|
||||
// Tests touch pin (GPIO2) as AnyPin and Output
|
||||
// https://github.com/esp-rs/esp-hal/issues/1943
|
||||
#[test]
|
||||
fn test_gpio_touch_anypin_output() {
|
||||
let any_pin2 = AnyPin::new(unsafe { TestGpio1::steal() });
|
||||
let any_pin3 = AnyPin::new(unsafe { TestGpio2::steal() });
|
||||
fn test_gpio_touch_anypin_output(ctx: Context) {
|
||||
let any_pin2 = AnyPin::new(ctx.test_gpio1);
|
||||
let any_pin3 = AnyPin::new(ctx.test_gpio2);
|
||||
|
||||
let out_pin = Output::new(any_pin2, Level::High);
|
||||
let in_pin = Input::new(any_pin3, Pull::Down);
|
||||
@ -288,9 +284,9 @@ mod tests {
|
||||
// Tests touch pin (GPIO2) as AnyPin and Input
|
||||
// https://github.com/esp-rs/esp-hal/issues/1943
|
||||
#[test]
|
||||
fn test_gpio_touch_anypin_input() {
|
||||
let any_pin2 = AnyPin::new(unsafe { TestGpio1::steal() });
|
||||
let any_pin3 = AnyPin::new(unsafe { TestGpio2::steal() });
|
||||
fn test_gpio_touch_anypin_input(ctx: Context) {
|
||||
let any_pin2 = AnyPin::new(ctx.test_gpio1);
|
||||
let any_pin3 = AnyPin::new(ctx.test_gpio2);
|
||||
|
||||
let out_pin = Output::new(any_pin3, Level::Low);
|
||||
let in_pin = Input::new(any_pin2, Pull::Down);
|
||||
|
@ -15,7 +15,7 @@
|
||||
use esp_hal::{
|
||||
dma::{Channel, Dma, DmaPriority, DmaRxBuf},
|
||||
dma_buffers,
|
||||
gpio::{AnyOutput, AnyPin, Io, Level},
|
||||
gpio::{ErasedPin, Io, Level, Output},
|
||||
prelude::*,
|
||||
spi::{
|
||||
master::{Address, Command, Spi, SpiDma},
|
||||
@ -41,13 +41,13 @@ cfg_if::cfg_if! {
|
||||
struct Context {
|
||||
spi: esp_hal::peripherals::SPI2,
|
||||
dma_channel: Channel<'static, DmaChannel0, Blocking>,
|
||||
miso: AnyPin<'static>,
|
||||
miso_mirror: AnyOutput<'static>,
|
||||
miso: ErasedPin,
|
||||
miso_mirror: Output<'static>,
|
||||
}
|
||||
|
||||
fn execute(
|
||||
mut spi: SpiDma<'static, esp_hal::peripherals::SPI2, DmaChannel0, HalfDuplexMode, Blocking>,
|
||||
mut miso_mirror: AnyOutput<'static>,
|
||||
mut miso_mirror: Output<'static>,
|
||||
wanted: u8,
|
||||
) {
|
||||
const DMA_BUFFER_SIZE: usize = 4;
|
||||
@ -103,8 +103,8 @@ mod tests {
|
||||
|
||||
let (miso, miso_mirror) = hil_test::common_test_pins!(io);
|
||||
|
||||
let miso = AnyPin::new(miso);
|
||||
let miso_mirror = AnyOutput::new(miso_mirror, Level::High);
|
||||
let miso = miso.degrade();
|
||||
let miso_mirror = Output::new(miso_mirror, Level::High);
|
||||
|
||||
let dma = Dma::new(peripherals.DMA);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
use esp_hal::{
|
||||
dma::{Channel, Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||
dma_buffers,
|
||||
gpio::{AnyOutput, AnyPin, Io, Level},
|
||||
gpio::{ErasedPin, Io, Level, Output},
|
||||
prelude::*,
|
||||
spi::{
|
||||
master::{Address, Command, Spi, SpiDma},
|
||||
@ -43,13 +43,13 @@ cfg_if::cfg_if! {
|
||||
struct Context {
|
||||
spi: esp_hal::peripherals::SPI2,
|
||||
dma_channel: Channel<'static, DmaChannel0, Blocking>,
|
||||
mosi: AnyPin<'static>,
|
||||
mosi_mirror: AnyOutput<'static>,
|
||||
mosi: ErasedPin,
|
||||
mosi_mirror: Output<'static>,
|
||||
}
|
||||
|
||||
fn execute(
|
||||
mut spi: SpiDma<'static, esp_hal::peripherals::SPI2, DmaChannel0, HalfDuplexMode, Blocking>,
|
||||
mut mosi_mirror: AnyOutput<'static>,
|
||||
mut mosi_mirror: Output<'static>,
|
||||
wanted: u8,
|
||||
) {
|
||||
const DMA_BUFFER_SIZE: usize = 4;
|
||||
@ -105,8 +105,8 @@ mod tests {
|
||||
|
||||
let (mosi, mosi_mirror) = hil_test::common_test_pins!(io);
|
||||
|
||||
let mosi = AnyPin::new(mosi);
|
||||
let mosi_mirror = AnyOutput::new(mosi_mirror, Level::High);
|
||||
let mosi = mosi.degrade();
|
||||
let mosi_mirror = Output::new(mosi_mirror, Level::High);
|
||||
|
||||
let dma = Dma::new(peripherals.DMA);
|
||||
|
||||
|
@ -24,7 +24,7 @@ use embedded_hal_async::spi::SpiBus;
|
||||
use esp_hal::{
|
||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||
dma_buffers,
|
||||
gpio::{AnyPin, GpioPin, Io, Level, Output, Pull},
|
||||
gpio::{ErasedPin, Io, Level, Output, Pull},
|
||||
pcnt::{
|
||||
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
||||
unit::Unit,
|
||||
@ -57,8 +57,8 @@ const DMA_BUFFER_SIZE: usize = 5;
|
||||
struct Context {
|
||||
spi: SpiDmaBus<'static, SPI2, DmaChannel0, FullDuplexMode, Async>,
|
||||
pcnt_unit: Unit<'static, 0>,
|
||||
out_pin: Output<'static, GpioPin<5>>,
|
||||
mosi_mirror: AnyPin<'static>,
|
||||
out_pin: Output<'static>,
|
||||
mosi_mirror: ErasedPin,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -79,7 +79,7 @@ mod tests {
|
||||
let (mosi_mirror, mosi) = hil_test::common_test_pins!(io);
|
||||
let miso = io.pins.gpio4;
|
||||
let cs = io.pins.gpio8;
|
||||
let mosi_mirror = AnyPin::new(mosi_mirror);
|
||||
let mosi_mirror = mosi_mirror.degrade();
|
||||
|
||||
let mut out_pin = Output::new(io.pins.gpio5, Level::Low);
|
||||
out_pin.set_low();
|
||||
|
@ -20,7 +20,7 @@
|
||||
use esp_hal::{
|
||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||
dma_buffers,
|
||||
gpio::{AnyPin, GpioPin, Io, Level, Output, Pull},
|
||||
gpio::{ErasedPin, Io, Level, Output, Pull},
|
||||
pcnt::{
|
||||
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
||||
unit::Unit,
|
||||
@ -51,8 +51,8 @@ cfg_if::cfg_if! {
|
||||
struct Context {
|
||||
spi: SpiDma<'static, SPI2, DmaChannel0, FullDuplexMode, Blocking>,
|
||||
pcnt_unit: Unit<'static, 0>,
|
||||
out_pin: Output<'static, GpioPin<5>>,
|
||||
mosi_mirror: AnyPin<'static>,
|
||||
out_pin: Output<'static>,
|
||||
mosi_mirror: ErasedPin,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -91,7 +91,7 @@ mod tests {
|
||||
let mut out_pin = Output::new(io.pins.gpio5, Level::Low);
|
||||
out_pin.set_low();
|
||||
assert_eq!(out_pin.is_set_low(), true);
|
||||
let mosi_mirror = AnyPin::new(mosi_mirror);
|
||||
let mosi_mirror = mosi_mirror.degrade();
|
||||
|
||||
Context {
|
||||
spi,
|
||||
|
@ -16,7 +16,7 @@
|
||||
use esp_hal::{
|
||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||
dma_buffers,
|
||||
gpio::{AnyOutput, Io, Level},
|
||||
gpio::{Io, Level, Output},
|
||||
peripherals::SPI2,
|
||||
prelude::*,
|
||||
spi::{
|
||||
@ -42,7 +42,7 @@ cfg_if::cfg_if! {
|
||||
|
||||
struct Context {
|
||||
spi: SpiDma<'static, SPI2, DmaChannel0, HalfDuplexMode, Blocking>,
|
||||
miso_mirror: AnyOutput<'static>,
|
||||
miso_mirror: Output<'static>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -60,7 +60,7 @@ mod tests {
|
||||
let sclk = io.pins.gpio0;
|
||||
let (miso, miso_mirror) = hil_test::common_test_pins!(io);
|
||||
|
||||
let miso_mirror = AnyOutput::new(miso_mirror, Level::High);
|
||||
let miso_mirror = Output::new(miso_mirror, Level::High);
|
||||
|
||||
let dma = Dma::new(peripherals.DMA);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user