Compare commits
8 commits
45db5e8af8
...
d053f8d080
| Author | SHA1 | Date | |
|---|---|---|---|
| d053f8d080 | |||
| f26920a099 | |||
| 60d6aaecd6 | |||
| 10a38f9bbc | |||
| 5934336984 | |||
| f3ac43614c | |||
| b6fa0e3b2d | |||
| cd91b3f540 |
4 changed files with 159 additions and 86 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit f41336744c4e2548c8f6ba9b323ae4aa39959f1d
|
Subproject commit 4f11d68e62dcb0e7098eecf357168724a8322d80
|
||||||
|
|
@ -9,7 +9,7 @@ pub enum State {
|
||||||
Active,
|
Active,
|
||||||
}
|
}
|
||||||
|
|
||||||
mod settings {
|
pub mod settings {
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
pub enum Level {
|
pub enum Level {
|
||||||
|
|
@ -333,10 +333,11 @@ impl App {
|
||||||
services: Services,
|
services: Services,
|
||||||
sequences: Sequences,
|
sequences: Sequences,
|
||||||
interfaces: Interfaces,
|
interfaces: Interfaces,
|
||||||
|
settings: Settings,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: State::default(),
|
state: State::default(),
|
||||||
settings: Settings::default(),
|
settings,
|
||||||
timers: Timers::new(config.timers, config.system_tick_rate_hz),
|
timers: Timers::new(config.timers, config.system_tick_rate_hz),
|
||||||
services,
|
services,
|
||||||
sequences,
|
sequences,
|
||||||
|
|
@ -346,6 +347,8 @@ impl App {
|
||||||
|
|
||||||
pub fn init(&mut self) {
|
pub fn init(&mut self) {
|
||||||
// self.timers.init();
|
// self.timers.init();
|
||||||
|
self.interfaces.amp.enable();
|
||||||
|
|
||||||
self.timers.batt_adc_timer.reset();
|
self.timers.batt_adc_timer.reset();
|
||||||
self.timers.batt_adc_timer.enable(true);
|
self.timers.batt_adc_timer.enable(true);
|
||||||
|
|
||||||
|
|
@ -367,10 +370,11 @@ impl App {
|
||||||
// self.timers.led2_timer.reset();
|
// self.timers.led2_timer.reset();
|
||||||
// self.timers.led2_timer.enable(true);
|
// self.timers.led2_timer.enable(true);
|
||||||
|
|
||||||
self.services.synth0.set_freq(1);
|
// self.services.synth0.set_freq(1);
|
||||||
self.services.synth0.disable();
|
self.services.synth0.disable();
|
||||||
|
|
||||||
self.services.sequencer.disable();
|
self.services.sequencer.disable();
|
||||||
|
|
||||||
|
crate::riscv::asm::delay(2_500_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_state(&mut self, state: State) {
|
pub fn set_state(&mut self, state: State) {
|
||||||
|
|
@ -519,14 +523,10 @@ impl App {
|
||||||
} else {
|
} else {
|
||||||
self.services.sequencer.disable();
|
self.services.sequencer.disable();
|
||||||
self.services.synth0.disable();
|
self.services.synth0.disable();
|
||||||
self.interfaces.amp.disable();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.services.synth0.need_service() {
|
if self.services.synth0.need_service() {
|
||||||
if !self.interfaces.amp.enabled() {
|
|
||||||
self.interfaces.amp.enable();
|
|
||||||
}
|
|
||||||
let out = match self.services.synth0.service() {
|
let out = match self.services.synth0.service() {
|
||||||
Some(value) => value / 6 / self.settings.volume.as_volume_divisor(),
|
Some(value) => value / 6 / self.settings.volume.as_volume_divisor(),
|
||||||
None => 0,
|
None => 0,
|
||||||
|
|
@ -555,12 +555,11 @@ impl App {
|
||||||
self.interfaces
|
self.interfaces
|
||||||
.pwm_core
|
.pwm_core
|
||||||
.write_amplitude(self.services.led1.channel, 0);
|
.write_amplitude(self.services.led1.channel, 0);
|
||||||
// self.interfaces
|
crate::riscv::asm::delay(10_000_000);
|
||||||
// .pwm_core
|
|
||||||
// .write_amplitude(self.services.led2.channel, 0);
|
self.interfaces.pwm_core.pwm.borrow().shutdown();
|
||||||
self.interfaces
|
self.interfaces.adc_core.shutdown();
|
||||||
.pwm_core
|
|
||||||
.disable(ch32_hal::timer::Channel::Ch4);
|
|
||||||
self.interfaces.amp.disable();
|
self.interfaces.amp.disable();
|
||||||
}
|
}
|
||||||
pub fn volume_button(&mut self) {
|
pub fn volume_button(&mut self) {
|
||||||
|
|
@ -625,7 +624,7 @@ impl App {
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
impl App {
|
impl App {
|
||||||
fn main_button_click(&mut self) {
|
pub fn main_button_click(&mut self) {
|
||||||
// TODO
|
// TODO
|
||||||
#[cfg(feature = "enable_print")]
|
#[cfg(feature = "enable_print")]
|
||||||
println!("click");
|
println!("click");
|
||||||
|
|
@ -661,6 +660,9 @@ impl App {
|
||||||
pub fn get_state(&self) -> State {
|
pub fn get_state(&self) -> State {
|
||||||
self.state
|
self.state
|
||||||
}
|
}
|
||||||
|
pub fn get_settings(&self) -> Settings {
|
||||||
|
self.settings
|
||||||
|
}
|
||||||
pub fn should_wake(&self) -> bool {
|
pub fn should_wake(&self) -> bool {
|
||||||
if self.interfaces.usb.powered() {
|
if self.interfaces.usb.powered() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::insert_coin::services::{DacService, LedService, Service, TickService,
|
||||||
// static LED1_DCS: [u8; 5] = [0u8, 25u8, 50u8, 75u8, 100u8];
|
// static LED1_DCS: [u8; 5] = [0u8, 25u8, 50u8, 75u8, 100u8];
|
||||||
|
|
||||||
pub struct SimplePwmCore<'d, T: GeneralInstance16bit> {
|
pub struct SimplePwmCore<'d, T: GeneralInstance16bit> {
|
||||||
pwm: core::cell::RefCell<SimplePwm<'d, T>>,
|
pub pwm: core::cell::RefCell<SimplePwm<'d, T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: GeneralInstance16bit> SimplePwmCore<'d, T> {
|
impl<'d, T: GeneralInstance16bit> SimplePwmCore<'d, T> {
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,10 @@ impl AdcCore {
|
||||||
}
|
}
|
||||||
sum / self.batt_values.len() as u16
|
sum / self.batt_values.len() as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shutdown(&mut self) {
|
||||||
|
self.adc.shutdown()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -241,10 +245,20 @@ bind_interrupts!(struct Irqs {
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: remove
|
// TODO: remove
|
||||||
|
use app::settings::Settings;
|
||||||
use insert_coin::TickTimerService;
|
use insert_coin::TickTimerService;
|
||||||
use insert_coin::{TickService, TickServiceData};
|
use insert_coin::{TickService, TickServiceData};
|
||||||
|
|
||||||
fn app_main(mut p: hal::Peripherals) -> ! {
|
fn app_main(mut p: hal::Peripherals, app_settings: Settings) -> Settings {
|
||||||
|
// initialize ADC core first, and exit if battery is too low
|
||||||
|
let mut adc = hal::adc::Adc::new(p.ADC1, Default::default());
|
||||||
|
let mut batt_monitor_pin = p.PD4;
|
||||||
|
let mut adc_core = AdcCore::new(adc, batt_monitor_pin);
|
||||||
|
let bv = adc_core.get_battery_voltage();
|
||||||
|
if bv < 421 {
|
||||||
|
adc_core.shutdown();
|
||||||
|
return app_settings;
|
||||||
|
}
|
||||||
// === output setup ===
|
// === output setup ===
|
||||||
|
|
||||||
// LED0 output setup
|
// LED0 output setup
|
||||||
|
|
@ -255,10 +269,6 @@ fn app_main(mut p: hal::Peripherals) -> ! {
|
||||||
let led1_pin = PwmPin::new_ch1::<0>(p.PD2);
|
let led1_pin = PwmPin::new_ch1::<0>(p.PD2);
|
||||||
let led1_ch = hal::timer::Channel::Ch1;
|
let led1_ch = hal::timer::Channel::Ch1;
|
||||||
|
|
||||||
// // LED2 output setup
|
|
||||||
// let led2_pin = PwmPin::new_ch2::<0>(p.PA1);
|
|
||||||
// let led2_ch = hal::timer::Channel::Ch2;
|
|
||||||
|
|
||||||
// DAC output setup
|
// DAC output setup
|
||||||
let dac_pin = PwmPin::new_ch4::<0>(p.PC4);
|
let dac_pin = PwmPin::new_ch4::<0>(p.PC4);
|
||||||
// let dac_ch = hal::timer::Channel::Ch4;
|
// let dac_ch = hal::timer::Channel::Ch4;
|
||||||
|
|
@ -277,20 +287,22 @@ fn app_main(mut p: hal::Peripherals) -> ! {
|
||||||
|
|
||||||
pwm.set_polarity(led0_ch, OutputPolarity::ActiveHigh);
|
pwm.set_polarity(led0_ch, OutputPolarity::ActiveHigh);
|
||||||
pwm.set_polarity(led1_ch, OutputPolarity::ActiveLow);
|
pwm.set_polarity(led1_ch, OutputPolarity::ActiveLow);
|
||||||
|
let mut pwm_core = SimplePwmCore::new(pwm);
|
||||||
|
pwm_core.write_amplitude(led0_ch, 0);
|
||||||
|
pwm_core.write_amplitude(led1_ch, 0);
|
||||||
|
|
||||||
// pwm.set_polarity(led2_ch, OutputPolarity::ActiveLow);
|
// pwm.set_polarity(led2_ch, OutputPolarity::ActiveLow);
|
||||||
|
|
||||||
let tick_rate_hz = 50000;
|
let tick_rate_hz = 50000;
|
||||||
|
|
||||||
let core_config = CoreConfig::new(tick_rate_hz);
|
let core_config = CoreConfig::new(tick_rate_hz);
|
||||||
|
|
||||||
let pwm_core = SimplePwmCore::new(pwm);
|
|
||||||
|
|
||||||
// === input setup ===
|
// === input setup ===
|
||||||
|
|
||||||
// adc
|
// adc
|
||||||
let mut adc = hal::adc::Adc::new(p.ADC1, Default::default());
|
// let mut adc = hal::adc::Adc::new(p.ADC1, Default::default());
|
||||||
let mut batt_monitor_pin = p.PD4;
|
// let mut batt_monitor_pin = p.PD4;
|
||||||
let adc_core = AdcCore::new(adc, batt_monitor_pin);
|
// let adc_core = AdcCore::new(adc, batt_monitor_pin);
|
||||||
|
|
||||||
// adc2
|
// adc2
|
||||||
// let mut usb_detect_dc = hal::adc::Adc::new(p.ADC1, Default::default());
|
// let mut usb_detect_dc = hal::adc::Adc::new(p.ADC1, Default::default());
|
||||||
|
|
@ -309,8 +321,8 @@ fn app_main(mut p: hal::Peripherals) -> ! {
|
||||||
let volume_btn_pin = p.PC6;
|
let volume_btn_pin = p.PC6;
|
||||||
let light_ctrl_btn_pin = p.PC7;
|
let light_ctrl_btn_pin = p.PC7;
|
||||||
let amp_en = p.PC5;
|
let amp_en = p.PC5;
|
||||||
let extra_io_1 = p.PD0;
|
// let extra_io_1 = p.PD0;
|
||||||
let extra_io_2 = p.PD3;
|
// let extra_io_2 = p.PD3;
|
||||||
|
|
||||||
let mut amp_en_output = OutputOpenDrain::new(amp_en, Level::Low, Default::default());
|
let mut amp_en_output = OutputOpenDrain::new(amp_en, Level::Low, Default::default());
|
||||||
let amp = Amplifier::new(amp_en_output);
|
let amp = Amplifier::new(amp_en_output);
|
||||||
|
|
@ -340,7 +352,8 @@ fn app_main(mut p: hal::Peripherals) -> ! {
|
||||||
led0_timer_ms: 100,
|
led0_timer_ms: 100,
|
||||||
led1_timer_ms: 100,
|
led1_timer_ms: 100,
|
||||||
// 4 hours:
|
// 4 hours:
|
||||||
shutdown_timer_s: 4 * 60 * 60,
|
// shutdown_timer_s: 1,
|
||||||
|
shutdown_timer_s: 4 * 60 * 60 * 30 / 100,
|
||||||
// led2_timer_ms: 100,
|
// led2_timer_ms: 100,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -385,7 +398,24 @@ fn app_main(mut p: hal::Peripherals) -> ! {
|
||||||
usb,
|
usb,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut app = App::new(app_config, app_services, app_sequences, app_interfaces);
|
let mut app = App::new(
|
||||||
|
app_config,
|
||||||
|
app_services,
|
||||||
|
app_sequences,
|
||||||
|
app_interfaces,
|
||||||
|
app_settings,
|
||||||
|
);
|
||||||
|
|
||||||
|
let need_sound = unsafe {
|
||||||
|
#[allow(static_mut_refs)]
|
||||||
|
if INPUT_FLAGS.main_btn_flag.active() {
|
||||||
|
#[allow(static_mut_refs)]
|
||||||
|
INPUT_FLAGS.main_btn_flag.clear();
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// init systick
|
// init systick
|
||||||
systick_init(tick_rate_hz);
|
systick_init(tick_rate_hz);
|
||||||
|
|
@ -418,6 +448,9 @@ fn app_main(mut p: hal::Peripherals) -> ! {
|
||||||
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();
|
app.init();
|
||||||
|
if need_sound {
|
||||||
|
app.main_button_click();
|
||||||
|
}
|
||||||
loop {
|
loop {
|
||||||
// system servicing
|
// system servicing
|
||||||
|
|
||||||
|
|
@ -516,66 +549,90 @@ fn app_main(mut p: hal::Peripherals) -> ! {
|
||||||
// enter standby
|
// enter standby
|
||||||
app::State::DeepSleep => {
|
app::State::DeepSleep => {
|
||||||
app.shut_down();
|
app.shut_down();
|
||||||
|
return app.get_settings();
|
||||||
loop {
|
|
||||||
unsafe {
|
|
||||||
#[allow(static_mut_refs)]
|
|
||||||
INPUT_FLAGS.sense_coin_flag.clear();
|
|
||||||
#[allow(static_mut_refs)]
|
|
||||||
INPUT_FLAGS.main_btn_flag.clear();
|
|
||||||
}
|
|
||||||
unsafe { system::enter_standby() };
|
|
||||||
riscv::asm::wfi();
|
|
||||||
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()
|
|
||||||
|| (INPUT_FLAGS.main_btn_flag.active()
|
|
||||||
&& main_btn_input.is_high_immediate()))
|
|
||||||
&& app.should_wake()
|
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
use hal::pac::Interrupt;
|
|
||||||
use qingke::interrupt::Priority;
|
|
||||||
use qingke_rt::CoreInterrupt;
|
|
||||||
|
|
||||||
system::clear_interrupt(2, 6);
|
|
||||||
|
|
||||||
qingke::pfic::set_priority(
|
|
||||||
CoreInterrupt::SysTick as u8,
|
|
||||||
Priority::P15 as u8,
|
|
||||||
);
|
|
||||||
|
|
||||||
qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8);
|
|
||||||
qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8);
|
|
||||||
}
|
|
||||||
|
|
||||||
app.set_state(State::Active);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// for everything else, don't do anything
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// // 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();
|
use ch32_hal::timer::low_level::{OutputCompareMode, Timer};
|
||||||
// // adc1_timer.enable(true);
|
use ch32_hal::timer::Channel;
|
||||||
// // }
|
|
||||||
// }
|
// fn shutdown_main(p: Peripherals) {
|
||||||
|
fn shutdown_main(p: hal::Peripherals) {
|
||||||
|
// LED0 output setup
|
||||||
|
let led0_pin = OutputOpenDrain::new(p.PC3, Level::Low, Default::default());
|
||||||
|
let led1_pin = OutputOpenDrain::new(p.PD2, Level::High, Default::default());
|
||||||
|
let led2_pin = OutputOpenDrain::new(p.PA1, Level::High, Default::default());
|
||||||
|
let dac_pin = OutputOpenDrain::new(p.PC4, Level::Low, Default::default());
|
||||||
|
let mut amp_pin = OutputOpenDrain::new(p.PC5, Level::Low, Default::default());
|
||||||
|
amp_pin.set_high();
|
||||||
|
let volume_btn_pin = OutputOpenDrain::new(p.PC6, Level::Low, Default::default());
|
||||||
|
let light_ctrl_btn_pin = OutputOpenDrain::new(p.PC7, Level::Low, Default::default());
|
||||||
|
let usb_detect_input = OutputOpenDrain::new(p.PD5, Level::Low, Default::default());
|
||||||
|
|
||||||
|
let sense_coin_pin = p.PC2;
|
||||||
|
let main_btn_pin = p.PD6;
|
||||||
|
|
||||||
|
unsafe { system::init_gpio_irq(sense_coin_pin.pin(), sense_coin_pin.port(), true, false) };
|
||||||
|
unsafe { system::init_gpio_irq(main_btn_pin.pin(), main_btn_pin.port(), true, false) };
|
||||||
|
|
||||||
|
let sense_coin_pin = Input::new(sense_coin_pin, Pull::None);
|
||||||
|
let main_btn_pin = Input::new(main_btn_pin, Pull::None);
|
||||||
|
|
||||||
|
riscv::asm::delay(1_000_000);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
unsafe { system::enter_standby() };
|
||||||
|
riscv::asm::wfi();
|
||||||
|
unsafe {
|
||||||
|
#[allow(static_mut_refs)]
|
||||||
|
if (INPUT_FLAGS.sense_coin_flag.active() || INPUT_FLAGS.main_btn_flag.active())
|
||||||
|
// && app.should_wake()
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop {
|
||||||
|
// unsafe {
|
||||||
|
// #[allow(static_mut_refs)]
|
||||||
|
// INPUT_FLAGS.sense_coin_flag.clear();
|
||||||
|
// #[allow(static_mut_refs)]
|
||||||
|
// INPUT_FLAGS.main_btn_flag.clear();
|
||||||
|
// }
|
||||||
|
// unsafe { system::enter_standby() };
|
||||||
|
// riscv::asm::wfi();
|
||||||
|
// unsafe {
|
||||||
|
// #[allow(static_mut_refs)]
|
||||||
|
// if (INPUT_FLAGS.sense_coin_flag.active()
|
||||||
|
// || (INPUT_FLAGS.main_btn_flag.active() && main_btn_input.is_high_immediate()))
|
||||||
|
// && app.should_wake()
|
||||||
|
// {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// let mut config = hal::Config::default();
|
||||||
|
// config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI;
|
||||||
|
// unsafe {
|
||||||
|
// hal::rcc::init(config.rcc);
|
||||||
|
// }
|
||||||
|
// unsafe {
|
||||||
|
// use hal::pac::Interrupt;
|
||||||
|
// use qingke::interrupt::Priority;
|
||||||
|
// use qingke_rt::CoreInterrupt;
|
||||||
|
|
||||||
|
// system::clear_interrupt(2, 6);
|
||||||
|
|
||||||
|
// qingke::pfic::set_priority(CoreInterrupt::SysTick as u8, Priority::P15 as u8);
|
||||||
|
|
||||||
|
// qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8);
|
||||||
|
// qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
#[qingke_rt::entry]
|
#[qingke_rt::entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
|
@ -592,7 +649,21 @@ fn main() -> ! {
|
||||||
// println!("post");
|
// println!("post");
|
||||||
// debug_main(p);
|
// debug_main(p);
|
||||||
|
|
||||||
app_main(p);
|
let mut app_settings = Settings::default();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
unsafe {
|
||||||
|
hal::rcc::init(hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI);
|
||||||
|
}
|
||||||
|
let mut p = unsafe { hal::Peripherals::steal() };
|
||||||
|
app_settings = app_main(p, app_settings);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
hal::rcc::init(hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI);
|
||||||
|
}
|
||||||
|
let mut p = unsafe { hal::Peripherals::steal() };
|
||||||
|
shutdown_main(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue