Initial commit.
[kokare.git] / kokare.c
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3 #include <inttypes.h>
4
5 #define SEGA 128
6 #define SEGB 64
7 #define SEGC 4
8 #define SEGD 16
9 #define SEGE 32
10 #define SEGF 2
11 #define SEGG 1
12 #define SEGP 8
13
14 uint8_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 */
33 uint8_t dsp[2] = {0, 0};
34 char leda = 0;
35 char ledc = 0;
36 /* Timer */
37 char of = 0;
38 int oticks = 0;
39 /* Pulse counter */
40 char pstate = 0;
41 char pval = 0;
42 /* Switch */
43 char sstate = 0;
44 int stime = 0;
45 /* Temp sensor */
46 char tstate = 0;
47 char tlock = 0;
48 unsigned long tstart;
49 unsigned long ttime;
50 unsigned long ttimea = 10000;
51 /* Zero-cross detector*/
52 /* Triac */
53
54 void init(void)
55 {
56     /* Timer init */
57     TCCR1A = 0;
58     TCCR1B = 1;
59     TIMSK1 = 1;
60     
61     /*
62      * B0..2 = Pulse sensor
63      * B3..5 = ISP
64      * B6..7 = CLK
65      */
66     DDRB = 0x00;
67     PORTB = 0x07;
68     PCMSK0 = 0x07;
69     PCICR = 0x01;
70     /*
71      * C0..5 = LEDA0..5
72      * C6 = /RESET
73      * C7 = NC
74      */
75     DDRC = 0x3f;
76     PORTC = 0x00;
77     /*
78      * D0 = Triac
79      * D1 = NTC FET
80      * D2 = ZCD (INT0)
81      * D3 = NTC Op-amp (INT1)
82      * D4..5 = LEDA6..7
83      * D6..7 = LEDC0..1
84      */
85     DDRD = 0xf3;
86     PORTD = 0x00;
87     EICRA = 0x0d;
88     EIMSK = 0x03;
89 }
90
91 unsigned char bindisp(unsigned char num)
92 {
93     unsigned char ret;
94     
95     ret = 0;
96     if(num & 1)
97         ret |= SEGA;
98     if(num & 2)
99         ret |= SEGB;
100     if(num & 4)
101         ret |= SEGC;
102     if(num & 8)
103         ret |= SEGD;
104     if(num & 16)
105         ret |= SEGE;
106     if(num & 32)
107         ret |= SEGF;
108     if(num & 64)
109         ret |= SEGG;
110     if(num & 128)
111         ret |= SEGP;
112     return(ret);
113 }
114
115 void display(char num)
116 {
117     dsp[0] = font[(num / 10) % 10];
118     dsp[1] = font[num % 10];
119 }
120
121 void disphex(unsigned char num)
122 {
123     dsp[0] = font[(num & 0xf0) >> 4];
124     dsp[1] = font[num & 0x0f];
125 }
126
127 unsigned long getticks(void)
128 {
129     return(TCNT1 + (((unsigned long)oticks) << 16));
130 }
131
132 void ledcycle(void)
133 {
134     static uint16_t last = 0;
135     uint8_t c, d, v;
136     
137     if(TCNT1 - last > 500) {
138         last = TCNT1;
139         if(++leda >= 8) {
140             leda = 0;
141             if(++ledc >= 2)
142                 ledc = 0;
143         }
144         if(dsp[ledc] & (1 << leda)) {
145             if(leda < 6) {
146                 c = 1 << leda;
147                 d = 0;
148             } else {
149                 c = 0;
150                 d = 0x10 << (leda - 6);
151             }
152             d |= ledc?0x40:0x80;
153         } else {
154             c = d = 0;
155         }
156         PORTC = c;
157         PORTD = (PORTD & 0x0f) | d;
158     }
159 }
160
161 void tempcycle(void)
162 {
163     unsigned long now;
164     
165     now = getticks();
166     if(tstate == 0) {
167         if((PIND & 8) && (tlock == 0)) {
168             PORTD |= 2;
169             tstart = now;
170             tstate = 1;
171         }
172     } else if(tstate == 1) {
173         if(now - tstart > 1000) {
174             PORTD &= ~2;
175             tstate = 0;
176             tstart = now;
177         }
178     }
179 }
180
181 void calcavg(void)
182 {
183     if(tlock == 1) {
184         tlock = 2;
185         ttimea = ((ttimea * 15) + ttime) >> 4;
186         tlock = 0;
187     }
188 }
189
190 int main(void)
191 {
192     int cur;
193     
194     cur = 0;
195     init();
196     sei();
197     display(0);
198     while(1) {
199         ledcycle();
200         tempcycle();
201         calcavg();
202
203         /*
204           dsp[0] = bindisp((ttimea & 0xff00) >> 8);
205           dsp[1] = bindisp(ttimea & 0x00ff);
206         */
207         /*
208           disphex((ttimea & 0xff000) >> 12);
209         */
210         if(ttimea < 20000) {
211             display((ttimea / 100) % 100);
212             dsp[0] |= SEGP;
213             if(ttimea >= 10000)
214                 dsp[1] |= SEGP;
215         } else {
216             display(ttimea / 1000);
217         }
218
219         /*
220         cur += pval;
221         pval = 0;
222         if(sstate == 2) {
223             cur = stime;
224             sstate = 0;
225         }
226         if(cur > 99)
227             cur = 99;
228         if(cur < -99)
229             cur = -99;
230         if(cur < 0) {
231             display(-cur);
232             dsp[0] |= SEGP;
233         } else {
234             display(cur);
235         }
236         */
237     }
238 }
239
240 ISR(SIG_INTERRUPT0)
241 {
242 }
243
244 ISR(SIG_INTERRUPT1)
245 {
246     unsigned long now;
247     
248     now = getticks();
249     if(tstate == 0) {
250         tstate = 1;
251         if(tlock != 2)
252             ttime = now - tstart;
253         tstart = now;
254         PORTD |= 2;
255         tlock = 1;
256     }
257 }
258
259 ISR(SIG_OVERFLOW1)
260 {
261     of = 1;
262     oticks++;
263 }
264
265 ISR(SIG_PIN_CHANGE0)
266 {
267     if((sstate == 0) & ((PINB & 1) == 0)) {
268         stime = oticks;
269         sstate = 1;
270     }
271     if((sstate == 1) & ((PINB & 1) == 1)) {
272         stime = oticks - stime;
273         sstate = 2;
274     }
275     if(pstate == 0) {
276         if((PINB & 2) == 0) {
277             pstate = 1;
278         } else if((PINB & 4) == 0) {
279             pstate = 2;
280         }
281     } else if(pstate == 1) {
282         if((PINB & 4) == 0) {
283             pval++;
284             pstate = 3;
285         } else {
286             pstate = 0;
287         }
288     } else if(pstate == 2) {
289         if((PINB & 2) == 0) {
290             pval--;
291             pstate = 3;
292         } else {
293             pstate = 0;
294         }
295     } else {
296         if((PINB & 2) && (PINB & 4))
297             pstate = 0;
298     }
299 }