blob: 1b8f864a74025ef832179209778b194fc9b45d3d (
plain)
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
|
/*
* fsm-misc.c: Miscellaneous function for SpaghettiMonster.
*
* Copyright (C) 2017 Selene ToyKeeper
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef FSM_MISC_C
#define FSM_MISC_C
#ifdef USE_DYNAMIC_UNDERCLOCKING
void auto_clock_speed() {
uint8_t level = actual_level; // volatile, avoid repeat access
if (level < QUARTERSPEED_LEVEL) {
// run at quarter speed
// note: this only works when executed as two consecutive instructions
// (don't try to combine them or put other stuff between)
CLKPR = 1<<CLKPCE; CLKPR = 2;
}
else if (level < HALFSPEED_LEVEL) {
// run at half speed
CLKPR = 1<<CLKPCE; CLKPR = 1;
} else {
// run at full speed
CLKPR = 1<<CLKPCE; CLKPR = 0;
}
}
#endif
#if defined(USE_BLINK_NUM) || defined(USE_BLINK_DIGIT)
uint8_t blink_digit(uint8_t num) {
//StatePtr old_state = current_state;
// "zero" digit gets a single short blink
uint8_t ontime = 200;
if (!num) { ontime = 8; num ++; }
for (; num>0; num--) {
set_level(BLINK_BRIGHTNESS);
if (! nice_delay_ms(ontime)) { return 0; }
set_level(0);
//if (current_state != old_state) return 0;
if (! nice_delay_ms(400)) return 0;
//if (current_state != old_state) return 0;
}
return nice_delay_ms(600);
}
#endif
#ifdef USE_BLINK_NUM
uint8_t blink_num(uint8_t num) {
//StatePtr old_state = current_state;
#if 0
uint8_t hundreds = num / 100;
num = num % 100;
uint8_t tens = num / 10;
num = num % 10;
#else // 8 bytes smaller
uint8_t hundreds = 0;
uint8_t tens = 0;
for(; num >= 100; hundreds ++, num -= 100);
for(; num >= 10; tens ++, num -= 10);
#endif
#if 0
// wait a moment in the dark before starting
set_level(0);
if (! nice_delay_ms(200)) return 0;
#endif
#if 0
if (hundreds) {
if (! blink_digit(hundreds)) return 0;
if (! blink_digit(tens)) return 0;
}
else if (tens) {
if (! blink_digit(tens)) return 0;
}
if (! blink_digit(num)) return 0;
return nice_delay_ms(1000);
#else // same size :(
if (hundreds) if (! blink_digit(hundreds)) return 0;
if (hundreds || tens) if (! blink_digit(tens)) return 0;
if (! blink_digit(num)) return 0;
return nice_delay_ms(1000);
#endif
/*
uint8_t volts, tenths;
volts = voltage / 10;
tenths = voltage % 10;
if (! blink(volts)) return;
if (! nice_delay_ms(200)) return;
if (! blink(tenths)) return;
nice_delay_ms(200);
*/
}
#endif
#endif
|