add coin button handling and move coin dac inside app
This commit is contained in:
parent
930d10218f
commit
c8c42c0194
5 changed files with 81 additions and 57 deletions
|
|
@ -96,7 +96,7 @@ pub mod sequencer {
|
|||
}
|
||||
|
||||
use crate::insert_coin::{
|
||||
LedService, Service, SimplePwmCore, TickService, TickServiceData, TickTimerService,
|
||||
DacService, LedService, Service, SimplePwmCore, TickService, TickServiceData, TickTimerService,
|
||||
};
|
||||
use crate::synthesizer::SynthesizerService;
|
||||
|
||||
|
|
@ -193,11 +193,13 @@ pub struct Services {
|
|||
pub led1: LedService,
|
||||
pub led2: LedService,
|
||||
pub synth0: SynthesizerService,
|
||||
pub sample_player: DacService<'static>,
|
||||
}
|
||||
|
||||
impl Services {
|
||||
pub fn tick(&mut self) {
|
||||
self.synth0.tick();
|
||||
self.sample_player.tick();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -352,9 +354,17 @@ impl App {
|
|||
|
||||
if self.services.synth0.need_service() {
|
||||
let out = self.services.synth0.service() / self.settings.volume.as_volume_divisor();
|
||||
// self.interfaces
|
||||
// .pwm_core
|
||||
// .write_amplitude(ch32_hal::timer::Channel::Ch4, out);
|
||||
}
|
||||
|
||||
if self.services.sample_player.need_service() {
|
||||
self.services.sample_player.service();
|
||||
let out = self.services.sample_player.get_amplitude();
|
||||
self.interfaces
|
||||
.pwm_core
|
||||
.write_amplitude(ch32_hal::timer::Channel::Ch4, out);
|
||||
.write_amplitude(ch32_hal::timer::Channel::Ch4, out as u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -374,8 +384,10 @@ impl App {
|
|||
pub fn main_button(&mut self) {
|
||||
// TODO
|
||||
}
|
||||
pub fn coin_detect(&mut self) {
|
||||
// TODO
|
||||
pub fn coin_detect(&self) {
|
||||
#[cfg(feature = "enable_print")]
|
||||
println!("coin detect");
|
||||
self.services.sample_player.play_sample();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -390,8 +402,6 @@ impl App {
|
|||
// INTERFACE:
|
||||
// 1. short press handling
|
||||
// 2. long press handling
|
||||
// 3. volume press handling
|
||||
// 4. brightness press handling
|
||||
//
|
||||
// SYSTEM:
|
||||
// 1. deep sleep
|
||||
|
|
@ -401,3 +411,4 @@ impl App {
|
|||
// STRETCH TODO LIST
|
||||
// 1. clean up edge detector
|
||||
// 2. better handling for pwm scaling (brightness / volume)
|
||||
// 3. better interrupt handling structs
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
mod insert_coin;
|
||||
mod services;
|
||||
|
||||
pub use services::{LedService, Service, TickTimerService};
|
||||
pub use services::{DacService, LedService, Service, TickTimerService};
|
||||
|
||||
pub use insert_coin::{CoreConfig, InsertCoin, SimplePwmCore};
|
||||
pub use services::{TickService, TickServiceData};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use crate::insert_coin::services::{TickServiceData, TickService};
|
||||
|
||||
use crate::insert_coin::services::{TickService, TickServiceData};
|
||||
|
||||
use adpcm_pwm_dac::dac::DpcmDecoder;
|
||||
use ch32_hal::timer::Channel;
|
||||
|
|
@ -21,6 +20,10 @@ impl<'a> DacService<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn play_sample(&self) {
|
||||
self.dpcm_decoder.borrow_mut().seek_to_sample(0);
|
||||
}
|
||||
|
||||
pub fn load_data(&self, data: &'a [u8]) {
|
||||
self.dpcm_decoder.borrow_mut().load_data(data);
|
||||
self.dpcm_decoder.borrow_mut().seek_to_sample(0);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use app::{
|
|||
};
|
||||
|
||||
use ch32_hal::{adc::AdcChannel, interrupt::typelevel::Handler, timer::low_level::OutputPolarity};
|
||||
use insert_coin::{CoreConfig, InsertCoin, LedService, SimplePwmCore};
|
||||
use insert_coin::{CoreConfig, DacService, InsertCoin, LedService, SimplePwmCore};
|
||||
|
||||
use ch32_hal as hal;
|
||||
use hal::bind_interrupts;
|
||||
|
|
@ -56,8 +56,8 @@ impl Flag {
|
|||
|
||||
#[derive(Debug)]
|
||||
struct InputFlags {
|
||||
sense_coin_flag: bool,
|
||||
main_btn_flag: bool,
|
||||
sense_coin_flag: Flag,
|
||||
main_btn_flag: Flag,
|
||||
volume_btn_flag: bool,
|
||||
light_ctrl_btn_flag: bool,
|
||||
systick_flag: Flag,
|
||||
|
|
@ -66,8 +66,8 @@ struct InputFlags {
|
|||
impl Default for InputFlags {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
sense_coin_flag: false,
|
||||
main_btn_flag: false,
|
||||
sense_coin_flag: Flag { value: false },
|
||||
main_btn_flag: Flag { value: false },
|
||||
volume_btn_flag: false,
|
||||
light_ctrl_btn_flag: false,
|
||||
systick_flag: Flag { value: false },
|
||||
|
|
@ -76,8 +76,8 @@ impl Default for InputFlags {
|
|||
}
|
||||
|
||||
static mut INPUT_FLAGS: InputFlags = InputFlags {
|
||||
sense_coin_flag: false,
|
||||
main_btn_flag: false,
|
||||
sense_coin_flag: Flag { value: false },
|
||||
main_btn_flag: Flag { value: false },
|
||||
volume_btn_flag: false,
|
||||
light_ctrl_btn_flag: false,
|
||||
systick_flag: Flag { value: false },
|
||||
|
|
@ -90,8 +90,15 @@ impl Handler<hal::interrupt::typelevel::EXTI7_0> for Test {
|
|||
println!("on_interrupt()");
|
||||
critical_section::with(|_| unsafe {
|
||||
let flags = system::clear_interrupt(2, 6);
|
||||
INPUT_FLAGS.sense_coin_flag = flags.sense_coin_flag;
|
||||
INPUT_FLAGS.main_btn_flag = flags.main_btn_flag;
|
||||
if flags[0] {
|
||||
// safe because single-threaded
|
||||
#[allow(static_mut_refs)]
|
||||
INPUT_FLAGS.sense_coin_flag.set();
|
||||
}
|
||||
if flags[1] {
|
||||
#[allow(static_mut_refs)]
|
||||
INPUT_FLAGS.main_btn_flag.set();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -184,10 +191,11 @@ fn app_main(mut p: hal::Peripherals) -> ! {
|
|||
pwm.set_polarity(led0_ch, OutputPolarity::ActiveLow);
|
||||
pwm.set_polarity(led1_ch, OutputPolarity::ActiveLow);
|
||||
|
||||
let sample_rate_hz = 4000;
|
||||
// let sample_rate_hz = 4000;
|
||||
// let sample_rate_hz = 16000;
|
||||
let dac_tick_per_service = 5;
|
||||
let tick_rate_hz = sample_rate_hz * dac_tick_per_service;
|
||||
// let dac_tick_per_service = 5;
|
||||
// let tick_rate_hz = sample_rate_hz * dac_tick_per_service;
|
||||
let tick_rate_hz = 50000;
|
||||
|
||||
let core_config = CoreConfig::new(tick_rate_hz);
|
||||
|
||||
|
|
@ -265,11 +273,22 @@ fn app_main(mut p: hal::Peripherals) -> ! {
|
|||
// let square_wt = SimpleWavetable::new(&SQUARE_WAVETABLE);
|
||||
// let square = SimpleWavetableSynthesizer::new(square_wt, tick_rate_hz);
|
||||
|
||||
// DAC servicer setup
|
||||
let dac_sample_rate_hz = 16000;
|
||||
let dac_tick_per_service = tick_rate_hz / dac_sample_rate_hz;
|
||||
let dac_service_data = TickServiceData::new(dac_tick_per_service);
|
||||
|
||||
let coin_sound = include_bytes!("../audio/coin2.raw");
|
||||
|
||||
let sample_player = DacService::new(ch32_hal::timer::Channel::Ch4, dac_service_data);
|
||||
sample_player.load_data(coin_sound);
|
||||
|
||||
let app_services = Services {
|
||||
led0: LedService::new(led0_ch),
|
||||
led1: LedService::new(led1_ch),
|
||||
led2: LedService::new(led2_ch),
|
||||
synth0: SynthesizerService::new(tick_rate_hz),
|
||||
sample_player,
|
||||
};
|
||||
|
||||
let app_sequences = Sequences {
|
||||
|
|
@ -368,6 +387,27 @@ fn app_main(mut p: hal::Peripherals) -> ! {
|
|||
light_ctrl_btn_input.reset();
|
||||
}
|
||||
|
||||
// coin_detect interrupt
|
||||
|
||||
unsafe {
|
||||
#[allow(static_mut_refs)]
|
||||
if INPUT_FLAGS.sense_coin_flag.active() {
|
||||
#[allow(static_mut_refs)]
|
||||
INPUT_FLAGS.sense_coin_flag.clear();
|
||||
|
||||
#[cfg(feature = "enable_print")]
|
||||
println!("coin flag active");
|
||||
sense_coin_input.begin();
|
||||
}
|
||||
sense_coin_input.service();
|
||||
if sense_coin_input.ready() {
|
||||
#[cfg(feature = "enable_print")]
|
||||
println!("debounced coin_input value: {}", sense_coin_input.value());
|
||||
sense_coin_input.reset();
|
||||
app.coin_detect();
|
||||
}
|
||||
}
|
||||
|
||||
// systick tick
|
||||
if unsafe {
|
||||
#[allow(static_mut_refs)]
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ pub unsafe fn init_gpio_irq(pin: u8, port: u8, rising: bool, falling: bool) {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn clear_interrupt(coin_pin: u8, button_pin: u8) -> crate::InputFlags {
|
||||
let mut input_flags = crate::InputFlags::default();
|
||||
pub fn clear_interrupt(coin_pin: u8, button_pin: u8) -> [bool; 2] {
|
||||
let mut output = [false, false];
|
||||
|
||||
let exti = &hal::pac::EXTI;
|
||||
|
||||
|
|
@ -35,53 +35,23 @@ pub fn clear_interrupt(coin_pin: u8, button_pin: u8) -> crate::InputFlags {
|
|||
|
||||
// We don't handle or change any EXTI lines above 24.
|
||||
let bits = bits.0 & 0x00FFFFFF;
|
||||
#[cfg(feature = "enable_print")]
|
||||
println!("bits: {bits:08x}");
|
||||
|
||||
// coin_flag
|
||||
if (bits & (0x1 << coin_pin)) != 0x0 {
|
||||
#[cfg(feature = "enable_print")]
|
||||
println!("coin irq!");
|
||||
input_flags.sense_coin_flag = true;
|
||||
output[0] = true;
|
||||
}
|
||||
|
||||
// button_flag
|
||||
if (bits & (0x1 << button_pin)) != 0x0 {
|
||||
#[cfg(feature = "enable_print")]
|
||||
println!("main_btn irq!");
|
||||
input_flags.main_btn_flag = true;
|
||||
// CHECK PC6
|
||||
// unsafe {
|
||||
// let mut val = 0;
|
||||
// let reg: u32 = 0x40011008;
|
||||
// val = (reg as *mut u32).read_volatile();
|
||||
// if ((val >> 0x6) & 0x1) == 0x0 {
|
||||
// input_flags.volume_btn_flag = true;
|
||||
// #[cfg(feature = "enable_print")]
|
||||
// println!("volume irq!");
|
||||
// println!("CBANK: {val:08x}");
|
||||
// }
|
||||
// }
|
||||
// // CHECK PD6
|
||||
// unsafe {
|
||||
// let mut val = 0;
|
||||
// let reg: u32 = 0x40011408;
|
||||
// val = (reg as *mut u32).read_volatile();
|
||||
// // if ((val >> 0x6) & 0x1) == 0x0 {
|
||||
// input_flags.main_btn_flag = true;
|
||||
// #[cfg(feature = "enable_print")]
|
||||
// println!("main_btn irq!");
|
||||
// println!("DBANK: {val:08x}");
|
||||
// // }
|
||||
// }
|
||||
output[1] = true;
|
||||
}
|
||||
|
||||
// light_ctrl_btn_flag
|
||||
// if (bits & (0x1 << light_ctrl_btn_pin)) != 0x0 {
|
||||
// #[cfg(feature = "enable_print")]
|
||||
// println!("light ctrl btn irq!");
|
||||
// input_flags.light_ctrl_btn_flag = true;
|
||||
// }
|
||||
|
||||
// Clear pending - Clears the EXTI's line pending bits.
|
||||
exti.intfr().write(|w| w.0 = bits);
|
||||
|
||||
|
|
@ -94,7 +64,7 @@ pub fn clear_interrupt(coin_pin: u8, button_pin: u8) -> crate::InputFlags {
|
|||
exti.intenr().modify(|w| w.set_mr(coin_pin, true)); // enable interrupt
|
||||
exti.intenr().modify(|w| w.set_mr(button_pin, true)); // enable interrupt
|
||||
|
||||
input_flags
|
||||
output
|
||||
}
|
||||
|
||||
/// enter standby (SLEEPDEEP) mode, with WFE enabled.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue