4 * Copyright (C) 2013-06-10 K.Ohta <whatisthis.sowhat ai gmail.com>
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.
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,
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.
31 #include "commondef.h"
34 const char charcodemap[] = {charcode_0,
55 extern unsigned char pollkeybuf[32];
57 keyin_defs keyin_old[2];
67 void _PUTCHAR(unsigned char c)
69 acm1602_putchar(LCD_I2CADDR , c);
72 void _LOCATE(unsigned char x, unsigned char y)
74 acm1602_locate_16x2(LCD_I2CADDR , x, y);
77 void _LOCATE_0_0(void)
79 acm1602_locate_16x2(LCD_I2CADDR , 0, 0);
82 void _LOCATE_0_1(void)
84 acm1602_locate_16x2(LCD_I2CADDR , 0, 1);
89 acm1602_cls(LCD_I2CADDR);
93 acm1602_home(LCD_I2CADDR);
98 acm1602_dispcursor(LCD_I2CADDR, 0xff);
102 void _CURSOR_OFF(void)
104 acm1602_dispcursor(LCD_I2CADDR, 0x00);
107 void _CURSOR_LEFT(void)
109 acm1602_cursordir(LCD_I2CADDR , 0x00);
112 void _CURSOR_RIGHT(void)
114 acm1602_cursordir(LCD_I2CADDR , 0xff);
118 void keyin_init(void)
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;
127 for(i = 0; i < 32; i++) keyin_fifo[i] = 0x00;
131 cold = charcode_null;
134 * Push to keyin fifo; not used atomic-writing.
137 void push_keyinfifo(char b) __critical
139 void push_keyinfifo(char b)
142 if(keyin_counter >= 31) {
143 return; // Discard data.
145 keyin_fifo[keyin_nowp] = b;
148 if(keyin_nowp > 31) keyin_nowp = 0;
152 * Pop from keyin fifo; not used atomic-reading.
155 char pop_keyinfifo(void) __critical
157 char pop_keyinfifo(void)
161 if(keyin_counter <= 0) {
163 return charcode_null ;
165 c = keyin_fifo[keyin_readp];
168 if(keyin_readp > 31) keyin_readp = 0;
172 void printstr(const char *s)
176 if(s == NULL) return;
178 if(s[p] == '\0') break;
186 static void uint2bcd(unsigned long data, unsigned char *bcd)
191 for(i = 0; i <= 10; i++){
198 void print_numeric_nosupress(unsigned long data, unsigned char digit)
201 unsigned char bcd[11];
203 if(digit == 0) return;
204 if(digit > 10) digit = 10;
206 for(i = digit; i > 0; i--){
207 _PUTCHAR('0' + bcd[i - 1]);
213 unsigned long subst_numeric(unsigned long start, unsigned char pos, unsigned char c)
216 unsigned char bcd[11];
220 if(pos > 10) pos = 10;
221 uint2bcd(start, bcd);
226 for(i = 0; i < 11; i++){
227 val = val + (bcd[i] * fact);
233 unsigned long read_numeric(unsigned int initial, unsigned char digit,
234 char startx, char starty)
244 val =(unsigned long) initial;
249 _LOCATE(startx, starty);
250 print_numeric_nosupress(val, digit);
252 _LOCATE(startx + d - i, starty);
255 c = pollkey_single();
257 val = subst_numeric(val, i, 0);
259 } else if((c >= charcode_1) && (c <= charcode_9)) {
260 val = subst_numeric(val, i, c - charcode_1 + 1);
262 } else if(c == charcode_f) {
265 } else if(c == charcode_a) {
269 } else if(c == charcode_b) {
273 } else if(c == charcode_e) {
275 } else if(c == charcode_d) {
282 if(val > 0x7fffffff) val = 0x7fffffff;
286 unsigned char readkey_compare(void)
296 for(d = 0; d < 2; d++) {
298 for(b = 0; b < 8; b++){
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++;
305 * Clear older-inputs on .
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]);
321 unsigned char readkey(void)
324 for(i = 0; i < 9; i++) {
325 idle_time_ms(2); // 2ms
330 return pop_keyinfifo();
334 unsigned char pollkey_single(void)
336 unsigned int penalty = 0;
339 // cold = charcode_null;
341 idle_time_ms(5); // 5ms.
342 c = readkey(); // 2 * 9 = 18ms
344 if(c != charcode_null) {
354 cold = charcode_null; // About 100ms
361 unsigned char pollkey_numeric(unsigned char init)
364 _PUTCHAR('0' + init);
365 c = pollkey_single();
366 if(c == charcode_0) {
368 } else if((c >= charcode_1) && (c <= charcode_9)){
375 unsigned char pollkey_single_timeout(unsigned char limit, unsigned char repeat)
378 unsigned char ticks = 0;
379 unsigned char penalty = 0;
380 unsigned char count = 0;
383 cold = charcode_null;
384 pollkeybuf[0] = charcode_null;
392 idle_time_ms(5); // 5ms.
393 c = readkey(); // 2 * 9 = 18ms
396 if(c != charcode_null){
398 pollkeybuf[count++] = c;
410 cold = charcode_null;
419 while(ticks <= limit) {
420 idle_time_ms(5 + 18);
429 * Initialize sequence:
434 * In interrupt/unsleep hook(call per Nms):
438 * In application handler:
439 * c = pop_keyinfifo();