[ESP32-C6-LP] Add input support for IO driver, implement more embedded-hal output traits (#720)
* Add input support for IO driver, implement more `embedded-hal` output traits * Update CHANGELOG
This commit is contained in:
parent
a2ae6f37d1
commit
2dee0110be
@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Add the `esp32c6-lp-hal` package (#714)
|
||||
- Add GPIO (output) and delay functionality to `esp32c6-lp-hal` (#715)
|
||||
- Implement RTCIO pullup, pulldown and hold control for Xtensa MCUs (#684)
|
||||
- Add GPIO input support and implement additional `embedded-hal` output traits for the C6's LP core [#720]
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp32c6_lp_hal::{gpio::Io, prelude::*};
|
||||
use esp32c6_lp_hal::{delay::Delay, gpio::IO, prelude::*};
|
||||
use panic_halt as _;
|
||||
|
||||
#[entry]
|
||||
@ -13,11 +13,11 @@ fn main() -> ! {
|
||||
|
||||
let peripherals = esp32c6_lp::Peripherals::take().unwrap();
|
||||
|
||||
let io = Io::new(peripherals.LP_IO);
|
||||
let io = IO::new(peripherals.LP_IO);
|
||||
let mut gpio1 = io.gpio1.into_output();
|
||||
|
||||
let ptr = 0x5000_2000 as *mut u32;
|
||||
let mut delay = delay::Delay::new();
|
||||
let mut delay = Delay::new();
|
||||
|
||||
loop {
|
||||
i = i.wrapping_add(1u32);
|
||||
|
||||
@ -1,23 +1,14 @@
|
||||
//! LP-GPIO driver
|
||||
//! Low-power GPIO driver
|
||||
//!
|
||||
//! It's assumed that GPIOs are already configured correctly by the HP core.
|
||||
|
||||
use core::{convert::Infallible, marker::PhantomData};
|
||||
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
|
||||
pub struct Unknown {}
|
||||
|
||||
pub struct Output;
|
||||
use esp32c6_lp::LP_IO;
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct GpioPin<const PIN: u8, MODE> {
|
||||
phantom: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct Io {
|
||||
_peripheral: esp32c6_lp::LP_IO,
|
||||
pub struct IO {
|
||||
_peripheral: LP_IO,
|
||||
|
||||
pub gpio0: GpioPin<0, Unknown>,
|
||||
pub gpio1: GpioPin<1, Unknown>,
|
||||
@ -29,10 +20,11 @@ pub struct Io {
|
||||
pub gpio7: GpioPin<7, Unknown>,
|
||||
}
|
||||
|
||||
impl Io {
|
||||
pub fn new(peripheral: esp32c6_lp::LP_IO) -> Self {
|
||||
impl IO {
|
||||
pub fn new(peripheral: LP_IO) -> Self {
|
||||
Self {
|
||||
_peripheral: peripheral,
|
||||
|
||||
gpio0: GpioPin::new(),
|
||||
gpio1: GpioPin::new(),
|
||||
gpio2: GpioPin::new(),
|
||||
@ -45,13 +37,30 @@ impl Io {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Unknown {}
|
||||
|
||||
pub struct Input;
|
||||
|
||||
pub struct Output;
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct GpioPin<const PIN: u8, MODE> {
|
||||
phantom: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
impl<const PIN: u8, MODE> GpioPin<PIN, MODE> {
|
||||
fn new() -> Self {
|
||||
GpioPin {
|
||||
phantom: PhantomData::default(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Assuming the GPIO is already configured by the HP core this makes the
|
||||
/// GPIO into an input pin.
|
||||
pub fn into_input(self) -> GpioPin<PIN, Input> {
|
||||
GpioPin::new()
|
||||
}
|
||||
|
||||
/// Assuming the GPIO is already configured by the HP core this makes the
|
||||
/// GPIO into an output pin.
|
||||
pub fn into_output(self) -> GpioPin<PIN, Output> {
|
||||
@ -59,22 +68,64 @@ impl<const PIN: u8, MODE> GpioPin<PIN, MODE> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<const PIN: u8> OutputPin for GpioPin<PIN, Output> {
|
||||
impl<const PIN: u8> GpioPin<PIN, Input> {
|
||||
fn input_state(&self) -> bool {
|
||||
unsafe { &*LP_IO::PTR }.in_.read().bits() >> PIN & 0x1 != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl<const PIN: u8> GpioPin<PIN, Output> {
|
||||
fn output_state(&self) -> bool {
|
||||
unsafe { &*LP_IO::PTR }.out.read().bits() >> PIN & 0x1 != 0
|
||||
}
|
||||
|
||||
fn set_output_low(&mut self) {
|
||||
unsafe { &*LP_IO::PTR }
|
||||
.out_w1tc
|
||||
.write(|w| w.out_data_w1tc().variant(1 << PIN));
|
||||
}
|
||||
|
||||
fn set_output_high(&mut self) {
|
||||
unsafe { &*LP_IO::PTR }
|
||||
.out_w1ts
|
||||
.write(|w| w.out_data_w1ts().variant(1 << PIN));
|
||||
}
|
||||
}
|
||||
|
||||
impl<const PIN: u8> embedded_hal::digital::v2::InputPin for GpioPin<PIN, Input> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.input_state())
|
||||
}
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(!self.is_high()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const PIN: u8> embedded_hal::digital::v2::OutputPin for GpioPin<PIN, Output> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
let lp_gpio = unsafe { &*esp32c6_lp::LP_IO::PTR };
|
||||
lp_gpio
|
||||
.out_w1tc
|
||||
.write(|w| w.out_data_w1tc().variant(1 << PIN));
|
||||
self.set_output_low();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
let lp_gpio = unsafe { &*esp32c6_lp::LP_IO::PTR };
|
||||
lp_gpio
|
||||
.out_w1ts
|
||||
.write(|w| w.out_data_w1ts().variant(1 << PIN));
|
||||
self.set_output_high();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<const PIN: u8> embedded_hal::digital::v2::StatefulOutputPin for GpioPin<PIN, Output> {
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.output_state())
|
||||
}
|
||||
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(!self.is_set_high()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const PIN: u8> embedded_hal::digital::v2::toggleable::Default for GpioPin<PIN, Output> {}
|
||||
|
||||
@ -3,7 +3,13 @@
|
||||
//! Re-exports all traits required for interacting with the various peripheral
|
||||
//! drivers implemented in this crate.
|
||||
|
||||
pub use embedded_hal::{digital::v2::OutputPin, prelude::*};
|
||||
pub use embedded_hal::{
|
||||
digital::v2::{
|
||||
InputPin as _embedded_hal_digital_vs_InputPin,
|
||||
OutputPin as _embedded_hal_digital_vs_OutputPin,
|
||||
StatefulOutputPin as _embedded_hal_digital_vs_StatefulOutputPin,
|
||||
ToggleableOutputPin as _embedded_hal_digital_vs_ToggleableOutputPin,
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
pub use riscv_rt_macros::entry;
|
||||
|
||||
pub use crate::delay;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user