From 1bdb68c0d41cb86d61aed06ed1b3d2481a0f63cd Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Thu, 6 Nov 2025 10:53:57 -0700 Subject: [PATCH] add some sequences --- ch32v-insert-coin/src/app.rs | 10 +- ch32v-insert-coin/src/main.rs | 75 ++--- ch32v-insert-coin/src/sequences.rs | 505 +++++++++++++++++++++++++++++ 3 files changed, 542 insertions(+), 48 deletions(-) create mode 100644 ch32v-insert-coin/src/sequences.rs diff --git a/ch32v-insert-coin/src/app.rs b/ch32v-insert-coin/src/app.rs index 47194e3..28b22f2 100644 --- a/ch32v-insert-coin/src/app.rs +++ b/ch32v-insert-coin/src/app.rs @@ -295,7 +295,7 @@ pub struct Sequences { pub led0: sequencer::BasicSequence<'static>, pub led1: sequencer::BasicSequence<'static>, pub led2: sequencer::BasicSequence<'static>, - pub audio: [&'static [sequencer::SequenceEntry]; 2], + pub audio: &'static [&'static [sequencer::SequenceEntry]], } // things that touch hardware @@ -439,9 +439,15 @@ impl App { self.services.led2.service(); } + // TODO: disable when you get to the end automatically + // in the sequencer, not here if self.services.sequencer.need_service() { if let Some(out) = self.services.sequencer.service() { - self.services.synth0.set_freq(out.into()); + if out == 0 { + self.services.synth0.disable(); + } else { + self.services.synth0.set_freq(out.into()); + } } else { self.services.sequencer.disable(); self.services.synth0.disable(); diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index bb0678a..481fc31 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -16,6 +16,10 @@ use debounced_gpio::DebouncedGPIO; mod synthesizer; use synthesizer::SynthesizerService; +// sequences +mod sequences; +use sequences::SEQUENCE_LIST; + mod app; use app::{ sequencer::BasicSequence, App, Config, Interfaces, Sequences, Services, State, TimerConfig, @@ -39,27 +43,6 @@ use qingke::riscv; use crate::app::sequencer::{DynamicSequence, SequenceEntry}; static LED0_SEQ: [u8; 8] = [0u8, 25u8, 50u8, 75u8, 100u8, 75u8, 50u8, 25u8]; -pub static TEST_SEQ: [app::sequencer::SequenceEntry; 2] = [ - SequenceEntry { - frequency_hz: 440, - duration_ms: 1000, - }, - SequenceEntry { - frequency_hz: 220, - duration_ms: 1000, - }, -]; - -pub static TEST_SEQ1: [app::sequencer::SequenceEntry; 2] = [ - SequenceEntry { - frequency_hz: 440, - duration_ms: 100, - }, - SequenceEntry { - frequency_hz: 220, - duration_ms: 100, - }, -]; #[derive(Debug)] struct Flag { @@ -284,7 +267,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { let sample_player = DacService::new(ch32_hal::timer::Channel::Ch4, dac_service_data); sample_player.load_data(coin_sound); - let sequencer = app::sequencer::DynamicSequence::new(&TEST_SEQ, tick_rate_hz); + let sequencer = app::sequencer::DynamicSequence::new(&SEQUENCE_LIST[0], tick_rate_hz); let app_services = Services { led0: LedService::new(led0_ch), @@ -299,7 +282,7 @@ fn app_main(mut p: hal::Peripherals) -> ! { led0: BasicSequence::new(&LED0_SEQ), led1: BasicSequence::new(&LED0_SEQ), led2: BasicSequence::new(&LED0_SEQ), - audio: [&TEST_SEQ, &TEST_SEQ1], + audio: &SEQUENCE_LIST, }; let app_interfaces = Interfaces { pwm_core }; @@ -431,29 +414,29 @@ fn app_main(mut p: hal::Peripherals) -> ! { app.service(); - match app.get_state() { - // enter standby - app::State::DeepSleep => { - unsafe { system::enter_standby() }; - loop { - 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() { - app.set_state(State::Active); - break; - } - }; - } - } - // for everything else, don't do anything - _ => {} - } + // match app.get_state() { + // // enter standby + // app::State::DeepSleep => { + // unsafe { system::enter_standby() }; + // loop { + // 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() { + // app.set_state(State::Active); + // break; + // } + // }; + // } + // } + // // for everything else, don't do anything + // _ => {} + // } } } // // if adc1_timer.need_service() { diff --git a/ch32v-insert-coin/src/sequences.rs b/ch32v-insert-coin/src/sequences.rs new file mode 100644 index 0000000..55cac19 --- /dev/null +++ b/ch32v-insert-coin/src/sequences.rs @@ -0,0 +1,505 @@ +use crate::app::sequencer::SequenceEntry; + +pub static TEST_SEQ: [SequenceEntry; 2] = [ + SequenceEntry { + frequency_hz: 440, + duration_ms: 1000, + }, + SequenceEntry { + frequency_hz: 220, + duration_ms: 1000, + }, +]; + +pub static TEST_SEQ1: [SequenceEntry; 2] = [ + SequenceEntry { + frequency_hz: 440, + duration_ms: 100, + }, + SequenceEntry { + frequency_hz: 220, + duration_ms: 100, + }, +]; + +// play twice +pub static WAHWAH: [SequenceEntry; 9] = [ + SequenceEntry { + frequency_hz: 100, + duration_ms: 25, + }, + SequenceEntry { + frequency_hz: 200, + duration_ms: 25, + }, + SequenceEntry { + frequency_hz: 300, + duration_ms: 25, + }, + SequenceEntry { + frequency_hz: 400, + duration_ms: 25, + }, + SequenceEntry { + frequency_hz: 500, + duration_ms: 25, + }, + SequenceEntry { + frequency_hz: 600, + duration_ms: 25, + }, + SequenceEntry { + frequency_hz: 700, + duration_ms: 25, + }, + SequenceEntry { + frequency_hz: 800, + duration_ms: 25, + }, + SequenceEntry { + frequency_hz: 900, + duration_ms: 25, + }, +]; + +pub static DECENDING_TONES: [SequenceEntry; 71] = [ + // SequenceEntry { + // frequency_hz: 1000, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 990, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 980, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 970, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 960, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 950, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 940, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 930, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 920, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 910, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 900, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 890, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 880, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 870, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 860, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 850, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 840, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 830, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 820, + // duration_ms: 50, + // }, + // SequenceEntry { + // frequency_hz: 810, + // duration_ms: 50, + // }, + SequenceEntry { + frequency_hz: 800, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 790, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 780, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 770, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 760, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 750, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 740, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 730, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 720, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 710, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 700, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 690, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 680, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 670, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 660, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 650, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 640, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 630, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 620, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 610, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 600, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 590, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 580, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 570, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 560, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 550, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 540, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 530, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 520, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 510, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 500, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 490, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 480, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 470, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 460, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 450, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 440, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 430, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 420, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 410, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 400, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 390, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 380, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 370, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 360, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 350, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 340, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 330, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 320, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 310, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 300, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 290, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 280, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 270, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 260, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 250, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 240, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 230, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 220, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 210, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 200, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 190, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 180, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 170, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 160, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 150, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 140, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 130, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 120, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 110, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 100, + duration_ms: 50, + }, +]; + +// PLAY ONCE +pub static COIN_CHIRP: [SequenceEntry; 2] = [ + SequenceEntry { + frequency_hz: 1000, + duration_ms: 100, + }, + SequenceEntry { + frequency_hz: 1500, + duration_ms: 500, + }, +]; + +// PLAY ONCE +pub static SOUND_8_BIT_GAME: [SequenceEntry; 3] = [ + SequenceEntry { + frequency_hz: 440, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 660, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 880, + duration_ms: 50, + }, +]; + +// PLAY TWICE +// TODO: this isn't working quite right with the 0hz "non note" for a rest... +pub static SOUND_8_BIT_GAME_1: [SequenceEntry; 4] = [ + SequenceEntry { + frequency_hz: 440, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 880, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 0, + duration_ms: 1000, + }, + SequenceEntry { + frequency_hz: 880, + duration_ms: 50, + }, +]; + +// PLAY 3 TIMES +pub static SOUND_8_BIT_GAME_3: [SequenceEntry; 3] = [ + SequenceEntry { + frequency_hz: 440, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 660, + duration_ms: 50, + }, + SequenceEntry { + frequency_hz: 1500, + duration_ms: 50, + }, +]; + +pub static SEQUENCE_LIST: [&'static [SequenceEntry]; 6] = [ + &SOUND_8_BIT_GAME_3, + &SOUND_8_BIT_GAME_1, + &SOUND_8_BIT_GAME, + &COIN_CHIRP, + &WAHWAH, + &DECENDING_TONES, + // &TEST_SEQ, +];