Updated to new pin values.
[kokare.git] / kokare.c
CommitLineData
31415646
FT
1#include <avr/io.h>
2#include <avr/interrupt.h>
3#include <inttypes.h>
4
2378926d
FT
5#define SEGA 4
6#define SEGB 2
7#define SEGC 1
8#define SEGD 32
9#define SEGE 64
10#define SEGF 16
11#define SEGG 8
12#define SEGP 128
31415646
FT
13
14uint8_t font[16] = {
15 SEGA | SEGB | SEGC | SEGD | SEGE | SEGF,
16 SEGB | SEGC,
17 SEGA | SEGB | SEGD | SEGE | SEGG,
18 SEGA | SEGB | SEGC | SEGD | SEGG,
19 SEGB | SEGC | SEGF | SEGG,
20 SEGA | SEGC | SEGD | SEGF | SEGG,
21 SEGA | SEGC | SEGD | SEGE | SEGF | SEGG,
22 SEGA | SEGB | SEGC,
23 SEGA | SEGB | SEGC | SEGD | SEGE | SEGF | SEGG,
24 SEGA | SEGB | SEGC | SEGD | SEGF | SEGG,
25 SEGA | SEGB | SEGC | SEGE | SEGF | SEGG,
26 SEGC | SEGD | SEGE | SEGF | SEGG,
27 SEGA | SEGD | SEGE | SEGF,
28 SEGB | SEGC | SEGD | SEGE | SEGG,
29 SEGA | SEGD | SEGE | SEGF | SEGG,
30 SEGA | SEGE | SEGF | SEGG,
31};
32/* LED */
33uint8_t dsp[2] = {0, 0};
34char leda = 0;
35char ledc = 0;
36/* Timer */
37char of = 0;
38int oticks = 0;
59d1e985 39unsigned long mnow;
31415646
FT
40/* Pulse counter */
41char pstate = 0;
42char pval = 0;
43/* Switch */
44char sstate = 0;
45int stime = 0;
46/* Temp sensor */
47char tstate = 0;
48char tlock = 0;
49unsigned long tstart;
50unsigned long ttime;
51unsigned long ttimea = 10000;
c1346a55 52char tavgok = 0;
31415646 53/* Zero-cross detector*/
59d1e985
FT
54char zok = 0;
55unsigned long ztime;
31415646 56/* Triac */
59d1e985
FT
57char trstate = 0;
58char tron = 0;
495bea06 59unsigned long trtime;
59d1e985 60unsigned short trdelay = 0;
31415646
FT
61
62void init(void)
63{
64 /* Timer init */
65 TCCR1A = 0;
66 TCCR1B = 1;
67 TIMSK1 = 1;
68
69 /*
70 * B0..2 = Pulse sensor
71 * B3..5 = ISP
72 * B6..7 = CLK
73 */
c1346a55 74 DDRB = 0x38;
31415646
FT
75 PORTB = 0x07;
76 PCMSK0 = 0x07;
77 PCICR = 0x01;
78 /*
79 * C0..5 = LEDA0..5
80 * C6 = /RESET
81 * C7 = NC
82 */
83 DDRC = 0x3f;
84 PORTC = 0x00;
85 /*
86 * D0 = Triac
87 * D1 = NTC FET
88 * D2 = ZCD (INT0)
89 * D3 = NTC Op-amp (INT1)
90 * D4..5 = LEDA6..7
91 * D6..7 = LEDC0..1
92 */
93 DDRD = 0xf3;
94 PORTD = 0x00;
95 EICRA = 0x0d;
96 EIMSK = 0x03;
97}
98
99unsigned char bindisp(unsigned char num)
100{
101 unsigned char ret;
102
103 ret = 0;
104 if(num & 1)
105 ret |= SEGA;
106 if(num & 2)
107 ret |= SEGB;
108 if(num & 4)
109 ret |= SEGC;
110 if(num & 8)
111 ret |= SEGD;
112 if(num & 16)
113 ret |= SEGE;
114 if(num & 32)
115 ret |= SEGF;
116 if(num & 64)
117 ret |= SEGG;
118 if(num & 128)
119 ret |= SEGP;
120 return(ret);
121}
122
123void display(char num)
124{
125 dsp[0] = font[(num / 10) % 10];
126 dsp[1] = font[num % 10];
127}
128
129void disphex(unsigned char num)
130{
131 dsp[0] = font[(num & 0xf0) >> 4];
132 dsp[1] = font[num & 0x0f];
133}
134
135unsigned long getticks(void)
136{
137 return(TCNT1 + (((unsigned long)oticks) << 16));
138}
139
140void ledcycle(void)
141{
142 static uint16_t last = 0;
143 uint8_t c, d, v;
144
145 if(TCNT1 - last > 500) {
146 last = TCNT1;
147 if(++leda >= 8) {
148 leda = 0;
149 if(++ledc >= 2)
150 ledc = 0;
151 }
152 if(dsp[ledc] & (1 << leda)) {
153 if(leda < 6) {
154 c = 1 << leda;
155 d = 0;
156 } else {
157 c = 0;
158 d = 0x10 << (leda - 6);
159 }
160 d |= ledc?0x40:0x80;
161 } else {
162 c = d = 0;
163 }
164 PORTC = c;
165 PORTD = (PORTD & 0x0f) | d;
166 }
167}
168
169void tempcycle(void)
170{
31415646
FT
171 if(tstate == 0) {
172 if((PIND & 8) && (tlock == 0)) {
173 PORTD |= 2;
59d1e985 174 tstart = mnow;
31415646
FT
175 tstate = 1;
176 }
177 } else if(tstate == 1) {
59d1e985 178 if(mnow - tstart > 1000) {
31415646
FT
179 PORTD &= ~2;
180 tstate = 0;
59d1e985 181 tstart = mnow;
31415646
FT
182 }
183 }
184}
185
186void calcavg(void)
187{
188 if(tlock == 1) {
189 tlock = 2;
190 ttimea = ((ttimea * 15) + ttime) >> 4;
191 tlock = 0;
c1346a55 192 tavgok = 1;
31415646
FT
193 }
194}
195
59d1e985
FT
196void triaccycle(void)
197{
198 if(trstate == 0) {
199 if(tron && zok && (mnow > ztime + trdelay)) {
200 PORTD |= 1;
201 zok = 0;
202 trstate = 1;
495bea06 203 trtime = mnow;
59d1e985
FT
204 }
205 } else if(trstate == 1) {
495bea06
FT
206 if(mnow > trtime + 500) {
207 PORTD &= ~1;
208 trstate = 0;
209 }
59d1e985
FT
210 }
211}
212
31415646
FT
213int main(void)
214{
c1346a55
FT
215 int state, cur;
216 unsigned long utime;
31415646 217
c1346a55
FT
218 state = 0;
219 cur = 99;
31415646
FT
220 init();
221 sei();
222 display(0);
59d1e985 223
31415646 224 while(1) {
59d1e985 225 mnow = getticks();
31415646
FT
226 ledcycle();
227 tempcycle();
228 calcavg();
59d1e985 229 triaccycle();
31415646 230
63e3aac7 231#if 1
c1346a55
FT
232 /*
233 * User interface
234 */
235 if(state == 0) {
236 /* Display temperature */
237 if(tavgok) {
238 tavgok = 0;
239 if(ttimea < 20000) {
240 display((ttimea / 100) % 100);
241 dsp[0] |= SEGP;
242 if(ttimea >= 10000)
243 dsp[1] |= SEGP;
244 } else {
245 display(ttimea / 1000);
246 }
247 }
248 if(pval != 0) {
249 state = 1;
250 utime = mnow;
251 }
252 } else if(state == 1) {
253 /* Triac control */
254 if(pval != 0) {
255 cur += pval;
256 pval = 0;
257 if(cur < 0)
258 cur = 0;
259 if(cur > 99)
260 cur = 99;
261 display(cur);
262 trdelay = 10000 - ((unsigned short)cur * 100);
263 utime = mnow;
264 }
265 if(mnow - utime > 1000000) {
266 state = 0;
267 }
268 }
269 if(sstate == 2) {
270 tron = !tron;
271 sstate = 0;
272 }
273#endif
31415646
FT
274 /*
275 dsp[0] = bindisp((ttimea & 0xff00) >> 8);
276 dsp[1] = bindisp(ttimea & 0x00ff);
277 */
278 /*
279 disphex((ttimea & 0xff000) >> 12);
280 */
495bea06 281#if 0
59d1e985
FT
282 /*
283 Temp display
284 */
31415646
FT
285 if(ttimea < 20000) {
286 display((ttimea / 100) % 100);
287 dsp[0] |= SEGP;
288 if(ttimea >= 10000)
289 dsp[1] |= SEGP;
290 } else {
291 display(ttimea / 1000);
292 }
59d1e985 293#endif
2378926d 294#if 0
72ef9ac1
FT
295 /*
296 * ZVD debug
297 */
298 if(zok) {
299 if(++cur > 99)
300 cur = 0;
301 display(cur);
302 zok = 0;
303 }
63e3aac7 304#endif
c1346a55 305#if 0
495bea06
FT
306 /*
307 Phony Triac control
308 */
309 if(pval != 0) {
310 cur += pval;
311 if(cur < 0)
312 cur = 0;
313 if(cur > 99)
314 cur = 99;
315 display(cur);
316 trdelay = 10000 - ((unsigned short)cur * 100);
317 pval = 0;
318 }
319 if(sstate == 2) {
320 tron = !tron;
321 sstate = 0;
322 }
323#endif
59d1e985 324#if 0
31415646 325 /*
59d1e985
FT
326 Pulse counter display
327 */
31415646
FT
328 cur += pval;
329 pval = 0;
330 if(sstate == 2) {
331 cur = stime;
332 sstate = 0;
333 }
334 if(cur > 99)
335 cur = 99;
336 if(cur < -99)
337 cur = -99;
338 if(cur < 0) {
339 display(-cur);
340 dsp[0] |= SEGP;
341 } else {
342 display(cur);
343 }
59d1e985 344#endif
31415646
FT
345 }
346}
347
348ISR(SIG_INTERRUPT0)
349{
59d1e985
FT
350 ztime = getticks();
351 zok = 1;
31415646
FT
352}
353
354ISR(SIG_INTERRUPT1)
355{
356 unsigned long now;
357
358 now = getticks();
359 if(tstate == 0) {
360 tstate = 1;
361 if(tlock != 2)
362 ttime = now - tstart;
363 tstart = now;
364 PORTD |= 2;
365 tlock = 1;
366 }
367}
368
369ISR(SIG_OVERFLOW1)
370{
371 of = 1;
372 oticks++;
373}
374
375ISR(SIG_PIN_CHANGE0)
376{
2378926d 377 if((sstate == 0) & ((PINB & 4) == 0)) {
31415646
FT
378 stime = oticks;
379 sstate = 1;
380 }
2378926d 381 if((sstate == 1) & ((PINB & 4) == 1)) {
31415646
FT
382 stime = oticks - stime;
383 sstate = 2;
384 }
385 if(pstate == 0) {
386 if((PINB & 2) == 0) {
387 pstate = 1;
2378926d 388 } else if((PINB & 1) == 0) {
31415646
FT
389 pstate = 2;
390 }
391 } else if(pstate == 1) {
2378926d 392 if((PINB & 1) == 0) {
31415646
FT
393 pval++;
394 pstate = 3;
395 } else {
396 pstate = 0;
397 }
398 } else if(pstate == 2) {
399 if((PINB & 2) == 0) {
400 pval--;
401 pstate = 3;
402 } else {
403 pstate = 0;
404 }
405 } else {
2378926d 406 if((PINB & 2) && (PINB & 1))
31415646
FT
407 pstate = 0;
408 }
409}