keypad fix
[uccvend-snackrom.git] / ROM2 / main_basic.c
1 /*
2  * main_basic.c - a simplified main procedure that relies upon a ersver to do
3  * anything smart. Just be a dumb interface to a display, keypad, coin mech
4  * and snacks.
5  */
6
7 #include "display_basic.h"
8 #include "keypad.h"
9 #include "chime.h"
10 #include "coinmech.h"
11 #include "motors.h"
12 #include "comm.h"
13 #include "vend.h"
14
15 void motor_reply(char* slotptr, u8 code) {
16         /* returns a message of the form MXYY - X is return code, YY is motor */
17         wait_for_tx_free();
18         tx_buffer[0] = 'M';
19         tx_buffer[1] = code + '0';
20         tx_buffer[2] = *slotptr;
21         tx_buffer[3] = *(slotptr+1);
22         tx_buffer[4] = '\n';
23         tx_buffer[5] = 0;
24         send_packet();
25 }
26
27 void dispense_something() {
28         /* process a message VXX in msg_buf where XX is motor number */
29         u8 slot;
30
31         if ((msg_buf[1] < '0') || (msg_buf[1] > '9') ||
32                 (msg_buf[2] < '0') || (msg_buf[2] > '9')) {
33                 msg_buf[1] = msg_buf[2] = '0';
34                 motor_reply((char*)&msg_buf[1], MOTOR_NOSLOT);
35                 return;
36         }
37
38         slot = (msg_buf[1] - '0') * 10;
39         slot += msg_buf[2] - '0';
40
41         motor_reply((char*)&msg_buf[1], dispense_motor(slot));
42 }
43
44 void write_to_display() {
45         /* process a message in the form DXXXXXXXXXXX to send to display */
46         u8 i;
47         char buf[10];
48         for (i = 0; i < 10; i++)
49                 if (msg_buf[i+1])
50                         buf[i] = msg_buf[i+1];
51                 else
52                         break;
53
54         for (; i < 10; i++) /* pad the rest out with spaces */
55                 buf[i] = ' ';
56
57         set_msg(buf);
58         send_ack();
59 }
60
61 void send_balance() {
62         wait_for_tx_free();
63         tx_buffer[0] = 'C';
64         tx_buffer[1] = (coin_value/10000)%10;
65         tx_buffer[2] = (coin_value/1000)%10;
66         tx_buffer[3] = (coin_value/100)%10;
67         tx_buffer[4] = (coin_value/10)%10;
68         tx_buffer[5] = coin_value%10;
69         tx_buffer[6] = '\n';
70         tx_buffer[7] = 0;
71         send_packet();
72 }
73
74 void give_change() {
75         u16 cost;
76
77         if ((msg_buf[1] < '0') || (msg_buf[1] > '9') ||
78                 (msg_buf[2] < '0') || (msg_buf[2] > '9') ||
79                 (msg_buf[3] < '0') || (msg_buf[3] > '9') ||
80                 (msg_buf[4] < '0') || (msg_buf[4] > '9') ||
81                 (msg_buf[5] < '0') || (msg_buf[5] > '9')) {
82                 send_nack();
83         }
84         cost = msg_buf[1] - '0';
85         cost *= 10; cost = msg_buf[2] - '0';
86         cost *= 10; cost = msg_buf[3] - '0';
87         cost *= 10; cost = msg_buf[4] - '0';
88         cost *= 10; cost = msg_buf[5] - '0';
89
90         coin_cost(cost);
91         send_ack();
92
93
94 void send_keypress(u8 key) {
95         /* send a packet of the form KX with X being the key, or R for reset */
96         wait_for_tx_free();
97         tx_buffer[0] = 'K';
98         if (key == KEY_RESET)
99                 tx_buffer[1] = 'R';
100         else
101                 tx_buffer[1] = (key%10)+'0';
102         tx_buffer[2] = '\n';
103         tx_buffer[3] = 0;
104         send_packet();
105 }
106
107 void send_door_msg(bool open) {
108         wait_for_tx_free();
109         tx_buffer[0] = 'D';
110         tx_buffer[1] = open?'1':'0';
111         tx_buffer[2] = '\n';
112         tx_buffer[3] = 0;
113         send_packet();
114 }
115
116 void do_chime() {
117         chime_start();
118         send_ack();
119 }
120
121 int main() {
122         u16 last_coin_value;
123         bool last_door_open;
124
125         chime_start();
126         
127         misc_output = 0;
128         changer_output = 0x7f;
129         _io_ports[M6811_PORTA] = 0xc8;
130         _io_ports[M6811_DDRD] = 0x3e;
131         _io_ports[M6811_SPCR] = 0x12;
132
133         unlock(); /* enable interrupts */
134
135         display_init();
136         comm_init();
137         coinmech_init();
138
139         last_coin_value = 0;
140         last_door_open = 0;
141         
142         while(1) {
143                 if (door_open() != last_door_open) {
144                         last_door_open = door_open();
145                         send_door_msg(last_door_open);
146                 }
147
148                 if (rx_queue_state) {
149                         switch (msg_buf[0]) {
150                                 case 'V':
151                                         dispense_something();
152                                         break;
153                                 case 'D':
154                                         write_to_display();
155                                         break;
156                                 case 'B': 
157                                         do_chime();
158                                         break;
159                                 case 'U':
160                                         send_balance();
161                                         break;
162                                 case 'G':
163                                         give_change();
164                                         break;
165                                 default:
166                                 /* shrug */
167                                         send_nack();
168                                         break;
169                         }
170                         msg_clr();
171                 }
172
173                 keypad_read();
174                 if (keypad_pressed()) {
175                         send_keypress(last_key);
176                 }
177
178                 if (coin_value != last_coin_value) {
179                         send_balance();
180                         last_coin_value = coin_value;
181                 }
182         }
183 }
184

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