diff --git a/Cargo.lock b/Cargo.lock index 0b943b1..dad7dbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -749,6 +749,7 @@ dependencies = [ "esp-bootloader-esp-idf", "esp-hal", "esp-wifi", + "libm", "panic-rtt-target", "rtt-target", "smoltcp", @@ -925,6 +926,12 @@ dependencies = [ "syn", ] +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + [[package]] name = "linked_list_allocator" version = "0.10.5" diff --git a/Cargo.toml b/Cargo.toml index 462fc71..a4d62f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ path = "./src/bin/main.rs" [dependencies] defmt = "1.0.1" +libm = "0.2" esp-bootloader-esp-idf = { version = "0.2.0", features = ["esp32c6"] } esp-hal = { version = "=1.0.0-rc.0", features = [ "defmt", diff --git a/src/bin/main.rs b/src/bin/main.rs index 8c68063..3e4882f 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -9,20 +9,29 @@ use defmt::info; use esp_hal::clock::CpuClock; use esp_hal::delay::Delay; -use esp_hal::gpio::{Level, Output, OutputConfig}; +use esp_hal::ledc::{ + channel::{self, config::PinConfig, ChannelIFace}, + timer::{self, config::Duty, LSClockSource, TimerIFace}, + LSGlobalClkSource, Ledc, LowSpeed, +}; use esp_hal::main; +use esp_hal::time::Rate; use esp_hal::timer::timg::TimerGroup; use panic_rtt_target as _; extern crate alloc; -// This creates a default app-descriptor required by the esp-idf bootloader. -// For more information see: +use core::f32::consts::PI; + esp_bootloader_esp_idf::esp_app_desc!(); +fn calculate_sine_brightness(angle: f32) -> f32 { + let sine_value = libm::sinf(angle); + (sine_value + 1.0) / 2.0 +} + #[main] fn main() -> ! { - // generator version: 0.5.0 rtt_target::rtt_init_defmt!(); @@ -33,25 +42,68 @@ fn main() -> ! { let timg0 = TimerGroup::new(peripherals.TIMG0); let _init = esp_wifi::init(timg0.timer0, esp_hal::rng::Rng::new(peripherals.RNG)).unwrap(); - - let mut led = Output::new(peripherals.GPIO15, Level::Low, OutputConfig::default()); - // Initialize delay + let mut ledc = Ledc::new(peripherals.LEDC); + ledc.set_global_slow_clock(LSGlobalClkSource::APBClk); + + let mut lstimer0 = ledc.timer::(timer::Number::Timer0); + lstimer0 + .configure(timer::config::Config { + duty: Duty::Duty8Bit, + clock_source: LSClockSource::APBClk, + frequency: Rate::from_hz(1000), + }) + .unwrap(); + + let mut channels = [ + ledc.channel(channel::Number::Channel0, peripherals.GPIO1), + ledc.channel(channel::Number::Channel1, peripherals.GPIO18), + ledc.channel(channel::Number::Channel2, peripherals.GPIO9), + ledc.channel(channel::Number::Channel3, peripherals.GPIO19), + ledc.channel(channel::Number::Channel4, peripherals.GPIO20), + ledc.channel(channel::Number::Channel5, peripherals.GPIO21), + ]; + + for channel in channels.iter_mut() { + channel + .configure(channel::config::Config { + timer: &lstimer0, + duty_pct: 0, + pin_config: PinConfig::PushPull, + }) + .unwrap(); + } + let delay = Delay::new(); - info!("Starting LED blink program on GPIO15..."); + let mut angle: f32 = 0.0; + let cycle_duration_ms = 1000; + let steps_per_cycle = (cycle_duration_ms / 20) as u32; + let angle_step = (2.0 * PI) / steps_per_cycle as f32; + + info!("Starting smooth sine wave LED brightness control (1 second cycle)..."); loop { - // Turn LED on - led.set_high(); - info!("LED ON"); - delay.delay_millis(1000); - - // Turn LED off - led.set_low(); - info!("LED OFF"); - delay.delay_millis(1000); + for (i, channel) in channels.iter_mut().enumerate() { + let phase_offset = (i as f32) * (2.0 * PI) / 6.0; + let led_angle = angle + phase_offset; + + let brightness = calculate_sine_brightness(led_angle); + let duty_pct = (brightness * 100.0) as u8; + + channel.set_duty(duty_pct).unwrap(); + + if i == 0 { + info!("Base angle: {}, LED 0 brightness: {}%", angle, duty_pct); + } + } + + delay.delay_millis(20); + + angle += angle_step; + if angle >= 2.0 * PI { + angle = 0.0; + } } - - // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0-rc.0/examples/src/bin + }