-
Notifications
You must be signed in to change notification settings - Fork 0
/
sleep.rs
67 lines (57 loc) · 1.37 KB
/
sleep.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use avr_device::attiny1616::slpctrl::ctrla::SMODE_A;
use avr_device::attiny1616::SLPCTRL;
use portable_atomic::AtomicU8;
#[export_name = "__sleep"]
unsafe fn sleep() {
SLPCTRL::steal().ctrla().modify(|_, w| w.sen().set_bit());
avr_device::asm::sleep();
SLPCTRL::steal().ctrla().modify(|_, w| w.sen().clear_bit());
}
static COFFEE: AtomicU8 = AtomicU8::new(0);
pub struct Mug(bool);
impl Mug {
pub fn new() -> Self {
Self(false)
}
pub fn caffeinate(&mut self) {
if !self.0 {
caffeinate();
self.0 = true;
}
}
pub fn decaffeinate(&mut self) {
if self.0 {
decaffeinate();
self.0 = false;
}
}
}
fn caffeinate() {
let v = COFFEE.fetch_add(1, portable_atomic::Ordering::SeqCst);
if v == 0 {
set_sleep_mode(SMODE_A::STANDBY);
}
}
fn decaffeinate() {
let v = COFFEE.fetch_sub(1, portable_atomic::Ordering::SeqCst);
if v == 1 {
set_sleep_mode(SMODE_A::PDOWN);
}
}
#[macro_export]
macro_rules! with_wakelock {
($e:expr) => {{
let mut m = crate::sleep::Mug::new();
m.caffeinate();
let result = $e;
m.decaffeinate();
result
}};
}
pub fn set_sleep_mode(mode: SMODE_A) {
unsafe {
SLPCTRL::steal()
.ctrla()
.modify(|_, w| w.smode().variant(mode));
}
}