UART code for a 16550.
[uccvend-snackrom.git] / ROM2 / main.c
index 3331548..81919f0 100644 (file)
@@ -1,5 +1,241 @@
+#include "display.h"
+#include "keypad.h"
+#include "chime.h"
+#include "server.h"
+#include "coinmech.h"
 #include "vend.h"
 
+u16 uid;
+u16 pin;
+u8 selection;
+
+u16 scroll_timer;
+
+bool uid_enter() {
+       u8 uidpos;
+       /* the user has started to type in his/her UID. grab the last key and continue
+        * reading. Returns true if a UID was entered successfully.
+        * The UID will be entered as 5 digits. (shorter uids should be pre-padded
+        * with zeros)
+        */
+       uid = last_key%10; /* 10 => 0, it was _not_ reset (hopefuly :) */
+       set_msg("UID?      ", WRAP_NONE);
+       set_char((last_key%10)+'0', 5);
+
+       for (uidpos = 2; uidpos <= 5; uidpos++) {
+               keypad_getkey();
+               if (last_key == KEY_RESET) {
+                       uid = 0;
+                       return 0;
+               }
+               uid = (uid*10) + (last_key%10);
+               set_char((last_key%10)+'0', 4+uidpos);
+       }
+       return (uid!=0);
+}
+
+bool pin_enter() {
+       u8 pinpos;
+       /* We ask for a pin, display a PIN: prompt. PINs must be a 4 digit number.
+        * Strictly, they must be 16-bit, but it's easier to use the guarantee that
+        * 4-digits numbers are < 65536
+        *
+        * Also display X's on screen as the pin is entered.
+        */
+       pin = 0;
+       set_msg("PIN?      ", WRAP_NONE);
+       for (pinpos = 1; pinpos <= 4; pinpos++) {
+               keypad_getkey();
+               if (last_key == KEY_RESET) {
+                       pin = 0;
+                       return 0;
+               }
+               pin = (pin*10) + (last_key%10);
+               set_char('X', 4+pinpos);
+       }
+       return 1;
+}
+
+void make_request(u8 selection) {
+       set_msg("REQUESTING", WRAP_NONE); /* XXX: maybe this isn't needed? */
+       switch(server_request(uid, pin, selection)) {
+               case REQUEST_OK:
+                       set_msg("THANK YOU!", WRAP_NONE);
+                       break;
+               case REQUEST_NO_MONEY:
+                       set_msg("NO MONEY!", WRAP_NONE);
+                       break;
+               case REQUEST_SERVFAIL:
+                       set_msg("SERV FAIL!", WRAP_NONE);
+                       break;
+               case REQUEST_EMPTY:
+                       set_msg("NONE LEFT!", WRAP_NONE);
+                       break;
+               case REQUEST_INVAL:
+                       set_msg(" BAD SELN ", WRAP_NONE);
+                       break;
+       }
+       delay(1000);
+}
+
+void selection_menu() {
+       /* we have a valid username & PIN number */
+       /* either ask for a 2-digit selection, or wait for coins to be entered */
+       /* get the username somehow? */
+       set_msg("ENTER SELECTION OR INSERT COINS  ", WRAP_SCROLL);
+       selection = 0;
+       while(1) {
+               if (coin_value) { /* we have coins inserted */
+                       int prev_coin = 0;
+                       /* alternate between the price and a confirm message */
+                       while (coin_value) {
+                               if (prev_coin != coin_value) {
+                                       print_amount(coin_value);
+                                       append_msg("0: CONFIRM", WRAP_ALTERNATE);
+                                       prev_coin = coin_value;
+                               }
+                               keypad_read();
+                               if (keypad_pressed()) {
+                                       switch (last_key) {
+                                               case KEY_RESET:
+                                                       scroll_msg("PRESS COIN REFUND");
+                                                       while (coin_value);
+                                                       break;
+                                               case KEY_0:
+                                                       switch (server_credit_account(uid, pin, coin_value)) {
+                                                               case CREDIT_OK:
+                                                                       coin_eat();
+                                                                       set_msg(" SUCCESS! ", WRAP_NONE);
+                                                                       delay(1000);
+                                                                       break;
+                                                               case CREDIT_FAIL:
+                                                                       set_msg(" FAILED!  " "PRESS COIN" "  REFUND  ",
+                                                                                       WRAP_ALTERNATE);
+                                                                       while (coin_value);
+                                                                       break;
+                                                       }
+                                                       break;
+                                       }
+                               }
+                       }
+                       /* coins were refunded */
+               }
+
+               if (selection) { /* half way through a selection */
+                       keypad_read();
+                       if (keypad_pressed()) {
+                               switch (last_key) {
+                                       case KEY_RESET:
+                                               selection = 0;
+                                               break;
+                                       case 0:
+                                               break;
+                                       default:
+                                               selection = selection * 10 + (last_key%10);
+                                               make_request(selection);
+                                               selection = 0;
+                               }
+                       }
+               } else { /* else listen for the first key of a selection */
+                       keypad_read();
+                       if (keypad_pressed()) {
+                               switch (last_key) {
+                                       case KEY_RESET:
+                                               return;
+                                       case 0:
+                                               break;
+                                       default:
+                                               selection = last_key%10;
+                               }
+                       }
+               }
+       }
+}
+
+void load_default_msg() {
+       /* FIXME: want this message to be changeable from the server */
+       set_msg("UNIVERSITY COMPUTER CLUB *** INSERT COINS OR USER-ID *** ",
+                       WRAP_SCROLL);
+}
+
+void service_menu() {
+       while (door_open()) { /* don't quit until door is closed */
+
+       }
+}
+
+int main() {
+       /* do stuff */
+       set_msg("UNIVERSITY", WRAP_NONE);
+       delay(1000);
+       set_msg(" COMPUTER ", WRAP_NONE);
+       delay(1000);
+       set_msg("   CLUB   ", WRAP_NONE);
+       delay(1000);
+
+       load_default_msg();
+       while(1) {
+               /* this needs to be a relatively tight loop to make sure we catch
+                * keypresses at the main menu
+                */
+               keypad_read();
+               if (keypad_pressed()) {
+                       if (last_key != KEY_RESET) {
+                               if (uid_enter() && pin_enter()) {
+                                       /* authenticate them */
+                                       switch (server_authenticate(uid, pin)) {
+                                               case AUTH_GOOD:
+                                                       selection_menu();
+                                                       break;
+                                               case AUTH_BAD:
+                                                       set_msg(" BAD USER ", WRAP_NONE);
+                                                       delay(1000);
+                                                       break;
+                                               case AUTH_NO_MONEY:
+                                                       set_msg(" NO MONEY ", WRAP_NONE);
+                                                       delay(1000);
+                                                       break;
+                                               case AUTH_LOCKED:
+                                                       set_msg("YOUR ACCOUNT IS LOCKED", WRAP_SCROLL);
+                                                       delay(1000);
+                                                       break;
+                                       }
+                               }
+                               uid = 0;
+                               pin = 0;
+                               /* move on */
+                       }
+                       load_default_msg();
+               }
+
+               /* test door switch   */
+               if (door_open()) {
+                       service_menu();
+                       load_default_msg();
+               }
+
+               /* check on coin mech */
+       }
+}
+
 void _start() {
+       /* Initialize Stuff.  Particularly some memory locations that can only be
+        * written in the first 64 clock cycles upon reset.
+        */
+       display_init();
+       set_bus_expanded();
+       /* enable RTI & set rate */
+       /* init coin mech */
+       main();
 }
 
+void rti() {
+       chime(); /* turn chime on or of as need be */
+
+       /* scroll the display if need be too */
+       if (scroll_timer == 0) {
+               display_shift();
+               scroll_timer = SCROLL_TIME;
+       }
+       scroll_timer--;
+}

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