rev |
line source |
nuclear@0
|
1 /* pin assignments
|
nuclear@0
|
2 * C[0,5] 7seg [a,f]
|
nuclear@0
|
3 * B1 7seg g
|
nuclear@0
|
4 * B0 select display (0: units, 1: tens)
|
nuclear@0
|
5 * B[2,3] buttons with internal pullups
|
nuclear@0
|
6 * D[6,7] mode leds
|
nuclear@1
|
7 * D4 emergency inverted B0 ...
|
nuclear@0
|
8 */
|
nuclear@0
|
9
|
nuclear@0
|
10 #ifdef XTAL
|
nuclear@0
|
11 #define F_CLK XTAL
|
nuclear@0
|
12 #define F_CPU XTAL
|
nuclear@0
|
13 #else
|
nuclear@0
|
14 #define F_CLK 1000000
|
nuclear@0
|
15 #define F_CPU 1000000
|
nuclear@0
|
16 #endif
|
nuclear@0
|
17
|
nuclear@0
|
18 #include <stdio.h>
|
nuclear@0
|
19 #include <avr/io.h>
|
nuclear@0
|
20 #include <avr/interrupt.h>
|
nuclear@0
|
21 #include <util/delay.h>
|
nuclear@0
|
22 #include "serial.h"
|
nuclear@0
|
23
|
nuclear@0
|
24 #define SHOW_TICKET_DELAY 256
|
nuclear@0
|
25
|
nuclear@0
|
26 #define BN_NEXT 2
|
nuclear@0
|
27 #define BN_TICKET 3
|
nuclear@0
|
28
|
nuclear@0
|
29 #define LED_MODE_CUR 6
|
nuclear@0
|
30 #define LED_MODE_TICKET 7
|
nuclear@0
|
31
|
nuclear@0
|
32 void show(int num, int digit);
|
nuclear@0
|
33 void disp_off(void);
|
nuclear@0
|
34 void runcmd(const char *cmd);
|
nuclear@0
|
35
|
nuclear@0
|
36 int show_ticket_cnt;
|
nuclear@0
|
37 int cur_customer;
|
nuclear@0
|
38 int last_ticket;
|
nuclear@0
|
39
|
nuclear@1
|
40 int com_issue_pending, com_cust_pending;
|
nuclear@1
|
41 int report_inputs;
|
nuclear@1
|
42
|
nuclear@0
|
43 #define MAX_INPUT_SIZE 256
|
nuclear@0
|
44 char input[MAX_INPUT_SIZE];
|
nuclear@0
|
45 int inp_cidx;
|
nuclear@0
|
46
|
nuclear@0
|
47 int cmd_echo = 1;
|
nuclear@0
|
48
|
nuclear@0
|
49 int main(void)
|
nuclear@0
|
50 {
|
nuclear@0
|
51 int i = 0;
|
nuclear@0
|
52
|
nuclear@0
|
53 DDRB = 0xf3; /* B: output except [2,3] */
|
nuclear@0
|
54 DDRC = 0xff; /* C: output */
|
nuclear@0
|
55 DDRD = 0xff; /* D: output */
|
nuclear@0
|
56
|
nuclear@0
|
57 PORTB = 0xff; /* activate pullups and whatever */
|
nuclear@0
|
58 PORTC = 0xff;
|
nuclear@0
|
59 PORTD = 1 << LED_MODE_CUR;
|
nuclear@0
|
60
|
nuclear@0
|
61 PCICR = (1 << PCIE0); /* enable pin change interrupt 2 */
|
nuclear@0
|
62 PCMSK0 = (1 << PCINT2) | (1 << PCINT3);
|
nuclear@0
|
63
|
nuclear@0
|
64 init_serial();
|
nuclear@0
|
65
|
nuclear@0
|
66 sei();
|
nuclear@0
|
67
|
nuclear@0
|
68 for(;;) {
|
nuclear@0
|
69 int digit = i & 1;
|
nuclear@0
|
70
|
nuclear@1
|
71 if(com_issue_pending) {
|
nuclear@1
|
72 printf("ticket: %d\n", last_ticket);
|
nuclear@1
|
73 com_issue_pending = 0;
|
nuclear@1
|
74 }
|
nuclear@1
|
75 if(com_cust_pending) {
|
nuclear@1
|
76 printf("customer: %d\n", cur_customer);
|
nuclear@1
|
77 com_cust_pending = 0;
|
nuclear@1
|
78 }
|
nuclear@1
|
79
|
nuclear@0
|
80 /* first grab any input from the serial port */
|
nuclear@0
|
81 while(have_input()) {
|
nuclear@0
|
82 int c = getchar();
|
nuclear@0
|
83 if(cmd_echo) {
|
nuclear@0
|
84 putchar(c); /* echo back */
|
nuclear@0
|
85 }
|
nuclear@0
|
86 if(c == '\r' || c == '\n') {
|
nuclear@0
|
87 input[inp_cidx] = 0;
|
nuclear@0
|
88 runcmd(input);
|
nuclear@0
|
89 inp_cidx = 0;
|
nuclear@0
|
90 } else {
|
nuclear@0
|
91 input[inp_cidx++] = c;
|
nuclear@0
|
92 }
|
nuclear@0
|
93 }
|
nuclear@0
|
94
|
nuclear@0
|
95 disp_off();
|
nuclear@0
|
96 PORTB = (PORTB & 0xfe) | digit;
|
nuclear@1
|
97 PORTD = (PORTD & 0xef) | (((~digit) & 1) << 4);
|
nuclear@0
|
98 /*PORTD = (PORTD & 0xdf) | ((~digit) << 5);*/
|
nuclear@0
|
99
|
nuclear@0
|
100 if(show_ticket_cnt > 0) {
|
nuclear@0
|
101 --show_ticket_cnt;
|
nuclear@0
|
102 show(last_ticket, digit);
|
nuclear@0
|
103 PORTD = (PORTD & 0x3f) | (1 << LED_MODE_TICKET);
|
nuclear@0
|
104 } else {
|
nuclear@0
|
105 show(cur_customer, digit);
|
nuclear@0
|
106 PORTD = (PORTD & 0x3f) | (1 << LED_MODE_CUR);
|
nuclear@0
|
107 }
|
nuclear@0
|
108
|
nuclear@0
|
109 ++i;
|
nuclear@1
|
110 _delay_ms(2);
|
nuclear@0
|
111 }
|
nuclear@0
|
112 }
|
nuclear@0
|
113
|
nuclear@0
|
114 void issue_ticket(void)
|
nuclear@0
|
115 {
|
nuclear@0
|
116 last_ticket++;
|
nuclear@0
|
117 show_ticket_cnt = SHOW_TICKET_DELAY;
|
nuclear@1
|
118 if(report_inputs) {
|
nuclear@1
|
119 com_issue_pending = 1;
|
nuclear@1
|
120 }
|
nuclear@1
|
121 _delay_ms(1);
|
nuclear@0
|
122 }
|
nuclear@0
|
123
|
nuclear@0
|
124 void next_customer(void)
|
nuclear@0
|
125 {
|
nuclear@0
|
126 if(cur_customer < last_ticket) {
|
nuclear@0
|
127 cur_customer++;
|
nuclear@0
|
128 show_ticket_cnt = 0;
|
nuclear@1
|
129 if(report_inputs) {
|
nuclear@1
|
130 com_cust_pending = 1;
|
nuclear@1
|
131 }
|
nuclear@0
|
132 }
|
nuclear@1
|
133 _delay_ms(1);
|
nuclear@0
|
134 }
|
nuclear@0
|
135
|
nuclear@0
|
136 ISR(PCINT0_vect)
|
nuclear@0
|
137 {
|
nuclear@0
|
138 unsigned char inp = PINB;
|
nuclear@0
|
139
|
nuclear@0
|
140 if((inp & (1 << BN_TICKET)) == 0) {
|
nuclear@0
|
141 /* customer pressed the ticket button */
|
nuclear@0
|
142 issue_ticket();
|
nuclear@0
|
143 }
|
nuclear@0
|
144 if((inp & (1 << BN_NEXT)) == 0) {
|
nuclear@0
|
145 /* teller pressed the next customer button */
|
nuclear@0
|
146 next_customer();
|
nuclear@0
|
147 }
|
nuclear@0
|
148 }
|
nuclear@0
|
149
|
nuclear@0
|
150 enum {
|
nuclear@0
|
151 SEG_A = 1 << 0,
|
nuclear@0
|
152 SEG_B = 1 << 1,
|
nuclear@0
|
153 SEG_C = 1 << 2,
|
nuclear@0
|
154 SEG_D = 1 << 3,
|
nuclear@0
|
155 SEG_E = 1 << 4,
|
nuclear@0
|
156 SEG_F = 1 << 5,
|
nuclear@0
|
157 SEG_G = 1 << 6
|
nuclear@0
|
158 };
|
nuclear@0
|
159
|
nuclear@0
|
160 static const unsigned char seg[] = {
|
nuclear@0
|
161 SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, /* 0 */
|
nuclear@0
|
162 SEG_B | SEG_C, /* 1 */
|
nuclear@0
|
163 SEG_A | SEG_B | SEG_G | SEG_E | SEG_D, /* 2 */
|
nuclear@0
|
164 SEG_A | SEG_B | SEG_G | SEG_C | SEG_D, /* 3 */
|
nuclear@0
|
165 SEG_F | SEG_B | SEG_G | SEG_C, /* 4 */
|
nuclear@0
|
166 SEG_A | SEG_F | SEG_G | SEG_C | SEG_D, /* 5 */
|
nuclear@0
|
167 SEG_A | SEG_F | SEG_G | SEG_E | SEG_C | SEG_D, /* 6 */
|
nuclear@0
|
168 SEG_A | SEG_B | SEG_C, /* 7 */
|
nuclear@0
|
169 0xff, /* 8 */
|
nuclear@0
|
170 SEG_A | SEG_B | SEG_F | SEG_G | SEG_C | SEG_D, /* 9 */
|
nuclear@0
|
171 0
|
nuclear@0
|
172 };
|
nuclear@0
|
173
|
nuclear@0
|
174 void show(int num, int digit)
|
nuclear@0
|
175 {
|
nuclear@0
|
176 int i, x = num;
|
nuclear@0
|
177 unsigned int bits;
|
nuclear@0
|
178
|
nuclear@0
|
179 for(i=0; i<digit; i++) {
|
nuclear@0
|
180 x /= 10;
|
nuclear@0
|
181 }
|
nuclear@0
|
182 x %= 10;
|
nuclear@0
|
183 bits = seg[x];
|
nuclear@0
|
184
|
nuclear@0
|
185 PORTC = (PORTC & 0xc0) | (bits & 0x3f);
|
nuclear@0
|
186 PORTB = (PORTB & 0xfd) | ((bits >> 5) & 2);
|
nuclear@0
|
187 }
|
nuclear@0
|
188
|
nuclear@0
|
189 void disp_off(void)
|
nuclear@0
|
190 {
|
nuclear@0
|
191 PORTC = PORTC & 0xc0;
|
nuclear@0
|
192 PORTB = PORTB & 0xfd;
|
nuclear@0
|
193 }
|
nuclear@0
|
194
|
nuclear@0
|
195 #define VERSTR \
|
nuclear@0
|
196 "Queue system v0.1 by John Tsiombikas <nuclear@member.fsf.org>"
|
nuclear@0
|
197
|
nuclear@0
|
198 void runcmd(const char *cmd)
|
nuclear@0
|
199 {
|
nuclear@0
|
200 switch(cmd[0]) {
|
nuclear@0
|
201 case 'e':
|
nuclear@0
|
202 cmd_echo = !cmd_echo;
|
nuclear@0
|
203 printf("OK,turning echo %s\n", cmd_echo ? "on" : "off");
|
nuclear@0
|
204 break;
|
nuclear@0
|
205
|
nuclear@1
|
206 case 'i':
|
nuclear@1
|
207 report_inputs = !report_inputs;
|
nuclear@1
|
208 printf("OK,turning input reports %s\n", report_inputs ? "on" : "off");
|
nuclear@1
|
209 break;
|
nuclear@1
|
210
|
nuclear@0
|
211 case 'v':
|
nuclear@0
|
212 printf("OK,%s\n", VERSTR);
|
nuclear@0
|
213 break;
|
nuclear@0
|
214
|
nuclear@0
|
215 case 'r':
|
nuclear@0
|
216 printf("OK,reseting queues\n");
|
nuclear@0
|
217 cur_customer = 0;
|
nuclear@0
|
218 last_ticket = 0;
|
nuclear@0
|
219 show_ticket_cnt = 0;
|
nuclear@0
|
220 break;
|
nuclear@0
|
221
|
nuclear@0
|
222 case 't':
|
nuclear@0
|
223 printf("OK,ticket: %d\n", last_ticket);
|
nuclear@0
|
224 break;
|
nuclear@0
|
225
|
nuclear@0
|
226 case 'c':
|
nuclear@0
|
227 printf("OK,customer: %d\n", cur_customer);
|
nuclear@0
|
228 break;
|
nuclear@0
|
229
|
nuclear@0
|
230 case 'q':
|
nuclear@0
|
231 printf("OK,issuing queue ticket\n");
|
nuclear@0
|
232 issue_ticket();
|
nuclear@0
|
233 break;
|
nuclear@0
|
234
|
nuclear@0
|
235 case 'n':
|
nuclear@0
|
236 printf("OK,next customer\n");
|
nuclear@0
|
237 next_customer();
|
nuclear@0
|
238 break;
|
nuclear@0
|
239
|
nuclear@0
|
240 case 'h':
|
nuclear@0
|
241 printf("OK,commands: (e)cho, (v)ersion, (t)icket, (c)ustomer, "
|
nuclear@1
|
242 "(n)ext, (q)ueue, (r)eset, (i)nput-reports, (h)elp.\n");
|
nuclear@0
|
243 break;
|
nuclear@0
|
244
|
nuclear@0
|
245 default:
|
nuclear@0
|
246 printf("ERR,unknown command: %s\n", cmd);
|
nuclear@0
|
247 }
|
nuclear@0
|
248 }
|