DO NOT USE - debounce successfully compiled.
This commit is contained in:
		
							parent
							
								
									3949ab322d
								
							
						
					
					
						commit
						d0b691df0e
					
				
					 7 changed files with 251 additions and 65 deletions
				
			
		
							
								
								
									
										123
									
								
								quantum/debounce/debounce_eager_pk.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								quantum/debounce/debounce_eager_pk.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,123 @@
 | 
			
		|||
/*
 | 
			
		||||
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;
 | 
			
		||||
  }  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//Implementation of no debounce.
 | 
			
		||||
							
								
								
									
										58
									
								
								quantum/debounce/debounce_sym_g.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								quantum/debounce/debounce_sym_g.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
/*
 | 
			
		||||
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 bool debouncing = false;
 | 
			
		||||
static uint16_t debouncing_time;
 | 
			
		||||
 | 
			
		||||
void debounce_init(void) {}
 | 
			
		||||
 | 
			
		||||
#if DEBOUNCE > 0
 | 
			
		||||
void debounce(matrix_row_t raw[], matrix_row_t cooked[], bool changed)
 | 
			
		||||
{
 | 
			
		||||
  if (changed) {
 | 
			
		||||
    debouncing = true;
 | 
			
		||||
    debouncing_time = timer_read();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) {
 | 
			
		||||
    for (int i = 0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
      cooked[i] = raw[i];
 | 
			
		||||
    }
 | 
			
		||||
    debouncing = false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#else //no debouncing.
 | 
			
		||||
void debounce(matrix_row_t raw[], matrix_row_t cooked[], bool changed)
 | 
			
		||||
{
 | 
			
		||||
  for (int i = 0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
    cooked[i] = raw[i];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
bool debounce_active() {
 | 
			
		||||
  return debouncing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										28
									
								
								quantum/debounce/readme.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								quantum/debounce/readme.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
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…
	
	Add table
		Add a link
		
	
		Reference in a new issue