parent
							
								
									c9ba618654
								
							
						
					
					
						commit
						39ca330f10
					
				| @ -1,22 +0,0 @@ | ||||
| /*
 | ||||
| Copyright 2017 Alex Ong<the.onga@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 of the License, or | ||||
| (at your option) any later version. | ||||
| This 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 program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| #include "debounce.h" | ||||
| #include "matrix.h" | ||||
| //Default implementation - no debouncing
 | ||||
| __attribute__((weak)) void matrix_debounce_init(void) {} | ||||
| __attribute__((weak)) void matrix_debounce(void) {} | ||||
| __attribute__((weak)) matrix_row_t matrix_debounce_get_row(uint8_t row) | ||||
| { | ||||
|   return matrix_get_row(row); | ||||
| } | ||||
| @ -1,21 +0,0 @@ | ||||
| #ifndef DEBOUNCE_H | ||||
| #define DEBOUNCE_H | ||||
| #include <stdbool.h> | ||||
| #include <stdint.h> | ||||
| #include "matrix.h" | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|   /* called to initialize any data stores your implementation has*/ | ||||
|   void matrix_debounce_init(void); | ||||
|   /* call this every keyboard_task to debounce the matrix*/ | ||||
|   void matrix_debounce(void); | ||||
|   /* matrix state on row */ | ||||
|   matrix_row_t matrix_debounce_get_row(uint8_t row); | ||||
|   /* whether a switch is on */ | ||||
|   bool matrix_debounce_is_on(uint8_t row, uint8_t col); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| #endif | ||||
| @ -1,124 +0,0 @@ | ||||
| /*
 | ||||
| Copyright 2017 Alex Ong<the.onga@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 of the License, or | ||||
| (at your option) any later version. | ||||
| This 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 program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| 
 | ||||
| /*
 | ||||
| Basic per-key algorithm. Uses an 8-bit counter per key. | ||||
| After pressing a key, it immediately changes state, and sets a counter. | ||||
| No further inputs are accepted until DEBOUNCE milliseconds have occurred. | ||||
| */ | ||||
| 
 | ||||
| #include "debounce.h" | ||||
| #include "matrix.h" | ||||
| #include "timer.h" | ||||
| 
 | ||||
| #ifndef DEBOUNCE | ||||
|   #define DEBOUNCE 5 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #if (MATRIX_COLS <= 8) | ||||
| #    define ROW_SHIFTER ((uint8_t)1) | ||||
| #elif (MATRIX_COLS <= 16) | ||||
| #    define ROW_SHIFTER ((uint16_t)1) | ||||
| #elif (MATRIX_COLS <= 32) | ||||
| #    define ROW_SHIFTER  ((uint32_t)1) | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #define debounce_counter_t uint8_t | ||||
| 
 | ||||
| static matrix_row_t matrix_debounced[MATRIX_ROWS]; | ||||
| static debounce_counter_t debounce_counters[MATRIX_ROWS*MATRIX_COLS]; | ||||
| 
 | ||||
| #define DEBOUNCE_ELAPSED 251 | ||||
| #define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1) | ||||
| 
 | ||||
| void update_debounce_counters(uint8_t current_time); | ||||
| void transfer_matrix_values(uint8_t current_time); | ||||
| 
 | ||||
| void matrix_debounce_init(void) | ||||
| { | ||||
|   for (uint8_t r = 0; r < MATRIX_ROWS; r++) | ||||
|   { | ||||
|     matrix_debounced[r] = 0; | ||||
|   } | ||||
| 
 | ||||
|   int i = 0; | ||||
|   for (uint8_t r = 0; r < MATRIX_ROWS; r++) | ||||
|   { | ||||
|     for (uint8_t c = 0; c < MATRIX_COLS; c++) | ||||
|     { | ||||
|       debounce_counters[i++] = DEBOUNCE_ELAPSED; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void matrix_debounce(void) | ||||
| { | ||||
|   uint8_t current_time = timer_read() % MAX_DEBOUNCE; | ||||
|   update_debounce_counters(current_time); | ||||
|   transfer_matrix_values(current_time); | ||||
| } | ||||
| 
 | ||||
| //If the current time is > debounce counter, set the counter to enable input.
 | ||||
| void update_debounce_counters(uint8_t current_time) | ||||
| { | ||||
|   debounce_counter_t *debounce_pointer = debounce_counters; | ||||
|   for (uint8_t row = 0; row < MATRIX_ROWS; row++) | ||||
|   { | ||||
|     for (uint8_t col = 0; col < MATRIX_COLS; col++) | ||||
|     { | ||||
|       if (*debounce_pointer != DEBOUNCE_ELAPSED) | ||||
|       { | ||||
|         if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= | ||||
|             DEBOUNCING_DELAY) { | ||||
|           *debounce_pointer = DEBOUNCE_ELAPSED; | ||||
|         } | ||||
|       } | ||||
|       debounce_pointer++; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // upload from raw_matrix to final matrix;
 | ||||
| void transfer_matrix_values(uint8_t current_time) | ||||
| { | ||||
|   debounce_counter_t *debounce_pointer = debounce_counters; | ||||
|   for (uint8_t row = 0; row < MATRIX_ROWS; row++) | ||||
|   { | ||||
|     matrix_row_t existing_row = matrix_debounced[row];  | ||||
|     matrix_row_t raw_row = matrix_get_row(row); | ||||
| 
 | ||||
|     for (uint8_t col = 0; col < MATRIX_COLS; col++) | ||||
|     { | ||||
|       matrix_row_t col_mask = (ROW_SHIFTER << col); | ||||
|       bool final_value = raw_row & col_mask; | ||||
|       bool existing_value = existing_row & col_mask; | ||||
|       if (*debounce_pointer == DEBOUNCE_ELAPSED && | ||||
|           (existing_value != final_value)) | ||||
|       { | ||||
|         *debounce_pointer = current_time; | ||||
|         existing_row ^= col_mask; //flip the bit.
 | ||||
|       } | ||||
|       debounce_pointer++; | ||||
|     } | ||||
|     matrix_debounced[row] = existing_row; | ||||
|   }   | ||||
| } | ||||
| 
 | ||||
| matrix_row_t matrix_debounce_get_row(uint8_t row) | ||||
| { | ||||
|   return matrix_debounced[row]; | ||||
| } | ||||
| @ -1,59 +0,0 @@ | ||||
| /*
 | ||||
| Copyright 2017 Alex Ong<the.onga@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 of the License, or | ||||
| (at your option) any later version. | ||||
| This 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 program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| 
 | ||||
| /*
 | ||||
| Basic global debounce algorithm. Used in 99% of keyboards at time of implementation | ||||
| When no state changes have occured for DEBOUNCE milliseconds, we push the state. | ||||
| */ | ||||
| #include "debounce.h" | ||||
| #include "matrix.h" | ||||
| #include "timer.h" | ||||
| #ifndef DEBOUNCE | ||||
|   #define DEBOUNCE 5 | ||||
| #endif | ||||
| static matrix_row_t matrix_debounced[MATRIX_ROWS]; | ||||
| static bool debouncing = false; | ||||
| static uint16_t debouncing_time; | ||||
| 
 | ||||
| void matrix_debounce_init(void) | ||||
| { | ||||
|   for (uint8_t r = 0; r < MATRIX_ROWS; r++) | ||||
|   { | ||||
|     matrix_debounced[r] = 0; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void matrix_debounce(void) | ||||
| { | ||||
|   for (uint8_t r = 0; r < MATRIX_ROWS; r++) | ||||
|   { | ||||
|     matrix_row_t raw = matrix_get_row(r); | ||||
|     if (raw != matrix_debounced[r]) | ||||
|     { | ||||
|       debouncing = true; | ||||
|       debouncing_time = timer_read(); | ||||
|     } | ||||
|   } | ||||
|   if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) { | ||||
|     for (int i = 0; i < MATRIX_ROWS; i++) { | ||||
|       matrix_debounced[i] = matrix_get_row(i); | ||||
|     } | ||||
|     debouncing = false; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| matrix_row_t matrix_debounce_get_row(uint8_t row) | ||||
| { | ||||
|   return matrix_debounced[row]; | ||||
| } | ||||
| @ -1,28 +0,0 @@ | ||||
| Debounce algorithms belong in this folder. | ||||
| Here are a few ideas | ||||
| 
 | ||||
| 1) Global vs Per-Key vs Per-Row | ||||
|  * Global - one timer for all keys. Any key change state affects global timer | ||||
|  * Per key - one timer per key | ||||
|  * Per row - one timer per row | ||||
| 
 | ||||
| 2) Eager vs symmetric vs assymetric | ||||
|  * Eager - any key change is reported immediately. All further inputs for DEBOUNCE ms are ignored. | ||||
|  * Symmetric - wait for no changes for DEBOUNCE ms before reporting change | ||||
|  * Assymetric - wait for different times depending on key-down/key-up. E.g. Eager key-down, DEBOUNCE ms key up. | ||||
| 
 | ||||
| 3) Timestamp vs cycles | ||||
|  * old old old code waits n cycles, decreasing count by one each matrix_scan | ||||
|  * newer code stores the millisecond the change occurred, and does subraction to figure out time elapsed. | ||||
|  * Timestamps are superior, i don't think cycles will ever be used again once upgraded. | ||||
| 
 | ||||
| The default algorithm is symmetric and global. | ||||
| Here are a few that could be implemented: | ||||
| 
 | ||||
| debounce_sym_g.c | ||||
| debounce_sym_pk.c  | ||||
| debounce_sym_pr.c  | ||||
| debounce_sym_pr_cycles.c //currently used in ergo-dox | ||||
| debounce_eager_g.c | ||||
| debounce_eager_pk.c | ||||
| debounce_eager_pr.c //could be used in ergo-dox! | ||||
					Loading…
					
					
				
		Reference in new issue
	
	 alex-ong
						alex-ong