/*
* OpenI2CRADIO
* UI Handler
- * (C) 2013-06-10 K.Ohta <whatisthis.sowhat ai gmail.com>
- * License: GPL2
+ * Copyright (C) 2013-06-10 K.Ohta <whatisthis.sowhat ai gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ * This library / program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; see the file COPYING. If not, write to the
+ * Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * As a special exception, if you link this(includeed from sdcc) library
+ * with other files, some of which are compiled with SDCC,
+ * to produce an executable, this library does not by itself cause
+ * the resulting executable to be covered by the GNU General Public License.
+ * This exception does not however invalidate any other reasons why
+ * the executable file might be covered by the GNU General Public License.
*/
-#include <sdcc-lib.h>
-#include <pic18fregs.h> /* ONLY FOR PIC18x */
+#include "ioports.h"
+#include "ui.h"
+#include "idle.h"
+#include "commondef.h"
+
+
+const char charcodemap[] = {charcode_0,
+ charcode_1,
+ charcode_4,
+ charcode_7,
+
+ charcode_f,
+ charcode_2,
+ charcode_5,
+ charcode_8,
+
+ charcode_e,
+ charcode_3,
+ charcode_6,
+ charcode_9,
-#include "iodef.h"
+ charcode_d,
+ charcode_c,
+ charcode_b,
+ charcode_a,
+};
+
+extern unsigned char pollkeybuf[32];
keyin_defs keyin_old[2];
keyin_defs keyin_now;
-char keyin_fifo[16];
+char keyin_fifo[32];
char keyin_nowp;
char keyin_readp;
char keyin_counter;
+unsigned char cold;
+
+// LCD Routines
+void _PUTCHAR(unsigned char c)
+{
+ acm1602_putchar(LCD_I2CADDR , c);
+}
+
+void _LOCATE(unsigned char x, unsigned char y)
+{
+ acm1602_locate_16x2(LCD_I2CADDR , x, y);
+}
+
+void _LOCATE_0_0(void)
+{
+ acm1602_locate_16x2(LCD_I2CADDR , 0, 0);
+}
+
+void _LOCATE_0_1(void)
+{
+ acm1602_locate_16x2(LCD_I2CADDR , 0, 1);
+}
+
+void _CLS(void)
+{
+ acm1602_cls(LCD_I2CADDR);
+}
+void _HOME(void)
+{
+ acm1602_home(LCD_I2CADDR);
+}
+
+void _CURSOR_ON(void)
+{
+ acm1602_dispcursor(LCD_I2CADDR, 0xff);
+}
+
+
+void _CURSOR_OFF(void)
+{
+ acm1602_dispcursor(LCD_I2CADDR, 0x00);
+}
+
+void _CURSOR_LEFT(void)
+{
+ acm1602_cursordir(LCD_I2CADDR , 0x00);
+}
+
+void _CURSOR_RIGHT(void)
+{
+ acm1602_cursordir(LCD_I2CADDR , 0xff);
+}
+
+
void keyin_init(void)
{
char i;
/* Initialize vars*/
- for(i = 0; i < 3; i++) {
+ for(i = 0; i < 2; i++) {
keyin_old[0].byte[i] = 0x00;
keyin_old[1].byte[i] = 0x00;
keyin_now.byte[i] = 0x00;
}
- for(i = 0; i < 16; i++) keyin_fifo[i] = 0x00;
+ for(i = 0; i < 32; i++) keyin_fifo[i] = 0x00;
keyin_nowp = 0;
keyin_readp = 0;
keyin_counter = 0;
-
+ cold = charcode_null;
}
-
-void keyin_ioinit(void)
-{
- /* Initialize IOPORTS*/
- PORTA = 0x00;
- LATA = 0x00;
- ANSELA = AN_A_VAL;
- TRISA = TRIS_A_VAL;
-
- PORTB = 0x00;
- LATB = 0x00;
- ANSELB = AN_B_VAL;
- TRISB = TRIS_B_VAL;
-
- PORTC = 0x00;
- LATC = 0x00;
- ANSELC = AN_C_VAL;
- TRISC = TRIS_C_VAL_O;
-}
-
/*
* Push to keyin fifo; not used atomic-writing.
*/
+#ifdef __SDCC
+void push_keyinfifo(char b) __critical
+#else
void push_keyinfifo(char b)
+#endif
{
- keyin_nowp++;
- if((keyin_nowp > 15) || (keyin_nowp < 0))keyin_nowp = 0;
+ if(keyin_counter >= 31) {
+ return; // Discard data.
+ }
keyin_fifo[keyin_nowp] = b;
+ keyin_nowp++;
keyin_counter++;
- if(keyin_counter > 16) keyin_counter = 16;
+ if(keyin_nowp > 31) keyin_nowp = 0;
}
/*
* Pop from keyin fifo; not used atomic-reading.
*/
+#ifdef __SDCC
+char pop_keyinfifo(void) __critical
+#else
char pop_keyinfifo(void)
+#endif
{
char c;
if(keyin_counter <= 0) {
keyin_counter = 0;
return charcode_null ;
}
- if(keyin_readp > 15) keyin_readp = 15;
c = keyin_fifo[keyin_readp];
keyin_readp++;
- if(keyin_readp > 15) keyin_readp = 0;
keyin_counter--;
- if(keyin_counter < 0)keyin_counter = 0;
+ if(keyin_readp > 31) keyin_readp = 0;
return c;
}
+void printstr(const char *s)
+{
+ int p = 0;
+// _CURSOR_RIGHT();
+ if(s == NULL) return;
+ do {
+ if(s[p] == '\0') break;
+ _PUTCHAR(s[p]);
+ p++;
+ } while(p < 32);
+}
+
+
+static void uint2bcd(unsigned long data, unsigned char *bcd)
+{
+ unsigned char i;
+ unsigned char j;
+
+ for(i = 0; i <= 10; i++){
+ bcd[i] = data % 10;
+ data = data / 10;
+ }
+ bcd[10] = 0;
+}
+
+void print_numeric_nosupress(unsigned long data, unsigned char digit)
+{
+ unsigned char i;
+ unsigned char bcd[11];
+
+ if(digit == 0) return;
+ if(digit > 10) digit = 10;
+ uint2bcd(data, bcd);
+ for(i = digit; i > 0; i--){
+ _PUTCHAR('0' + bcd[i - 1]);
+ }
+}
/*
- * Read IOPORTS for KEY.
+ * Read Numeric(int)
*/
-void readkey_io(void)
+unsigned long subst_numeric(unsigned long start, unsigned char pos, unsigned char c)
{
+ unsigned long val;
+ unsigned char bcd[11];
char i;
- unsigned char portvar;
- unsigned char latchvar;
- unsigned char high;
- unsigned char low;
- if(keyin_counter > 16) keyin_counter = 0;
- for(i = 0; i < 3; i++){
- keyin_old[1].byte[i] = keyin_old[0].byte[i];
- keyin_old[0].byte[i] = keyin_now.byte[i];
- keyin_now.byte[i] = 0x00;
- }
- /* SCANLINE A*/
- latchvar = LATA | 0x02;
- LATA = latchvar;
- portvar = PORTA;
- low = (portvar & 0x3c) >>2;
- latchvar = LATA & 0xfd;
- LATA = latchvar;
- /* SCANLINE B*/
- latchvar = LATB | 0x02;
- LATB = latchvar;
- portvar = PORTA;
- high = (portvar & 0x3c) >>2;
- latchvar = LATB & 0xfd;
- LATB = latchvar;
- /* Pos */
- keyin_now.byte[0] = (low << 4) | high;
-
- /* SCANLINE C*/
- latchvar = LATB | 0x04;
- LATA = latchvar;
- portvar = PORTA;
- low = (portvar & 0x3c) >>2;
- latchvar = LATB & 0xfb;
- LATA = latchvar;
- /* SCANLINE D*/
- latchvar = LATB | 0x20;
- LATB = latchvar;
- portvar = PORTA;
- high = (portvar & 0x3c) >>2;
- latchvar = LATB & 0xdf;
- LATB = latchvar;
- /* Pos */
- keyin_now.byte[1] = (low << 4) | high;
-
- /* Special KEYS */
- keyin_now.BIT0F = PORTBbits.RB1;
- keyin_now.BIT1F = PORTBbits.RB2;
- keyin_now.BIT2F = PORTBbits.RB3;
- keyin_now.BIT3F = 0; // Reserve
+ unsigned long fact;
+
+ if(pos > 10) pos = 10;
+ uint2bcd(start, bcd);
+ bcd[pos] = c;
+
+ fact = 1;
+ val = 0;
+ for(i = 0; i < 11; i++){
+ val = val + (bcd[i] * fact);
+ fact = fact * 10;
+ }
+ return val;
+}
+
+unsigned long read_numeric(unsigned int initial, unsigned char digit,
+ char startx, char starty)
+{
+ unsigned char c;
+ unsigned char n;
+ char i;
+ unsigned long val;
+ unsigned long v;
+ char d;
+
+ d = digit - 1;
+ val =(unsigned long) initial;
+ i = d;
+ do {
+// _CURSOR_OFF();
+ ClrWdt();
+ _LOCATE(startx, starty);
+ print_numeric_nosupress(val, digit);
+ ClrWdt();
+ _LOCATE(startx + d - i, starty);
+ _CURSOR_ON();
+
+ c = pollkey_single();
+ if(c == charcode_0){
+ val = subst_numeric(val, i, 0);
+ i--;
+ } else if((c >= charcode_1) && (c <= charcode_9)) {
+ val = subst_numeric(val, i, c - charcode_1 + 1);
+ i--;
+ } else if(c == charcode_f) {
+ // Enter
+ break;
+ } else if(c == charcode_a) {
+ // Del
+ val = val / 10;
+ i++;
+ } else if(c == charcode_b) {
+ // cancel
+ _CURSOR_OFF();
+ return 0xffffffff;
+ } else if(c == charcode_e) {
+ i++;
+ } else if(c == charcode_d) {
+ i--;
+ }
+ if(i <= 0) i = 0;
+ if(i > d) i = d;
+ } while(1);
+ _CURSOR_OFF();
+ if(val > 0x7fffffff) val = 0x7fffffff;
+ return val;
}
unsigned char readkey_compare(void)
unsigned char f;
f = 0;
e = 0;
- for(d = 0; d < 3; d++) {
+ for(d = 0; d < 2; d++) {
shift = 0x01;
for(b = 0; b < 8; b++){
c = 0;
- if((keyin_now.byte[c] & shift) != 0) c++;
- if((keyin_old[0].byte[c] & shift) != 0) c++;
- if((keyin_old[1].byte[c] & shift) != 0) c++;
+ if((keyin_now.byte[d] & shift) != 0) c++;
+ if((keyin_old[0].byte[d] & shift) != 0) c++;
+ if((keyin_old[1].byte[d] & shift) != 0) c++;
if(c >= 2) {
/*
* Clear older-inputs on .
*/
f |= 1;
- keyin_old[0].byte[c] &= ~shift;
- keyin_old[1].byte[c] &= ~shift;
- keyin_now.byte[c] &= ~shift;
- if(e == 0) {
- push_keyinfifo(charcode_0);
- } else if(e <= 15) {
- push_keyinfifo(b);
- } else if(e < 20) {
- push_keyinfifo(e + 1);
- }
+ keyin_old[0].byte[d] &= ~shift;
+ keyin_old[1].byte[d] &= ~shift;
+ keyin_now.byte[d] &= ~shift;
+ push_keyinfifo(charcodemap[e]);
}
shift <<= 1;
e++;
return f;
}
+unsigned char readkey(void)
+{
+ unsigned char i;
+ for(i = 0; i < 9; i++) {
+ idle_time_ms(2); // 2ms
+ readkey_io(i);
+// ClrWdt();
+ }
+ readkey_compare();
+ return pop_keyinfifo();
+}
+
+
+unsigned char pollkey_single(void)
+{
+ unsigned int penalty = 0;
+ unsigned char c;
+
+// cold = charcode_null;
+ do {
+ idle_time_ms(5); // 5ms.
+ c = readkey(); // 2 * 9 = 18ms
+ ClrWdt();
+ if(c != charcode_null) {
+ if(cold != c){
+ cold = c;
+ return c;
+ }
+ penalty = 0;
+ } else {
+ penalty++;
+ if(penalty > 4) {
+ penalty = 0;
+ cold = charcode_null; // About 100ms
+ }
+ }
+ } while(1);
+}
+
+
+unsigned char pollkey_numeric(unsigned char init)
+{
+ unsigned char c;
+ _PUTCHAR('0' + init);
+ c = pollkey_single();
+ if(c == charcode_0) {
+ return 0;
+ } else if((c >= charcode_1) && (c <= charcode_9)){
+ return c;
+ } else {
+ return init;
+ }
+}
+
+unsigned char pollkey_single_timeout(unsigned char limit, unsigned char repeat)
+{
+ unsigned char c;
+ unsigned char ticks = 0;
+ unsigned char penalty = 0;
+ unsigned char count = 0;
+
+
+ cold = charcode_null;
+ pollkeybuf[0] = charcode_null;
+ do {
+ if(limit != 0) {
+ ticks++;
+ if(ticks > limit) {
+ break;
+ }
+ }
+ idle_time_ms(5); // 5ms.
+ c = readkey(); // 2 * 9 = 18ms
+ ClrWdt();
+ ticks++;
+ if(c != charcode_null){
+ if(cold != c) {
+ pollkeybuf[count++] = c;
+ cold = c;
+ count++;
+ if(repeat == 0) {
+ break;
+ }
+ penalty = 0;
+ }
+ } else {
+ penalty++;
+ if(penalty > 4){
+ penalty = 0;
+ cold = charcode_null;
+ }
+ }
+ } while(count < 32);
+
+ /*
+ * Set Deadzone.
+ */
+ if(limit != 0) {
+ while(ticks <= limit) {
+ idle_time_ms(5 + 18);
+ ticks++;
+ }
+ }
+ c = pollkeybuf[0];
+ return c;
+}
/*
* Notes:
* Initialize sequence:
* In application handler:
* c = pop_keyinfifo();
* if(c != 0) do(c);
- */
\ No newline at end of file
+ */