OSDN Git Service

[UI][Key] Add input-keymatrix support @low-level.
[openi2cradio/OpenI2CRadio.git] / ui.c
1 /*
2  * OpenI2CRADIO
3  * UI Handler
4  * Copyright (C) 2013-06-10 K.Ohta <whatisthis.sowhat ai gmail.com>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2,
9  *  or (at your option) any later version.
10  *  This library / program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  *  See the GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this library; see the file COPYING. If not, write to the
17  *  Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
18  *  MA 02110-1301, USA.
19  *
20  *  As a special exception, if you link this(includeed from sdcc) library
21  *  with other files, some of which are compiled with SDCC,
22  *  to produce an executable, this library does not by itself cause
23  *  the resulting executable to be covered by the GNU General Public License.
24  *  This exception does not however invalidate any other reasons why
25  *  the executable file might be covered by the GNU General Public License.
26  */
27
28 #include "ioports.h"
29 #include "ui.h"
30 #include "idle.h"
31
32
33 const char charcodemap[] = {charcode_0,
34                             charcode_1,
35                             charcode_4,
36                             charcode_7,
37
38                             charcode_f,
39                             charcode_2,
40                             charcode_5,
41                             charcode_8,
42
43                             charcode_e,
44                             charcode_3,
45                             charcode_6,
46                             charcode_9,
47
48                             charcode_d,
49                             charcode_c,
50                             charcode_b,
51                             charcode_a,
52 };
53
54 keyin_defs keyin_old[2];
55 keyin_defs keyin_now;
56 char keyin_fifo[32];
57 char keyin_nowp;
58 char keyin_readp;
59 char keyin_counter;
60
61 void keyin_init(void)
62 {
63     char i;
64     /* Initialize vars*/
65     for(i = 0; i < 2; i++) {
66         keyin_old[0].byte[i] = 0x00;
67         keyin_old[1].byte[i] = 0x00;
68         keyin_now.byte[i] = 0x00;
69     }
70     for(i = 0; i < 16; i++) keyin_fifo[i] = 0x00;
71     keyin_nowp = 0;
72     keyin_readp = 0;
73     keyin_counter = 0;
74
75 }
76 /*
77  * Push to keyin fifo; not used atomic-writing.
78  */
79 void push_keyinfifo(char b) __critical
80 {
81     if(keyin_counter >= 31) {
82         keyin_counter = 31;
83         return;
84     }
85     keyin_nowp++;
86     if((keyin_nowp > 31) || (keyin_nowp < 0))keyin_nowp = 0;
87     keyin_fifo[keyin_nowp] = b;
88     keyin_counter++;
89 }
90
91 /*
92  * Pop from keyin fifo; not used atomic-reading.
93  */
94 char pop_keyinfifo(void) __critical
95 {
96     char c;
97     if(keyin_counter <= 0) {
98         keyin_counter = 0;
99         return charcode_null ;
100     }
101     if(keyin_readp > 31) keyin_readp = 0;
102     c = keyin_fifo[keyin_readp];
103     keyin_readp++;
104     keyin_counter--;
105     if(keyin_counter < 0) keyin_counter = 0;
106     return c;
107 }
108
109 void print_numeric(int i, unsigned char supressf)
110 {
111     if((i == 0) && (supressf != 0)){
112         unsigned char c;
113         c = '0';
114         _CURSOR_LEFT();
115         _PUTCHAR(c);
116         _CURSOR_RIGHT();
117     } else {
118         int l;
119         unsigned char supress = 0;
120         if(supressf == 0) supress = 1;
121          _CURSOR_LEFT();
122         if(i < 0){
123             _PUTCHAR('-');
124             i = -i;
125         }
126         l = i / 10000;
127         i = i % 10000;
128         if(l != 0) {
129             _PUTCHAR((l & 0x0f)+ '0');
130             supress = 1;
131         } else if(supress != 0) {
132             _PUTCHAR('0');
133         }
134         l = i / 1000;
135         i = i % 1000;
136         if(supress != 0){
137              _PUTCHAR((l & 0x0f)+ '0');
138         } else if(l != 0){
139              _PUTCHAR((l & 0x0f)+ '0');
140             supress = 1;
141
142         }
143         l = i / 100;
144         i = i % 100;
145         if(supress != 0){
146              _PUTCHAR((l & 0x0f)+ '0');
147         } else if(l != 0){
148              _PUTCHAR((l & 0x0f)+ '0');
149             supress = 1;
150
151         }
152         l = i / 10;
153         i = i % 10;
154         if(supress != 0){
155              _PUTCHAR((l & 0x0f)+ '0');
156         } else if(l != 0){
157              _PUTCHAR((l & 0x0f)+ '0');
158             supress = 1;
159
160         }
161         _PUTCHAR((i & 0x0f) + '0');
162         _CURSOR_RIGHT();
163     }
164
165 }
166
167 void printstr(char *s)
168 {
169     int p = 0;
170     _CURSOR_RIGHT();
171     if(s == NULL) return;
172     do {
173         if(s[p] == '\0') break;
174         _PUTCHAR(s[p]);
175         p++;
176     } while(p < 255);
177 }
178
179 void print_numeric_nosupress(unsigned int data, unsigned char digit)
180 {
181     unsigned int i;
182     int ref = 10;
183     int div = 1;
184
185     if(digit == 0) return;
186     if(digit >= 5) digit = 5;
187     if(digit == 5){
188         i = data / 10000;
189         data = data % 10000;
190         _PUTCHAR(i + '0');
191         digit--;
192     }
193     if(digit == 4){
194         i = data / 1000;
195         data = data % 1000;
196         _PUTCHAR(i + '0');
197         digit--;
198     }
199     if(digit == 3){
200         i = data / 100;
201         data = data % 100;
202         _PUTCHAR(i + '0');
203         digit--;
204     }
205     if(digit == 2){
206         i = data / 10;
207         data = data % 10;
208         _PUTCHAR(i + '0');
209         digit--;
210     }
211     if(digit == 1){
212         i = data;
213         _PUTCHAR(i + '0');
214         digit--;
215     }
216 }
217 /*
218  * Read Numeric(int)
219  */
220 unsigned int subst_numeric(unsigned int start, unsigned char pos, unsigned char c)
221 {
222     unsigned int p = pos;
223     unsigned int val;
224     if(p > 4) p = 4;
225     switch(p){
226         case 0:
227             val = (start / 10) * 10 + c;
228             break;
229         case 1:
230             val = (start / 100) * 100 + start % 10 + c * 10;
231             break;
232         case 2:
233             val = (start / 1000) * 1000 + start % 100 + c * 100;
234             break;
235         case 3:
236             val = (start / 10000) * 10000 + start % 1000 + c * 1000;
237             break;
238         case 4:
239             val = start % 10000 + c * 10000;
240             break;
241         default:
242             val = start;
243             break;
244       }
245     return val;
246 }
247
248 unsigned int read_numeric(unsigned int initial, unsigned char digit,
249         char startx, char starty)
250 {
251     unsigned char c;
252     unsigned char i;
253     unsigned int val;
254     unsigned char d;
255     unsigned char input_flag;
256
257     d = digit;
258     if(d > 4) d = 4;
259     val = initial;
260     i = 0;
261     do {
262         _LOCATE(startx, starty);
263         print_numeric_nosupress(val, digit);
264         
265         do {
266             input_flag = readkey_compare();
267             idle(0xff80);
268         } while(input_flag == 0);
269         c = pop_keyinfifo();
270
271         if(c == charcode_0){
272             val = subst_numeric(val, i, 0);
273             i++;
274         } else if((c >= charcode_1) && (c <= charcode_9)) {
275             val = subst_numeric(val, i, c - charcode_1 + 1);
276         } else if(c == charcode_f) {
277             // Enter
278             break;
279         } else if(c == charcode_d) {
280             // Del
281             if(i > 0) {
282                 val = (val / 10) * 10;
283                 i--;
284             }
285         } else if(c == charcode_b) {
286             // cancel
287             val = initial;
288             break;
289         }
290         print_numeric_nosupress(val, d);
291         idle(0xff00);
292     } while(i <= d);
293     return val;
294 }
295
296
297
298
299
300
301
302 unsigned char readkey_compare(void)
303 {
304     char b;
305     char c;
306     char d;
307     char e;
308     unsigned char shift;
309     unsigned char f;
310     f = 0;
311     e = 0;
312     for(d = 0; d < 2; d++) {
313         shift = 0x01;
314         for(b = 0; b < 8; b++){
315             c = 0;
316             if((keyin_now.byte[d] & shift) != 0) c++;
317             if((keyin_old[0].byte[d] & shift) != 0) c++;
318             if((keyin_old[1].byte[d] & shift) != 0) c++;
319             if(c >= 2) {
320             /*
321              * Clear older-inputs on .
322              */
323                 f |= 1;
324                 keyin_old[0].byte[d] &= ~shift;
325                 keyin_old[1].byte[d] &= ~shift;
326                 keyin_now.byte[d] &= ~shift;
327                 if(e < 16) {
328                     push_keyinfifo(charcodemap[e]);
329                 } 
330             }
331             shift <<= 1;
332             e++;
333         }
334     }
335     /**/
336     return f;
337 }
338
339 unsigned char readkey(void)
340 {
341     unsigned char i;
342     for(i = 0; i < 8; i++) {
343         idle(0xfffe); // 1.5ms?
344         readkey_io(i);
345     }
346     readkey_compare();
347     return pop_keyinfifo();
348 }
349
350 /*
351  * Notes:
352  * Initialize sequence:
353  * keyin_init();
354  * keyin_ioinit();
355  * 
356  * Read-key-sequence:
357  * In interrupt/unsleep hook(call per Nms):
358  * readkey_io();
359  * readkey_compare();
360  *
361  * In application handler:
362  * c = pop_keyinfifo();
363  * if(c != 0) do(c);
364  */