OSDN Git Service

[General] Add support of PIC18F45K20.
[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
30 keyin_defs keyin_old[2];
31 keyin_defs keyin_now;
32 char keyin_fifo[16];
33 char keyin_nowp;
34 char keyin_readp;
35 char keyin_counter;
36
37 void keyin_init(void)
38 {
39     char i;
40     /* Initialize vars*/
41     for(i = 0; i < 3; i++) {
42         keyin_old[0].byte[i] = 0x00;
43         keyin_old[1].byte[i] = 0x00;
44         keyin_now.byte[i] = 0x00;
45     }
46     for(i = 0; i < 16; i++) keyin_fifo[i] = 0x00;
47     keyin_nowp = 0;
48     keyin_readp = 0;
49     keyin_counter = 0;
50
51 }
52
53 #if defined(__18F23K22) || defined(__18F24K22) || defined(__18F25K22) || defined(__18F26K22)
54
55 void keyin_ioinit(void)
56 {
57     /* Initialize IOPORTS*/
58     PORTA = 0x00;
59     LATA = 0x00;
60     ANSELA = AN_A_VAL;
61     TRISA = TRIS_A_VAL;
62
63     PORTB = 0x00;
64     LATB = 0x00;
65     ANSELB = AN_B_VAL;
66     TRISB = TRIS_B_VAL;
67
68     PORTC = 0x00;
69     LATC = 0x00;
70     ANSELC = AN_C_VAL;
71     TRISC = TRIS_C_VAL_O;
72 }
73 #elif defined(__18F43K20) || defined(__18F44K20) || defined(__18F45K20) || defined(__18F46K20)
74
75 void keyin_ioinit(void)
76 {
77     /* Initialize IOPORTS*/
78     PORTA = 0x00;
79     LATA = 0x00;
80     ANSEL = 0x01; // Use RA0 AS ADC, Another is not used.
81     ANSELH = 0x00; //
82     TRISA = TRIS_A_VAL;
83
84     PORTB = 0x00;
85     LATB = 0x00;
86     TRISB = TRIS_B_VAL;
87
88     PORTC = 0x00;
89     LATC = 0x00;
90     TRISC = TRIS_C_VAL_O;
91 }
92 #else
93 void keyin_ioinit(void)
94 {
95     /* Initialize IOPORTS*/
96     PORTA = 0x00;
97     LATA = 0x00;
98 //    ANSEL = 0x01; // Use RA0 AS ADC, Another is not used.
99 //    ANSELH = 0x00; //
100     TRISA = TRIS_A_VAL;
101
102     PORTB = 0x00;
103     LATB = 0x00;
104     TRISB = TRIS_B_VAL;
105
106     PORTC = 0x00;
107     LATC = 0x00;
108     TRISC = TRIS_C_VAL_O;
109 }
110 #endif
111 /*
112  * Push to keyin fifo; not used atomic-writing.
113  */
114 void push_keyinfifo(char b) __critical
115 {
116     keyin_nowp++;
117     if((keyin_nowp > 15) || (keyin_nowp < 0))keyin_nowp = 0;
118     keyin_fifo[keyin_nowp] = b;
119     keyin_counter++;
120     if(keyin_counter > 16) keyin_counter = 16;
121 }
122
123 /*
124  * Pop from keyin fifo; not used atomic-reading.
125  */
126 char pop_keyinfifo(void) __critical
127 {
128     char c;
129     if(keyin_counter <= 0) {
130         keyin_counter = 0;
131         return charcode_null ;
132     }
133     if(keyin_readp > 15) keyin_readp = 15;
134     c = keyin_fifo[keyin_readp];
135     keyin_readp++;
136     if(keyin_readp > 15) keyin_readp = 0;
137     keyin_counter--;
138     if(keyin_counter < 0)keyin_counter = 0;
139     return c;
140 }
141
142 void print_numeric(int i)
143 {
144     if(i == 0){
145         unsigned char c;
146         c = '0';
147         _CURSOR_LEFT();
148         _PUTCHAR(c);
149         _CURSOR_RIGHT();
150     } else {
151         int l;
152         unsigned char supress = 0;
153          _CURSOR_LEFT();
154         if(i < 0){
155             _PUTCHAR('-');
156             i = -i;
157         }
158         l = i / 10000;
159         i = i % 10000;
160         if(l != 0) {
161             _PUTCHAR((l & 0x0f)+ '0');
162             supress = 1;
163         }
164         l = i / 1000;
165         i = i % 1000;
166         if(supress != 0){
167              _PUTCHAR((l & 0x0f)+ '0');
168         } else if(l != 0){
169              _PUTCHAR((l & 0x0f)+ '0');
170             supress = 1;
171
172         }
173         l = i / 100;
174         i = i % 100;
175         if(supress != 0){
176              _PUTCHAR((l & 0x0f)+ '0');
177         } else if(l != 0){
178              _PUTCHAR((l & 0x0f)+ '0');
179             supress = 1;
180
181         }
182         l = i / 10;
183         i = i % 10;
184         if(supress != 0){
185              _PUTCHAR((l & 0x0f)+ '0');
186         } else if(l != 0){
187              _PUTCHAR((l & 0x0f)+ '0');
188             supress = 1;
189
190         }
191         _PUTCHAR((i & 0x0f) + '0');
192         _CURSOR_RIGHT();
193     }
194
195 }
196
197 void printstr(char *s)
198 {
199     int p = 0;
200     _CURSOR_RIGHT();
201     if(s == NULL) return;
202     do {
203         if(s[p] == '\0') break;
204         _PUTCHAR(s[p]);
205         p++;
206     } while(p < 255);
207 }
208
209 void setsignal_tune(unsigned char flag)
210 {
211     if(flag != 0){
212         LATCbits.LATC0 = 1;
213     } else {
214         LATCbits.LATC0 = 0;
215     }
216 }
217
218 void set_backlight(unsigned char flag, unsigned int val)
219 {
220     if(flag != 0){
221         LATBbits.LATB0 = 1;
222     } else {
223         LATBbits.LATB0 = 0;
224     }
225 }
226
227
228 /*
229  * Read IOPORTS for KEY.
230  */
231 void readkey_io(void)
232 {
233     char i;
234     unsigned char portvar;
235     unsigned char latchvar;
236     unsigned char high;
237     unsigned char low;
238     if(keyin_counter > 16) keyin_counter = 0;
239     for(i = 0; i < 3; i++){
240         keyin_old[1].byte[i] = keyin_old[0].byte[i];
241         keyin_old[0].byte[i] = keyin_now.byte[i];
242         keyin_now.byte[i] = 0x00;
243      }
244      /* SCANLINE A*/
245     latchvar = LATA | 0x02;
246     LATA = latchvar;
247     portvar = PORTA;
248     low = (portvar & 0x3c) >>2;
249     latchvar = LATA & 0xfd;
250     LATA = latchvar;
251     /* SCANLINE B*/
252     latchvar = LATB | 0x02;
253     LATB = latchvar;
254     portvar = PORTA;
255     high = (portvar & 0x3c) >>2;
256     latchvar = LATB & 0xfd;
257     LATB = latchvar;
258     /* Pos */
259     keyin_now.byte[0] = (low << 4) | high;
260
261     /* SCANLINE C*/
262     latchvar = LATB | 0x04;
263     LATA = latchvar;
264     portvar = PORTA;
265     low = (portvar & 0x3c) >>2;
266     latchvar = LATB & 0xfb;
267     LATA = latchvar;
268     /* SCANLINE D*/
269     latchvar = LATB | 0x20;
270     LATB = latchvar;
271     portvar = PORTA;
272     high = (portvar & 0x3c) >>2;
273     latchvar = LATB & 0xdf;
274     LATB = latchvar;
275     /* Pos */
276     keyin_now.byte[1] = (low << 4) | high;
277
278     /* Special KEYS */
279     keyin_now.BIT0F = PORTBbits.RB1;
280     keyin_now.BIT1F = PORTBbits.RB2;
281     keyin_now.BIT2F = PORTBbits.RB3;
282     keyin_now.BIT3F = 0; // Reserve
283 }
284
285 unsigned char readkey_compare(void)
286 {
287     char b;
288     char c;
289     char d;
290     char e;
291     unsigned char shift;
292     unsigned char f;
293     f = 0;
294     e = 0;
295     for(d = 0; d < 3; d++) {
296         shift = 0x01;
297         for(b = 0; b < 8; b++){
298             c = 0;
299             if((keyin_now.byte[c] & shift) != 0) c++;
300             if((keyin_old[0].byte[c] & shift) != 0) c++;
301             if((keyin_old[1].byte[c] & shift) != 0) c++;
302             if(c >= 2) {
303             /*
304              * Clear older-inputs on .
305              */
306                 f |= 1;
307                 keyin_old[0].byte[c] &= ~shift;
308                 keyin_old[1].byte[c] &= ~shift;
309                 keyin_now.byte[c] &= ~shift;
310                 if(e == 0) {
311                     push_keyinfifo(charcode_0);
312                 } else if(e <= 15) {
313                     push_keyinfifo(b);
314                 } else if(e < 20) {
315                     push_keyinfifo(e + 1);
316                 }
317             }
318             shift <<= 1;
319             e++;
320         }
321     }
322     /**/
323     return f;
324 }
325
326 /*
327  * Notes:
328  * Initialize sequence:
329  * keyin_init();
330  * keyin_ioinit();
331  * 
332  * Read-key-sequence:
333  * In interrupt/unsleep hook(call per Nms):
334  * readkey_io();
335  * readkey_compare();
336  *
337  * In application handler:
338  * c = pop_keyinfifo();
339  * if(c != 0) do(c);
340  */