OSDN Git Service

[LCD][BUG] Set correct sequence,OOPs!
[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 = 0x00; // 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 int 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     if(digit == 5){
263         i = data / 10000;
264         data = data % 10000;
265         _PUTCHAR(i + '0');
266         digit--;
267     }
268     if(digit == 4){
269         i = data / 1000;
270         data = data % 1000;
271         _PUTCHAR(i + '0');
272         digit--;
273     }
274     if(digit == 3){
275         i = data / 100;
276         data = data % 100;
277         _PUTCHAR(i + '0');
278         digit--;
279     }
280     if(digit == 2){
281         i = data / 10;
282         data = data % 10;
283         _PUTCHAR(i + '0');
284         digit--;
285     }
286     if(digit == 1){
287         i = data;
288         _PUTCHAR(i + '0');
289         digit--;
290     }
291 }
292 /*
293  * Read Numeric(int)
294  */
295 unsigned int subst_numeric(unsigned int start, unsigned char pos, unsigned char c)
296 {
297     unsigned int p = pos;
298     unsigned int val;
299     if(p > 4) p = 4;
300     switch(p){
301         case 0:
302             val = (start / 10) * 10 + c;
303             break;
304         case 1:
305             val = (start / 100) * 100 + start % 10 + c * 10;
306             break;
307         case 2:
308             val = (start / 1000) * 1000 + start % 100 + c * 100;
309             break;
310         case 3:
311             val = (start / 10000) * 10000 + start % 1000 + c * 1000;
312             break;
313         case 4:
314             val = start % 10000 + c * 10000;
315             break;
316         default:
317             val = start;
318             break;
319       }
320     return val;
321 }
322
323 unsigned int read_numeric(unsigned int initial, unsigned char digit,
324         char startx, char starty)
325 {
326     unsigned char c;
327     unsigned char i;
328     unsigned int val;
329     unsigned char d;
330     unsigned char input_flag;
331
332     d = digit;
333     if(d > 4) d = 4;
334     val = initial;
335     i = 0;
336     do {
337         _LOCATE(startx, starty);
338         print_numeric_nosupress(val, digit);
339         
340         do {
341             input_flag = readkey_compare();
342             idle(0xff80);
343         } while(input_flag == 0);
344         c = pop_keyinfifo();
345
346         if(c == charcode_0){
347             val = subst_numeric(val, i, 0);
348             i++;
349         } else if((c >= charcode_1) && (c <= charcode_9)) {
350             val = subst_numeric(val, i, c - charcode_1 + 1);
351         } else if(c == charcode_f) {
352             // Enter
353             break;
354         } else if(c == charcode_d) {
355             // Del
356             if(i > 0) {
357                 val = (val / 10) * 10;
358                 i--;
359             }
360         } else if(c == charcode_b) {
361             // cancel
362             val = initial;
363             break;
364         }
365         print_numeric_nosupress(val, d);
366         idle(0xff00);
367     } while(i <= d);
368     return val;
369 }
370
371
372
373 /*
374  * Set signal tune status led assigned to RC0.
375  * You should modify if you modify circuit.
376  */
377 void setsignal_tune(unsigned char flag)
378 {
379     if(flag != 0){
380         LATCbits.LATC0 = 1;
381     } else {
382         LATCbits.LATC0 = 0;
383     }
384 }
385
386 /*
387  * Set power of lcd backlight assigned to RB0.
388  * You should modify if you modify circuit.
389  */
390 void set_backlight(unsigned char flag, unsigned int val)
391 {
392     if(flag != 0){
393         LATBbits.LATB0 = 1;
394     } else {
395         LATBbits.LATB0 = 0;
396     }
397 }
398
399
400 /*
401  * Read IOPORTS for KEY. You should modify if you modify circuit.
402  */
403 void readkey_io(void)
404 {
405     char i;
406     unsigned char portvar;
407     unsigned char latchvar;
408     unsigned char high;
409     unsigned char low;
410     if(keyin_counter > 16) keyin_counter = 0;
411     for(i = 0; i < 3; i++){
412         keyin_old[1].byte[i] = keyin_old[0].byte[i];
413         keyin_old[0].byte[i] = keyin_now.byte[i];
414         keyin_now.byte[i] = 0x00;
415      }
416      /* SCANLINE A*/
417     latchvar = LATA | 0x02;
418     LATA = latchvar;
419     portvar = PORTA;
420     low = (portvar & 0x3c) >>2;
421     latchvar = LATA & 0xfd;
422     LATA = latchvar;
423     /* SCANLINE B*/
424     latchvar = LATB | 0x02;
425     LATB = latchvar;
426     portvar = PORTA;
427     high = (portvar & 0x3c) >>2;
428     latchvar = LATB & 0xfd;
429     LATB = latchvar;
430     /* Pos */
431     keyin_now.byte[0] = (low << 4) | high;
432
433     /* SCANLINE C*/
434     latchvar = LATB | 0x04;
435     LATA = latchvar;
436     portvar = PORTA;
437     low = (portvar & 0x3c) >>2;
438     latchvar = LATB & 0xfb;
439     LATA = latchvar;
440     /* SCANLINE D*/
441     latchvar = LATB | 0x20;
442     LATB = latchvar;
443     portvar = PORTA;
444     high = (portvar & 0x3c) >>2;
445     latchvar = LATB & 0xdf;
446     LATB = latchvar;
447     /* Pos */
448     keyin_now.byte[1] = (low << 4) | high;
449
450     /* Special KEYS */
451     keyin_now.BIT0F = PORTBbits.RB1;
452     keyin_now.BIT1F = PORTBbits.RB2;
453     keyin_now.BIT2F = PORTBbits.RB3;
454     keyin_now.BIT3F = 0; // Reserve
455 }
456
457 unsigned char readkey_compare(void)
458 {
459     char b;
460     char c;
461     char d;
462     char e;
463     unsigned char shift;
464     unsigned char f;
465     f = 0;
466     e = 0;
467     for(d = 0; d < 3; d++) {
468         shift = 0x01;
469         for(b = 0; b < 8; b++){
470             c = 0;
471             if((keyin_now.byte[c] & shift) != 0) c++;
472             if((keyin_old[0].byte[c] & shift) != 0) c++;
473             if((keyin_old[1].byte[c] & shift) != 0) c++;
474             if(c >= 2) {
475             /*
476              * Clear older-inputs on .
477              */
478                 f |= 1;
479                 keyin_old[0].byte[c] &= ~shift;
480                 keyin_old[1].byte[c] &= ~shift;
481                 keyin_now.byte[c] &= ~shift;
482                 if(e == 0) {
483                     push_keyinfifo(charcode_0);
484                 } else if(e <= 15) {
485                     push_keyinfifo(b);
486                 } else if(e < 20) {
487                     push_keyinfifo(e + 1);
488                 }
489             }
490             shift <<= 1;
491             e++;
492         }
493     }
494     /**/
495     return f;
496 }
497
498 /*
499  * Notes:
500  * Initialize sequence:
501  * keyin_init();
502  * keyin_ioinit();
503  * 
504  * Read-key-sequence:
505  * In interrupt/unsleep hook(call per Nms):
506  * readkey_io();
507  * readkey_compare();
508  *
509  * In application handler:
510  * c = pop_keyinfifo();
511  * if(c != 0) do(c);
512  */