-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheggs.c
318 lines (266 loc) · 6.03 KB
/
eggs.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
#include "eggs.h"
#define LED_0 BIT0
#define LED_1 BIT6
#define LED_OUT P1OUT
#define LED_DIR P1DIR
#define RELAY BIT4
#define RELAY_OUT P1OUT
#define RELAY_DIR P1DIR
#ifdef VLOCLK12Khz
/*
* 12 Khz / 3 Khz to get even numbers
*
* */
#define TONE 12000/3/1000
#define DUTY 12000/3/2/1000
#endif
#ifdef VLOCLK32Khz
/*
* 32 Khz / 4 Khz best for buzzer
*
* */
#define TONE 32768/4/1000
#define DUTY 32768/4/2/1000
#endif
#ifndef VLOCLK12Khz
#ifndef VLOCLK32Khz
// 8 Mhz / 4 Khz
#define TONE (int)(8000000L/4L/1000L)
#define DUTY (int)(8000000L/4L/2L/1000L)
#endif
#endif
char buf[10];
/* strlen: return length of s */
int strlen(char s[])
{
int i = 0;
while (s[i] != '\0')
++i;
return i;
}
/* reverse: reverse string s in place */
void reverse(char s[])
{
int i, j;
char c;
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
/* itoa: convert n to characters in s */
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
i = 0;
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
volatile unsigned int events; // 16 events
volatile unsigned long event_counter;
#define EVENT_CHECKTEMP 0x0001
#define EVENT_RECORDTEMP 0x0002
#define EVENT_BLINKLED 0x0004
#define EVENT_EXT_CHECKTEMP 0x0008
#define EVENT_EXT_RECORDTEMP 0x0010
void inline time_event()
{
/**
* Let us kick off the event counter before we detect the events,
* This allows us to avoid running events in a brownout conidition.
* */
event_counter ++;
if ((event_counter % 200L) == 0) // Every 2 seconds
{
events |= EVENT_CHECKTEMP | EVENT_EXT_CHECKTEMP | EVENT_BLINKLED;
if ((event_counter % 90000L) == 0) // Every 15 minutes (15 * 60 * 100 = 900 * 100 = 90,000
{
events |= EVENT_RECORDTEMP | EVENT_EXT_RECORDTEMP;
event_counter = 0;// Reset Event counter
}
}
}
/**************************
*
* Memory for history is stored at 0xc000 + 12288 bytes
* Each block is divided into 512 byte segments
* 0xe000 - 0xe1ff
* 0xe200 - 0xe3ff
* 0xe400 - 0xe5ff
* 0xe600 - 0xe7ff
* ...
*
* Temp will be store as an int with a value less then 0xffff giving us
* 1024 data points, or about 10 days of data points. (Data point every 15 minutes)
*
* Max ints is 6144
* Int cannot == 0xffff, so we make it 0xfffe
* Ints per segment = 256
* */
#define INFOE ((int *)(0xc000))
#define INTS_PER_SEGMENT 256
#define INTS_TOTAL 6144
volatile int next_memory;
void save_temp(int temp)
{
int after_next_memory = 0;
if (temp == 0xffff)
{
temp = 0xfffe;
}
flash_write_int(INFOE + next_memory, temp);
next_memory ++;
if (next_memory >= INTS_TOTAL)
next_memory = 0;
after_next_memory = next_memory + 1;
if (after_next_memory >= INTS_TOTAL)
after_next_memory = 0;
if (*(INFOE + after_next_memory) != 0xffff)
{
flash_erase(INFOE + after_next_memory);
}
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
// Setup the Clocks
//Set MCLK to 1Mhz
BCSCTL1 = CALBC1_8MHZ; // Set range
DCOCTL = CALDCO_8MHZ; // Set DCO step and modulation
#ifdef VLOCLK12Khz
//Set ACLK to Internal Very Low Power Low Frequency Oscillator ~12Khz
BCSCTL3 |= LFXT1S_2;
#endif
#ifdef VLOCLK32Khz
BCSCTL3 = XCAP_1;
#endif
// Setup the LEDS
LED_DIR |= (LED_0 | LED_1); // Set P1.0 and P1.6
LED_OUT &= ~(LED_0 | LED_1); // Set the LEDs off
// Setup Relay
RELAY_DIR |= RELAY; // Set P1.0 and P1.6
RELAY_OUT &= ~(RELAY); // Set the LEDs off
TA0CCTL0 = CCIE;
// Setup Events
events = 0;
event_counter = 0;
// Setup memory
{
int i;
for (i = 0; i < INTS_TOTAL; i ++)
{
if (*(INFOE + i) == 0xffff)
break;
}
if (i > INTS_TOTAL)
{
i = 0;
flash_erase(INFOE);
}
next_memory = i;
}
// Setup Timer
setup_time();
__enable_interrupt();
// Setup Buzzer on P2.0
P2DIR |= BIT1;
P2SEL |= BIT1;
TA1CCTL1 = OUTMOD_7;
TA1CCR0 = 0;
TA1CCR1 = DUTY;
#ifdef VLOCLK32Khz
TA1CTL = TASSEL_1 + MC_1;
#endif
#ifdef VLOCLK12Khz
TA1CTL = TASSEL_1 + MC_1;
#endif
#ifndef VLOCLK12Khz
#ifndef VLOCLK32Khz
TA1CTL = TASSEL_2 + MC_1;
#endif
#endif
while (1) // Event loop
{
if (events != 0)
{
if ((events & EVENT_RECORDTEMP) != 0)
{
int tmp = 0;
save_temp(tmp);// Store a 0 before ext temp
tmp = (int)(((long)get_temp_f(3)
+ (long)get_temp_f(3)
+ (long)get_temp_f(3)
+ (long)get_temp_f(3)) / 4L);
save_temp(tmp);
events &= ~EVENT_RECORDTEMP;
}
if ((events & EVENT_EXT_RECORDTEMP) != 0)
{
int tmp = 1;
save_temp(tmp);// Store a 1 before ext temp
// Be careful not to take to long to store the temperature, if we do so, we can accidently leave the relay on for too long.
tmp = (int)(long)get_ext_temp_f(0);
save_temp(tmp);
events &= ~EVENT_EXT_RECORDTEMP;
}
if ((events & EVENT_BLINKLED) != 0)
{
LED_OUT |= (LED_1);
sleep(5);
LED_OUT &= ~(LED_1);
events &= ~EVENT_BLINKLED;
}
if ((events & EVENT_CHECKTEMP) != 0)
{
/* int tmp = 0;
tmp = get_temp_f(3);
// If temp is above 101.50 or below 96.00 F
if (tmp >= 10250)// || tmp <= 9600) // include two decimal places
{
TA1CCR0 = TONE;
sleep(50);
TA1CCR0 = 0;
itoa(tmp, buf);
morse_send_string(buf);
}*/
events &= ~EVENT_CHECKTEMP;
}
if ((events & EVENT_EXT_CHECKTEMP) != 0)
{
int tmp = 0;
tmp = get_ext_temp_f(0);
// tmp returns 0 C on read error
if (tmp <= 9850 && tmp > 3300)
{
RELAY_OUT |= RELAY; // Turn on RELAY to increase temperature
}
if (tmp >= 9900)
{
RELAY_OUT &= ~(RELAY); // Turn off RELAY to decrease temperature
}
// If temp is above 101.50 or below 96.00 F
if (tmp >= 10250)// || tmp <= 9600) // include two decimal places
{
TA1CCR0 = TONE;
sleep(50);
TA1CCR0 = 0;
itoa(tmp, buf);
morse_send_string(buf);
}
events &= ~EVENT_EXT_CHECKTEMP;
}
}
if (events == 0)
{
sleep(100); // Sleep 1 second
}
}
}