/****************************************************************************
kbd.c
v1.0 (10/02/2003)
Generic keyboard scan driver. This driver can scan up to 64 keys.
Input and output may be on the same resister. In this case you can scan
up to 16 keys.
You can use one register for output and an other for input. Yon can scan
in this case up to 64 keys.
Written by Philippe Corbes <philippe.corbes@laposte.net>
This code is free for personal use.
You need my agreement for a commercial use.
USAGE:
kbd_Getc(c) Will return a key value if pressed or /0 if not
This function should be called frequently so as
not to miss a key press.
****************************************************************************/
#include <pic.h>
#include "kbd.h" // Constantes definitions
#include "kbd_keys.h" // Keyboard map definitions
#if KBD_LINES == 1
#define ALL_LINES (LINE0)
#elif KBD_LINES == 2
#define ALL_LINES (LINE0|LINE1)
#elif KBD_LINES == 3
#define ALL_LINES (LINE0|LINE1|LINE2)
#elif KBD_LINES == 4
#define ALL_LINES (LINE0|LINE1|LINE2|LINE3)
#elif KBD_LINES == 5
#define ALL_LINES (LINE0|LINE1|LINE2|LINE3|LINE4)
#elif KBD_LINES == 6
#define ALL_LINES (LINE0|LINE1|LINE2|LINE3|LINE4|LINE5)
#elif KBD_LINES == 7
#define ALL_LINES (LINE0|LINE1|LINE2|LINE3|LINE4|LINE5|LINE6)
#elif KBD_LINES == 8
#define ALL_LINES (LINE0|LINE1|LINE2|LINE3|LINE4|LINE5|LINE6|LINE7)
#else
#warning KBD_LINES is greater than 8
#endif
#if (KBD_IO == 1)
#if KBD_COLS == 1
#define ALL_COLS (ALL_LINES|COL0)
#elif KBD_COLS == 2
#define ALL_COLS (ALL_LINES|COL0|COL1)
#elif KBD_COLS == 3
#define ALL_COLS (ALL_LINES|COL0|COL1|COL2)
#elif KBD_COLS == 4
#define ALL_COLS (ALL_LINES|COL0|COL1|COL2|COL3)
#elif KBD_COLS == 5
#define ALL_COLS (ALL_LINES|COL0|COL1|COL2|COL3|COL4)
#elif KBD_COLS == 6
#define ALL_COLS (ALL_LINES|COL0|COL1|COL2|COL3|COL4|COL5)
#elif KBD_COLS == 7
#define ALL_COLS (ALL_LINES|COL0|COL1|COL2|COL3|COL4|COL5|COL6)
#elif KBD_COLS == 8
#define ALL_COLS (ALL_LINES|COL0|COL1|COL2|COL3|COL4|COL5|COL6|COL7)
#else
#warning KBD_COLS is greater than 8
#endif
#else
#if KBD_COLS == 1
#define ALL_COLS (COL0)
#elif KBD_COLS == 2
#define ALL_COLS (COL0|COL1)
#elif KBD_COLS == 3
#define ALL_COLS (COL0|COL1|COL2)
#elif KBD_COLS == 4
#define ALL_COLS (COL0|COL1|COL2|COL3)
#elif KBD_COLS == 5
#define ALL_COLS (COL0|COL1|COL2|COL3|COL4)
#elif KBD_COLS == 6
#define ALL_COLS (COL0|COL1|COL2|COL3|COL4|COL5)
#elif KBD_COLS == 7
#define ALL_COLS (COL0|COL1|COL2|COL3|COL4|COL5|COL6)
#elif KBD_COLS == 8
#define ALL_COLS (COL0|COL1|COL2|COL3|COL4|COL5|COL6|COL7)
#else
#warning KBD_COLS is greater than 8
#endif
#endif
char kbd_Getc() {
static unsigned int kbd_count;
static short int kbd_down;
static unsigned char col;
unsigned char kchar;
unsigned char row;
kchar='\0';
if(++kbd_count>KBD_DEBOUNCE_FACTOR) {
#if (KBD_IO == 2)
kbd_lc |= ALL_LINES;
#endif
switch (col) {
#ifdef KBD_COLS
case 0 :
#if (ALL_COLS == 0xff)
kbd_cc = ~COL0;
kbd_c = COL0;
#else
kbd_cc = (kbd_cc&~ALL_COLS)|(ALL_COLS&~COL0);
kbd_c = (kbd_c&~ALL_COLS)|COL0;
#endif
break;
#if KBD_COLS > 1
case 1 :
#if (ALL_COLS == 0xff)
kbd_cc = ~COL1;
kbd_c = COL1;
#else
kbd_cc = (kbd_cc&~ALL_COLS)|(ALL_COLS&~COL1);
kbd_c = (kbd_c&~ALL_COLS)|COL1;
#endif
break;
#if KBD_COLS > 2
case 2 :
#if (ALL_COLS == 0xff)
kbd_cc = ~COL2;
kbd_c = COL2;
#else
kbd_cc = (kbd_cc&~ALL_COLS)|(ALL_COLS&~COL2);
kbd_c = (kbd_c&~ALL_COLS)|COL2;
#endif
break;
#if KBD_COLS > 3
case 3 :
#if (ALL_COLS == 0xff)
kbd_cc = ~COL3;
kbd_c = COL3;
#else
kbd_cc = (kbd_cc&~ALL_COLS)|(ALL_COLS&~COL3);
kbd_c = (kbd_c&~ALL_COLS)|COL3;
#endif
break;
#if KBD_COLS > 4
case 4 :
#if (ALL_COLS == 0xff)
kbd_cc = ~COL4;
kbd_c = COL4;
#else
kbd_cc = (kbd_cc&~ALL_COLS)|(ALL_COLS&~COL4);
kbd_c = (kbd_c&~ALL_COLS)|COL4;
#endif
break;
#if KBD_COLS > 5
case 5 :
#if (ALL_COLS == 0xff)
kbd_cc = ~COL5;
kbd_c = COL5;
#else
kbd_cc = (kbd_cc&~ALL_COLS)|(ALL_COLS&~COL5);
kbd_c = (kbd_c&~ALL_COLS)|COL5;
#endif
break;
#if KBD_COLS > 6
case 6 :
#if (ALL_COLS == 0xff)
kbd_cc = ~COL6;
kbd_c = COL6;
#else
kbd_cc = (kbd_cc&~ALL_COLS)|(ALL_COLS&~COL6);
kbd_c = (kbd_c&~ALL_COLS)|COL6;
#endif
break;
#if KBD_COLS > 7
case 7 :
#if (ALL_COLS == 0xff)
kbd_cc = ~COL7;
kbd_c = COL7;
#else
kbd_cc = (kbd_cc&~ALL_COLS)|(ALL_COLS&~COL7);
kbd_c = (kbd_c&~ALL_COLS)|COL7;
#endif
break;
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#endif
}
if(kbd_down!=0) {
// Wait for key up
kbd_down = kbd_l & ALL_LINES;
} else {
if((kbd_l & (ALL_LINES))!=0) {
#ifdef KBD_LINES
if((kbd_l & LINE0)!=0)
row = 0;
#if KBD_LINES > 1
else if((kbd_l & LINE1)!=0)
row = 1;
#if KBD_LINES > 2
else if((kbd_l & LINE2)!=0)
row = 2;
#if KBD_LINES > 3
else if((kbd_l & LINE3)!=0)
row = 3;
#if KBD_LINES > 4
else if((kbd_l & LINE4)!=0)
row = 4;
#if KBD_LINES > 5
else if((kbd_l & LINE5)!=0)
row = 5;
#if KBD_LINES > 6
else if((kbd_l & LINE6)!=0)
row = 6;
#if KBD_LINES > 7
else if((kbd_l & LINE7)!=0)
row = 7;
#endif
#endif
#endif
#endif
#endif
#endif
#endif
kchar = KEYS[row][col];
kbd_down = 1;
#endif
} else {
++col;
if(col==KBD_COLS)
col = 0;
}
}
kbd_count = 0;
}
kbd_cc |= ALL_COLS;
return(kchar);
}