avr-equeue

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