avr-equeue

view equeue.c @ 0:b1d590a201df

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 09 Jul 2014 08:58:46 +0300
parents
children 9cb1db5d0e7c
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 */
9 #ifdef XTAL
10 #define F_CLK XTAL
11 #define F_CPU XTAL
12 #else
13 #define F_CLK 1000000
14 #define F_CPU 1000000
15 #endif
17 #include <stdio.h>
18 #include <avr/io.h>
19 #include <avr/interrupt.h>
20 #include <util/delay.h>
21 #include "serial.h"
23 #define SHOW_TICKET_DELAY 256
25 #define BN_NEXT 2
26 #define BN_TICKET 3
28 #define LED_MODE_CUR 6
29 #define LED_MODE_TICKET 7
31 void show(int num, int digit);
32 void disp_off(void);
33 void runcmd(const char *cmd);
35 int show_ticket_cnt;
36 int cur_customer;
37 int last_ticket;
39 #define MAX_INPUT_SIZE 256
40 char input[MAX_INPUT_SIZE];
41 int inp_cidx;
43 int cmd_echo = 1;
45 int main(void)
46 {
47 int i = 0;
49 DDRB = 0xf3; /* B: output except [2,3] */
50 DDRC = 0xff; /* C: output */
51 DDRD = 0xff; /* D: output */
53 PORTB = 0xff; /* activate pullups and whatever */
54 PORTC = 0xff;
55 PORTD = 1 << LED_MODE_CUR;
57 PCICR = (1 << PCIE0); /* enable pin change interrupt 2 */
58 PCMSK0 = (1 << PCINT2) | (1 << PCINT3);
60 init_serial();
62 sei();
64 for(;;) {
65 int digit = i & 1;
67 /* first grab any input from the serial port */
68 while(have_input()) {
69 int c = getchar();
70 if(cmd_echo) {
71 putchar(c); /* echo back */
72 }
73 if(c == '\r' || c == '\n') {
74 input[inp_cidx] = 0;
75 runcmd(input);
76 inp_cidx = 0;
77 } else {
78 input[inp_cidx++] = c;
79 }
80 }
82 disp_off();
83 _delay_ms(1);
84 PORTB = (PORTB & 0xfe) | digit;
85 /*PORTD = (PORTD & 0xdf) | ((~digit) << 5);*/
86 _delay_ms(1);
88 if(show_ticket_cnt > 0) {
89 --show_ticket_cnt;
90 show(last_ticket, digit);
91 PORTD = (PORTD & 0x3f) | (1 << LED_MODE_TICKET);
92 } else {
93 show(cur_customer, digit);
94 PORTD = (PORTD & 0x3f) | (1 << LED_MODE_CUR);
95 }
97 ++i;
98 _delay_ms(1);
99 }
100 }
102 void issue_ticket(void)
103 {
104 last_ticket++;
105 show_ticket_cnt = SHOW_TICKET_DELAY;
106 printf("ticket: %d\n", last_ticket);
107 }
109 void next_customer(void)
110 {
111 if(cur_customer < last_ticket) {
112 cur_customer++;
113 show_ticket_cnt = 0;
114 printf("customer: %d\n", cur_customer);
115 }
116 }
118 ISR(PCINT0_vect)
119 {
120 unsigned char inp = PINB;
122 if((inp & (1 << BN_TICKET)) == 0) {
123 /* customer pressed the ticket button */
124 issue_ticket();
125 }
126 if((inp & (1 << BN_NEXT)) == 0) {
127 /* teller pressed the next customer button */
128 next_customer();
129 }
130 }
132 enum {
133 SEG_A = 1 << 0,
134 SEG_B = 1 << 1,
135 SEG_C = 1 << 2,
136 SEG_D = 1 << 3,
137 SEG_E = 1 << 4,
138 SEG_F = 1 << 5,
139 SEG_G = 1 << 6
140 };
142 static const unsigned char seg[] = {
143 SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, /* 0 */
144 SEG_B | SEG_C, /* 1 */
145 SEG_A | SEG_B | SEG_G | SEG_E | SEG_D, /* 2 */
146 SEG_A | SEG_B | SEG_G | SEG_C | SEG_D, /* 3 */
147 SEG_F | SEG_B | SEG_G | SEG_C, /* 4 */
148 SEG_A | SEG_F | SEG_G | SEG_C | SEG_D, /* 5 */
149 SEG_A | SEG_F | SEG_G | SEG_E | SEG_C | SEG_D, /* 6 */
150 SEG_A | SEG_B | SEG_C, /* 7 */
151 0xff, /* 8 */
152 SEG_A | SEG_B | SEG_F | SEG_G | SEG_C | SEG_D, /* 9 */
153 0
154 };
156 void show(int num, int digit)
157 {
158 int i, x = num;
159 unsigned int bits;
161 for(i=0; i<digit; i++) {
162 x /= 10;
163 }
164 x %= 10;
165 bits = seg[x];
167 PORTC = (PORTC & 0xc0) | (bits & 0x3f);
168 PORTB = (PORTB & 0xfd) | ((bits >> 5) & 2);
169 }
171 void disp_off(void)
172 {
173 PORTC = PORTC & 0xc0;
174 PORTB = PORTB & 0xfd;
175 }
177 #define VERSTR \
178 "Queue system v0.1 by John Tsiombikas <nuclear@member.fsf.org>"
180 void runcmd(const char *cmd)
181 {
182 switch(cmd[0]) {
183 case 'e':
184 cmd_echo = !cmd_echo;
185 printf("OK,turning echo %s\n", cmd_echo ? "on" : "off");
186 break;
188 case 'v':
189 printf("OK,%s\n", VERSTR);
190 break;
192 case 'r':
193 printf("OK,reseting queues\n");
194 cur_customer = 0;
195 last_ticket = 0;
196 show_ticket_cnt = 0;
197 break;
199 case 't':
200 printf("OK,ticket: %d\n", last_ticket);
201 break;
203 case 'c':
204 printf("OK,customer: %d\n", cur_customer);
205 break;
207 case 'q':
208 printf("OK,issuing queue ticket\n");
209 issue_ticket();
210 break;
212 case 'n':
213 printf("OK,next customer\n");
214 next_customer();
215 break;
217 case 'h':
218 printf("OK,commands: (e)cho, (v)ersion, (t)icket, (c)ustomer, "
219 "(n)ext, (q)ueue, (r)eset, (h)elp.\n");
220 break;
222 default:
223 printf("ERR,unknown command: %s\n", cmd);
224 }
225 }