avr-equeue

annotate 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
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 }