convert app to tick servicing
This commit is contained in:
parent
008bf334a4
commit
791d5db4c8
3 changed files with 460 additions and 269 deletions
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
|
||||||
|
|
@ -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,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue