comparison Scan/MatrixARM/matrix_scan.c @ 343:e464aaa4730f

Adding timing based debounce code - Uses expiry timer to decide on when to allow a state change - Initial state transitions are unaffected - Use MinDebounceTime define in kll to configure - ms granularity
author Jacob Alexander <haata@kiibohd.com>
date Fri, 19 Jun 2015 01:50:56 -0700
parents c856f826bd49
children 86b937945313
comparison
equal deleted inserted replaced
342:b29c291ad130 343:e464aaa4730f
80 // Matrix Scan Counters 80 // Matrix Scan Counters
81 uint16_t matrixMaxScans = 0; 81 uint16_t matrixMaxScans = 0;
82 uint16_t matrixCurScans = 0; 82 uint16_t matrixCurScans = 0;
83 uint16_t matrixPrevScans = 0; 83 uint16_t matrixPrevScans = 0;
84 84
85 // System Timer used for delaying debounce decisions
86 extern volatile uint32_t systick_millis_count;
87
85 88
86 89
87 // ----- Functions ----- 90 // ----- Functions -----
88 91
89 // Pin action (Strobe, Sense, Strobe Setup, Sense Setup) 92 // Pin action (Strobe, Sense, Strobe Setup, Sense Setup)
195 printHex( Matrix_maxKeys ); 198 printHex( Matrix_maxKeys );
196 199
197 // Clear out Debounce Array 200 // Clear out Debounce Array
198 for ( uint8_t item = 0; item < Matrix_maxKeys; item++ ) 201 for ( uint8_t item = 0; item < Matrix_maxKeys; item++ )
199 { 202 {
200 Matrix_scanArray[ item ].prevState = KeyState_Off; 203 Matrix_scanArray[ item ].prevState = KeyState_Off;
201 Matrix_scanArray[ item ].curState = KeyState_Off; 204 Matrix_scanArray[ item ].curState = KeyState_Off;
202 Matrix_scanArray[ item ].activeCount = 0; 205 Matrix_scanArray[ item ].activeCount = 0;
203 Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state 206 Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state
207 Matrix_scanArray[ item ].prevDecisionTime = 0;
204 } 208 }
205 209
206 // Clear scan stats counters 210 // Clear scan stats counters
207 matrixMaxScans = 0; 211 matrixMaxScans = 0;
208 matrixPrevScans = 0; 212 matrixPrevScans = 0;
259 } 263 }
260 else 264 else
261 { 265 {
262 matrixCurScans++; 266 matrixCurScans++;
263 } 267 }
268
269 // Read systick for event scheduling
270 uint8_t currentTime = (uint8_t)systick_millis_count;
264 271
265 // For each strobe, scan each of the sense pins 272 // For each strobe, scan each of the sense pins
266 for ( uint8_t strobe = 0; strobe < Matrix_colsNum; strobe++ ) 273 for ( uint8_t strobe = 0; strobe < Matrix_colsNum; strobe++ )
267 { 274 {
268 // Strobe Pin 275 // Strobe Pin
303 if ( state->inactiveCount < DebounceDivThreshold_define ) state->inactiveCount += 1; 310 if ( state->inactiveCount < DebounceDivThreshold_define ) state->inactiveCount += 1;
304 state->activeCount >>= 1; 311 state->activeCount >>= 1;
305 } 312 }
306 313
307 // Check for state change if it hasn't been set 314 // Check for state change if it hasn't been set
315 // But only if enough time has passed since last state change
308 // Only check if the minimum number of scans has been met 316 // Only check if the minimum number of scans has been met
309 // the current state is invalid 317 // the current state is invalid
310 // and either active or inactive count is over the debounce threshold 318 // and either active or inactive count is over the debounce threshold
311 if ( state->curState == KeyState_Invalid ) 319 if ( state->curState == KeyState_Invalid )
312 { 320 {
321 // Determine time since last decision
322 uint8_t lastTransition = currentTime - state->prevDecisionTime;
323
324 // Attempt state transition
313 switch ( state->prevState ) 325 switch ( state->prevState )
314 { 326 {
315 case KeyState_Press: 327 case KeyState_Press:
316 case KeyState_Hold: 328 case KeyState_Hold:
317 if ( state->activeCount > state->inactiveCount ) 329 if ( state->activeCount > state->inactiveCount )
318 { 330 {
319 state->curState = KeyState_Hold; 331 state->curState = KeyState_Hold;
320 } 332 }
321 else 333 else
322 { 334 {
335 // If not enough time has passed since Hold
336 // Keep previous state
337 if ( lastTransition < MinDebounceTime_define )
338 {
339 //warn_print("FAST Release stopped");
340 state->curState = state->prevState;
341 continue;
342 }
343
323 state->curState = KeyState_Release; 344 state->curState = KeyState_Release;
324 } 345 }
325 break; 346 break;
326 347
327 case KeyState_Release: 348 case KeyState_Release:
328 case KeyState_Off: 349 case KeyState_Off:
329 if ( state->activeCount > state->inactiveCount ) 350 if ( state->activeCount > state->inactiveCount )
330 { 351 {
352 // If not enough time has passed since Hold
353 // Keep previous state
354 if ( lastTransition < MinDebounceTime_define )
355 {
356 //warn_print("FAST Press stopped");
357 state->curState = state->prevState;
358 continue;
359 }
360
331 state->curState = KeyState_Press; 361 state->curState = KeyState_Press;
332 } 362 }
333 else 363 else
334 { 364 {
335 state->curState = KeyState_Off; 365 state->curState = KeyState_Off;
339 case KeyState_Invalid: 369 case KeyState_Invalid:
340 default: 370 default:
341 erro_print("Matrix scan bug!! Report me!"); 371 erro_print("Matrix scan bug!! Report me!");
342 break; 372 break;
343 } 373 }
374
375 // Update decision time
376 state->prevDecisionTime = currentTime;
344 377
345 // Send keystate to macro module 378 // Send keystate to macro module
346 Macro_keyState( key, state->curState ); 379 Macro_keyState( key, state->curState );
347 380
348 // Matrix Debug, only if there is a state change 381 // Matrix Debug, only if there is a state change