use systick event system to drive synthesis
This commit is contained in:
parent
58579ae6c2
commit
0836fc58df
4 changed files with 229 additions and 31 deletions
18
ch32v-insert-coin/audio/sequences
Normal file
18
ch32v-insert-coin/audio/sequences
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
"wahwahwahwah" sound - let play a few times
|
||||||
|
note timing: 6hz
|
||||||
|
data: let freqs = [100, 200, 300, 400, 500, 600, 700, 800, 900];
|
||||||
|
|
||||||
|
"falling" sound
|
||||||
|
note timing: 6hz
|
||||||
|
[
|
||||||
|
1000,
|
||||||
|
990, 980, 970, 960, 950, 940, 930, 920, 910, 900,
|
||||||
|
890, 880, 870, 860, 850, 840, 830, 820, 810, 800,
|
||||||
|
790, 780, 770, 760, 750, 740, 730, 720, 710, 700,
|
||||||
|
690, 680, 670, 660, 650, 640, 630, 620, 610, 600,
|
||||||
|
590, 580, 570, 560, 550, 540, 530, 520, 510, 500,
|
||||||
|
490, 480, 470, 460, 450, 440, 430, 420, 410, 400,
|
||||||
|
390, 380, 370, 360, 350, 340, 330, 320, 310, 300,
|
||||||
|
290, 280, 270, 260, 250, 240, 230, 220, 210, 200,
|
||||||
|
190, 180, 170, 160, 150, 140, 130, 120, 110, 100,
|
||||||
|
]
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9417e6edbf590f3fe777e39ad76efc21a024e01d
|
Subproject commit e6ca9c7ed8b9af193333be793983df5e48cb961a
|
||||||
|
|
@ -195,6 +195,107 @@ impl Handler<hal::interrupt::typelevel::EXTI7_0> for Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mut LED: Option<ch32_hal::gpio::Output<'_>> = None;
|
||||||
|
static mut SYSTICK_COUNT: u32 = 0;
|
||||||
|
static mut SYNTHESIZERS: Option<AppSynthesizers<'_, ch32_hal::peripherals::TIM1>> = None;
|
||||||
|
static mut TOGGLE_COUNT: u32 = 0;
|
||||||
|
static mut TICK_FLAG: bool = false;
|
||||||
|
static mut SYNTH_TICK_FLAG: bool = false;
|
||||||
|
static mut NOTE_TICK_FLAG: bool = false;
|
||||||
|
static mut FREQ: [usize; 2] = [220, 440];
|
||||||
|
static mut INDEX: usize = 0;
|
||||||
|
|
||||||
|
fn flag() -> bool {
|
||||||
|
unsafe { core::ptr::read_volatile(&raw const TICK_FLAG as *const bool) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_flag() {
|
||||||
|
unsafe {
|
||||||
|
TICK_FLAG = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn synth_flag() -> bool {
|
||||||
|
unsafe { core::ptr::read_volatile(&raw const SYNTH_TICK_FLAG as *const bool) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_synth_flag() {
|
||||||
|
unsafe {
|
||||||
|
SYNTH_TICK_FLAG = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn note_flag() -> bool {
|
||||||
|
unsafe { core::ptr::read_volatile(&raw const NOTE_TICK_FLAG as *const bool) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_note_flag() {
|
||||||
|
unsafe {
|
||||||
|
NOTE_TICK_FLAG = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[qingke_rt::interrupt(core)]
|
||||||
|
fn SysTick() {
|
||||||
|
let r = &ch32_hal::pac::SYSTICK;
|
||||||
|
|
||||||
|
// Clear interrupt flag
|
||||||
|
r.sr().write(|w| w.set_cntif(false));
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// if let Some(ref mut synthesizers) = SYNTHESIZERS {
|
||||||
|
// println!("tick");
|
||||||
|
// synthesizers.tick();
|
||||||
|
// }
|
||||||
|
SYNTH_TICK_FLAG = true;
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
SYSTICK_COUNT = SYSTICK_COUNT.wrapping_add(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn systick_init(tick_freq_hz: usize) {
|
||||||
|
let r = &ch32_hal::pac::SYSTICK;
|
||||||
|
|
||||||
|
// Calculate counts per millisecond using HCLK/8 as clock source
|
||||||
|
// HCLK/8 = 48MHz/8 = 6MHz
|
||||||
|
// For tick_freq_hz interrupt: 6MHz / tick_freq_hz
|
||||||
|
let systick_per_tick = (48_000_000 / 8 / tick_freq_hz) as u32;
|
||||||
|
|
||||||
|
// Reset SysTick
|
||||||
|
r.ctlr().write(|w| {
|
||||||
|
// Start with everything disabled
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set compare register and reset counter
|
||||||
|
r.cmp().write_value(systick_per_tick - 1);
|
||||||
|
r.cnt().write_value(0);
|
||||||
|
|
||||||
|
// Clear interrupt flag
|
||||||
|
r.sr().write(|w| w.set_cntif(false));
|
||||||
|
|
||||||
|
// Configure and start SysTick
|
||||||
|
r.ctlr().write(|w| {
|
||||||
|
w.set_ste(true); // Enable counter
|
||||||
|
w.set_stie(true); // Enable interrupt
|
||||||
|
w.set_stre(true); // Auto reload enable
|
||||||
|
w.set_stclk(ch32_hal::pac::systick::vals::Stclk::HCLK_DIV8); // HCLK/8 clock source
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
bind_interrupts!(struct Irqs {
|
||||||
EXTI7_0 => Test;
|
EXTI7_0 => Test;
|
||||||
});
|
});
|
||||||
|
|
@ -203,15 +304,20 @@ bind_interrupts!(struct Irqs {
|
||||||
use insert_coin::TickTimerService;
|
use insert_coin::TickTimerService;
|
||||||
use insert_coin::{TickService, TickServiceData};
|
use insert_coin::{TickService, TickServiceData};
|
||||||
|
|
||||||
fn debug_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
fn debug_main(mut p: hal::Peripherals) -> ! {
|
||||||
// LED0 output setup
|
// LED0 output setup
|
||||||
use hal::gpio::{Level, Output};
|
use hal::gpio::{Level, Output};
|
||||||
let mut led0_pin = Output::new(p.PC3, Level::High, Default::default());
|
let mut led = Output::new(p.PC3, Level::High, Default::default());
|
||||||
|
|
||||||
delay.delay_ms(1000);
|
// unsafe {
|
||||||
|
// LED = Some(led);
|
||||||
|
// }
|
||||||
|
|
||||||
let tick_rate_hz = 100000; // 100khz
|
println!("pre");
|
||||||
let tick_interval_us = 1000000 / tick_rate_hz;
|
riscv::asm::delay(20_000_000);
|
||||||
|
println!("post2");
|
||||||
|
|
||||||
|
let tick_rate_hz = 100000; // 50khz
|
||||||
|
|
||||||
// DAC output setup
|
// DAC output setup
|
||||||
let dac_pin = PwmPin::new_ch4::<0>(p.PC4);
|
let dac_pin = PwmPin::new_ch4::<0>(p.PC4);
|
||||||
|
|
@ -224,24 +330,76 @@ fn debug_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
Some(dac_pin),
|
Some(dac_pin),
|
||||||
Hertz::khz(200),
|
Hertz::khz(500),
|
||||||
CountingMode::default(),
|
CountingMode::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let pwm_core = SimplePwmCore::new(pwm);
|
let pwm_core = SimplePwmCore::new(pwm);
|
||||||
|
unsafe {
|
||||||
|
use qingke_rt::CoreInterrupt;
|
||||||
|
|
||||||
|
qingke::pfic::disable_interrupt(CoreInterrupt::SysTick as u8);
|
||||||
|
}
|
||||||
|
|
||||||
// === synthesizer setup ===
|
// === synthesizer setup ===
|
||||||
let mut synthesizer = AppSynthesizers::new(tick_rate_hz, pwm_core);
|
// unsafe {
|
||||||
synthesizer.square.set_freq(440);
|
// let mut synth = AppSynthesizers::new(tick_rate_hz, pwm_core);
|
||||||
|
// synth.square.set_freq(440);
|
||||||
|
// SYNTHESIZERS = Some(synth);
|
||||||
|
// }
|
||||||
|
let mut synth = AppSynthesizers::new(tick_rate_hz, pwm_core);
|
||||||
|
synth.square.set_freq(440);
|
||||||
|
|
||||||
#[cfg(feature = "enable_print")]
|
#[cfg(feature = "enable_print")]
|
||||||
println!("begin loop");
|
println!("begin loop");
|
||||||
|
|
||||||
led0_pin.toggle();
|
systick_init(tick_rate_hz);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
use qingke::interrupt::Priority;
|
||||||
|
use qingke_rt::CoreInterrupt;
|
||||||
|
qingke::pfic::set_priority(CoreInterrupt::SysTick as u8, Priority::P15 as u8);
|
||||||
|
qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut index = 0;
|
||||||
|
let freqs = [1567, 1396, 1318, 1174, 1046, 987, 880, 783, 698];
|
||||||
|
// let freqs = [100, 200, 300, 400, 500, 600, 700, 800, 900];
|
||||||
|
// let freqs = [
|
||||||
|
// 1000, 990, 980, 970, 960, 950, 940, 930, 920, 910, 900, 890, 880, 870, 860, 850, 840, 830,
|
||||||
|
// 820, 810, 800, 790, 780, 770, 760, 750, 740, 730, 720, 710, 700, 690, 680, 670, 660, 650,
|
||||||
|
// 640, 630, 620, 610, 600, 590, 580, 570, 560, 550, 540, 530, 520, 510, 500, 490, 480, 470,
|
||||||
|
// 460, 450, 440, 430, 420, 410, 400, 390, 380, 370, 360, 350, 340, 330, 320, 310, 300, 290,
|
||||||
|
// 280, 270, 260, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110,
|
||||||
|
// 100,
|
||||||
|
// ];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
synthesizer.service();
|
if flag() {
|
||||||
delay.delay_us(tick_interval_us as u32);
|
clear_flag();
|
||||||
|
led.toggle();
|
||||||
|
}
|
||||||
|
if synth_flag() {
|
||||||
|
clear_synth_flag();
|
||||||
|
synth.tick();
|
||||||
|
}
|
||||||
|
if note_flag() {
|
||||||
|
clear_note_flag();
|
||||||
|
synth.square.set_freq(freqs[index]);
|
||||||
|
// println!("{}", { freqs[index] });
|
||||||
|
// println!("{}", freqs[index]);
|
||||||
|
index += 1;
|
||||||
|
if index > freqs.len() - 1 {
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if (unsafe { TICK_FLAG == true }) {
|
||||||
|
// println!("TICK!");
|
||||||
|
// led.toggle();
|
||||||
|
// unsafe {
|
||||||
|
// TICK_FLAG = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -394,11 +552,11 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
||||||
// 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");
|
||||||
let coin_sound = include_bytes!("../audio/button_1.raw");
|
// let coin_sound = include_bytes!("../audio/button_1.raw");
|
||||||
|
|
||||||
let button_sound_1 = include_bytes!("../audio/button_1.raw");
|
// let button_sound_1 = include_bytes!("../audio/button_1.raw");
|
||||||
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;
|
let mut system_state = SystemState::Active;
|
||||||
|
|
||||||
|
|
@ -464,7 +622,7 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
||||||
// todo: enter active
|
// todo: enter active
|
||||||
tt0.enable(true);
|
tt0.enable(true);
|
||||||
tt1.enable(true);
|
tt1.enable(true);
|
||||||
interfaces.dac.load_data(coin_sound);
|
// interfaces.dac.load_data(coin_sound);
|
||||||
}
|
}
|
||||||
if INPUT_FLAGS.main_btn_flag {
|
if INPUT_FLAGS.main_btn_flag {
|
||||||
#[cfg(feature = "enable_print")]
|
#[cfg(feature = "enable_print")]
|
||||||
|
|
@ -504,12 +662,12 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
||||||
println!("debounced button_input value: {}", value);
|
println!("debounced button_input value: {}", value);
|
||||||
|
|
||||||
if !value {
|
if !value {
|
||||||
interfaces.dac.load_data(match settings.button_sound_index {
|
// interfaces.dac.load_data(match settings.button_sound_index {
|
||||||
0 => button_sound_1,
|
// 0 => button_sound_1,
|
||||||
1 => button_sound_2,
|
// 1 => button_sound_2,
|
||||||
2 => button_sound_3,
|
// 2 => button_sound_3,
|
||||||
_ => button_sound_1,
|
// _ => button_sound_1,
|
||||||
});
|
// });
|
||||||
// interfaces
|
// interfaces
|
||||||
// .dac
|
// .dac
|
||||||
// .load_data(button_sounds[settings.button_sound_index]);
|
// .load_data(button_sounds[settings.button_sound_index]);
|
||||||
|
|
@ -645,14 +803,16 @@ fn main() -> ! {
|
||||||
let mut p = hal::init(config);
|
let mut p = hal::init(config);
|
||||||
|
|
||||||
// delay to let the debugger attach
|
// delay to let the debugger attach
|
||||||
let mut delay = Delay;
|
println!("pre");
|
||||||
delay.delay_ms(1000);
|
riscv::asm::delay(20_000_000);
|
||||||
|
println!("post");
|
||||||
|
debug_main(p);
|
||||||
|
|
||||||
debug_main(p, delay);
|
|
||||||
// app_main(p, delay);
|
// app_main(p, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||||
|
// println!("panic: {info:?}");
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@ use ch32_hal::println;
|
||||||
use ch32_hal::timer::GeneralInstance16bit;
|
use ch32_hal::timer::GeneralInstance16bit;
|
||||||
use wavetable_synth::{synthesizer::SimpleWavetableSynthesizer, wavetable::SimpleWavetable};
|
use wavetable_synth::{synthesizer::SimpleWavetableSynthesizer, wavetable::SimpleWavetable};
|
||||||
|
|
||||||
const SQUARE_WAVETABLE: [u8; 32] = [
|
const SQUARE_WAVETABLE: [u8; 2] = [0, 100];
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 100, 100, 100, 100, 100,
|
// const SQUARE_WAVETABLE: [u8; 32] = [
|
||||||
100, 100, 100, 100, 100, 100, 100,
|
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 100, 100, 100, 100, 100,
|
||||||
];
|
// 100, 100, 100, 100, 100, 100, 100,
|
||||||
|
// ];
|
||||||
|
|
||||||
pub struct AppSynthesizers<'a, T: GeneralInstance16bit> {
|
pub struct AppSynthesizers<'a, T: GeneralInstance16bit> {
|
||||||
pub square: SimpleWavetableSynthesizer<SimpleWavetable<'static, u8>>,
|
pub square: SimpleWavetableSynthesizer<SimpleWavetable<'static, u8>>,
|
||||||
|
|
@ -21,11 +22,30 @@ impl<'a, T: GeneralInstance16bit> AppSynthesizers<'a, T> {
|
||||||
Self { square, output }
|
Self { square, output }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn service(&mut self) {
|
pub fn tick(&mut self) {
|
||||||
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!("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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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(
|
self.output.write_amplitude(
|
||||||
ch32_hal::timer::Channel::Ch4,
|
ch32_hal::timer::Channel::Ch4,
|
||||||
out / 2,
|
out / 2,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue