avr-equeue
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/equeue.c Wed Jul 09 08:58:46 2014 +0300 1.3 @@ -0,0 +1,225 @@ 1.4 +/* pin assignments 1.5 + * C[0,5] 7seg [a,f] 1.6 + * B1 7seg g 1.7 + * B0 select display (0: units, 1: tens) 1.8 + * B[2,3] buttons with internal pullups 1.9 + * D[6,7] mode leds 1.10 + */ 1.11 + 1.12 +#ifdef XTAL 1.13 +#define F_CLK XTAL 1.14 +#define F_CPU XTAL 1.15 +#else 1.16 +#define F_CLK 1000000 1.17 +#define F_CPU 1000000 1.18 +#endif 1.19 + 1.20 +#include <stdio.h> 1.21 +#include <avr/io.h> 1.22 +#include <avr/interrupt.h> 1.23 +#include <util/delay.h> 1.24 +#include "serial.h" 1.25 + 1.26 +#define SHOW_TICKET_DELAY 256 1.27 + 1.28 +#define BN_NEXT 2 1.29 +#define BN_TICKET 3 1.30 + 1.31 +#define LED_MODE_CUR 6 1.32 +#define LED_MODE_TICKET 7 1.33 + 1.34 +void show(int num, int digit); 1.35 +void disp_off(void); 1.36 +void runcmd(const char *cmd); 1.37 + 1.38 +int show_ticket_cnt; 1.39 +int cur_customer; 1.40 +int last_ticket; 1.41 + 1.42 +#define MAX_INPUT_SIZE 256 1.43 +char input[MAX_INPUT_SIZE]; 1.44 +int inp_cidx; 1.45 + 1.46 +int cmd_echo = 1; 1.47 + 1.48 +int main(void) 1.49 +{ 1.50 + int i = 0; 1.51 + 1.52 + DDRB = 0xf3; /* B: output except [2,3] */ 1.53 + DDRC = 0xff; /* C: output */ 1.54 + DDRD = 0xff; /* D: output */ 1.55 + 1.56 + PORTB = 0xff; /* activate pullups and whatever */ 1.57 + PORTC = 0xff; 1.58 + PORTD = 1 << LED_MODE_CUR; 1.59 + 1.60 + PCICR = (1 << PCIE0); /* enable pin change interrupt 2 */ 1.61 + PCMSK0 = (1 << PCINT2) | (1 << PCINT3); 1.62 + 1.63 + init_serial(); 1.64 + 1.65 + sei(); 1.66 + 1.67 + for(;;) { 1.68 + int digit = i & 1; 1.69 + 1.70 + /* first grab any input from the serial port */ 1.71 + while(have_input()) { 1.72 + int c = getchar(); 1.73 + if(cmd_echo) { 1.74 + putchar(c); /* echo back */ 1.75 + } 1.76 + if(c == '\r' || c == '\n') { 1.77 + input[inp_cidx] = 0; 1.78 + runcmd(input); 1.79 + inp_cidx = 0; 1.80 + } else { 1.81 + input[inp_cidx++] = c; 1.82 + } 1.83 + } 1.84 + 1.85 + disp_off(); 1.86 + _delay_ms(1); 1.87 + PORTB = (PORTB & 0xfe) | digit; 1.88 + /*PORTD = (PORTD & 0xdf) | ((~digit) << 5);*/ 1.89 + _delay_ms(1); 1.90 + 1.91 + if(show_ticket_cnt > 0) { 1.92 + --show_ticket_cnt; 1.93 + show(last_ticket, digit); 1.94 + PORTD = (PORTD & 0x3f) | (1 << LED_MODE_TICKET); 1.95 + } else { 1.96 + show(cur_customer, digit); 1.97 + PORTD = (PORTD & 0x3f) | (1 << LED_MODE_CUR); 1.98 + } 1.99 + 1.100 + ++i; 1.101 + _delay_ms(1); 1.102 + } 1.103 +} 1.104 + 1.105 +void issue_ticket(void) 1.106 +{ 1.107 + last_ticket++; 1.108 + show_ticket_cnt = SHOW_TICKET_DELAY; 1.109 + printf("ticket: %d\n", last_ticket); 1.110 +} 1.111 + 1.112 +void next_customer(void) 1.113 +{ 1.114 + if(cur_customer < last_ticket) { 1.115 + cur_customer++; 1.116 + show_ticket_cnt = 0; 1.117 + printf("customer: %d\n", cur_customer); 1.118 + } 1.119 +} 1.120 + 1.121 +ISR(PCINT0_vect) 1.122 +{ 1.123 + unsigned char inp = PINB; 1.124 + 1.125 + if((inp & (1 << BN_TICKET)) == 0) { 1.126 + /* customer pressed the ticket button */ 1.127 + issue_ticket(); 1.128 + } 1.129 + if((inp & (1 << BN_NEXT)) == 0) { 1.130 + /* teller pressed the next customer button */ 1.131 + next_customer(); 1.132 + } 1.133 +} 1.134 + 1.135 +enum { 1.136 + SEG_A = 1 << 0, 1.137 + SEG_B = 1 << 1, 1.138 + SEG_C = 1 << 2, 1.139 + SEG_D = 1 << 3, 1.140 + SEG_E = 1 << 4, 1.141 + SEG_F = 1 << 5, 1.142 + SEG_G = 1 << 6 1.143 +}; 1.144 + 1.145 +static const unsigned char seg[] = { 1.146 + SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, /* 0 */ 1.147 + SEG_B | SEG_C, /* 1 */ 1.148 + SEG_A | SEG_B | SEG_G | SEG_E | SEG_D, /* 2 */ 1.149 + SEG_A | SEG_B | SEG_G | SEG_C | SEG_D, /* 3 */ 1.150 + SEG_F | SEG_B | SEG_G | SEG_C, /* 4 */ 1.151 + SEG_A | SEG_F | SEG_G | SEG_C | SEG_D, /* 5 */ 1.152 + SEG_A | SEG_F | SEG_G | SEG_E | SEG_C | SEG_D, /* 6 */ 1.153 + SEG_A | SEG_B | SEG_C, /* 7 */ 1.154 + 0xff, /* 8 */ 1.155 + SEG_A | SEG_B | SEG_F | SEG_G | SEG_C | SEG_D, /* 9 */ 1.156 + 0 1.157 +}; 1.158 + 1.159 +void show(int num, int digit) 1.160 +{ 1.161 + int i, x = num; 1.162 + unsigned int bits; 1.163 + 1.164 + for(i=0; i<digit; i++) { 1.165 + x /= 10; 1.166 + } 1.167 + x %= 10; 1.168 + bits = seg[x]; 1.169 + 1.170 + PORTC = (PORTC & 0xc0) | (bits & 0x3f); 1.171 + PORTB = (PORTB & 0xfd) | ((bits >> 5) & 2); 1.172 +} 1.173 + 1.174 +void disp_off(void) 1.175 +{ 1.176 + PORTC = PORTC & 0xc0; 1.177 + PORTB = PORTB & 0xfd; 1.178 +} 1.179 + 1.180 +#define VERSTR \ 1.181 + "Queue system v0.1 by John Tsiombikas <nuclear@member.fsf.org>" 1.182 + 1.183 +void runcmd(const char *cmd) 1.184 +{ 1.185 + switch(cmd[0]) { 1.186 + case 'e': 1.187 + cmd_echo = !cmd_echo; 1.188 + printf("OK,turning echo %s\n", cmd_echo ? "on" : "off"); 1.189 + break; 1.190 + 1.191 + case 'v': 1.192 + printf("OK,%s\n", VERSTR); 1.193 + break; 1.194 + 1.195 + case 'r': 1.196 + printf("OK,reseting queues\n"); 1.197 + cur_customer = 0; 1.198 + last_ticket = 0; 1.199 + show_ticket_cnt = 0; 1.200 + break; 1.201 + 1.202 + case 't': 1.203 + printf("OK,ticket: %d\n", last_ticket); 1.204 + break; 1.205 + 1.206 + case 'c': 1.207 + printf("OK,customer: %d\n", cur_customer); 1.208 + break; 1.209 + 1.210 + case 'q': 1.211 + printf("OK,issuing queue ticket\n"); 1.212 + issue_ticket(); 1.213 + break; 1.214 + 1.215 + case 'n': 1.216 + printf("OK,next customer\n"); 1.217 + next_customer(); 1.218 + break; 1.219 + 1.220 + case 'h': 1.221 + printf("OK,commands: (e)cho, (v)ersion, (t)icket, (c)ustomer, " 1.222 + "(n)ext, (q)ueue, (r)eset, (h)elp.\n"); 1.223 + break; 1.224 + 1.225 + default: 1.226 + printf("ERR,unknown command: %s\n", cmd); 1.227 + } 1.228 +}