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 {
|
||||
// system is asleep, waiting for wake from coin insertion
|
||||
DeepSleep,
|
||||
|
|
@ -10,9 +10,12 @@ pub enum State {
|
|||
}
|
||||
|
||||
mod settings {
|
||||
|
||||
#[derive(Default, Clone, Copy)]
|
||||
pub enum Level {
|
||||
Off,
|
||||
Low,
|
||||
#[default]
|
||||
Medium,
|
||||
High,
|
||||
Maximum,
|
||||
|
|
@ -30,6 +33,7 @@ mod settings {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Settings {
|
||||
pub brightness: Level,
|
||||
pub volume: Level,
|
||||
|
|
@ -47,20 +51,180 @@ mod settings {
|
|||
}
|
||||
}
|
||||
|
||||
use crate::insert_coin::{TickService, TickServiceData, TickTimerService};
|
||||
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 {
|
||||
state: State,
|
||||
pub settings: Settings,
|
||||
timers: Timers,
|
||||
// TODO: make this the "sound module" or whatever.
|
||||
// synthesizers: AppSynthesizers,
|
||||
}
|
||||
|
||||
impl Default for App {
|
||||
fn default() -> Self {
|
||||
impl App {
|
||||
pub fn new(config: Config) -> Self {
|
||||
Self {
|
||||
state: State::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;
|
||||
|
||||
mod app;
|
||||
use app::App;
|
||||
use app::{App, Config, State, TimerConfig};
|
||||
|
||||
use ch32_hal::{adc::AdcChannel, interrupt::typelevel::Handler, timer::low_level::OutputPolarity};
|
||||
use insert_coin::{CoreConfig, InsertCoin, SimplePwmCore};
|
||||
|
|
@ -108,14 +108,36 @@ pub enum SystemState {
|
|||
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)]
|
||||
struct InputFlags {
|
||||
sense_coin_flag: bool,
|
||||
main_btn_flag: bool,
|
||||
volume_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 {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
|
@ -123,6 +145,7 @@ impl Default for InputFlags {
|
|||
main_btn_flag: false,
|
||||
volume_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,
|
||||
volume_btn_flag: false,
|
||||
light_ctrl_btn_flag: false,
|
||||
systick_flag: Flag { value: false },
|
||||
};
|
||||
|
||||
struct Test {}
|
||||
|
|
@ -216,20 +240,24 @@ fn SysTick() {
|
|||
// }
|
||||
SYNTH_TICK_FLAG = true;
|
||||
|
||||
if SYSTICK_COUNT % 5000 == 0 {
|
||||
NOTE_TICK_FLAG = true;
|
||||
}
|
||||
// safe because single-threaded
|
||||
#[allow(static_mut_refs)]
|
||||
INPUT_FLAGS.systick_flag.set();
|
||||
|
||||
if SYSTICK_COUNT % 50000 == 0 {
|
||||
TICK_FLAG = true;
|
||||
// if let Some(ref mut led) = LED {
|
||||
// let toggle = TOGGLE_COUNT;
|
||||
// // println!("TOGGLE {toggle}");
|
||||
// TOGGLE_COUNT += 1;
|
||||
// led.toggle();
|
||||
// if SYSTICK_COUNT % 5000 == 0 {
|
||||
// NOTE_TICK_FLAG = true;
|
||||
// }
|
||||
|
||||
// if SYSTICK_COUNT % 50000 == 0 {
|
||||
// TICK_FLAG = true;
|
||||
// // if let Some(ref mut led) = LED {
|
||||
// // let toggle = TOGGLE_COUNT;
|
||||
// // // println!("TOGGLE {toggle}");
|
||||
// // TOGGLE_COUNT += 1;
|
||||
// // led.toggle();
|
||||
// // }
|
||||
// // println!("HERE");
|
||||
// }
|
||||
// println!("HERE");
|
||||
}
|
||||
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 ===
|
||||
|
||||
// LED0 output setup
|
||||
|
|
@ -430,7 +458,6 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
|||
let mut usb_detect_pin = p.PD5;
|
||||
|
||||
// println!("ADC_PIN CHANNEL: {}", adc_pin.channel().channel());
|
||||
delay.delay_ms(1000);
|
||||
let adc_cal = adc.calibrate();
|
||||
|
||||
#[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);
|
||||
interfaces.set_active(true);
|
||||
// insert_coin.init();
|
||||
|
||||
// let mut settings = Se::default();
|
||||
let mut app = App::default();
|
||||
|
||||
let mut led0_index = 0;
|
||||
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 led1_dcs = [0u8, 25u8, 50u8, 75u8, 100u8];
|
||||
|
||||
// tick timer 0
|
||||
let tt0_fire_rate_hz = 9;
|
||||
let tt0_tick_per_service = interfaces.config.tick_rate_hz / (tt0_fire_rate_hz * 2);
|
||||
let tt0_service_data = TickServiceData::new(tt0_tick_per_service);
|
||||
let mut tt0 = TickTimerService::new(tt0_service_data, true);
|
||||
|
||||
// tick timer 1
|
||||
let tt1_fire_rate_hz = 3;
|
||||
let tt1_tick_per_service = interfaces.config.tick_rate_hz / (tt1_fire_rate_hz * 2);
|
||||
let tt1_service_data = TickServiceData::new(tt1_tick_per_service);
|
||||
let 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);
|
||||
// // 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 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
|
||||
// let coin_sound = include_bytes!("../audio/coin2.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_3 = include_bytes!("../audio/button_3.raw");
|
||||
|
||||
let mut system_state = SystemState::Active;
|
||||
|
||||
interfaces.led0.set_amplitude(0);
|
||||
interfaces.led1.set_amplitude(0);
|
||||
interfaces.service();
|
||||
|
||||
// init systick
|
||||
systick_init(tick_rate_hz);
|
||||
|
||||
// set up interrupts
|
||||
unsafe {
|
||||
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);
|
||||
|
||||
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::pfic::enable_interrupt(CoreInterrupt::SysTick as u8);
|
||||
}
|
||||
|
||||
// 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 light_ctrl_btn_prev = light_ctrl_btn_input.is_high_immediate();
|
||||
|
||||
app.init();
|
||||
loop {
|
||||
// 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;
|
||||
// system servicing
|
||||
|
||||
// systick tick
|
||||
if unsafe {
|
||||
#[allow(static_mut_refs)]
|
||||
INPUT_FLAGS.systick_flag.active()
|
||||
} {
|
||||
unsafe {
|
||||
INPUT_FLAGS.volume_btn_flag = true;
|
||||
}
|
||||
}
|
||||
#[allow(static_mut_refs)]
|
||||
INPUT_FLAGS.systick_flag.clear();
|
||||
}
|
||||
// #[cfg(feature = "enable_print")]
|
||||
// println!("tick!");
|
||||
|
||||
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
|
||||
system_state = SystemState::Active;
|
||||
// app tick
|
||||
app.tick();
|
||||
|
||||
// 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!("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);
|
||||
app.service();
|
||||
interfaces.service();
|
||||
}
|
||||
|
||||
if lp_timer.need_service() {
|
||||
#[cfg(feature = "enable_print")]
|
||||
println!("lp detect!");
|
||||
lp_timer.reset();
|
||||
// // 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;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// todo enter deepsleep
|
||||
system_state = SystemState::DeepSleep;
|
||||
// TODO: fix polarity
|
||||
interfaces.led0.set_amplitude(0);
|
||||
interfaces.led1.set_amplitude(0);
|
||||
interfaces.service();
|
||||
}
|
||||
// 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);
|
||||
|
||||
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);
|
||||
// // 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();
|
||||
// }
|
||||
// }
|
||||
|
||||
adc1_timer.reset();
|
||||
adc1_timer.enable(true);
|
||||
}
|
||||
}
|
||||
// // debouncer
|
||||
// sense_coin_input.service();
|
||||
// main_btn_input.service();
|
||||
// volume_btn_input.service();
|
||||
// light_ctrl_btn_input.service();
|
||||
|
||||
match system_state {
|
||||
SystemState::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 {
|
||||
system_state = SystemState::Active;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
SystemState::Idle => {}
|
||||
SystemState::Active => {
|
||||
tt0.tick();
|
||||
tt1.tick();
|
||||
// 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 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 !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]);
|
||||
|
||||
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()
|
||||
}
|
||||
// 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();
|
||||
// }
|
||||
|
||||
interfaces.service();
|
||||
}
|
||||
}
|
||||
// // if sp_timer.need_service() {
|
||||
// // #[cfg(feature = "enable_print")]
|
||||
// // println!("sp detect!");
|
||||
// // sp_timer.reset();
|
||||
|
||||
delay.delay_us(tick_interval_us as u32);
|
||||
}
|
||||
// // // 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]
|
||||
|
|
@ -774,9 +812,9 @@ fn main() -> ! {
|
|||
println!("pre");
|
||||
riscv::asm::delay(20_000_000);
|
||||
println!("post");
|
||||
debug_main(p);
|
||||
// debug_main(p);
|
||||
|
||||
// app_main(p, delay);
|
||||
app_main(p);
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
|
|
|
|||
|
|
@ -26,31 +26,20 @@ impl<'a, T: GeneralInstance16bit> AppSynthesizers<'a, T> {
|
|||
self.square.tick();
|
||||
if self.square.has_new_output() {
|
||||
let out = self.square.get_output();
|
||||
// println!("OUTPUT: {out}");
|
||||
|
||||
// println!("new out");
|
||||
self.output.write_amplitude(
|
||||
ch32_hal::timer::Channel::Ch4,
|
||||
// TODO: set level here. or maybe use dac?
|
||||
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) {
|
||||
// println!("HERE");
|
||||
if self.square.has_new_output() {
|
||||
let out = self.square.get_output();
|
||||
// println!("OUTPUT: {out}");
|
||||
|
||||
// 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,
|
||||
);
|
||||
self.output
|
||||
.write_amplitude(ch32_hal::timer::Channel::Ch4, out / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue