mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 14:44:42 +00:00
Add some miscellaneous examples for the ESP32-H2 (#548)
* Add some miscellaneous examples for the ESP32-H2 * Update the CHANGELOG
This commit is contained in:
parent
3be64df304
commit
661a9de5eb
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
@ -224,10 +224,10 @@ jobs:
|
||||
run: cd esp32h2-hal/ && cargo +nightly check --examples --features=eh1,ufmt
|
||||
- name: check esp32h2-hal (async, i2c)
|
||||
run: cd esp32h2-hal/ && cargo check --example=embassy_i2c --features=embassy,embassy-time-systick,async
|
||||
# - name: check esp32h2-hal (async, systick)
|
||||
# run: cd esp32h2-hal/ && cargo +nightly check --example=embassy_hello_world --features=embassy,embassy-time-systick
|
||||
# - name: check esp32h2-hal (async, timg0)
|
||||
# run: cd esp32h2-hal/ && cargo +nightly check --example=embassy_hello_world --features=embassy,embassy-time-timg0
|
||||
- name: check esp32h2-hal (async, systick)
|
||||
run: cd esp32h2-hal/ && cargo +nightly check --example=embassy_hello_world --features=embassy,embassy-time-systick
|
||||
- name: check esp32h2-hal (async, timg0)
|
||||
run: cd esp32h2-hal/ && cargo +nightly check --example=embassy_hello_world --features=embassy,embassy-time-timg0
|
||||
# - name: check esp32h2-hal (async, gpio)
|
||||
# run: cd esp32h2-hal/ && cargo +nightly check --example=embassy_wait --features=embassy,embassy-time-systick,async
|
||||
# - name: check esp32h2-hal (async, spi)
|
||||
@ -440,7 +440,7 @@ jobs:
|
||||
uses: dangoslen/changelog-enforcer@v3
|
||||
with:
|
||||
changeLogPath: CHANGELOG.md
|
||||
skipLabels: 'skip-changelog'
|
||||
missingUpdateErrorMessage: 'Please add a changelog entry in the CHANGELOG.md file.'
|
||||
skipLabels: "skip-changelog"
|
||||
missingUpdateErrorMessage: "Please add a changelog entry in the CHANGELOG.md file."
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
@ -24,21 +24,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Add LEDC hardware fade support
|
||||
- Added support for multicore async GPIO (#542)
|
||||
- Add initial support for MCPWM in ESP32-H2 (#544)
|
||||
- Add some miscellaneous examples for the ESP32-H2 (#548)
|
||||
|
||||
### Fixed
|
||||
|
||||
- DMA is supported for SPI3 on ESP32-S3 (#507)
|
||||
- `change_bus_frequency` is now available on `SpiDma` (#529)
|
||||
- Fixed a bug where a GPIO interrupt could erroneously fire again causing the next `await` on that pin to instantly return `Poll::Ok` (#537)
|
||||
- Fixed a bug where a GPIO interrupt could erroneously fire again causing the next `await` on that pin to instantly return `Poll::Ok` (#537)
|
||||
- Set `vecbase` on core 1 (ESP32, ESP32-S3) (#536)
|
||||
- ESP32-S3: Move PSRAM related function to RAM (#546)
|
||||
|
||||
### Changed
|
||||
|
||||
- Improve examples documentation (#533)
|
||||
|
||||
### Breaking
|
||||
|
||||
- As part of the refactoring in #537, the public GPIO type has changed.
|
||||
- As part of the refactoring in #537, the public GPIO type has changed.
|
||||
|
||||
## [0.9.0] - 2023-05-02
|
||||
|
||||
|
@ -55,7 +55,7 @@ esp32 = { version = "0.23.0", features = ["critical-section"], optional = true
|
||||
esp32c2 = { version = "0.11.0", features = ["critical-section"], optional = true }
|
||||
esp32c3 = { version = "0.14.0", features = ["critical-section"], optional = true }
|
||||
esp32c6 = { version = "0.4.0", features = ["critical-section"], optional = true }
|
||||
esp32h2 = { git = "https://github.com/esp-rs/esp-pacs", rev = "5828519", package = "esp32h2", features = ["critical-section"], optional = true }
|
||||
esp32h2 = { git = "https://github.com/esp-rs/esp-pacs", rev = "ff70333", package = "esp32h2", features = ["critical-section"], optional = true }
|
||||
esp32s2 = { version = "0.14.0", features = ["critical-section"], optional = true }
|
||||
esp32s3 = { version = "0.18.0", features = ["critical-section"], optional = true }
|
||||
|
||||
|
@ -56,7 +56,7 @@ peripherals = [
|
||||
"uart0",
|
||||
"uart1",
|
||||
# "uhci0",
|
||||
# "usb_device",
|
||||
"usb_device",
|
||||
|
||||
# Additional peripherals defined by us (the developers):
|
||||
"adc",
|
||||
|
@ -58,6 +58,6 @@ crate::peripherals! {
|
||||
UART0 => true,
|
||||
UART1 => true,
|
||||
// UHCI0 => true,
|
||||
// USB_DEVICE => true,
|
||||
USB_DEVICE => true,
|
||||
RADIO => false,
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ impl<T, const CHANNEL: u8> Alarm<T, CHANNEL> {
|
||||
#[cfg(esp32s2)]
|
||||
systimer.step.write(|w| w.timer_xtal_step().bits(0x1)); // run at XTAL freq, not 80 * XTAL freq
|
||||
|
||||
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32s3))]
|
||||
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
|
||||
{
|
||||
tconf.write(|w| w.target0_timer_unit_sel().clear_bit()); // default, use unit 0
|
||||
systimer
|
||||
@ -148,7 +148,7 @@ impl<T, const CHANNEL: u8> Alarm<T, CHANNEL> {
|
||||
|
||||
conf(tconf, hi, lo);
|
||||
|
||||
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32s3))]
|
||||
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
|
||||
{
|
||||
match CHANNEL {
|
||||
0 => {
|
||||
|
@ -61,6 +61,10 @@ embassy = ["esp-hal-common/embassy"]
|
||||
embassy-time-systick = ["esp-hal-common/embassy-time-systick", "embassy-time/tick-hz-16_000_000"]
|
||||
embassy-time-timg0 = ["esp-hal-common/embassy-time-timg0", "embassy-time/tick-hz-1_000_000"]
|
||||
|
||||
[[example]]
|
||||
name = "embassy_hello_world"
|
||||
required-features = ["embassy"]
|
||||
|
||||
[[example]]
|
||||
name = "embassy_i2c"
|
||||
required-features = ["embassy", "async", "embassy-time-systick"]
|
||||
required-features = ["embassy", "async", "embassy-time-systick"]
|
||||
|
89
esp32h2-hal/examples/advanced_serial.rs
Normal file
89
esp32h2-hal/examples/advanced_serial.rs
Normal file
@ -0,0 +1,89 @@
|
||||
//! This shows how to configure UART
|
||||
//! You can short the TX and RX pin and see it reads what was written.
|
||||
//! Additionally you can connect a logic analzyer to TX and see how the changes
|
||||
//! of the configuration change the output signal.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp32h2_hal::{
|
||||
clock::ClockControl,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
timer::TimerGroup,
|
||||
uart::{
|
||||
config::{Config, DataBits, Parity, StopBits},
|
||||
TxRxPins,
|
||||
},
|
||||
Rtc,
|
||||
Uart,
|
||||
IO,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println::println;
|
||||
use nb::block;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = Peripherals::take();
|
||||
let mut system = peripherals.PCR.split();
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
// Disable the watchdog timers. For the ESP32-H2, this includes the Super WDT,
|
||||
// and the TIMG WDTs.
|
||||
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
|
||||
let timer_group0 = TimerGroup::new(
|
||||
peripherals.TIMG0,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut timer0 = timer_group0.timer0;
|
||||
let mut wdt0 = timer_group0.wdt;
|
||||
let timer_group1 = TimerGroup::new(
|
||||
peripherals.TIMG1,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt1 = timer_group1.wdt;
|
||||
|
||||
rtc.swd.disable();
|
||||
rtc.rwdt.disable();
|
||||
wdt0.disable();
|
||||
wdt1.disable();
|
||||
|
||||
let config = Config {
|
||||
baudrate: 115200,
|
||||
data_bits: DataBits::DataBits8,
|
||||
parity: Parity::ParityNone,
|
||||
stop_bits: StopBits::STOP1,
|
||||
};
|
||||
|
||||
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let pins = TxRxPins::new_tx_rx(
|
||||
io.pins.gpio1.into_push_pull_output(),
|
||||
io.pins.gpio2.into_floating_input(),
|
||||
);
|
||||
|
||||
let mut serial1 = Uart::new_with_config(
|
||||
peripherals.UART1,
|
||||
Some(config),
|
||||
Some(pins),
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
|
||||
timer0.start(250u64.millis());
|
||||
|
||||
println!("Start");
|
||||
loop {
|
||||
serial1.write(0x42).ok();
|
||||
let read = block!(serial1.read());
|
||||
|
||||
match read {
|
||||
Ok(read) => println!("Read {:02x}", read),
|
||||
Err(err) => println!("Error {:?}", err),
|
||||
}
|
||||
|
||||
block!(timer0.wait()).unwrap();
|
||||
}
|
||||
}
|
82
esp32h2-hal/examples/embassy_hello_world.rs
Normal file
82
esp32h2-hal/examples/embassy_hello_world.rs
Normal file
@ -0,0 +1,82 @@
|
||||
//! embassy hello world
|
||||
//!
|
||||
//! This is an example of running the embassy executor with multiple tasks
|
||||
//! concurrently.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
use embassy_executor::Executor;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp32h2_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
timer::TimerGroup,
|
||||
Rtc,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use static_cell::StaticCell;
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn run1() {
|
||||
loop {
|
||||
esp_println::println!("Hello world from embassy using esp-hal-async!");
|
||||
Timer::after(Duration::from_millis(1_000)).await;
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn run2() {
|
||||
loop {
|
||||
esp_println::println!("Bing!");
|
||||
Timer::after(Duration::from_millis(5_000)).await;
|
||||
}
|
||||
}
|
||||
|
||||
static EXECUTOR: StaticCell<Executor> = StaticCell::new();
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
esp_println::println!("Init!");
|
||||
let peripherals = Peripherals::take();
|
||||
let mut system = peripherals.PCR.split();
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
|
||||
let timer_group0 = TimerGroup::new(
|
||||
peripherals.TIMG0,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt0 = timer_group0.wdt;
|
||||
let timer_group1 = TimerGroup::new(
|
||||
peripherals.TIMG1,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt1 = timer_group1.wdt;
|
||||
|
||||
// Disable watchdog timers
|
||||
rtc.swd.disable();
|
||||
rtc.rwdt.disable();
|
||||
wdt0.disable();
|
||||
wdt1.disable();
|
||||
|
||||
#[cfg(feature = "embassy-time-systick")]
|
||||
embassy::init(
|
||||
&clocks,
|
||||
esp32h2_hal::systimer::SystemTimer::new(peripherals.SYSTIMER),
|
||||
);
|
||||
|
||||
#[cfg(feature = "embassy-time-timg0")]
|
||||
embassy::init(&clocks, timer_group0.timer0);
|
||||
|
||||
let executor = EXECUTOR.init(Executor::new());
|
||||
executor.run(|spawner| {
|
||||
spawner.spawn(run1()).ok();
|
||||
spawner.spawn(run2()).ok();
|
||||
});
|
||||
}
|
138
esp32h2-hal/examples/systimer.rs
Normal file
138
esp32h2-hal/examples/systimer.rs
Normal file
@ -0,0 +1,138 @@
|
||||
//! This shows how to use the SYSTIMER peripheral including interrupts.
|
||||
//! It's an additional timer besides the TIMG peripherals.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32h2_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
interrupt::Priority,
|
||||
peripherals::{self, Peripherals},
|
||||
prelude::*,
|
||||
systimer::{Alarm, Periodic, SystemTimer, Target},
|
||||
timer::TimerGroup,
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println::println;
|
||||
|
||||
static ALARM0: Mutex<RefCell<Option<Alarm<Periodic, 0>>>> = Mutex::new(RefCell::new(None));
|
||||
static ALARM1: Mutex<RefCell<Option<Alarm<Target, 1>>>> = Mutex::new(RefCell::new(None));
|
||||
static ALARM2: Mutex<RefCell<Option<Alarm<Target, 2>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = Peripherals::take();
|
||||
let mut system = peripherals.PCR.split();
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
// Disable the watchdog timers. For the ESP32-H2, this includes the Super WDT,
|
||||
// and the TIMG WDTs.
|
||||
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
|
||||
let timer_group0 = TimerGroup::new(
|
||||
peripherals.TIMG0,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt0 = timer_group0.wdt;
|
||||
let timer_group1 = TimerGroup::new(
|
||||
peripherals.TIMG1,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt1 = timer_group1.wdt;
|
||||
|
||||
// Disable watchdog timers
|
||||
rtc.swd.disable();
|
||||
rtc.rwdt.disable();
|
||||
wdt0.disable();
|
||||
wdt1.disable();
|
||||
|
||||
let syst = SystemTimer::new(peripherals.SYSTIMER);
|
||||
|
||||
println!("SYSTIMER Current value = {}", SystemTimer::now());
|
||||
|
||||
let alarm0 = syst.alarm0.into_periodic();
|
||||
alarm0.set_period(1u32.Hz());
|
||||
alarm0.clear_interrupt();
|
||||
alarm0.interrupt_enable(true);
|
||||
|
||||
let alarm1 = syst.alarm1;
|
||||
alarm1.set_target(SystemTimer::now() + (SystemTimer::TICKS_PER_SECOND * 2));
|
||||
alarm1.interrupt_enable(true);
|
||||
|
||||
let alarm2 = syst.alarm2;
|
||||
alarm2.set_target(SystemTimer::now() + (SystemTimer::TICKS_PER_SECOND * 3));
|
||||
alarm2.interrupt_enable(true);
|
||||
|
||||
critical_section::with(|cs| {
|
||||
ALARM0.borrow_ref_mut(cs).replace(alarm0);
|
||||
ALARM1.borrow_ref_mut(cs).replace(alarm1);
|
||||
ALARM2.borrow_ref_mut(cs).replace(alarm2);
|
||||
});
|
||||
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::SYSTIMER_TARGET0,
|
||||
Priority::Priority1,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::SYSTIMER_TARGET1,
|
||||
Priority::Priority2,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::SYSTIMER_TARGET2,
|
||||
Priority::Priority2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Initialize the Delay peripheral, and use it to toggle the LED state in a
|
||||
// loop.
|
||||
let mut delay = Delay::new(&clocks);
|
||||
|
||||
loop {
|
||||
delay.delay_ms(10000u32);
|
||||
}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET0() {
|
||||
println!("Interrupt lvl1 (alarm0)");
|
||||
critical_section::with(|cs| {
|
||||
ALARM0
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET1() {
|
||||
println!("Interrupt lvl2 (alarm1)");
|
||||
critical_section::with(|cs| {
|
||||
ALARM1
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET2() {
|
||||
println!("Interrupt lvl2 (alarm2)");
|
||||
critical_section::with(|cs| {
|
||||
ALARM2
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
99
esp32h2-hal/examples/usb_serial_jtag.rs
Normal file
99
esp32h2-hal/examples/usb_serial_jtag.rs
Normal file
@ -0,0 +1,99 @@
|
||||
//! This shows how to output text via USB Serial/JTAG.
|
||||
//! You need to connect via the Serial/JTAG interface to see any output.
|
||||
//! Most dev-kits use a USB-UART-bridge - in that case you won't see any output.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::{cell::RefCell, fmt::Write};
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32h2_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
peripherals::{self, Peripherals},
|
||||
prelude::*,
|
||||
riscv,
|
||||
timer::TimerGroup,
|
||||
Cpu,
|
||||
Rtc,
|
||||
UsbSerialJtag,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
|
||||
static USB_SERIAL: Mutex<RefCell<Option<UsbSerialJtag>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = Peripherals::take();
|
||||
let mut system = peripherals.PCR.split();
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
|
||||
let timer_group0 = TimerGroup::new(
|
||||
peripherals.TIMG0,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut timer0 = timer_group0.timer0;
|
||||
let mut wdt0 = timer_group0.wdt;
|
||||
let timer_group1 = TimerGroup::new(
|
||||
peripherals.TIMG1,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt1 = timer_group1.wdt;
|
||||
|
||||
// Disable watchdog timers
|
||||
rtc.swd.disable();
|
||||
rtc.rwdt.disable();
|
||||
wdt0.disable();
|
||||
wdt1.disable();
|
||||
|
||||
let mut usb_serial =
|
||||
UsbSerialJtag::new(peripherals.USB_DEVICE, &mut system.peripheral_clock_control);
|
||||
|
||||
usb_serial.listen_rx_packet_recv_interrupt();
|
||||
|
||||
timer0.start(1u64.secs());
|
||||
|
||||
critical_section::with(|cs| USB_SERIAL.borrow_ref_mut(cs).replace(usb_serial));
|
||||
|
||||
interrupt::enable(peripherals::Interrupt::USB, interrupt::Priority::Priority1).unwrap();
|
||||
|
||||
interrupt::set_kind(
|
||||
Cpu::ProCpu,
|
||||
interrupt::CpuInterrupt::Interrupt1,
|
||||
interrupt::InterruptKind::Edge,
|
||||
);
|
||||
|
||||
unsafe {
|
||||
riscv::interrupt::enable();
|
||||
}
|
||||
|
||||
loop {
|
||||
critical_section::with(|cs| {
|
||||
writeln!(
|
||||
USB_SERIAL.borrow_ref_mut(cs).as_mut().unwrap(),
|
||||
"Hello world!"
|
||||
)
|
||||
.ok();
|
||||
});
|
||||
|
||||
block!(timer0.wait()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn USB() {
|
||||
critical_section::with(|cs| {
|
||||
let mut usb_serial = USB_SERIAL.borrow_ref_mut(cs);
|
||||
let usb_serial = usb_serial.as_mut().unwrap();
|
||||
writeln!(usb_serial, "USB serial interrupt").unwrap();
|
||||
while let nb::Result::Ok(c) = usb_serial.read_byte() {
|
||||
writeln!(usb_serial, "Read byte: {:02x}", c).unwrap();
|
||||
}
|
||||
usb_serial.reset_rx_packet_recv_interrupt();
|
||||
});
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user