OSDN Git Service

[SCHEMATIC] Modify SW/MW/LW Preamp, insert galbanic-isolator replace of common-mode...
[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 #include "commondef.h"
32
33
34 const char charcodemap[] = {charcode_0,
35                             charcode_1,
36                             charcode_4,
37                             charcode_7,
38
39                             charcode_f,
40                             charcode_2,
41                             charcode_5,
42                             charcode_8,
43
44                             charcode_e,
45                             charcode_3,
46                             charcode_6,
47                             charcode_9,
48
49                             charcode_d,
50                             charcode_c,
51                             charcode_b,
52                             charcode_a,
53 };
54
55 extern unsigned char pollkeybuf[32];
56
57 keyin_defs keyin_old[2];
58 keyin_defs keyin_now;
59 char keyin_fifo[32];
60 char keyin_nowp;
61 char keyin_readp;
62 char keyin_counter;
63
64 unsigned char cold;
65
66 // LCD Routines
67 void _PUTCHAR(unsigned char c)
68 {
69     acm1602_putchar(LCD_I2CADDR , c);
70 }
71
72 void _LOCATE(unsigned char x, unsigned char y)
73 {
74     acm1602_locate_16x2(LCD_I2CADDR , x, y);
75 }
76
77 void _LOCATE_0_0(void)
78 {
79     acm1602_locate_16x2(LCD_I2CADDR , 0, 0);
80 }
81
82 void _LOCATE_0_1(void)
83 {
84     acm1602_locate_16x2(LCD_I2CADDR , 0, 1);
85 }
86
87 void _CLS(void)
88 {
89     acm1602_cls(LCD_I2CADDR);
90 }
91 void _HOME(void)
92 {
93     acm1602_home(LCD_I2CADDR);
94 }
95
96 void _CURSOR_ON(void)
97 {
98     acm1602_dispcursor(LCD_I2CADDR, 0xff);
99 }
100
101
102 void _CURSOR_OFF(void)
103 {
104     acm1602_dispcursor(LCD_I2CADDR, 0x00);
105 }
106
107 void _CURSOR_LEFT(void)
108 {
109     acm1602_cursordir(LCD_I2CADDR , 0x00);
110 }
111
112 void _CURSOR_RIGHT(void)
113 {
114     acm1602_cursordir(LCD_I2CADDR , 0xff);
115 }
116
117
118 void keyin_init(void)
119 {
120     char i;
121     /* Initialize vars*/
122     for(i = 0; i < 2; i++) {
123         keyin_old[0].byte[i] = 0x00;
124         keyin_old[1].byte[i] = 0x00;
125         keyin_now.byte[i] = 0x00;
126     }
127     for(i = 0; i < 32; i++) keyin_fifo[i] = 0x00;
128     keyin_nowp = 0;
129     keyin_readp = 0;
130     keyin_counter = 0;
131     cold = charcode_null;
132 }
133 /*
134  * Push to keyin fifo; not used atomic-writing.
135  */
136 #ifdef __SDCC
137 void push_keyinfifo(char b) __critical
138 #else
139 void push_keyinfifo(char b)
140 #endif
141 {
142     if(keyin_counter >= 31) {
143         return; // Discard data.
144     }
145     keyin_fifo[keyin_nowp] = b;
146     keyin_nowp++;
147     keyin_counter++;
148     if(keyin_nowp > 31) keyin_nowp = 0;
149 }
150
151 /*
152  * Pop from keyin fifo; not used atomic-reading.
153  */
154 #ifdef __SDCC
155 char pop_keyinfifo(void) __critical
156 #else
157 char pop_keyinfifo(void)
158 #endif
159 {
160     char c;
161     if(keyin_counter <= 0) {
162         keyin_counter = 0;
163         return charcode_null ;
164     }
165     c = keyin_fifo[keyin_readp];
166     keyin_readp++;
167     keyin_counter--;
168     if(keyin_readp > 31) keyin_readp = 0;
169     return c;
170 }
171
172 void printstr(const char *s)
173 {
174     int p = 0;
175 //    _CURSOR_RIGHT();
176     if(s == NULL) return;
177     do {
178         if(s[p] == '\0') break;
179         _PUTCHAR(s[p]);
180         p++;
181     } while(p < 32);
182 }
183
184
185
186 static void uint2bcd(unsigned long data, unsigned char *bcd)
187 {
188     unsigned char i;
189     unsigned char j;
190
191     for(i = 0; i <= 10; i++){
192         bcd[i] = data % 10;
193         data = data / 10;
194     }
195     bcd[10] = 0;
196 }
197
198 void print_numeric_nosupress(unsigned long data, unsigned char digit)
199 {
200     unsigned char i;
201     unsigned char bcd[11];
202
203     if(digit == 0) return;
204     if(digit > 10) digit = 10;
205     uint2bcd(data, bcd);
206     for(i = digit; i > 0; i--){
207         _PUTCHAR('0' + bcd[i - 1]);
208     }
209 }
210 /*
211  * Read Numeric(int)
212  */
213 unsigned long subst_numeric(unsigned long start, unsigned char pos, unsigned char c)
214 {
215     unsigned long val;
216     unsigned char bcd[11];
217     char i;
218     unsigned long fact;
219
220     if(pos > 10) pos = 10;
221     uint2bcd(start, bcd);
222     bcd[pos] = c;
223     
224     fact = 1;
225     val = 0;
226     for(i = 0; i < 11; i++){
227         val = val + (bcd[i] * fact);
228         fact = fact * 10;
229     }
230     return val;
231 }
232
233 unsigned long read_numeric(unsigned int initial, unsigned char digit,
234         char startx, char starty)
235 {
236     unsigned char c;
237     unsigned char n;
238     char i;
239     unsigned long val;
240     unsigned long v;
241     char d;
242
243     d = digit - 1;
244     val =(unsigned long) initial;
245     i = d;
246     do {
247 //        _CURSOR_OFF();
248        ClrWdt();
249         _LOCATE(startx, starty);
250         print_numeric_nosupress(val, digit);
251        ClrWdt();
252         _LOCATE(startx + d -  i, starty);
253        _CURSOR_ON();
254
255         c = pollkey_single();
256         if(c == charcode_0){
257             val = subst_numeric(val, i, 0);
258             i--;
259         } else if((c >= charcode_1) && (c <= charcode_9)) {
260             val = subst_numeric(val, i, c - charcode_1 + 1);
261             i--;
262         } else if(c == charcode_f) {
263             // Enter
264             break;
265         } else if(c == charcode_a) {
266             // Del
267             val = val / 10;
268             i++;
269         } else if(c == charcode_b) {
270             // cancel
271            _CURSOR_OFF();
272             return 0xffffffff;
273         }  else if(c == charcode_e) {
274             i++;
275         } else if(c == charcode_d) {
276             i--;
277         }
278        if(i <= 0) i = 0;
279        if(i > d) i = d;
280     } while(1);
281     _CURSOR_OFF();
282     if(val > 0x7fffffff) val = 0x7fffffff;
283     return val;
284 }
285
286 unsigned char readkey_compare(void)
287 {
288     char b;
289     char c;
290     char d;
291     char e;
292     unsigned char shift;
293     unsigned char f;
294     f = 0;
295     e = 0;
296     for(d = 0; d < 2; d++) {
297         shift = 0x01;
298         for(b = 0; b < 8; b++){
299             c = 0;
300             if((keyin_now.byte[d] & shift) != 0) c++;
301             if((keyin_old[0].byte[d] & shift) != 0) c++;
302             if((keyin_old[1].byte[d] & shift) != 0) c++;
303             if(c >= 2) {
304             /*
305              * Clear older-inputs on .
306              */
307                 f |= 1;
308                 keyin_old[0].byte[d] &= ~shift;
309                 keyin_old[1].byte[d] &= ~shift;
310                 keyin_now.byte[d] &= ~shift;
311                 push_keyinfifo(charcodemap[e]);
312             }
313             shift <<= 1;
314             e++;
315         }
316     }
317     /**/
318     return f;
319 }
320
321 unsigned char readkey(void)
322 {
323     unsigned char i;
324     for(i = 0; i < 9; i++) {
325         idle_time_ms(2); // 2ms
326         readkey_io(i);
327 //        ClrWdt();
328     }
329     readkey_compare();
330     return pop_keyinfifo();
331 }
332
333
334 unsigned char pollkey_single(void)
335 {
336     unsigned int penalty = 0;
337     unsigned char c;
338
339 //    cold = charcode_null;
340     do {
341         idle_time_ms(5); // 5ms.
342         c = readkey(); // 2 * 9 = 18ms
343         ClrWdt();
344         if(c != charcode_null) {
345             if(cold != c){
346                 cold = c;
347                 return c;
348             }
349             penalty = 0;
350         } else {
351             penalty++;
352             if(penalty > 4) {
353                 penalty = 0;
354                 cold = charcode_null; // About 100ms
355             }
356         }
357     } while(1);
358 }
359
360
361 unsigned char pollkey_numeric(unsigned char init)
362 {
363     unsigned char c;
364     _PUTCHAR('0' + init);
365     c = pollkey_single();
366     if(c == charcode_0) {
367         return 0;
368     } else if((c >= charcode_1) && (c <= charcode_9)){
369         return c;
370     } else {
371         return init;
372     }
373 }
374
375 unsigned char pollkey_single_timeout(unsigned char limit, unsigned char repeat)
376 {
377     unsigned char c;
378     unsigned char ticks = 0;
379     unsigned char penalty = 0;
380     unsigned char count = 0;
381
382
383     cold = charcode_null;
384     pollkeybuf[0] = charcode_null;
385     do {
386         if(limit != 0) {
387             ticks++;
388             if(ticks > limit) {
389                 break;
390             }
391         }
392         idle_time_ms(5); // 5ms.
393         c = readkey(); // 2 * 9 = 18ms
394         ClrWdt();
395         ticks++;
396         if(c != charcode_null){
397             if(cold != c) {
398                 pollkeybuf[count++] = c;
399                 cold = c;
400                 count++;
401                 if(repeat == 0) {
402                         break;
403                 }
404                 penalty = 0;
405             }
406         }  else {
407             penalty++;
408             if(penalty > 4){
409                 penalty = 0;
410                 cold = charcode_null;
411             }
412         }
413     } while(count < 32);
414
415     /*
416      * Set Deadzone.
417      */
418     if(limit != 0) {
419         while(ticks <= limit) {
420             idle_time_ms(5 + 18);
421             ticks++;
422         }
423     }
424     c = pollkeybuf[0];
425     return c;
426 }
427 /*
428  * Notes:
429  * Initialize sequence:
430  * keyin_init();
431  * keyin_ioinit();
432  * 
433  * Read-key-sequence:
434  * In interrupt/unsleep hook(call per Nms):
435  * readkey_io();
436  * readkey_compare();
437  *
438  * In application handler:
439  * c = pop_keyinfifo();
440  * if(c != 0) do(c);
441  */