led fader migrated to esp-hal 1.0.0-beta

This commit is contained in:
ImplFerris 2025-03-14 18:50:15 +05:30
parent 7c9bb78edf
commit aa4a74660f
5 changed files with 130 additions and 90 deletions

View File

@ -34,9 +34,9 @@ cargo install esp-generate
If you want to follow the code exactly as it is in this project, install this esp-generate version used for generating the examples:
```sh
cargo install esp-generate@0.2.1
cargo install esp-generate@0.3.1
```
The related rust toolchain for this version is 1.82.0
The related rust toolchain for this version is 1.84.0
### Creating project with `esp-generate`
@ -59,7 +59,7 @@ espup install
If you want to use the project I created as it is, you might need the exact Rust toolchain version. You can use this command:
```sh
espup install --toolchain-version 1.82.0
espup install --toolchain-version 1.84.0
```
**NOTE:** Install this specific version **only** if you plan to clone and run the project examples exactly as they are. Using a mismatched version may lead to weird errors (example error: asm! macro is not allowed in naked functions)

View File

@ -16,7 +16,7 @@ To start the project, use the `esp-generate` command. Run the following:
esp-generate --chip esp32 blinky-embassy
```
This will open a screen asking you to select options. But, this time we select "Adds `embassy` framework support" and save it to generate the project template with support of embassy.
This will open a screen prompting you to select options. This time, choose "Adds embassy framework support" and save to generate the project template with Embassy support. However, if you find that the "embassy" option is unavailable, first enable "Enable unstable HAL features", then proceed with selecting "embassy" support.
If you notice, the main function is now marked as async, along with a few other changes in the code. However, the core logic for blinking the LED remains the same.
@ -27,37 +27,34 @@ If you notice, the main function is now marked as async, along with a few other
#![no_main]
use embassy_executor::Spawner;
use embassy_time::Timer;
use esp_backtrace as _;
use esp_hal::{
gpio::{Io, Level, Output},
prelude::*,
};
use log::info;
use embassy_time::{Duration, Timer};
use esp_hal::clock::CpuClock;
use esp_hal::gpio::{Level, Output, OutputConfig};
use esp_hal::timer::timg::TimerGroup;
#[main]
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[esp_hal_embassy::main]
async fn main(_spawner: Spawner) {
let peripherals = esp_hal::init({
let mut config = esp_hal::Config::default();
config.cpu_clock = CpuClock::max();
config
});
// generator version: 0.3.1
esp_println::logger::init_logger_from_env();
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
let timg0 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG0);
esp_hal_embassy::init(timg0.timer0);
info!("Embassy initialized!");
let timer0 = TimerGroup::new(peripherals.TIMG1);
esp_hal_embassy::init(timer0.timer0);
let mut led = Output::new(peripherals.GPIO2, Level::High, OutputConfig::default());
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let mut led = Output::new(io.pins.gpio2, Level::High);
loop {
led.set_high();
Timer::after_millis(500).await;
led.set_low();
Timer::after_millis(500).await;
led.toggle();
Timer::after(Duration::from_secs(1)).await;
}
// for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0-beta.0/examples/src/bin
}
```

View File

@ -27,3 +27,7 @@ You have two options:
- You can check the nightly version used in this book's projects [here](./dev-env.md#toolchains-for-risc-v-and-xtensa-targets).
- Install the matching version to ensure compatibility.
### 4. I am getting import error while following the instructions?
Your code editor should typically assist with imports. However, in some cases, it might not work as expected. You can always cross-check your code with the "full code" section or clone the project to compare and add any missing imports.

View File

@ -12,18 +12,33 @@ To create the project, use the `esp-generate` command. Run the following:
esp-generate --chip esp32 led-fader
```
This will open a screen asking you to select options. For now, we dont need to select any options. Just save it by pressing "s" in the keyboard.
This will open a screen asking you to select options. For now, we dont need to select any options. In the latest esp-hal, ledc requires us to enable the unstable features.
Let's start by initializing the peripherals with the default configuration. This function configures the CPU clock and watchdog, and then returns the instance of the peripherals.
- So you select the option "Enable unstable HAL features."
Then save it by pressing "s" in the keyboard.
<div class="alert-box alert-box-info">
<span class="icon"><i class="fa fa-info"></i></span>
<div class="alert-content">
<b class="alert-title">Imports</b>
<p>In the explanation, I won't include the required imports since they aren't particularly interesting or need much explanation. You can always refer to the "Full Code" section below or clone the project to cross-check.</p>
</div>
</div>
## Auto generated code
When you generate a project with esp-generate, it sets up the basic structure, configures the CPU clock, and includes boilerplate code for peripherals, so you don't have to type these out every time. In this book, we will always create projects using esp-generate and build on top of that.
```rust
let peripherals = esp_hal::init({
let mut config = esp_hal::Config::default();
config.cpu_clock = CpuClock::max();
config
});
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
```
## LED Pin
Next, we take our desired GPIO from the peripherals instance. In this case, we're turning on the onboard LED of the Devkit, which is connected to GPIO 2.
```rust
@ -46,25 +61,28 @@ let mut lstimer0 = ledc.timer::<LowSpeed>(timer::Number::Timer0);
We need to do a few more configurations before using the timer. We'll set the frequency to 24 kHz. For this frequency with the APB clock, the formula gives a maximum resolution of 12 bits and a minimum resolution of 2 bits. In the esp-hal, a 5-bit PWM resolution is used for this frequency, and we will use the same.
```rust
lstimer0.configure(timer::config::Config {
duty: timer::config::Duty::Duty5Bit,
clock_source: timer::LSClockSource::APBClk,
frequency: 24.kHz(),
})
.unwrap();
lstimer0
.configure(timer::config::Config {
duty: timer::config::Duty::Duty5Bit,
clock_source: timer::LSClockSource::APBClk,
frequency: Rate::from_khz(24),
})
.unwrap();
```
### PWM Channels
Next, we configure the PWM channel. We'll use channel0 and set it up with the selected timer and initial duty percentage "10%". Additionally, we'll set the pin configuration as PushPull.
```rust
let mut channel0 = ledc.channel(channel::Number::Channel0, led);
channel0.configure(channel::config::Config {
timer: &lstimer0,
duty_pct: 10,
pin_config: channel::config::PinConfig::PushPull,
})
.unwrap();
channel0
.configure(channel::config::Config {
timer: &lstimer0,
duty_pct: 10,
pin_config: channel::config::PinConfig::PushPull,
})
.unwrap();
```
### Fading
@ -75,7 +93,7 @@ The esp-hal has a function called start_duty_fade, which makes our job easier. O
channel0.start_duty_fade(0, 100, 1000).unwrap();
```
We will run this in a loop and use another function provided by the HAL, is_duty_fade_running; It returns boolean value whether the duty fade is complete or not.
We will run this in a loop and use another function provided by the HAL, `is_duty_fade_running`; It returns boolean value whether the duty fade is complete or not.
```rust
while channel0.is_duty_fade_running() {}
@ -87,36 +105,36 @@ while channel0.is_duty_fade_running() {}
#![no_std]
#![no_main]
use esp_backtrace as _;
use esp_hal::{
ledc::{
channel::{self, ChannelIFace},
timer::{self, TimerIFace},
LSGlobalClkSource, Ledc, LowSpeed,
},
prelude::*,
};
use esp_hal::clock::CpuClock;
use esp_hal::ledc::channel::ChannelIFace;
use esp_hal::ledc::timer::TimerIFace;
use esp_hal::ledc::{channel, timer, LSGlobalClkSource, Ledc, LowSpeed};
use esp_hal::main;
use esp_hal::time::Rate;
#[entry]
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[main]
fn main() -> ! {
let peripherals = esp_hal::init({
let mut config = esp_hal::Config::default();
config.cpu_clock = CpuClock::max();
config
});
// generator version: 0.3.1
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
let led = peripherals.GPIO2;
// let led = peripherals.GPIO5;
let mut ledc = Ledc::new(peripherals.LEDC);
ledc.set_global_slow_clock(LSGlobalClkSource::APBClk);
let mut lstimer0 = ledc.timer::<LowSpeed>(timer::Number::Timer0);
lstimer0
.configure(timer::config::Config {
duty: timer::config::Duty::Duty5Bit,
clock_source: timer::LSClockSource::APBClk,
frequency: 24.kHz(),
frequency: Rate::from_khz(24),
})
.unwrap();
@ -136,6 +154,7 @@ fn main() -> ! {
while channel0.is_duty_fade_running() {}
}
}
```

View File

@ -26,33 +26,45 @@ Open the src/bin/main.rs file. It will contain a simple "Hello, World" code. We
This code creates a blinking effect by toggling an LED connected to a GPIO pin between high and low states.
#### Import Required Module
### Import Required Module
Additional import we need to set the LED as output pin
```rust
use esp_hal::gpio::{Io, Level, Output};
```
#### Initialize ESP HAL and Delay
Set up the ESP HAL and configure a delay
### Initialize ESP HAL peripherals
This code is already generated by the template. You have to change the "_peripherals" variable name to "peripherals".
```rust
let peripherals = esp_hal::init(esp_hal::Config::default());
let delay = Delay::new();
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
```
Then lets set the LED GPIO pin "GPIO2" as an output pin with an initial state "High"(LED is turned on):
## Setup Output
Then lets set the LED GPIO pin "GPIO2" as an output pin with an initial state "High"(LED is turned on). The GPIO2 is the pin for the onboard LED.
```rust
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let mut led = Output::new(io.pins.gpio2, Level::High);
let mut led = Output::new(peripherals.GPIO2, Level::High, OutputConfig::default());
```
#### Blinking Loop
## Helper function for delay
Let's write a small function to introduce a blocking delay that pauses execution for a specified duration.
```rust
fn blocking_delay(duration: Duration) {
let delay_start = Instant::now();
while delay_start.elapsed() < duration {}
}
```
### Blinking Loop
Create a loop to toggle the LED state(between High and Low).
```rust
loop {
led.toggle();
delay.delay_millis(500);
led.toggle();
delay.delay_millis(500);
blocking_delay(Duration::from_millis(500));
}
```
@ -61,27 +73,35 @@ loop {
#![no_std]
#![no_main]
use esp_hal::delay::Delay;
use esp_hal::prelude::*;
use {esp_backtrace as _};
use esp_hal::clock::CpuClock;
use esp_hal::gpio::{Level, Output, OutputConfig};
use esp_hal::main;
use esp_hal::time::{Duration, Instant};
use esp_hal::gpio::{Io, Level, Output};
#[entry]
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[main]
fn main() -> ! {
#[allow(unused)]
let peripherals = esp_hal::init(esp_hal::Config::default());
let delay = Delay::new();
// generator version: 0.3.1
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let mut led = Output::new(io.pins.gpio2, Level::High);
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
let mut led = Output::new(peripherals.GPIO2, Level::High, OutputConfig::default());
loop {
led.toggle();
delay.delay_millis(500);
led.toggle();
delay.delay_millis(500);
blocking_delay(Duration::from_millis(500));
}
}
fn blocking_delay(duration: Duration) {
let delay_start = Instant::now();
while delay_start.elapsed() < duration {}
}
```
## Flash - `Run Rust Run`