- Commenting cleaned up - usb_keyboard_debug is not finished yet in terms of cleanup (needs DEBUB_PRINT #ifdef's) - Added LoadFile script generation - Formalized KeyIndex and USBKeys data containers - Split parts of scan_loop into Macro, USB, and main.c - Added interface to USB modules - Added interface to Macro modules - Added proper Debug module enable/disablesimple
@@ -9,11 +9,8 @@ | |||
#| Set the Compilers (must be set first) | |||
include( CMakeForceCompiler ) | |||
set( CMAKE_SYSTEM_NAME Generic ) | |||
cmake_force_c_compiler ( avr-gcc AVRCCompiler ) | |||
cmake_force_cxx_compiler( avr-g++ AVRCxxCompiler ) | |||
set( CMAKE_CROSSCOMPILING on ) | |||
message( STATUS ${CMAKE_CROSSCOMPILING}) | |||
### | |||
@@ -185,3 +182,20 @@ add_custom_target( SizeAfter ALL avr-size --target=${FORMAT} ${TARGET_HEX} ${TAR | |||
COMMENT "Size after generation:" | |||
) | |||
### | |||
# Setup Loader Script | |||
# | |||
#| Provides the user with the correct teensy-loader-cli command for the built .HEX file | |||
#| teensy-loader-cli must be in the user's path | |||
if( ${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) | |||
configure_file( LoadFile/bash load ) | |||
endif( ${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) | |||
#| TODO Windows | |||
if( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" ) | |||
message( STATUS "Load Script is on my TODO List for Windows..." ) | |||
endif( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" ) | |||
@@ -0,0 +1,28 @@ | |||
###| CMake Kiibohd Controller Debug Module |### | |||
# | |||
# Written by Jacob Alexander in 2011 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
### | |||
### | |||
# Module C files | |||
# | |||
#| XXX Requires the ../ due to how the paths are constructed | |||
set( DEBUG_SRCS | |||
../led/led.c | |||
../print/print.c | |||
) | |||
### | |||
# Module Specific Options | |||
# | |||
add_definitions( | |||
-I${HEAD_DIR}/Debug/led | |||
-I${HEAD_DIR}/Debug/print | |||
) | |||
@@ -0,0 +1,52 @@ | |||
/* Copyright (C) 2011 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 ----- | |||
// AVR Includes | |||
// Project Includes | |||
#include "led.h" | |||
// ----- Functions ----- | |||
// Error LED Setup | |||
void init_errorLED() | |||
{ | |||
// Use pin D6 as an output (LED) | |||
DDRD |= (1<<6); | |||
} | |||
// Error LED Control | |||
void errorLED( uint8_t on ) | |||
{ | |||
// Error LED On (D6) | |||
if ( on ) { | |||
PORTD |= (1<<6); | |||
} | |||
// Error LED Off | |||
else { | |||
PORTD &= ~(1<<6); | |||
} | |||
} | |||
@@ -0,0 +1,38 @@ | |||
/* Copyright (C) 2011 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. | |||
*/ | |||
#ifndef __led_h | |||
#define __led_h | |||
// ----- Includes ----- | |||
// AVR Includes | |||
#include <avr/io.h> | |||
// ----- Functions ----- | |||
void init_errorLED( void ); | |||
void errorLED( uint8_t on ); | |||
#endif | |||
@@ -0,0 +1,28 @@ | |||
###| CMake Kiibohd Controller Debug Module |### | |||
# | |||
# Written by Jacob Alexander in 2011 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
### | |||
### | |||
# Module C files | |||
# | |||
set( DEBUG_SRCS | |||
led.c | |||
) | |||
### | |||
# Module Specific Options | |||
# | |||
### | |||
# Just in case, you only want this module and are using others as well | |||
# | |||
add_definitions( -I${HEAD_DIR}/Debug/off ) | |||
@@ -0,0 +1,30 @@ | |||
/* Copyright (C) 2011 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. | |||
*/ | |||
#ifndef __led_h | |||
#define __led_h | |||
// ----- Disabler Defines ----- | |||
#define init_errorLED() | |||
#define errorLED(on) | |||
#endif | |||
@@ -0,0 +1,70 @@ | |||
/* Copyright (C) 2011 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. | |||
*/ | |||
#ifndef print_h__ | |||
#define print_h__ | |||
// ----- Disabler Defines ----- | |||
#define dPrint(c) | |||
#define dPrintStr(c) | |||
#define dPrintStrs(...) | |||
#define dPrintStrNL(c) | |||
#define dPrintStrsNL(...) | |||
// Special Msg Constructs (Uses VT100 tags) | |||
#define dPrintMsg(colour_code_str,msg,...) | |||
#define printMsg(colour_code_str,msg,str) | |||
// Info Messages | |||
#define info_dPrint(...) | |||
#define info_print(str) | |||
// Warning Messages | |||
#define warn_dPrint(...) | |||
#define warn_print(str) | |||
// Error Messages | |||
#define erro_dPrint(...) | |||
#define erro_print(str) | |||
// Debug Messages | |||
#define dbug_dPrint(...) | |||
#define dbug_print(str) | |||
// Static String Printing | |||
#define print(s) _print(PSTR(s)) | |||
// Output Functions | |||
#define _print(s) | |||
#define usb_debug_putstr(s) | |||
#define usb_debug_putstrs(s, ...) | |||
// String Functions | |||
#define hexToStr(hex, out) | |||
#define int8ToStr(in, out) | |||
#define int16ToStr(in, out) | |||
#define hexToStr_op(in, out, op) | |||
#define revsStr(in) | |||
#define lenStr(in) | |||
#endif | |||
@@ -10,10 +10,7 @@ | |||
### | |||
# Module C files | |||
# | |||
set( DEBUG_SRCS | |||
print.c | |||
) | |||
#| None! | |||
### |
@@ -19,19 +19,18 @@ | |||
* THE SOFTWARE. | |||
*/ | |||
// ----- Includes ----- | |||
// Compiler Includes | |||
#include <stdarg.h> | |||
// AVR Includes | |||
#include <avr/io.h> | |||
#include <avr/pgmspace.h> | |||
// Project Includes | |||
#include "print.h" | |||
// Defines | |||
// ----- Functions ----- | |||
// USB HID String Output | |||
void usb_debug_putstr( char* s ) | |||
{ |
@@ -22,16 +22,23 @@ | |||
#ifndef print_h__ | |||
#define print_h__ | |||
// ----- Includes ----- | |||
// AVR Includes | |||
#include <avr/pgmspace.h> | |||
// Project Includes | |||
#include "usb_keyboard_debug.h" | |||
// Defines | |||
// ----- Defines ----- | |||
#define NL "\r\n" | |||
// ----- Functions and Corresponding Function Aliases ----- | |||
/* XXX | |||
* Note that all the variadic functions below, take comma separated string lists, they are purposely not printf style (simplicity) | |||
*/ |
@@ -0,0 +1,28 @@ | |||
###| CMake Kiibohd Controller Debug Module |### | |||
# | |||
# Written by Jacob Alexander in 2011 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
### | |||
### | |||
# Module C files | |||
# | |||
set( DEBUG_SRCS | |||
print.c | |||
) | |||
### | |||
# Module Specific Options | |||
# | |||
### | |||
# Just in case, you only want this module and are using others as well | |||
# | |||
add_definitions( -I${HEAD_DIR}/Debug/off ) | |||
@@ -1,16 +1,49 @@ | |||
/* Copyright (C) 2011 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. | |||
*/ | |||
#ifndef __KEYMAP_h | |||
#define __KEYMAP_h | |||
// ----- Includes ----- | |||
#include "usb_keys.h" | |||
// ----- Defines ----- | |||
// Modifier Mask | |||
#define MODIFIERS_KEYPAD 0 | |||
#define MODIFIERS_KEYBOARD 4 | |||
static uint8_t keypad_modifierMask[] = {}; | |||
// ----- Variables ----- | |||
//static uint8_t keypad_modifierMask[] = {}; | |||
static uint8_t keyboard_modifierMask[] = { 1, 17, 33, 49 }; | |||
static uint8_t alternate_modifierMask[] = { 1, 17, 33, 49, 62 }; | |||
//static uint8_t alternate_modifierMask[] = { 1, 17, 33, 49, 62 }; | |||
// Default 1-indexed key mappings | |||
/* | |||
static uint8_t keypadDefaultMap[] = { 0, | |||
KEYPAD_7, | |||
KEYPAD_8, | |||
@@ -28,7 +61,7 @@ static uint8_t keypadDefaultMap[] = { 0, | |||
KEYPAD_0, | |||
KEYPAD_PERIOD, | |||
KEYPAD_PLUS }; | |||
*/ | |||
static uint8_t defaultMap[] = { 0, | |||
KEY_GUI, | |||
KEY_1, | |||
@@ -93,7 +126,7 @@ static uint8_t defaultMap[] = { 0, | |||
KEY_LEFT, | |||
KEY_RIGHT, | |||
KEY_SPACE }; | |||
/* | |||
static uint8_t navigationMap[] = { 0, | |||
KEY_GUI, | |||
KEY_F1, | |||
@@ -223,6 +256,6 @@ static uint8_t colemakMap[] = { 0, | |||
165, | |||
KEY_RIGHT_ALT, | |||
KEY_SPACE }; | |||
*/ | |||
#endif | |||
@@ -1,6 +1,28 @@ | |||
/* Copyright (C) 2011 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. | |||
*/ | |||
#ifndef __usb_keys_h | |||
#define __usb_keys_h | |||
// ----- Defines ----- | |||
// List of Modifiers | |||
#define KEY_CTRL 0x01 | |||
@@ -236,9 +258,5 @@ | |||
#define KEYS_RGUI 231 | |||
// 232 - 65535 Reserved | |||
#endif | |||
@@ -0,0 +1,8 @@ | |||
#!/bin/bash | |||
#| Loads the hex file onto the teensy | |||
sudo teensy-loader-cli -mmcu=@MCU@ -w @TARGET_HEX@ | |||
exit 0 | |||
@@ -1,8 +0,0 @@ | |||
#!/bin/bash | |||
#| Loads the hex file onto the teensy++ 2.0 | |||
sudo teensy-loader-cli -mmcu=at90usb1286 -w Build/main.hex | |||
exit 0 | |||
@@ -0,0 +1,86 @@ | |||
/* Copyright (C) 2011 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 ----- | |||
// AVR Includes | |||
// Project Includes | |||
#include <usb_com.h> | |||
#include <scan_loop.h> | |||
#include <print.h> | |||
// Keymaps | |||
#include <keymap.h> | |||
#include <usb_keys.h> | |||
// Local Includes | |||
#include "macro.h" | |||
// ----- Functions ----- | |||
// Given a sampling array, and the current number of detected keypress | |||
// Add as many keypresses from the sampling array to the USB key send array as possible. | |||
void keyPressDetection( uint8_t *keys, uint8_t *validKeys, uint8_t numberOfKeys, uint8_t *modifiers, uint8_t numberOfModifiers, uint8_t *map ) | |||
{ | |||
for ( uint8_t key = 0; key < numberOfKeys + 1; key++ ) { | |||
if ( keys[key] & (1 << 7) ) { | |||
// TODO Debug Out | |||
uint8_t modFound = 0; | |||
// Determine if the key is a modifier | |||
for ( uint8_t mod = 0; mod < numberOfModifiers; mod++ ) { | |||
// Modifier found | |||
if ( modifiers[mod] == key ) { | |||
USBKeys_Modifiers |= map[key]; | |||
modFound = 1; | |||
break; | |||
} | |||
} | |||
if ( modFound ) | |||
continue; | |||
// Too many keys | |||
if ( *validKeys >= USBKeys_MaxSize ) | |||
break; | |||
// Allow ignoring keys with 0's | |||
if ( map[key] != 0 ) | |||
USBKeys_Array[(*validKeys)++] = map[key]; | |||
} | |||
} | |||
} | |||
void process_macros(void) | |||
{ | |||
// Layout Setup | |||
uint8_t validKeys = 0; | |||
uint8_t *keyboard_MODMASK = keyboard_modifierMask; | |||
uint8_t keyboard_NUMMODS = MODIFIERS_KEYBOARD; | |||
uint8_t *keyboard_MAP = defaultMap; | |||
// Debounce Sampling Array to USB Data Array | |||
keyPressDetection( KeyIndex_Array, &validKeys, KeyIndex_Size, keyboard_MODMASK, keyboard_NUMMODS, keyboard_MAP ); | |||
} | |||
@@ -0,0 +1,38 @@ | |||
/* Copyright (C) 2011 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. | |||
*/ | |||
#ifndef __macro_h | |||
#define __macro_h | |||
// ----- Includes ----- | |||
// Compiler Includes | |||
#include <stdint.h> | |||
// ----- Functions ----- | |||
void keyPressDetection( uint8_t *keys, uint8_t *validKeys, uint8_t numberOfKeys, uint8_t *modifiers, uint8_t numberOfModifiers, uint8_t *map ); | |||
void process_macros(void); | |||
#endif | |||
@@ -12,6 +12,7 @@ | |||
# | |||
set( MACRO_SRCS | |||
macro.c | |||
) | |||
@@ -19,8 +19,15 @@ | |||
* THE SOFTWARE. | |||
*/ | |||
// ----- Includes ----- | |||
// Local Includes | |||
#include "matrix.h" | |||
// ----- Macros ----- | |||
#define REG_SET(reg) reg |= (1 << ( matrix[row][col] % 10 ) ) | |||
#define PIN_SET_COL(pin) \ | |||
@@ -59,6 +66,15 @@ | |||
break | |||
// ----- Variables ----- | |||
uint8_t KeyIndex_Array[KEYBOARD_SIZE + 1]; | |||
// ----- Functions ----- | |||
void matrix_pinSetup( uint8_t *matrix ) | |||
{ | |||
// Setup the variables |
@@ -22,6 +22,12 @@ | |||
#ifndef __MATRIX_H | |||
#define __MATRIX_H | |||
// ----- Includes ----- | |||
// Compiler Includes | |||
#include <stdint.h> | |||
// ----- Quick Map (don't change) ----- | |||
#define pinA0 0 | |||
#define pinA1 1 | |||
@@ -97,12 +103,13 @@ | |||
// ----- Key Settings ----- | |||
#define keyboardSize 16 // # of keys | |||
#define KEYBOARD_SIZE 16 // # of keys | |||
#define MAX_ROW_SIZE 16 // # of keys in the largest row | |||
// ----- Matrix Configuration ----- | |||
static uint8_t matrix_pinout[][] = { | |||
static const uint8_t matrix_pinout[][MAX_ROW_SIZE + 1] = { | |||
@@ -111,6 +118,7 @@ static uint8_t matrix_pinout[][] = { | |||
// The mode allows for optimization in the kind of scanning algorithms that are done | |||
// | |||
// The key numbers are used to translate into the keymap table (array) (and always start from 1, not 0). | |||
// Thus if a row doesn't use all the key positions, you can denote it as 0, which will be ignored/skipped on each scan | |||
// See the keymap.h file for the various preconfigured arrays. | |||
// Scan Mode | Col 1 | Col 2 | Col 3 | Col 4 | Col 4 | ... | |||
@@ -135,11 +143,13 @@ static uint8_t matrix_pinout[][] = { | |||
}; | |||
// ----- Variables ----- | |||
// NOTE: Highest Bit: Valid keypress (0x80 is valid keypress) | |||
// Other Bits: Pressed state sample counter | |||
uint8_t keyboardDetectArray[keyboardSize + 1]; | |||
extern uint8_t KeyIndex_Array [KEYBOARD_SIZE + 1]; | |||
static const uint8_t KeyIndex_Size = KEYBOARD_SIZE; | |||
@@ -19,13 +19,23 @@ | |||
* THE SOFTWARE. | |||
*/ | |||
// ----- Includes ----- | |||
// Local Includes | |||
#include "scan_loop.h" | |||
// ----- Defines ----- | |||
#include <stdint.h> | |||
#include <usb_keyboard_debug.h> | |||
#include <keymap.h> | |||
// Debouncing Defines | |||
#define SAMPLE_THRESHOLD 110 | |||
#define MAX_SAMPLES 127 // Max is 127, reaching 128 is very bad | |||
#define MAX_SAMPLES 127 // Max is 127, reaching 128 is very bad | |||
// ----- Macros ----- | |||
// Loop over all of the sampled keys of the given array | |||
// If the number of samples is higher than the sample threshold, flag the high bit, clear otherwise | |||
// This should be resetting VERY quickly, cutting off a potentially valid keypress is not an issue | |||
@@ -34,104 +44,32 @@ | |||
table[key] = ( table[key] & ~(1 << 7) ) > SAMPLE_THRESHOLD ? (1 << 7) : 0x00; \ | |||
} \ | |||
// NOTE: Highest Bit: Valid keypress (0x80 is valid keypress) | |||
// Other Bits: Pressed state sample counter | |||
#define KEYBOARD_SIZE 23 | |||
uint8_t keyboardDetectArray[KEYBOARD_SIZE + 1]; | |||
// Interrupt Variable | |||
volatile uint8_t sendKeypresses = 0; | |||
// USB Data Send | |||
void usb_send( uint8_t validKeys ) | |||
{ | |||
// TODO undo potentially old keys | |||
for ( uint8_t c = validKeys; c < 6; c++ ) | |||
keyboard_keys[c] = 0; | |||
// Send keypresses | |||
usb_keyboard_send(); | |||
// Clear sendKeypresses Flag | |||
sendKeypresses = 0; | |||
// ----- Variables ----- | |||
// Clear modifiers | |||
keyboard_modifier_keys = 0; | |||
} | |||
// Keeps track of the number of scans, so we only do a debounce assess when it would be valid (as it throws away data) | |||
uint8_t scan_count = 0; | |||
// Given a sampling array, and the current number of detected keypress | |||
// Add as many keypresses from the sampling array to the USB key send array as possible. | |||
void keyPressDetection( uint8_t *keys, uint8_t *validKeys, uint8_t numberOfKeys, uint8_t *modifiers, uint8_t numberOfModifiers, uint8_t *map ) { | |||
for ( uint8_t key = 0; key < numberOfKeys + 1; key++ ) { | |||
if ( keys[key] & (1 << 7) ) { | |||
pint8( key ); | |||
//print(" "); | |||
uint8_t modFound = 0; | |||
// Determine if the key is a modifier | |||
for ( uint8_t mod = 0; mod < numberOfModifiers; mod++ ) { | |||
// Modifier found | |||
if ( modifiers[mod] == key ) { | |||
keyboard_modifier_keys |= map[key]; | |||
modFound = 1; | |||
break; | |||
} | |||
} | |||
if ( modFound ) | |||
continue; | |||
// Too many keys | |||
if ( *validKeys == 6 ) | |||
break; | |||
// Allow ignoring keys with 0's | |||
if ( map[key] != 0 ) | |||
keyboard_keys[(*validKeys)++] = map[key]; | |||
} | |||
} | |||
} | |||
// ----- Functions ----- | |||
// Main Detection Loop | |||
void scan_loop( void ) | |||
void scan_loop() | |||
{ | |||
//matrix_pinSetup( matrix_pinout ); | |||
uint8_t count = 0; | |||
for ( ;; ) { | |||
//matrix_scan( matrix_pinout, keyboardDetectArray ); | |||
// Check count to see if the sample threshold may have been reached, otherwise collect more data | |||
if ( count++ < MAX_SAMPLES ) | |||
continue; | |||
// Reset Sample Counter | |||
count = 0; | |||
// Assess debouncing sample table | |||
//DEBOUNCE_ASSESS(keyDetectArray,KEYBOARD_SIZE) | |||
// Send keypresses over USB if the ISR has signalled that it's time | |||
if ( !sendKeypresses ) | |||
continue; | |||
// Layout Setup | |||
uint8_t validKeys = 0; | |||
uint8_t *keyboard_MODMASK = keyboard_modifierMask; | |||
uint8_t keyboard_NUMMODS = MODIFIERS_KEYBOARD; | |||
uint8_t *keyboard_MAP = defaultMap; | |||
// TODO Layout Switching | |||
//matrix_scan( matrix_pinout, keyboardDetectArray ); | |||
// TODO Macro Processing | |||
// Check count to see if the sample threshold may have been reached, otherwise collect more data | |||
if ( scan_count++ < MAX_SAMPLES ) | |||
return; | |||
// Debounce Sampling Array to USB Data Array | |||
keyPressDetection( keyboardDetectArray, &validKeys, KEYBOARD_SIZE, keyboard_MODMASK, keyboard_NUMMODS, keyboard_MAP ); | |||
// Reset Sample Counter | |||
scan_count = 0; | |||
// Send USB Data | |||
usb_send( validKeys ); | |||
} | |||
// Assess debouncing sample table | |||
//DEBOUNCE_ASSESS(keyDetectArray,KEYBOARD_SIZE) | |||
} | |||
@@ -22,8 +22,14 @@ | |||
#ifndef __SCAN_LOOP_H | |||
#define __SCAN_LOOP_H | |||
//extern uint8_t keyboardDetectArray[KEYBOARDZ | |||
extern volatile uint8_t sendKeypresses; | |||
// ----- Includes ----- | |||
// Local Includes | |||
#include "matrix.h" | |||
// ----- Functions ----- | |||
void scan_loop( void ); | |||
@@ -12,6 +12,7 @@ | |||
# | |||
set( USB_SRCS | |||
usb_com.c | |||
usb_keyboard_debug.c | |||
) | |||
@@ -0,0 +1,85 @@ | |||
/* Copyright (C) 2011 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 <util/delay.h> | |||
// AVR Includes | |||
// Project Includes | |||
#include "usb_keyboard_debug.h" | |||
// Local Includes | |||
#include "usb_com.h" | |||
// ----- Variables ----- | |||
// which modifier keys are currently pressed | |||
// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui | |||
// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui | |||
uint8_t USBKeys_Modifiers = 0; | |||
// which keys are currently pressed, up to 6 keys may be down at once | |||
uint8_t USBKeys_Array[USB_MAX_KEY_SEND] = {0,0,0,0,0,0}; | |||
// The number of keys sent to the usb in the array | |||
uint8_t USBKeys_Sent; | |||
// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana | |||
volatile uint8_t USBKeys_LEDs = 0; | |||
// ----- Functions ----- | |||
// USB Module Setup | |||
void usb_setup(void) | |||
{ | |||
// Initialize the USB, and then wait for the host to set configuration. | |||
// If the Teensy is powered without a PC connected to the USB port, | |||
// this will wait forever. | |||
usb_init(); | |||
while ( !usb_configured() ) /* wait */ ; | |||
// Wait an extra second for the PC's operating system to load drivers | |||
// and do whatever it does to actually be ready for input | |||
_delay_ms(1000); | |||
} | |||
// USB Data Send | |||
void usb_send(void) | |||
{ | |||
// TODO undo potentially old keys | |||
for ( uint8_t c = USBKeys_Sent; c < USBKeys_MaxSize; c++ ) | |||
USBKeys_Array[c] = 0; | |||
// Send keypresses | |||
usb_keyboard_send(); | |||
// Clear modifiers | |||
USBKeys_Modifiers = 0; | |||
} | |||
@@ -0,0 +1,73 @@ | |||
/* Copyright (C) 2011 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. | |||
*/ | |||
#ifndef __usb_com_h | |||
#define __usb_com_h | |||
// ----- Includes ----- | |||
// AVR Includes | |||
// Compiler Includes | |||
#include <stdint.h> | |||
// Local Includes | |||
// ----- Defines ----- | |||
// Indicator for other modules through USBKeys_MaxSize for how capable the USB module is when sending large number of keypresses | |||
#define USB_MAX_KEY_SEND 6 | |||
// You can change these to give your code its own name. | |||
#define STR_MANUFACTURER L"MfgName" | |||
#define STR_PRODUCT L"Keyboard" | |||
// Mac OS-X and Linux automatically load the correct drivers. On | |||
// Windows, even though the driver is supplied by Microsoft, an | |||
// INF file is needed to load the driver. These numbers need to | |||
// match the INF file. | |||
#define VENDOR_ID 0x16C0 | |||
#define PRODUCT_ID 0x047D | |||
// ----- Variables ----- | |||
// Variables used to communciate to the usb module | |||
extern uint8_t USBKeys_Modifiers; | |||
extern uint8_t USBKeys_Array[USB_MAX_KEY_SEND]; | |||
extern uint8_t USBKeys_Sent; | |||
extern volatile uint8_t USBKeys_LEDs; | |||
static const uint8_t USBKeys_MaxSize = USB_MAX_KEY_SEND; | |||
// ----- Functions ----- | |||
void usb_setup(void); | |||
void usb_send(void); | |||
#endif | |||
@@ -33,19 +33,6 @@ | |||
* | |||
**************************************************************************/ | |||
// You can change these to give your code its own name. | |||
#define STR_MANUFACTURER L"MfgName" | |||
#define STR_PRODUCT L"Keyboard" | |||
// Mac OS-X and Linux automatically load the correct drivers. On | |||
// Windows, even though the driver is supplied by Microsoft, an | |||
// INF file is needed to load the driver. These numbers need to | |||
// match the INF file. | |||
#define VENDOR_ID 0x16C0 | |||
#define PRODUCT_ID 0x047D | |||
// USB devices are supposed to implment a halt feature, which is | |||
// rarely (if ever) used. If you comment this line out, the halt | |||
// code will be removed, saving 102 bytes of space (gcc 4.3.0). | |||
@@ -286,14 +273,6 @@ static volatile uint8_t usb_configuration=0; | |||
// packet, or send a zero length packet. | |||
static volatile uint8_t debug_flush_timer=0; | |||
// which modifier keys are currently pressed | |||
// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui | |||
// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui | |||
uint8_t keyboard_modifier_keys=0; | |||
// which keys are currently pressed, up to 6 keys may be down at once | |||
uint8_t keyboard_keys[6]={0,0,0,0,0,0}; | |||
// protocol setting from the host. We use exactly the same report | |||
// either way, so this variable only stores the setting since we | |||
// are required to be able to report which setting is in use. | |||
@@ -306,9 +285,6 @@ static uint8_t keyboard_idle_config=125; | |||
// count until idle timeout | |||
static uint8_t keyboard_idle_count=0; | |||
// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana | |||
volatile uint8_t keyboard_leds=0; | |||
/************************************************************************** | |||
* | |||
@@ -344,16 +320,16 @@ int8_t usb_keyboard_press(uint8_t key, uint8_t modifier) | |||
{ | |||
int8_t r; | |||
keyboard_modifier_keys = modifier; | |||
keyboard_keys[0] = key; | |||
USBKeys_Modifiers = modifier; | |||
USBKeys_Array[0] = key; | |||
r = usb_keyboard_send(); | |||
if (r) return r; | |||
keyboard_modifier_keys = 0; | |||
keyboard_keys[0] = 0; | |||
USBKeys_Modifiers = 0; | |||
USBKeys_Array[0] = 0; | |||
return usb_keyboard_send(); | |||
} | |||
// send the contents of keyboard_keys and keyboard_modifier_keys | |||
// send the contents of USBKeys_Array and USBKeys_Modifiers | |||
int8_t usb_keyboard_send(void) | |||
{ | |||
uint8_t i, intr_state, timeout; | |||
@@ -376,10 +352,10 @@ int8_t usb_keyboard_send(void) | |||
cli(); | |||
UENUM = KEYBOARD_ENDPOINT; | |||
} | |||
UEDATX = keyboard_modifier_keys; | |||
UEDATX = USBKeys_Modifiers; | |||
UEDATX = 0; | |||
for (i=0; i<6; i++) { | |||
UEDATX = keyboard_keys[i]; | |||
UEDATX = USBKeys_Array[i]; | |||
} | |||
UEINTX = 0x3A; | |||
keyboard_idle_count = 0; | |||
@@ -505,10 +481,10 @@ ISR(USB_GEN_vect) | |||
keyboard_idle_count++; | |||
if (keyboard_idle_count == keyboard_idle_config) { | |||
keyboard_idle_count = 0; | |||
UEDATX = keyboard_modifier_keys; | |||
UEDATX = USBKeys_Modifiers; | |||
UEDATX = 0; | |||
for (i=0; i<6; i++) { | |||
UEDATX = keyboard_keys[i]; | |||
UEDATX = USBKeys_Array[i]; | |||
} | |||
UEINTX = 0x3A; | |||
} | |||
@@ -679,10 +655,10 @@ ISR(USB_COM_vect) | |||
if (bmRequestType == 0xA1) { | |||
if (bRequest == HID_GET_REPORT) { | |||
usb_wait_in_ready(); | |||
UEDATX = keyboard_modifier_keys; | |||
UEDATX = USBKeys_Modifiers; | |||
UEDATX = 0; | |||
for (i=0; i<6; i++) { | |||
UEDATX = keyboard_keys[i]; | |||
UEDATX = USBKeys_Array[i]; | |||
} | |||
usb_send_in(); | |||
return; | |||
@@ -703,7 +679,7 @@ ISR(USB_COM_vect) | |||
if (bmRequestType == 0x21) { | |||
if (bRequest == HID_SET_REPORT) { | |||
usb_wait_receive_out(); | |||
keyboard_leds = UEDATX; | |||
USBKeys_LEDs = UEDATX; | |||
usb_ack_out(); | |||
usb_send_in(); | |||
return; |
@@ -2,15 +2,14 @@ | |||
#define usb_serial_h__ | |||
#include <stdint.h> | |||
#include "usb_com.h" | |||
void usb_init(void); // initialize everything | |||
uint8_t usb_configured(void); // is the USB port configured | |||
int8_t usb_keyboard_press(uint8_t key, uint8_t modifier); | |||
int8_t usb_keyboard_send(void); | |||
extern uint8_t keyboard_modifier_keys; | |||
extern uint8_t keyboard_keys[6]; | |||
extern volatile uint8_t keyboard_leds; | |||
int8_t usb_debug_putchar(uint8_t c); // transmit a character | |||
void usb_debug_flush_output(void); // immediately transmit any buffered output |
@@ -19,51 +19,57 @@ | |||
* THE SOFTWARE. | |||
*/ | |||
// ----- Includes ----- | |||
// AVR Includes | |||
#include <avr/io.h> | |||
#include <avr/pgmspace.h> | |||
#include <avr/interrupt.h> | |||
#include <util/delay.h> | |||
// Project Includes | |||
//#include "usb_keys.h" | |||
#include "scan_loop.h" | |||
//#include "layouts.h" | |||
//#include "usb_keyboard.h" | |||
// TEMP INCLUDES | |||
#include "usb_keyboard_debug.h" | |||
#include "print.h" | |||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) | |||
#include "led.h" | |||
// ----- Defines ----- | |||
// Verified Keypress Defines | |||
#define USB_TRANSFER_DIVIDER 10 // 1024 == 1 Send of keypresses per second, 1 == 1 Send of keypresses per ~1 millisecond | |||
// Error LED Control | |||
void errorLED( uint8_t on ) | |||
{ | |||
// Error LED On | |||
if ( on ) { | |||
PORTD |= (1<<6); | |||
} | |||
// Error LED Off | |||
else { | |||
PORTD &= ~(1<<6); | |||
} | |||
} | |||
// ----- Macros ----- | |||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) | |||
// ----- Variables ----- | |||
// Timer Interrupt for flagging a send of the sampled key detection data to the USB host | |||
uint16_t sendKeypressCounter = 0; | |||
// Flag generated by the timer interrupt | |||
volatile uint8_t sendKeypresses = 0; | |||
// Initial Pin Setup | |||
// If the matrix is properly set, this function does not need to be changed | |||
// ----- Functions ----- | |||
// Initial Pin Setup, make sure they are sane | |||
inline void pinSetup(void) | |||
{ | |||
// For each pin, 0=input, 1=output | |||
DDRA = 0x00; | |||
DDRB = 0x00; | |||
DDRC = 0x00; | |||
DDRD = 0x40; // LED Setup | |||
DDRD = 0x00; | |||
DDRE = 0x00; | |||
DDRF = 0x00; | |||
@@ -72,12 +78,12 @@ inline void pinSetup(void) | |||
PORTA = 0x00; | |||
PORTB = 0x00; | |||
PORTC = 0x00; | |||
PORTD = 0x40; // LED Enable | |||
PORTD = 0x00; | |||
PORTE = 0x00; | |||
PORTF = 0x00; | |||
} | |||
int main( void ) | |||
int main(void) | |||
{ | |||
// Setup with 16 MHz clock | |||
CPU_PRESCALE( 0 ); | |||
@@ -85,15 +91,8 @@ int main( void ) | |||
// Configuring Pins | |||
pinSetup(); | |||
// Initialize the USB, and then wait for the host to set configuration. | |||
// If the Teensy is powered without a PC connected to the USB port, | |||
// this will wait forever. | |||
usb_init(); | |||
while ( !usb_configured() ) /* wait */ ; | |||
// Wait an extra second for the PC's operating system to load drivers | |||
// and do whatever it does to actually be ready for input | |||
_delay_ms(1000); | |||
// Setup USB Module | |||
usb_setup(); | |||
// Setup ISR Timer for flagging a kepress send to USB | |||
// Set to 256 * 1024 (8 bit timer with Clock/1024 prescalar) timer | |||
@@ -101,7 +100,6 @@ int main( void ) | |||
TCCR0B = 0x03; | |||
TIMSK0 = (1 << TOIE0); | |||
uint16_t led = 0; | |||
// Main Detection Loop | |||
while ( 1 ) { | |||
//scan_loop(); | |||
@@ -111,12 +109,19 @@ int main( void ) | |||
// HID Debug Error message | |||
erro_print("Detection loop error, this is very bad...bug report!"); | |||
// Send keypresses over USB if the ISR has signalled that it's time | |||
if ( !sendKeypresses ) | |||
continue; | |||
// Send USB Data | |||
usb_send(); | |||
// Clear sendKeypresses Flag | |||
sendKeypresses = 0; | |||
} | |||
} | |||
// Timer Interrupt for flagging a send of the sampled key detection data to the USB host | |||
uint16_t sendKeypressCounter = 0; | |||
ISR( TIMER0_OVF_vect ) | |||
{ | |||
sendKeypressCounter++; |
@@ -29,7 +29,7 @@ set( MacroModule "basic" ) | |||
set( USBModule "pjrc" ) | |||
##| Debugging source to use, each module has it's own set of defines that it sets | |||
set( DebugModule "basic" ) | |||
set( DebugModule "full" ) | |||