Implement ESPHome dimmer

This commit is contained in:
Jakob Lechner 2025-08-20 11:01:41 +02:00
parent 57f213a5f0
commit 179279df79
3 changed files with 48 additions and 38 deletions

2
Cargo.lock generated
View file

@ -42,7 +42,7 @@ dependencies = [
[[package]] [[package]]
name = "ch32-hal" name = "ch32-hal"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/paval-shlyk/ch32-hal?rev=ace32859924ab0d5e411521a8f392df01ce262ff#ace32859924ab0d5e411521a8f392df01ce262ff" source = "git+https://github.com/paval-shlyk/ch32-hal?rev=f9490337b9c5c97b480e5a7274ff01264da7e1ee#f9490337b9c5c97b480e5a7274ff01264da7e1ee"
dependencies = [ dependencies = [
"ch32-metapac", "ch32-metapac",
"critical-section", "critical-section",

View file

@ -12,7 +12,7 @@ bench = false
panic-halt = "1.0.0" panic-halt = "1.0.0"
# https://github.com/ch32-rs/ch32-hal/pull/75 # https://github.com/ch32-rs/ch32-hal/pull/75
ch32-hal = {git = "https://github.com/paval-shlyk/ch32-hal", rev="ace32859924ab0d5e411521a8f392df01ce262ff", features = [ ch32-hal = {git = "https://github.com/paval-shlyk/ch32-hal", rev="f9490337b9c5c97b480e5a7274ff01264da7e1ee", features = [
"ch32v203f6p6", "ch32v203f6p6",
"time-driver-tim1", "time-driver-tim1",
]} ]}

View file

@ -4,21 +4,37 @@
#![feature(impl_trait_in_assoc_type)] #![feature(impl_trait_in_assoc_type)]
use ch32_hal as hal; use ch32_hal as hal;
use hal::gpio::{Input, Pull};
use hal::println; use hal::println;
use hal::time::Hertz; use hal::time::Hertz;
use hal::timer::low_level::CountingMode; use hal::timer::low_level::CountingMode;
use hal::timer::simple_pwm::{PwmPin, SimplePwm}; use hal::timer::simple_pwm::{PwmPin, SimplePwm};
use hal::can::{Can, CanFifo, CanFilter, CanFrame, CanMode, StandardId}; use hal::can::{Can, CanFifo, CanFilter, CanMode};
use qingke::riscv; use embedded_can::blocking::Can as _;
use embedded_can::nb::Can as _;
#[qingke_rt::entry] #[qingke_rt::entry]
fn main() -> ! { fn main() -> ! {
hal::debug::SDIPrint::enable(); hal::debug::SDIPrint::enable();
let p = hal::init(hal::Config::default()); let p = hal::init(hal::Config::default());
let j1 = Input::new(p.PA0, Pull::Up);
let j2 = Input::new(p.PA4, Pull::Up);
let j3 = Input::new(p.PA5, Pull::Up);
let j4 = Input::new(p.PB1, Pull::Up);
let mut addr: u16 = 0;
if j1.is_low() { addr |= 1; }
if j2.is_low() { addr |= 2; }
if j3.is_low() { addr |= 4; }
if j4.is_low() { addr |= 8; }
let base_id: u16 = 0x180;
let node_id: u16 = base_id + addr;
println!("CAN Node ID: 0x{:03X}", node_id);
println!("setting up can"); println!("setting up can");
let mut can = Can::new(p.CAN1, p.PA11, p.PA12, CanFifo::Fifo1, CanMode::Normal, 500_000).expect("Valid"); let mut can = Can::new_blocking(p.CAN1, p.PA11, p.PA12, CanFifo::Fifo0, CanMode::Normal, 500_000, Default::default()).expect("Valid");
can.add_filter(CanFilter::accept_all()); can.add_filter(CanFilter::accept_all());
println!("setting up pwm"); println!("setting up pwm");
@ -58,7 +74,6 @@ fn main() -> ! {
); );
let (ch_cw, ch_ww) = (hal::timer::Channel::Ch1, hal::timer::Channel::Ch2); let (ch_cw, ch_ww) = (hal::timer::Channel::Ch1, hal::timer::Channel::Ch2);
let _max_duty = pwm_w.get_max_duty();
pwm_w.set_duty(ch_ww, 0); pwm_w.set_duty(ch_ww, 0);
pwm_w.enable(ch_ww); pwm_w.enable(ch_ww);
@ -66,40 +81,35 @@ fn main() -> ! {
pwm_w.enable(ch_cw); pwm_w.enable(ch_cw);
println!("entering main loop"); println!("entering main loop");
let msg: [u8; 3] = [0xAB, 0xCD, 0xEF];
let delay = 100_000;
loop { loop {
let frame = CanFrame::new(StandardId::new(0x42).unwrap(), &msg).unwrap();
match can.transmit(&frame) {
Ok(_) => println!("Sent CAN message {:?}", msg),
Err(_) => println!("Error sending CAN message"),
};
let _ = can.transmit(&frame);
println!("-");
match can.receive() { match can.receive() {
Err(err) => println!("Receive error: {:?}", err), Ok(recv_msg) => {
Ok(recv_msg) => println!("Received: {:?}", recv_msg), if let embedded_can::Id::Standard(std_id) = recv_msg.id() {
} if std_id.as_raw() == node_id {
let data = recv_msg.data();
if data.len() >= 5 {
let channel = data[0];
println!("."); let mut fbytes = [0u8; 4];
fbytes.copy_from_slice(&data[1..5]);
let value = f32::from_le_bytes(fbytes).clamp(0.0, 1.0);
for x in 0..100 { let duty = (value * pwm_w.get_max_duty() as f32) as u32;
pwm_w.set_duty(ch_cw, x*8);
riscv::asm::delay(delay); match channel {
0 => { pwm_w.set_duty(ch_cw, duty); println!("CW -> {}", duty); }
1 => { pwm_w.set_duty(ch_ww, duty); println!("WW -> {}", duty); }
2 => { pwm_rgb.set_duty(ch_r, duty); println!("R -> {}", duty); }
3 => { pwm_rgb.set_duty(ch_g, duty); println!("G -> {}", duty); }
4 => { pwm_rgb.set_duty(ch_b, duty); println!("B -> {}", duty); }
_ => println!("Unknown channel {}", channel),
} }
for x in 0..100 {
pwm_w.set_duty(ch_cw, (100-x)*8);
riscv::asm::delay(delay);
} }
for x in 0..100 {
pwm_w.set_duty(ch_ww, x*8);
riscv::asm::delay(delay);
} }
for x in 0..100 { }
pwm_w.set_duty(ch_ww, (100-x)*8); }
riscv::asm::delay(delay); Err(err) => println!("CAN error: {:?}", err),
} }
} }
} }