-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsleep.c
63 lines (46 loc) · 1.16 KB
/
sleep.c
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
// SPDX-FileCopyrightText: 2023 Andreas Sig Rosvall
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "bsp/clock.h"
#include "bsp/interrupts.h"
#include "bsp/sleep.h"
#include "bsp/watchdog.h"
#include "led.h"
#include "log.h"
#include "radio.h"
#include "sleep.h"
__bit sleep_flag;
static void
sleep(void)
{
// The instruction immediately following the write to PCON
// is only correctly executed on resume if NOT 4-byte aligned!
// NOTE: Flash cache MUST be on!
// Align the 3 byte 'mov PCON, #PCON_IDLE' to an even address, so
// the next instructon is on an odd address
__asm__(".even");
PCON = PCON_IDLE;
interrupts_disable();
// And now we resume here and return to caller,
// instead of the interrupt handler that woke us up...
}
void
sleep_enter_pm1(void)
{
LOGI(__func__);
radio_stop();
watchdog_feed();
led_red_off();
led_green_off();
// Go to sleep
SLEEPCMD = SLEEPCMD_MODE_PM1;
sleep();
// We're awake again with interrupts off
// Wait for oscillator to be stable again
do {
watchdog_feed();
} while (CLKCONSTA & CLK_OSC_16MHZ_RC);
LOGI("resuming now");
// Now let's handle the interrupt that woke us up
interrupts_enable();
}