164 lines
5.2 KiB
Rust
164 lines
5.2 KiB
Rust
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 {pin}:{port}");
|
|
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));
|
|
});
|
|
}
|
|
|
|
pub fn clear_interrupt(coin_pin: u8, button_pin: u8) -> crate::InputFlags {
|
|
let mut input_flags = crate::InputFlags::default();
|
|
|
|
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;
|
|
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;
|
|
}
|
|
|
|
// 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}");
|
|
// // }
|
|
// }
|
|
}
|
|
|
|
// 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);
|
|
|
|
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() {
|
|
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 = unsafe { (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");
|
|
});
|
|
}
|