deep sleep and wakeup working!
This commit is contained in:
parent
fba0fbec61
commit
1a420018d1
2 changed files with 109 additions and 48 deletions
|
|
@ -3,6 +3,9 @@ name = "ch32v-insert-coin"
|
|||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[features]
|
||||
enable_print = []
|
||||
|
||||
[dependencies]
|
||||
ch32-hal = { path = "ext/ch32-hal/", features = [
|
||||
"ch32v003f4u6",
|
||||
|
|
|
|||
|
|
@ -102,56 +102,53 @@ unsafe fn enter_standby(pin: usize) {
|
|||
let pfic = &hal::pac::PFIC;
|
||||
pfic.sctlr().modify(|w| {
|
||||
// we only want to wake on enabled interrupts
|
||||
w.set_sevonpend(true);
|
||||
w.set_sevonpend(false);
|
||||
// we want to enable deep sleep
|
||||
w.set_sleepdeep(true);
|
||||
w.set_wfitowfe(true);
|
||||
w.set_wfitowfe(false);
|
||||
w.set_sleeponexit(false);
|
||||
});
|
||||
|
||||
// // disable all exti interrupts
|
||||
// let exti = &hal::pac::EXTI;
|
||||
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
|
||||
// clear all pending exti interrupts
|
||||
let bits = 0xFFFFFFFF;
|
||||
exti.intfr().write(|w| w.0 = bits);
|
||||
|
||||
|
||||
// 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);
|
||||
// });
|
||||
// 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::disable_interrupt(CoreInterrupt::SysTick as u8);
|
||||
qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8);
|
||||
}
|
||||
|
||||
// execute WFI
|
||||
|
||||
// execute WFI
|
||||
#[cfg(feature="enable_print")]
|
||||
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");
|
||||
let exti = &hal::pac::EXTI;
|
||||
let afio = &hal::pac::AFIO;
|
||||
#[cfg(features="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;
|
||||
|
|
@ -181,6 +178,7 @@ fn clear_interrupt(coin_pin: u8, button_pin: u8) {
|
|||
|
||||
// coin_flag
|
||||
if (bits & (0x1 << coin_pin)) != 0x0 {
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("coin irq!");
|
||||
unsafe {
|
||||
INPUT_FLAGS.coin_flag = true;
|
||||
|
|
@ -189,6 +187,7 @@ fn clear_interrupt(coin_pin: u8, button_pin: u8) {
|
|||
|
||||
// button_flag
|
||||
if (bits & (0x1 << button_pin)) != 0x0 {
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("button irq!");
|
||||
unsafe {
|
||||
INPUT_FLAGS.button_flag = true;
|
||||
|
|
@ -222,6 +221,7 @@ static mut INPUT_FLAGS: InputFlags = InputFlags {
|
|||
struct Test {}
|
||||
impl Handler<hal::interrupt::typelevel::EXTI7_0> for Test {
|
||||
unsafe fn on_interrupt() {
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("on_interrupt()");
|
||||
critical_section::with(|_| {
|
||||
clear_interrupt(2, 6);
|
||||
|
|
@ -237,16 +237,37 @@ bind_interrupts!(struct Irqs {
|
|||
use insert_coin::TickTimerService;
|
||||
use insert_coin::{TickService, TickServiceData};
|
||||
|
||||
#[qingke_rt::entry]
|
||||
fn main() -> ! {
|
||||
hal::debug::SDIPrint::enable();
|
||||
let mut config = hal::Config::default();
|
||||
config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSE;
|
||||
let p = hal::init(config);
|
||||
fn debug_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
||||
// LED0 output setup
|
||||
use hal::gpio::{Output, Level};
|
||||
let mut led0_pin = Output::new(p.PC3, Level::High, Default::default());
|
||||
|
||||
// button pin setup
|
||||
let button_pin = p.PD6;
|
||||
unsafe {init_gpio_irq(button_pin.pin(), button_pin.port(), false, true)};
|
||||
let mut button_input = Input::new(button_pin, Pull::Up);
|
||||
|
||||
// delay to let the debugger attach
|
||||
let mut delay = Delay;
|
||||
delay.delay_ms(1000);
|
||||
|
||||
unsafe{enter_standby(4)};
|
||||
delay.delay_ms(1000);
|
||||
riscv::asm::wfi();
|
||||
|
||||
// get the clocks re-initialized
|
||||
let mut config = hal::Config::default();
|
||||
config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI;
|
||||
unsafe { hal::rcc::init(config.rcc); }
|
||||
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("begin loop");
|
||||
|
||||
loop {
|
||||
led0_pin.toggle();
|
||||
delay.delay_ms(100);
|
||||
}
|
||||
}
|
||||
|
||||
fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
|
||||
|
||||
// === output setup ===
|
||||
|
||||
|
|
@ -296,6 +317,8 @@ fn main() -> ! {
|
|||
// println!("ADC_PIN CHANNEL: {}", adc_pin.channel().channel());
|
||||
delay.delay_ms(1000);
|
||||
let adc_cal = adc.calibrate();
|
||||
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("ADC calibration value: {}", adc_cal);
|
||||
|
||||
// definitions
|
||||
|
|
@ -384,9 +407,9 @@ fn main() -> ! {
|
|||
// 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);
|
||||
clear_interrupt(2, 6);
|
||||
qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8);
|
||||
// qingke::pfic::enable_interrupt(CoreInterrupt::SysTick as u8);
|
||||
}
|
||||
|
||||
// MAIN APPLICATION
|
||||
|
|
@ -397,12 +420,14 @@ fn main() -> ! {
|
|||
// -depress the big button for approx 2s and it puts the led into low light mode. Just making it dimmer than usual.
|
||||
// -depress the big button for 5s and it goes into deep sleep, everything off with the low sleep current draw
|
||||
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("begin");
|
||||
loop {
|
||||
{
|
||||
// system input servicing
|
||||
unsafe {
|
||||
if INPUT_FLAGS.coin_flag {
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("coin flag active");
|
||||
INPUT_FLAGS.coin_flag = false;
|
||||
coin_input.begin();
|
||||
|
|
@ -415,6 +440,7 @@ fn main() -> ! {
|
|||
interfaces.dac.load_data(coin_sound);
|
||||
}
|
||||
if INPUT_FLAGS.button_flag {
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("button flag active");
|
||||
INPUT_FLAGS.button_flag = false;
|
||||
button_input.begin();
|
||||
|
|
@ -426,17 +452,20 @@ fn main() -> ! {
|
|||
button_input.service();
|
||||
|
||||
if coin_input.ready() {
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("debounced coin_input value: {}", coin_input.value());
|
||||
coin_input.reset();
|
||||
}
|
||||
if button_input.ready() {
|
||||
let value = button_input.value();
|
||||
button_input.reset();
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("debounced button_input value: {}", value);
|
||||
|
||||
if !value {
|
||||
// interfaces.dac.load_data(button_sound);
|
||||
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("reset hold timers + enable");
|
||||
sp_timer.reset();
|
||||
sp_timer.enable(true);
|
||||
|
|
@ -454,6 +483,7 @@ fn main() -> ! {
|
|||
adc1_timer.tick();
|
||||
|
||||
if sp_timer.need_service() {
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("sp detect!");
|
||||
sp_timer.reset();
|
||||
|
||||
|
|
@ -466,6 +496,7 @@ fn main() -> ! {
|
|||
}
|
||||
|
||||
if lp_timer.need_service() {
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("lp detect!");
|
||||
lp_timer.reset();
|
||||
|
||||
|
|
@ -479,6 +510,7 @@ fn main() -> ! {
|
|||
|
||||
if adc1_timer.need_service() {
|
||||
let val = adc.convert(&mut adc_pin, hal::adc::SampleTime::CYCLES241);
|
||||
#[cfg(feature="enable_print")]
|
||||
println!("ADC value: {}", val);
|
||||
|
||||
adc1_timer.reset();
|
||||
|
|
@ -488,18 +520,24 @@ 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 => {}
|
||||
// TODO: make this REALLY deep sleep
|
||||
unsafe{enter_standby(4)};
|
||||
loop {
|
||||
riscv::asm::wfi();
|
||||
let mut config = hal::Config::default();
|
||||
config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI;
|
||||
unsafe { hal::rcc::init(config.rcc); }
|
||||
unsafe{
|
||||
if INPUT_FLAGS.coin_flag {
|
||||
system_state = SystemState::Active;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
SystemState::Idle => {
|
||||
|
||||
},
|
||||
SystemState::Active => {
|
||||
tt0.tick();
|
||||
tt1.tick();
|
||||
|
|
@ -530,6 +568,26 @@ fn main() -> ! {
|
|||
}
|
||||
}
|
||||
|
||||
#[qingke_rt::entry]
|
||||
fn main() -> ! {
|
||||
#[cfg(feature="enable_print")]
|
||||
hal::debug::SDIPrint::enable();
|
||||
|
||||
let mut config = hal::Config::default();
|
||||
config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI;
|
||||
let mut p = hal::init(config);
|
||||
|
||||
// delay to let the debugger attach
|
||||
let mut delay = Delay;
|
||||
delay.delay_ms(1000);
|
||||
|
||||
debug_main(p, delay);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue