Merge branch 'master' of github.com:kiibohd/controller
This commit is contained in:
		
						commit
						47ec39da8e
					
				
					 14 changed files with 555 additions and 1 deletions
				
			
		|  | @ -84,6 +84,7 @@ Contact | |||
| If you really need to get a hold of HaaTa, email is best: `haata@kiibohd.com` | ||||
| 
 | ||||
| IRC is likely faster though. | ||||
| `#input.club@irc.freenode.net` | ||||
| `#geekhack@irc.freenode.net` | ||||
| `#deskthority@irc.freenode.net` | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										85
									
								
								Scan/CK3/defaultMap.kll
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								Scan/CK3/defaultMap.kll
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,85 @@ | |||
| Name = CK3; | ||||
| Version = 0.3; | ||||
| Author = "Crystal Hammer 2016"; | ||||
| KLL = 0.3c; | ||||
| 
 | ||||
| # Modified Date | ||||
| Date = 2016-02-19; | ||||
| 
 | ||||
| 
 | ||||
| S0x00 : U"Esc"; | ||||
| S0x01 : U"1"; | ||||
| S0x02 : U"2"; | ||||
| S0x03 : U"3"; | ||||
| S0x04 : U"4"; | ||||
| S0x05 : U"5"; | ||||
| S0x06 : U"6"; | ||||
| S0x07 : U"7"; | ||||
| S0x08 : U"8"; | ||||
| S0x09 : U"9"; | ||||
| S0x0A : U"0"; | ||||
| S0x0B : U"Minus"; | ||||
| S0x0C : U"Equal"; | ||||
| S0x0D : U"Backslash"; | ||||
| S0x0E : U"Backtick"; | ||||
| S0x0F : U"Tab"; | ||||
| S0x10 : U"Q"; | ||||
| S0x11 : U"W"; | ||||
| S0x12 : U"E"; | ||||
| S0x13 : U"R"; | ||||
| S0x14 : U"T"; | ||||
| S0x15 : U"Y"; | ||||
| S0x16 : U"U"; | ||||
| S0x17 : U"I"; | ||||
| S0x18 : U"O"; | ||||
| S0x19 : U"P"; | ||||
| S0x1A : U"LBrace"; | ||||
| S0x1B : U"RBrace"; | ||||
| S0x1C : U"Backspace"; | ||||
| S0x1D : U"Ctrl"; | ||||
| S0x1E : U"A"; | ||||
| S0x1F : U"S"; | ||||
| S0x20 : U"D"; | ||||
| S0x21 : U"F"; | ||||
| S0x22 : U"G"; | ||||
| S0x23 : U"H"; | ||||
| S0x24 : U"J"; | ||||
| S0x25 : U"K"; | ||||
| S0x26 : U"L"; | ||||
| S0x27 : U"Semicolon"; | ||||
| S0x28 : U"Quote"; | ||||
| S0x29 : U"Enter"; | ||||
| S0x2A : U"LShift"; | ||||
| S0x2B : U"Z"; | ||||
| S0x2C : U"X"; | ||||
| S0x2D : U"C"; | ||||
| S0x2E : U"V"; | ||||
| S0x2F : U"B"; | ||||
| S0x30 : U"N"; | ||||
| S0x31 : U"M"; | ||||
| S0x32 : U"Comma"; | ||||
| S0x33 : U"Period"; | ||||
| S0x34 : U"Slash"; | ||||
| S0x35 : U"RShift"; | ||||
| S0x36 : U"Function1"; # Fun key | ||||
| S0x37 : U"Function2"; # Left Blank Key | ||||
| S0x38 : U"LAlt"; | ||||
| S0x39 : U"LGui"; | ||||
| S0x3A : U"Space"; | ||||
| S0x3B : U"RGui"; | ||||
| S0x3C : U"RAlt"; | ||||
| S0x3D : U"Function3"; # Right Blank Key 1 | ||||
| S0x3E : U"Function4"; # Right Blank Key 2 | ||||
| 
 | ||||
| 
 | ||||
| # Custom Action Examples | ||||
| 
 | ||||
| # Example capability, prints to cli | ||||
| action1 => CustomAction_action1_capability(); # No arguments | ||||
| 
 | ||||
| # Blocks given USB Code, must be used with blockLink | ||||
| # Simple example, supports only blocking a single key at a time | ||||
| # Keys must be specified using numbers see Macro/PartialMap/usb_hid.h | ||||
| blockHold => CustomAction_blockHold_capability( usbCode : 1 ); # Single 8-bit argument | ||||
| blockKey => CustomAction_blockKey_capability( usbCode : 1 ); | ||||
| 
 | ||||
							
								
								
									
										54
									
								
								Scan/CK3/matrix.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								Scan/CK3/matrix.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| /* Copyright (C) 2014-2015 by Jacob Alexander
 | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| // ----- Includes -----
 | ||||
| 
 | ||||
| // Project Includes
 | ||||
| #include <matrix_setup.h> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ----- Matrix Definition -----
 | ||||
| 
 | ||||
| // Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31
 | ||||
| // Not all chips have access to all of these pins (most don't have 160 pins :P)
 | ||||
| //
 | ||||
| // NOTE:
 | ||||
| // Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down
 | ||||
| // Checking this is completely on the ownness of the user
 | ||||
| 
 | ||||
| //
 | ||||
| // Columns (Strobe)  //  PTB0..3,16,17 PTC4,5 PTD0
 | ||||
| // Rows	   (Sense)   //  PTD1..7
 | ||||
| 
 | ||||
| // Define Rows (Sense) and Columns (Strobes)
 | ||||
| GPIO_Pin Matrix_cols[] = { gpio(B,0), gpio(B,1), gpio(B,2), gpio(B,3), gpio(B,16), gpio(B,17), gpio(C,4), gpio(C,6), gpio(D,0) }; | ||||
| GPIO_Pin Matrix_rows[] = { gpio(D,1), gpio(D,2), gpio(D,3), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7) }; | ||||
| 
 | ||||
| // Define type of scan matrix
 | ||||
| Config Matrix_type = Config_Pulldown; | ||||
| 
 | ||||
| 
 | ||||
| // Define this if your matrix has ghosting (i.e. regular keyboard without diodes)
 | ||||
| // this will enable the anti-ghosting code
 | ||||
| #define GHOSTING_MATRIX | ||||
							
								
								
									
										204
									
								
								Scan/CK3/scan_loop.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								Scan/CK3/scan_loop.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,204 @@ | |||
| /* Copyright (C) 2014 by Jacob Alexander
 | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| // ----- Includes -----
 | ||||
| 
 | ||||
| // Compiler Includes
 | ||||
| #include <Lib/ScanLib.h> | ||||
| 
 | ||||
| // Project Includes
 | ||||
| #include <cli.h> | ||||
| #include <led.h> | ||||
| #include <print.h> | ||||
| #include <matrix_scan.h> | ||||
| #include <macro.h> | ||||
| 
 | ||||
| // Local Includes
 | ||||
| #include "scan_loop.h" | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ----- Function Declarations -----
 | ||||
| 
 | ||||
| // CLI Functions
 | ||||
| void cliFunc_echo( char* args ); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ----- Variables -----
 | ||||
| 
 | ||||
| // Scan Module command dictionary
 | ||||
| CLIDict_Entry( echo,        "Example command, echos the arguments." ); | ||||
| 
 | ||||
| CLIDict_Def( scanCLIDict, "Scan Module Commands" ) = { | ||||
| 	CLIDict_Item( echo ), | ||||
| 	{ 0, 0, 0 } // Null entry for dictionary end
 | ||||
| }; | ||||
| 
 | ||||
| // Number of scans since the last USB send
 | ||||
| uint16_t Scan_scanCount = 0; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ----- Functions -----
 | ||||
| 
 | ||||
| // Setup
 | ||||
| inline void Scan_setup() | ||||
| { | ||||
| 	// Register Scan CLI dictionary
 | ||||
| 	CLI_registerDictionary( scanCLIDict, scanCLIDictName ); | ||||
| 
 | ||||
| 	// Setup GPIO pins for matrix scanning
 | ||||
| 	Matrix_setup(); | ||||
| 
 | ||||
| 	// Reset scan count
 | ||||
| 	Scan_scanCount = 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Main Detection Loop
 | ||||
| inline uint8_t Scan_loop() | ||||
| { | ||||
| 	Matrix_scan( Scan_scanCount++ ); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Signal from Macro Module that all keys have been processed (that it knows about)
 | ||||
| inline void Scan_finishedWithMacro( uint8_t sentKeys ) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Signal from Output Module that all keys have been processed (that it knows about)
 | ||||
| inline void Scan_finishedWithOutput( uint8_t sentKeys ) | ||||
| { | ||||
| 	// Reset scan loop indicator (resets each key debounce state)
 | ||||
| 	// TODO should this occur after USB send or Macro processing?
 | ||||
| 	Scan_scanCount = 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ----- Capabilities -----
 | ||||
| 
 | ||||
| // Custom capability examples
 | ||||
| // Refer to kll.h in Macros/PartialMap for state and stateType information
 | ||||
| void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args ) | ||||
| { | ||||
| 	// Display capability name
 | ||||
| 	// XXX This is required for debug cli to give you a list of capabilities
 | ||||
| 	if ( stateType == 0xFF && state == 0xFF ) | ||||
| 	{ | ||||
| 		print("CustomAction_action1_capability()"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	// Prints Action1 info message to the debug cli
 | ||||
| 	info_print("Action1"); | ||||
| } | ||||
| 
 | ||||
| uint8_t CustomAction_blockHold_storage = 0; | ||||
| void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args ) | ||||
| { | ||||
| 	// Display capability name
 | ||||
| 	if ( stateType == 0xFF && state == 0xFF ) | ||||
| 	{ | ||||
| 		print("CustomAction_blockHold_capability(usbCode)"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	// Retrieve 8-bit argument
 | ||||
| 	uint8_t key = args[0]; | ||||
| 
 | ||||
| 	// We only care about normal keys
 | ||||
| 	if ( stateType == 0x00 ) | ||||
| 	{ | ||||
| 		// Block given key if we're in the "Press" or "Hold" state
 | ||||
| 		if ( ( state == 0x01 || state == 0x02 ) | ||||
| 			&& CustomAction_blockHold_storage == 0 ) | ||||
| 		{ | ||||
| 			CustomAction_blockHold_storage = key; | ||||
| 			info_msg("Blocking Key: "); | ||||
| 			printHex( key ); | ||||
| 			print( NL ); | ||||
| 		} | ||||
| 		// Release if in the "Off" or "Release" state and we're blocking
 | ||||
| 		else if ( ( state == 0x00 || state == 0x03 ) | ||||
| 			&& key == CustomAction_blockHold_storage ) | ||||
| 		{ | ||||
| 			info_msg("Unblocking Key: "); | ||||
| 			printHex( CustomAction_blockHold_storage ); | ||||
| 			print( NL ); | ||||
| 			CustomAction_blockHold_storage = 0; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args ) | ||||
| { | ||||
| 	// Display capability name
 | ||||
| 	if ( stateType == 0xFF && state == 0xFF ) | ||||
| 	{ | ||||
| 		print("CustomAction_blockKey_capability(usbCode)"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	// Retrieve 8-bit argument
 | ||||
| 	uint8_t key = args[0]; | ||||
| 
 | ||||
| 	// If key is not blocked, process
 | ||||
| 	if ( key != CustomAction_blockHold_storage ) | ||||
| 	{ | ||||
| 		extern void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); | ||||
| 		Output_usbCodeSend_capability( state, stateType, &key ); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ----- CLI Command Functions -----
 | ||||
| 
 | ||||
| // XXX Just an example command showing how to parse arguments (more complex than generally needed)
 | ||||
| void cliFunc_echo( char* args ) | ||||
| { | ||||
| 	char* curArgs; | ||||
| 	char* arg1Ptr; | ||||
| 	char* arg2Ptr = args; | ||||
| 
 | ||||
| 	// Parse args until a \0 is found
 | ||||
| 	while ( 1 ) | ||||
| 	{ | ||||
| 		print( NL ); // No \r\n by default after the command is entered
 | ||||
| 
 | ||||
| 		curArgs = arg2Ptr; // Use the previous 2nd arg pointer to separate the next arg from the list
 | ||||
| 		CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); | ||||
| 
 | ||||
| 		// Stop processing args if no more are found
 | ||||
| 		if ( *arg1Ptr == '\0' ) | ||||
| 			break; | ||||
| 
 | ||||
| 		// Print out the arg
 | ||||
| 		dPrint( arg1Ptr ); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										32
									
								
								Scan/CK3/setup.cmake
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								Scan/CK3/setup.cmake
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| ###| CMake Kiibohd Controller Scan Module |### | ||||
| # | ||||
| # Written by Jacob Alexander in 2014 for the Kiibohd Controller | ||||
| # | ||||
| # Released into the Public Domain | ||||
| # | ||||
| ### | ||||
| 
 | ||||
| 
 | ||||
| ### | ||||
| # Required Submodules | ||||
| # | ||||
| 
 | ||||
| AddModule ( Scan MatrixARM ) | ||||
| 
 | ||||
| 
 | ||||
| ### | ||||
| # Module C files | ||||
| # | ||||
| 
 | ||||
| set ( Module_SRCS | ||||
| 	scan_loop.c | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| ### | ||||
| # Compiler Family Compatibility | ||||
| # | ||||
| set ( ModuleCompatibility | ||||
| 	arm | ||||
| ) | ||||
| 
 | ||||
|  | @ -1,4 +1,4 @@ | |||
| Name = MD1_1; | ||||
| Name = MD1.1; | ||||
| Version = 0.3d; | ||||
| Author = "HaaTa (Jacob Alexander) 2014-2016"; | ||||
| KLL = 0.3c; | ||||
							
								
								
									
										48
									
								
								Scan/MD1.1/scan_loop.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								Scan/MD1.1/scan_loop.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | |||
| /* Copyright (C) 2014-2015 by Jacob Alexander
 | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| // ----- Includes -----
 | ||||
| 
 | ||||
| // Compiler Includes
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ----- Functions -----
 | ||||
| 
 | ||||
| // Functions to be called by main.c
 | ||||
| void Scan_setup( void ); | ||||
| uint8_t Scan_loop( void ); | ||||
| 
 | ||||
| // Call-backs
 | ||||
| void Scan_finishedWithMacro( uint8_t sentKeys );  // Called by Macro Module
 | ||||
| void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module
 | ||||
| 
 | ||||
| 
 | ||||
| // ----- Capabilities -----
 | ||||
| 
 | ||||
| // Example capabilities
 | ||||
| void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args ); | ||||
| void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args ); | ||||
| void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args ); | ||||
| 
 | ||||
|  | @ -70,6 +70,15 @@ CLIDict_Def( matrixCLIDict, "Matrix Module Commands" ) = { | |||
| // Debounce Array
 | ||||
| KeyState Matrix_scanArray[ Matrix_colsNum * Matrix_rowsNum ]; | ||||
| 
 | ||||
| // Ghost Arrays
 | ||||
| #ifdef GHOSTING_MATRIX | ||||
| KeyGhost Matrix_ghostArray[ Matrix_colsNum * Matrix_rowsNum ]; | ||||
| 
 | ||||
| uint8_t col_use[Matrix_colsNum], row_use[Matrix_rowsNum];  // used count
 | ||||
| uint8_t col_ghost[Matrix_colsNum], row_ghost[Matrix_rowsNum];  // marked as having ghost if 1
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| // Matrix debug flag - If set to 1, for each keypress the scan code is displayed in hex
 | ||||
| //                     If set to 2, for each key state change, the scan code is displayed along with the state
 | ||||
| uint8_t matrixDebugMode = 0; | ||||
|  | @ -111,10 +120,17 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type ) | |||
| 	{ | ||||
| 	case Type_StrobeOn: | ||||
| 		*GPIO_PSOR |= (1 << gpio.pin); | ||||
| 		#ifdef GHOSTING_MATRIX | ||||
| 		*GPIO_PDDR |= (1 << gpio.pin);  // output
 | ||||
| 		#endif | ||||
| 		break; | ||||
| 
 | ||||
| 	case Type_StrobeOff: | ||||
| 		*GPIO_PCOR |= (1 << gpio.pin); | ||||
| 		#ifdef GHOSTING_MATRIX | ||||
| 		// Ghosting martix needs to put not used (off) strobes in high impedance state
 | ||||
| 		*GPIO_PDDR &= ~(1 << gpio.pin);  // input, high Z state
 | ||||
| 		#endif | ||||
| 		break; | ||||
| 
 | ||||
| 	case Type_StrobeSetup: | ||||
|  | @ -206,6 +222,11 @@ void Matrix_setup() | |||
| 		Matrix_scanArray[ item ].activeCount      = 0; | ||||
| 		Matrix_scanArray[ item ].inactiveCount    = DebounceDivThreshold_define; // Start at 'off' steady state
 | ||||
| 		Matrix_scanArray[ item ].prevDecisionTime = 0; | ||||
| 		#ifdef GHOSTING_MATRIX | ||||
| 		Matrix_ghostArray[ item ].prev            = KeyState_Off; | ||||
| 		Matrix_ghostArray[ item ].cur             = KeyState_Off; | ||||
| 		Matrix_ghostArray[ item ].saved           = KeyState_Off; | ||||
| 		#endif | ||||
| 	} | ||||
| 
 | ||||
| 	// Clear scan stats counters
 | ||||
|  | @ -377,7 +398,9 @@ void Matrix_scan( uint16_t scanNum ) | |||
| 				state->prevDecisionTime = currentTime; | ||||
| 
 | ||||
| 				// Send keystate to macro module
 | ||||
| 				#ifndef GHOSTING_MATRIX | ||||
| 				Macro_keyState( key, state->curState ); | ||||
| 				#endif | ||||
| 
 | ||||
| 				// Matrix Debug, only if there is a state change
 | ||||
| 				if ( matrixDebugMode && state->curState != state->prevState ) | ||||
|  | @ -403,6 +426,101 @@ void Matrix_scan( uint16_t scanNum ) | |||
| 		Matrix_pin( Matrix_cols[ strobe ], Type_StrobeOff ); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	// Matrix ghosting check and elimination
 | ||||
| 	// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
 | ||||
| #ifdef GHOSTING_MATRIX | ||||
| 	// strobe = column, sense = row
 | ||||
| 
 | ||||
| 	// Count (rows) use for columns
 | ||||
| 	//print("C ");
 | ||||
| 	for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) | ||||
| 	{ | ||||
| 		uint8_t used = 0; | ||||
| 		for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) | ||||
| 		{ | ||||
| 			uint8_t key = Matrix_colsNum * row + col; | ||||
| 			KeyState *state = &Matrix_scanArray[ key ]; | ||||
| 			if ( keyOn(state->curState) ) | ||||
| 				used++; | ||||
| 		} | ||||
| 		//printInt8(used);
 | ||||
| 		col_use[col] = used; | ||||
| 		col_ghost[col] = 0;  // clear
 | ||||
| 	} | ||||
| 
 | ||||
| 	// Count (columns) use for rows
 | ||||
| 	//print("  R ");
 | ||||
| 	for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) | ||||
| 	{ | ||||
| 		uint8_t used = 0; | ||||
| 		for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) | ||||
| 		{ | ||||
| 			uint8_t key = Matrix_colsNum * row + col; | ||||
| 			KeyState *state = &Matrix_scanArray[ key ]; | ||||
| 			if ( keyOn(state->curState) ) | ||||
| 				used++; | ||||
| 		} | ||||
| 		//printInt8(used);
 | ||||
| 		row_use[row] = used; | ||||
| 		row_ghost[row] = 0;  // clear
 | ||||
| 	} | ||||
| 	 | ||||
| 	// Check if matrix has ghost
 | ||||
| 	// Happens when key is pressed and some other key is pressed in same row and another in same column
 | ||||
| 	//print("  G ");
 | ||||
| 	for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) | ||||
| 	{ | ||||
| 		for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) | ||||
| 		{ | ||||
| 			uint8_t key = Matrix_colsNum * row + col; | ||||
| 			KeyState *state = &Matrix_scanArray[ key ]; | ||||
| 			if ( keyOn(state->curState) && col_use[col] >= 2 && row_use[row] >= 2 ) | ||||
| 			{ | ||||
| 				// mark col and row as having ghost
 | ||||
| 				col_ghost[col] = 1; | ||||
| 				row_ghost[row] = 1; | ||||
| 				//print(" ");  printInt8(col);  print(",");  printInt8(row);
 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	//print( NL );
 | ||||
| 
 | ||||
| 	// Send keys
 | ||||
| 	for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) | ||||
| 	{ | ||||
| 		for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) | ||||
| 		{ | ||||
| 			uint8_t key = Matrix_colsNum * row + col; | ||||
| 			KeyState *state = &Matrix_scanArray[ key ]; | ||||
| 			KeyGhost *st = &Matrix_ghostArray[ key ]; | ||||
| 			 | ||||
| 			// col or row is ghosting (crossed)
 | ||||
| 			uint8_t ghost = (col_ghost[col] > 0 || row_ghost[row] > 0) ? 1 : 0; | ||||
| 			 | ||||
| 			st->prev = st->cur;  // previous
 | ||||
| 			// save state if no ghost or outside ghosted area
 | ||||
| 			if ( ghost == 0 ) | ||||
| 				st->saved = state->curState;  // save state if no ghost
 | ||||
| 			// final
 | ||||
| 			// use saved state if ghosting, or current if not
 | ||||
| 			st->cur = ghost > 0 ? st->saved : state->curState; | ||||
| 			 | ||||
| 			//  Send keystate to macro module
 | ||||
| 			KeyPosition k = !st->cur  | ||||
| 				? (!st->prev ? KeyState_Off : KeyState_Release) | ||||
| 				: ( st->prev ? KeyState_Hold : KeyState_Press); | ||||
| 			//if (!st->cur && !st->prev)  k = KeyState_Off; else
 | ||||
| 			//if ( st->cur &&  st->prev)  k = KeyState_Hold; else
 | ||||
| 			//if ( st->cur && !st->prev)  k = KeyState_Press; else
 | ||||
| 			//if (!st->cur &&  st->prev)  k = KeyState_Release;
 | ||||
| 			Macro_keyState( key, k ); | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 	// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
 | ||||
| 
 | ||||
| 
 | ||||
| 	// State Table Output Debug
 | ||||
| 	if ( matrixDebugStateCounter > 0 ) | ||||
| 	{ | ||||
|  |  | |||
|  | @ -139,6 +139,18 @@ typedef struct KeyState { | |||
| 	uint8_t         prevDecisionTime; | ||||
| } __attribute__((packed)) KeyState; | ||||
| 
 | ||||
| // Ghost Element, after ghost detection/cancelation
 | ||||
| typedef struct KeyGhost { | ||||
| 	KeyPosition     prev; | ||||
| 	KeyPosition     cur; | ||||
| 	KeyPosition     saved;  // state before ghosting
 | ||||
| } __attribute__((packed)) KeyGhost; | ||||
| 
 | ||||
| // utility
 | ||||
| inline uint8_t keyOn(/*KeyPosition*/uint8_t st) | ||||
| { | ||||
| 	return (st == KeyState_Press || st == KeyState_Hold) ? 1 : 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // ----- Functions -----
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jacob Alexander
						Jacob Alexander