ESP32-C6 LP CORE delay and basic gpio (#715)
* ESP32-C6 LP CORE delay and basic gpio * CHANGELOG.md, build LP examples in release mode
This commit is contained in:
parent
64556da803
commit
bbe1e5df59
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -244,7 +244,7 @@ jobs:
|
||||
# Perform a full build initially to verify that the examples not only
|
||||
# build, but also link successfully.
|
||||
- name: build esp32c6-lp-hal (no features)
|
||||
run: cd esp32c6-lp-hal/ && cargo +nightly build --examples
|
||||
run: cd esp32c6-lp-hal/ && cargo +nightly build --release --examples
|
||||
# Ensure documentation can be built
|
||||
- name: rustdoc
|
||||
run: cd esp32c6-lp-hal/ && cargo doc
|
||||
|
||||
@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Added
|
||||
|
||||
- Add the `esp32c6-lp-hal` package (#714)
|
||||
- Add GPIO (output) and delay functionality to `esp32c6-lp-hal` (#715)
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
[target.riscv32imac-unknown-none-elf]
|
||||
runner = "espflash flash --monitor"
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlinkall.x",
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
]
|
||||
|
||||
[build]
|
||||
|
||||
@ -25,6 +25,11 @@ critical-section = { version = "1.1.2", features = ["restore-state-u8"] }
|
||||
embedded-hal = { version = "0.2.7", features = ["unproven"] }
|
||||
esp32c6-lp = { git = "https://github.com/esp-rs/esp-pacs", rev = "a9cad5e", features = ["critical-section"] }
|
||||
riscv = "0.10.1"
|
||||
riscv-rt-macros = "0.2.0"
|
||||
paste = "1.0.14"
|
||||
|
||||
[dev-dependencies]
|
||||
panic-halt = "0.2.0"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
34
esp32c6-lp-hal/examples/blinky.rs
Normal file
34
esp32c6-lp-hal/examples/blinky.rs
Normal file
@ -0,0 +1,34 @@
|
||||
//! Counts a 32 bit value at 0x5000_2000 and blinks GPIO 1.
|
||||
//! Make sure the LP RAM is cleared before loading the code.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp32c6_lp_hal::{gpio::Io, prelude::*};
|
||||
use panic_halt as _;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let mut i: u32 = 0;
|
||||
|
||||
let peripherals = esp32c6_lp::Peripherals::take().unwrap();
|
||||
|
||||
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();
|
||||
|
||||
loop {
|
||||
i = i.wrapping_add(1u32);
|
||||
unsafe {
|
||||
ptr.write_volatile(i);
|
||||
}
|
||||
|
||||
gpio1.set_high().unwrap();
|
||||
delay.delay_ms(500);
|
||||
|
||||
gpio1.set_low().unwrap();
|
||||
delay.delay_ms(500);
|
||||
}
|
||||
}
|
||||
41
esp32c6-lp-hal/src/delay.rs
Normal file
41
esp32c6-lp-hal/src/delay.rs
Normal file
@ -0,0 +1,41 @@
|
||||
//! Simple blocking delay functionality
|
||||
//!
|
||||
//! This uses the delay functionality provided by the `riscv` crate under the
|
||||
//! hood.
|
||||
|
||||
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
|
||||
|
||||
use crate::CPU_CLOCK;
|
||||
|
||||
pub struct Delay {
|
||||
rv_delay: riscv::delay::McycleDelay,
|
||||
}
|
||||
|
||||
impl Delay {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
rv_delay: riscv::delay::McycleDelay::new(CPU_CLOCK),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DelayUs<u64> for Delay {
|
||||
#[inline(always)]
|
||||
fn delay_us(&mut self, us: u64) {
|
||||
self.rv_delay.delay_us(us);
|
||||
}
|
||||
}
|
||||
|
||||
impl DelayUs<u32> for Delay {
|
||||
#[inline(always)]
|
||||
fn delay_us(&mut self, us: u32) {
|
||||
self.rv_delay.delay_us(us);
|
||||
}
|
||||
}
|
||||
|
||||
impl DelayMs<u32> for Delay {
|
||||
#[inline(always)]
|
||||
fn delay_ms(&mut self, ms: u32) {
|
||||
self.rv_delay.delay_ms(ms);
|
||||
}
|
||||
}
|
||||
80
esp32c6-lp-hal/src/gpio.rs
Normal file
80
esp32c6-lp-hal/src/gpio.rs
Normal file
@ -0,0 +1,80 @@
|
||||
//! LP-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;
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct GpioPin<const PIN: u8, MODE> {
|
||||
phantom: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct Io {
|
||||
_peripheral: esp32c6_lp::LP_IO,
|
||||
|
||||
pub gpio0: GpioPin<0, Unknown>,
|
||||
pub gpio1: GpioPin<1, Unknown>,
|
||||
pub gpio2: GpioPin<2, Unknown>,
|
||||
pub gpio3: GpioPin<3, Unknown>,
|
||||
pub gpio4: GpioPin<4, Unknown>,
|
||||
pub gpio5: GpioPin<5, Unknown>,
|
||||
pub gpio6: GpioPin<6, Unknown>,
|
||||
pub gpio7: GpioPin<7, Unknown>,
|
||||
}
|
||||
|
||||
impl Io {
|
||||
pub fn new(peripheral: esp32c6_lp::LP_IO) -> Self {
|
||||
Self {
|
||||
_peripheral: peripheral,
|
||||
gpio0: GpioPin::new(),
|
||||
gpio1: GpioPin::new(),
|
||||
gpio2: GpioPin::new(),
|
||||
gpio3: GpioPin::new(),
|
||||
gpio4: GpioPin::new(),
|
||||
gpio5: GpioPin::new(),
|
||||
gpio6: GpioPin::new(),
|
||||
gpio7: GpioPin::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<const PIN: u8, MODE> GpioPin<PIN, MODE> {
|
||||
fn new() -> Self {
|
||||
GpioPin {
|
||||
phantom: PhantomData::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
GpioPin::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const PIN: u8> 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));
|
||||
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));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,9 @@
|
||||
|
||||
use core::arch::global_asm;
|
||||
|
||||
pub mod delay;
|
||||
pub mod gpio;
|
||||
|
||||
pub mod riscv {
|
||||
//! Low level access to RISC-V processors.
|
||||
//!
|
||||
@ -9,6 +12,9 @@ pub mod riscv {
|
||||
|
||||
pub use riscv::*;
|
||||
}
|
||||
pub mod prelude;
|
||||
|
||||
const CPU_CLOCK: u32 = 16_000_000;
|
||||
|
||||
global_asm!(
|
||||
r#"
|
||||
|
||||
9
esp32c6-lp-hal/src/prelude.rs
Normal file
9
esp32c6-lp-hal/src/prelude.rs
Normal file
@ -0,0 +1,9 @@
|
||||
//! The prelude
|
||||
//!
|
||||
//! 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 riscv_rt_macros::entry;
|
||||
|
||||
pub use crate::delay;
|
||||
Loading…
Reference in New Issue
Block a user