OSDN Git Service

[UI] Using key is only keypad; '0' to 'F'.
[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 "ui.h"
29 #include "idle.h"
30
31 keyin_defs keyin_old[2];
32 keyin_defs keyin_now;
33 char keyin_fifo[16];
34 char keyin_nowp;
35 char keyin_readp;
36 char keyin_counter;
37
38 void keyin_init(void)
39 {
40     char i;
41     /* Initialize vars*/
42     for(i = 0; i < 3; i++) {
43         keyin_old[0].byte[i] = 0x00;
44         keyin_old[1].byte[i] = 0x00;
45         keyin_now.byte[i] = 0x00;
46     }
47     for(i = 0; i < 16; i++) keyin_fifo[i] = 0x00;
48     keyin_nowp = 0;
49     keyin_readp = 0;
50     keyin_counter = 0;
51
52 }
53 #if defined(pic18f23k22) || defined(pic18f24k22) || defined(pic18f25k22) || defined(pic18f26k22)
54 /*
55  * For 28Pin PIC(18F2xK22), I2C lcd using.
56  */
57
58 void keyin_ioinit(void)
59 {
60     /* Initialize IOPORTS*/
61     PORTA = 0x00;
62     LATA = 0x00;
63     ANSELA = AN_A_VAL;
64     TRISA = TRIS_A_VAL;
65
66     PORTB = 0x00;
67     LATB = 0x00;
68     ANSELB = AN_B_VAL;
69     TRISB = TRIS_B_VAL;
70
71     PORTC = 0x00;
72     LATC = 0x00;
73     ANSELC = AN_C_VAL;
74     TRISC = TRIS_C_VAL_O;
75 }
76 #endif
77
78 #if defined(pic18f23k20) || defined(pic18f24k20) || defined(pic18f25k20) || defined(pic18f26k20)
79 /*
80  * For 28Pin PIC(18F2xK20), I2C lcd using.
81  */
82
83 void keyin_ioinit(void)
84 {
85     /* Initialize IOPORTS*/
86     PORTA = 0x00;
87     LATA = 0x00;
88     ANSEL = 0x01; // Use RA0 AS ADC, Another is not used.
89     ANSELH = 0x00; //
90     TRISA = TRIS_A_VAL;
91
92     PORTB = 0x00;
93     LATB = 0x00;
94     TRISB = TRIS_B_VAL;
95
96     PORTC = 0x00;
97     LATC = 0x00;
98     TRISC = TRIS_C_VAL_O;
99 }
100 #endif
101
102 #if defined(pic18f43k20) || defined(pic18f44k20) || defined(pic18f45k20) || defined(pic18f46k20)
103 /*
104  * For 40Pin PIC(18F4xK20), paralell or I2C lcd using.
105  */
106 void keyin_ioinit(void)
107 {
108     /* Initialize IOPORTS*/
109     PORTA = 0x00;
110     LATA = 0x00;
111     ANSEL = 0x01; // Use RA0 AS ADC, Another is not used.
112     ANSELH = 0x00; //
113     TRISA = TRIS_A_VAL;
114
115     PORTB = 0x00;
116     LATB = 0x00;
117     TRISB = TRIS_B_VAL;
118
119     PORTC = 0x00;
120     LATC = 0x00;
121     TRISC = TRIS_C_VAL_O;
122
123     /*
124      * You can use PORTD,RE0-RE2 extention, when using I2C lcd.
125      */
126     PORTD = 0x00;
127     LATD = 0x00;
128     TRISD = TRIS_D_VAL;
129
130     PORTE = 0x00;
131     TRISE = TRIS_E_VAL;
132 }
133 #else
134 void keyin_ioinit(void)
135 {
136     /* Initialize IOPORTS*/
137     PORTA = 0x00;
138     LATA = 0x00;
139 //    ANSEL = 0x01; // Use RA0 AS ADC, Another is not used.
140 //    ANSELH = 0x00; //
141     TRISA = TRIS_A_VAL;
142
143     PORTB = 0x00;
144     LATB = 0x00;
145     TRISB = TRIS_B_VAL;
146
147     PORTC = 0x00;
148     LATC = 0x00;
149     TRISC = TRIS_C_VAL_O;
150 }
151 #endif
152 /*
153  * Push to keyin fifo; not used atomic-writing.
154  */
155 void push_keyinfifo(char b) __critical
156 {
157     keyin_nowp++;
158     if((keyin_nowp > 15) || (keyin_nowp < 0))keyin_nowp = 0;
159     keyin_fifo[keyin_nowp] = b;
160     keyin_counter++;
161     if(keyin_counter > 16) keyin_counter = 16;
162 }
163
164 /*
165  * Pop from keyin fifo; not used atomic-reading.
166  */
167 char pop_keyinfifo(void) __critical
168 {
169     char c;
170     if(keyin_counter <= 0) {
171         keyin_counter = 0;
172         return charcode_null ;
173     }
174     if(keyin_readp > 15) keyin_readp = 15;
175     c = keyin_fifo[keyin_readp];
176     keyin_readp++;
177     if(keyin_readp > 15) keyin_readp = 0;
178     keyin_counter--;
179     if(keyin_counter < 0)keyin_counter = 0;
180     return c;
181 }
182
183 void print_numeric(int i, unsigned char supressf)
184 {
185     if((i == 0) && (supressf != 0)){
186         unsigned char c;
187         c = '0';
188         _CURSOR_LEFT();
189         _PUTCHAR(c);
190         _CURSOR_RIGHT();
191     } else {
192         int l;
193         unsigned char supress = 0;
194         if(supressf == 0) supress = 1;
195          _CURSOR_LEFT();
196         if(i < 0){
197             _PUTCHAR('-');
198             i = -i;
199         }
200         l = i / 10000;
201         i = i % 10000;
202         if(l != 0) {
203             _PUTCHAR((l & 0x0f)+ '0');
204             supress = 1;
205         } else if(supress != 0) {
206             _PUTCHAR('0');
207         }
208         l = i / 1000;
209         i = i % 1000;
210         if(supress != 0){
211              _PUTCHAR((l & 0x0f)+ '0');
212         } else if(l != 0){
213              _PUTCHAR((l & 0x0f)+ '0');
214             supress = 1;
215
216         }
217         l = i / 100;
218         i = i % 100;
219         if(supress != 0){
220              _PUTCHAR((l & 0x0f)+ '0');
221         } else if(l != 0){
222              _PUTCHAR((l & 0x0f)+ '0');
223             supress = 1;
224
225         }
226         l = i / 10;
227         i = i % 10;
228         if(supress != 0){
229              _PUTCHAR((l & 0x0f)+ '0');
230         } else if(l != 0){
231              _PUTCHAR((l & 0x0f)+ '0');
232             supress = 1;
233
234         }
235         _PUTCHAR((i & 0x0f) + '0');
236         _CURSOR_RIGHT();
237     }
238
239 }
240
241 void printstr(char *s)
242 {
243     int p = 0;
244     _CURSOR_RIGHT();
245     if(s == NULL) return;
246     do {
247         if(s[p] == '\0') break;
248         _PUTCHAR(s[p]);
249         p++;
250     } while(p < 255);
251 }
252
253 void print_numeric_nosupress(unsigned int data, unsigned char digit)
254 {
255     unsigned char i;
256     unsigned char c;
257     int ref = 10;
258     int div = 1;
259
260     if(digit == 0) return;
261     if(digit >= 5) digit = 5;
262     _CURSOR_LEFT();
263     for(i = 0; i < digit; i++){
264         c = (data % ref) / div + '0';
265         _PUTCHAR(c);
266         ref *= 10;
267     }
268     _CURSOR_RIGHT();
269 }
270 /*
271  * Read Numeric(int)
272  */
273 unsigned int subst_numeric(unsigned int start, unsigned char pos, unsigned char c)
274 {
275     unsigned int p = pos;
276     unsigned int val;
277     if(p > 4) p = 4;
278     switch(p){
279         case 0:
280             val = (start / 10) * 10 + c;
281             break;
282         case 1:
283             val = (start / 100) * 100 + start % 10 + c * 10;
284             break;
285         case 2:
286             val = (start / 1000) * 1000 + start % 100 + c * 100;
287             break;
288         case 3:
289             val = (start / 10000) * 10000 + start % 1000 + c * 1000;
290             break;
291         case 4:
292             val = start % 10000 + c * 10000;
293             break;
294         default:
295             val = start;
296             break;
297       }
298     return val;
299 }
300
301 unsigned int read_numeric(unsigned int initial, unsigned char digit,
302         char startx, char starty)
303 {
304     unsigned char c;
305     unsigned char i;
306     unsigned int val;
307     unsigned char d;
308     unsigned char input_flag;
309
310     d = digit;
311     if(d > 4) d = 4;
312     val = initial;
313     i = 0;
314     do {
315         _LOCATE(startx, starty);
316         print_numeric_nosupress(val, digit);
317         
318         do {
319             input_flag = readkey_compare();
320             idle(0xff80);
321         } while(input_flag == 0);
322         c = pop_keyinfifo();
323
324         if(c == charcode_0){
325             val = subst_numeric(val, i, 0);
326             i++;
327         } else if((c >= charcode_1) && (c <= charcode_9)) {
328             val = subst_numeric(val, i, c - charcode_1 + 1);
329         } else if(c == charcode_f) {
330             // Enter
331             break;
332         } else if(c == charcode_d) {
333             // Del
334             if(i > 0) {
335                 val = (val / 10) * 10;
336                 i--;
337             }
338         } else if(c == charcode_b) {
339             // cancel
340             val = initial;
341             break;
342         }
343         print_numeric_nosupress(val, d);
344         idle(0xff00);
345     } while(i <= d);
346     return val;
347 }
348
349
350
351 /*
352  * Set signal tune status led assigned to RC0.
353  * You should modify if you modify circuit.
354  */
355 void setsignal_tune(unsigned char flag)
356 {
357     if(flag != 0){
358         LATCbits.LATC0 = 1;
359     } else {
360         LATCbits.LATC0 = 0;
361     }
362 }
363
364 /*
365  * Set power of lcd backlight assigned to RB0.
366  * You should modify if you modify circuit.
367  */
368 void set_backlight(unsigned char flag, unsigned int val)
369 {
370     if(flag != 0){
371         LATBbits.LATB0 = 1;
372     } else {
373         LATBbits.LATB0 = 0;
374     }
375 }
376
377
378 /*
379  * Read IOPORTS for KEY. You should modify if you modify circuit.
380  */
381 void readkey_io(void)
382 {
383     char i;
384     unsigned char portvar;
385     unsigned char latchvar;
386     unsigned char high;
387     unsigned char low;
388     if(keyin_counter > 16) keyin_counter = 0;
389     for(i = 0; i < 3; i++){
390         keyin_old[1].byte[i] = keyin_old[0].byte[i];
391         keyin_old[0].byte[i] = keyin_now.byte[i];
392         keyin_now.byte[i] = 0x00;
393      }
394      /* SCANLINE A*/
395     latchvar = LATA | 0x02;
396     LATA = latchvar;
397     portvar = PORTA;
398     low = (portvar & 0x3c) >>2;
399     latchvar = LATA & 0xfd;
400     LATA = latchvar;
401     /* SCANLINE B*/
402     latchvar = LATB | 0x02;
403     LATB = latchvar;
404     portvar = PORTA;
405     high = (portvar & 0x3c) >>2;
406     latchvar = LATB & 0xfd;
407     LATB = latchvar;
408     /* Pos */
409     keyin_now.byte[0] = (low << 4) | high;
410
411     /* SCANLINE C*/
412     latchvar = LATB | 0x04;
413     LATA = latchvar;
414     portvar = PORTA;
415     low = (portvar & 0x3c) >>2;
416     latchvar = LATB & 0xfb;
417     LATA = latchvar;
418     /* SCANLINE D*/
419     latchvar = LATB | 0x20;
420     LATB = latchvar;
421     portvar = PORTA;
422     high = (portvar & 0x3c) >>2;
423     latchvar = LATB & 0xdf;
424     LATB = latchvar;
425     /* Pos */
426     keyin_now.byte[1] = (low << 4) | high;
427
428     /* Special KEYS */
429     keyin_now.BIT0F = PORTBbits.RB1;
430     keyin_now.BIT1F = PORTBbits.RB2;
431     keyin_now.BIT2F = PORTBbits.RB3;
432     keyin_now.BIT3F = 0; // Reserve
433 }
434
435 unsigned char readkey_compare(void)
436 {
437     char b;
438     char c;
439     char d;
440     char e;
441     unsigned char shift;
442     unsigned char f;
443     f = 0;
444     e = 0;
445     for(d = 0; d < 3; d++) {
446         shift = 0x01;
447         for(b = 0; b < 8; b++){
448             c = 0;
449             if((keyin_now.byte[c] & shift) != 0) c++;
450             if((keyin_old[0].byte[c] & shift) != 0) c++;
451             if((keyin_old[1].byte[c] & shift) != 0) c++;
452             if(c >= 2) {
453             /*
454              * Clear older-inputs on .
455              */
456                 f |= 1;
457                 keyin_old[0].byte[c] &= ~shift;
458                 keyin_old[1].byte[c] &= ~shift;
459                 keyin_now.byte[c] &= ~shift;
460                 if(e == 0) {
461                     push_keyinfifo(charcode_0);
462                 } else if(e <= 15) {
463                     push_keyinfifo(b);
464                 } else if(e < 20) {
465                     push_keyinfifo(e + 1);
466                 }
467             }
468             shift <<= 1;
469             e++;
470         }
471     }
472     /**/
473     return f;
474 }
475
476 /*
477  * Notes:
478  * Initialize sequence:
479  * keyin_init();
480  * keyin_ioinit();
481  * 
482  * Read-key-sequence:
483  * In interrupt/unsleep hook(call per Nms):
484  * readkey_io();
485  * readkey_compare();
486  *
487  * In application handler:
488  * c = pop_keyinfifo();
489  * if(c != 0) do(c);
490  */