From f4759a0c7141f6778709507f02252d07d577259a Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Thu, 6 Nov 2025 19:19:58 -0700 Subject: [PATCH 01/27] update .gitmodules to use https --- .gitmodules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index e953eec..84792a2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,12 +1,12 @@ [submodule "ch32v-insert-coin/ext/ch32-hal"] path = ch32v-insert-coin/ext/ch32-hal - url = git@github.com:sigil-03/ch32-hal.git + url = https://github.com/sigil-03/ch32-hal.git [submodule "ch32v-insert-coin/ext/qingke"] path = ch32v-insert-coin/ext/qingke - url = git@github.com:ch32-rs/qingke.git + url = https://github.com/ch32-rs/qingke.git [submodule "ch32v-insert-coin/ext/adpcm-pwm-dac"] path = ch32v-insert-coin/ext/adpcm-pwm-dac - url = ssh://git@git.glyphs.tech:222/sigil-03/adpcm-pwm-dac.git + url = https://git.glyphs.tech/sigil-03/adpcm-pwm-dac.git [submodule "ch32v-insert-coin/ext/wavetable-synth"] path = ch32v-insert-coin/ext/wavetable-synth url = https://git.glyphs.tech/sigil-03/wavetable-synth.git From 5288cba869471122f3fa46183afa75904cbfdf02 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Wed, 12 Nov 2025 20:06:17 -0700 Subject: [PATCH 02/27] add AdcCore for ADC measurement --- ch32v-insert-coin/src/app.rs | 1 + ch32v-insert-coin/src/main.rs | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index c48a073..fbd2ddc 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -301,6 +301,7 @@ pub struct Sequences { // things that touch hardware pub struct Interfaces { pub pwm_core: SimplePwmCore<'static, ch32_hal::peripherals::TIM1>, + pub adc_core: crate::AdcCore, } pub struct App { diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 1e9e74c..d8dc81d 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -44,6 +44,30 @@ use crate::app::sequencer::{DynamicSequence, SequenceEntry}; static LED0_SEQ: [u8; 8] = [0u8, 25u8, 50u8, 75u8, 100u8, 75u8, 50u8, 25u8]; +use hal::adc::Adc; +use hal::peripherals::{ADC1, PD4}; + +pub struct AdcCore { + adc: Adc<'static, ADC1>, + battery_pin: PD4, +} + +impl AdcCore { + pub fn new(mut adc: Adc<'static, ADC1>, pin: PD4) -> Self { + adc.calibrate(); + Self { + adc, + battery_pin: pin, + } + } + + // TODO make this a float or something + pub fn get_battery_voltage(&mut self) -> u16 { + self.adc + .convert(&mut self.battery_pin, hal::adc::SampleTime::CYCLES241) + } +} + #[derive(Debug)] struct Flag { value: bool, @@ -205,13 +229,13 @@ fn app_main(mut p: hal::Peripherals) -> ! { // adc let mut adc = hal::adc::Adc::new(p.ADC1, Default::default()); let mut batt_monitor_pin = p.PD4; + let adc_core = AdcCore::new(adc, batt_monitor_pin); // adc2 // let mut usb_detect_dc = hal::adc::Adc::new(p.ADC1, Default::default()); let mut usb_detect_pin = p.PD5; // println!("ADC_PIN CHANNEL: {}", adc_pin.channel().channel()); - let adc_cal = adc.calibrate(); // #[cfg(feature = "enable_print")] // println!("ADC calibration value: {}", adc_cal); @@ -289,7 +313,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { audio: &SEQUENCE_LIST, }; - let app_interfaces = Interfaces { pwm_core }; + let app_interfaces = Interfaces { pwm_core, adc_core }; let mut app = App::new(app_config, app_services, app_sequences, app_interfaces); From 43790abbc5fdc64da74f30f6701283d66ab0369a Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Wed, 12 Nov 2025 20:13:57 -0700 Subject: [PATCH 03/27] initial commit off adc into app --- ch32v-insert-coin/src/app.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index fbd2ddc..4cc0dd7 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -389,8 +389,12 @@ impl App { } if self.timers.batt_adc_timer.need_service() { self.timers.batt_adc_timer.service(); + let bv = self.interfaces.adc_core.get_battery_voltage(); #[cfg(feature = "enable_print")] - println!("batt adc service"); + println!("batt adc service: {bv}"); + + // TODO: + // do stuff if the battery voltage is below some threshold } if self.timers.usb_adc_timer.need_service() { self.timers.usb_adc_timer.service(); From b0b77a15382d46c7a7eda66421f67c7e83be833a Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Thu, 13 Nov 2025 20:12:38 -0700 Subject: [PATCH 04/27] add initial ADC shutdown code --- ch32v-insert-coin/src/app.rs | 13 ++++++++++--- ch32v-insert-coin/src/main.rs | 30 +++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index 4cc0dd7..3904630 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -183,7 +183,7 @@ use crate::synthesizer::SynthesizerService; pub use settings::Settings; -#[cfg(feature = "enable_print")] +// #[cfg(feature = "enable_print")] use ch32_hal::println; pub struct TimerConfig { @@ -390,8 +390,15 @@ impl App { if self.timers.batt_adc_timer.need_service() { self.timers.batt_adc_timer.service(); let bv = self.interfaces.adc_core.get_battery_voltage(); - #[cfg(feature = "enable_print")] - println!("batt adc service: {bv}"); + let avg = self.interfaces.adc_core.get_average(); + // #[cfg(feature = "enable_print")] + // println!("batt adc service: {bv}, {avg}"); + if avg < 421 { + // self.services + // .sequencer + // .play_sequence(&crate::sequences::COIN_CHIRP, 0); + self.set_state(State::DeepSleep); + } // TODO: // do stuff if the battery voltage is below some threshold diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index d8dc81d..facacbf 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -50,21 +50,41 @@ use hal::peripherals::{ADC1, PD4}; pub struct AdcCore { adc: Adc<'static, ADC1>, battery_pin: PD4, + batt_values: [u16; 10], + index: usize, } impl AdcCore { pub fn new(mut adc: Adc<'static, ADC1>, pin: PD4) -> Self { + riscv::asm::delay(20_000); adc.calibrate(); Self { adc, battery_pin: pin, + batt_values: [1024; 10], + index: 0, } } // TODO make this a float or something pub fn get_battery_voltage(&mut self) -> u16 { - self.adc - .convert(&mut self.battery_pin, hal::adc::SampleTime::CYCLES241) + let val = self + .adc + .convert(&mut self.battery_pin, hal::adc::SampleTime::CYCLES241); + self.batt_values[self.index] = val; + self.index += 1; + if self.index > &self.batt_values.len() - 1 { + self.index = 0; + } + val + } + + pub fn get_average(&self) -> u16 { + let mut sum = 0; + for value in &self.batt_values { + sum += value; + } + sum / self.batt_values.len() as u16 } } @@ -272,7 +292,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { let timer_config = TimerConfig { sp_timer_ms: 1000, lp_timer_ms: 3000, - batt_adc_timer_ms: 10000, + batt_adc_timer_ms: 1000, usb_adc_timer_ms: 10000, led0_timer_ms: 100, led1_timer_ms: 100, @@ -289,11 +309,11 @@ fn app_main(mut p: hal::Peripherals) -> ! { let dac_tick_per_service = tick_rate_hz / dac_sample_rate_hz; let dac_service_data = TickServiceData::new(dac_tick_per_service); - let coin_sound = include_bytes!("../audio/coin5.raw"); + // let coin_sound = include_bytes!("../audio/coin5.raw"); // let coin_sound = include_bytes!("../audio/coin2.raw"); let sample_player = DacService::new(ch32_hal::timer::Channel::Ch4, dac_service_data); - sample_player.load_data(coin_sound); + // sample_player.load_data(coin_sound); let sequencer = app::sequencer::DynamicSequence::new(&SEQUENCE_LIST[0].0, tick_rate_hz); From 17d6f156db5cf49f6cdcb41e2bd8dd3906f57d79 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Fri, 14 Nov 2025 12:56:11 -0700 Subject: [PATCH 05/27] remove led2 (tiny led) --- ch32v-insert-coin/src/app.rs | 74 +++++++++++++++++------------------ ch32v-insert-coin/src/main.rs | 17 ++++---- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index 3904630..5775a60 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -193,7 +193,7 @@ pub struct TimerConfig { pub usb_adc_timer_ms: usize, pub led0_timer_ms: usize, pub led1_timer_ms: usize, - pub led2_timer_ms: usize, + // pub led2_timer_ms: usize, } pub struct Timers { @@ -203,7 +203,7 @@ pub struct Timers { usb_adc_timer: TickTimerService, led0_timer: TickTimerService, led1_timer: TickTimerService, - led2_timer: TickTimerService, + // led2_timer: TickTimerService, } impl Timers { @@ -233,10 +233,10 @@ impl Timers { TickServiceData::new(config.led1_timer_ms * system_tick_rate_hz / 1000), true, ), - led2_timer: TickTimerService::new( - TickServiceData::new(config.led2_timer_ms * system_tick_rate_hz / 1000), - true, - ), + // led2_timer: TickTimerService::new( + // TickServiceData::new(config.led2_timer_ms * system_tick_rate_hz / 1000), + // true, + // ), } } pub fn tick(&mut self) { @@ -246,7 +246,7 @@ impl Timers { self.usb_adc_timer.tick(); self.led0_timer.tick(); self.led1_timer.tick(); - self.led2_timer.tick(); + // self.led2_timer.tick(); } pub fn need_service(&self) -> bool { self.sp_timer.need_service() @@ -255,7 +255,7 @@ impl Timers { | self.usb_adc_timer.need_service() | self.led0_timer.need_service() | self.led1_timer.need_service() - | self.led2_timer.need_service() + // | self.led2_timer.need_service() } pub fn init(&mut self) { self.led0_timer.reset(); @@ -272,7 +272,7 @@ impl Timers { pub struct Services { pub led0: LedService, pub led1: LedService, - pub led2: LedService, + // pub led2: LedService, pub synth0: SynthesizerService, pub sample_player: DacService<'static>, pub sequencer: sequencer::DynamicSequence<'static>, @@ -294,7 +294,7 @@ pub struct Config { pub struct Sequences { pub led0: sequencer::BasicSequence<'static>, pub led1: sequencer::BasicSequence<'static>, - pub led2: sequencer::BasicSequence<'static>, + // pub led2: sequencer::BasicSequence<'static>, pub audio: &'static [(&'static [sequencer::SequenceEntry], usize)], } @@ -345,8 +345,8 @@ impl App { self.timers.led1_timer.reset(); self.timers.led1_timer.enable(true); - self.timers.led2_timer.reset(); - self.timers.led2_timer.enable(true); + // self.timers.led2_timer.reset(); + // self.timers.led2_timer.enable(true); self.services.synth0.set_freq(1); self.services.synth0.disable(); @@ -442,23 +442,23 @@ impl App { // #[cfg(feature = "enable_print")] // println!("led1 service"); } - if self.timers.led2_timer.need_service() { - let out = match self.settings.brightness { - Level::Off => 0, - Level::Low => 5, - Level::Medium => 25, - Level::High => 75, - Level::Maximum => { - self.sequences.led2.next(); - self.sequences.led2.get_value() / 6 - } - }; - self.timers.led2_timer.service(); - self.services.led2.set_amplitude(out); + // if self.timers.led2_timer.need_service() { + // let out = match self.settings.brightness { + // Level::Off => 0, + // Level::Low => 5, + // Level::Medium => 25, + // Level::High => 75, + // Level::Maximum => { + // self.sequences.led2.next(); + // self.sequences.led2.get_value() / 6 + // } + // }; + // self.timers.led2_timer.service(); + // self.services.led2.set_amplitude(out); - // #[cfg(feature = "enable_print")] - // println!("led2 service"); - } + // // #[cfg(feature = "enable_print")] + // // println!("led2 service"); + // } // services if self.services.led0.need_service() { @@ -473,12 +473,12 @@ impl App { .write_amplitude(self.services.led1.channel, self.services.led1.amplitude); self.services.led1.service(); } - if self.services.led2.need_service() { - self.interfaces - .pwm_core - .write_amplitude(self.services.led2.channel, self.services.led2.amplitude); - self.services.led2.service(); - } + // if self.services.led2.need_service() { + // self.interfaces + // .pwm_core + // .write_amplitude(self.services.led2.channel, self.services.led2.amplitude); + // self.services.led2.service(); + // } // TODO: disable when you get to the end automatically // in the sequencer, not here @@ -525,9 +525,9 @@ impl App { self.interfaces .pwm_core .write_amplitude(self.services.led1.channel, 0); - self.interfaces - .pwm_core - .write_amplitude(self.services.led2.channel, 0); + // self.interfaces + // .pwm_core + // .write_amplitude(self.services.led2.channel, 0); self.interfaces .pwm_core .disable(ch32_hal::timer::Channel::Ch4); diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index facacbf..5d75d4f 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -215,9 +215,9 @@ fn app_main(mut p: hal::Peripherals) -> ! { let led1_pin = PwmPin::new_ch1::<0>(p.PD2); let led1_ch = hal::timer::Channel::Ch1; - // LED2 output setup - let led2_pin = PwmPin::new_ch2::<0>(p.PA1); - let led2_ch = hal::timer::Channel::Ch2; + // // LED2 output setup + // let led2_pin = PwmPin::new_ch2::<0>(p.PA1); + // let led2_ch = hal::timer::Channel::Ch2; // DAC output setup let dac_pin = PwmPin::new_ch4::<0>(p.PC4); @@ -227,7 +227,8 @@ fn app_main(mut p: hal::Peripherals) -> ! { let mut pwm = SimplePwm::new( p.TIM1, Some(led1_pin), - Some(led2_pin), + // Some(led2_pin), + None, Some(led0_pin), Some(dac_pin), Hertz::khz(200), @@ -236,7 +237,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { pwm.set_polarity(led0_ch, OutputPolarity::ActiveHigh); pwm.set_polarity(led1_ch, OutputPolarity::ActiveLow); - pwm.set_polarity(led2_ch, OutputPolarity::ActiveLow); + // pwm.set_polarity(led2_ch, OutputPolarity::ActiveLow); let tick_rate_hz = 50000; @@ -296,7 +297,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { usb_adc_timer_ms: 10000, led0_timer_ms: 100, led1_timer_ms: 100, - led2_timer_ms: 100, + // led2_timer_ms: 100, }; let app_config = Config { @@ -320,7 +321,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { let app_services = Services { led0: LedService::new(led0_ch), led1: LedService::new(led1_ch), - led2: LedService::new(led2_ch), + // led2: LedService::new(led2_ch), synth0: SynthesizerService::new(tick_rate_hz), sample_player, sequencer, @@ -329,7 +330,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { let app_sequences = Sequences { led0: BasicSequence::new(&LED0_SEQ), led1: BasicSequence::new(&LED0_SEQ), - led2: BasicSequence::new(&LED0_SEQ), + // led2: BasicSequence::new(&LED0_SEQ), audio: &SEQUENCE_LIST, }; From 1c2823eb1b1b3b706501e9789c58927ca27c6af6 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Fri, 14 Nov 2025 13:14:02 -0700 Subject: [PATCH 06/27] add 4 hour shutdown timer --- ch32v-insert-coin/src/app.rs | 37 +++++++++++++++++++++++++---------- ch32v-insert-coin/src/main.rs | 1 + 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index 5775a60..f2e46c0 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -193,6 +193,7 @@ pub struct TimerConfig { pub usb_adc_timer_ms: usize, pub led0_timer_ms: usize, pub led1_timer_ms: usize, + pub shutdown_timer_ms: usize, // pub led2_timer_ms: usize, } @@ -203,6 +204,7 @@ pub struct Timers { usb_adc_timer: TickTimerService, led0_timer: TickTimerService, led1_timer: TickTimerService, + shutdown_timer: TickTimerService, // led2_timer: TickTimerService, } @@ -233,10 +235,13 @@ impl Timers { TickServiceData::new(config.led1_timer_ms * system_tick_rate_hz / 1000), true, ), - // led2_timer: TickTimerService::new( - // TickServiceData::new(config.led2_timer_ms * system_tick_rate_hz / 1000), - // true, - // ), + shutdown_timer: TickTimerService::new( + TickServiceData::new(config.shutdown_timer_ms * system_tick_rate_hz / 1000), + false, + ), // led2_timer: TickTimerService::new( + // TickServiceData::new(config.led2_timer_ms * system_tick_rate_hz / 1000), + // true, + // ), } } pub fn tick(&mut self) { @@ -246,6 +251,7 @@ impl Timers { self.usb_adc_timer.tick(); self.led0_timer.tick(); self.led1_timer.tick(); + self.shutdown_timer.tick(); // self.led2_timer.tick(); } pub fn need_service(&self) -> bool { @@ -255,6 +261,7 @@ impl Timers { | self.usb_adc_timer.need_service() | self.led0_timer.need_service() | self.led1_timer.need_service() + | self.shutdown_timer.need_service() // | self.led2_timer.need_service() } pub fn init(&mut self) { @@ -345,6 +352,9 @@ impl App { self.timers.led1_timer.reset(); self.timers.led1_timer.enable(true); + self.timers.shutdown_timer.reset(); + self.timers.shutdown_timer.enable(true); + // self.timers.led2_timer.reset(); // self.timers.led2_timer.enable(true); @@ -394,14 +404,8 @@ impl App { // #[cfg(feature = "enable_print")] // println!("batt adc service: {bv}, {avg}"); if avg < 421 { - // self.services - // .sequencer - // .play_sequence(&crate::sequences::COIN_CHIRP, 0); self.set_state(State::DeepSleep); } - - // TODO: - // do stuff if the battery voltage is below some threshold } if self.timers.usb_adc_timer.need_service() { self.timers.usb_adc_timer.service(); @@ -442,6 +446,11 @@ impl App { // #[cfg(feature = "enable_print")] // println!("led1 service"); } + if self.timers.shutdown_timer.need_service() { + self.timers.shutdown_timer.service(); + self.timers.shutdown_timer.reset(); + self.set_state(State::DeepSleep); + } // if self.timers.led2_timer.need_service() { // let out = match self.settings.brightness { // Level::Off => 0, @@ -536,11 +545,15 @@ impl App { self.settings.volume.next(); #[cfg(feature = "enable_print")] println!("new volume: {:?}", self.settings.volume); + self.timers.shutdown_timer.reset(); + self.timers.shutdown_timer.enable(true); } pub fn brightness_button(&mut self) { self.settings.brightness.next(); #[cfg(feature = "enable_print")] println!("new brightness: {:?}", self.settings.brightness); + self.timers.shutdown_timer.reset(); + self.timers.shutdown_timer.enable(true); } pub fn main_button_press(&mut self) { // TODO @@ -548,8 +561,10 @@ impl App { println!("main button press"); self.timers.sp_timer.reset(); self.timers.lp_timer.reset(); + self.timers.shutdown_timer.reset(); self.timers.sp_timer.enable(true); self.timers.lp_timer.enable(true); + self.timers.shutdown_timer.enable(true); self.main_button_click(); } pub fn main_button_release(&mut self) { @@ -581,6 +596,8 @@ impl App { self.services .sequencer .play_sequence(&crate::sequences::COIN_CHIRP, 0); + self.timers.shutdown_timer.reset(); + self.timers.shutdown_timer.enable(true); } } diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 5d75d4f..b46f114 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -297,6 +297,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { usb_adc_timer_ms: 10000, led0_timer_ms: 100, led1_timer_ms: 100, + shutdown_timer_ms: 4 * 60 * 60 * 1000, // led2_timer_ms: 100, }; From 8ea4b4401ec0fa99ac88b15e83cdefedead9d8b7 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Fri, 14 Nov 2025 13:30:01 -0700 Subject: [PATCH 07/27] add amp_en control --- ch32v-insert-coin/src/app.rs | 6 ++++++ ch32v-insert-coin/src/main.rs | 29 +++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index f2e46c0..2eb5de9 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -309,6 +309,7 @@ pub struct Sequences { pub struct Interfaces { pub pwm_core: SimplePwmCore<'static, ch32_hal::peripherals::TIM1>, pub adc_core: crate::AdcCore, + pub amp: crate::Amplifier, } pub struct App { @@ -502,10 +503,14 @@ impl App { } else { self.services.sequencer.disable(); self.services.synth0.disable(); + self.interfaces.amp.disable(); } } if self.services.synth0.need_service() { + if !self.interfaces.amp.enabled() { + self.interfaces.amp.enable(); + } let out = match self.services.synth0.service() { Some(value) => value / 6 / self.settings.volume.as_volume_divisor(), None => 0, @@ -540,6 +545,7 @@ impl App { self.interfaces .pwm_core .disable(ch32_hal::timer::Channel::Ch4); + self.interfaces.amp.disable(); } pub fn volume_button(&mut self) { self.settings.volume.next(); diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index b46f114..6a29a7a 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -44,6 +44,27 @@ use crate::app::sequencer::{DynamicSequence, SequenceEntry}; static LED0_SEQ: [u8; 8] = [0u8, 25u8, 50u8, 75u8, 100u8, 75u8, 50u8, 25u8]; +pub struct Amplifier { + amp_en: Output<'static>, +} + +impl Amplifier { + pub fn new(amp_en: Output<'static>) -> Self { + let mut amp = Self { amp_en }; + amp.disable(); + amp + } + pub fn enable(&mut self) { + self.amp_en.set_low(); + } + pub fn disable(&mut self) { + self.amp_en.set_high(); + } + pub fn enabled(&self) -> bool { + !self.amp_en.is_set_high() + } +} + use hal::adc::Adc; use hal::peripherals::{ADC1, PD4}; @@ -271,7 +292,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { let extra_io_2 = p.PD3; let mut amp_en_output = Output::new(amp_en, Level::Low, Default::default()); - amp_en_output.set_low(); + let amp = Amplifier::new(amp_en_output); // set up interrupts unsafe { system::init_gpio_irq(sense_coin_pin.pin(), sense_coin_pin.port(), true, false) }; @@ -335,7 +356,11 @@ fn app_main(mut p: hal::Peripherals) -> ! { audio: &SEQUENCE_LIST, }; - let app_interfaces = Interfaces { pwm_core, adc_core }; + let app_interfaces = Interfaces { + pwm_core, + adc_core, + amp, + }; let mut app = App::new(app_config, app_services, app_sequences, app_interfaces); From c43cc5599e016afe37c1267565c836cf57b0b181 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Fri, 14 Nov 2025 14:34:29 -0700 Subject: [PATCH 08/27] add usb power detection + check to ADC shutdown logic --- ch32v-insert-coin/src/app.rs | 15 +++++++++------ ch32v-insert-coin/src/main.rs | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index 2eb5de9..482c354 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -310,6 +310,7 @@ pub struct Interfaces { pub pwm_core: SimplePwmCore<'static, ch32_hal::peripherals::TIM1>, pub adc_core: crate::AdcCore, pub amp: crate::Amplifier, + pub usb: crate::Usb, } pub struct App { @@ -400,12 +401,14 @@ impl App { } if self.timers.batt_adc_timer.need_service() { self.timers.batt_adc_timer.service(); - let bv = self.interfaces.adc_core.get_battery_voltage(); - let avg = self.interfaces.adc_core.get_average(); - // #[cfg(feature = "enable_print")] - // println!("batt adc service: {bv}, {avg}"); - if avg < 421 { - self.set_state(State::DeepSleep); + if !self.interfaces.usb.powered() { + let bv = self.interfaces.adc_core.get_battery_voltage(); + let avg = self.interfaces.adc_core.get_average(); + // #[cfg(feature = "enable_print")] + // println!("batt adc service: {bv}, {avg}"); + if avg < 421 { + self.set_state(State::DeepSleep); + } } } if self.timers.usb_adc_timer.need_service() { diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 6a29a7a..0bb8271 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -44,6 +44,19 @@ use crate::app::sequencer::{DynamicSequence, SequenceEntry}; static LED0_SEQ: [u8; 8] = [0u8, 25u8, 50u8, 75u8, 100u8, 75u8, 50u8, 25u8]; +pub struct Usb { + usb_pin: Input<'static>, +} + +impl Usb { + pub fn new(usb_pin: Input<'static>) -> Self { + Self { usb_pin } + } + pub fn powered(&self) -> bool { + self.usb_pin.is_high() + } +} + pub struct Amplifier { amp_en: Output<'static>, } @@ -276,6 +289,8 @@ fn app_main(mut p: hal::Peripherals) -> ! { // adc2 // let mut usb_detect_dc = hal::adc::Adc::new(p.ADC1, Default::default()); let mut usb_detect_pin = p.PD5; + let usb_detect_input = Input::new(usb_detect_pin, Pull::Down); + let usb = Usb::new(usb_detect_input); // println!("ADC_PIN CHANNEL: {}", adc_pin.channel().channel()); @@ -360,6 +375,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { pwm_core, adc_core, amp, + usb, }; let mut app = App::new(app_config, app_services, app_sequences, app_interfaces); From 2f92805c1a0424b3707bc92c9b9f026ada234a47 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Fri, 14 Nov 2025 15:08:40 -0700 Subject: [PATCH 09/27] add USB check for powerup --- ch32v-insert-coin/src/app.rs | 10 ++++++++++ ch32v-insert-coin/src/main.rs | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index 482c354..56162b1 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -648,6 +648,16 @@ impl App { pub fn get_state(&self) -> State { self.state } + pub fn should_wake(&self) -> bool { + if self.interfaces.usb.powered() { + return true; + } else { + if self.interfaces.adc_core.get_average() > 421 { + return true; + } + } + return false; + } } // TODO LIST diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 0bb8271..8e8a6dc 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -526,9 +526,10 @@ fn app_main(mut p: hal::Peripherals) -> ! { } unsafe { #[allow(static_mut_refs)] - if INPUT_FLAGS.sense_coin_flag.active() + if (INPUT_FLAGS.sense_coin_flag.active() || (INPUT_FLAGS.main_btn_flag.active() - && main_btn_input.is_high_immediate()) + && main_btn_input.is_high_immediate())) + && app.should_wake() { unsafe { use hal::pac::Interrupt; From 64aa1808d21efc36ebb638030466e78355f0019d Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Fri, 14 Nov 2025 15:15:03 -0700 Subject: [PATCH 10/27] change direction of the USB detect input --- ch32v-insert-coin/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 8e8a6dc..3414329 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -289,7 +289,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { // adc2 // let mut usb_detect_dc = hal::adc::Adc::new(p.ADC1, Default::default()); let mut usb_detect_pin = p.PD5; - let usb_detect_input = Input::new(usb_detect_pin, Pull::Down); + let usb_detect_input = Input::new(usb_detect_pin, Pull::Up); let usb = Usb::new(usb_detect_input); // println!("ADC_PIN CHANNEL: {}", adc_pin.channel().channel()); From 7e187680f5b75172fa8445f528c9e2951d5ecccf Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Fri, 14 Nov 2025 15:46:28 -0700 Subject: [PATCH 11/27] don't use pullups --- ch32v-insert-coin/src/debounced_gpio.rs | 2 +- ch32v-insert-coin/src/main.rs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ch32v-insert-coin/src/debounced_gpio.rs b/ch32v-insert-coin/src/debounced_gpio.rs index baec633..784c3fd 100644 --- a/ch32v-insert-coin/src/debounced_gpio.rs +++ b/ch32v-insert-coin/src/debounced_gpio.rs @@ -17,7 +17,7 @@ impl<'a> DebouncedGPIO<'a> { pub fn new(pin: AnyPin, system_tick_rate_hz: usize, debounce_time_ms: usize) -> Self { // coin debounce timer (100ms) Self { - input: Input::new(pin, Pull::Up), + input: Input::new(pin, Pull::None), value: false, ready: false, active: false, diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 3414329..c4e404f 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -55,6 +55,12 @@ impl Usb { pub fn powered(&self) -> bool { self.usb_pin.is_high() } + // pub fn enable(&mut self) { + // self.usb_pin.set_as_input(Pull::Up); + // } + // pub fn disable(&mut self) { + // self.usb_pin.set_as_input(Pull::None); + // } } pub struct Amplifier { From c71ace5063111ba4187d9e800e7fd976ac0231ba Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Fri, 14 Nov 2025 16:09:27 -0700 Subject: [PATCH 12/27] fix sleep timer overflow --- ch32v-insert-coin/src/app.rs | 29 +++++++++++++++++++++-------- ch32v-insert-coin/src/main.rs | 4 +++- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index 56162b1..c2596e1 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -193,7 +193,7 @@ pub struct TimerConfig { pub usb_adc_timer_ms: usize, pub led0_timer_ms: usize, pub led1_timer_ms: usize, - pub shutdown_timer_ms: usize, + pub shutdown_timer_s: usize, // pub led2_timer_ms: usize, } @@ -205,6 +205,7 @@ pub struct Timers { led0_timer: TickTimerService, led1_timer: TickTimerService, shutdown_timer: TickTimerService, + pps_timer: TickTimerService, // led2_timer: TickTimerService, } @@ -236,12 +237,14 @@ impl Timers { true, ), shutdown_timer: TickTimerService::new( - TickServiceData::new(config.shutdown_timer_ms * system_tick_rate_hz / 1000), + TickServiceData::new(config.shutdown_timer_s), false, - ), // led2_timer: TickTimerService::new( - // TickServiceData::new(config.led2_timer_ms * system_tick_rate_hz / 1000), - // true, - // ), + ), + pps_timer: TickTimerService::new(TickServiceData::new(system_tick_rate_hz), true), + // led2_timer: TickTimerService::new( + // TickServiceData::new(config.led2_timer_ms * system_tick_rate_hz / 1000), + // true, + // ), } } pub fn tick(&mut self) { @@ -251,7 +254,7 @@ impl Timers { self.usb_adc_timer.tick(); self.led0_timer.tick(); self.led1_timer.tick(); - self.shutdown_timer.tick(); + self.pps_timer.tick(); // self.led2_timer.tick(); } pub fn need_service(&self) -> bool { @@ -262,6 +265,7 @@ impl Timers { | self.led0_timer.need_service() | self.led1_timer.need_service() | self.shutdown_timer.need_service() + | self.pps_timer.need_service() // | self.led2_timer.need_service() } pub fn init(&mut self) { @@ -357,6 +361,9 @@ impl App { self.timers.shutdown_timer.reset(); self.timers.shutdown_timer.enable(true); + self.timers.pps_timer.reset(); + self.timers.pps_timer.enable(true); + // self.timers.led2_timer.reset(); // self.timers.led2_timer.enable(true); @@ -406,6 +413,7 @@ impl App { let avg = self.interfaces.adc_core.get_average(); // #[cfg(feature = "enable_print")] // println!("batt adc service: {bv}, {avg}"); + // println!("none USB"); if avg < 421 { self.set_state(State::DeepSleep); } @@ -450,9 +458,14 @@ impl App { // #[cfg(feature = "enable_print")] // println!("led1 service"); } + if self.timers.pps_timer.need_service() { + self.timers.pps_timer.service(); + self.timers.shutdown_timer.tick(); + } if self.timers.shutdown_timer.need_service() { self.timers.shutdown_timer.service(); self.timers.shutdown_timer.reset(); + // println!("eepy"); self.set_state(State::DeepSleep); } // if self.timers.led2_timer.need_service() { @@ -652,7 +665,7 @@ impl App { if self.interfaces.usb.powered() { return true; } else { - if self.interfaces.adc_core.get_average() > 421 { + if self.interfaces.adc_core.get_average() >= 421 { return true; } } diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index c4e404f..9693e27 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -339,7 +339,8 @@ fn app_main(mut p: hal::Peripherals) -> ! { usb_adc_timer_ms: 10000, led0_timer_ms: 100, led1_timer_ms: 100, - shutdown_timer_ms: 4 * 60 * 60 * 1000, + // 4 hours: + shutdown_timer_s: 4 * 60 * 60, // led2_timer_ms: 100, }; @@ -517,6 +518,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { app.shut_down(); loop { + riscv::asm::delay(20_000); unsafe { system::enter_standby() }; unsafe { #[allow(static_mut_refs)] From 6ba94f1cbb9f414f07a3db69bcc6654eecebde5d Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Fri, 14 Nov 2025 16:14:09 -0700 Subject: [PATCH 13/27] make amp_en OutputOpenDrain --- ch32v-insert-coin/src/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 9693e27..159a55e 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -31,7 +31,7 @@ use insert_coin::{CoreConfig, DacService, InsertCoin, LedService, SimplePwmCore} use ch32_hal as hal; use hal::bind_interrupts; use hal::delay::Delay; -use hal::gpio::{AnyPin, Input, Level, Output, Pin, Pull}; +use hal::gpio::{AnyPin, Input, Level, Output, OutputOpenDrain, Pin, Pull}; use hal::time::Hertz; use hal::timer::low_level::CountingMode; use hal::timer::simple_pwm::{PwmPin, SimplePwm}; @@ -64,11 +64,11 @@ impl Usb { } pub struct Amplifier { - amp_en: Output<'static>, + amp_en: OutputOpenDrain<'static>, } impl Amplifier { - pub fn new(amp_en: Output<'static>) -> Self { + pub fn new(amp_en: OutputOpenDrain<'static>) -> Self { let mut amp = Self { amp_en }; amp.disable(); amp @@ -312,7 +312,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { let extra_io_1 = p.PD0; let extra_io_2 = p.PD3; - let mut amp_en_output = Output::new(amp_en, Level::Low, Default::default()); + let mut amp_en_output = OutputOpenDrain::new(amp_en, Level::Low, Default::default()); let amp = Amplifier::new(amp_en_output); // set up interrupts From 45db5e8af861dad93c34e218b240cd4f79a09977 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Fri, 14 Nov 2025 18:57:36 -0700 Subject: [PATCH 14/27] fix deep sleep --- ch32v-insert-coin/src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 159a55e..8b17c75 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -518,14 +518,13 @@ fn app_main(mut p: hal::Peripherals) -> ! { app.shut_down(); loop { - riscv::asm::delay(20_000); - unsafe { system::enter_standby() }; unsafe { #[allow(static_mut_refs)] INPUT_FLAGS.sense_coin_flag.clear(); #[allow(static_mut_refs)] INPUT_FLAGS.main_btn_flag.clear(); } + unsafe { system::enter_standby() }; riscv::asm::wfi(); let mut config = hal::Config::default(); config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI; From cd91b3f540b91cff9c0605565a5c08d5a966db47 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 01:01:10 -0700 Subject: [PATCH 15/27] clean up sleep handling a tiny amount --- ch32v-insert-coin/src/main.rs | 42 ++++++++++++++++------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 8b17c75..ba69e0b 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -526,11 +526,6 @@ fn app_main(mut p: hal::Peripherals) -> ! { } unsafe { system::enter_standby() }; riscv::asm::wfi(); - let mut config = hal::Config::default(); - config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI; - unsafe { - hal::rcc::init(config.rcc); - } unsafe { #[allow(static_mut_refs)] if (INPUT_FLAGS.sense_coin_flag.active() @@ -538,28 +533,29 @@ fn app_main(mut p: hal::Peripherals) -> ! { && main_btn_input.is_high_immediate())) && app.should_wake() { - unsafe { - use hal::pac::Interrupt; - use qingke::interrupt::Priority; - use qingke_rt::CoreInterrupt; - - system::clear_interrupt(2, 6); - - qingke::pfic::set_priority( - CoreInterrupt::SysTick as u8, - Priority::P15 as u8, - ); - - qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8); - qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8); - } - - app.set_state(State::Active); - break; } } } + let mut config = hal::Config::default(); + config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI; + unsafe { + hal::rcc::init(config.rcc); + } + unsafe { + use hal::pac::Interrupt; + use qingke::interrupt::Priority; + use qingke_rt::CoreInterrupt; + + system::clear_interrupt(2, 6); + + qingke::pfic::set_priority(CoreInterrupt::SysTick as u8, Priority::P15 as u8); + + qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8); + qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8); + } + + app.set_state(State::Active); } // for everything else, don't do anything _ => {} From b6fa0e3b2d528299484de0d48e97ca715bb78be5 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 14:56:22 -0700 Subject: [PATCH 16/27] first working deep sleep entry with all peripherals enabled prior --- ch32v-insert-coin/ext/ch32-hal | 2 +- ch32v-insert-coin/src/app.rs | 14 +- .../src/insert_coin/insert_coin.rs | 2 +- ch32v-insert-coin/src/main.rs | 198 ++++++++++++++---- 4 files changed, 164 insertions(+), 52 deletions(-) diff --git a/ch32v-insert-coin/ext/ch32-hal b/ch32v-insert-coin/ext/ch32-hal index f413367..4f11d68 160000 --- a/ch32v-insert-coin/ext/ch32-hal +++ b/ch32v-insert-coin/ext/ch32-hal @@ -1 +1 @@ -Subproject commit f41336744c4e2548c8f6ba9b323ae4aa39959f1d +Subproject commit 4f11d68e62dcb0e7098eecf357168724a8322d80 diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index c2596e1..e2af3ef 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -551,16 +551,20 @@ impl App { pub fn shut_down(&mut self) { self.interfaces .pwm_core - .write_amplitude(self.services.led0.channel, 0); + .disable(ch32_hal::timer::Channel::Ch1); self.interfaces .pwm_core - .write_amplitude(self.services.led1.channel, 0); - // self.interfaces - // .pwm_core - // .write_amplitude(self.services.led2.channel, 0); + .disable(ch32_hal::timer::Channel::Ch2); + self.interfaces + .pwm_core + .disable(ch32_hal::timer::Channel::Ch3); self.interfaces .pwm_core .disable(ch32_hal::timer::Channel::Ch4); + + self.interfaces.pwm_core.pwm.borrow().shutdown(); + self.interfaces.adc_core.shutdown(); + self.interfaces.amp.disable(); } pub fn volume_button(&mut self) { diff --git a/ch32v-insert-coin/src/insert_coin/insert_coin.rs b/ch32v-insert-coin/src/insert_coin/insert_coin.rs index d453bea..8c0a606 100644 --- a/ch32v-insert-coin/src/insert_coin/insert_coin.rs +++ b/ch32v-insert-coin/src/insert_coin/insert_coin.rs @@ -11,7 +11,7 @@ use crate::insert_coin::services::{DacService, LedService, Service, TickService, // static LED1_DCS: [u8; 5] = [0u8, 25u8, 50u8, 75u8, 100u8]; pub struct SimplePwmCore<'d, T: GeneralInstance16bit> { - pwm: core::cell::RefCell>, + pub pwm: core::cell::RefCell>, } impl<'d, T: GeneralInstance16bit> SimplePwmCore<'d, T> { diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index ba69e0b..989a3ff 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -126,6 +126,10 @@ impl AdcCore { } sum / self.batt_values.len() as u16 } + + pub fn shutdown(&mut self) { + self.adc.shutdown() + } } #[derive(Debug)] @@ -244,7 +248,7 @@ bind_interrupts!(struct Irqs { use insert_coin::TickTimerService; use insert_coin::{TickService, TickServiceData}; -fn app_main(mut p: hal::Peripherals) -> ! { +fn app_main(mut p: hal::Peripherals) { // === output setup === // LED0 output setup @@ -309,8 +313,8 @@ fn app_main(mut p: hal::Peripherals) -> ! { let volume_btn_pin = p.PC6; let light_ctrl_btn_pin = p.PC7; let amp_en = p.PC5; - let extra_io_1 = p.PD0; - let extra_io_2 = p.PD3; + // let extra_io_1 = p.PD0; + // let extra_io_2 = p.PD3; let mut amp_en_output = OutputOpenDrain::new(amp_en, Level::Low, Default::default()); let amp = Amplifier::new(amp_en_output); @@ -340,6 +344,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { led0_timer_ms: 100, led1_timer_ms: 100, // 4 hours: + // shutdown_timer_s: 1, shutdown_timer_s: 4 * 60 * 60, // led2_timer_ms: 100, }; @@ -516,48 +521,8 @@ fn app_main(mut p: hal::Peripherals) -> ! { // enter standby app::State::DeepSleep => { app.shut_down(); - - loop { - unsafe { - #[allow(static_mut_refs)] - INPUT_FLAGS.sense_coin_flag.clear(); - #[allow(static_mut_refs)] - INPUT_FLAGS.main_btn_flag.clear(); - } - unsafe { system::enter_standby() }; - riscv::asm::wfi(); - unsafe { - #[allow(static_mut_refs)] - if (INPUT_FLAGS.sense_coin_flag.active() - || (INPUT_FLAGS.main_btn_flag.active() - && main_btn_input.is_high_immediate())) - && app.should_wake() - { - break; - } - } - } - let mut config = hal::Config::default(); - config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI; - unsafe { - hal::rcc::init(config.rcc); - } - unsafe { - use hal::pac::Interrupt; - use qingke::interrupt::Priority; - use qingke_rt::CoreInterrupt; - - system::clear_interrupt(2, 6); - - qingke::pfic::set_priority(CoreInterrupt::SysTick as u8, Priority::P15 as u8); - - qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8); - qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8); - } - - app.set_state(State::Active); + return; } - // for everything else, don't do anything _ => {} } } @@ -573,6 +538,137 @@ fn app_main(mut p: hal::Peripherals) -> ! { // // } // } +use ch32_hal::timer::low_level::{OutputCompareMode, Timer}; +use ch32_hal::timer::Channel; + +// fn shutdown_main(p: Peripherals) { +fn shutdown_main(p: hal::Peripherals) { + // drop(p.TIM1); + // LED0 output setup + let led0_pin = OutputOpenDrain::new(p.PC3, Level::Low, Default::default()); + let led1_pin = OutputOpenDrain::new(p.PD2, Level::High, Default::default()); + let led2_pin = OutputOpenDrain::new(p.PA1, Level::High, Default::default()); + let dac_pin = OutputOpenDrain::new(p.PC4, Level::Low, Default::default()); + let mut amp_pin = OutputOpenDrain::new(p.PC5, Level::Low, Default::default()); + amp_pin.set_high(); + let volume_btn_pin = OutputOpenDrain::new(p.PC6, Level::Low, Default::default()); + let light_ctrl_btn_pin = OutputOpenDrain::new(p.PC7, Level::Low, Default::default()); + let usb_detect_input = OutputOpenDrain::new(p.PD5, Level::Low, Default::default()); + + let sense_coin_pin = p.PC2; + let main_btn_pin = p.PD6; + + unsafe { system::init_gpio_irq(sense_coin_pin.pin(), sense_coin_pin.port(), true, false) }; + unsafe { system::init_gpio_irq(main_btn_pin.pin(), main_btn_pin.port(), true, true) }; + + let sense_coin_pin = Input::new(sense_coin_pin, Pull::None); + let main_btn_pin = Input::new(main_btn_pin, Pull::None); + + let mut t = Timer::new(p.TIM1); + // // t.stop(); + // // t.enable_channel(ch32_hal::timer::Channel::Ch1, false); + // // t.enable_channel(ch32_hal::timer::Channel::Ch2, false); + // // t.enable_channel(ch32_hal::timer::Channel::Ch3, false); + // // t.enable_channel(ch32_hal::timer::Channel::Ch4, false); + // // t.enable_update_interrupt(false); + // // t.set_moe(false); + + t.set_counting_mode(CountingMode::default()); + t.set_frequency(Hertz::khz(300)); + t.enable_outputs(); + t.start(); + + [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] + .iter() + .for_each(|&channel| { + t.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); + t.set_output_compare_preload(channel, true); + t.set_compare_value(channel, 1000); + t.enable_channel(channel, true); + }); + + // [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] + // .iter() + // .for_each(|&channel| { + // t.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); + // t.set_output_compare_preload(channel, false); + // t.enable_channel(channel, false); + // }); + + // t.stop(); + // t.disable_outputs() + + // PWM timer setup + // let mut pwm = SimplePwm::new( + // p.TIM1, + // None, + // // Some(led2_pin), + // None, + // None, + // None, + // Hertz::hz(1), + // CountingMode::default(), + // ); + // drop(pwm); + + // pwm.disable(); + + riscv::asm::delay(1_000_000); + // let sense_coin_pin = p.PC2; + // let main_btn_pin = p.PD6; + // let volume_btn_pin = p.PC6; + // let light_ctrl_btn_pin = p.PC7; + + unsafe { system::enter_standby() }; + riscv::asm::wfi(); + + // t.set_moe(false); + // // pwm.shutdown(); + + // riscv::asm::delay(1_000_000); + + // unsafe { system::enter_standby() }; + // riscv::asm::wfi(); + // let mut b = t.get_compare_value(Channel::Ch1); + // b += 1; + // loop { + // unsafe { + // #[allow(static_mut_refs)] + // INPUT_FLAGS.sense_coin_flag.clear(); + // #[allow(static_mut_refs)] + // INPUT_FLAGS.main_btn_flag.clear(); + // } + // unsafe { system::enter_standby() }; + // riscv::asm::wfi(); + // unsafe { + // #[allow(static_mut_refs)] + // if (INPUT_FLAGS.sense_coin_flag.active() + // || (INPUT_FLAGS.main_btn_flag.active() && main_btn_input.is_high_immediate())) + // && app.should_wake() + // { + // break; + // } + // } + // } + // let mut config = hal::Config::default(); + // config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI; + // unsafe { + // hal::rcc::init(config.rcc); + // } + // unsafe { + // use hal::pac::Interrupt; + // use qingke::interrupt::Priority; + // use qingke_rt::CoreInterrupt; + + // system::clear_interrupt(2, 6); + + // qingke::pfic::set_priority(CoreInterrupt::SysTick as u8, Priority::P15 as u8); + + // qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8); + // qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8); + // } +} + #[qingke_rt::entry] fn main() -> ! { #[cfg(feature = "enable_print")] @@ -588,7 +684,19 @@ fn main() -> ! { // println!("post"); // debug_main(p); - app_main(p); + loop { + unsafe { + hal::rcc::init(hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI); + } + let mut p = unsafe { hal::Peripherals::steal() }; + app_main(p); + + unsafe { + hal::rcc::init(hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI); + } + let mut p = unsafe { hal::Peripherals::steal() }; + shutdown_main(p); + } } #[panic_handler] From f3ac43614cf70eb8f0f82fa542d82b2b7cb772ef Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 15:22:24 -0700 Subject: [PATCH 17/27] fix amp_en --- ch32v-insert-coin/src/app.rs | 11 +++-- ch32v-insert-coin/src/main.rs | 75 +---------------------------------- 2 files changed, 6 insertions(+), 80 deletions(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index e2af3ef..d5ab28a 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -346,6 +346,8 @@ impl App { pub fn init(&mut self) { // self.timers.init(); + self.interfaces.amp.enable(); + self.timers.batt_adc_timer.reset(); self.timers.batt_adc_timer.enable(true); @@ -367,10 +369,11 @@ impl App { // self.timers.led2_timer.reset(); // self.timers.led2_timer.enable(true); - self.services.synth0.set_freq(1); + // self.services.synth0.set_freq(1); self.services.synth0.disable(); - self.services.sequencer.disable(); + + crate::riscv::asm::delay(2_500_000); } pub fn set_state(&mut self, state: State) { @@ -519,14 +522,10 @@ impl App { } else { self.services.sequencer.disable(); self.services.synth0.disable(); - self.interfaces.amp.disable(); } } if self.services.synth0.need_service() { - if !self.interfaces.amp.enabled() { - self.interfaces.amp.enable(); - } let out = match self.services.synth0.service() { Some(value) => value / 6 / self.settings.volume.as_volume_divisor(), None => 0, diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 989a3ff..7517136 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -527,23 +527,12 @@ fn app_main(mut p: hal::Peripherals) { } } } -// // if adc1_timer.need_service() { -// // let val = adc.convert(&mut batt_monitor_pin, hal::adc::SampleTime::CYCLES241); -// // let val = adc.convert(&mut usb_detect_pin, hal::adc::SampleTime::CYCLES241); -// // #[cfg(feature = "enable_print")] -// // println!("ADC value: {}", val); - -// // adc1_timer.reset(); -// // adc1_timer.enable(true); -// // } -// } use ch32_hal::timer::low_level::{OutputCompareMode, Timer}; use ch32_hal::timer::Channel; // fn shutdown_main(p: Peripherals) { fn shutdown_main(p: hal::Peripherals) { - // drop(p.TIM1); // LED0 output setup let led0_pin = OutputOpenDrain::new(p.PC3, Level::Low, Default::default()); let led1_pin = OutputOpenDrain::new(p.PD2, Level::High, Default::default()); @@ -559,78 +548,16 @@ fn shutdown_main(p: hal::Peripherals) { let main_btn_pin = p.PD6; unsafe { system::init_gpio_irq(sense_coin_pin.pin(), sense_coin_pin.port(), true, false) }; - unsafe { system::init_gpio_irq(main_btn_pin.pin(), main_btn_pin.port(), true, true) }; + unsafe { system::init_gpio_irq(main_btn_pin.pin(), main_btn_pin.port(), true, false) }; let sense_coin_pin = Input::new(sense_coin_pin, Pull::None); let main_btn_pin = Input::new(main_btn_pin, Pull::None); - let mut t = Timer::new(p.TIM1); - // // t.stop(); - // // t.enable_channel(ch32_hal::timer::Channel::Ch1, false); - // // t.enable_channel(ch32_hal::timer::Channel::Ch2, false); - // // t.enable_channel(ch32_hal::timer::Channel::Ch3, false); - // // t.enable_channel(ch32_hal::timer::Channel::Ch4, false); - // // t.enable_update_interrupt(false); - // // t.set_moe(false); - - t.set_counting_mode(CountingMode::default()); - t.set_frequency(Hertz::khz(300)); - t.enable_outputs(); - t.start(); - - [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] - .iter() - .for_each(|&channel| { - t.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); - t.set_output_compare_preload(channel, true); - t.set_compare_value(channel, 1000); - t.enable_channel(channel, true); - }); - - // [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] - // .iter() - // .for_each(|&channel| { - // t.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); - // t.set_output_compare_preload(channel, false); - // t.enable_channel(channel, false); - // }); - - // t.stop(); - // t.disable_outputs() - - // PWM timer setup - // let mut pwm = SimplePwm::new( - // p.TIM1, - // None, - // // Some(led2_pin), - // None, - // None, - // None, - // Hertz::hz(1), - // CountingMode::default(), - // ); - // drop(pwm); - - // pwm.disable(); - riscv::asm::delay(1_000_000); - // let sense_coin_pin = p.PC2; - // let main_btn_pin = p.PD6; - // let volume_btn_pin = p.PC6; - // let light_ctrl_btn_pin = p.PC7; unsafe { system::enter_standby() }; riscv::asm::wfi(); - // t.set_moe(false); - // // pwm.shutdown(); - - // riscv::asm::delay(1_000_000); - - // unsafe { system::enter_standby() }; - // riscv::asm::wfi(); - // let mut b = t.get_compare_value(Channel::Ch1); - // b += 1; // loop { // unsafe { // #[allow(static_mut_refs)] From 5934336984edd7122bddc3cc163159dbb650473c Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 15:33:38 -0700 Subject: [PATCH 18/27] add battery level checking --- ch32v-insert-coin/src/main.rs | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 7517136..4f9aaae 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -249,6 +249,15 @@ use insert_coin::TickTimerService; use insert_coin::{TickService, TickServiceData}; fn app_main(mut p: hal::Peripherals) { + // initialize ADC core first, and exit if battery is too low + let mut adc = hal::adc::Adc::new(p.ADC1, Default::default()); + let mut batt_monitor_pin = p.PD4; + let mut adc_core = AdcCore::new(adc, batt_monitor_pin); + let bv = adc_core.get_battery_voltage(); + if bv < 421 { + adc_core.shutdown(); + return; + } // === output setup === // LED0 output setup @@ -292,9 +301,9 @@ fn app_main(mut p: hal::Peripherals) { // === input setup === // adc - let mut adc = hal::adc::Adc::new(p.ADC1, Default::default()); - let mut batt_monitor_pin = p.PD4; - let adc_core = AdcCore::new(adc, batt_monitor_pin); + // let mut adc = hal::adc::Adc::new(p.ADC1, Default::default()); + // let mut batt_monitor_pin = p.PD4; + // let adc_core = AdcCore::new(adc, batt_monitor_pin); // adc2 // let mut usb_detect_dc = hal::adc::Adc::new(p.ADC1, Default::default()); @@ -555,8 +564,18 @@ fn shutdown_main(p: hal::Peripherals) { riscv::asm::delay(1_000_000); - unsafe { system::enter_standby() }; - riscv::asm::wfi(); + loop { + unsafe { system::enter_standby() }; + riscv::asm::wfi(); + unsafe { + #[allow(static_mut_refs)] + if (INPUT_FLAGS.sense_coin_flag.active() || INPUT_FLAGS.main_btn_flag.active()) + // && app.should_wake() + { + break; + } + } + } // loop { // unsafe { From 10a38f9bbc10936f71bb7b67440b9ddff563de1c Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 15:40:08 -0700 Subject: [PATCH 19/27] add shutdown delay --- ch32v-insert-coin/src/app.rs | 1 + ch32v-insert-coin/src/main.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index d5ab28a..1599599 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -565,6 +565,7 @@ impl App { self.interfaces.adc_core.shutdown(); self.interfaces.amp.disable(); + crate::riscv::asm::delay(20_000_000); } pub fn volume_button(&mut self) { self.settings.volume.next(); diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 4f9aaae..6370d78 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -354,7 +354,7 @@ fn app_main(mut p: hal::Peripherals) { led1_timer_ms: 100, // 4 hours: // shutdown_timer_s: 1, - shutdown_timer_s: 4 * 60 * 60, + shutdown_timer_s: 4 * 60 * 60 * 30 / 100, // led2_timer_ms: 100, }; From 60d6aaecd6a93c6d0566bf4319899c7029c148fc Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 15:55:23 -0700 Subject: [PATCH 20/27] add ability for main button sound --- ch32v-insert-coin/src/app.rs | 14 ++++---------- ch32v-insert-coin/src/main.rs | 24 ++++++++++++++++++------ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index 1599599..1d5d0f3 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -550,22 +550,16 @@ impl App { pub fn shut_down(&mut self) { self.interfaces .pwm_core - .disable(ch32_hal::timer::Channel::Ch1); + .write_amplitude(self.services.led0.channel, 0); self.interfaces .pwm_core - .disable(ch32_hal::timer::Channel::Ch2); - self.interfaces - .pwm_core - .disable(ch32_hal::timer::Channel::Ch3); - self.interfaces - .pwm_core - .disable(ch32_hal::timer::Channel::Ch4); + .write_amplitude(self.services.led1.channel, 0); + crate::riscv::asm::delay(20_000_000); self.interfaces.pwm_core.pwm.borrow().shutdown(); self.interfaces.adc_core.shutdown(); self.interfaces.amp.disable(); - crate::riscv::asm::delay(20_000_000); } pub fn volume_button(&mut self) { self.settings.volume.next(); @@ -629,7 +623,7 @@ impl App { // Events impl App { - fn main_button_click(&mut self) { + pub fn main_button_click(&mut self) { // TODO #[cfg(feature = "enable_print")] println!("click"); diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 6370d78..ca5a9dd 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -268,10 +268,6 @@ fn app_main(mut p: hal::Peripherals) { let led1_pin = PwmPin::new_ch1::<0>(p.PD2); let led1_ch = hal::timer::Channel::Ch1; - // // LED2 output setup - // let led2_pin = PwmPin::new_ch2::<0>(p.PA1); - // let led2_ch = hal::timer::Channel::Ch2; - // DAC output setup let dac_pin = PwmPin::new_ch4::<0>(p.PC4); // let dac_ch = hal::timer::Channel::Ch4; @@ -290,14 +286,16 @@ fn app_main(mut p: hal::Peripherals) { pwm.set_polarity(led0_ch, OutputPolarity::ActiveHigh); pwm.set_polarity(led1_ch, OutputPolarity::ActiveLow); + let mut pwm_core = SimplePwmCore::new(pwm); + pwm_core.write_amplitude(led0_ch, 0); + pwm_core.write_amplitude(led1_ch, 0); + // pwm.set_polarity(led2_ch, OutputPolarity::ActiveLow); let tick_rate_hz = 50000; let core_config = CoreConfig::new(tick_rate_hz); - let pwm_core = SimplePwmCore::new(pwm); - // === input setup === // adc @@ -401,6 +399,17 @@ fn app_main(mut p: hal::Peripherals) { let mut app = App::new(app_config, app_services, app_sequences, app_interfaces); + let need_sound = unsafe { + #[allow(static_mut_refs)] + if INPUT_FLAGS.main_btn_flag.active() { + #[allow(static_mut_refs)] + INPUT_FLAGS.main_btn_flag.clear(); + true + } else { + false + } + }; + // init systick systick_init(tick_rate_hz); @@ -432,6 +441,9 @@ fn app_main(mut p: hal::Peripherals) { let mut light_ctrl_btn_prev = light_ctrl_btn_input.is_high_immediate(); app.init(); + if need_sound { + app.main_button_click(); + } loop { // system servicing From f26920a0994c811d18f4fb47d663e9af19b2d735 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 16:03:32 -0700 Subject: [PATCH 21/27] add persistent settings --- ch32v-insert-coin/src/app.rs | 8 ++++++-- ch32v-insert-coin/src/main.rs | 19 ++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index 1d5d0f3..775a908 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -9,7 +9,7 @@ pub enum State { Active, } -mod settings { +pub mod settings { #[derive(Debug, Default, Clone, Copy)] pub enum Level { @@ -333,10 +333,11 @@ impl App { services: Services, sequences: Sequences, interfaces: Interfaces, + settings: Settings, ) -> Self { Self { state: State::default(), - settings: Settings::default(), + settings, timers: Timers::new(config.timers, config.system_tick_rate_hz), services, sequences, @@ -659,6 +660,9 @@ impl App { pub fn get_state(&self) -> State { self.state } + pub fn get_settings(&self) -> Settings { + self.settings + } pub fn should_wake(&self) -> bool { if self.interfaces.usb.powered() { return true; diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index ca5a9dd..c92f562 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -245,10 +245,11 @@ bind_interrupts!(struct Irqs { }); // TODO: remove +use app::settings::Settings; use insert_coin::TickTimerService; use insert_coin::{TickService, TickServiceData}; -fn app_main(mut p: hal::Peripherals) { +fn app_main(mut p: hal::Peripherals, app_settings: Settings) -> Settings { // initialize ADC core first, and exit if battery is too low let mut adc = hal::adc::Adc::new(p.ADC1, Default::default()); let mut batt_monitor_pin = p.PD4; @@ -256,7 +257,7 @@ fn app_main(mut p: hal::Peripherals) { let bv = adc_core.get_battery_voltage(); if bv < 421 { adc_core.shutdown(); - return; + return app_settings; } // === output setup === @@ -397,7 +398,13 @@ fn app_main(mut p: hal::Peripherals) { usb, }; - let mut app = App::new(app_config, app_services, app_sequences, app_interfaces); + let mut app = App::new( + app_config, + app_services, + app_sequences, + app_interfaces, + app_settings, + ); let need_sound = unsafe { #[allow(static_mut_refs)] @@ -542,7 +549,7 @@ fn app_main(mut p: hal::Peripherals) { // enter standby app::State::DeepSleep => { app.shut_down(); - return; + return app.get_settings(); } _ => {} } @@ -642,12 +649,14 @@ fn main() -> ! { // println!("post"); // debug_main(p); + let mut app_settings = Settings::default(); + loop { unsafe { hal::rcc::init(hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI); } let mut p = unsafe { hal::Peripherals::steal() }; - app_main(p); + app_settings = app_main(p, app_settings); unsafe { hal::rcc::init(hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI); From d053f8d080448f353b4ca56492e336976e4b04f7 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 16:06:54 -0700 Subject: [PATCH 22/27] decrease wait time for app shutdown --- ch32v-insert-coin/src/app.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index 775a908..14138f8 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -555,7 +555,7 @@ impl App { self.interfaces .pwm_core .write_amplitude(self.services.led1.channel, 0); - crate::riscv::asm::delay(20_000_000); + crate::riscv::asm::delay(10_000_000); self.interfaces.pwm_core.pwm.borrow().shutdown(); self.interfaces.adc_core.shutdown(); From 1d2e4a5482c46e26979400505010ac44a8426433 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 16:09:06 -0700 Subject: [PATCH 23/27] update shutdown timer addtl time to 10% from 30% --- ch32v-insert-coin/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index c92f562..c628f65 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -353,7 +353,7 @@ fn app_main(mut p: hal::Peripherals, app_settings: Settings) -> Settings { led1_timer_ms: 100, // 4 hours: // shutdown_timer_s: 1, - shutdown_timer_s: 4 * 60 * 60 * 30 / 100, + shutdown_timer_s: 4 * 60 * 60 * 10 / 100, // led2_timer_ms: 100, }; From 4c80907c0f417562648e2371608f4abdaad51794 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 16:10:35 -0700 Subject: [PATCH 24/27] change fudge factor to 110% bc i'm stupid --- ch32v-insert-coin/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index c628f65..9e6ea47 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -353,7 +353,7 @@ fn app_main(mut p: hal::Peripherals, app_settings: Settings) -> Settings { led1_timer_ms: 100, // 4 hours: // shutdown_timer_s: 1, - shutdown_timer_s: 4 * 60 * 60 * 10 / 100, + shutdown_timer_s: 4 * 60 * 60 * 110 / 100, // led2_timer_ms: 100, }; From 472e43056dc03b4978611117520cb03867b16576 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 16:23:18 -0700 Subject: [PATCH 25/27] add systick disable --- ch32v-insert-coin/src/main.rs | 45 +++++++---------------------------- 1 file changed, 8 insertions(+), 37 deletions(-) diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 9e6ea47..4556f25 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -239,6 +239,13 @@ fn systick_init(tick_freq_hz: usize) { w.set_stclk(ch32_hal::pac::systick::vals::Stclk::HCLK_DIV8); // HCLK/8 clock source }); } +fn systick_stop() { + let r = &ch32_hal::pac::SYSTICK; + // Reset SysTick + r.ctlr().write(|w| { + // Start with everything disabled + }); +} bind_interrupts!(struct Irqs { EXTI7_0 => Test; @@ -561,6 +568,7 @@ use ch32_hal::timer::Channel; // fn shutdown_main(p: Peripherals) { fn shutdown_main(p: hal::Peripherals) { + systick_stop(); // LED0 output setup let led0_pin = OutputOpenDrain::new(p.PC3, Level::Low, Default::default()); let led1_pin = OutputOpenDrain::new(p.PD2, Level::High, Default::default()); @@ -595,43 +603,6 @@ fn shutdown_main(p: hal::Peripherals) { } } } - - // loop { - // unsafe { - // #[allow(static_mut_refs)] - // INPUT_FLAGS.sense_coin_flag.clear(); - // #[allow(static_mut_refs)] - // INPUT_FLAGS.main_btn_flag.clear(); - // } - // unsafe { system::enter_standby() }; - // riscv::asm::wfi(); - // unsafe { - // #[allow(static_mut_refs)] - // if (INPUT_FLAGS.sense_coin_flag.active() - // || (INPUT_FLAGS.main_btn_flag.active() && main_btn_input.is_high_immediate())) - // && app.should_wake() - // { - // break; - // } - // } - // } - // let mut config = hal::Config::default(); - // config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI; - // unsafe { - // hal::rcc::init(config.rcc); - // } - // unsafe { - // use hal::pac::Interrupt; - // use qingke::interrupt::Priority; - // use qingke_rt::CoreInterrupt; - - // system::clear_interrupt(2, 6); - - // qingke::pfic::set_priority(CoreInterrupt::SysTick as u8, Priority::P15 as u8); - - // qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8); - // qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8); - // } } #[qingke_rt::entry] From d8477e3d2d6b74ce14b8a260b5ad6d4a06734fa8 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 15 Nov 2025 16:38:07 -0700 Subject: [PATCH 26/27] add usb power gating --- ch32v-insert-coin/src/main.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index 4556f25..694ce75 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -261,8 +261,15 @@ fn app_main(mut p: hal::Peripherals, app_settings: Settings) -> Settings { let mut adc = hal::adc::Adc::new(p.ADC1, Default::default()); let mut batt_monitor_pin = p.PD4; let mut adc_core = AdcCore::new(adc, batt_monitor_pin); + + let mut usb_detect_pin = p.PD5; + let usb_detect_input = Input::new(usb_detect_pin, Pull::Up); + let usb = Usb::new(usb_detect_input); + let bv = adc_core.get_battery_voltage(); - if bv < 421 { + + // if we don't have USB power, and the batt ADC reads under 421, don't wake + if !usb.powered() && bv < 421 { adc_core.shutdown(); return app_settings; } @@ -313,9 +320,6 @@ fn app_main(mut p: hal::Peripherals, app_settings: Settings) -> Settings { // adc2 // let mut usb_detect_dc = hal::adc::Adc::new(p.ADC1, Default::default()); - let mut usb_detect_pin = p.PD5; - let usb_detect_input = Input::new(usb_detect_pin, Pull::Up); - let usb = Usb::new(usb_detect_input); // println!("ADC_PIN CHANNEL: {}", adc_pin.channel().channel()); From 3265325d283fc4c0ac3f6d212ec42d367bad0cd1 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Mon, 17 Nov 2025 18:42:16 -0700 Subject: [PATCH 27/27] add coin chirp when you click the volume button --- ch32v-insert-coin/src/app.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index 14138f8..a8fdbb8 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -566,6 +566,9 @@ impl App { self.settings.volume.next(); #[cfg(feature = "enable_print")] println!("new volume: {:?}", self.settings.volume); + self.services + .sequencer + .play_sequence(&crate::sequences::COIN_CHIRP, 0); self.timers.shutdown_timer.reset(); self.timers.shutdown_timer.enable(true); }