Mercurial > louis > kiibohd-controller
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 |