more changes
[uccvend-snackrom.git] / ROM2 / main.c
1 #include "display.h"
2 #include "keypad.h"
3 #include "chime.h"
4 #include "server.h"
5 #include "vend.h"
6
7 u16 uid;
8 u16 pin;
9 u8 selection;
10
11 u16 scroll_timer;
12
13 bool uid_enter() {
14         u8 uidpos;
15         /* the user has started to type in his/her UID. grab the last key and continue
16          * reading. Returns true if a UID was entered successfully.
17          * The UID will be entered as 5 digits. (shorter uids should be pre-padded
18          * with zeros)
19          */
20         uid = last_key%10; /* 10 => 0, it was _not_ reset (hopefuly :) */
21         set_msg("UID?      ", WRAP_NONE);
22         set_char((last_key%10)+'0', 5);
23
24         for (uidpos = 2; uidpos <= 5; uidpos++) {
25                 keypad_getkey();
26                 if (last_key == KEY_RESET) {
27                         uid = 0;
28                         return 0;
29                 }
30                 uid = (uid*10) + (last_key%10);
31                 set_char((last_key%10)+'0', 4+uidpos);
32         }
33         return (uid!=0);
34 }
35
36 bool pin_enter() {
37         u8 pinpos;
38         /* We ask for a pin, display a PIN: prompt. PINs must be a 4 digit number.
39          * Strictly, they must be 16-bit, but it's easier to use the guarantee that
40          * 4-digits numbers are < 65536
41          *
42          * Also display X's on screen as the pin is entered.
43          */
44         pin = 0;
45         set_msg("PIN?      ", WRAP_NONE);
46         for (pinpos = 1; pinpos <= 4; pinpos++) {
47                 keypad_getkey();
48                 if (last_key == KEY_RESET) {
49                         pin = 0;
50                         return 0;
51                 }
52                 pin = (pin*10) + (last_key%10);
53                 set_char('X', 4+pinpos);
54         }
55         return 1;
56 }
57
58 void make_request(u8 selection) {
59         set_msg("REQUESTING", WRAP_NONE); /* XXX: maybe this isn't needed? */
60         switch(server_request(uid, pin, selection)) {
61                 case REQUEST_OK:
62                         set_msg("THANK YOU!", WRAP_NONE);
63                         break;
64                 case REQUEST_NO_MONEY:
65                         set_msg("NO MONEY!", WRAP_NONE);
66                         break;
67                 case REQUEST_SERVFAIL:
68                         set_msg("SERV FAIL!", WRAP_NONE);
69                         break;
70                 case REQUEST_EMPTY:
71                         set_msg("NONE LEFT!", WRAP_NONE);
72                         break;
73                 case REQUEST_INVAL:
74                         set_msg(" BAD SELN ", WRAP_NONE);
75                         break;
76         }
77         delay(1000);
78 }
79
80 void selection_menu() {
81         /* we have a valid username & PIN number */
82         /* either ask for a 2-digit selection, or wait for coins to be entered */
83         /* get the username somehow? */
84         set_msg("ENTER SELECTION OR INSERT COINS  ", WRAP_SCROLL);
85         selection = 0;
86         while(1) {
87                 if (coin_value) { /* we have coins inserted */
88                         int prev_coin = 0;
89                         /* alternate between the price and a confirm message */
90                         while (coin_value) {
91                                 if (prev_coin != coin_value) {
92                                         print_amount(coin_value);
93                                         append_msg("0: CONFIRM", WRAP_ALTERNATE);
94                                         prev_coin = coin_value;
95                                 }
96                                 keypad_read();
97                                 if (keypad_pressed()) {
98                                         switch (last_key) {
99                                                 case KEY_RESET:
100                                                         scroll_msg("PRESS COIN REFUND");
101                                                         goto reset;
102                                                 case KEY_0:
103                                                         switch (server_credit_account(uid, pin, coin_value)) {
104                                                                 case CREDIT_OK:
105                                                                         coin_eat();
106                                                                         set_msg(" SUCCESS! ");
107                                                                         delay(1000);
108                                                                         break;
109                                                                 case CREDIT_FAIL:
110                                                                         coin_refund();
111                                                                         set_msg("  FAILED! ");
112                                                                         delay(1000);
113                                                                         break;
114                                                         }
115                                                         break;
116                                         }
117                                 }
118                         }
119                         /* coins were refunded */
120                 }
121
122                 if (selection) { /* half way through a selection */
123                         keypad_read();
124                         if (keypad_pressed()) {
125                                 switch (last_key) {
126                                         case KEY_RESET:
127                                                 selection = 0;
128                                                 break;
129                                         case 0:
130                                                 break;
131                                         default:
132                                                 selection = selection * 10 + (last_key%10);
133                                                 make_request(uid, pin, selection);
134                                                 selection = 0;
135                                 }
136                         }
137                 } else { /* else listen for the first key of a selection */
138                         keypad_read();
139                         if (keypad_pressed()) {
140                                 switch (last_key) {
141                                         case KEY_RESET:
142                                                 return;
143                                         case 0:
144                                                 break;
145                                         default:
146                                                 selection = last_key%10;
147                                 }
148                         }
149                 }
150         }
151 }
152
153 void load_default_msg() {
154         /* FIXME: want this message to be changeable from the server */
155         set_msg("UNIVERSITY COMPUTER CLUB *** INSERT COINS OR USER-ID *** ",
156                         WRAP_SCROLL);
157 }
158
159 void service_menu() {
160         while (door_open()) { /* don't quit until door is closed */
161
162         }
163 }
164
165 int main() {
166         /* do stuff */
167         set_msg("UNIVERSITY", WRAP_NONE);
168         delay(1000);
169         set_msg(" COMPUTER ", WRAP_NONE);
170         delay(1000);
171         set_msg("   CLUB   ", WRAP_NONE);
172         delay(1000);
173
174         load_default_msg();
175         while(1) {
176                 /* this needs to be a relatively tight loop to make sure we catch
177                  * keypresses at the main menu
178                  */
179                 keypad_read();
180                 if (keypad_pressed()) {
181                         if (last_key != KEY_RESET) {
182                                 if (uid_enter() && pin_enter()) {
183                                         /* authenticate them */
184                                         switch (server_authenticate(uid, pin)) {
185                                                 case AUTH_GOOD:
186                                                         selection_menu();
187                                                         break;
188                                                 case AUTH_BAD:
189                                                         set_msg(" BAD USER ", WRAP_NONE);
190                                                         delay(1000);
191                                                         break;
192                                                 case AUTH_NO_MONEY:
193                                                         set_msg(" NO MONEY ", WRAP_NONE);
194                                                         delay(1000);
195                                                         break;
196                                                 case AUTH_LOCKED:
197                                                         set_msg("YOUR ACCOUNT IS LOCKED", WRAP_SCROLL);
198                                                         delay(1000);
199                                                         break;
200                                         }
201                                 }
202                                 uid = 0;
203                                 pin = 0;
204                                 /* move on */
205                         }
206                         load_default_msg();
207                 }
208
209                 /* test door switch   */
210                 if (door_open()) {
211                         service_menu();
212                         load_default_msg();
213                 }
214
215                 /* check on coin mech */
216         }
217 }
218
219 void _start() {
220         /* Initialize Stuff.  Particularly some memory locations that can only be
221          * written in the first 64 clock cycles upon reset.
222          */
223         display_init();
224         set_bus_expanded();
225         /* enable RTI & set rate */
226         /* init coin mech */
227         main();
228 }
229
230 void rti() {
231         chime(); /* turn chime on or of as need be */
232
233         /* scroll the display if need be too */
234         if (scroll_timer == 0) {
235                 display_shift();
236                 scroll_timer = SCROLL_TIME;
237         }
238         scroll_timer--;
239 }

UCC git Repository :: git.ucc.asn.au