avr-equeue

view equeue.c @ 1:9cb1db5d0e7c

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