bugfix for keys

- initialize count, so that there is no initial keypress at powerup
- use int8_t instead of uint32_t to pass new key, since only 1 new key
used
This commit is contained in:
Jeff Wang 2019-04-01 01:55:47 -04:00
parent 8aec2ae134
commit f5d8d601a2
3 changed files with 212 additions and 198 deletions

View File

@ -9,7 +9,15 @@
#include "utils.h" #include "utils.h"
#include "key.h" #include "key.h"
#ifndef DESKTOP #ifdef DESKTOP
#include <stdio.h>
const char state_names[4][32] = {
"STEADY_LOW" ,
"TRANS_LOW_HIGH",
"STEADY_HIGH" ,
"TRANS_HIGH_LOW"
};
#else
#include "stc15.h" #include "stc15.h"
#endif #endif
@ -17,7 +25,7 @@
#define M_COLS 4 #define M_COLS 4
uint8_t Keys[TOTAL_ROWS]; //only bottom nibbles get set uint8_t Keys[TOTAL_ROWS]; //only bottom nibbles get set
static uint32_t new_keys_pressed; //bottom 20 bits get set int8_t NewKeyPressed; //row*M_COLS + col, see KEY_MAP[] in main.c
static uint8_t last_state[TOTAL_ROWS]; //all used, 2 bits per key static uint8_t last_state[TOTAL_ROWS]; //all used, 2 bits per key
static int8_t last_count[TOTAL_ROWS][M_COLS]; //all used static int8_t last_count[TOTAL_ROWS][M_COLS]; //all used
static uint8_t unexpected_count; //count of unexpected transitions static uint8_t unexpected_count; //count of unexpected transitions
@ -35,7 +43,14 @@ static const int8_t THRESH_TRANS = 2;
#ifdef DESKTOP #ifdef DESKTOP
//test functions //test functions
void KeyInit(void){} void KeyInit(void){
//initialize counts
for (uint8_t i = 0; i < TOTAL_ROWS; i++){
for (uint8_t j = 0; j < M_COLS; j++){
last_count[i][j] = COUNT_LIM_LOW;
}
}
}
static void raw_scan(void){ static void raw_scan(void){
static uint8_t i = 0; static uint8_t i = 0;
@ -49,7 +64,7 @@ static void raw_scan(void){
0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0
}; };
keys[1] = data[i]; Keys[1] = data[i];
i++; i++;
if (i >= (sizeof(data)/sizeof(data[0]))){ if (i >= (sizeof(data)/sizeof(data[0]))){
i = 0; i = 0;
@ -57,6 +72,8 @@ static void raw_scan(void){
} }
#else #else
void KeyInit(void){ void KeyInit(void){
uint8_t i, j;
//set column drivers bits 7:4 to quasi-bidirectional w/ pullup M[1:0]=b00 //set column drivers bits 7:4 to quasi-bidirectional w/ pullup M[1:0]=b00
//and row inputs bits 3:0 to quasi-bidirectional w/ pullup M[1:0]=b00 //and row inputs bits 3:0 to quasi-bidirectional w/ pullup M[1:0]=b00
P1M1 = 0x00; P1M1 = 0x00;
@ -73,6 +90,13 @@ void KeyInit(void){
P5M1 &= ~(0x30); P5M1 &= ~(0x30);
P5M0 &= ~(0x30); P5M0 &= ~(0x30);
P5 |= 0x30; //pull up P5 |= 0x30; //pull up
//initialize counts
for (i = 0; i < TOTAL_ROWS; i++){
for (j = 0; j < M_COLS; j++){
last_count[i][j] = COUNT_LIM_LOW;
}
}
} }
static void raw_scan(void){ static void raw_scan(void){
@ -112,7 +136,8 @@ static void raw_scan(void){
//https://summivox.wordpress.com/2016/06/03/keyboard-matrix-scanning-and-debouncing/ //https://summivox.wordpress.com/2016/06/03/keyboard-matrix-scanning-and-debouncing/
static void debounce(void){ static void debounce(void){
uint8_t i, j; uint8_t i, j;
new_keys_pressed = 0; //initially NewKeyPressed = -1; //initially
// new_keys_pressed = 0; //initially
for (i = 0; i < TOTAL_ROWS; i++){ for (i = 0; i < TOTAL_ROWS; i++){
for (j = 0; j < M_COLS; j++){ for (j = 0; j < M_COLS; j++){
int8_t new_count; int8_t new_count;
@ -180,9 +205,14 @@ static void debounce(void){
new_count = COUNT_LIM_LOW; new_count = COUNT_LIM_LOW;
unexpected_count++; unexpected_count++;
} //switch(curr_state) } //switch(curr_state)
//track new keys down //track new key down
if (curr_state != TRANS_LOW_HIGH && new_state == TRANS_LOW_HIGH){ if (curr_state != TRANS_LOW_HIGH && new_state == TRANS_LOW_HIGH){
new_keys_pressed |= ((uint32_t) 1 << (i*M_COLS + j)); NewKeyPressed = (i*M_COLS + j); //can only track 1 for now
#ifdef DESKTOP
printf("new key (%d, %d) pressed\n", i, j);
// printf("curr_state: %d, new_state: %d\n", curr_state, new_state);
#endif
// new_keys_pressed |= ((uint32_t) 1 << (i*M_COLS + j));
} }
//write back new count //write back new count
last_count[i][j] = new_count; last_count[i][j] = new_count;
@ -204,33 +234,29 @@ const uint8_t* DebugGetKeys(void){
} }
#endif #endif
const uint32_t GetNewKeys(void){
return new_keys_pressed;
}
#ifdef DESKTOP #ifdef DESKTOP
#include <stdio.h>
const char state_names[4][32] = {
"STEADY_LOW" ,
"TRANS_LOW_HIGH",
"STEADY_HIGH" ,
"TRANS_HIGH_LOW"
};
int main(void){ int main(void){
KeyInit();
for (int iii = 0; iii < 100; iii++){ for (int iii = 0; iii < 100; iii++){
KeyScan(); //look at '9' key at row 1, col 1 (0 indexed)
const uint8_t* keys = DebugGetKeys(); //the corresponding new key code is 5, see KEY_MAP[] in main.c
static const uint8_t i = 1, j = 1; static const uint8_t i = 1, j = 1;
uint8_t curr_count = last_count[i][j/2] & (0xf << ((j&1)*4)); int8_t curr_count = last_count[i][j/2] & (0xf << ((j&1)*4));
uint8_t curr_state = last_state[i] & (0x3 << (j*2)); uint8_t curr_state = last_state[i] & (0x3 << (j*2));
curr_count >>= (j&1)*4; curr_count >>= (j&1)*4;
curr_state >>= j*2; curr_state >>= j*2;
printf("%3d: %x, %14s, %2u, %2lx\n", if (iii == 0){
iii, keys[1], state_names[curr_state], curr_count, (unsigned long) GetNewKeys()); printf("%3d: %x, %14s, %2d, %2d\n",
iii, Keys[1], state_names[curr_state], curr_count, NewKeyPressed);
}
KeyScan();
printf("%3d: %x, %14s, %2d, %2d\n",
iii, Keys[1], state_names[curr_state], curr_count, NewKeyPressed);
} }
return 0; return 0;

View File

@ -21,6 +21,7 @@ const uint8_t* DebugGetKeys(void);
//prefer using GetNewKeys(); //prefer using GetNewKeys();
#define TOTAL_ROWS 5 #define TOTAL_ROWS 5
extern uint8_t Keys[TOTAL_ROWS]; //only bottom nibbles get set extern uint8_t Keys[TOTAL_ROWS]; //only bottom nibbles get set
extern int8_t NewKeyPressed;
#endif /* SRC_KEY_H_ */ #endif /* SRC_KEY_H_ */

View File

@ -22,7 +22,7 @@ static const char KEY_MAP[20] = {
}; };
uint32_t NewKeyBuf[4]; int8_t NewKeyBuf[4];
volatile uint8_t new_key_write_i; volatile uint8_t new_key_write_i;
volatile uint8_t new_key_read_i; volatile uint8_t new_key_read_i;
volatile uint8_t NewKeyEmpty; volatile uint8_t NewKeyEmpty;
@ -37,17 +37,14 @@ void timer0_isr() SDCC_ISR(1,1)
static uint8_t min_count = 0, hour_count = 0; static uint8_t min_count = 0, hour_count = 0;
#endif #endif
uint32_t new_keys;
//scan keyboard //scan keyboard
KeyScan(); KeyScan();
new_keys = GetNewKeys(); if (NewKeyPressed != -1){
if (new_keys != 0){
if (!NewKeyEmpty && (new_key_write_i == new_key_read_i)){ if (!NewKeyEmpty && (new_key_write_i == new_key_read_i)){
//do not overwrite keymap currently being processed //do not overwrite keymap currently being processed
INCR_NEW_KEY_I(new_key_write_i); INCR_NEW_KEY_I(new_key_write_i);
} }
NewKeyBuf[new_key_write_i] = new_keys; NewKeyBuf[new_key_write_i] = NewKeyPressed;
INCR_NEW_KEY_I(new_key_write_i); INCR_NEW_KEY_I(new_key_write_i);
NewKeyEmpty = 0; NewKeyEmpty = 0;
} }
@ -200,185 +197,175 @@ int main()
#endif //DEBUG_KEYS #endif //DEBUG_KEYS
///get new keys ///get new key
if (!NewKeyEmpty){ if (!NewKeyEmpty){
uint8_t i_key; int8_t i_key = NewKeyBuf[new_key_read_i];
uint32_t new_keys = NewKeyBuf[new_key_read_i];
INCR_NEW_KEY_I(new_key_read_i); INCR_NEW_KEY_I(new_key_read_i);
if (new_key_read_i == new_key_write_i){ if (new_key_read_i == new_key_write_i){
NewKeyEmpty = 1; NewKeyEmpty = 1;
} }
#ifdef DEBUG_KEYS #ifdef DEBUG_KEYS
LCD_GoTo(1,j); LCD_GoTo(1,j);
TERMIO_PutChar(KEY_MAP[i_key]);
j++;
j &= 0x0f;
#endif #endif
//find first key pressed in array (if any) //process key
for (i_key = 0; i_key < 20; i_key++){ switch(KEY_MAP[i_key]){
if (new_keys & ((uint32_t) 1 << i_key)){ //////////
#ifdef DEBUG_KEYS case '0': {
TERMIO_PutChar(KEY_MAP[i_key]); if (entering_exp >= ENTERING_EXP){
j++; if (exp_i == 0){
j &= 0x0f; ExpBuf[0] = 0;
#endif exp_i = 1;
//process key } else {
switch(KEY_MAP[i_key]){ ExpBuf[1] = ExpBuf[0];
////////// ExpBuf[0] = 0;
case '0': { exp_i++;
if (entering_exp >= ENTERING_EXP){ if (exp_i > 2){
if (exp_i == 0){ exp_i = 1;
ExpBuf[0] = 0;
exp_i = 1;
} else {
ExpBuf[1] = ExpBuf[0];
ExpBuf[0] = 0;
exp_i++;
if (exp_i > 2){
exp_i = 1;
}
}
} else if (entering_exp == ENTERING_DONE){
entering_exp = ENTERING_SIGNIF;
EntryBuf[entry_i] = KEY_MAP[i_key];
//do not increment entry_i from 0, until first non-0 entry
} else if (entry_i != 0 && entry_i < MAX_CHARS_PER_LINE - 1 + 1){
EntryBuf[entry_i] = KEY_MAP[i_key];
entry_i++;
} }
} break; }
////////// } else if (entering_exp == ENTERING_DONE){
case '1': //fallthrough entering_exp = ENTERING_SIGNIF;
case '2': //fallthrough EntryBuf[entry_i] = KEY_MAP[i_key];
case '3': //fallthrough //do not increment entry_i from 0, until first non-0 entry
case '4': //fallthrough } else if (entry_i != 0 && entry_i < MAX_CHARS_PER_LINE - 1 + 1){
case '5': //fallthrough EntryBuf[entry_i] = KEY_MAP[i_key];
case '6': //fallthrough entry_i++;
case '7': //fallthrough }
case '8': //fallthrough } break;
case '9': { //////////
if (entering_exp >= ENTERING_EXP){ case '1': //fallthrough
if (exp_i == 0){ case '2': //fallthrough
ExpBuf[0] = KEY_MAP[i_key] - '0'; case '3': //fallthrough
exp_i = 1; case '4': //fallthrough
} else { case '5': //fallthrough
ExpBuf[1] = ExpBuf[0]; case '6': //fallthrough
ExpBuf[0] = KEY_MAP[i_key] - '0'; case '7': //fallthrough
exp_i++; case '8': //fallthrough
if (exp_i > 2){ case '9': {
exp_i = 1; if (entering_exp >= ENTERING_EXP){
} if (exp_i == 0){
} ExpBuf[0] = KEY_MAP[i_key] - '0';
} else if (entering_exp == ENTERING_DONE){ exp_i = 1;
entering_exp = ENTERING_SIGNIF; } else {
EntryBuf[entry_i] = KEY_MAP[i_key]; ExpBuf[1] = ExpBuf[0];
entry_i++; ExpBuf[0] = KEY_MAP[i_key] - '0';
} else if (entry_i < MAX_CHARS_PER_LINE - 1 + 1){ exp_i++;
EntryBuf[entry_i] = KEY_MAP[i_key]; if (exp_i > 2){
entry_i++; exp_i = 1;
} }
} break; }
////////// } else if (entering_exp == ENTERING_DONE){
case '.': { entering_exp = ENTERING_SIGNIF;
if (entering_exp == ENTERING_DONE){ EntryBuf[entry_i] = KEY_MAP[i_key];
EntryBuf[entry_i++] = '0'; entry_i++;
EntryBuf[entry_i++] = '.'; } else if (entry_i < MAX_CHARS_PER_LINE - 1 + 1){
entering_exp = ENTERING_FRAC; EntryBuf[entry_i] = KEY_MAP[i_key];
} else if (entering_exp == ENTERING_SIGNIF){ entry_i++;
if (entry_i == 0){ }
EntryBuf[entry_i++] = '0'; } break;
} //////////
EntryBuf[entry_i++] = '.'; case '.': {
entering_exp = ENTERING_FRAC; if (entering_exp == ENTERING_DONE){
} else if (entering_exp <= ENTERING_EXP) { EntryBuf[entry_i++] = '0';
entering_exp++; EntryBuf[entry_i++] = '.';
} else { //entering_exp == ENTERING_EXP_NEG entering_exp = ENTERING_FRAC;
entering_exp = ENTERING_EXP; } else if (entering_exp == ENTERING_SIGNIF){
} if (entry_i == 0){
} break; EntryBuf[entry_i++] = '0';
////////// }
case '=': { EntryBuf[entry_i++] = '.';
//track stack lift entering_exp = ENTERING_FRAC;
if (entering_exp != ENTERING_DONE){ } else if (entering_exp <= ENTERING_EXP) {
//finish entry entering_exp++;
int8_t exponent; //exponent is only 2 digits } else { //entering_exp == ENTERING_EXP_NEG
exponent = 10*ExpBuf[1] + ExpBuf[0]; entering_exp = ENTERING_EXP;
if (entering_exp == ENTERING_EXP_NEG){ }
exponent = -exponent; } break;
} //////////
EntryBuf[entry_i] = '\0'; case '=': {
push_decn(EntryBuf, exponent, no_lift); //track stack lift
process_cmd(KEY_MAP[i_key]); if (entering_exp != ENTERING_DONE){
//reset state as initial ENTERING_DONE state //finish entry
entering_exp = ENTERING_DONE; int8_t exponent; //exponent is only 2 digits
entry_i = 0; exponent = 10*ExpBuf[1] + ExpBuf[0];
exp_i = 0; if (entering_exp == ENTERING_EXP_NEG){
ExpBuf[0] = 0; exponent = -exponent;
ExpBuf[1] = 0; }
} else { EntryBuf[entry_i] = '\0';
//dup push_decn(EntryBuf, exponent, no_lift);
process_cmd(KEY_MAP[i_key]); process_cmd(KEY_MAP[i_key]);
} //reset state as initial ENTERING_DONE state
no_lift = 1; entering_exp = ENTERING_DONE;
} break; entry_i = 0;
////////// exp_i = 0;
case 'c': { ExpBuf[0] = 0;
if (entering_exp == ENTERING_DONE){ ExpBuf[1] = 0;
//clear } else {
clear_x(); //dup
no_lift = 1; process_cmd(KEY_MAP[i_key]);
entering_exp = ENTERING_SIGNIF; }
EntryBuf[entry_i] = '0'; no_lift = 1;
//do not increment entry_i from 0, until first non-0 entry } break;
} else if (entering_exp >= ENTERING_EXP){ //////////
//go back to digit entry case 'c': {
entering_exp--; if (entering_exp == ENTERING_DONE){
exp_i = 0; //clear
ExpBuf[0] = 0; clear_x();
ExpBuf[1] = 0; no_lift = 1;
} else if (entry_i > 0){ entering_exp = ENTERING_SIGNIF;
//backspace EntryBuf[entry_i] = '0';
if (EntryBuf[entry_i] == '.'){ //do not increment entry_i from 0, until first non-0 entry
entering_exp--; } else if (entering_exp >= ENTERING_EXP){
} //go back to digit entry
entry_i--; entering_exp--;
} exp_i = 0;
} break; ExpBuf[0] = 0;
////////// ExpBuf[1] = 0;
case '+': //fallthrough } else if (entry_i > 0){
case '*': //fallthrough //backspace
case '-': //fallthrough if (EntryBuf[entry_i] == '.'){
case '/': //fallthrough entering_exp--;
case '<': //fallthrough //use as +/- }
case 'r': { //use as swap entry_i--;
if (entering_exp != ENTERING_DONE){ }
//finish entry } break;
int8_t exponent; //exponent is only 2 digits //////////
exponent = 10*ExpBuf[1] + ExpBuf[0]; case '+': //fallthrough
if (entering_exp == ENTERING_EXP_NEG){ case '*': //fallthrough
exponent = -exponent; case '-': //fallthrough
} case '/': //fallthrough
EntryBuf[entry_i] = '\0'; case '<': //fallthrough //use as +/-
push_decn(EntryBuf, exponent, no_lift); case 'r': { //use as swap
process_cmd(KEY_MAP[i_key]); if (entering_exp != ENTERING_DONE){
//reset state as initial ENTERING_DONE state //finish entry
entering_exp = ENTERING_DONE; int8_t exponent; //exponent is only 2 digits
entry_i = 0; exponent = 10*ExpBuf[1] + ExpBuf[0];
exp_i = 0; if (entering_exp == ENTERING_EXP_NEG){
ExpBuf[0] = 0; exponent = -exponent;
ExpBuf[1] = 0; }
} else { EntryBuf[entry_i] = '\0';
//process key push_decn(EntryBuf, exponent, no_lift);
process_cmd(KEY_MAP[i_key]); process_cmd(KEY_MAP[i_key]);
} //reset state as initial ENTERING_DONE state
no_lift = 0; entering_exp = ENTERING_DONE;
} break; entry_i = 0;
////////// exp_i = 0;
default: process_cmd(KEY_MAP[i_key]); ExpBuf[0] = 0;
////////// ExpBuf[1] = 0;
} //switch(KEY_MAP[i_key]) } else {
//process key
break; process_cmd(KEY_MAP[i_key]);
} //if found new key pressed }
} //for new key array no_lift = 0;
} //if (!NewKeyEmpty) } break;
//////////
default: process_cmd(KEY_MAP[i_key]);
//////////
} //switch(KEY_MAP[i_key])
} //if found new key pressed
//print X //print X
LCD_ClearToEnd(0); //go to 2nd row LCD_ClearToEnd(0); //go to 2nd row