From 36dc52f464b0e1cbb92a6e389cb26616866a77a9 Mon Sep 17 00:00:00 2001 From: Philipp_EndevourOS Date: Wed, 13 Aug 2025 00:55:25 +0200 Subject: [PATCH] try to control LED with SmartLED and RMT --- Cargo.lock | 54 ++++++++++++++++++ Cargo.toml | 6 ++ src/init/hardware.rs | 128 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 168 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06f0f40..542fbfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -578,6 +578,19 @@ dependencies = [ "embedded-nal", ] +[[package]] +name = "embedded-sdmmc-dev" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceec3a654b00a4acf9e2788d72b66fc3ba86d91b834586a4ed576324e351e38b" +dependencies = [ + "byteorder", + "embedded-hal 1.0.0", + "embedded-io", + "heapless", + "log", +] + [[package]] name = "embedded-storage" version = "0.3.1" @@ -761,6 +774,16 @@ dependencies = [ "termcolor", ] +[[package]] +name = "esp-hal-smartled" +version = "0.16.0" +source = "git+https://github.com/esp-rs/esp-hal-community.git?branch=main#bbe8484a013267132cd3fb4693606de2c8317a53" +dependencies = [ + "document-features", + "esp-hal", + "smart-leds-trait", +] + [[package]] name = "esp-metadata" version = "0.8.0" @@ -1025,17 +1048,21 @@ dependencies = [ "embassy-net", "embassy-sync 0.7.0", "embassy-time", + "embedded-hal 1.0.0", "embedded-io", "embedded-io-async", + "embedded-sdmmc-dev", "esp-alloc", "esp-bootloader-esp-idf", "esp-hal", "esp-hal-embassy", + "esp-hal-smartled", "esp-println", "esp-wifi", "heapless", "log", "picoserve", + "smart-leds", "smoltcp", "static_cell", ] @@ -1521,6 +1548,15 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +[[package]] +name = "rgb" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" +dependencies = [ + "bytemuck", +] + [[package]] name = "riscv" version = "0.12.1" @@ -1642,6 +1678,24 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "smart-leds" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66df34e571fa9993fa6f99131a374d58ca3d694b75f9baac93458fe0d6057bf0" +dependencies = [ + "smart-leds-trait", +] + +[[package]] +name = "smart-leds-trait" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edeb89c73244414bb0568611690dd095b2358b3fda5bae65ad784806cca00157" +dependencies = [ + "rgb", +] + [[package]] name = "smoltcp" version = "0.12.0" diff --git a/Cargo.toml b/Cargo.toml index 6dd583d..f40d8f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ embassy-net = { version = "0.7.0", features = [ "tcp", "udp", ] } +embedded-hal = "=1.0.0" embedded-io = "0.6.1" embedded-io-async = "0.6.1" esp-alloc = "0.8.0" @@ -63,6 +64,11 @@ embassy-sync = { version = "0.7.0", features = ["log"] } ds3231 = { version = "0.3.0", features = ["async", "temperature_f32"] } chrono = { version = "0.4.41", default-features = false } dir-embed = "0.3.0" +embedded-sdmmc-dev = "0.8.2" + +esp-hal-smartled = { git = "https://github.com/esp-rs/esp-hal-community.git", package = "esp-hal-smartled", branch = "main", features = ["esp32c6"]} +smart-leds = "0.4.0" + [profile.dev] # Rust debug is too slow. diff --git a/src/init/hardware.rs b/src/init/hardware.rs index 8b6dadc..ddba834 100644 --- a/src/init/hardware.rs +++ b/src/init/hardware.rs @@ -1,24 +1,36 @@ use embassy_executor::Spawner; -use embassy_net::{Stack, driver}; -use embassy_sync::blocking_mutex::Mutex; -use embassy_sync::blocking_mutex::raw::NoopRawMutex; -use esp_hal::gpio::{Input, Pull}; +use embassy_net::Stack; +use embassy_time::Duration; +use embedded_sdmmc_dev::SdCard; use esp_hal::i2c::master::Config; use esp_hal::peripherals::{ - self, GPIO0, GPIO1, GPIO2, GPIO21, GPIO22, GPIO23, GPIO16, GPIO17, GPIO20, GPIO10, GPIO19, GPIO6, GPIO7, I2C0, - UART1, + self, GPIO0, GPIO1, GPIO2, GPIO10, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, + GPIO23, I2C0, RMT, SPI2, UART1, }; -use esp_hal::spi::master::Spi; -use esp_hal::spi::master::Config as Spi_config; +use esp_hal::rmt::{ConstChannelAccess, Rmt, Tx}; +use esp_hal::spi::{ + Mode, + master::{Config as Spi_config, Spi}, +}; + use esp_hal::time::Rate; +use esp_hal::timer::timg::TimerGroup; use esp_hal::{ Async, clock::CpuClock, gpio::{Output, OutputConfig}, i2c::master::I2c, - timer::{systimer::SystemTimer, timg::TimerGroup}, + timer::systimer::SystemTimer, uart::Uart, }; + +use esp_hal_smartled::{SmartLedsAdapterAsync, buffer_size_async}; + +use smart_leds::{ + RGB8, SmartLedsWriteAsync, brightness, gamma, + hsv::{Hsv, hsv2rgb}, +}; + use esp_println::logger::init_logger; use log::{debug, error}; @@ -39,7 +51,7 @@ use crate::init::wifi; * D8 -> GPIO19 -> SPI/SCLK * D9 -> GPIO20 -> SPI/MISO * D10 -> GPIO10 -> SPI/MOSI - * + * *************************************************/ #[panic_handler] @@ -83,20 +95,54 @@ pub async fn hardware_init( let i2c_device = setup_i2c(peripherals.I2C0, peripherals.GPIO22, peripherals.GPIO23); + let spi_device = setup_spi( + peripherals.SPI2, + peripherals.GPIO19, + peripherals.GPIO20, + peripherals.GPIO18, + peripherals.GPIO2, + ); + + let sd_card = setup_sdcard(spi_device); + let buzzer_gpio = peripherals.GPIO21; - - let spi = match Spi::new(peripherals.SPI2 , Spi_config::default()) { - Ok(spi) => spi.with_mosi(peripherals.GPIO18).with_miso(peripherals.GPIO20), - Err(e) => { - error!("Failed to initialize I2C: {:?}", e); - panic!(); //TODO panic! - - } - }; + let mut led = setup_led(peripherals.RMT, peripherals.GPIO1); debug!("hardware init done"); + let mut color = Hsv { + hue: 162, + sat: 226, + val: 10, + }; + + let mut data: RGB8; + let level = 100; + + + let pixel: RGB8 = RGB8 { r: 0, g: 100, b: 0 }; + + for hue in 0..=255 { + color.hue = hue; + // Convert from the HSV color space (where we can easily transition from one + // color to the other) to the RGB color space that we can then send to the LED + data = hsv2rgb(color); + // When sending to the LED, we do a gamma correction first (see smart_leds + // documentation for details) and then limit the brightness to 10 out of 255 so + // that the output is not too bright. + led.write(pixel.iter()) + .await + .expect("failed to write LED data"); + + + // for i in 0..64 { + // debug!("iterator {}", i); + // led.write(pixel) + // } + + } + (uart_device, stack, i2c_device, buzzer_gpio) } @@ -140,6 +186,29 @@ fn setup_i2c( i2c } +fn setup_spi( + spi2: SPI2<'static>, + sck: GPIO19<'static>, + miso: GPIO20<'static>, + mosi: GPIO18<'static>, + cs: GPIO2<'static>, +) -> Spi<'static, Async> { + let spi = match Spi::new(spi2, Spi_config::default()) { + Ok(spi) => spi + .with_sck(sck) + .with_miso(miso) + .with_mosi(mosi) + .with_cs(cs) + .into_async(), + Err(e) => panic!("Failed to initialize SPI: {:?}", e), + }; + spi +} + +fn setup_sdcard(spi_device: Spi<'static, Async>) { + //let sdcard = SdCard::new(spi_device as embedded_hal::spi::SpiDevice(), delayer) +} + pub fn setup_buzzer(buzzer_gpio: GPIO21<'static>) -> Output<'static> { let config = esp_hal::gpio::OutputConfig::default() .with_drive_strength(esp_hal::gpio::DriveStrength::_40mA); @@ -148,4 +217,23 @@ pub fn setup_buzzer(buzzer_gpio: GPIO21<'static>) -> Output<'static> { buzzer } -fn setup_spi_led() {} +fn setup_led( + rmt: RMT<'static>, + led_gpio: GPIO1<'static>, +) -> SmartLedsAdapterAsync, 1600> { + debug!("setup led"); + let rmt: Rmt<'_, esp_hal::Async> = { + let frequency: Rate = Rate::from_mhz(80); + Rmt::new(rmt, frequency) + } + .expect("Failed to initialize RMT") + .into_async(); + + let rmt_channel = rmt.channel0; + let rmt_buffer = [0_u32; buffer_size_async(64)]; + + let mut led: SmartLedsAdapterAsync<_, 1600> = + SmartLedsAdapterAsync::new(rmt_channel, led_gpio, rmt_buffer); + + led +}