-
Notifications
You must be signed in to change notification settings - Fork 2
/
idle.c
125 lines (96 loc) · 3.69 KB
/
idle.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*-------------------------------------------------------------------------
idle.c - handle idle mode on the EC
Copyright (C) 2007 Frieder Ferlemann <Frieder.Ferlemann AT web.de>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
As a special exception, you may use this file as part of a free software
library for the XO of the One Laptop per Child project without restriction.
Specifically, if other files instantiate
templates or use macros or inline functions from this file, or you compile
this file and link it with other files to produce an executable, this
file does not by itself cause the resulting executable to be covered by
the GNU General Public License. This exception does not however
invalidate any other reasons why the executable file might be covered by
the GNU General Public License.
-------------------------------------------------------------------------*/
#include <stdbool.h>
#include "chip.h"
#include "idle.h"
//! This is set by an interrupt routine or a state machine
/*! Value is reset during each iteration of the main loop.
\see may_sleep
*/
bool busy;
//! This is kind of "not busy"
/*! It's value is expected to persevere for more than one
iteration of the main loop.
Note, "maysleep" might not be checked within the sleep mode
(only when entering sleep mode - use "busy" if sleep mode
should be exited). Currently not in use?
\see busy
*/
bool may_sleep = 1;
#if defined(SDCC)
//! Entering low power mode
/*! IRQs should wake us again, but if they do not tell us
to stay awake, then fall asleep again.
*/
void sleep_if_allowed( void )
{
__asm
jnb _may_sleep, END$; not checked within the loop
LOOP$:
clr EA ; disable IRQ to avoid a race condition when checking flags
jb _busy, EXIT$
setb EA ; enable IRQ again, next instruction is executed anyway
orl PCON, #0x01 ; sleep now, see PMUCFG and CLKCFG
sjmp LOOP$
EXIT$:
setb EA
END$:
__endasm;
}
#else
//! Entering low power mode
/*! IRQs should wake us again, but if they do not tell us
to stay awake, then fall asleep again.
*/
void sleep_if_allowed( void )
{
/* disable IRQ to avoid a race condition when checking flags */
EA = 0;
while( !busy && may_sleep )
{
/* enable IRQ again, next instruction executed anyway */
EA = 1;
/* sleep, see PMUCFG and CLKCFG */
PCON |= 0x01;
/* data sheet mentions Ultra Low clock
at one place (PMUCFG bit 3).
Eventually/likely this is the 32768 Hz
clock mentioned for GPT and WDT units.
Can we use it? */
#if defined(SDCC)
__asm
nop
__endasm;
#endif
/* disable IRQ again */
EA = 0;
}
/* leave with IRQ enabled */
EA = 1;
}
#endif