OSDN Git Service

[SCHEMATIC] Add symbol: SA612 , NXP's mixer IC.
[openi2cradio/OpenI2CRadio.git] / ui.c
diff --git a/ui.c b/ui.c
index a1b3547..07dcc0a 100644 (file)
--- a/ui.c
+++ b/ui.c
 /*
  * 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)
@@ -151,28 +293,22 @@ 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++;
@@ -182,6 +318,112 @@ unsigned char readkey_compare(void)
     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:
@@ -196,4 +438,4 @@ unsigned char readkey_compare(void)
  * In application handler:
  * c = pop_keyinfifo();
  * if(c != 0) do(c);
- */
\ No newline at end of file
+ */