convert app to tick servicing

This commit is contained in:
sigil-03 2025-11-02 10:59:10 -07:00
parent 008bf334a4
commit 791d5db4c8
3 changed files with 460 additions and 269 deletions

View file

@ -1,4 +1,4 @@
#[derive(Default)] #[derive(Default, Clone, Copy)]
pub enum State { pub enum State {
// system is asleep, waiting for wake from coin insertion // system is asleep, waiting for wake from coin insertion
DeepSleep, DeepSleep,
@ -10,9 +10,12 @@ pub enum State {
} }
mod settings { mod settings {
#[derive(Default, Clone, Copy)]
pub enum Level { pub enum Level {
Off, Off,
Low, Low,
#[default]
Medium, Medium,
High, High,
Maximum, Maximum,
@ -30,6 +33,7 @@ mod settings {
} }
} }
#[derive(Clone, Copy)]
pub struct Settings { pub struct Settings {
pub brightness: Level, pub brightness: Level,
pub volume: Level, pub volume: Level,
@ -47,20 +51,180 @@ mod settings {
} }
} }
use crate::insert_coin::{TickService, TickServiceData, TickTimerService};
pub use settings::Settings; pub use settings::Settings;
#[cfg(feature = "enable_print")]
use ch32_hal::println;
pub struct TimerConfig {
pub sp_timer_ms: usize,
pub lp_timer_ms: usize,
pub batt_adc_timer_ms: usize,
pub usb_adc_timer_ms: usize,
pub led0_timer_ms: usize,
pub led1_timer_ms: usize,
pub led2_timer_ms: usize,
}
pub struct Timers {
sp_timer: TickTimerService,
lp_timer: TickTimerService,
batt_adc_timer: TickTimerService,
usb_adc_timer: TickTimerService,
led0_timer: TickTimerService,
led1_timer: TickTimerService,
led2_timer: TickTimerService,
}
impl Timers {
pub fn new(config: TimerConfig, system_tick_rate_hz: usize) -> Self {
Self {
sp_timer: TickTimerService::new(
TickServiceData::new(config.sp_timer_ms * system_tick_rate_hz / 1000),
false,
),
lp_timer: TickTimerService::new(
TickServiceData::new(config.lp_timer_ms * system_tick_rate_hz / 1000),
false,
),
batt_adc_timer: TickTimerService::new(
TickServiceData::new(config.batt_adc_timer_ms * system_tick_rate_hz / 1000),
false,
),
usb_adc_timer: TickTimerService::new(
TickServiceData::new(config.usb_adc_timer_ms * system_tick_rate_hz / 1000),
false,
),
led0_timer: TickTimerService::new(
TickServiceData::new(config.led0_timer_ms * system_tick_rate_hz / 1000),
true,
),
led1_timer: TickTimerService::new(
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,
),
}
}
pub fn tick(&mut self) {
self.sp_timer.tick();
self.lp_timer.tick();
self.batt_adc_timer.tick();
self.usb_adc_timer.tick();
self.led0_timer.tick();
self.led1_timer.tick();
self.led2_timer.tick();
}
pub fn need_service(&self) -> bool {
self.sp_timer.need_service()
| self.lp_timer.need_service()
| self.batt_adc_timer.need_service()
| self.usb_adc_timer.need_service()
| self.led0_timer.need_service()
| self.led1_timer.need_service()
| self.led2_timer.need_service()
}
pub fn init(&mut self) {
self.led0_timer.reset();
self.led0_timer.enable(true);
}
}
pub struct Config {
pub system_tick_rate_hz: usize,
pub timers: TimerConfig,
}
pub struct App { pub struct App {
state: State, state: State,
pub settings: Settings, pub settings: Settings,
timers: Timers,
// TODO: make this the "sound module" or whatever. // TODO: make this the "sound module" or whatever.
// synthesizers: AppSynthesizers, // synthesizers: AppSynthesizers,
} }
impl Default for App { impl App {
fn default() -> Self { pub fn new(config: Config) -> Self {
Self { Self {
state: State::default(), state: State::default(),
settings: Settings::default(), settings: Settings::default(),
timers: Timers::new(config.timers, config.system_tick_rate_hz),
}
}
pub fn init(&mut self) {
// self.timers.init();
self.timers.batt_adc_timer.reset();
self.timers.batt_adc_timer.enable(true);
self.timers.usb_adc_timer.reset();
self.timers.usb_adc_timer.enable(true);
self.timers.led0_timer.reset();
self.timers.led0_timer.enable(true);
self.timers.led1_timer.reset();
self.timers.led1_timer.enable(true);
self.timers.led2_timer.reset();
self.timers.led2_timer.enable(true);
}
pub fn set_state(&mut self, state: State) {
self.state = state
}
pub fn state(&self) -> State {
self.state
}
pub fn settings(&self) -> Settings {
self.settings
}
pub fn tick(&mut self) {
self.timers.tick();
}
pub fn service(&mut self) {
if self.timers.sp_timer.need_service() {
self.timers.batt_adc_timer.service();
#[cfg(feature = "enable_print")]
println!("sp service");
}
if self.timers.lp_timer.need_service() {
self.timers.batt_adc_timer.service();
#[cfg(feature = "enable_print")]
println!("lp service");
}
if self.timers.batt_adc_timer.need_service() {
self.timers.batt_adc_timer.service();
#[cfg(feature = "enable_print")]
println!("batt adc service");
}
if self.timers.usb_adc_timer.need_service() {
self.timers.usb_adc_timer.service();
#[cfg(feature = "enable_print")]
println!("usb adc service");
}
if self.timers.led0_timer.need_service() {
self.timers.led0_timer.service();
#[cfg(feature = "enable_print")]
println!("led0 service");
}
if self.timers.led1_timer.need_service() {
self.timers.led1_timer.service();
#[cfg(feature = "enable_print")]
println!("led1 service");
}
if self.timers.led2_timer.need_service() {
self.timers.led2_timer.service();
#[cfg(feature = "enable_print")]
println!("led2 service");
} }
} }
} }

View file

@ -14,7 +14,7 @@ mod synthesizer;
use synthesizer::AppSynthesizers; use synthesizer::AppSynthesizers;
mod app; mod app;
use app::App; use app::{App, Config, State, TimerConfig};
use ch32_hal::{adc::AdcChannel, interrupt::typelevel::Handler, timer::low_level::OutputPolarity}; use ch32_hal::{adc::AdcChannel, interrupt::typelevel::Handler, timer::low_level::OutputPolarity};
use insert_coin::{CoreConfig, InsertCoin, SimplePwmCore}; use insert_coin::{CoreConfig, InsertCoin, SimplePwmCore};
@ -108,14 +108,36 @@ pub enum SystemState {
Active, Active,
} }
#[derive(Debug)]
struct Flag {
value: bool,
}
impl Flag {
pub fn active(&self) -> bool {
unsafe { core::ptr::read_volatile(&raw const self.value as *const bool) }
}
pub fn set(&mut self) {
unsafe { core::ptr::write_volatile(&raw mut self.value as *mut bool, true) }
}
pub fn clear(&mut self) {
unsafe { core::ptr::write_volatile(&raw mut self.value as *mut bool, false) }
}
}
#[derive(Debug)] #[derive(Debug)]
struct InputFlags { struct InputFlags {
sense_coin_flag: bool, sense_coin_flag: bool,
main_btn_flag: bool, main_btn_flag: bool,
volume_btn_flag: bool, volume_btn_flag: bool,
light_ctrl_btn_flag: bool, light_ctrl_btn_flag: bool,
systick_flag: Flag,
// synth_tick_flag: bool,
} }
// impl InputFlags {
// pub fn sense_coin_flag(&self) -> bool {}
// }
impl Default for InputFlags { impl Default for InputFlags {
fn default() -> Self { fn default() -> Self {
Self { Self {
@ -123,6 +145,7 @@ impl Default for InputFlags {
main_btn_flag: false, main_btn_flag: false,
volume_btn_flag: false, volume_btn_flag: false,
light_ctrl_btn_flag: false, light_ctrl_btn_flag: false,
systick_flag: Flag { value: false },
} }
} }
} }
@ -147,6 +170,7 @@ static mut INPUT_FLAGS: InputFlags = InputFlags {
main_btn_flag: false, main_btn_flag: false,
volume_btn_flag: false, volume_btn_flag: false,
light_ctrl_btn_flag: false, light_ctrl_btn_flag: false,
systick_flag: Flag { value: false },
}; };
struct Test {} struct Test {}
@ -216,20 +240,24 @@ fn SysTick() {
// } // }
SYNTH_TICK_FLAG = true; SYNTH_TICK_FLAG = true;
if SYSTICK_COUNT % 5000 == 0 { // safe because single-threaded
NOTE_TICK_FLAG = true; #[allow(static_mut_refs)]
} INPUT_FLAGS.systick_flag.set();
if SYSTICK_COUNT % 50000 == 0 { // if SYSTICK_COUNT % 5000 == 0 {
TICK_FLAG = true; // NOTE_TICK_FLAG = true;
// if let Some(ref mut led) = LED { // }
// let toggle = TOGGLE_COUNT;
// // println!("TOGGLE {toggle}"); // if SYSTICK_COUNT % 50000 == 0 {
// TOGGLE_COUNT += 1; // TICK_FLAG = true;
// led.toggle(); // // if let Some(ref mut led) = LED {
// } // // let toggle = TOGGLE_COUNT;
// println!("HERE"); // // // println!("TOGGLE {toggle}");
} // // TOGGLE_COUNT += 1;
// // led.toggle();
// // }
// // println!("HERE");
// }
SYSTICK_COUNT = SYSTICK_COUNT.wrapping_add(1); SYSTICK_COUNT = SYSTICK_COUNT.wrapping_add(1);
} }
} }
@ -370,7 +398,7 @@ fn debug_main(mut p: hal::Peripherals) -> ! {
} }
} }
fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! { fn app_main(mut p: hal::Peripherals) -> ! {
// === output setup === // === output setup ===
// LED0 output setup // LED0 output setup
@ -430,7 +458,6 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
let mut usb_detect_pin = p.PD5; let mut usb_detect_pin = p.PD5;
// println!("ADC_PIN CHANNEL: {}", adc_pin.channel().channel()); // println!("ADC_PIN CHANNEL: {}", adc_pin.channel().channel());
delay.delay_ms(1000);
let adc_cal = adc.calibrate(); let adc_cal = adc.calibrate();
#[cfg(feature = "enable_print")] #[cfg(feature = "enable_print")]
@ -473,10 +500,6 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
let mut interfaces = InsertCoin::new(core_config, pwm_core); let mut interfaces = InsertCoin::new(core_config, pwm_core);
interfaces.set_active(true); interfaces.set_active(true);
// insert_coin.init();
// let mut settings = Se::default();
let mut app = App::default();
let mut led0_index = 0; let mut led0_index = 0;
let led0_dcs = [0u8, 25u8, 50u8, 75u8, 100u8, 75u8, 50u8, 25u8]; let led0_dcs = [0u8, 25u8, 50u8, 75u8, 100u8, 75u8, 50u8, 25u8];
@ -484,39 +507,32 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
let mut led1_index = 0; let mut led1_index = 0;
let led1_dcs = [0u8, 25u8, 50u8, 75u8, 100u8]; let led1_dcs = [0u8, 25u8, 50u8, 75u8, 100u8];
// tick timer 0 // // battery read timer
let tt0_fire_rate_hz = 9; // let adc1_ticks = 5 * interfaces.config.tick_rate_hz;
let tt0_tick_per_service = interfaces.config.tick_rate_hz / (tt0_fire_rate_hz * 2); // let adc1_timer_data = TickServiceData::new(adc1_ticks);
let tt0_service_data = TickServiceData::new(tt0_tick_per_service); // let mut adc1_timer = TickTimerService::new(adc1_timer_data, false);
let mut tt0 = TickTimerService::new(tt0_service_data, true); // adc1_timer.reset();
// adc1_timer.enable(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 mut tt1 = TickTimerService::new(tt1_service_data, true);
// 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();
// battery read timer
let adc1_ticks = 5 * interfaces.config.tick_rate_hz;
let adc1_timer_data = TickServiceData::new(adc1_ticks);
let mut adc1_timer = TickTimerService::new(adc1_timer_data, false);
adc1_timer.reset();
adc1_timer.enable(true);
let tick_interval_us = 1000000 / interfaces.config.tick_rate_hz - 10; let tick_interval_us = 1000000 / interfaces.config.tick_rate_hz - 10;
let timer_config = TimerConfig {
sp_timer_ms: 2000,
lp_timer_ms: 5000,
batt_adc_timer_ms: 10000,
usb_adc_timer_ms: 10000,
led0_timer_ms: 1000,
led1_timer_ms: 300,
led2_timer_ms: 1100,
};
let app_config = Config {
system_tick_rate_hz: tick_rate_hz,
timers: timer_config,
};
let mut app = App::new(app_config);
// dac data // dac data
// let coin_sound = include_bytes!("../audio/coin2.raw"); // let coin_sound = include_bytes!("../audio/coin2.raw");
// let coin_sound = include_bytes!("../audio/sweep_dpcm_u4.raw"); // let coin_sound = include_bytes!("../audio/sweep_dpcm_u4.raw");
@ -526,20 +542,25 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
// let button_sound_2 = include_bytes!("../audio/button_2.raw"); // let button_sound_2 = include_bytes!("../audio/button_2.raw");
// let button_sound_3 = include_bytes!("../audio/button_3.raw"); // let button_sound_3 = include_bytes!("../audio/button_3.raw");
let mut system_state = SystemState::Active;
interfaces.led0.set_amplitude(0); interfaces.led0.set_amplitude(0);
interfaces.led1.set_amplitude(0); interfaces.led1.set_amplitude(0);
interfaces.service(); interfaces.service();
// init systick
systick_init(tick_rate_hz);
// set up interrupts
unsafe { unsafe {
use hal::pac::Interrupt; use hal::pac::Interrupt;
// use qingke_rt::CoreInterrupt; use qingke::interrupt::Priority;
use qingke_rt::CoreInterrupt;
// qingke::pfic::unpend_interrupt(Interrupt::EXTI7_0 as u8);
system::clear_interrupt(2, 6); 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(Interrupt::EXTI7_0 as u8);
// qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8); qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8);
} }
// MAIN APPLICATION // MAIN APPLICATION
@ -555,210 +576,227 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
let mut volume_btn_prev = volume_btn_input.is_high_immediate(); let mut volume_btn_prev = volume_btn_input.is_high_immediate();
let mut light_ctrl_btn_prev = light_ctrl_btn_input.is_high_immediate(); let mut light_ctrl_btn_prev = light_ctrl_btn_input.is_high_immediate();
app.init();
loop { loop {
// edge detector // system servicing
if !volume_btn_input.active() {
let volume_btn_curr = volume_btn_input.is_high_immediate();
if volume_btn_prev != volume_btn_curr {
volume_btn_prev = volume_btn_curr;
unsafe {
INPUT_FLAGS.volume_btn_flag = true;
}
}
}
if !light_ctrl_btn_input.active() { // systick tick
let light_ctrl_btn_curr = light_ctrl_btn_input.is_high_immediate(); if unsafe {
if light_ctrl_btn_prev != light_ctrl_btn_curr { #[allow(static_mut_refs)]
light_ctrl_btn_prev = light_ctrl_btn_curr; INPUT_FLAGS.systick_flag.active()
unsafe { } {
INPUT_FLAGS.light_ctrl_btn_flag = true;
}
}
}
{
// system input servicing
unsafe { unsafe {
if INPUT_FLAGS.sense_coin_flag { #[allow(static_mut_refs)]
#[cfg(feature = "enable_print")] INPUT_FLAGS.systick_flag.clear();
println!("coin flag active");
INPUT_FLAGS.sense_coin_flag = false;
sense_coin_input.begin();
// enter the active state
system_state = SystemState::Active;
// todo: enter active
tt0.enable(true);
tt1.enable(true);
// interfaces.dac.load_data(coin_sound);
}
if INPUT_FLAGS.main_btn_flag {
#[cfg(feature = "enable_print")]
println!("button flag active");
INPUT_FLAGS.main_btn_flag = false;
main_btn_input.begin();
}
if INPUT_FLAGS.volume_btn_flag {
#[cfg(feature = "enable_print")]
println!("volume btn triggered");
INPUT_FLAGS.volume_btn_flag = false;
volume_btn_input.begin();
}
if INPUT_FLAGS.light_ctrl_btn_flag {
#[cfg(feature = "enable_print")]
println!("light ctrl btn triggered!");
INPUT_FLAGS.light_ctrl_btn_flag = false;
light_ctrl_btn_input.begin();
}
} }
// #[cfg(feature = "enable_print")]
// println!("tick!");
// debouncer // app tick
sense_coin_input.service(); app.tick();
main_btn_input.service();
volume_btn_input.service();
light_ctrl_btn_input.service();
if sense_coin_input.ready() { // interfaces
#[cfg(feature = "enable_print")]
println!("debounced coin_input value: {}", sense_coin_input.value());
sense_coin_input.reset();
}
if main_btn_input.ready() {
let value = main_btn_input.value();
main_btn_input.reset();
#[cfg(feature = "enable_print")]
println!("debounced button_input value: {}", value);
if !value {
// interfaces.dac.load_data(match settings.button_sound_index {
// 0 => button_sound_1,
// 1 => button_sound_2,
// 2 => button_sound_3,
// _ => button_sound_1,
// });
// interfaces
// .dac
// .load_data(button_sounds[settings.button_sound_index]);
app.settings.button_sound_index += 1;
if app.settings.button_sound_index > 2 {
// if settings.button_sound_index > button_sounds.len() - 1 {
app.settings.button_sound_index = 0;
}
#[cfg(feature = "enable_print")]
println!("reset hold timers + enable");
sp_timer.reset();
sp_timer.enable(true);
lp_timer.reset();
lp_timer.enable(true);
} else {
sp_timer.reset();
lp_timer.reset();
}
}
if volume_btn_input.ready() {
#[cfg(feature = "enable_print")]
println!("volume btn value: {}", volume_btn_input.value());
app.settings.volume.next();
volume_btn_input.reset();
}
if light_ctrl_btn_input.ready() {
#[cfg(feature = "enable_print")]
println!("light_ctrl_btn value: {}", light_ctrl_btn_input.value());
app.settings.brightness.next();
light_ctrl_btn_input.reset();
}
// timers
sp_timer.tick();
lp_timer.tick();
adc1_timer.tick();
if sp_timer.need_service() {
#[cfg(feature = "enable_print")]
println!("sp detect!");
sp_timer.reset();
// todo enter idle
system_state = SystemState::Idle;
// TODO: fix polarity
interfaces.led0.set_amplitude(10);
interfaces.led1.set_amplitude(10);
interfaces.service();
}
if lp_timer.need_service() {
#[cfg(feature = "enable_print")]
println!("lp detect!");
lp_timer.reset();
// todo enter deepsleep
system_state = SystemState::DeepSleep;
// TODO: fix polarity
interfaces.led0.set_amplitude(0);
interfaces.led1.set_amplitude(0);
interfaces.service();
}
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);
}
} }
match system_state { app.service();
SystemState::DeepSleep => { interfaces.service();
// TODO: make this REALLY deep sleep
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 {
if INPUT_FLAGS.sense_coin_flag {
system_state = SystemState::Active;
break;
}
};
}
}
SystemState::Idle => {}
SystemState::Active => {
tt0.tick();
tt1.tick();
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()
}
interfaces.service();
}
}
delay.delay_us(tick_interval_us as u32);
} }
// // edge detector
// if !volume_btn_input.active() {
// let volume_btn_curr = volume_btn_input.is_high_immediate();
// if volume_btn_prev != volume_btn_curr {
// volume_btn_prev = volume_btn_curr;
// unsafe {
// INPUT_FLAGS.volume_btn_flag = true;
// }
// }
// }
// if !light_ctrl_btn_input.active() {
// let light_ctrl_btn_curr = light_ctrl_btn_input.is_high_immediate();
// if light_ctrl_btn_prev != light_ctrl_btn_curr {
// light_ctrl_btn_prev = light_ctrl_btn_curr;
// unsafe {
// INPUT_FLAGS.light_ctrl_btn_flag = true;
// }
// }
// }
// {
// // system input servicing
// unsafe {
// if INPUT_FLAGS.sense_coin_flag {
// #[cfg(feature = "enable_print")]
// println!("coin flag active");
// INPUT_FLAGS.sense_coin_flag = false;
// sense_coin_input.begin();
// // enter the active state
// app.set_state(State::Active);
// // todo: enter active
// // tt0.enable(true);
// // tt1.enable(true);
// // interfaces.dac.load_data(coin_sound);
// }
// if INPUT_FLAGS.main_btn_flag {
// #[cfg(feature = "enable_print")]
// println!("button flag active");
// INPUT_FLAGS.main_btn_flag = false;
// main_btn_input.begin();
// }
// if INPUT_FLAGS.volume_btn_flag {
// #[cfg(feature = "enable_print")]
// println!("volume btn triggered");
// INPUT_FLAGS.volume_btn_flag = false;
// volume_btn_input.begin();
// }
// if INPUT_FLAGS.light_ctrl_btn_flag {
// #[cfg(feature = "enable_print")]
// println!("light ctrl btn triggered!");
// INPUT_FLAGS.light_ctrl_btn_flag = false;
// light_ctrl_btn_input.begin();
// }
// }
// // debouncer
// sense_coin_input.service();
// main_btn_input.service();
// volume_btn_input.service();
// light_ctrl_btn_input.service();
// if sense_coin_input.ready() {
// #[cfg(feature = "enable_print")]
// println!("debounced coin_input value: {}", sense_coin_input.value());
// sense_coin_input.reset();
// }
// if main_btn_input.ready() {
// let value = main_btn_input.value();
// main_btn_input.reset();
// #[cfg(feature = "enable_print")]
// println!("debounced button_input value: {}", value);
// if !value {
// // interfaces.dac.load_data(match settings.button_sound_index {
// // 0 => button_sound_1,
// // 1 => button_sound_2,
// // 2 => button_sound_3,
// // _ => button_sound_1,
// // });
// // interfaces
// // .dac
// // .load_data(button_sounds[settings.button_sound_index]);
// app.settings.button_sound_index += 1;
// if app.settings.button_sound_index > 2 {
// // if settings.button_sound_index > button_sounds.len() - 1 {
// app.settings.button_sound_index = 0;
// }
// #[cfg(feature = "enable_print")]
// println!("TODO reset hold timers + enable");
// // sp_timer.reset();
// // sp_timer.enable(true);
// // lp_timer.reset();
// // lp_timer.enable(true);
// } else {
// // sp_timer.reset();
// // lp_timer.reset();
// }
// }
// if volume_btn_input.ready() {
// #[cfg(feature = "enable_print")]
// println!("volume btn value: {}", volume_btn_input.value());
// app.settings.volume.next();
// volume_btn_input.reset();
// }
// if light_ctrl_btn_input.ready() {
// #[cfg(feature = "enable_print")]
// println!("light_ctrl_btn value: {}", light_ctrl_btn_input.value());
// app.settings.brightness.next();
// light_ctrl_btn_input.reset();
// }
// // if sp_timer.need_service() {
// // #[cfg(feature = "enable_print")]
// // println!("sp detect!");
// // sp_timer.reset();
// // // todo enter idle
// // app.set_state(State::Idle);
// // // TODO: fix polarity
// // interfaces.led0.set_amplitude(10);
// // interfaces.led1.set_amplitude(10);
// // interfaces.service();
// // }
// // if lp_timer.need_service() {
// // #[cfg(feature = "enable_print")]
// // println!("lp detect!");
// // lp_timer.reset();
// // // todo enter deepsleep
// // app.set_state(State::DeepSleep);
// // // TODO: fix polarity
// // interfaces.led0.set_amplitude(0);
// // interfaces.led1.set_amplitude(0);
// // interfaces.service();
// // }
// // 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);
// // }
// }
// match app.state() {
// State::DeepSleep => {
// // TODO: make this REALLY deep sleep
// 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 {
// if INPUT_FLAGS.sense_coin_flag {
// app.set_state(State::Active);
// break;
// }
// };
// }
// }
// State::Idle => {}
// State::Active => {
// // tt0.tick();
// // tt1.tick();
// // 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()
// // }
// }
// }
// }
} }
#[qingke_rt::entry] #[qingke_rt::entry]
@ -774,9 +812,9 @@ fn main() -> ! {
println!("pre"); println!("pre");
riscv::asm::delay(20_000_000); riscv::asm::delay(20_000_000);
println!("post"); println!("post");
debug_main(p); // debug_main(p);
// app_main(p, delay); app_main(p);
} }
#[panic_handler] #[panic_handler]

View file

@ -26,31 +26,20 @@ impl<'a, T: GeneralInstance16bit> AppSynthesizers<'a, T> {
self.square.tick(); self.square.tick();
if self.square.has_new_output() { if self.square.has_new_output() {
let out = self.square.get_output(); let out = self.square.get_output();
// println!("OUTPUT: {out}");
// println!("new out");
self.output.write_amplitude( self.output.write_amplitude(
ch32_hal::timer::Channel::Ch4, ch32_hal::timer::Channel::Ch4,
// TODO: set level here. or maybe use dac?
out / 2, out / 2,
// (out as f32 * (u8::MAX as f32 / u32::MAX as f32)) as u8,
); );
} }
// println!("{}{}", self.square.counter, self.square.has_new_output());
} }
pub fn service(&mut self) { pub fn service(&mut self) {
// println!("HERE"); // println!("HERE");
if self.square.has_new_output() { if self.square.has_new_output() {
let out = self.square.get_output(); let out = self.square.get_output();
// println!("OUTPUT: {out}"); self.output
.write_amplitude(ch32_hal::timer::Channel::Ch4, out / 2);
// println!("new out");
self.output.write_amplitude(
ch32_hal::timer::Channel::Ch4,
out / 2,
// (out as f32 * (u8::MAX as f32 / u32::MAX as f32)) as u8,
);
} }
} }
} }