From 83c2a64f129cecf3eb6e1d8327df760405c1ace2 Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Sat, 30 Aug 2025 13:54:13 -0600 Subject: [PATCH] holy shit i think it's deep sleeping --- ch32v-insert-coin/src/main.rs | 155 ++++++++++++++++++++++++++-------- 1 file changed, 119 insertions(+), 36 deletions(-) diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index ac2877e..9bf1359 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -84,6 +84,73 @@ pub enum SystemState { 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(true); + // we want to enable deep sleep + w.set_sleepdeep(true); + w.set_wfitowfe(true); + w.set_sleeponexit(false); + }); + + // // 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(Interrupt::EXTI7_0 as u8); + // qingke::pfic::disable_interrupt(CoreInterrupt::SysTick as u8); + // qingke::pfic::disable_interrupt(CoreInterrupt::SysTick as u8); + qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8); + } + + + // execute WFI + println!("WFI CONFIGURED HOPEFULLY"); + + // core::arch::asm!("wfi"); + + // pfic. + // qingke::pfic:: + }); + +} + unsafe fn init_gpio_irq(pin: u8, port: u8, rising: bool, falling: bool) { critical_section::with(|_| { println!("init_gpio_irq"); @@ -135,7 +202,11 @@ fn clear_interrupt (coin_pin: u8, button_pin: u8) { // Clear pending - Clears the EXTI's line pending bits. exti.intfr().write(|w| w.0 = bits); - exti.intenr().modify(|w| w.0 = 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 } @@ -297,8 +368,13 @@ fn main() -> ! { unsafe { use hal::pac::Interrupt; + // use qingke_rt::CoreInterrupt; + + // qingke::pfic::unpend_interrupt(Interrupt::EXTI7_0 as u8); + clear_interrupt(4, 6); qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8); + // qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8); } @@ -312,41 +388,6 @@ fn main() -> ! { println!("begin"); loop { - match system_state { - SystemState::DeepSleep => { - // TODO: make this REALLY deep sleep - riscv::asm::wfi(); - }, - SystemState::Idle => { - - }, - SystemState::Active => { - tt0.tick(); - tt1.tick(); - - if tt0.need_service() { - interfaces.led0.set_amplitude(led0_dcs[led0_index]); - led0_index += 1; - if led0_index > led0_dcs.len() - 1 { - led0_index = 0; - } - tt0.service(); - } - - if tt1.need_service() { - interfaces.led1.set_amplitude(led1_dcs[led1_index]); - led1_index += 1; - if led1_index > led1_dcs.len() - 1 { - led1_index = 0; - } - tt1.service() - } - - interfaces.service(); - }, - } - - { // system input servicing unsafe { @@ -431,6 +472,48 @@ fn main() -> ! { } } + match system_state { + SystemState::DeepSleep => { + // TODO: make this REALLY deep sleep + unsafe{enter_standby(4)}; + loop { + riscv::asm::wfi(); + unsafe{ + if INPUT_FLAGS.coin_flag { + break; + } + }; + } + }, + SystemState::Idle => { + + }, + SystemState::Active => { + tt0.tick(); + tt1.tick(); + + if tt0.need_service() { + interfaces.led0.set_amplitude(led0_dcs[led0_index]); + led0_index += 1; + if led0_index > led0_dcs.len() - 1 { + led0_index = 0; + } + tt0.service(); + } + + if tt1.need_service() { + interfaces.led1.set_amplitude(led1_dcs[led1_index]); + led1_index += 1; + if led1_index > led1_dcs.len() - 1 { + led1_index = 0; + } + tt1.service() + } + + interfaces.service(); + }, + } + delay.delay_us(tick_interval_us as u32); } }