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