From e3235b34a4ec52267c61a5741eb75a6c7e205edf Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 16 Aug 2025 21:40:39 -0600 Subject: [PATCH] initial demo --- ch32v-insert-coin/ext/adpcm-pwm-dac | 2 +- .../src/insert_coin/insert_coin.rs | 6 +- ch32v-insert-coin/src/insert_coin/mod.rs | 2 +- .../src/insert_coin/services/led.rs | 22 ++- .../src/insert_coin/services/mod.rs | 2 +- .../src/insert_coin/services/services.rs | 8 +- .../src/insert_coin/services/tick_timer.rs | 28 +++- ch32v-insert-coin/src/main.rs | 148 +++++++++++++++--- 8 files changed, 167 insertions(+), 51 deletions(-) diff --git a/ch32v-insert-coin/ext/adpcm-pwm-dac b/ch32v-insert-coin/ext/adpcm-pwm-dac index c8d33b3..ba25b7c 160000 --- a/ch32v-insert-coin/ext/adpcm-pwm-dac +++ b/ch32v-insert-coin/ext/adpcm-pwm-dac @@ -1 +1 @@ -Subproject commit c8d33b3c41bf4b53ff76837a9557f7960f508df5 +Subproject commit ba25b7c89f4deb52426d97fd35eb13496f183775 diff --git a/ch32v-insert-coin/src/insert_coin/insert_coin.rs b/ch32v-insert-coin/src/insert_coin/insert_coin.rs index 6487029..fe69780 100644 --- a/ch32v-insert-coin/src/insert_coin/insert_coin.rs +++ b/ch32v-insert-coin/src/insert_coin/insert_coin.rs @@ -4,7 +4,7 @@ use ch32_hal::timer::simple_pwm::SimplePwm; use ch32_hal::timer::Channel; use ch32_hal::delay::Delay; -use crate::insert_coin::services::{DacService, LedService, TickService, TickServiceData}; +use crate::insert_coin::services::{DacService, LedService, TickService, TickServiceData, Service}; // static mut led0_index: usize = 0; @@ -122,8 +122,6 @@ impl<'a, T: GeneralInstance16bit> InsertCoin<'a, T> { pub fn service(&mut self) { if self.is_active() { - self.led0.tick(); - self.led1.tick(); self.dac.tick(); @@ -159,8 +157,6 @@ impl<'a, T: GeneralInstance16bit> InsertCoin<'a, T> { let led1_dcs = [0u8, 25u8, 50u8, 75u8, 100u8]; loop { - self.led0.tick(); - self.led1.tick(); self.dac.tick(); diff --git a/ch32v-insert-coin/src/insert_coin/mod.rs b/ch32v-insert-coin/src/insert_coin/mod.rs index c97fd60..e13b953 100644 --- a/ch32v-insert-coin/src/insert_coin/mod.rs +++ b/ch32v-insert-coin/src/insert_coin/mod.rs @@ -4,5 +4,5 @@ use services::LedService; pub use services::TickTimerService; -pub use services::{TickService, TickServiceData}; +pub use services::{TickService, TickServiceData, Service}; pub use insert_coin::{InsertCoin, CoreConfig, SimplePwmCore}; \ No newline at end of file diff --git a/ch32v-insert-coin/src/insert_coin/services/led.rs b/ch32v-insert-coin/src/insert_coin/services/led.rs index b11e9d8..d248ab6 100644 --- a/ch32v-insert-coin/src/insert_coin/services/led.rs +++ b/ch32v-insert-coin/src/insert_coin/services/led.rs @@ -1,9 +1,10 @@ use ch32_hal::timer::Channel; -use crate::insert_coin::services::{TickServiceData, TickService}; +use crate::insert_coin::services::{Service, TickService, TickServiceData}; pub struct LedService { - service_data: core::cell::RefCell, + // need_service: core::cell::RefCell, + need_service: bool, pub channel: Channel, pub amplitude: u8, } @@ -11,7 +12,8 @@ pub struct LedService { impl LedService { pub fn new(channel: Channel, service_data: TickServiceData) -> Self { Self { - service_data: core::cell::RefCell::new(service_data), + // service_data: core::cell::RefCell::new(service_data), + need_service: false, channel, amplitude: 0, } @@ -19,23 +21,19 @@ impl LedService { pub fn set_amplitude(&mut self, amplitude: u8) { self.amplitude = amplitude; + self.need_service = true; } } -impl TickService for LedService { - fn tick(&self) { - let mut tc = self.service_data.borrow_mut(); - tc.ticks_remaining = tc.ticks_remaining.saturating_sub(1); - } +impl Service for LedService { fn need_service(&self) -> bool { - self.service_data.borrow().ticks_remaining == 0 + self.need_service } - fn service(&self) { - let mut tc = self.service_data.borrow_mut(); - tc.ticks_remaining = tc.ticks_per_service; + fn service(&mut self) { + self.need_service = false; } } diff --git a/ch32v-insert-coin/src/insert_coin/services/mod.rs b/ch32v-insert-coin/src/insert_coin/services/mod.rs index 730c651..a761548 100644 --- a/ch32v-insert-coin/src/insert_coin/services/mod.rs +++ b/ch32v-insert-coin/src/insert_coin/services/mod.rs @@ -1,5 +1,5 @@ mod services; -pub use services::{TickService, TickServiceData}; +pub use services::{TickService, TickServiceData, Service}; mod led; pub use led::LedService; diff --git a/ch32v-insert-coin/src/insert_coin/services/services.rs b/ch32v-insert-coin/src/insert_coin/services/services.rs index 45e0ac0..e2c86e2 100644 --- a/ch32v-insert-coin/src/insert_coin/services/services.rs +++ b/ch32v-insert-coin/src/insert_coin/services/services.rs @@ -7,7 +7,7 @@ impl TickServiceData { pub fn new(ticks_per_service: usize) -> Self { Self { ticks_per_service, - ticks_remaining: 0, + ticks_remaining: ticks_per_service, } } } @@ -23,3 +23,9 @@ pub trait TickService { /// the service needs to be serviced here fn service(&self); } + + +pub trait Service { + fn need_service(&self) -> bool; + fn service(&mut self); +} \ No newline at end of file diff --git a/ch32v-insert-coin/src/insert_coin/services/tick_timer.rs b/ch32v-insert-coin/src/insert_coin/services/tick_timer.rs index c740c6b..90e0188 100644 --- a/ch32v-insert-coin/src/insert_coin/services/tick_timer.rs +++ b/ch32v-insert-coin/src/insert_coin/services/tick_timer.rs @@ -4,25 +4,45 @@ use crate::insert_coin::services::{TickServiceData, TickService}; pub struct TickTimerService { service_data: core::cell::RefCell, + auto_reset: bool, + enabled: bool, } impl TickTimerService { - pub fn new(service_data: TickServiceData) -> Self { + pub fn new(service_data: TickServiceData, auto_reset: bool) -> Self { Self { service_data: core::cell::RefCell::new(service_data), + auto_reset, + enabled: false, } + } + + pub fn is_enabled(&self) -> bool { + self.enabled + } + + pub fn reset(&mut self) { + let mut sd = self.service_data.borrow_mut(); + sd.ticks_per_service = sd.ticks_remaining; + self.enabled = false; } + + pub fn enable(&mut self, enable: bool) { + self.enabled = enable; + } } impl TickService for TickTimerService { fn tick(&self) { - let mut tc = self.service_data.borrow_mut(); - tc.ticks_remaining = tc.ticks_remaining.saturating_sub(1); + if self.enabled { + let mut tc = self.service_data.borrow_mut(); + tc.ticks_remaining = tc.ticks_remaining.saturating_sub(1); + } } fn need_service(&self) -> bool { - self.service_data.borrow().ticks_remaining == 0 + self.enabled && self.service_data.borrow().ticks_remaining == 0 } fn service(&self) { diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index aaab104..59515b9 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -95,7 +95,7 @@ fn main() -> ! { let p = hal::init(config); // coin button input setup - let b1 = Input::new(p.PD4, Pull::Up); + let coin_button = Input::new(p.PD4, Pull::Up); // p.EXTI4 // let ei = hal::exti::ExtiInput::new(p.PD4, p.EXTI4, Pull::Up); @@ -151,47 +151,143 @@ fn main() -> ! { let tt0_fire_rate_hz = 9; let tt0_tick_per_service = (interfaces.config.tick_rate_hz/(tt0_fire_rate_hz * 2)); let tt0_service_data = TickServiceData::new(tt0_tick_per_service); - let tt0 = TickTimerService::new(tt0_service_data); + let mut tt0 = TickTimerService::new(tt0_service_data, true); // tick timer 1 let tt1_fire_rate_hz = 3; let tt1_tick_per_service = (interfaces.config.tick_rate_hz/(tt1_fire_rate_hz * 2)); let tt1_service_data = TickServiceData::new(tt1_tick_per_service); - let tt1 = TickTimerService::new(tt1_service_data); + let mut tt1 = TickTimerService::new(tt1_service_data, true); + // debounce timer + // let db_ticks = interfaces.config.tick_rate_hz / 100; + let db_ticks = interfaces.config.tick_rate_hz / 100; + let db_timer_data = TickServiceData::new(db_ticks); + let mut db_timer = TickTimerService::new(db_timer_data, false); + db_timer.reset(); + + // short press timer + let sp_ticks = 2 * interfaces.config.tick_rate_hz; + let sp_timer_data = TickServiceData::new(sp_ticks); + let mut sp_timer = TickTimerService::new(sp_timer_data, false); + sp_timer.reset(); + + // long press timer + let lp_ticks = 5 * interfaces.config.tick_rate_hz; + let lp_timer_data = TickServiceData::new(lp_ticks); + let mut lp_timer = TickTimerService::new(lp_timer_data, false); + lp_timer.reset(); let mut delay = Delay; let tick_interval_us = 1000000/interfaces.config.tick_rate_hz; - + + interfaces.led0.set_amplitude(100); + interfaces.led1.set_amplitude(100); + + loop { - - tt0.tick(); - tt1.tick(); - // TODO: timer - // if app.led0.need_service() { - if tt0.need_service() { - interfaces.led0.set_amplitude(led0_dcs[led0_index]); - led0_index += 1; - if led0_index > led0_dcs.len() - 1 { - led0_index = 0; + // wait for button to be released if it's pressed + if (coin_button.is_low()) { + loop { + if coin_button.is_high() && !db_timer.is_enabled() { + db_timer.enable(true); + } + if db_timer.need_service() { + db_timer.reset(); + if coin_button.is_high() { + break; + } + } + db_timer.tick(); + delay.delay_us(tick_interval_us as u32); } - tt0.service(); } - // } - - // if app.led1.need_service() { - if tt1.need_service() { - interfaces.led1.set_amplitude(led1_dcs[led1_index]); - led1_index += 1; - if led1_index > led1_dcs.len() - 1 { - led1_index = 0; + // wait for button input + loop { + if coin_button.is_low() && !db_timer.is_enabled() { + db_timer.enable(true); } - tt1.service() + if db_timer.need_service() { + db_timer.reset(); + if coin_button.is_low() { + break; + } + } + db_timer.tick(); + delay.delay_us(tick_interval_us as u32); } - interfaces.service(); + let mut active = true; + tt0.enable(true); + tt1.enable(true); + loop { + if active { + tt0.tick(); + tt1.tick(); - delay.delay_us(tick_interval_us as u32); + if tt0.need_service() { + interfaces.led0.set_amplitude(led0_dcs[led0_index]); + led0_index += 1; + if led0_index > led0_dcs.len() - 1 { + led0_index = 0; + } + tt0.service(); + } + + if tt1.need_service() { + interfaces.led1.set_amplitude(led1_dcs[led1_index]); + led1_index += 1; + if led1_index > led1_dcs.len() - 1 { + led1_index = 0; + } + tt1.service() + } + + } + + // buttons + + // SP + if coin_button.is_low() && !sp_timer.is_enabled() { + sp_timer.reset(); + sp_timer.enable(true); + } + if sp_timer.need_service() { + sp_timer.reset(); + if coin_button.is_low() { + active = false; + // TODO: fix polarity + interfaces.led0.set_amplitude(90); + interfaces.led1.set_amplitude(90); + } + } + if coin_button.is_high() && sp_timer.is_enabled() { + sp_timer.reset(); + } + sp_timer.tick(); + + + // LP + if coin_button.is_low() && !lp_timer.is_enabled() { + lp_timer.reset(); + lp_timer.enable(true); + } + if lp_timer.need_service() { + lp_timer.reset(); + if coin_button.is_low() { + interfaces.led0.set_amplitude(100); + interfaces.led1.set_amplitude(100); + // break; + } + } + if coin_button.is_high() && lp_timer.is_enabled() { + lp_timer.reset(); + } + lp_timer.tick(); + + interfaces.service(); + delay.delay_us(tick_interval_us as u32); + } } // // DAC servicer setup // let mut pwm_dac_interface = SimplePwmDacHandle{pin: core::cell::RefCell::new(pwm), ch: dac_ch};