move most of the system functions out of main.rs
This commit is contained in:
parent
08d7289c93
commit
3eb410c796
2 changed files with 162 additions and 143 deletions
|
|
@ -3,7 +3,12 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![feature(impl_trait_in_assoc_type)]
|
#![feature(impl_trait_in_assoc_type)]
|
||||||
|
|
||||||
|
// app stuff
|
||||||
mod insert_coin;
|
mod insert_coin;
|
||||||
|
|
||||||
|
// system stuff
|
||||||
|
mod system;
|
||||||
|
|
||||||
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};
|
||||||
|
|
||||||
|
|
@ -84,139 +89,6 @@ pub enum SystemState {
|
||||||
Active,
|
Active,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// enter standby (SLEEPDEEP) mode, with WFE enabled.
|
|
||||||
/// from CH32V003 reference manual 2.3.1:
|
|
||||||
/// entry:
|
|
||||||
/// 1. configure core register control bit: SLEEPDEEP=1 | PDDS = 1
|
|
||||||
/// 2. configure external interrupt register to mask all but EXTI7_0
|
|
||||||
/// 3. execute WFI or WFE (optionally SEVONPEND) and SLEEPONEXIT
|
|
||||||
/// * (probably WFI?)
|
|
||||||
/// exit:
|
|
||||||
/// 1. any interrupt/event (set in external interrupt register)
|
|
||||||
unsafe fn enter_standby(pin: usize) {
|
|
||||||
critical_section::with(|_| {
|
|
||||||
use hal::pac::Interrupt;
|
|
||||||
use qingke_rt::CoreInterrupt;
|
|
||||||
|
|
||||||
// configure core register control bit (SLEEPDEEP=1 | PDDS=1)
|
|
||||||
let pfic = &hal::pac::PFIC;
|
|
||||||
pfic.sctlr().modify(|w| {
|
|
||||||
// we only want to wake on enabled interrupts
|
|
||||||
w.set_sevonpend(false);
|
|
||||||
// we want to enable deep sleep
|
|
||||||
w.set_sleepdeep(true);
|
|
||||||
w.set_wfitowfe(false);
|
|
||||||
w.set_sleeponexit(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// set PDDS=1:
|
|
||||||
// get current value of PWR_CTLR
|
|
||||||
let mut reg: u32 = 0x4000_7000;
|
|
||||||
let mut val: u32 = 0;
|
|
||||||
unsafe {
|
|
||||||
val = (reg as *mut u32).read_volatile();
|
|
||||||
}
|
|
||||||
// modify PDDS
|
|
||||||
val |= 1 << 1; // PWR_CTLR[1] -> PDDS
|
|
||||||
unsafe {
|
|
||||||
(reg as *mut u32).write_volatile(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
// // disable all exti interrupts
|
|
||||||
let exti = &hal::pac::EXTI;
|
|
||||||
// exti.intenr().write(| w| {
|
|
||||||
// w.0 = 0x00000000;
|
|
||||||
// // w.set_mr(pin, true);
|
|
||||||
// // w.set_mr(pin, true);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// clear all pending exti interrupts
|
|
||||||
let bits = 0xFFFFFFFF;
|
|
||||||
exti.intfr().write(|w| w.0 = bits);
|
|
||||||
|
|
||||||
// enable all exti interrupts
|
|
||||||
let exti = &hal::pac::EXTI;
|
|
||||||
exti.intenr().write(|w| {
|
|
||||||
w.0 = 0x00FFFFFF;
|
|
||||||
// w.set_mr(pin, true);
|
|
||||||
// w.set_mr(pin, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
qingke::pfic::disable_interrupt(CoreInterrupt::SysTick as u8);
|
|
||||||
qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// execute WFI
|
|
||||||
#[cfg(feature = "enable_print")]
|
|
||||||
println!("WFI CONFIGURED HOPEFULLY");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn init_gpio_irq(pin: u8, port: u8, rising: bool, falling: bool) {
|
|
||||||
critical_section::with(|_| {
|
|
||||||
#[cfg(feature = "enable_print")]
|
|
||||||
println!("init_gpio_irq");
|
|
||||||
let exti = &hal::pac::EXTI;
|
|
||||||
let afio = &hal::pac::AFIO;
|
|
||||||
|
|
||||||
let port = port as u8;
|
|
||||||
let pin = pin as usize;
|
|
||||||
|
|
||||||
// let b = afio.exticr().read();
|
|
||||||
afio.exticr().modify(|w| w.set_exti(pin, port));
|
|
||||||
|
|
||||||
exti.intenr().modify(|w| w.set_mr(pin, true)); // enable interrupt
|
|
||||||
exti.rtenr().modify(|w| w.set_tr(pin, rising));
|
|
||||||
exti.ftenr().modify(|w| w.set_tr(pin, falling));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_interrupt(coin_pin: u8, button_pin: u8) {
|
|
||||||
let exti = &hal::pac::EXTI;
|
|
||||||
|
|
||||||
let coin_pin = coin_pin as usize;
|
|
||||||
let button_pin = button_pin as usize;
|
|
||||||
|
|
||||||
exti.intenr().modify(|w| w.set_mr(coin_pin, false)); // disable interrupt
|
|
||||||
exti.intenr().modify(|w| w.set_mr(button_pin, false)); // disable interrupt
|
|
||||||
|
|
||||||
let bits = exti.intfr().read();
|
|
||||||
|
|
||||||
// We don't handle or change any EXTI lines above 24.
|
|
||||||
let bits = bits.0 & 0x00FFFFFF;
|
|
||||||
|
|
||||||
// coin_flag
|
|
||||||
if (bits & (0x1 << coin_pin)) != 0x0 {
|
|
||||||
#[cfg(feature = "enable_print")]
|
|
||||||
println!("coin irq!");
|
|
||||||
unsafe {
|
|
||||||
INPUT_FLAGS.coin_flag = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// button_flag
|
|
||||||
if (bits & (0x1 << button_pin)) != 0x0 {
|
|
||||||
#[cfg(feature = "enable_print")]
|
|
||||||
println!("button irq!");
|
|
||||||
unsafe {
|
|
||||||
INPUT_FLAGS.button_flag = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear pending - Clears the EXTI's line pending bits.
|
|
||||||
exti.intfr().write(|w| w.0 = bits);
|
|
||||||
|
|
||||||
use hal::pac::Interrupt;
|
|
||||||
unsafe {
|
|
||||||
qingke::pfic::unpend_interrupt(Interrupt::EXTI7_0 as u8);
|
|
||||||
};
|
|
||||||
|
|
||||||
// exti.intenr().modify(|w| w.0 = w.0 & !bits);
|
|
||||||
exti.intenr().modify(|w| w.set_mr(coin_pin, true)); // enable interrupt
|
|
||||||
exti.intenr().modify(|w| w.set_mr(button_pin, true)); // enable interrupt
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct InputFlags {
|
struct InputFlags {
|
||||||
coin_flag: bool,
|
coin_flag: bool,
|
||||||
|
|
@ -233,8 +105,8 @@ impl Handler<hal::interrupt::typelevel::EXTI7_0> for Test {
|
||||||
unsafe fn on_interrupt() {
|
unsafe fn on_interrupt() {
|
||||||
#[cfg(feature = "enable_print")]
|
#[cfg(feature = "enable_print")]
|
||||||
println!("on_interrupt()");
|
println!("on_interrupt()");
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| unsafe {
|
||||||
clear_interrupt(2, 6);
|
INPUT_FLAGS = system::clear_interrupt(2, 6);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -254,12 +126,12 @@ fn debug_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
||||||
|
|
||||||
// button pin setup
|
// button pin setup
|
||||||
let button_pin = p.PD6;
|
let button_pin = p.PD6;
|
||||||
unsafe { init_gpio_irq(button_pin.pin(), button_pin.port(), false, true) };
|
unsafe { system::init_gpio_irq(button_pin.pin(), button_pin.port(), false, true) };
|
||||||
let mut button_input = Input::new(button_pin, Pull::Up);
|
let mut button_input = Input::new(button_pin, Pull::Up);
|
||||||
|
|
||||||
delay.delay_ms(1000);
|
delay.delay_ms(1000);
|
||||||
|
|
||||||
unsafe { enter_standby(4) };
|
unsafe { system::enter_standby(4) };
|
||||||
delay.delay_ms(1000);
|
delay.delay_ms(1000);
|
||||||
riscv::asm::wfi();
|
riscv::asm::wfi();
|
||||||
|
|
||||||
|
|
@ -357,8 +229,8 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
||||||
// 2025-09-10 00:32:23.515: push pin: 6 | push port: 3
|
// 2025-09-10 00:32:23.515: push pin: 6 | push port: 3
|
||||||
|
|
||||||
// set up interrupts
|
// set up interrupts
|
||||||
unsafe { init_gpio_irq(coin_pin.pin(), coin_pin.port(), false, true) };
|
unsafe { system::init_gpio_irq(coin_pin.pin(), coin_pin.port(), false, true) };
|
||||||
unsafe { init_gpio_irq(button_pin.pin(), button_pin.port(), true, true) };
|
unsafe { system::init_gpio_irq(button_pin.pin(), button_pin.port(), true, true) };
|
||||||
|
|
||||||
// coin debouncer (100ms)
|
// coin debouncer (100ms)
|
||||||
let mut coin_input = DebouncedGPIO::new(coin_pin.degrade(), core_config.tick_rate_hz, 100);
|
let mut coin_input = DebouncedGPIO::new(coin_pin.degrade(), core_config.tick_rate_hz, 100);
|
||||||
|
|
@ -411,7 +283,8 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
||||||
let tick_interval_us = 1000000 / interfaces.config.tick_rate_hz - 10;
|
let tick_interval_us = 1000000 / interfaces.config.tick_rate_hz - 10;
|
||||||
|
|
||||||
// dac data
|
// dac data
|
||||||
let coin_sound = include_bytes!("../audio/coin.raw");
|
// let coin_sound = include_bytes!("../audio/coin.raw");
|
||||||
|
let coin_sound = include_bytes!("../audio/sweep_dpcm_u4.raw");
|
||||||
// let button_sound = include_bytes!("../audio/coinMixTest1_dpcm_u4.raw");
|
// let button_sound = include_bytes!("../audio/coinMixTest1_dpcm_u4.raw");
|
||||||
|
|
||||||
let mut system_state = SystemState::Active;
|
let mut system_state = SystemState::Active;
|
||||||
|
|
@ -425,7 +298,7 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
||||||
// use qingke_rt::CoreInterrupt;
|
// use qingke_rt::CoreInterrupt;
|
||||||
|
|
||||||
// qingke::pfic::unpend_interrupt(Interrupt::EXTI7_0 as u8);
|
// qingke::pfic::unpend_interrupt(Interrupt::EXTI7_0 as u8);
|
||||||
clear_interrupt(2, 6);
|
system::clear_interrupt(2, 6);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
@ -540,7 +413,7 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
||||||
match system_state {
|
match system_state {
|
||||||
SystemState::DeepSleep => {
|
SystemState::DeepSleep => {
|
||||||
// TODO: make this REALLY deep sleep
|
// TODO: make this REALLY deep sleep
|
||||||
unsafe { enter_standby(4) };
|
unsafe { system::enter_standby(4) };
|
||||||
loop {
|
loop {
|
||||||
riscv::asm::wfi();
|
riscv::asm::wfi();
|
||||||
let mut config = hal::Config::default();
|
let mut config = hal::Config::default();
|
||||||
|
|
@ -600,7 +473,8 @@ fn main() -> ! {
|
||||||
let mut delay = Delay;
|
let mut delay = Delay;
|
||||||
delay.delay_ms(1000);
|
delay.delay_ms(1000);
|
||||||
|
|
||||||
debug_main(p, delay);
|
// debug_main(p, delay);
|
||||||
|
app_main(p, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
|
|
|
||||||
145
ch32v-insert-coin/src/system.rs
Normal file
145
ch32v-insert-coin/src/system.rs
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
use ch32_hal as hal;
|
||||||
|
use hal::println;
|
||||||
|
|
||||||
|
pub unsafe fn init_gpio_irq(pin: u8, port: u8, rising: bool, falling: bool) {
|
||||||
|
critical_section::with(|_| {
|
||||||
|
#[cfg(feature = "enable_print")]
|
||||||
|
println!("init_gpio_irq");
|
||||||
|
let exti = &hal::pac::EXTI;
|
||||||
|
let afio = &hal::pac::AFIO;
|
||||||
|
|
||||||
|
let port = port as u8;
|
||||||
|
let pin = pin as usize;
|
||||||
|
|
||||||
|
// let b = afio.exticr().read();
|
||||||
|
afio.exticr().modify(|w| w.set_exti(pin, port));
|
||||||
|
|
||||||
|
exti.intenr().modify(|w| w.set_mr(pin, true)); // enable interrupt
|
||||||
|
exti.rtenr().modify(|w| w.set_tr(pin, rising));
|
||||||
|
exti.ftenr().modify(|w| w.set_tr(pin, falling));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: should return a vec of the interrupts
|
||||||
|
pub fn clear_interrupt(coin_pin: u8, button_pin: u8) -> crate::InputFlags {
|
||||||
|
let mut input_flags = crate::InputFlags {
|
||||||
|
coin_flag: false,
|
||||||
|
button_flag: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let exti = &hal::pac::EXTI;
|
||||||
|
|
||||||
|
let coin_pin = coin_pin as usize;
|
||||||
|
let button_pin = button_pin as usize;
|
||||||
|
|
||||||
|
exti.intenr().modify(|w| w.set_mr(coin_pin, false)); // disable interrupt
|
||||||
|
exti.intenr().modify(|w| w.set_mr(button_pin, false)); // disable interrupt
|
||||||
|
|
||||||
|
let bits = exti.intfr().read();
|
||||||
|
|
||||||
|
// We don't handle or change any EXTI lines above 24.
|
||||||
|
let bits = bits.0 & 0x00FFFFFF;
|
||||||
|
|
||||||
|
// coin_flag
|
||||||
|
if (bits & (0x1 << coin_pin)) != 0x0 {
|
||||||
|
#[cfg(feature = "enable_print")]
|
||||||
|
println!("coin irq!");
|
||||||
|
input_flags.coin_flag = true;
|
||||||
|
// unsafe {
|
||||||
|
// INPUT_FLAGS.coin_flag = true;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// button_flag
|
||||||
|
if (bits & (0x1 << button_pin)) != 0x0 {
|
||||||
|
#[cfg(feature = "enable_print")]
|
||||||
|
println!("button irq!");
|
||||||
|
input_flags.button_flag = true;
|
||||||
|
// unsafe {
|
||||||
|
// INPUT_FLAGS.button_flag = true;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear pending - Clears the EXTI's line pending bits.
|
||||||
|
exti.intfr().write(|w| w.0 = bits);
|
||||||
|
|
||||||
|
use hal::pac::Interrupt;
|
||||||
|
unsafe {
|
||||||
|
qingke::pfic::unpend_interrupt(Interrupt::EXTI7_0 as u8);
|
||||||
|
};
|
||||||
|
|
||||||
|
// exti.intenr().modify(|w| w.0 = w.0 & !bits);
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
/// enter standby (SLEEPDEEP) mode, with WFE enabled.
|
||||||
|
/// from CH32V003 reference manual 2.3.1:
|
||||||
|
/// entry:
|
||||||
|
/// 1. configure core register control bit: SLEEPDEEP=1 | PDDS = 1
|
||||||
|
/// 2. configure external interrupt register to mask all but EXTI7_0
|
||||||
|
/// 3. execute WFI or WFE (optionally SEVONPEND) and SLEEPONEXIT
|
||||||
|
/// * (probably WFI?)
|
||||||
|
/// exit:
|
||||||
|
/// 1. any interrupt/event (set in external interrupt register)
|
||||||
|
pub unsafe fn enter_standby(pin: usize) {
|
||||||
|
critical_section::with(|_| {
|
||||||
|
use hal::pac::Interrupt;
|
||||||
|
use qingke_rt::CoreInterrupt;
|
||||||
|
|
||||||
|
// configure core register control bit (SLEEPDEEP=1 | PDDS=1)
|
||||||
|
let pfic = &hal::pac::PFIC;
|
||||||
|
pfic.sctlr().modify(|w| {
|
||||||
|
// we only want to wake on enabled interrupts
|
||||||
|
w.set_sevonpend(false);
|
||||||
|
// we want to enable deep sleep
|
||||||
|
w.set_sleepdeep(true);
|
||||||
|
w.set_wfitowfe(false);
|
||||||
|
w.set_sleeponexit(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// set PDDS=1:
|
||||||
|
// get current value of PWR_CTLR
|
||||||
|
let mut reg: u32 = 0x4000_7000;
|
||||||
|
let mut val: u32 = 0;
|
||||||
|
unsafe {
|
||||||
|
val = (reg as *mut u32).read_volatile();
|
||||||
|
}
|
||||||
|
// modify PDDS
|
||||||
|
val |= 1 << 1; // PWR_CTLR[1] -> PDDS
|
||||||
|
unsafe {
|
||||||
|
(reg as *mut u32).write_volatile(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
// // disable all exti interrupts
|
||||||
|
let exti = &hal::pac::EXTI;
|
||||||
|
// exti.intenr().write(| w| {
|
||||||
|
// w.0 = 0x00000000;
|
||||||
|
// // w.set_mr(pin, true);
|
||||||
|
// // w.set_mr(pin, true);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// clear all pending exti interrupts
|
||||||
|
let bits = 0xFFFFFFFF;
|
||||||
|
exti.intfr().write(|w| w.0 = bits);
|
||||||
|
|
||||||
|
// enable all exti interrupts
|
||||||
|
let exti = &hal::pac::EXTI;
|
||||||
|
exti.intenr().write(|w| {
|
||||||
|
w.0 = 0x00FFFFFF;
|
||||||
|
// w.set_mr(pin, true);
|
||||||
|
// w.set_mr(pin, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
qingke::pfic::disable_interrupt(CoreInterrupt::SysTick as u8);
|
||||||
|
qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute WFI
|
||||||
|
#[cfg(feature = "enable_print")]
|
||||||
|
println!("WFI CONFIGURED HOPEFULLY");
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue