mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 12:50:53 +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)
|
||||
- Add TWAI support for ESP32-C6 (#1323)
|
||||
- `GpioPin::steal` unsafe API (#1363)
|
||||
- Inherent implementions of GPIO pin `set_low`, `is_low`, etc.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -542,68 +542,37 @@ pub struct GpioPin<MODE, const GPIONUM: u8> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "embedded-hal-02")]
|
||||
impl<MODE, const GPIONUM: u8> embedded_hal_02::digital::v2::InputPin
|
||||
for GpioPin<Input<MODE>, GPIONUM>
|
||||
impl<MODE, const GPIONUM: u8> GpioPin<Input<MODE>, 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)
|
||||
/// Is the input pin high?
|
||||
#[inline]
|
||||
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> embedded_hal_02::digital::v2::InputPin
|
||||
for GpioPin<Output<OpenDrain>, GPIONUM>
|
||||
impl<const GPIONUM: u8> 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)
|
||||
/// Is the input pin high?
|
||||
#[inline]
|
||||
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")]
|
||||
impl<MODE, const GPIONUM: u8> embedded_hal::digital::ErrorType for GpioPin<Input<MODE>, GPIONUM>
|
||||
where
|
||||
Self: GpioProperties,
|
||||
{
|
||||
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()?)
|
||||
/// Is the input pin low?
|
||||
#[inline]
|
||||
pub fn is_low(&self) -> bool {
|
||||
!self.is_high()
|
||||
}
|
||||
}
|
||||
|
||||
@ -906,97 +875,49 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "embedded-hal-02")]
|
||||
impl<MODE, const GPIONUM: u8> embedded_hal_02::digital::v2::OutputPin
|
||||
for GpioPin<Output<MODE>, GPIONUM>
|
||||
impl<MODE, const GPIONUM: u8> 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> {
|
||||
/// Drives the pin high.
|
||||
#[inline]
|
||||
pub fn set_high(&mut self) {
|
||||
<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));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "embedded-hal-02")]
|
||||
impl<MODE, const GPIONUM: u8> embedded_hal_02::digital::v2::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 as GpioProperties>::Bank::read_output() & (1 << (GPIONUM % 32)) != 0)
|
||||
}
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(!self.is_set_high()?)
|
||||
}
|
||||
}
|
||||
// TODO: add `set_state(PinState)`
|
||||
// Drives the pin high or low depending on the provided value.
|
||||
|
||||
#[cfg(feature = "embedded-hal-02")]
|
||||
impl<MODE, const GPIONUM: u8> embedded_hal_02::digital::v2::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> {
|
||||
use embedded_hal_02::digital::v2::{OutputPin as _, StatefulOutputPin as _};
|
||||
if self.is_set_high()? {
|
||||
Ok(self.set_low()?)
|
||||
/// Is the pin in drive high mode?
|
||||
#[inline]
|
||||
pub fn is_set_high(&self) -> bool {
|
||||
<Self as GpioProperties>::Bank::read_output() & (1 << (GPIONUM % 32)) != 0
|
||||
}
|
||||
|
||||
/// Is the pin in drive low mode?
|
||||
#[inline]
|
||||
pub fn is_set_low(&self) -> bool {
|
||||
!self.is_set_high()
|
||||
}
|
||||
|
||||
/// Toggle pin output.
|
||||
#[inline]
|
||||
pub fn toggle(&mut self) {
|
||||
if self.is_set_high() {
|
||||
self.set_low();
|
||||
} 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>
|
||||
where
|
||||
Self: GpioProperties,
|
||||
@ -1772,131 +1693,91 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "embedded-hal-02")]
|
||||
impl<MODE, TYPE> embedded_hal_02::digital::v2::InputPin for AnyPin<Input<MODE>, TYPE> {
|
||||
type Error = core::convert::Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
impl<MODE, TYPE> AnyPin<Input<MODE>, TYPE> {
|
||||
/// Is the input pin high?
|
||||
#[inline]
|
||||
pub fn is_high(&self) -> bool {
|
||||
let inner = &self.inner;
|
||||
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;
|
||||
handle_gpio_input!(inner, target, { target.is_low() })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "embedded-hal")]
|
||||
impl<MODE, TYPE> embedded_hal::digital::ErrorType for AnyPin<Input<MODE>, TYPE> {
|
||||
type Error = core::convert::Infallible;
|
||||
}
|
||||
|
||||
#[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> {
|
||||
impl<MODE, TYPE> AnyPin<Output<MODE>, TYPE> {
|
||||
/// Drives the pin low.
|
||||
#[inline]
|
||||
pub fn set_low(&mut self) {
|
||||
let inner = &mut self.inner;
|
||||
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;
|
||||
handle_gpio_output!(inner, target, { target.set_high() })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "embedded-hal-02")]
|
||||
impl<MODE, TYPE> embedded_hal_02::digital::v2::StatefulOutputPin for AnyPin<Output<MODE>, TYPE> {
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
// TODO: add `set_state(PinState)`
|
||||
// Drives the pin high or low depending on the provided value.
|
||||
|
||||
/// Is the pin in drive high mode?
|
||||
#[inline]
|
||||
pub fn is_set_high(&self) -> bool {
|
||||
let inner = &self.inner;
|
||||
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;
|
||||
handle_gpio_output!(inner, target, { target.is_set_low() })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "embedded-hal-02")]
|
||||
impl<MODE, TYPE> embedded_hal_02::digital::v2::ToggleableOutputPin for AnyPin<Output<MODE>, TYPE> {
|
||||
type Error = core::convert::Infallible;
|
||||
|
||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||
/// Toggle pin output.
|
||||
#[inline]
|
||||
pub fn toggle(&mut self) {
|
||||
let inner = &mut self.inner;
|
||||
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")]
|
||||
impl<MODE, TYPE> embedded_hal_async::digital::Wait for AnyPin<Input<MODE>, TYPE> {
|
||||
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
||||
impl<MODE, TYPE> AnyPin<Input<MODE>, TYPE> {
|
||||
/// 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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
handle_gpio_input!(inner, target, { target.wait_for_any_edge().await })
|
||||
}
|
||||
@ -3138,7 +3019,6 @@ mod asynch {
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use embedded_hal_async::digital::Wait;
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -3146,54 +3026,68 @@ mod asynch {
|
||||
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
||||
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
|
||||
Self: GpioProperties,
|
||||
<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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
impl<const GPIONUM: u8> Wait for GpioPin<Output<OpenDrain>, GPIONUM>
|
||||
impl<const GPIONUM: u8> GpioPin<Output<OpenDrain>, GPIONUM>
|
||||
where
|
||||
Self: GpioProperties,
|
||||
<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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -3204,7 +3098,7 @@ mod asynch {
|
||||
|
||||
impl<'a, P> PinFuture<'a, P>
|
||||
where
|
||||
P: crate::gpio::Pin + embedded_hal::digital::ErrorType,
|
||||
P: crate::gpio::Pin,
|
||||
{
|
||||
pub fn new(pin: &'a mut P, event: Event) -> Self {
|
||||
pin.listen(event);
|
||||
@ -3214,9 +3108,9 @@ mod asynch {
|
||||
|
||||
impl<'a, P> core::future::Future for PinFuture<'a, P>
|
||||
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> {
|
||||
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
|
||||
// therefore the future has resolved
|
||||
if !self.pin.is_listening() {
|
||||
Poll::Ready(Ok(()))
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
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)
|
||||
|
||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||
//% FEATURES: embedded-hal-02
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use embedded_hal_02::digital::v2::{OutputPin, ToggleableOutputPin};
|
||||
use esp_backtrace as _;
|
||||
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.
|
||||
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
|
||||
// loop.
|
||||
let delay = Delay::new(&clocks);
|
||||
|
||||
loop {
|
||||
led.toggle().unwrap();
|
||||
led.toggle();
|
||||
delay.delay_millis(500);
|
||||
led.toggle().unwrap();
|
||||
led.toggle();
|
||||
// or using `fugit` duration
|
||||
delay.delay(2.secs());
|
||||
}
|
||||
|
@ -52,10 +52,10 @@ fn main() -> ! {
|
||||
|
||||
fn toggle_pins(leds: &mut [AnyPin<Output<PushPull>>], button: &AnyPin<Input<PullDown>>) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
@ -43,10 +43,10 @@ async fn control_led(
|
||||
loop {
|
||||
if control.wait().await {
|
||||
esp_println::println!("LED on");
|
||||
led.set_low().unwrap();
|
||||
led.set_low();
|
||||
} else {
|
||||
esp_println::println!("LED off");
|
||||
led.set_high().unwrap();
|
||||
led.set_high();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,10 +59,10 @@ async fn control_led(
|
||||
loop {
|
||||
if control.wait().await {
|
||||
esp_println::println!("LED on");
|
||||
led.set_low().unwrap();
|
||||
led.set_low();
|
||||
} else {
|
||||
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>>) {
|
||||
loop {
|
||||
for _ in 0..10 {
|
||||
pin.toggle().unwrap();
|
||||
pin.toggle();
|
||||
Timer::after(Duration::from_micros(10)).await;
|
||||
}
|
||||
Timer::after(Duration::from_millis(1000)).await;
|
||||
|
@ -40,7 +40,7 @@ async fn main(_spawner: Spawner) {
|
||||
|
||||
loop {
|
||||
esp_println::println!("Waiting...");
|
||||
input.wait_for_rising_edge().await.unwrap();
|
||||
input.wait_for_rising_edge().await;
|
||||
esp_println::println!("Ping!");
|
||||
Timer::after(Duration::from_millis(100)).await;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ fn main() -> ! {
|
||||
let mut led = io.pins.gpio1.into_push_pull_output();
|
||||
let button = io.pins.gpio9.into_pull_down_input();
|
||||
|
||||
led.set_high().unwrap();
|
||||
led.set_high();
|
||||
|
||||
// setup ETM
|
||||
let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
|
||||
|
@ -4,7 +4,6 @@
|
||||
//! It also blinks an LED like the blinky example.
|
||||
|
||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||
//% FEATURES: embedded-hal-02
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
@ -12,7 +11,6 @@
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use embedded_hal_02::digital::v2::{OutputPin, ToggleableOutputPin};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
@ -50,14 +48,14 @@ fn main() -> ! {
|
||||
button.listen(Event::FallingEdge);
|
||||
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
|
||||
// loop.
|
||||
let delay = Delay::new(&clocks);
|
||||
|
||||
loop {
|
||||
led.toggle().unwrap();
|
||||
led.toggle();
|
||||
delay.delay_millis(500);
|
||||
}
|
||||
}
|
||||
|
@ -18,12 +18,10 @@
|
||||
//! D7 GPIO15
|
||||
|
||||
//% CHIPS: esp32s3
|
||||
//% FEATURES: embedded-hal-02
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use embedded_hal_02::digital::v2::OutputPin;
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
@ -97,9 +95,9 @@ fn main() -> ! {
|
||||
// https://gist.github.com/sukesh-ak/610508bc84779a26efdcf969bf51a2d1
|
||||
// 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);
|
||||
reset.set_high().unwrap();
|
||||
reset.set_high();
|
||||
delay.delay_micros(64_000);
|
||||
|
||||
// const CMD_FRMCTR1: u8 = 0xB1;
|
||||
@ -210,7 +208,7 @@ fn main() -> ! {
|
||||
const RED: u16 = 0b00000_000000_11111;
|
||||
const BLUE: u16 = 0b11111_000000_00000;
|
||||
|
||||
backlight.set_high().unwrap();
|
||||
backlight.set_high();
|
||||
|
||||
let total_pixels = width as usize * height as usize;
|
||||
let total_bytes = total_pixels * 2;
|
||||
|
@ -2,12 +2,10 @@
|
||||
//! Connect GPIO5 to GPIO4
|
||||
|
||||
//% CHIPS: esp32 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||
//% FEATURES: embedded-hal-02
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use embedded_hal_02::digital::v2::OutputPin;
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
@ -75,9 +73,9 @@ fn main() -> ! {
|
||||
|
||||
// simulate input
|
||||
for i in 0u32..5u32 {
|
||||
out.set_high().unwrap();
|
||||
out.set_high();
|
||||
delay.delay_micros(i * 10 + 20);
|
||||
out.set_low().unwrap();
|
||||
out.set_low();
|
||||
delay.delay_micros(i * 20 + 20);
|
||||
}
|
||||
|
||||
|
@ -61,9 +61,9 @@ fn main() -> ! {
|
||||
let mut master_mosi = io.pins.gpio8.into_push_pull_output();
|
||||
let slave_cs = io.pins.gpio3;
|
||||
let mut master_cs = io.pins.gpio9.into_push_pull_output();
|
||||
master_cs.set_high().unwrap();
|
||||
master_sclk.set_low().unwrap();
|
||||
master_mosi.set_low().unwrap();
|
||||
master_cs.set_high();
|
||||
master_sclk.set_low();
|
||||
master_mosi.set_low();
|
||||
|
||||
let dma = Dma::new(peripherals.DMA);
|
||||
let dma_channel = dma.channel0;
|
||||
@ -115,31 +115,31 @@ fn main() -> ! {
|
||||
// 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
|
||||
// edge and set on the falling edge.
|
||||
master_cs.set_low().unwrap();
|
||||
master_cs.set_low();
|
||||
for (j, v) in master_send.iter().enumerate() {
|
||||
let mut b = *v;
|
||||
let mut rb = 0u8;
|
||||
for _ in 0..8 {
|
||||
if b & 128 != 0 {
|
||||
master_mosi.set_high().unwrap();
|
||||
master_mosi.set_high();
|
||||
} else {
|
||||
master_mosi.set_low().unwrap();
|
||||
master_mosi.set_low();
|
||||
}
|
||||
master_sclk.set_low().unwrap();
|
||||
master_sclk.set_low();
|
||||
b <<= 1;
|
||||
rb <<= 1;
|
||||
// NB: adding about 24 NOPs here makes the clock's duty cycle
|
||||
// run at about 50% ... but we don't strictly need the delay,
|
||||
// either.
|
||||
master_sclk.set_high().unwrap();
|
||||
if master_miso.is_high().unwrap() {
|
||||
master_sclk.set_high();
|
||||
if master_miso.is_high() {
|
||||
rb |= 1;
|
||||
}
|
||||
}
|
||||
master_receive[j] = rb;
|
||||
}
|
||||
master_cs.set_high().unwrap();
|
||||
master_sclk.set_low().unwrap();
|
||||
master_cs.set_high();
|
||||
master_sclk.set_low();
|
||||
// the buffers and spi is moved into the transfer and we can get it back via
|
||||
// `wait`
|
||||
transfer.wait().unwrap();
|
||||
@ -155,23 +155,23 @@ fn main() -> ! {
|
||||
|
||||
slave_receive.fill(0xff);
|
||||
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() {
|
||||
let mut b = *v;
|
||||
for _ in 0..8 {
|
||||
if b & 128 != 0 {
|
||||
master_mosi.set_high().unwrap();
|
||||
master_mosi.set_high();
|
||||
} else {
|
||||
master_mosi.set_low().unwrap();
|
||||
master_mosi.set_low();
|
||||
}
|
||||
b <<= 1;
|
||||
master_sclk.set_low().unwrap();
|
||||
master_sclk.set_high().unwrap();
|
||||
master_sclk.set_low();
|
||||
master_sclk.set_high();
|
||||
}
|
||||
}
|
||||
master_cs.set_high().unwrap();
|
||||
master_cs.set_high();
|
||||
transfer.wait().unwrap();
|
||||
println!(
|
||||
"slave got {:x?} .. {:x?}",
|
||||
@ -184,20 +184,20 @@ fn main() -> ! {
|
||||
|
||||
master_receive.fill(0);
|
||||
|
||||
master_cs.set_low().unwrap();
|
||||
master_cs.set_low();
|
||||
for (j, _) in master_send.iter().enumerate() {
|
||||
let mut rb = 0u8;
|
||||
for _ in 0..8 {
|
||||
master_sclk.set_low().unwrap();
|
||||
master_sclk.set_low();
|
||||
rb <<= 1;
|
||||
master_sclk.set_high().unwrap();
|
||||
if master_miso.is_high().unwrap() {
|
||||
master_sclk.set_high();
|
||||
if master_miso.is_high() {
|
||||
rb |= 1;
|
||||
}
|
||||
}
|
||||
master_receive[j] = rb;
|
||||
}
|
||||
master_cs.set_high().unwrap();
|
||||
master_cs.set_high();
|
||||
transfer.wait().unwrap();
|
||||
|
||||
println!(
|
||||
|
@ -11,7 +11,6 @@ use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use defmt_rtt as _;
|
||||
use embedded_hal::digital::{InputPin as _, OutputPin as _, StatefulOutputPin as _};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
@ -74,7 +73,6 @@ pub fn interrupt_handler() {
|
||||
mod tests {
|
||||
use defmt::assert_eq;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embedded_hal_async::digital::Wait;
|
||||
use esp_hal::gpio::{Event, Pin};
|
||||
use portable_atomic::{AtomicUsize, Ordering};
|
||||
|
||||
@ -84,7 +82,7 @@ mod tests {
|
||||
fn init() -> Context {
|
||||
let mut ctx = Context::init();
|
||||
// make sure tests don't interfere with each other
|
||||
ctx.io4.set_low().ok();
|
||||
ctx.io4.set_low();
|
||||
ctx
|
||||
}
|
||||
|
||||
@ -97,15 +95,15 @@ mod tests {
|
||||
embassy_futures::select::select(
|
||||
async {
|
||||
loop {
|
||||
io2.wait_for_rising_edge().await.unwrap();
|
||||
io2.wait_for_rising_edge().await;
|
||||
counter.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
},
|
||||
async {
|
||||
for _ in 0..5 {
|
||||
io4.set_high().unwrap();
|
||||
io4.set_high();
|
||||
Timer::after(Duration::from_millis(25)).await;
|
||||
io4.set_low().unwrap();
|
||||
io4.set_low();
|
||||
Timer::after(Duration::from_millis(25)).await;
|
||||
}
|
||||
},
|
||||
@ -128,30 +126,30 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpio_input(mut ctx: Context) {
|
||||
fn test_gpio_input(ctx: Context) {
|
||||
// `InputPin`:
|
||||
assert_eq!(ctx.io2.is_low(), Ok(true));
|
||||
assert_eq!(ctx.io2.is_high(), Ok(false));
|
||||
assert_eq!(ctx.io2.is_low(), true);
|
||||
assert_eq!(ctx.io2.is_high(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpio_output(mut ctx: Context) {
|
||||
// `StatefulOutputPin`:
|
||||
assert_eq!(ctx.io4.is_set_low(), Ok(true));
|
||||
assert_eq!(ctx.io4.is_set_high(), Ok(false));
|
||||
assert!(ctx.io4.set_high().is_ok());
|
||||
assert_eq!(ctx.io4.is_set_low(), Ok(false));
|
||||
assert_eq!(ctx.io4.is_set_high(), Ok(true));
|
||||
assert_eq!(ctx.io4.is_set_low(), true);
|
||||
assert_eq!(ctx.io4.is_set_high(), false);
|
||||
ctx.io4.set_high();
|
||||
assert_eq!(ctx.io4.is_set_low(), false);
|
||||
assert_eq!(ctx.io4.is_set_high(), true);
|
||||
|
||||
// `ToggleableOutputPin`:
|
||||
assert!(ctx.io4.toggle().is_ok());
|
||||
assert_eq!(ctx.io4.is_set_low(), Ok(true));
|
||||
assert_eq!(ctx.io4.is_set_high(), Ok(false));
|
||||
assert!(ctx.io4.toggle().is_ok());
|
||||
assert_eq!(ctx.io4.is_set_low(), Ok(false));
|
||||
assert_eq!(ctx.io4.is_set_high(), Ok(true));
|
||||
ctx.io4.toggle();
|
||||
assert_eq!(ctx.io4.is_set_low(), true);
|
||||
assert_eq!(ctx.io4.is_set_high(), false);
|
||||
ctx.io4.toggle();
|
||||
assert_eq!(ctx.io4.is_set_low(), false);
|
||||
assert_eq!(ctx.io4.is_set_high(), true);
|
||||
// Leave in initial state for next test
|
||||
assert!(ctx.io4.toggle().is_ok());
|
||||
ctx.io4.toggle();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -161,23 +159,23 @@ mod tests {
|
||||
ctx.io2.listen(Event::AnyEdge);
|
||||
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);
|
||||
assert!(ctx.io4.set_low().is_ok());
|
||||
ctx.io4.set_low();
|
||||
ctx.delay.delay_millis(1);
|
||||
assert!(ctx.io4.set_high().is_ok());
|
||||
ctx.io4.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
assert!(ctx.io4.set_low().is_ok());
|
||||
ctx.io4.set_low();
|
||||
ctx.delay.delay_millis(1);
|
||||
assert!(ctx.io4.set_high().is_ok());
|
||||
ctx.io4.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
assert!(ctx.io4.set_low().is_ok());
|
||||
ctx.io4.set_low();
|
||||
ctx.delay.delay_millis(1);
|
||||
assert!(ctx.io4.set_high().is_ok());
|
||||
ctx.io4.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
assert!(ctx.io4.set_low().is_ok());
|
||||
ctx.io4.set_low();
|
||||
ctx.delay.delay_millis(1);
|
||||
assert!(ctx.io4.set_high().is_ok());
|
||||
ctx.io4.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
|
||||
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();
|
||||
io4.internal_pull_up(true);
|
||||
|
||||
assert!(io2.set_high().is_ok());
|
||||
assert!(io4.set_high().is_ok());
|
||||
io2.set_high();
|
||||
io4.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
|
||||
assert_eq!(io2.is_high(), Ok(true));
|
||||
assert_eq!(io4.is_high(), Ok(true));
|
||||
assert_eq!(io2.is_high(), true);
|
||||
assert_eq!(io4.is_high(), true);
|
||||
|
||||
assert!(io2.set_low().is_ok());
|
||||
assert!(io4.set_high().is_ok());
|
||||
io2.set_low();
|
||||
io4.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
|
||||
assert_eq!(io2.is_low(), Ok(true));
|
||||
assert_eq!(io4.is_low(), Ok(true));
|
||||
assert_eq!(io2.is_low(), true);
|
||||
assert_eq!(io4.is_low(), true);
|
||||
|
||||
assert!(io2.set_high().is_ok());
|
||||
assert!(io4.set_high().is_ok());
|
||||
io2.set_high();
|
||||
io4.set_high();
|
||||
ctx.delay.delay_millis(1);
|
||||
|
||||
assert_eq!(io2.is_high(), Ok(true));
|
||||
assert_eq!(io4.is_high(), Ok(true));
|
||||
assert_eq!(io2.is_high(), true);
|
||||
assert_eq!(io4.is_high(), true);
|
||||
|
||||
assert!(io2.set_high().is_ok());
|
||||
assert!(io4.set_low().is_ok());
|
||||
io2.set_high();
|
||||
io4.set_low();
|
||||
ctx.delay.delay_millis(1);
|
||||
|
||||
assert_eq!(io2.is_low(), Ok(true));
|
||||
assert_eq!(io4.is_low(), Ok(true));
|
||||
assert_eq!(io2.is_low(), true);
|
||||
assert_eq!(io4.is_low(), true);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user