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"); }); }