mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 14:44:42 +00:00
inherent gpio methods (#1284)
This commit is contained in:
parent
ba73154c36
commit
13c81177c5
@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Added async support for TWAI (#1320)
|
- Added async support for TWAI (#1320)
|
||||||
- Add TWAI support for ESP32-C6 (#1323)
|
- Add TWAI support for ESP32-C6 (#1323)
|
||||||
- `GpioPin::steal` unsafe API (#1363)
|
- `GpioPin::steal` unsafe API (#1363)
|
||||||
|
- Inherent implementions of GPIO pin `set_low`, `is_low`, etc.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -542,68 +542,37 @@ pub struct GpioPin<MODE, const GPIONUM: u8> {
|
|||||||
_mode: PhantomData<MODE>,
|
_mode: PhantomData<MODE>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
impl<MODE, const GPIONUM: u8> GpioPin<Input<MODE>, GPIONUM>
|
||||||
impl<MODE, const GPIONUM: u8> embedded_hal_02::digital::v2::InputPin
|
|
||||||
for GpioPin<Input<MODE>, GPIONUM>
|
|
||||||
where
|
where
|
||||||
Self: GpioProperties,
|
Self: GpioProperties,
|
||||||
{
|
{
|
||||||
type Error = core::convert::Infallible;
|
/// Is the input pin high?
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
#[inline]
|
||||||
Ok(<Self as GpioProperties>::Bank::read_input() & (1 << (GPIONUM % 32)) != 0)
|
pub fn is_high(&self) -> bool {
|
||||||
|
<Self as GpioProperties>::Bank::read_input() & (1 << (GPIONUM % 32)) != 0
|
||||||
}
|
}
|
||||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(!self.is_high()?)
|
/// Is the input pin low?
|
||||||
|
#[inline]
|
||||||
|
pub fn is_low(&self) -> bool {
|
||||||
|
!self.is_high()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
impl<const GPIONUM: u8> GpioPin<Output<OpenDrain>, GPIONUM>
|
||||||
impl<const GPIONUM: u8> embedded_hal_02::digital::v2::InputPin
|
|
||||||
for GpioPin<Output<OpenDrain>, GPIONUM>
|
|
||||||
where
|
where
|
||||||
Self: GpioProperties,
|
Self: GpioProperties,
|
||||||
{
|
{
|
||||||
type Error = core::convert::Infallible;
|
/// Is the input pin high?
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
#[inline]
|
||||||
Ok(<Self as GpioProperties>::Bank::read_input() & (1 << (GPIONUM % 32)) != 0)
|
pub fn is_high(&self) -> bool {
|
||||||
|
<Self as GpioProperties>::Bank::read_input() & (1 << (GPIONUM % 32)) != 0
|
||||||
}
|
}
|
||||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(!self.is_high()?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
/// Is the input pin low?
|
||||||
impl<MODE, const GPIONUM: u8> embedded_hal::digital::ErrorType for GpioPin<Input<MODE>, GPIONUM>
|
#[inline]
|
||||||
where
|
pub fn is_low(&self) -> bool {
|
||||||
Self: GpioProperties,
|
!self.is_high()
|
||||||
{
|
|
||||||
type Error = core::convert::Infallible;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
|
||||||
impl<MODE, const GPIONUM: u8> embedded_hal::digital::InputPin for GpioPin<Input<MODE>, GPIONUM>
|
|
||||||
where
|
|
||||||
Self: GpioProperties,
|
|
||||||
{
|
|
||||||
fn is_high(&mut self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(<Self as GpioProperties>::Bank::read_input() & (1 << (GPIONUM % 32)) != 0)
|
|
||||||
}
|
|
||||||
fn is_low(&mut self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(!self.is_high()?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
|
||||||
impl<const GPIONUM: u8> embedded_hal::digital::InputPin for GpioPin<Output<OpenDrain>, GPIONUM>
|
|
||||||
where
|
|
||||||
Self: GpioProperties,
|
|
||||||
<Self as GpioProperties>::PinType: IsOutputPin,
|
|
||||||
{
|
|
||||||
fn is_high(&mut self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(<Self as GpioProperties>::Bank::read_input() & (1 << (GPIONUM % 32)) != 0)
|
|
||||||
}
|
|
||||||
fn is_low(&mut self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(!self.is_high()?)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -906,97 +875,49 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
impl<MODE, const GPIONUM: u8> GpioPin<Output<MODE>, GPIONUM>
|
||||||
impl<MODE, const GPIONUM: u8> embedded_hal_02::digital::v2::OutputPin
|
|
||||||
for GpioPin<Output<MODE>, GPIONUM>
|
|
||||||
where
|
where
|
||||||
Self: GpioProperties,
|
Self: GpioProperties,
|
||||||
<Self as GpioProperties>::PinType: IsOutputPin,
|
<Self as GpioProperties>::PinType: IsOutputPin,
|
||||||
{
|
{
|
||||||
type Error = core::convert::Infallible;
|
/// Drives the pin high.
|
||||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
#[inline]
|
||||||
|
pub fn set_high(&mut self) {
|
||||||
<Self as GpioProperties>::Bank::write_output_set(1 << (GPIONUM % 32));
|
<Self as GpioProperties>::Bank::write_output_set(1 << (GPIONUM % 32));
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
|
||||||
|
/// Drives the pin low.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_low(&mut self) {
|
||||||
<Self as GpioProperties>::Bank::write_output_clear(1 << (GPIONUM % 32));
|
<Self as GpioProperties>::Bank::write_output_clear(1 << (GPIONUM % 32));
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
// TODO: add `set_state(PinState)`
|
||||||
impl<MODE, const GPIONUM: u8> embedded_hal_02::digital::v2::StatefulOutputPin
|
// Drives the pin high or low depending on the provided value.
|
||||||
for GpioPin<Output<MODE>, GPIONUM>
|
|
||||||
where
|
|
||||||
Self: GpioProperties,
|
|
||||||
<Self as GpioProperties>::PinType: IsOutputPin,
|
|
||||||
{
|
|
||||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(<Self as GpioProperties>::Bank::read_output() & (1 << (GPIONUM % 32)) != 0)
|
|
||||||
}
|
|
||||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(!self.is_set_high()?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
/// Is the pin in drive high mode?
|
||||||
impl<MODE, const GPIONUM: u8> embedded_hal_02::digital::v2::ToggleableOutputPin
|
#[inline]
|
||||||
for GpioPin<Output<MODE>, GPIONUM>
|
pub fn is_set_high(&self) -> bool {
|
||||||
where
|
<Self as GpioProperties>::Bank::read_output() & (1 << (GPIONUM % 32)) != 0
|
||||||
Self: GpioProperties,
|
}
|
||||||
<Self as GpioProperties>::PinType: IsOutputPin,
|
|
||||||
{
|
/// Is the pin in drive low mode?
|
||||||
type Error = core::convert::Infallible;
|
#[inline]
|
||||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
pub fn is_set_low(&self) -> bool {
|
||||||
use embedded_hal_02::digital::v2::{OutputPin as _, StatefulOutputPin as _};
|
!self.is_set_high()
|
||||||
if self.is_set_high()? {
|
}
|
||||||
Ok(self.set_low()?)
|
|
||||||
|
/// Toggle pin output.
|
||||||
|
#[inline]
|
||||||
|
pub fn toggle(&mut self) {
|
||||||
|
if self.is_set_high() {
|
||||||
|
self.set_low();
|
||||||
} else {
|
} else {
|
||||||
Ok(self.set_high()?)
|
self.set_high();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
|
||||||
impl<MODE, const GPIONUM: u8> embedded_hal::digital::ErrorType for GpioPin<Output<MODE>, GPIONUM>
|
|
||||||
where
|
|
||||||
Self: GpioProperties,
|
|
||||||
<Self as GpioProperties>::PinType: IsOutputPin,
|
|
||||||
{
|
|
||||||
type Error = core::convert::Infallible;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
|
||||||
impl<MODE, const GPIONUM: u8> embedded_hal::digital::OutputPin for GpioPin<Output<MODE>, GPIONUM>
|
|
||||||
where
|
|
||||||
Self: GpioProperties,
|
|
||||||
<Self as GpioProperties>::PinType: IsOutputPin,
|
|
||||||
{
|
|
||||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
|
||||||
<Self as GpioProperties>::Bank::write_output_clear(1 << (GPIONUM % 32));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
|
||||||
<Self as GpioProperties>::Bank::write_output_set(1 << (GPIONUM % 32));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
|
||||||
impl<MODE, const GPIONUM: u8> embedded_hal::digital::StatefulOutputPin
|
|
||||||
for GpioPin<Output<MODE>, GPIONUM>
|
|
||||||
where
|
|
||||||
Self: GpioProperties,
|
|
||||||
<Self as GpioProperties>::PinType: IsOutputPin,
|
|
||||||
{
|
|
||||||
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(<Self as GpioProperties>::Bank::read_output() & (1 << (GPIONUM % 32)) != 0)
|
|
||||||
}
|
|
||||||
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(!self.is_set_high()?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<MODE, const GPIONUM: u8> crate::peripheral::Peripheral for GpioPin<MODE, GPIONUM>
|
impl<MODE, const GPIONUM: u8> crate::peripheral::Peripheral for GpioPin<MODE, GPIONUM>
|
||||||
where
|
where
|
||||||
Self: GpioProperties,
|
Self: GpioProperties,
|
||||||
@ -1772,131 +1693,91 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
impl<MODE, TYPE> AnyPin<Input<MODE>, TYPE> {
|
||||||
impl<MODE, TYPE> embedded_hal_02::digital::v2::InputPin for AnyPin<Input<MODE>, TYPE> {
|
/// Is the input pin high?
|
||||||
type Error = core::convert::Infallible;
|
#[inline]
|
||||||
|
pub fn is_high(&self) -> bool {
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
|
||||||
let inner = &self.inner;
|
let inner = &self.inner;
|
||||||
handle_gpio_input!(inner, target, { target.is_high() })
|
handle_gpio_input!(inner, target, { target.is_high() })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
/// Is the input pin low?
|
||||||
|
#[inline]
|
||||||
|
pub fn is_low(&self) -> bool {
|
||||||
let inner = &self.inner;
|
let inner = &self.inner;
|
||||||
handle_gpio_input!(inner, target, { target.is_low() })
|
handle_gpio_input!(inner, target, { target.is_low() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
impl<MODE, TYPE> AnyPin<Output<MODE>, TYPE> {
|
||||||
impl<MODE, TYPE> embedded_hal::digital::ErrorType for AnyPin<Input<MODE>, TYPE> {
|
/// Drives the pin low.
|
||||||
type Error = core::convert::Infallible;
|
#[inline]
|
||||||
}
|
pub fn set_low(&mut self) {
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
|
||||||
impl<MODE, TYPE> embedded_hal::digital::InputPin for AnyPin<Input<MODE>, TYPE> {
|
|
||||||
fn is_high(&mut self) -> Result<bool, Self::Error> {
|
|
||||||
let inner = &mut self.inner;
|
|
||||||
handle_gpio_input!(inner, target, { target.is_high() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_low(&mut self) -> Result<bool, Self::Error> {
|
|
||||||
let inner = &mut self.inner;
|
|
||||||
handle_gpio_input!(inner, target, { target.is_low() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
|
||||||
impl<MODE, TYPE> embedded_hal_02::digital::v2::OutputPin for AnyPin<Output<MODE>, TYPE> {
|
|
||||||
type Error = core::convert::Infallible;
|
|
||||||
|
|
||||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
|
||||||
let inner = &mut self.inner;
|
let inner = &mut self.inner;
|
||||||
handle_gpio_output!(inner, target, { target.set_low() })
|
handle_gpio_output!(inner, target, { target.set_low() })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
/// Drives the pin high.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_high(&mut self) {
|
||||||
let inner = &mut self.inner;
|
let inner = &mut self.inner;
|
||||||
handle_gpio_output!(inner, target, { target.set_high() })
|
handle_gpio_output!(inner, target, { target.set_high() })
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
// TODO: add `set_state(PinState)`
|
||||||
impl<MODE, TYPE> embedded_hal_02::digital::v2::StatefulOutputPin for AnyPin<Output<MODE>, TYPE> {
|
// Drives the pin high or low depending on the provided value.
|
||||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
|
||||||
|
/// Is the pin in drive high mode?
|
||||||
|
#[inline]
|
||||||
|
pub fn is_set_high(&self) -> bool {
|
||||||
let inner = &self.inner;
|
let inner = &self.inner;
|
||||||
handle_gpio_output!(inner, target, { target.is_set_high() })
|
handle_gpio_output!(inner, target, { target.is_set_high() })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
/// Is the pin in drive low mode?
|
||||||
|
#[inline]
|
||||||
|
pub fn is_set_low(&self) -> bool {
|
||||||
let inner = &self.inner;
|
let inner = &self.inner;
|
||||||
handle_gpio_output!(inner, target, { target.is_set_low() })
|
handle_gpio_output!(inner, target, { target.is_set_low() })
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal-02")]
|
/// Toggle pin output.
|
||||||
impl<MODE, TYPE> embedded_hal_02::digital::v2::ToggleableOutputPin for AnyPin<Output<MODE>, TYPE> {
|
#[inline]
|
||||||
type Error = core::convert::Infallible;
|
pub fn toggle(&mut self) {
|
||||||
|
|
||||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
|
||||||
let inner = &mut self.inner;
|
let inner = &mut self.inner;
|
||||||
handle_gpio_output!(inner, target, { target.toggle() })
|
handle_gpio_output!(inner, target, { target.toggle() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
|
||||||
impl<MODE, TYPE> embedded_hal::digital::ErrorType for AnyPin<Output<MODE>, TYPE> {
|
|
||||||
type Error = core::convert::Infallible;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
|
||||||
impl<MODE, TYPE> embedded_hal::digital::OutputPin for AnyPin<Output<MODE>, TYPE> {
|
|
||||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
|
||||||
let inner = &mut self.inner;
|
|
||||||
handle_gpio_output!(inner, target, { target.set_low() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
|
||||||
let inner = &mut self.inner;
|
|
||||||
handle_gpio_output!(inner, target, { target.set_high() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
|
||||||
impl<MODE, TYPE> embedded_hal::digital::StatefulOutputPin for AnyPin<Output<MODE>, TYPE> {
|
|
||||||
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
|
|
||||||
let inner = &mut self.inner;
|
|
||||||
handle_gpio_output!(inner, target, { target.is_set_high() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
|
|
||||||
let inner = &mut self.inner;
|
|
||||||
handle_gpio_output!(inner, target, { target.is_set_low() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
impl<MODE, TYPE> embedded_hal_async::digital::Wait for AnyPin<Input<MODE>, TYPE> {
|
impl<MODE, TYPE> AnyPin<Input<MODE>, TYPE> {
|
||||||
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
/// Wait until the pin is high. If it is already high, return immediately.
|
||||||
|
pub async fn wait_for_high(&mut self) {
|
||||||
let inner = &mut self.inner;
|
let inner = &mut self.inner;
|
||||||
handle_gpio_input!(inner, target, { target.wait_for_high().await })
|
handle_gpio_input!(inner, target, { target.wait_for_high().await })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
/// Wait until the pin is low. If it is already low, return immediately.
|
||||||
|
pub async fn wait_for_low(&mut self) {
|
||||||
let inner = &mut self.inner;
|
let inner = &mut self.inner;
|
||||||
handle_gpio_input!(inner, target, { target.wait_for_low().await })
|
handle_gpio_input!(inner, target, { target.wait_for_low().await })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
/// Wait for the pin to undergo a transition from low to high.
|
||||||
|
pub async fn wait_for_rising_edge(&mut self) {
|
||||||
let inner = &mut self.inner;
|
let inner = &mut self.inner;
|
||||||
handle_gpio_input!(inner, target, { target.wait_for_rising_edge().await })
|
handle_gpio_input!(inner, target, { target.wait_for_rising_edge().await })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
/// Wait for the pin to undergo a transition from high to low.
|
||||||
|
pub async fn wait_for_falling_edge(&mut self) {
|
||||||
let inner = &mut self.inner;
|
let inner = &mut self.inner;
|
||||||
handle_gpio_input!(inner, target, { target.wait_for_falling_edge().await })
|
handle_gpio_input!(inner, target, { target.wait_for_falling_edge().await })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
/// Wait for the pin to undergo any transition, i.e low to high OR high to
|
||||||
|
/// low.
|
||||||
|
pub async fn wait_for_any_edge(&mut self) {
|
||||||
let inner = &mut self.inner;
|
let inner = &mut self.inner;
|
||||||
handle_gpio_input!(inner, target, { target.wait_for_any_edge().await })
|
handle_gpio_input!(inner, target, { target.wait_for_any_edge().await })
|
||||||
}
|
}
|
||||||
@ -3138,7 +3019,6 @@ mod asynch {
|
|||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
use embedded_hal_async::digital::Wait;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -3146,54 +3026,68 @@ mod asynch {
|
|||||||
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
||||||
static PIN_WAKERS: [AtomicWaker; NUM_PINS] = [NEW_AW; NUM_PINS];
|
static PIN_WAKERS: [AtomicWaker; NUM_PINS] = [NEW_AW; NUM_PINS];
|
||||||
|
|
||||||
impl<MODE, const GPIONUM: u8> Wait for GpioPin<Input<MODE>, GPIONUM>
|
impl<MODE, const GPIONUM: u8> GpioPin<Input<MODE>, GPIONUM>
|
||||||
where
|
where
|
||||||
Self: GpioProperties,
|
Self: GpioProperties,
|
||||||
<Self as GpioProperties>::PinType: IsInputPin,
|
<Self as GpioProperties>::PinType: IsInputPin,
|
||||||
{
|
{
|
||||||
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
/// Wait until the pin is high. If it is already high, return
|
||||||
|
/// immediately.
|
||||||
|
pub async fn wait_for_high(&mut self) {
|
||||||
PinFuture::new(self, Event::HighLevel).await
|
PinFuture::new(self, Event::HighLevel).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
/// Wait until the pin is low. If it is already low, return immediately.
|
||||||
|
pub async fn wait_for_low(&mut self) {
|
||||||
PinFuture::new(self, Event::LowLevel).await
|
PinFuture::new(self, Event::LowLevel).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
/// Wait for the pin to undergo a transition from low to high.
|
||||||
|
pub async fn wait_for_rising_edge(&mut self) {
|
||||||
PinFuture::new(self, Event::RisingEdge).await
|
PinFuture::new(self, Event::RisingEdge).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
/// Wait for the pin to undergo a transition from high to low.
|
||||||
|
pub async fn wait_for_falling_edge(&mut self) {
|
||||||
PinFuture::new(self, Event::FallingEdge).await
|
PinFuture::new(self, Event::FallingEdge).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
/// Wait for the pin to undergo any transition, i.e low to high OR high
|
||||||
|
/// to low.
|
||||||
|
pub async fn wait_for_any_edge(&mut self) {
|
||||||
PinFuture::new(self, Event::AnyEdge).await
|
PinFuture::new(self, Event::AnyEdge).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const GPIONUM: u8> Wait for GpioPin<Output<OpenDrain>, GPIONUM>
|
impl<const GPIONUM: u8> GpioPin<Output<OpenDrain>, GPIONUM>
|
||||||
where
|
where
|
||||||
Self: GpioProperties,
|
Self: GpioProperties,
|
||||||
<Self as GpioProperties>::PinType: IsInputPin + IsOutputPin,
|
<Self as GpioProperties>::PinType: IsInputPin + IsOutputPin,
|
||||||
{
|
{
|
||||||
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
/// Wait until the pin is high. If it is already high, return
|
||||||
|
/// immediately.
|
||||||
|
pub async fn wait_for_high(&mut self) {
|
||||||
PinFuture::new(self, Event::HighLevel).await
|
PinFuture::new(self, Event::HighLevel).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
/// Wait until the pin is low. If it is already low, return immediately.
|
||||||
|
pub async fn wait_for_low(&mut self) {
|
||||||
PinFuture::new(self, Event::LowLevel).await
|
PinFuture::new(self, Event::LowLevel).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
/// Wait for the pin to undergo a transition from low to high.
|
||||||
|
pub async fn wait_for_rising_edge(&mut self) {
|
||||||
PinFuture::new(self, Event::RisingEdge).await
|
PinFuture::new(self, Event::RisingEdge).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
/// Wait for the pin to undergo a transition from high to low.
|
||||||
|
pub async fn wait_for_falling_edge(&mut self) {
|
||||||
PinFuture::new(self, Event::FallingEdge).await
|
PinFuture::new(self, Event::FallingEdge).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
/// Wait for the pin to undergo any transition, i.e low to high OR high
|
||||||
|
/// to low.
|
||||||
|
pub async fn wait_for_any_edge(&mut self) {
|
||||||
PinFuture::new(self, Event::AnyEdge).await
|
PinFuture::new(self, Event::AnyEdge).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3204,7 +3098,7 @@ mod asynch {
|
|||||||
|
|
||||||
impl<'a, P> PinFuture<'a, P>
|
impl<'a, P> PinFuture<'a, P>
|
||||||
where
|
where
|
||||||
P: crate::gpio::Pin + embedded_hal::digital::ErrorType,
|
P: crate::gpio::Pin,
|
||||||
{
|
{
|
||||||
pub fn new(pin: &'a mut P, event: Event) -> Self {
|
pub fn new(pin: &'a mut P, event: Event) -> Self {
|
||||||
pin.listen(event);
|
pin.listen(event);
|
||||||
@ -3214,9 +3108,9 @@ mod asynch {
|
|||||||
|
|
||||||
impl<'a, P> core::future::Future for PinFuture<'a, P>
|
impl<'a, P> core::future::Future for PinFuture<'a, P>
|
||||||
where
|
where
|
||||||
P: crate::gpio::Pin + embedded_hal::digital::ErrorType,
|
P: crate::gpio::Pin,
|
||||||
{
|
{
|
||||||
type Output = Result<(), P::Error>;
|
type Output = ();
|
||||||
|
|
||||||
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
PIN_WAKERS[self.pin.number() as usize].register(cx.waker());
|
PIN_WAKERS[self.pin.number() as usize].register(cx.waker());
|
||||||
@ -3224,7 +3118,7 @@ mod asynch {
|
|||||||
// if pin is no longer listening its been triggered
|
// if pin is no longer listening its been triggered
|
||||||
// therefore the future has resolved
|
// therefore the future has resolved
|
||||||
if !self.pin.is_listening() {
|
if !self.pin.is_listening() {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(())
|
||||||
} else {
|
} else {
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
@ -3278,3 +3172,334 @@ mod asynch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "embedded-hal-02")]
|
||||||
|
mod embedded_hal_02_impls {
|
||||||
|
use embedded_hal_02::digital::v2 as digital;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl<MODE, const GPIONUM: u8> digital::InputPin for GpioPin<Input<MODE>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
{
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_high())
|
||||||
|
}
|
||||||
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_low())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const GPIONUM: u8> digital::InputPin for GpioPin<Output<OpenDrain>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
{
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(<Self as GpioProperties>::Bank::read_input() & (1 << (GPIONUM % 32)) != 0)
|
||||||
|
}
|
||||||
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_low())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, const GPIONUM: u8> digital::OutputPin for GpioPin<Output<MODE>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
<Self as GpioProperties>::PinType: IsOutputPin,
|
||||||
|
{
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.set_high();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.set_low();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, const GPIONUM: u8> digital::StatefulOutputPin for GpioPin<Output<MODE>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
<Self as GpioProperties>::PinType: IsOutputPin,
|
||||||
|
{
|
||||||
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_set_high())
|
||||||
|
}
|
||||||
|
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_set_low())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, const GPIONUM: u8> digital::ToggleableOutputPin for GpioPin<Output<MODE>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
<Self as GpioProperties>::PinType: IsOutputPin,
|
||||||
|
{
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.toggle();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, TYPE> digital::InputPin for AnyPin<Input<MODE>, TYPE> {
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
|
||||||
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_high())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_low())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, TYPE> digital::OutputPin for AnyPin<Output<MODE>, TYPE> {
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
|
||||||
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.set_low();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.set_high();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, TYPE> digital::StatefulOutputPin for AnyPin<Output<MODE>, TYPE> {
|
||||||
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_set_high())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_set_low())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, TYPE> digital::ToggleableOutputPin for AnyPin<Output<MODE>, TYPE> {
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
|
||||||
|
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.toggle();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "embedded-hal")]
|
||||||
|
mod embedded_hal_impls {
|
||||||
|
use embedded_hal::digital;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl<MODE, const GPIONUM: u8> digital::ErrorType for GpioPin<Input<MODE>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
{
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, const GPIONUM: u8> digital::InputPin for GpioPin<Input<MODE>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
{
|
||||||
|
fn is_high(&mut self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(Self::is_high(self))
|
||||||
|
}
|
||||||
|
fn is_low(&mut self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(Self::is_low(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const GPIONUM: u8> digital::InputPin for GpioPin<Output<OpenDrain>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
<Self as GpioProperties>::PinType: IsOutputPin,
|
||||||
|
{
|
||||||
|
fn is_high(&mut self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(Self::is_high(self))
|
||||||
|
}
|
||||||
|
fn is_low(&mut self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(Self::is_low(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, const GPIONUM: u8> digital::ErrorType for GpioPin<Output<MODE>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
<Self as GpioProperties>::PinType: IsOutputPin,
|
||||||
|
{
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, const GPIONUM: u8> digital::OutputPin for GpioPin<Output<MODE>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
<Self as GpioProperties>::PinType: IsOutputPin,
|
||||||
|
{
|
||||||
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.set_low();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.set_high();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, const GPIONUM: u8> digital::StatefulOutputPin for GpioPin<Output<MODE>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
<Self as GpioProperties>::PinType: IsOutputPin,
|
||||||
|
{
|
||||||
|
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(Self::is_set_high(self))
|
||||||
|
}
|
||||||
|
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(Self::is_set_low(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, TYPE> digital::ErrorType for AnyPin<Input<MODE>, TYPE> {
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, TYPE> digital::InputPin for AnyPin<Input<MODE>, TYPE> {
|
||||||
|
fn is_high(&mut self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(Self::is_high(self))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_low(&mut self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(Self::is_low(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, TYPE> digital::ErrorType for AnyPin<Output<MODE>, TYPE> {
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, TYPE> digital::OutputPin for AnyPin<Output<MODE>, TYPE> {
|
||||||
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.set_low();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.set_high();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, TYPE> digital::StatefulOutputPin for AnyPin<Output<MODE>, TYPE> {
|
||||||
|
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(Self::is_set_high(self))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(Self::is_set_low(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "embedded-hal")]
|
||||||
|
#[cfg(feature = "async")]
|
||||||
|
mod embedded_hal_async_impls {
|
||||||
|
use embedded_hal_async::digital::Wait;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl<MODE, const GPIONUM: u8> Wait for GpioPin<Input<MODE>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
<Self as GpioProperties>::PinType: IsInputPin,
|
||||||
|
{
|
||||||
|
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_high().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_low().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_rising_edge().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_falling_edge().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_any_edge().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const GPIONUM: u8> Wait for GpioPin<Output<OpenDrain>, GPIONUM>
|
||||||
|
where
|
||||||
|
Self: GpioProperties,
|
||||||
|
<Self as GpioProperties>::PinType: IsInputPin + IsOutputPin,
|
||||||
|
{
|
||||||
|
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_high().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_low().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_rising_edge().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_falling_edge().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_any_edge().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<MODE, TYPE> embedded_hal_async::digital::Wait for AnyPin<Input<MODE>, TYPE> {
|
||||||
|
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_high().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_low().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_rising_edge().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_falling_edge().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_any_edge().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,12 +3,10 @@
|
|||||||
//! This assumes that a LED is connected to the pin assigned to `led`. (GPIO0)
|
//! This assumes that a LED is connected to the pin assigned to `led`. (GPIO0)
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
//% FEATURES: embedded-hal-02
|
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use embedded_hal_02::digital::v2::{OutputPin, ToggleableOutputPin};
|
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{clock::ClockControl, delay::Delay, gpio::IO, peripherals::Peripherals, prelude::*};
|
use esp_hal::{clock::ClockControl, delay::Delay, gpio::IO, peripherals::Peripherals, prelude::*};
|
||||||
|
|
||||||
@ -20,18 +18,18 @@ fn main() -> ! {
|
|||||||
|
|
||||||
// Set GPIO0 as an output, and set its state high initially.
|
// Set GPIO0 as an output, and set its state high initially.
|
||||||
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let mut led = io.pins.gpio0.into_push_pull_output();
|
let mut led = io.pins.gpio8.into_push_pull_output();
|
||||||
|
|
||||||
led.set_high().unwrap();
|
led.set_high();
|
||||||
|
|
||||||
// Initialize the Delay peripheral, and use it to toggle the LED state in a
|
// Initialize the Delay peripheral, and use it to toggle the LED state in a
|
||||||
// loop.
|
// loop.
|
||||||
let delay = Delay::new(&clocks);
|
let delay = Delay::new(&clocks);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
led.toggle().unwrap();
|
led.toggle();
|
||||||
delay.delay_millis(500);
|
delay.delay_millis(500);
|
||||||
led.toggle().unwrap();
|
led.toggle();
|
||||||
// or using `fugit` duration
|
// or using `fugit` duration
|
||||||
delay.delay(2.secs());
|
delay.delay(2.secs());
|
||||||
}
|
}
|
||||||
|
@ -52,10 +52,10 @@ fn main() -> ! {
|
|||||||
|
|
||||||
fn toggle_pins(leds: &mut [AnyPin<Output<PushPull>>], button: &AnyPin<Input<PullDown>>) {
|
fn toggle_pins(leds: &mut [AnyPin<Output<PushPull>>], button: &AnyPin<Input<PullDown>>) {
|
||||||
for pin in leds.iter_mut() {
|
for pin in leds.iter_mut() {
|
||||||
pin.toggle().unwrap();
|
pin.toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
if button.is_low().unwrap() {
|
if button.is_low() {
|
||||||
esp_println::println!("Button pressed");
|
esp_println::println!("Button pressed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,10 +43,10 @@ async fn control_led(
|
|||||||
loop {
|
loop {
|
||||||
if control.wait().await {
|
if control.wait().await {
|
||||||
esp_println::println!("LED on");
|
esp_println::println!("LED on");
|
||||||
led.set_low().unwrap();
|
led.set_low();
|
||||||
} else {
|
} else {
|
||||||
esp_println::println!("LED off");
|
esp_println::println!("LED off");
|
||||||
led.set_high().unwrap();
|
led.set_high();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,10 +59,10 @@ async fn control_led(
|
|||||||
loop {
|
loop {
|
||||||
if control.wait().await {
|
if control.wait().await {
|
||||||
esp_println::println!("LED on");
|
esp_println::println!("LED on");
|
||||||
led.set_low().unwrap();
|
led.set_low();
|
||||||
} else {
|
} else {
|
||||||
esp_println::println!("LED off");
|
esp_println::println!("LED off");
|
||||||
led.set_high().unwrap();
|
led.set_high();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ compile_error!("Run this example in release mode");
|
|||||||
async fn signal_task(mut pin: Gpio5<Output<PushPull>>) {
|
async fn signal_task(mut pin: Gpio5<Output<PushPull>>) {
|
||||||
loop {
|
loop {
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
pin.toggle().unwrap();
|
pin.toggle();
|
||||||
Timer::after(Duration::from_micros(10)).await;
|
Timer::after(Duration::from_micros(10)).await;
|
||||||
}
|
}
|
||||||
Timer::after(Duration::from_millis(1000)).await;
|
Timer::after(Duration::from_millis(1000)).await;
|
||||||
|
@ -40,7 +40,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
esp_println::println!("Waiting...");
|
esp_println::println!("Waiting...");
|
||||||
input.wait_for_rising_edge().await.unwrap();
|
input.wait_for_rising_edge().await;
|
||||||
esp_println::println!("Ping!");
|
esp_println::println!("Ping!");
|
||||||
Timer::after(Duration::from_millis(100)).await;
|
Timer::after(Duration::from_millis(100)).await;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ fn main() -> ! {
|
|||||||
let mut led = io.pins.gpio1.into_push_pull_output();
|
let mut led = io.pins.gpio1.into_push_pull_output();
|
||||||
let button = io.pins.gpio9.into_pull_down_input();
|
let button = io.pins.gpio9.into_pull_down_input();
|
||||||
|
|
||||||
led.set_high().unwrap();
|
led.set_high();
|
||||||
|
|
||||||
// setup ETM
|
// setup ETM
|
||||||
let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
|
let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
//! It also blinks an LED like the blinky example.
|
//! It also blinks an LED like the blinky example.
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
//% FEATURES: embedded-hal-02
|
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
@ -12,7 +11,6 @@
|
|||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use critical_section::Mutex;
|
use critical_section::Mutex;
|
||||||
use embedded_hal_02::digital::v2::{OutputPin, ToggleableOutputPin};
|
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
@ -50,14 +48,14 @@ fn main() -> ! {
|
|||||||
button.listen(Event::FallingEdge);
|
button.listen(Event::FallingEdge);
|
||||||
BUTTON.borrow_ref_mut(cs).replace(button)
|
BUTTON.borrow_ref_mut(cs).replace(button)
|
||||||
});
|
});
|
||||||
led.set_high().unwrap();
|
led.set_high();
|
||||||
|
|
||||||
// Initialize the Delay peripheral, and use it to toggle the LED state in a
|
// Initialize the Delay peripheral, and use it to toggle the LED state in a
|
||||||
// loop.
|
// loop.
|
||||||
let delay = Delay::new(&clocks);
|
let delay = Delay::new(&clocks);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
led.toggle().unwrap();
|
led.toggle();
|
||||||
delay.delay_millis(500);
|
delay.delay_millis(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,10 @@
|
|||||||
//! D7 GPIO15
|
//! D7 GPIO15
|
||||||
|
|
||||||
//% CHIPS: esp32s3
|
//% CHIPS: esp32s3
|
||||||
//% FEATURES: embedded-hal-02
|
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use embedded_hal_02::digital::v2::OutputPin;
|
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
@ -97,9 +95,9 @@ fn main() -> ! {
|
|||||||
// https://gist.github.com/sukesh-ak/610508bc84779a26efdcf969bf51a2d1
|
// https://gist.github.com/sukesh-ak/610508bc84779a26efdcf969bf51a2d1
|
||||||
// https://github.com/lovyan03/LovyanGFX/blob/302169a6f23e9a2a6451f03311c366d182193831/src/lgfx/v1/panel/Panel_ST7796.hpp#L28
|
// https://github.com/lovyan03/LovyanGFX/blob/302169a6f23e9a2a6451f03311c366d182193831/src/lgfx/v1/panel/Panel_ST7796.hpp#L28
|
||||||
|
|
||||||
reset.set_low().unwrap();
|
reset.set_low();
|
||||||
delay.delay_micros(8_000);
|
delay.delay_micros(8_000);
|
||||||
reset.set_high().unwrap();
|
reset.set_high();
|
||||||
delay.delay_micros(64_000);
|
delay.delay_micros(64_000);
|
||||||
|
|
||||||
// const CMD_FRMCTR1: u8 = 0xB1;
|
// const CMD_FRMCTR1: u8 = 0xB1;
|
||||||
@ -210,7 +208,7 @@ fn main() -> ! {
|
|||||||
const RED: u16 = 0b00000_000000_11111;
|
const RED: u16 = 0b00000_000000_11111;
|
||||||
const BLUE: u16 = 0b11111_000000_00000;
|
const BLUE: u16 = 0b11111_000000_00000;
|
||||||
|
|
||||||
backlight.set_high().unwrap();
|
backlight.set_high();
|
||||||
|
|
||||||
let total_pixels = width as usize * height as usize;
|
let total_pixels = width as usize * height as usize;
|
||||||
let total_bytes = total_pixels * 2;
|
let total_bytes = total_pixels * 2;
|
||||||
|
@ -2,12 +2,10 @@
|
|||||||
//! Connect GPIO5 to GPIO4
|
//! Connect GPIO5 to GPIO4
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
//% CHIPS: esp32 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
//% FEATURES: embedded-hal-02
|
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use embedded_hal_02::digital::v2::OutputPin;
|
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
@ -75,9 +73,9 @@ fn main() -> ! {
|
|||||||
|
|
||||||
// simulate input
|
// simulate input
|
||||||
for i in 0u32..5u32 {
|
for i in 0u32..5u32 {
|
||||||
out.set_high().unwrap();
|
out.set_high();
|
||||||
delay.delay_micros(i * 10 + 20);
|
delay.delay_micros(i * 10 + 20);
|
||||||
out.set_low().unwrap();
|
out.set_low();
|
||||||
delay.delay_micros(i * 20 + 20);
|
delay.delay_micros(i * 20 + 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,9 +61,9 @@ fn main() -> ! {
|
|||||||
let mut master_mosi = io.pins.gpio8.into_push_pull_output();
|
let mut master_mosi = io.pins.gpio8.into_push_pull_output();
|
||||||
let slave_cs = io.pins.gpio3;
|
let slave_cs = io.pins.gpio3;
|
||||||
let mut master_cs = io.pins.gpio9.into_push_pull_output();
|
let mut master_cs = io.pins.gpio9.into_push_pull_output();
|
||||||
master_cs.set_high().unwrap();
|
master_cs.set_high();
|
||||||
master_sclk.set_low().unwrap();
|
master_sclk.set_low();
|
||||||
master_mosi.set_low().unwrap();
|
master_mosi.set_low();
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
let dma_channel = dma.channel0;
|
let dma_channel = dma.channel0;
|
||||||
@ -115,31 +115,31 @@ fn main() -> ! {
|
|||||||
// Bit-bang out the contents of master_send and read into master_receive
|
// 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
|
// as quickly as manageable. MSB first. Mode 0, so sampled on the rising
|
||||||
// edge and set on the falling edge.
|
// edge and set on the falling edge.
|
||||||
master_cs.set_low().unwrap();
|
master_cs.set_low();
|
||||||
for (j, v) in master_send.iter().enumerate() {
|
for (j, v) in master_send.iter().enumerate() {
|
||||||
let mut b = *v;
|
let mut b = *v;
|
||||||
let mut rb = 0u8;
|
let mut rb = 0u8;
|
||||||
for _ in 0..8 {
|
for _ in 0..8 {
|
||||||
if b & 128 != 0 {
|
if b & 128 != 0 {
|
||||||
master_mosi.set_high().unwrap();
|
master_mosi.set_high();
|
||||||
} else {
|
} else {
|
||||||
master_mosi.set_low().unwrap();
|
master_mosi.set_low();
|
||||||
}
|
}
|
||||||
master_sclk.set_low().unwrap();
|
master_sclk.set_low();
|
||||||
b <<= 1;
|
b <<= 1;
|
||||||
rb <<= 1;
|
rb <<= 1;
|
||||||
// NB: adding about 24 NOPs here makes the clock's duty cycle
|
// NB: adding about 24 NOPs here makes the clock's duty cycle
|
||||||
// run at about 50% ... but we don't strictly need the delay,
|
// run at about 50% ... but we don't strictly need the delay,
|
||||||
// either.
|
// either.
|
||||||
master_sclk.set_high().unwrap();
|
master_sclk.set_high();
|
||||||
if master_miso.is_high().unwrap() {
|
if master_miso.is_high() {
|
||||||
rb |= 1;
|
rb |= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
master_receive[j] = rb;
|
master_receive[j] = rb;
|
||||||
}
|
}
|
||||||
master_cs.set_high().unwrap();
|
master_cs.set_high();
|
||||||
master_sclk.set_low().unwrap();
|
master_sclk.set_low();
|
||||||
// the buffers and spi is moved into the transfer and we can get it back via
|
// the buffers and spi is moved into the transfer and we can get it back via
|
||||||
// `wait`
|
// `wait`
|
||||||
transfer.wait().unwrap();
|
transfer.wait().unwrap();
|
||||||
@ -155,23 +155,23 @@ fn main() -> ! {
|
|||||||
|
|
||||||
slave_receive.fill(0xff);
|
slave_receive.fill(0xff);
|
||||||
let transfer = spi.dma_read(&mut slave_receive).unwrap();
|
let transfer = spi.dma_read(&mut slave_receive).unwrap();
|
||||||
master_cs.set_high().unwrap();
|
master_cs.set_high();
|
||||||
|
|
||||||
master_cs.set_low().unwrap();
|
master_cs.set_low();
|
||||||
for v in master_send.iter() {
|
for v in master_send.iter() {
|
||||||
let mut b = *v;
|
let mut b = *v;
|
||||||
for _ in 0..8 {
|
for _ in 0..8 {
|
||||||
if b & 128 != 0 {
|
if b & 128 != 0 {
|
||||||
master_mosi.set_high().unwrap();
|
master_mosi.set_high();
|
||||||
} else {
|
} else {
|
||||||
master_mosi.set_low().unwrap();
|
master_mosi.set_low();
|
||||||
}
|
}
|
||||||
b <<= 1;
|
b <<= 1;
|
||||||
master_sclk.set_low().unwrap();
|
master_sclk.set_low();
|
||||||
master_sclk.set_high().unwrap();
|
master_sclk.set_high();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
master_cs.set_high().unwrap();
|
master_cs.set_high();
|
||||||
transfer.wait().unwrap();
|
transfer.wait().unwrap();
|
||||||
println!(
|
println!(
|
||||||
"slave got {:x?} .. {:x?}",
|
"slave got {:x?} .. {:x?}",
|
||||||
@ -184,20 +184,20 @@ fn main() -> ! {
|
|||||||
|
|
||||||
master_receive.fill(0);
|
master_receive.fill(0);
|
||||||
|
|
||||||
master_cs.set_low().unwrap();
|
master_cs.set_low();
|
||||||
for (j, _) in master_send.iter().enumerate() {
|
for (j, _) in master_send.iter().enumerate() {
|
||||||
let mut rb = 0u8;
|
let mut rb = 0u8;
|
||||||
for _ in 0..8 {
|
for _ in 0..8 {
|
||||||
master_sclk.set_low().unwrap();
|
master_sclk.set_low();
|
||||||
rb <<= 1;
|
rb <<= 1;
|
||||||
master_sclk.set_high().unwrap();
|
master_sclk.set_high();
|
||||||
if master_miso.is_high().unwrap() {
|
if master_miso.is_high() {
|
||||||
rb |= 1;
|
rb |= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
master_receive[j] = rb;
|
master_receive[j] = rb;
|
||||||
}
|
}
|
||||||
master_cs.set_high().unwrap();
|
master_cs.set_high();
|
||||||
transfer.wait().unwrap();
|
transfer.wait().unwrap();
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
|
@ -11,7 +11,6 @@ use core::cell::RefCell;
|
|||||||
|
|
||||||
use critical_section::Mutex;
|
use critical_section::Mutex;
|
||||||
use defmt_rtt as _;
|
use defmt_rtt as _;
|
||||||
use embedded_hal::digital::{InputPin as _, OutputPin as _, StatefulOutputPin as _};
|
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
@ -74,7 +73,6 @@ pub fn interrupt_handler() {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use defmt::assert_eq;
|
use defmt::assert_eq;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use embedded_hal_async::digital::Wait;
|
|
||||||
use esp_hal::gpio::{Event, Pin};
|
use esp_hal::gpio::{Event, Pin};
|
||||||
use portable_atomic::{AtomicUsize, Ordering};
|
use portable_atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
@ -84,7 +82,7 @@ mod tests {
|
|||||||
fn init() -> Context {
|
fn init() -> Context {
|
||||||
let mut ctx = Context::init();
|
let mut ctx = Context::init();
|
||||||
// make sure tests don't interfere with each other
|
// make sure tests don't interfere with each other
|
||||||
ctx.io4.set_low().ok();
|
ctx.io4.set_low();
|
||||||
ctx
|
ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,15 +95,15 @@ mod tests {
|
|||||||
embassy_futures::select::select(
|
embassy_futures::select::select(
|
||||||
async {
|
async {
|
||||||
loop {
|
loop {
|
||||||
io2.wait_for_rising_edge().await.unwrap();
|
io2.wait_for_rising_edge().await;
|
||||||
counter.fetch_add(1, Ordering::SeqCst);
|
counter.fetch_add(1, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async {
|
async {
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
io4.set_high().unwrap();
|
io4.set_high();
|
||||||
Timer::after(Duration::from_millis(25)).await;
|
Timer::after(Duration::from_millis(25)).await;
|
||||||
io4.set_low().unwrap();
|
io4.set_low();
|
||||||
Timer::after(Duration::from_millis(25)).await;
|
Timer::after(Duration::from_millis(25)).await;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -128,30 +126,30 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gpio_input(mut ctx: Context) {
|
fn test_gpio_input(ctx: Context) {
|
||||||
// `InputPin`:
|
// `InputPin`:
|
||||||
assert_eq!(ctx.io2.is_low(), Ok(true));
|
assert_eq!(ctx.io2.is_low(), true);
|
||||||
assert_eq!(ctx.io2.is_high(), Ok(false));
|
assert_eq!(ctx.io2.is_high(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gpio_output(mut ctx: Context) {
|
fn test_gpio_output(mut ctx: Context) {
|
||||||
// `StatefulOutputPin`:
|
// `StatefulOutputPin`:
|
||||||
assert_eq!(ctx.io4.is_set_low(), Ok(true));
|
assert_eq!(ctx.io4.is_set_low(), true);
|
||||||
assert_eq!(ctx.io4.is_set_high(), Ok(false));
|
assert_eq!(ctx.io4.is_set_high(), false);
|
||||||
assert!(ctx.io4.set_high().is_ok());
|
ctx.io4.set_high();
|
||||||
assert_eq!(ctx.io4.is_set_low(), Ok(false));
|
assert_eq!(ctx.io4.is_set_low(), false);
|
||||||
assert_eq!(ctx.io4.is_set_high(), Ok(true));
|
assert_eq!(ctx.io4.is_set_high(), true);
|
||||||
|
|
||||||
// `ToggleableOutputPin`:
|
// `ToggleableOutputPin`:
|
||||||
assert!(ctx.io4.toggle().is_ok());
|
ctx.io4.toggle();
|
||||||
assert_eq!(ctx.io4.is_set_low(), Ok(true));
|
assert_eq!(ctx.io4.is_set_low(), true);
|
||||||
assert_eq!(ctx.io4.is_set_high(), Ok(false));
|
assert_eq!(ctx.io4.is_set_high(), false);
|
||||||
assert!(ctx.io4.toggle().is_ok());
|
ctx.io4.toggle();
|
||||||
assert_eq!(ctx.io4.is_set_low(), Ok(false));
|
assert_eq!(ctx.io4.is_set_low(), false);
|
||||||
assert_eq!(ctx.io4.is_set_high(), Ok(true));
|
assert_eq!(ctx.io4.is_set_high(), true);
|
||||||
// Leave in initial state for next test
|
// Leave in initial state for next test
|
||||||
assert!(ctx.io4.toggle().is_ok());
|
ctx.io4.toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -161,23 +159,23 @@ mod tests {
|
|||||||
ctx.io2.listen(Event::AnyEdge);
|
ctx.io2.listen(Event::AnyEdge);
|
||||||
INPUT_PIN.borrow_ref_mut(cs).replace(ctx.io2);
|
INPUT_PIN.borrow_ref_mut(cs).replace(ctx.io2);
|
||||||
});
|
});
|
||||||
assert!(ctx.io4.set_high().is_ok());
|
ctx.io4.set_high();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
assert!(ctx.io4.set_low().is_ok());
|
ctx.io4.set_low();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
assert!(ctx.io4.set_high().is_ok());
|
ctx.io4.set_high();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
assert!(ctx.io4.set_low().is_ok());
|
ctx.io4.set_low();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
assert!(ctx.io4.set_high().is_ok());
|
ctx.io4.set_high();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
assert!(ctx.io4.set_low().is_ok());
|
ctx.io4.set_low();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
assert!(ctx.io4.set_high().is_ok());
|
ctx.io4.set_high();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
assert!(ctx.io4.set_low().is_ok());
|
ctx.io4.set_low();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
assert!(ctx.io4.set_high().is_ok());
|
ctx.io4.set_high();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
|
|
||||||
let count = critical_section::with(|cs| *COUNTER.borrow_ref(cs));
|
let count = critical_section::with(|cs| *COUNTER.borrow_ref(cs));
|
||||||
@ -194,32 +192,32 @@ mod tests {
|
|||||||
let mut io4 = ctx.io4.into_open_drain_output();
|
let mut io4 = ctx.io4.into_open_drain_output();
|
||||||
io4.internal_pull_up(true);
|
io4.internal_pull_up(true);
|
||||||
|
|
||||||
assert!(io2.set_high().is_ok());
|
io2.set_high();
|
||||||
assert!(io4.set_high().is_ok());
|
io4.set_high();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
|
|
||||||
assert_eq!(io2.is_high(), Ok(true));
|
assert_eq!(io2.is_high(), true);
|
||||||
assert_eq!(io4.is_high(), Ok(true));
|
assert_eq!(io4.is_high(), true);
|
||||||
|
|
||||||
assert!(io2.set_low().is_ok());
|
io2.set_low();
|
||||||
assert!(io4.set_high().is_ok());
|
io4.set_high();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
|
|
||||||
assert_eq!(io2.is_low(), Ok(true));
|
assert_eq!(io2.is_low(), true);
|
||||||
assert_eq!(io4.is_low(), Ok(true));
|
assert_eq!(io4.is_low(), true);
|
||||||
|
|
||||||
assert!(io2.set_high().is_ok());
|
io2.set_high();
|
||||||
assert!(io4.set_high().is_ok());
|
io4.set_high();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
|
|
||||||
assert_eq!(io2.is_high(), Ok(true));
|
assert_eq!(io2.is_high(), true);
|
||||||
assert_eq!(io4.is_high(), Ok(true));
|
assert_eq!(io4.is_high(), true);
|
||||||
|
|
||||||
assert!(io2.set_high().is_ok());
|
io2.set_high();
|
||||||
assert!(io4.set_low().is_ok());
|
io4.set_low();
|
||||||
ctx.delay.delay_millis(1);
|
ctx.delay.delay_millis(1);
|
||||||
|
|
||||||
assert_eq!(io2.is_low(), Ok(true));
|
assert_eq!(io2.is_low(), true);
|
||||||
assert_eq!(io4.is_low(), Ok(true));
|
assert_eq!(io4.is_low(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user