SimpleSleep
An Arduino library for simple means of putting your Arduino into low power sleep modes.
Main Page
Classes
Files
File List
avr.h
Go to the documentation of this file.
1
6
#ifndef SS_AVR_h
7
#define SS_AVR_h
8
#if defined (__AVR__)
9
10
#include <Arduino.h>
11
12
#include <avr/sleep.h>
13
#include <avr/wdt.h>
14
#include <avr/power.h>
15
#include <avr/interrupt.h>
16
19
#include "ATMegaX8.h"
20
#include "ATTinyX5.h"
21
#include "ATTinyX4.h"
22
#include "ATTiny13.h"
23
24
#ifndef SS_SUPPORTED_CHIP
25
#error "SimpleSleep does not support this microcontroller."
26
#endif
27
33
#ifndef SS_USE_INT_CAL
34
#define SS_USE_INT_CAL 1
35
#endif
36
37
#ifdef NO_MILLIS
38
39
/* If millis is not available, then we can not really do calibration,
40
* the calibration will always just return 1
41
*/
42
43
typedef
uint8_t SimpleSleep_Cal;
44
45
#elif SS_USE_INT_CAL == 1
46
58
struct
SimpleSleep_Cal
59
{
60
int8_t adjust15MS = 0;
// Increase or decrease the sleepMs by this many mS every 15mS
61
int8_t adjust250MS = 0;
// Increase or decrease the sleepMs by this many mS every 250mS
62
};
63
64
#else
65
69
typedef
float
SimpleSleep_Cal;
70
#endif
71
73
#ifndef WDT_HAS_INTERRUPT
74
#if !defined(WDIE) && !defined(WDTIE)
75
#define WDT_HAS_INTERRUPT 0
76
#else
77
#define WDT_HAS_INTERRUPT 1
78
#endif
79
#endif
80
90
inline
uint16_t wdt_period_for(uint32_t *sleepMs)
91
{
92
#ifdef WDP3
93
// 8000, 4000, 2000, 1000, 500, 250, and then 120, 60, 30, 15
94
uint16_t period = 8000;
95
int8_t x = 9;
96
#else
97
// 2000, 1000, 500, 250, and then 120, 60, 30, 15
98
uint16_t period = 2000;
99
int8_t x = 7;
100
#endif
101
102
while
(x >= 1)
103
{
104
if
(*sleepMs >= period)
105
{
106
*sleepMs -= period;
107
return
x;
108
}
109
110
x--;
111
period/=2;
112
113
// There are two sequences, 8000->250 and 120->15 so that you don't
114
// end up fractional,so once we hit 125, drop down to the 120->15 seequence
115
if
(period == 125)
116
{
117
period = 120;
118
}
119
}
120
121
// The sleep time is less than 30mS (x == 1), if it's greater than 15mS,
122
// spin-wait until it's 15mS then allow the WDT to do the rest, if it's less
123
// than 15mS then 15mS it is, that is the minimum we can sleep for and we
124
// MUST sleep.
125
126
if
(*sleepMs > 15)
127
{
128
delay(*sleepMs - 15);
129
}
130
131
*sleepMs = 0;
132
return
WDTO_15MS;
133
}
134
150
#define power_declare_all(...) \
151
power_declare_prr(__VA_ARGS__); \
152
power_declare_prr0(__VA_ARGS__);\
153
power_declare_prr1(__VA_ARGS__);\
154
power_declare_prr2(__VA_ARGS__);\
155
power_declare_prpa(__VA_ARGS__);\
156
power_declare_prpb(__VA_ARGS__);\
157
power_declare_prpc(__VA_ARGS__);\
158
power_declare_prpd(__VA_ARGS__);\
159
power_declare_prpe(__VA_ARGS__);\
160
power_declare_prpf(__VA_ARGS__);\
161
power_declare_prgen(__VA_ARGS__);
162
163
174
#define power_save_all() \
175
power_save_prr(); \
176
power_save_prr0();\
177
power_save_prr1();\
178
power_save_prr2();\
179
power_save_prpa();\
180
power_save_prpb();\
181
power_save_prpc();\
182
power_save_prpd();\
183
power_save_prpe();\
184
power_save_prpf();\
185
power_save_prgen();
186
187
198
#define power_restore_all() \
199
power_restore_prr(); \
200
power_restore_prr0();\
201
power_restore_prr1();\
202
power_restore_prr2();\
203
power_restore_prpa();\
204
power_restore_prpb();\
205
power_restore_prpc();\
206
power_restore_prpd();\
207
power_restore_prpe();\
208
power_restore_prpf();\
209
power_restore_prgen();
210
211
// The below register names are extraced from
212
// cat ./hardware/tools/avr/avr/include/avr/power.h | grep "define powe" | grep -Po "[0-9A-Z_]+ &" | sort | uniq
213
214
#ifdef PRR
215
#define power_declare_prr(...) __VA_ARGS__ uint8_t oldPRR;
216
#define power_save_prr() oldPRR = PRR;
217
#define power_restore_prr() PRR = oldPRR;
218
#else
219
#define power_declare_prr(...)
220
#define power_save_prr()
221
#define power_restore_prr()
222
#endif
223
224
#ifdef PRR0
225
#define power_declare_prr0(...) __VA_ARGS__ uint8_t oldPRR0;
226
#define power_save_prr0() oldPRR0 = PRR0;
227
#define power_restore_prr0() PRR = oldPRR0;
228
#else
229
#define power_declare_prr0(...)
230
#define power_save_prr0()
231
#define power_restore_prr0()
232
#endif
233
234
#ifdef PRR1
235
#define power_declare_prr1(...) __VA_ARGS__ uint8_t oldPRR1;
236
#define power_save_prr1() oldPRR1 = PRR1;
237
#define power_restore_prr1() PRR = oldPRR1;
238
#else
239
#define power_declare_prr1(...)
240
#define power_save_prr1()
241
#define power_restore_prr1()
242
#endif
243
244
#ifdef PRR2
245
#define power_declare_prr2(...) __VA_ARGS__ uint8_t oldPRR2;
246
#define power_save_prr2() oldPRR2 = PRR2;
247
#define power_restore_prr2() PRR = oldPRR2;
248
#else
249
#define power_declare_prr2(...)
250
#define power_save_prr2()
251
#define power_restore_prr2()
252
#endif
253
254
#ifdef PR_PRPF
255
#define power_declare_prpf(...) __VA_ARGS__ uint8_t oldPRPF;
256
#define power_save_prpf() oldPR_PRPF = PR_PRPF;
257
#define power_restore_prpf() PR_PRPF = oldPR_PRPF;
258
#else
259
#define power_declare_prpf(...)
260
#define power_save_prpf()
261
#define power_restore_prpf()
262
#endif
263
264
#ifdef PR_PRPE
265
#define power_declare_prpe(...) __VA_ARGS__ uint8_t oldPRPE;
266
#define power_save_prpe() oldPR_PRPE = PR_PRPE;
267
#define power_restore_prpe() PR_PRPE = oldPR_PRPE;
268
#else
269
#define power_declare_prpe(...)
270
#define power_save_prpe()
271
#define power_restore_prpe()
272
#endif
273
274
#ifdef PR_PRPD
275
#define power_declare_prpd(...) __VA_ARGS__ uint8_t oldPRPD;
276
#define power_save_prpd() oldPR_PRPD = PR_PRPD;
277
#define power_restore_prpd() PR_PRPD = oldPR_PRPD;
278
#else
279
#define power_declare_prpd(...)
280
#define power_save_prpd()
281
#define power_restore_prpd()
282
#endif
283
284
#ifdef PR_PRPC
285
#define power_declare_prpc(...) __VA_ARGS__ uint8_t oldPRPC;
286
#define power_save_prpc() oldPR_PRPC = PR_PRPC;
287
#define power_restore_prpc() PR_PRPC = oldPR_PRPC;
288
#else
289
#define power_declare_prpc(...)
290
#define power_save_prpc()
291
#define power_restore_prpc()
292
#endif
293
294
#ifdef PR_PRPB
295
#define power_declare_prpb(...) __VA_ARGS__ uint8_t oldPRPB;
296
#define power_save_prpb() oldPR_PRPB = PR_PRPB;
297
#define power_restore_prpb() PR_PRPB = oldPR_PRPB;
298
#else
299
#define power_declare_prpb(...)
300
#define power_save_prpb()
301
#define power_restore_prpb()
302
#endif
303
304
#ifdef PR_PRPA
305
#define power_declare_prpa(...) __VA_ARGS__ uint8_t oldPRPA;
306
#define power_save_prpa() oldPR_PRPA = PR_PRPA;
307
#define power_restore_prpa() PR_PRPA = oldPR_PRPA;
308
#else
309
#define power_declare_prpa(...)
310
#define power_save_prpa()
311
#define power_restore_prpa()
312
#endif
313
314
#ifdef PR_PRGEN
315
#define power_declare_prgen(...) __VA_ARGS__ uint8_t oldPRGEN;
316
#define power_save_prgen() oldPR_PRGEN = PR_PRGEN;
317
#define power_restore_prgen() PR_PRGEN = oldPR_PRGEN;
318
#else
319
#define power_declare_prgen(...)
320
#define power_save_prgen()
321
#define power_restore_prgen()
322
#endif
323
324
#if defined(PRR) || defined(PRR0) || defined(PRR1) || defined(PRR2) || \
325
defined( PR_PRPA ) || defined( PR_PRPB ) || defined( PR_PRPC ) || defined( PR_PRPD ) || defined( PR_PRPE ) || defined( PR_PRPF ) || \
326
defined(PRGEN)
327
328
#define power_has_power() 1
329
#else
330
#define power_has_power() 0
331
#endif
332
#endif
333
#endif
src
avr
avr.h
Generated on Tue Aug 28 2018 12:10:52 for SimpleSleep by
1.8.9.1